xref: /illumos-gate/usr/src/lib/krb5/plugins/kdb/db2/libdb2/recno/rec_get.c (revision 1da57d551424de5a9d469760be7c4b4d4f10a755)
1*54925bf6Swillf /*-
2*54925bf6Swillf  * Copyright (c) 1990, 1993, 1994
3*54925bf6Swillf  *	The Regents of the University of California.  All rights reserved.
4*54925bf6Swillf  *
5*54925bf6Swillf  * Redistribution and use in source and binary forms, with or without
6*54925bf6Swillf  * modification, are permitted provided that the following conditions
7*54925bf6Swillf  * are met:
8*54925bf6Swillf  * 1. Redistributions of source code must retain the above copyright
9*54925bf6Swillf  *    notice, this list of conditions and the following disclaimer.
10*54925bf6Swillf  * 2. Redistributions in binary form must reproduce the above copyright
11*54925bf6Swillf  *    notice, this list of conditions and the following disclaimer in the
12*54925bf6Swillf  *    documentation and/or other materials provided with the distribution.
13*54925bf6Swillf  * 3. All advertising materials mentioning features or use of this software
14*54925bf6Swillf  *    must display the following acknowledgement:
15*54925bf6Swillf  *	This product includes software developed by the University of
16*54925bf6Swillf  *	California, Berkeley and its contributors.
17*54925bf6Swillf  * 4. Neither the name of the University nor the names of its contributors
18*54925bf6Swillf  *    may be used to endorse or promote products derived from this software
19*54925bf6Swillf  *    without specific prior written permission.
20*54925bf6Swillf  *
21*54925bf6Swillf  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*54925bf6Swillf  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*54925bf6Swillf  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*54925bf6Swillf  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*54925bf6Swillf  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*54925bf6Swillf  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*54925bf6Swillf  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*54925bf6Swillf  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*54925bf6Swillf  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*54925bf6Swillf  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*54925bf6Swillf  * SUCH DAMAGE.
32*54925bf6Swillf  */
33*54925bf6Swillf 
34*54925bf6Swillf #if defined(LIBC_SCCS) && !defined(lint)
35*54925bf6Swillf static char sccsid[] = "@(#)rec_get.c	8.9 (Berkeley) 8/18/94";
36*54925bf6Swillf #endif /* LIBC_SCCS and not lint */
37*54925bf6Swillf 
38*54925bf6Swillf #include <sys/types.h>
39*54925bf6Swillf 
40*54925bf6Swillf #include <errno.h>
41*54925bf6Swillf #include <stddef.h>
42*54925bf6Swillf #include <stdio.h>
43*54925bf6Swillf #include <stdlib.h>
44*54925bf6Swillf #include <string.h>
45*54925bf6Swillf #include <unistd.h>
46*54925bf6Swillf 
47*54925bf6Swillf #include "db-int.h"
48*54925bf6Swillf #include "recno.h"
49*54925bf6Swillf 
50*54925bf6Swillf /*
51*54925bf6Swillf  * __REC_GET -- Get a record from the btree.
52*54925bf6Swillf  *
53*54925bf6Swillf  * Parameters:
54*54925bf6Swillf  *	dbp:	pointer to access method
55*54925bf6Swillf  *	key:	key to find
56*54925bf6Swillf  *	data:	data to return
57*54925bf6Swillf  *	flag:	currently unused
58*54925bf6Swillf  *
59*54925bf6Swillf  * Returns:
60*54925bf6Swillf  *	RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
61*54925bf6Swillf  */
62*54925bf6Swillf int
__rec_get(dbp,key,data,flags)63*54925bf6Swillf __rec_get(dbp, key, data, flags)
64*54925bf6Swillf 	const DB *dbp;
65*54925bf6Swillf 	const DBT *key;
66*54925bf6Swillf 	DBT *data;
67*54925bf6Swillf 	u_int flags;
68*54925bf6Swillf {
69*54925bf6Swillf 	BTREE *t;
70*54925bf6Swillf 	EPG *e;
71*54925bf6Swillf 	recno_t nrec;
72*54925bf6Swillf 	int status;
73*54925bf6Swillf 
74*54925bf6Swillf 	t = dbp->internal;
75*54925bf6Swillf 
76*54925bf6Swillf 	/* Toss any page pinned across calls. */
77*54925bf6Swillf 	if (t->bt_pinned != NULL) {
78*54925bf6Swillf 		mpool_put(t->bt_mp, t->bt_pinned, 0);
79*54925bf6Swillf 		t->bt_pinned = NULL;
80*54925bf6Swillf 	}
81*54925bf6Swillf 
82*54925bf6Swillf 	/* Get currently doesn't take any flags, and keys of 0 are illegal. */
83*54925bf6Swillf 	if (flags || (nrec = *(recno_t *)key->data) == 0) {
84*54925bf6Swillf 		errno = EINVAL;
85*54925bf6Swillf 		return (RET_ERROR);
86*54925bf6Swillf 	}
87*54925bf6Swillf 
88*54925bf6Swillf 	/*
89*54925bf6Swillf 	 * If we haven't seen this record yet, try to find it in the
90*54925bf6Swillf 	 * original file.
91*54925bf6Swillf 	 */
92*54925bf6Swillf 	if (nrec > t->bt_nrecs) {
93*54925bf6Swillf 		if (F_ISSET(t, R_EOF | R_INMEM))
94*54925bf6Swillf 			return (RET_SPECIAL);
95*54925bf6Swillf 		if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
96*54925bf6Swillf 			return (status);
97*54925bf6Swillf 	}
98*54925bf6Swillf 
99*54925bf6Swillf 	--nrec;
100*54925bf6Swillf 	if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
101*54925bf6Swillf 		return (RET_ERROR);
102*54925bf6Swillf 
103*54925bf6Swillf 	status = __rec_ret(t, e, 0, NULL, data);
104*54925bf6Swillf 	if (F_ISSET(t, B_DB_LOCK))
105*54925bf6Swillf 		mpool_put(t->bt_mp, e->page, 0);
106*54925bf6Swillf 	else
107*54925bf6Swillf 		t->bt_pinned = e->page;
108*54925bf6Swillf 	return (status);
109*54925bf6Swillf }
110*54925bf6Swillf 
111*54925bf6Swillf /*
112*54925bf6Swillf  * __REC_FPIPE -- Get fixed length records from a pipe.
113*54925bf6Swillf  *
114*54925bf6Swillf  * Parameters:
115*54925bf6Swillf  *	t:	tree
116*54925bf6Swillf  *	cnt:	records to read
117*54925bf6Swillf  *
118*54925bf6Swillf  * Returns:
119*54925bf6Swillf  *	RET_ERROR, RET_SUCCESS
120*54925bf6Swillf  */
121*54925bf6Swillf int
__rec_fpipe(t,top)122*54925bf6Swillf __rec_fpipe(t, top)
123*54925bf6Swillf 	BTREE *t;
124*54925bf6Swillf 	recno_t top;
125*54925bf6Swillf {
126*54925bf6Swillf 	DBT data;
127*54925bf6Swillf 	recno_t nrec;
128*54925bf6Swillf 	size_t len;
129*54925bf6Swillf 	int ch;
130*54925bf6Swillf 	u_char *p;
131*54925bf6Swillf 
132*54925bf6Swillf 	if (t->bt_rdata.size < t->bt_reclen) {
133*54925bf6Swillf 		t->bt_rdata.data = t->bt_rdata.data == NULL ?
134*54925bf6Swillf 		    malloc(t->bt_reclen) :
135*54925bf6Swillf 		    realloc(t->bt_rdata.data, t->bt_reclen);
136*54925bf6Swillf 		if (t->bt_rdata.data == NULL)
137*54925bf6Swillf 			return (RET_ERROR);
138*54925bf6Swillf 		t->bt_rdata.size = t->bt_reclen;
139*54925bf6Swillf 	}
140*54925bf6Swillf 	data.data = t->bt_rdata.data;
141*54925bf6Swillf 	data.size = t->bt_reclen;
142*54925bf6Swillf 
143*54925bf6Swillf 	for (nrec = t->bt_nrecs; nrec < top;) {
144*54925bf6Swillf 		len = t->bt_reclen;
145*54925bf6Swillf 		for (p = t->bt_rdata.data;; *p++ = ch)
146*54925bf6Swillf 			if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
147*54925bf6Swillf 				if (ch != EOF)
148*54925bf6Swillf 					*p = ch;
149*54925bf6Swillf 				if (len != 0)
150*54925bf6Swillf 					memset(p, t->bt_bval, len);
151*54925bf6Swillf 				if (__rec_iput(t,
152*54925bf6Swillf 				    nrec, &data, 0) != RET_SUCCESS)
153*54925bf6Swillf 					return (RET_ERROR);
154*54925bf6Swillf 				++nrec;
155*54925bf6Swillf 				break;
156*54925bf6Swillf 			}
157*54925bf6Swillf 		if (ch == EOF)
158*54925bf6Swillf 			break;
159*54925bf6Swillf 	}
160*54925bf6Swillf 	if (nrec < top) {
161*54925bf6Swillf 		F_SET(t, R_EOF);
162*54925bf6Swillf 		return (RET_SPECIAL);
163*54925bf6Swillf 	}
164*54925bf6Swillf 	return (RET_SUCCESS);
165*54925bf6Swillf }
166*54925bf6Swillf 
167*54925bf6Swillf /*
168*54925bf6Swillf  * __REC_VPIPE -- Get variable length records from a pipe.
169*54925bf6Swillf  *
170*54925bf6Swillf  * Parameters:
171*54925bf6Swillf  *	t:	tree
172*54925bf6Swillf  *	cnt:	records to read
173*54925bf6Swillf  *
174*54925bf6Swillf  * Returns:
175*54925bf6Swillf  *	RET_ERROR, RET_SUCCESS
176*54925bf6Swillf  */
177*54925bf6Swillf int
__rec_vpipe(t,top)178*54925bf6Swillf __rec_vpipe(t, top)
179*54925bf6Swillf 	BTREE *t;
180*54925bf6Swillf 	recno_t top;
181*54925bf6Swillf {
182*54925bf6Swillf 	DBT data;
183*54925bf6Swillf 	recno_t nrec;
184*54925bf6Swillf 	indx_t len;
185*54925bf6Swillf 	size_t sz;
186*54925bf6Swillf 	int bval, ch;
187*54925bf6Swillf 	u_char *p;
188*54925bf6Swillf 
189*54925bf6Swillf 	bval = t->bt_bval;
190*54925bf6Swillf 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
191*54925bf6Swillf 		for (p = t->bt_rdata.data,
192*54925bf6Swillf 		    sz = t->bt_rdata.size;; *p++ = ch, --sz) {
193*54925bf6Swillf 			if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
194*54925bf6Swillf 				data.data = t->bt_rdata.data;
195*54925bf6Swillf 				data.size = p - (u_char *)t->bt_rdata.data;
196*54925bf6Swillf 				if (ch == EOF && data.size == 0)
197*54925bf6Swillf 					break;
198*54925bf6Swillf 				if (__rec_iput(t, nrec, &data, 0)
199*54925bf6Swillf 				    != RET_SUCCESS)
200*54925bf6Swillf 					return (RET_ERROR);
201*54925bf6Swillf 				break;
202*54925bf6Swillf 			}
203*54925bf6Swillf 			if (sz == 0) {
204*54925bf6Swillf 				len = p - (u_char *)t->bt_rdata.data;
205*54925bf6Swillf 				t->bt_rdata.size += (sz = 256);
206*54925bf6Swillf 				t->bt_rdata.data = t->bt_rdata.data == NULL ?
207*54925bf6Swillf 				    malloc(t->bt_rdata.size) :
208*54925bf6Swillf 				    realloc(t->bt_rdata.data, t->bt_rdata.size);
209*54925bf6Swillf 				if (t->bt_rdata.data == NULL)
210*54925bf6Swillf 					return (RET_ERROR);
211*54925bf6Swillf 				p = (u_char *)t->bt_rdata.data + len;
212*54925bf6Swillf 			}
213*54925bf6Swillf 		}
214*54925bf6Swillf 		if (ch == EOF)
215*54925bf6Swillf 			break;
216*54925bf6Swillf 	}
217*54925bf6Swillf 	if (nrec < top) {
218*54925bf6Swillf 		F_SET(t, R_EOF);
219*54925bf6Swillf 		return (RET_SPECIAL);
220*54925bf6Swillf 	}
221*54925bf6Swillf 	return (RET_SUCCESS);
222*54925bf6Swillf }
223*54925bf6Swillf 
224*54925bf6Swillf /*
225*54925bf6Swillf  * __REC_FMAP -- Get fixed length records from a file.
226*54925bf6Swillf  *
227*54925bf6Swillf  * Parameters:
228*54925bf6Swillf  *	t:	tree
229*54925bf6Swillf  *	cnt:	records to read
230*54925bf6Swillf  *
231*54925bf6Swillf  * Returns:
232*54925bf6Swillf  *	RET_ERROR, RET_SUCCESS
233*54925bf6Swillf  */
234*54925bf6Swillf int
__rec_fmap(t,top)235*54925bf6Swillf __rec_fmap(t, top)
236*54925bf6Swillf 	BTREE *t;
237*54925bf6Swillf 	recno_t top;
238*54925bf6Swillf {
239*54925bf6Swillf 	DBT data;
240*54925bf6Swillf 	recno_t nrec;
241*54925bf6Swillf 	u_char *sp, *ep, *p;
242*54925bf6Swillf 	size_t len;
243*54925bf6Swillf 
244*54925bf6Swillf 	if (t->bt_rdata.size < t->bt_reclen) {
245*54925bf6Swillf 		t->bt_rdata.data = t->bt_rdata.data == NULL ?
246*54925bf6Swillf 		    malloc(t->bt_reclen) :
247*54925bf6Swillf 		    realloc(t->bt_rdata.data, t->bt_reclen);
248*54925bf6Swillf 		if (t->bt_rdata.data == NULL)
249*54925bf6Swillf 			return (RET_ERROR);
250*54925bf6Swillf 		t->bt_rdata.size = t->bt_reclen;
251*54925bf6Swillf 	}
252*54925bf6Swillf 	data.data = t->bt_rdata.data;
253*54925bf6Swillf 	data.size = t->bt_reclen;
254*54925bf6Swillf 
255*54925bf6Swillf 	sp = (u_char *)t->bt_cmap;
256*54925bf6Swillf 	ep = (u_char *)t->bt_emap;
257*54925bf6Swillf 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
258*54925bf6Swillf 		if (sp >= ep) {
259*54925bf6Swillf 			F_SET(t, R_EOF);
260*54925bf6Swillf 			return (RET_SPECIAL);
261*54925bf6Swillf 		}
262*54925bf6Swillf 		len = t->bt_reclen;
263*54925bf6Swillf 		for (p = t->bt_rdata.data;
264*54925bf6Swillf 		    sp < ep && len > 0; *p++ = *sp++, --len);
265*54925bf6Swillf 		if (len != 0)
266*54925bf6Swillf 			memset(p, t->bt_bval, len);
267*54925bf6Swillf 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
268*54925bf6Swillf 			return (RET_ERROR);
269*54925bf6Swillf 	}
270*54925bf6Swillf 	t->bt_cmap = (caddr_t)sp;
271*54925bf6Swillf 	return (RET_SUCCESS);
272*54925bf6Swillf }
273*54925bf6Swillf 
274*54925bf6Swillf /*
275*54925bf6Swillf  * __REC_VMAP -- Get variable length records from a file.
276*54925bf6Swillf  *
277*54925bf6Swillf  * Parameters:
278*54925bf6Swillf  *	t:	tree
279*54925bf6Swillf  *	cnt:	records to read
280*54925bf6Swillf  *
281*54925bf6Swillf  * Returns:
282*54925bf6Swillf  *	RET_ERROR, RET_SUCCESS
283*54925bf6Swillf  */
284*54925bf6Swillf int
__rec_vmap(t,top)285*54925bf6Swillf __rec_vmap(t, top)
286*54925bf6Swillf 	BTREE *t;
287*54925bf6Swillf 	recno_t top;
288*54925bf6Swillf {
289*54925bf6Swillf 	DBT data;
290*54925bf6Swillf 	u_char *sp, *ep;
291*54925bf6Swillf 	recno_t nrec;
292*54925bf6Swillf 	int bval;
293*54925bf6Swillf 
294*54925bf6Swillf 	sp = (u_char *)t->bt_cmap;
295*54925bf6Swillf 	ep = (u_char *)t->bt_emap;
296*54925bf6Swillf 	bval = t->bt_bval;
297*54925bf6Swillf 
298*54925bf6Swillf 	for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
299*54925bf6Swillf 		if (sp >= ep) {
300*54925bf6Swillf 			F_SET(t, R_EOF);
301*54925bf6Swillf 			return (RET_SPECIAL);
302*54925bf6Swillf 		}
303*54925bf6Swillf 		for (data.data = sp; sp < ep && *sp != bval; ++sp);
304*54925bf6Swillf 		data.size = sp - (u_char *)data.data;
305*54925bf6Swillf 		if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
306*54925bf6Swillf 			return (RET_ERROR);
307*54925bf6Swillf 		++sp;
308*54925bf6Swillf 	}
309*54925bf6Swillf 	t->bt_cmap = (caddr_t)sp;
310*54925bf6Swillf 	return (RET_SUCCESS);
311*54925bf6Swillf }
312