2 /* Adapted from DJB's original cdb-0.75 package */
13 #define EPROTO -15 /* cdb 0.75's default for PROTOless systems */
16 void cdb_free(struct cdb
*c
)
19 munmap(c
->map
,c
->size
);
24 void cdb_findstart(struct cdb
*c
)
29 void cdb_init(struct cdb
*c
,int fd
)
38 if (fstat(fd
,&st
) == 0)
39 if (st
.st_size
<= 0xffffffff) {
40 x
= mmap(0,st
.st_size
,PROT_READ
,MAP_SHARED
,fd
,0);
48 int cdb_read(struct cdb
*c
,char *buf
,unsigned int len
,uint32 pos
)
51 if ((pos
> c
->size
) || (c
->size
- pos
< len
)) goto FORMAT
;
52 memcpy(buf
,c
->map
+ pos
,len
);
55 if (lseek(c
->fd
,pos
,SEEK_SET
) == -1) return -1;
56 /* if (seek_set(c->fd,pos) == -1) return -1; */
60 r
= read(c
->fd
,buf
,len
);
61 while ((r
== -1) && (errno
== EINTR
));
62 if (r
== -1) return -1;
63 if (r
== 0) goto FORMAT
;
75 static int match(struct cdb
*c
,char *key
,unsigned int len
,uint32 pos
)
83 if (cdb_read(c
,buf
,n
,pos
) == -1) return -1;
84 if (memcmp(buf
,key
,n
)) return 0;
92 int cdb_findnext(struct cdb
*c
,char *key
,unsigned int len
)
99 u
= cdb_hash(key
,len
);
100 if (cdb_read(c
,buf
,8,(u
<< 3) & 2047) == -1) return -1;
101 uint32_unpack(buf
+ 4,&c
->hslots
);
102 if (!c
->hslots
) return 0;
103 uint32_unpack(buf
,&c
->hpos
);
108 c
->kpos
= c
->hpos
+ u
;
111 while (c
->loop
< c
->hslots
) {
112 if (cdb_read(c
,buf
,8,c
->kpos
) == -1) return -1;
113 uint32_unpack(buf
+ 4,&pos
);
117 if (c
->kpos
== c
->hpos
+ (c
->hslots
<< 3)) c
->kpos
= c
->hpos
;
118 uint32_unpack(buf
,&u
);
120 if (cdb_read(c
,buf
,8,pos
) == -1) return -1;
121 uint32_unpack(buf
,&u
);
123 switch(match(c
,key
,len
,pos
+ 8)) {
127 uint32_unpack(buf
+ 4,&c
->dlen
);
128 c
->dpos
= pos
+ 8 + len
;
137 int cdb_find(struct cdb
*c
,char *key
,unsigned int len
)
140 return cdb_findnext(c
,key
,len
);