ezmlmx 0.68
ezmlmx
Loading...
Searching...
No Matches
issub.c
Go to the documentation of this file.
1#include <unistd.h>
2#include "stralloc.h"
3#include "getln.h"
4#include "readwrite.h"
5#include "buffer.h"
6#include "open.h"
7#include "byte.h"
8#include "case.h"
9#include "error.h"
10#include "uint_t.h"
11#include "fmt.h"
12#include "subscribe.h"
13#include "errtxt.h"
14#include "idx.h"
15#include "logmsg.h"
16
17#define WHO "issub"
18
24
25static stralloc addr = {0};
26static stralloc lcaddr = {0};
27static stralloc line = {0};
28static stralloc fn = {0};
29static buffer bi;
30static char inbuf[512];
31
32static void die_nomem() { logmsg(WHO,111,FATAL,ERR_NOMEM); }
33
43
44
45const char *issub(const char *dbname,const char *userhost,const char *tab)
46{
47
48 int fd;
49 unsigned int j;
50 uint32 h, lch;
51 char ch, lcch;
52 int match;
53
54 if (!stralloc_copys(&addr,"T")) die_nomem();
55 if (!stralloc_cats(&addr,userhost)) die_nomem();
56
57 j = byte_rchr(addr.s,addr.len,'@');
58 if (j == addr.len) return (char *) 0;
59 case_lowerb(addr.s + j + 1,addr.len - j - 1);
60 if (!stralloc_copy(&lcaddr,&addr)) die_nomem();
61 case_lowerb(lcaddr.s + 1,j - 1); /* totally lc version of addr */
62
63 h = 5381;
64 lch = h; /* make hash for both for backwards comp */
65 for (j = 0; j < addr.len; ++j) { /* (lcaddr.len == addr.len) */
66 h = (h + (h << 5)) ^ (uint32) (unsigned char) addr.s[j];
67 lch = (lch + (lch << 5)) ^ (uint32) (unsigned char) lcaddr.s[j];
68 }
69 ch = 64 + (h % 53);
70 lcch = 64 + (lch % 53);
71
72 if (!stralloc_0(&addr)) die_nomem();
73 if (!stralloc_0(&lcaddr)) die_nomem();
74 if (!stralloc_copys(&fn,dbname)) die_nomem();
75 if (!stralloc_cats(&fn,"/subscribers/")) die_nomem();
76 if (!stralloc_catb(&fn,&lcch,1)) die_nomem();
77 if (!stralloc_0(&fn)) die_nomem();
78
79 fd = open_read(fn.s);
80 if (fd == -1) {
81 if (errno != ENOENT)
82 logmsg(WHO,111,FATAL,B(ERR_OPEN,fn.s));
83 } else {
84 buffer_init(&bi,buffer_unixread,fd,inbuf,sizeof(inbuf));
85
86 for (;;) {
87 if (getln(&bi,&line,&match,'\0') == -1)
88 logmsg(WHO,111,FATAL,B(ERR_READ,fn.s));
89 if (!match) break;
90 if (line.len == lcaddr.len)
91 if (!case_diffb(line.s,line.len,lcaddr.s))
92 { close(fd); return line.s + 1; }
93 }
94
95 close(fd);
96 }
97 /* here if file not found or (file found && addr not there) */
98
99 if (ch == lcch) return (char *) 0;
100
101 /* try case sensitive hash for backwards compatibility */
102 fn.s[fn.len - 2] = ch;
103 fd = open_read(fn.s);
104 if (fd == -1) {
105 if (errno != ENOENT)
106 logmsg(WHO,111,FATAL,B(ERR_OPEN,fn.s));
107 return (char *) 0;
108 }
109 buffer_init(&bi,buffer_unixread,fd,inbuf,sizeof(inbuf));
110
111 for (;;) {
112 if (getln(&bi,&line,&match,'\0') == -1)
113 logmsg(WHO,111,FATAL,B(ERR_READ,fn.s));
114 if (!match) break;
115 if (line.len == addr.len)
116 if (!case_diffb(line.s,line.len,addr.s))
117 { close(fd); return line.s + 1; }
118 }
119
120 close(fd);
121
122 return (char *) 0;
123}
int issub()
Returns (char *) to match if userhost is in the subscriber database dbname, 0 otherwise....
Error messages. If you translate these, I would urge you to keep the English version as well....
#define ERR_NOMEM
Definition errtxt.h:14
#define ERR_OPEN
Definition errtxt.h:30
#define ERR_READ
Definition errtxt.h:18
void die_nomem()
Definition getconf.c:17
#define WHO
Definition author.c:1
stralloc fn
char inbuf[1024]
buffer bi
char * userhost
stralloc addr
Definition ezmlm-cron.c:45
int fd
Definition ezmlm-cgi.c:141
int match
Definition ezmlm-cgi.c:140
const char * logmsg(const char *dir, unsigned long num, unsigned long listno, unsigned long subs, int done)
Definition loginfo.c:32