s/qmail  3.3.23
Next generation secure email transport
cdb.c
Go to the documentation of this file.
1 /* Public domain. */
2 
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <sys/mman.h>
6 #include "readwrite.h"
7 #include "error.h"
8 #include "seek.h"
9 #include "byte.h"
10 #include "cdb.h"
11 
12 void cdb_free(struct cdb *c)
13 {
14  if (c->map) {
15  munmap(c->map,c->size);
16  c->map = 0;
17  }
18 }
19 
20 void cdb_findstart(struct cdb *c)
21 {
22  c->loop = 0;
23 }
24 
25 void cdb_init(struct cdb *c,int fd)
26 {
27  struct stat st;
28  char *x;
29 
30  cdb_free(c);
31  cdb_findstart(c);
32  c->fd = fd;
33 
34  if (fstat(fd,&st) == 0)
35  if (st.st_size <= 0xffffffff) {
36  x = mmap(0,st.st_size,PROT_READ,MAP_SHARED,fd,0);
37  if (x + 1) {
38  c->size = st.st_size;
39  c->map = x;
40  }
41  }
42 }
43 
44 int cdb_read(struct cdb *c,char *buf,unsigned int len,uint32 pos)
45 {
46  if (c->map) {
47  if ((pos > c->size) || (c->size - pos < len)) goto FORMAT;
48  byte_copy(buf,len,c->map + pos);
49  }
50  else {
51  if (seek_set(c->fd,pos) == -1) return -1;
52  while (len > 0) {
53  int r;
54  do
55  r = read(c->fd,buf,len);
56  while ((r == -1) && (errno == error_intr));
57  if (r == -1) return -1;
58  if (r == 0) goto FORMAT;
59  buf += r;
60  len -= r;
61  }
62  }
63  return 0;
64 
65  FORMAT:
67  return -1;
68 }
69 
70 static int match(struct cdb *c,char *key,unsigned int len,uint32 pos)
71 {
72  char buf[32];
73  int n;
74 
75  while (len > 0) {
76  n = sizeof(buf);
77  if (n > len) n = len;
78  if (cdb_read(c,buf,n,pos) == -1) return -1;
79  if (byte_diff(buf,n,key)) return 0;
80  pos += n;
81  key += n;
82  len -= n;
83  }
84  return 1;
85 }
86 
87 int cdb_findnext(struct cdb *c,char *key,unsigned int len)
88 {
89  char buf[8];
90  uint32 pos;
91  uint32 u;
92 
93  if (!c->loop) {
94  u = cdb_hash(key,len);
95  if (cdb_read(c,buf,8,(u << 3) & 2047) == -1) return -1;
96  uint32_unpack(buf + 4,&c->hslots);
97  if (!c->hslots) return 0;
98  uint32_unpack(buf,&c->hpos);
99  c->khash = u;
100  u >>= 8;
101  u %= c->hslots;
102  u <<= 3;
103  c->kpos = c->hpos + u;
104  }
105 
106  while (c->loop < c->hslots) {
107  if (cdb_read(c,buf,8,c->kpos) == -1) return -1;
108  uint32_unpack(buf + 4,&pos);
109  if (!pos) return 0;
110  c->loop += 1;
111  c->kpos += 8;
112  if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos;
113  uint32_unpack(buf,&u);
114  if (u == c->khash) {
115  if (cdb_read(c,buf,8,pos) == -1) return -1;
116  uint32_unpack(buf,&u);
117  if (u == len)
118  switch(match(c,key,len,pos + 8)) {
119  case -1:
120  return -1;
121  case 1:
122  uint32_unpack(buf + 4,&c->dlen);
123  c->dpos = pos + 8 + len;
124  return 1;
125  }
126  }
127  }
128 
129  return 0;
130 }
131 
132 int cdb_find(struct cdb *c,char *key,unsigned int len)
133 {
134  cdb_findstart(c);
135  return cdb_findnext(c,key,len);
136 }
uint32 kpos
Definition: cdb.h:18
int byte_diff(char *, unsigned int, char *)
void uint32_unpack(char s[4], uint32 *u)
Definition: uint32_unpack.c:3
uint32 hpos
Definition: cdb.h:19
uint32 size
Definition: cdb.h:15
int fd
Definition: idedit.c:16
int fd
Definition: cdb.h:14
int error_proto
Definition: error.c:104
int seek_set()
void c(char *home, char *subdir, char *file, int uid, int gid, int mode)
Definition: install.c:57
void byte_copy(char *, unsigned int, char *)
Definition: cdb.h:12
int cdb_read(struct cdb *c, char *buf, unsigned int len, uint32 pos)
Definition: cdb.c:44
uint32 hslots
Definition: cdb.h:20
stralloc key
Definition: fastforward.c:119
int cdb_find(struct cdb *c, char *key, unsigned int len)
Definition: cdb.c:132
unsigned len
Definition: matchup.c:36
void cdb_free(struct cdb *c)
Definition: cdb.c:12
int errno
uint32 dpos
Definition: cdb.h:21
unsigned x
Definition: matchup.c:36
int error_intr
Definition: error.c:6
uint32 loop
Definition: cdb.h:16
unsigned n
Definition: matchup.c:36
void cdb_init(struct cdb *c, int fd)
Definition: cdb.c:25
uint32 khash
Definition: cdb.h:17
uint32 dlen
Definition: cdb.h:22
unsigned char * buf
Definition: dns.c:41
int cdb_findnext(struct cdb *c, char *key, unsigned int len)
Definition: cdb.c:87
char * map
Definition: cdb.h:13
int match
Definition: matchup.c:181
uint32 cdb_hash(char *, unsigned int)
Definition: cdb_hash.c:11
unsigned u
Definition: matchup.c:36
void cdb_findstart(struct cdb *c)
Definition: cdb.c:20