11 #include "subscribe.h"
16 static char inbuf[512];
17 char strnum[FMT_ULONG];
18 static stralloc line = {0};
19 static stralloc domains = {0};
20 static stralloc quoted = {0};
21 static stralloc fn = {0};
23 static void die_nomem(fatal)
26 strerr_die2x(111,fatal,ERR_NOMEM);
29 static void die_write(fatal)
32 strerr_die3x(111,fatal,ERR_WRITE,"stdout");
35 unsigned long putsubs(dbname,hash_lo,hash_hi,
36 subwrite,flagsql,fatal)
37 /* Outputs all userhostesses in 'dbname' to stdout. If userhost is not null */
38 /* that userhost is excluded. 'dbname' is the base directory name. For the */
39 /* mysql version, dbname is the directory where the file "sql" with mysql */
40 /* access info is found. If this file is not present or if flagmysql is not */
41 /* set, the routine falls back to the old database style. subwrite must be a*/
42 /* function returning >=0 on success, -1 on error, and taking arguments */
43 /* (char* string, unsigned int length). It will be called once per address */
44 /* and should take care of newline or whatever needed for the output form. */
46 char *dbname; /* database base dir */
47 unsigned long hash_lo;
48 unsigned long hash_hi;
49 int subwrite(); /* write function. */
51 char *fatal; /* fatal error string */
56 char *table = (char *) 0;
57 unsigned long *lengths;
61 unsigned long no = 0L;
65 char *ret = (char *) 0;
67 if (!flagsql || (ret = opensql(dbname,&table))) {
68 if (flagsql && *ret) strerr_die2x(111,fatal,ret);
69 /* fallback to local db */
70 if (!stralloc_copys(&fn,dbname)) die_nomem(fatal);
71 if (!stralloc_catb(&fn,"/subscribers/?",15)) die_nomem(fatal);
72 /* NOTE: Also copies terminal '\0' */
74 if (hash_lo > 52) hash_lo = 52;
75 if (hash_hi > 52) hash_hi = 52;
76 if (hash_hi < hash_lo) hash_hi = hash_lo;
78 for (i = hash_lo;i <= hash_hi;++i) {
79 fn.s[hashpos] = 64 + i; /* hash range 0-52 */
82 if (errno != error_noent)
83 strerr_die4sys(111,fatal,ERR_READ,fn.s,": ");
85 substdio_fdbuf(&ssin,read,fd,inbuf,sizeof(inbuf));
87 if (getln(&ssin,&line,&match,'\0') == -1)
88 strerr_die4sys(111,fatal,ERR_READ,fn.s,": ");
91 if (subwrite(line.s + 1,line.len - 2) == -1) die_write(fatal);
99 } else { /* SQL Version */
102 if (!stralloc_copys(&line,"SELECT address FROM "))
104 if (!stralloc_cats(&line,table)) die_nomem(fatal);
105 if (!stralloc_cats(&line," WHERE hash BETWEEN ")) die_nomem(fatal);
106 if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,hash_lo)))
108 if (!stralloc_cats(&line," AND ")) die_nomem(fatal);
109 if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,hash_hi)))
111 if (mysql_real_query((MYSQL *) psql,line.s,line.len)) /* query */
112 strerr_die2x(111,fatal,mysql_error((MYSQL *) psql));
113 if (!(result = mysql_use_result((MYSQL *) psql)))
114 strerr_die2x(111,fatal,mysql_error((MYSQL *) psql));
116 while ((row = mysql_fetch_row(result))) {
117 /* this is safe even if someone messes with the address field def */
118 if (!(lengths = mysql_fetch_lengths(result)))
119 strerr_die2x(111,fatal,mysql_error((MYSQL *) psql));
120 if (subwrite(row[0],lengths[0]) == -1) die_write(fatal);
121 no++; /* count for list-list fxn */
123 if (!mysql_eof(result))
124 strerr_die2x(111,fatal,mysql_error((MYSQL *) psql));
125 mysql_free_result(result);