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