81ab6ad5d390b53c6e76aeb811ccbb8b1fe16a20
[ezmlm] / issub.c
1 #include "stralloc.h"
2 #include "getln.h"
3 #include "readwrite.h"
4 #include "substdio.h"
5 #include "open.h"
6 #include "byte.h"
7 #include "case.h"
8 #include "lock.h"
9 #include "error.h"
10 #include "issub.h"
11 #include "uint32.h"
12
13 static stralloc addr = {0};
14 static stralloc line = {0};
15 static stralloc fn = {0};
16 static int fd;
17 static substdio ss;
18 static char ssbuf[256];
19
20 static int doit(userhost)
21 char *userhost;
22 {
23 int j;
24 uint32 h;
25 char ch;
26 int match;
27
28 if (!stralloc_copys(&addr,"T")) return -2;
29 if (!stralloc_cats(&addr,userhost)) return -2;
30
31 j = byte_rchr(addr.s,addr.len,'@');
32 if (j == addr.len) return 0;
33 case_lowerb(addr.s + j + 1,addr.len - j - 1);
34
35 h = 5381;
36 for (j = 0;j < addr.len;++j)
37 h = (h + (h << 5)) ^ (uint32) (unsigned char) addr.s[j];
38 ch = 64 + (h % 53);
39
40 if (!stralloc_0(&addr)) return -2;
41
42 if (!stralloc_copys(&fn,"subscribers/")) return -2;
43 if (!stralloc_catb(&fn,&ch,1)) return -2;
44 if (!stralloc_0(&fn)) return -2;
45
46 fd = open_read(fn.s);
47 if (fd == -1) {
48 if (errno != error_noent) return -3;
49 return 0;
50 }
51 substdio_fdbuf(&ss,read,fd,ssbuf,sizeof(ssbuf));
52
53 for (;;) {
54 if (getln(&ss,&line,&match,'\0') == -1) { close(fd); return -3; }
55 if (!match) break;
56 if (line.len == addr.len)
57 if (!byte_diff(line.s,line.len,addr.s)) { close(fd); return 1; }
58 }
59
60 close(fd);
61 return 0;
62 }
63
64 struct strerr issub_err;
65
66 int issub(userhost)
67 char *userhost;
68 {
69 int fdlock;
70 int r;
71
72 fdlock = open_append("lock");
73 if (fdlock == -1)
74 STRERR_SYS(-1,issub_err,"unable to open lock: ")
75 if (lock_ex(fdlock) == -1) {
76 close(fdlock);
77 STRERR_SYS(-1,issub_err,"unable to obtain lock: ")
78 }
79
80 r = doit(userhost);
81 close(fdlock);
82
83 if (r == -2) STRERR(-1,issub_err,"out of memory")
84 if (r == -3) STRERR_SYS3(-1,issub_err,"unable to read ",fn.s,": ")
85
86 return r;
87 }