cdb_seek.c (1783B)
1 #include <sys/types.h> 2 #include <errno.h> 3 #include <unistd.h> 4 #include "cdb.h" 5 6 #ifndef SEEK_SET 7 #define SEEK_SET 0 8 #endif 9 10 int cdb_bread(fd,buf,len) 11 int fd; 12 char *buf; 13 int len; 14 { 15 int r; 16 while (len > 0) { 17 do 18 r = read(fd,buf,len); 19 while ((r == -1) && (errno == EINTR)); 20 if (r == -1) return -1; 21 if (r == 0) { errno = EIO; return -1; } 22 buf += r; 23 len -= r; 24 } 25 return 0; 26 } 27 28 static int match(fd,key,len) 29 int fd; 30 char *key; 31 unsigned int len; 32 { 33 char buf[32]; 34 int n; 35 int i; 36 37 while (len > 0) { 38 n = sizeof(buf); 39 if (n > len) n = len; 40 if (cdb_bread(fd,buf,n) == -1) return -1; 41 for (i = 0;i < n;++i) if (buf[i] != key[i]) return 0; 42 key += n; 43 len -= n; 44 } 45 return 1; 46 } 47 48 int cdb_seek(fd,key,len,dlen) 49 int fd; 50 char *key; 51 unsigned int len; 52 uint32 *dlen; 53 { 54 char packbuf[8]; 55 uint32 pos; 56 uint32 h; 57 uint32 lenhash; 58 uint32 h2; 59 uint32 loop; 60 uint32 poskd; 61 62 h = cdb_hash(key,len); 63 64 pos = 8 * (h & 255); 65 if (lseek(fd,(off_t) pos,SEEK_SET) == -1) return -1; 66 67 if (cdb_bread(fd,packbuf,8) == -1) return -1; 68 69 pos = cdb_unpack(packbuf); 70 lenhash = cdb_unpack(packbuf + 4); 71 72 if (!lenhash) return 0; 73 h2 = (h >> 8) % lenhash; 74 75 for (loop = 0;loop < lenhash;++loop) { 76 if (lseek(fd,(off_t) (pos + 8 * h2),SEEK_SET) == -1) return -1; 77 if (cdb_bread(fd,packbuf,8) == -1) return -1; 78 poskd = cdb_unpack(packbuf + 4); 79 if (!poskd) return 0; 80 if (cdb_unpack(packbuf) == h) { 81 if (lseek(fd,(off_t) poskd,SEEK_SET) == -1) return -1; 82 if (cdb_bread(fd,packbuf,8) == -1) return -1; 83 if (cdb_unpack(packbuf) == len) 84 switch(match(fd,key,len)) { 85 case -1: 86 return -1; 87 case 1: 88 *dlen = cdb_unpack(packbuf + 4); 89 return 1; 90 } 91 } 92 if (++h2 == lenhash) h2 = 0; 93 } 94 return 0; 95 }