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*66213Sbostic static char sccsid[] = "@(#)rec_get.c 8.3 (Berkeley) 02/21/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 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 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 data.data = t->bt_dbuf; 10750995Sbostic data.size = t->bt_reclen; 10850995Sbostic 10950995Sbostic if (t->bt_dbufsz < t->bt_reclen) { 110*66213Sbostic if ((t->bt_dbuf = 111*66213Sbostic (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 11250995Sbostic return (RET_ERROR); 11350995Sbostic t->bt_dbufsz = t->bt_reclen; 11450995Sbostic } 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 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); 172*66213Sbostic if ((t->bt_dbuf = (char *)realloc(t->bt_dbuf, 173*66213Sbostic 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 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 20958747Sbostic sp = t->bt_cmap; 21050995Sbostic ep = t->bt_emap; 21150995Sbostic data.data = t->bt_dbuf; 21250995Sbostic data.size = t->bt_reclen; 21350995Sbostic 21450995Sbostic if (t->bt_dbufsz < t->bt_reclen) { 215*66213Sbostic if ((t->bt_dbuf = 216*66213Sbostic (char *)realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 21750995Sbostic return (RET_ERROR); 21850995Sbostic t->bt_dbufsz = t->bt_reclen; 21950995Sbostic } 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 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