150995Sbostic /*- 250995Sbostic * Copyright (c) 1990 The Regents of the University of California. 350995Sbostic * All rights reserved. 450995Sbostic * 550995Sbostic * %sccs.include.redist.c% 650995Sbostic */ 750995Sbostic 850995Sbostic #if defined(LIBC_SCCS) && !defined(lint) 9*51086Sbostic static char sccsid[] = "@(#)rec_get.c 5.2 (Berkeley) 09/11/91"; 1050995Sbostic #endif /* LIBC_SCCS and not lint */ 1150995Sbostic 1250995Sbostic #include <sys/types.h> 1350995Sbostic #include <errno.h> 1450995Sbostic #include <db.h> 1550995Sbostic #include <unistd.h> 1650995Sbostic #include <stddef.h> 1750995Sbostic #include <stdio.h> 1850995Sbostic #include <stdlib.h> 1950995Sbostic #include <string.h> 20*51086Sbostic #include "recno.h" 2150995Sbostic 2250995Sbostic /* 2350995Sbostic * __REC_GET -- Get a record from the btree. 2450995Sbostic * 2550995Sbostic * Parameters: 2650995Sbostic * dbp: pointer to access method 2750995Sbostic * key: key to find 2850995Sbostic * data: data to return 2950995Sbostic * flag: currently unused 3050995Sbostic * 3150995Sbostic * Returns: 3250995Sbostic * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. 3350995Sbostic */ 3450995Sbostic int 3550995Sbostic __rec_get(dbp, key, data, flags) 3650995Sbostic const DB *dbp; 37*51086Sbostic const DBT *key; 38*51086Sbostic DBT *data; 3950995Sbostic u_int flags; 4050995Sbostic { 4150995Sbostic BTREE *t; 4250995Sbostic EPG *e; 4350995Sbostic recno_t nrec; 4450995Sbostic int exact, status; 4550995Sbostic 4650995Sbostic if (flags || (nrec = *(recno_t *)key->data) == 0) { 4750995Sbostic errno = EINVAL; 4850995Sbostic return (RET_ERROR); 4950995Sbostic } 5050995Sbostic 5150995Sbostic /* 5250995Sbostic * If we haven't seen this record yet, try to find it in the 5350995Sbostic * original file. 5450995Sbostic */ 5550995Sbostic t = dbp->internal; 5650995Sbostic if (nrec > t->bt_nrecs && 5750995Sbostic (status = t->bt_irec(t, nrec)) != RET_SUCCESS) 5850995Sbostic return (status); 5950995Sbostic 6050995Sbostic --nrec; 61*51086Sbostic if ((e = __rec_search(t, nrec, SEARCH)) == NULL) 6250995Sbostic return (RET_ERROR); 6350995Sbostic 6450995Sbostic if (!exact) { 6550995Sbostic mpool_put(t->bt_mp, e->page, 0); 6650995Sbostic return (RET_SPECIAL); 6750995Sbostic } 6850995Sbostic 6950995Sbostic status = __rec_ret(t, e, data); 7050995Sbostic mpool_put(t->bt_mp, e->page, 0); 7150995Sbostic return (status); 7250995Sbostic } 7350995Sbostic 7450995Sbostic /* 7550995Sbostic * __REC_FPIPE -- Get fixed length records from a pipe. 7650995Sbostic * 7750995Sbostic * Parameters: 7850995Sbostic * t: tree 7950995Sbostic * cnt: records to read 8050995Sbostic * 8150995Sbostic * Returns: 8250995Sbostic * RET_ERROR, RET_SUCCESS 8350995Sbostic */ 8450995Sbostic int 8550995Sbostic __rec_fpipe(t, top) 8650995Sbostic BTREE *t; 8750995Sbostic recno_t top; 8850995Sbostic { 8950995Sbostic static int eof; 9050995Sbostic DBT data; 9150995Sbostic recno_t nrec; 9250995Sbostic size_t len; 9350995Sbostic int ch; 9450995Sbostic char *p; 9550995Sbostic 9650995Sbostic if (eof) 9750995Sbostic return (RET_SPECIAL); 9850995Sbostic 9950995Sbostic data.data = t->bt_dbuf; 10050995Sbostic data.size = t->bt_reclen; 10150995Sbostic 10250995Sbostic if (t->bt_dbufsz < t->bt_reclen) { 10350995Sbostic if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 10450995Sbostic return (RET_ERROR); 10550995Sbostic t->bt_dbufsz = t->bt_reclen; 10650995Sbostic } 10750995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 10850995Sbostic for (p = t->bt_dbuf;; *p++ = ch) 10950995Sbostic if ((ch = getc(t->bt_rfp)) == EOF || !len--) { 11050995Sbostic if (__rec_iput(t, nrec, &data, 0) 11150995Sbostic != RET_SUCCESS) 11250995Sbostic return (RET_ERROR); 11350995Sbostic break; 11450995Sbostic } 11550995Sbostic if (ch == EOF) 11650995Sbostic break; 11750995Sbostic } 11850995Sbostic if (nrec < top) { 11950995Sbostic eof = 1; 12050995Sbostic return (RET_SPECIAL); 12150995Sbostic } 12250995Sbostic return (RET_SUCCESS); 12350995Sbostic } 12450995Sbostic 12550995Sbostic /* 12650995Sbostic * __REC_VPIPE -- Get variable length records from a pipe. 12750995Sbostic * 12850995Sbostic * Parameters: 12950995Sbostic * t: tree 13050995Sbostic * cnt: records to read 13150995Sbostic * 13250995Sbostic * Returns: 13350995Sbostic * RET_ERROR, RET_SUCCESS 13450995Sbostic */ 13550995Sbostic int 13650995Sbostic __rec_vpipe(t, top) 13750995Sbostic BTREE *t; 13850995Sbostic recno_t top; 13950995Sbostic { 14050995Sbostic static int eof; 14150995Sbostic DBT data; 14250995Sbostic recno_t nrec; 14350995Sbostic index_t len; 14450995Sbostic size_t sz; 14550995Sbostic int bval, ch; 14650995Sbostic char *p; 14750995Sbostic 14850995Sbostic if (eof) 14950995Sbostic return (RET_SPECIAL); 15050995Sbostic 15150995Sbostic bval = t->bt_bval; 15250995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 15350995Sbostic for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) { 15450995Sbostic if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) { 15550995Sbostic data.data = t->bt_dbuf; 15650995Sbostic data.size = p - t->bt_dbuf; 15750995Sbostic if (__rec_iput(t, nrec, &data, 0) 15850995Sbostic != RET_SUCCESS) 15950995Sbostic return (RET_ERROR); 16050995Sbostic break; 16150995Sbostic } 16250995Sbostic if (sz == 0) { 16350995Sbostic len = p - t->bt_dbuf; 16450995Sbostic sz = t->bt_dbufsz += 256; 16550995Sbostic if ((t->bt_dbuf = 16650995Sbostic realloc(t->bt_dbuf, sz)) == NULL) 16750995Sbostic return (RET_ERROR); 16850995Sbostic p = t->bt_dbuf + len; 16950995Sbostic } 17050995Sbostic } 17150995Sbostic if (ch == EOF) 17250995Sbostic break; 17350995Sbostic } 17450995Sbostic if (nrec < top) { 17550995Sbostic eof = 1; 17650995Sbostic return (RET_SPECIAL); 17750995Sbostic } 17850995Sbostic return (RET_SUCCESS); 17950995Sbostic } 18050995Sbostic 18150995Sbostic /* 18250995Sbostic * __REC_FMAP -- Get fixed length records from a file. 18350995Sbostic * 18450995Sbostic * Parameters: 18550995Sbostic * t: tree 18650995Sbostic * cnt: records to read 18750995Sbostic * 18850995Sbostic * Returns: 18950995Sbostic * RET_ERROR, RET_SUCCESS 19050995Sbostic */ 19150995Sbostic int 19250995Sbostic __rec_fmap(t, top) 19350995Sbostic BTREE *t; 19450995Sbostic recno_t top; 19550995Sbostic { 19650995Sbostic static int eof; 19750995Sbostic DBT data; 19850995Sbostic recno_t nrec; 19950995Sbostic caddr_t sp, ep; 20050995Sbostic size_t len; 20150995Sbostic char *p; 20250995Sbostic 20350995Sbostic if (eof) 20450995Sbostic return (RET_SPECIAL); 20550995Sbostic 20650995Sbostic sp = t->bt_smap; 20750995Sbostic ep = t->bt_emap; 20850995Sbostic data.data = t->bt_dbuf; 20950995Sbostic data.size = t->bt_reclen; 21050995Sbostic 21150995Sbostic if (t->bt_dbufsz < t->bt_reclen) { 21250995Sbostic if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 21350995Sbostic return (RET_ERROR); 21450995Sbostic t->bt_dbufsz = t->bt_reclen; 21550995Sbostic } 21650995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 21750995Sbostic if (sp >= ep) { 21850995Sbostic eof = 1; 21950995Sbostic return (RET_SPECIAL); 22050995Sbostic } 22150995Sbostic len = t->bt_reclen; 22250995Sbostic for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++); 22350995Sbostic memset(p, t->bt_bval, len); 22450995Sbostic if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 22550995Sbostic return (RET_ERROR); 22650995Sbostic } 22750995Sbostic t->bt_smap = sp; 22850995Sbostic return (RET_SUCCESS); 22950995Sbostic } 23050995Sbostic 23150995Sbostic /* 23250995Sbostic * __REC_VMAP -- Get variable length records from a file. 23350995Sbostic * 23450995Sbostic * Parameters: 23550995Sbostic * t: tree 23650995Sbostic * cnt: records to read 23750995Sbostic * 23850995Sbostic * Returns: 23950995Sbostic * RET_ERROR, RET_SUCCESS 24050995Sbostic */ 24150995Sbostic int 24250995Sbostic __rec_vmap(t, top) 24350995Sbostic BTREE *t; 24450995Sbostic recno_t top; 24550995Sbostic { 24650995Sbostic static int eof; 24750995Sbostic DBT data; 248*51086Sbostic caddr_t sp, ep; 24950995Sbostic recno_t nrec; 25050995Sbostic int bval; 25150995Sbostic 25250995Sbostic if (eof) 25350995Sbostic return (RET_SPECIAL); 25450995Sbostic 25550995Sbostic sp = t->bt_smap; 25650995Sbostic ep = t->bt_emap; 25750995Sbostic bval = t->bt_bval; 25850995Sbostic 25950995Sbostic for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 26050995Sbostic if (sp >= ep) { 26150995Sbostic eof = 1; 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 } 27050995Sbostic t->bt_smap = sp; 27150995Sbostic return (RET_SUCCESS); 27250995Sbostic } 273