11573Srgrimes/*- 214272Spst * Copyright (c) 1990, 1993, 1994 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 4. Neither the name of the University nor the names of its contributors 141573Srgrimes * may be used to endorse or promote products derived from this software 151573Srgrimes * without specific prior written permission. 161573Srgrimes * 171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271573Srgrimes * SUCH DAMAGE. 281573Srgrimes */ 291573Srgrimes 301573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 3114272Spststatic char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94"; 321573Srgrimes#endif /* LIBC_SCCS and not lint */ 3392986Sobrien#include <sys/cdefs.h> 3492986Sobrien__FBSDID("$FreeBSD: releng/10.3/lib/libc/db/recno/rec_get.c 189387 2009-03-05 00:57:01Z delphij $"); 351573Srgrimes 361573Srgrimes#include <sys/types.h> 371573Srgrimes 381573Srgrimes#include <errno.h> 391573Srgrimes#include <stddef.h> 401573Srgrimes#include <stdio.h> 411573Srgrimes#include <stdlib.h> 421573Srgrimes#include <string.h> 431573Srgrimes#include <unistd.h> 441573Srgrimes 451573Srgrimes#include <db.h> 461573Srgrimes#include "recno.h" 471573Srgrimes 481573Srgrimes/* 491573Srgrimes * __REC_GET -- Get a record from the btree. 501573Srgrimes * 511573Srgrimes * Parameters: 521573Srgrimes * dbp: pointer to access method 531573Srgrimes * key: key to find 541573Srgrimes * data: data to return 551573Srgrimes * flag: currently unused 561573Srgrimes * 571573Srgrimes * Returns: 581573Srgrimes * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. 591573Srgrimes */ 601573Srgrimesint 61189291Sdelphij__rec_get(const DB *dbp, const DBT *key, DBT *data, u_int flags) 621573Srgrimes{ 631573Srgrimes BTREE *t; 641573Srgrimes EPG *e; 651573Srgrimes recno_t nrec; 661573Srgrimes int status; 671573Srgrimes 681573Srgrimes t = dbp->internal; 691573Srgrimes 701573Srgrimes /* Toss any page pinned across calls. */ 711573Srgrimes if (t->bt_pinned != NULL) { 721573Srgrimes mpool_put(t->bt_mp, t->bt_pinned, 0); 731573Srgrimes t->bt_pinned = NULL; 741573Srgrimes } 751573Srgrimes 761573Srgrimes /* Get currently doesn't take any flags, and keys of 0 are illegal. */ 771573Srgrimes if (flags || (nrec = *(recno_t *)key->data) == 0) { 781573Srgrimes errno = EINVAL; 791573Srgrimes return (RET_ERROR); 801573Srgrimes } 811573Srgrimes 821573Srgrimes /* 831573Srgrimes * If we haven't seen this record yet, try to find it in the 841573Srgrimes * original file. 851573Srgrimes */ 861573Srgrimes if (nrec > t->bt_nrecs) { 8714272Spst if (F_ISSET(t, R_EOF | R_INMEM)) 881573Srgrimes return (RET_SPECIAL); 891573Srgrimes if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS) 901573Srgrimes return (status); 911573Srgrimes } 921573Srgrimes 931573Srgrimes --nrec; 941573Srgrimes if ((e = __rec_search(t, nrec, SEARCH)) == NULL) 951573Srgrimes return (RET_ERROR); 961573Srgrimes 971573Srgrimes status = __rec_ret(t, e, 0, NULL, data); 9814272Spst if (F_ISSET(t, B_DB_LOCK)) 991573Srgrimes mpool_put(t->bt_mp, e->page, 0); 1001573Srgrimes else 1011573Srgrimes t->bt_pinned = e->page; 1021573Srgrimes return (status); 1031573Srgrimes} 1041573Srgrimes 1051573Srgrimes/* 1061573Srgrimes * __REC_FPIPE -- Get fixed length records from a pipe. 1071573Srgrimes * 1081573Srgrimes * Parameters: 1091573Srgrimes * t: tree 1101573Srgrimes * cnt: records to read 1111573Srgrimes * 1121573Srgrimes * Returns: 1131573Srgrimes * RET_ERROR, RET_SUCCESS 1141573Srgrimes */ 1151573Srgrimesint 116189291Sdelphij__rec_fpipe(BTREE *t, recno_t top) 1171573Srgrimes{ 1181573Srgrimes DBT data; 1191573Srgrimes recno_t nrec; 1201573Srgrimes size_t len; 1211573Srgrimes int ch; 12214272Spst u_char *p; 1231573Srgrimes 12414272Spst if (t->bt_rdata.size < t->bt_reclen) { 125189387Sdelphij t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_reclen); 12614272Spst if (t->bt_rdata.data == NULL) 1271573Srgrimes return (RET_ERROR); 12814272Spst t->bt_rdata.size = t->bt_reclen; 1291573Srgrimes } 13014272Spst data.data = t->bt_rdata.data; 1311573Srgrimes data.size = t->bt_reclen; 1321573Srgrimes 13314272Spst for (nrec = t->bt_nrecs; nrec < top;) { 1341573Srgrimes len = t->bt_reclen; 13514272Spst for (p = t->bt_rdata.data;; *p++ = ch) 13614272Spst if ((ch = getc(t->bt_rfp)) == EOF || !--len) { 13714272Spst if (ch != EOF) 13814272Spst *p = ch; 13914272Spst if (len != 0) 14014272Spst memset(p, t->bt_bval, len); 14114272Spst if (__rec_iput(t, 14214272Spst nrec, &data, 0) != RET_SUCCESS) 1431573Srgrimes return (RET_ERROR); 14414272Spst ++nrec; 1451573Srgrimes break; 1461573Srgrimes } 1471573Srgrimes if (ch == EOF) 1481573Srgrimes break; 1491573Srgrimes } 1501573Srgrimes if (nrec < top) { 15114272Spst F_SET(t, R_EOF); 1521573Srgrimes return (RET_SPECIAL); 1531573Srgrimes } 1541573Srgrimes return (RET_SUCCESS); 1551573Srgrimes} 1561573Srgrimes 1571573Srgrimes/* 1581573Srgrimes * __REC_VPIPE -- Get variable length records from a pipe. 1591573Srgrimes * 1601573Srgrimes * Parameters: 1611573Srgrimes * t: tree 1621573Srgrimes * cnt: records to read 1631573Srgrimes * 1641573Srgrimes * Returns: 1651573Srgrimes * RET_ERROR, RET_SUCCESS 1661573Srgrimes */ 1671573Srgrimesint 168189291Sdelphij__rec_vpipe(BTREE *t, recno_t top) 1691573Srgrimes{ 1701573Srgrimes DBT data; 1711573Srgrimes recno_t nrec; 17268455Sobrien size_t len; 1731573Srgrimes size_t sz; 1741573Srgrimes int bval, ch; 17514272Spst u_char *p; 1761573Srgrimes 1771573Srgrimes bval = t->bt_bval; 1781573Srgrimes for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 17914272Spst for (p = t->bt_rdata.data, 18014272Spst sz = t->bt_rdata.size;; *p++ = ch, --sz) { 1811573Srgrimes if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) { 18214272Spst data.data = t->bt_rdata.data; 18314272Spst data.size = p - (u_char *)t->bt_rdata.data; 1841573Srgrimes if (ch == EOF && data.size == 0) 1851573Srgrimes break; 1861573Srgrimes if (__rec_iput(t, nrec, &data, 0) 1871573Srgrimes != RET_SUCCESS) 1881573Srgrimes return (RET_ERROR); 1891573Srgrimes break; 1901573Srgrimes } 1911573Srgrimes if (sz == 0) { 19214272Spst len = p - (u_char *)t->bt_rdata.data; 19314272Spst t->bt_rdata.size += (sz = 256); 194189387Sdelphij t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_rdata.size); 19514272Spst if (t->bt_rdata.data == NULL) 1961573Srgrimes return (RET_ERROR); 19714272Spst p = (u_char *)t->bt_rdata.data + len; 1981573Srgrimes } 1991573Srgrimes } 2001573Srgrimes if (ch == EOF) 2011573Srgrimes break; 2021573Srgrimes } 2031573Srgrimes if (nrec < top) { 20414272Spst F_SET(t, R_EOF); 2051573Srgrimes return (RET_SPECIAL); 2061573Srgrimes } 2071573Srgrimes return (RET_SUCCESS); 2081573Srgrimes} 2091573Srgrimes 2101573Srgrimes/* 2111573Srgrimes * __REC_FMAP -- Get fixed length records from a file. 2121573Srgrimes * 2131573Srgrimes * Parameters: 2141573Srgrimes * t: tree 2151573Srgrimes * cnt: records to read 2161573Srgrimes * 2171573Srgrimes * Returns: 2181573Srgrimes * RET_ERROR, RET_SUCCESS 2191573Srgrimes */ 2201573Srgrimesint 221189291Sdelphij__rec_fmap(BTREE *t, recno_t top) 2221573Srgrimes{ 2231573Srgrimes DBT data; 2241573Srgrimes recno_t nrec; 22514272Spst u_char *sp, *ep, *p; 2261573Srgrimes size_t len; 2271573Srgrimes 22814272Spst if (t->bt_rdata.size < t->bt_reclen) { 229189387Sdelphij t->bt_rdata.data = reallocf(t->bt_rdata.data, t->bt_reclen); 23014272Spst if (t->bt_rdata.data == NULL) 2311573Srgrimes return (RET_ERROR); 23214272Spst t->bt_rdata.size = t->bt_reclen; 2331573Srgrimes } 23414272Spst data.data = t->bt_rdata.data; 2351573Srgrimes data.size = t->bt_reclen; 2361573Srgrimes 23714272Spst sp = (u_char *)t->bt_cmap; 23814272Spst ep = (u_char *)t->bt_emap; 2391573Srgrimes for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 2401573Srgrimes if (sp >= ep) { 24114272Spst F_SET(t, R_EOF); 2421573Srgrimes return (RET_SPECIAL); 2431573Srgrimes } 2441573Srgrimes len = t->bt_reclen; 24514272Spst for (p = t->bt_rdata.data; 24614272Spst sp < ep && len > 0; *p++ = *sp++, --len); 24714272Spst if (len != 0) 24814272Spst memset(p, t->bt_bval, len); 2491573Srgrimes if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 2501573Srgrimes return (RET_ERROR); 2511573Srgrimes } 25214272Spst t->bt_cmap = (caddr_t)sp; 2531573Srgrimes return (RET_SUCCESS); 2541573Srgrimes} 2551573Srgrimes 2561573Srgrimes/* 2571573Srgrimes * __REC_VMAP -- Get variable length records from a file. 2581573Srgrimes * 2591573Srgrimes * Parameters: 2601573Srgrimes * t: tree 2611573Srgrimes * cnt: records to read 2621573Srgrimes * 2631573Srgrimes * Returns: 2641573Srgrimes * RET_ERROR, RET_SUCCESS 2651573Srgrimes */ 2661573Srgrimesint 267189291Sdelphij__rec_vmap(BTREE *t, recno_t top) 2681573Srgrimes{ 2691573Srgrimes DBT data; 27014272Spst u_char *sp, *ep; 2711573Srgrimes recno_t nrec; 2721573Srgrimes int bval; 2731573Srgrimes 27414272Spst sp = (u_char *)t->bt_cmap; 27514272Spst ep = (u_char *)t->bt_emap; 2761573Srgrimes bval = t->bt_bval; 2771573Srgrimes 2781573Srgrimes for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 2791573Srgrimes if (sp >= ep) { 28014272Spst F_SET(t, R_EOF); 2811573Srgrimes return (RET_SPECIAL); 2821573Srgrimes } 2831573Srgrimes for (data.data = sp; sp < ep && *sp != bval; ++sp); 28414272Spst data.size = sp - (u_char *)data.data; 2851573Srgrimes if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 2861573Srgrimes return (RET_ERROR); 2871573Srgrimes ++sp; 2881573Srgrimes } 28914272Spst t->bt_cmap = (caddr_t)sp; 2901573Srgrimes return (RET_SUCCESS); 2911573Srgrimes} 292