Import ezmlm-idx 0.40
[ezmlm] / sub_std / putsubs.c
1 #include "error.h"
2 #include "strerr.h"
3 #include "readwrite.h"
4 #include "str.h"
5 #include "fmt.h"
6 #include "stralloc.h"
7 #include "open.h"
8 #include "substdio.h"
9 #include "case.h"
10 #include "errtxt.h"
11 #include "subscribe.h"
12 #include "qmail.h"
13
14 static substdio ssin;
15 static char inbuf[512];
16 char strnum[FMT_ULONG];
17 static stralloc line = {0};
18 static stralloc domains = {0};
19 static stralloc quoted = {0};
20 static stralloc fn = {0};
21
22 static void die_nomem(fatal)
23 char *fatal;
24 {
25 strerr_die2x(111,fatal,ERR_NOMEM);
26 }
27
28 static void die_write(fatal)
29 char *fatal;
30 {
31 strerr_die3x(111,fatal,ERR_WRITE,"stdout");
32 }
33
34 unsigned long putsubs(dbname,hash_lo,hash_hi,
35 subwrite,flagsql,fatal)
36 /* Outputs all userhostesses in 'dbname' to stdout. If userhost is not null */
37 /* that userhost is excluded. 'dbname' is the base directory name. */
38 /* subwrite must be a*/
39 /* function returning >=0 on success, -1 on error, and taking arguments */
40 /* (char* string, unsigned int length). It will be called once per address */
41 /* and should take care of newline or whatever needed for the output form. */
42
43 char *dbname; /* database base dir */
44 unsigned long hash_lo;
45 unsigned long hash_hi;
46 int subwrite(); /* write function. */
47 int flagsql;
48 char *fatal; /* fatal error string */
49
50 {
51
52 unsigned int i;
53 int fd;
54 unsigned long no = 0L;
55 int match;
56 unsigned int hashpos;
57
58 if (!stralloc_copys(&fn,dbname)) die_nomem(fatal);
59 if (!stralloc_catb(&fn,"/subscribers/?",15)) die_nomem(fatal);
60 /* NOTE: Also copies terminal '\0' */
61 hashpos = fn.len - 2;
62 if (hash_lo > 52) hash_lo = 52;
63 if (hash_hi > 52) hash_hi = 52;
64 if (hash_hi < hash_lo) hash_hi = hash_lo;
65
66 for (i = hash_lo;i <= hash_hi;++i) {
67 fn.s[hashpos] = 64 + i; /* hash range 0-52 */
68 fd = open_read(fn.s);
69 if (fd == -1) {
70 if (errno != error_noent)
71 strerr_die4sys(111,fatal,ERR_READ,fn.s,": ");
72 } else {
73 substdio_fdbuf(&ssin,read,fd,inbuf,sizeof(inbuf));
74 for (;;) {
75 if (getln(&ssin,&line,&match,'\0') == -1)
76 strerr_die4sys(111,fatal,ERR_READ,fn.s,": ");
77 if (!match)
78 break;
79 if (subwrite(line.s + 1,line.len - 2) == -1) die_write(fatal);
80 no++;
81 }
82 close(fd);
83 }
84 }
85 return no;
86 }