150995Sbostic /*-
261207Sbostic * Copyright (c) 1990, 1993
361207Sbostic * The Regents of the University of California. All rights reserved.
450995Sbostic *
550995Sbostic * %sccs.include.redist.c%
650995Sbostic */
750995Sbostic
850995Sbostic #if defined(LIBC_SCCS) && !defined(lint)
9*66294Sbostic static char sccsid[] = "@(#)rec_get.c 8.4 (Berkeley) 03/01/94";
1050995Sbostic #endif /* LIBC_SCCS and not lint */
1150995Sbostic
1250995Sbostic #include <sys/types.h>
1356753Sbostic
1450995Sbostic #include <errno.h>
1550995Sbostic #include <stddef.h>
1650995Sbostic #include <stdio.h>
1750995Sbostic #include <stdlib.h>
1850995Sbostic #include <string.h>
1956753Sbostic #include <unistd.h>
2056753Sbostic
2157933Sbostic #include <db.h>
2251086Sbostic #include "recno.h"
2350995Sbostic
2450995Sbostic /*
2550995Sbostic * __REC_GET -- Get a record from the btree.
2650995Sbostic *
2750995Sbostic * Parameters:
2850995Sbostic * dbp: pointer to access method
2950995Sbostic * key: key to find
3050995Sbostic * data: data to return
3150995Sbostic * flag: currently unused
3250995Sbostic *
3350995Sbostic * Returns:
3450995Sbostic * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
3550995Sbostic */
3650995Sbostic int
__rec_get(dbp,key,data,flags)3750995Sbostic __rec_get(dbp, key, data, flags)
3850995Sbostic const DB *dbp;
3951086Sbostic const DBT *key;
4051086Sbostic DBT *data;
4150995Sbostic u_int flags;
4250995Sbostic {
4350995Sbostic BTREE *t;
4450995Sbostic EPG *e;
4550995Sbostic recno_t nrec;
4654279Sbostic int status;
4750995Sbostic
4864461Sbostic t = dbp->internal;
4964461Sbostic
5064461Sbostic /* Toss any page pinned across calls. */
5164461Sbostic if (t->bt_pinned != NULL) {
5264461Sbostic mpool_put(t->bt_mp, t->bt_pinned, 0);
5364461Sbostic t->bt_pinned = NULL;
5464461Sbostic }
5564461Sbostic
5664461Sbostic /* Get currently doesn't take any flags, and keys of 0 are illegal. */
5750995Sbostic if (flags || (nrec = *(recno_t *)key->data) == 0) {
5850995Sbostic errno = EINVAL;
5950995Sbostic return (RET_ERROR);
6050995Sbostic }
6150995Sbostic
6250995Sbostic /*
6350995Sbostic * If we haven't seen this record yet, try to find it in the
6450995Sbostic * original file.
6550995Sbostic */
6658747Sbostic if (nrec > t->bt_nrecs) {
6760051Sbostic if (ISSET(t, R_EOF | R_INMEM))
6858747Sbostic return (RET_SPECIAL);
6958747Sbostic if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
7050995Sbostic return (status);
7158747Sbostic }
7250995Sbostic
7350995Sbostic --nrec;
7451086Sbostic if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
7550995Sbostic return (RET_ERROR);
7650995Sbostic
7756753Sbostic status = __rec_ret(t, e, 0, NULL, data);
7864461Sbostic if (ISSET(t, B_DB_LOCK))
7964461Sbostic mpool_put(t->bt_mp, e->page, 0);
8064461Sbostic else
8164461Sbostic t->bt_pinned = e->page;
8250995Sbostic return (status);
8350995Sbostic }
8450995Sbostic
8550995Sbostic /*
8650995Sbostic * __REC_FPIPE -- Get fixed length records from a pipe.
8750995Sbostic *
8850995Sbostic * Parameters:
8950995Sbostic * t: tree
9050995Sbostic * cnt: records to read
9150995Sbostic *
9250995Sbostic * Returns:
9350995Sbostic * RET_ERROR, RET_SUCCESS
9450995Sbostic */
9550995Sbostic int
__rec_fpipe(t,top)9650995Sbostic __rec_fpipe(t, top)
9750995Sbostic BTREE *t;
9850995Sbostic recno_t top;
9950995Sbostic {
10050995Sbostic DBT data;
10150995Sbostic recno_t nrec;
10250995Sbostic size_t len;
10350995Sbostic int ch;
10450995Sbostic char *p;
10550995Sbostic
10650995Sbostic if (t->bt_dbufsz < t->bt_reclen) {
10766213Sbostic if ((t->bt_dbuf =
10866213Sbostic (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
10950995Sbostic return (RET_ERROR);
11050995Sbostic t->bt_dbufsz = t->bt_reclen;
11150995Sbostic }
112*66294Sbostic data.data = t->bt_dbuf;
113*66294Sbostic data.size = t->bt_reclen;
114*66294Sbostic
11550995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
11656753Sbostic len = t->bt_reclen;
11750995Sbostic for (p = t->bt_dbuf;; *p++ = ch)
11850995Sbostic if ((ch = getc(t->bt_rfp)) == EOF || !len--) {
11950995Sbostic if (__rec_iput(t, nrec, &data, 0)
12050995Sbostic != RET_SUCCESS)
12150995Sbostic return (RET_ERROR);
12250995Sbostic break;
12350995Sbostic }
12450995Sbostic if (ch == EOF)
12550995Sbostic break;
12650995Sbostic }
12750995Sbostic if (nrec < top) {
12860051Sbostic SET(t, R_EOF);
12950995Sbostic return (RET_SPECIAL);
13050995Sbostic }
13150995Sbostic return (RET_SUCCESS);
13250995Sbostic }
13350995Sbostic
13450995Sbostic /*
13550995Sbostic * __REC_VPIPE -- Get variable length records from a pipe.
13650995Sbostic *
13750995Sbostic * Parameters:
13850995Sbostic * t: tree
13950995Sbostic * cnt: records to read
14050995Sbostic *
14150995Sbostic * Returns:
14250995Sbostic * RET_ERROR, RET_SUCCESS
14350995Sbostic */
14450995Sbostic int
__rec_vpipe(t,top)14550995Sbostic __rec_vpipe(t, top)
14650995Sbostic BTREE *t;
14750995Sbostic recno_t top;
14850995Sbostic {
14950995Sbostic DBT data;
15050995Sbostic recno_t nrec;
15157988Sbostic indx_t len;
15250995Sbostic size_t sz;
15350995Sbostic int bval, ch;
15450995Sbostic char *p;
15550995Sbostic
15650995Sbostic bval = t->bt_bval;
15750995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
15850995Sbostic for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) {
15950995Sbostic if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
16050995Sbostic data.data = t->bt_dbuf;
16150995Sbostic data.size = p - t->bt_dbuf;
16259793Sbostic if (ch == EOF && data.size == 0)
16359793Sbostic break;
16450995Sbostic if (__rec_iput(t, nrec, &data, 0)
16550995Sbostic != RET_SUCCESS)
16650995Sbostic return (RET_ERROR);
16750995Sbostic break;
16850995Sbostic }
16950995Sbostic if (sz == 0) {
17050995Sbostic len = p - t->bt_dbuf;
17158098Sbostic t->bt_dbufsz += (sz = 256);
17266213Sbostic if ((t->bt_dbuf = (char *)realloc(t->bt_dbuf,
17366213Sbostic t->bt_dbufsz)) == NULL)
17450995Sbostic return (RET_ERROR);
17550995Sbostic p = t->bt_dbuf + len;
17650995Sbostic }
17750995Sbostic }
17850995Sbostic if (ch == EOF)
17950995Sbostic break;
18050995Sbostic }
18150995Sbostic if (nrec < top) {
18260051Sbostic SET(t, R_EOF);
18350995Sbostic return (RET_SPECIAL);
18450995Sbostic }
18550995Sbostic return (RET_SUCCESS);
18650995Sbostic }
18750995Sbostic
18850995Sbostic /*
18950995Sbostic * __REC_FMAP -- Get fixed length records from a file.
19050995Sbostic *
19150995Sbostic * Parameters:
19250995Sbostic * t: tree
19350995Sbostic * cnt: records to read
19450995Sbostic *
19550995Sbostic * Returns:
19650995Sbostic * RET_ERROR, RET_SUCCESS
19750995Sbostic */
19850995Sbostic int
__rec_fmap(t,top)19950995Sbostic __rec_fmap(t, top)
20050995Sbostic BTREE *t;
20150995Sbostic recno_t top;
20250995Sbostic {
20350995Sbostic DBT data;
20450995Sbostic recno_t nrec;
20550995Sbostic caddr_t sp, ep;
20650995Sbostic size_t len;
20750995Sbostic char *p;
20850995Sbostic
20950995Sbostic if (t->bt_dbufsz < t->bt_reclen) {
21066213Sbostic if ((t->bt_dbuf =
21166213Sbostic (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL)
21250995Sbostic return (RET_ERROR);
21350995Sbostic t->bt_dbufsz = t->bt_reclen;
21450995Sbostic }
215*66294Sbostic data.data = t->bt_dbuf;
216*66294Sbostic data.size = t->bt_reclen;
217*66294Sbostic
218*66294Sbostic sp = t->bt_cmap;
219*66294Sbostic ep = t->bt_emap;
22050995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
22150995Sbostic if (sp >= ep) {
22260051Sbostic SET(t, R_EOF);
22350995Sbostic return (RET_SPECIAL);
22450995Sbostic }
22550995Sbostic len = t->bt_reclen;
22650995Sbostic for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++);
22750995Sbostic memset(p, t->bt_bval, len);
22850995Sbostic if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
22950995Sbostic return (RET_ERROR);
23050995Sbostic }
23158747Sbostic t->bt_cmap = sp;
23250995Sbostic return (RET_SUCCESS);
23350995Sbostic }
23450995Sbostic
23550995Sbostic /*
23650995Sbostic * __REC_VMAP -- Get variable length records from a file.
23750995Sbostic *
23850995Sbostic * Parameters:
23950995Sbostic * t: tree
24050995Sbostic * cnt: records to read
24150995Sbostic *
24250995Sbostic * Returns:
24350995Sbostic * RET_ERROR, RET_SUCCESS
24450995Sbostic */
24550995Sbostic int
__rec_vmap(t,top)24650995Sbostic __rec_vmap(t, top)
24750995Sbostic BTREE *t;
24850995Sbostic recno_t top;
24950995Sbostic {
25050995Sbostic DBT data;
25151086Sbostic caddr_t sp, ep;
25250995Sbostic recno_t nrec;
25350995Sbostic int bval;
25450995Sbostic
25558747Sbostic sp = t->bt_cmap;
25650995Sbostic ep = t->bt_emap;
25750995Sbostic bval = t->bt_bval;
25850995Sbostic
25950995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
26050995Sbostic if (sp >= ep) {
26160051Sbostic SET(t, R_EOF);
26250995Sbostic return (RET_SPECIAL);
26350995Sbostic }
26450995Sbostic for (data.data = sp; sp < ep && *sp != bval; ++sp);
26550995Sbostic data.size = sp - (caddr_t)data.data;
26650995Sbostic if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
26750995Sbostic return (RET_ERROR);
26850995Sbostic ++sp;
26950995Sbostic }
27058747Sbostic t->bt_cmap = sp;
27150995Sbostic return (RET_SUCCESS);
27250995Sbostic }
273