1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)rec_get.c 5.2 (Berkeley) 09/11/91"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/types.h> 13 #include <errno.h> 14 #include <db.h> 15 #include <unistd.h> 16 #include <stddef.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include "recno.h" 21 22 /* 23 * __REC_GET -- Get a record from the btree. 24 * 25 * Parameters: 26 * dbp: pointer to access method 27 * key: key to find 28 * data: data to return 29 * flag: currently unused 30 * 31 * Returns: 32 * RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found. 33 */ 34 int 35 __rec_get(dbp, key, data, flags) 36 const DB *dbp; 37 const DBT *key; 38 DBT *data; 39 u_int flags; 40 { 41 BTREE *t; 42 EPG *e; 43 recno_t nrec; 44 int exact, status; 45 46 if (flags || (nrec = *(recno_t *)key->data) == 0) { 47 errno = EINVAL; 48 return (RET_ERROR); 49 } 50 51 /* 52 * If we haven't seen this record yet, try to find it in the 53 * original file. 54 */ 55 t = dbp->internal; 56 if (nrec > t->bt_nrecs && 57 (status = t->bt_irec(t, nrec)) != RET_SUCCESS) 58 return (status); 59 60 --nrec; 61 if ((e = __rec_search(t, nrec, SEARCH)) == NULL) 62 return (RET_ERROR); 63 64 if (!exact) { 65 mpool_put(t->bt_mp, e->page, 0); 66 return (RET_SPECIAL); 67 } 68 69 status = __rec_ret(t, e, data); 70 mpool_put(t->bt_mp, e->page, 0); 71 return (status); 72 } 73 74 /* 75 * __REC_FPIPE -- Get fixed length records from a pipe. 76 * 77 * Parameters: 78 * t: tree 79 * cnt: records to read 80 * 81 * Returns: 82 * RET_ERROR, RET_SUCCESS 83 */ 84 int 85 __rec_fpipe(t, top) 86 BTREE *t; 87 recno_t top; 88 { 89 static int eof; 90 DBT data; 91 recno_t nrec; 92 size_t len; 93 int ch; 94 char *p; 95 96 if (eof) 97 return (RET_SPECIAL); 98 99 data.data = t->bt_dbuf; 100 data.size = t->bt_reclen; 101 102 if (t->bt_dbufsz < t->bt_reclen) { 103 if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 104 return (RET_ERROR); 105 t->bt_dbufsz = t->bt_reclen; 106 } 107 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 108 for (p = t->bt_dbuf;; *p++ = ch) 109 if ((ch = getc(t->bt_rfp)) == EOF || !len--) { 110 if (__rec_iput(t, nrec, &data, 0) 111 != RET_SUCCESS) 112 return (RET_ERROR); 113 break; 114 } 115 if (ch == EOF) 116 break; 117 } 118 if (nrec < top) { 119 eof = 1; 120 return (RET_SPECIAL); 121 } 122 return (RET_SUCCESS); 123 } 124 125 /* 126 * __REC_VPIPE -- Get variable length records from a pipe. 127 * 128 * Parameters: 129 * t: tree 130 * cnt: records to read 131 * 132 * Returns: 133 * RET_ERROR, RET_SUCCESS 134 */ 135 int 136 __rec_vpipe(t, top) 137 BTREE *t; 138 recno_t top; 139 { 140 static int eof; 141 DBT data; 142 recno_t nrec; 143 index_t len; 144 size_t sz; 145 int bval, ch; 146 char *p; 147 148 if (eof) 149 return (RET_SPECIAL); 150 151 bval = t->bt_bval; 152 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 153 for (p = t->bt_dbuf, sz = t->bt_dbufsz;; *p++ = ch, --sz) { 154 if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) { 155 data.data = t->bt_dbuf; 156 data.size = p - t->bt_dbuf; 157 if (__rec_iput(t, nrec, &data, 0) 158 != RET_SUCCESS) 159 return (RET_ERROR); 160 break; 161 } 162 if (sz == 0) { 163 len = p - t->bt_dbuf; 164 sz = t->bt_dbufsz += 256; 165 if ((t->bt_dbuf = 166 realloc(t->bt_dbuf, sz)) == NULL) 167 return (RET_ERROR); 168 p = t->bt_dbuf + len; 169 } 170 } 171 if (ch == EOF) 172 break; 173 } 174 if (nrec < top) { 175 eof = 1; 176 return (RET_SPECIAL); 177 } 178 return (RET_SUCCESS); 179 } 180 181 /* 182 * __REC_FMAP -- Get fixed length records from a file. 183 * 184 * Parameters: 185 * t: tree 186 * cnt: records to read 187 * 188 * Returns: 189 * RET_ERROR, RET_SUCCESS 190 */ 191 int 192 __rec_fmap(t, top) 193 BTREE *t; 194 recno_t top; 195 { 196 static int eof; 197 DBT data; 198 recno_t nrec; 199 caddr_t sp, ep; 200 size_t len; 201 char *p; 202 203 if (eof) 204 return (RET_SPECIAL); 205 206 sp = t->bt_smap; 207 ep = t->bt_emap; 208 data.data = t->bt_dbuf; 209 data.size = t->bt_reclen; 210 211 if (t->bt_dbufsz < t->bt_reclen) { 212 if ((t->bt_dbuf = realloc(t->bt_dbuf, t->bt_reclen)) == NULL) 213 return (RET_ERROR); 214 t->bt_dbufsz = t->bt_reclen; 215 } 216 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 217 if (sp >= ep) { 218 eof = 1; 219 return (RET_SPECIAL); 220 } 221 len = t->bt_reclen; 222 for (p = t->bt_dbuf; sp < ep && len--; *p++ = *sp++); 223 memset(p, t->bt_bval, len); 224 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 225 return (RET_ERROR); 226 } 227 t->bt_smap = sp; 228 return (RET_SUCCESS); 229 } 230 231 /* 232 * __REC_VMAP -- Get variable length records from a file. 233 * 234 * Parameters: 235 * t: tree 236 * cnt: records to read 237 * 238 * Returns: 239 * RET_ERROR, RET_SUCCESS 240 */ 241 int 242 __rec_vmap(t, top) 243 BTREE *t; 244 recno_t top; 245 { 246 static int eof; 247 DBT data; 248 caddr_t sp, ep; 249 recno_t nrec; 250 int bval; 251 252 if (eof) 253 return (RET_SPECIAL); 254 255 sp = t->bt_smap; 256 ep = t->bt_emap; 257 bval = t->bt_bval; 258 259 for (nrec = t->bt_nrecs; nrec < top; ++nrec) { 260 if (sp >= ep) { 261 eof = 1; 262 return (RET_SPECIAL); 263 } 264 for (data.data = sp; sp < ep && *sp != bval; ++sp); 265 data.size = sp - (caddr_t)data.data; 266 if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS) 267 return (RET_ERROR); 268 ++sp; 269 } 270 t->bt_smap = sp; 271 return (RET_SUCCESS); 272 } 273