11 #include "subscribe.h"
17 static char inbuf
[512];
18 char strnum
[FMT_ULONG
];
19 static stralloc line
= {0};
20 static stralloc fn
= {0};
22 static void die_nomem(fatal
)
25 strerr_die2x(111,fatal
,ERR_NOMEM
);
28 static void die_write(fatal
)
31 strerr_die3x(111,fatal
,ERR_WRITE
,"stdout");
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. For the */
38 /* mysql version, dbname is the directory where the file "sql" with mysql */
39 /* access info is found. If this file is not present or if flagmysql is not */
40 /* set, the routine falls back to the old database style. subwrite must be a*/
41 /* function returning >=0 on success, -1 on error, and taking arguments */
42 /* (char* string, unsigned int length). It will be called once per address */
43 /* and should take care of newline or whatever needed for the output form. */
45 char *dbname
; /* database base dir */
46 unsigned long hash_lo
;
47 unsigned long hash_hi
;
48 int subwrite(); /* write function. */
50 char *fatal
; /* fatal error string */
57 char *table
= (char *) 0;
61 unsigned long no
= 0L;
64 char *ret
= (char *) 0;
66 if (!flagsql
|| (ret
= opensql(dbname
,&table
))) {
67 if (flagsql
&& *ret
) strerr_die2x(111,fatal
,ret
);
68 /* fallback to local db */
69 if (!stralloc_copys(&fn
,dbname
)) die_nomem(fatal
);
70 if (!stralloc_catb(&fn
,"/subscribers/?",15)) die_nomem(fatal
);
71 /* NOTE: Also copies terminal '\0' */
73 if (hash_lo
> 52) hash_lo
= 52;
74 if (hash_hi
> 52) hash_hi
= 52;
75 if (hash_hi
< hash_lo
) hash_hi
= hash_lo
;
77 for (i
= hash_lo
;i
<= hash_hi
;++i
) {
78 fn
.s
[hashpos
] = 64 + i
; /* hash range 0-52 */
81 if (errno
!= error_noent
)
82 strerr_die4sys(111,fatal
,ERR_READ
,fn
.s
,": ");
84 substdio_fdbuf(&ssin
,read
,fd
,inbuf
,sizeof(inbuf
));
86 if (getln(&ssin
,&line
,&match
,'\0') == -1)
87 strerr_die4sys(111,fatal
,ERR_READ
,fn
.s
,": ");
90 if (subwrite(line
.s
+ 1,line
.len
- 2) == -1) die_write(fatal
);
98 } else { /* SQL Version */
101 if (!stralloc_copys(&line
,"SELECT address FROM "))
103 if (!stralloc_cats(&line
,table
)) die_nomem(fatal
);
104 if (!stralloc_cats(&line
," WHERE hash BETWEEN ")) die_nomem(fatal
);
105 if (!stralloc_catb(&line
,strnum
,fmt_ulong(strnum
,hash_lo
)))
107 if (!stralloc_cats(&line
," AND ")) die_nomem(fatal
);
108 if (!stralloc_catb(&line
,strnum
,fmt_ulong(strnum
,hash_hi
)))
110 if (!stralloc_0(&line
)) die_nomem(fatal
);
111 result
= PQexec(psql
,line
.s
);
113 strerr_die2x(111,fatal
,PQerrorMessage(psql
));
114 if (PQresultStatus(result
) != PGRES_TUPLES_OK
)
115 strerr_die2x(111,fatal
,PQresultErrorMessage(result
));
118 for (row_nr
=0;row_nr
<PQntuples(result
);row_nr
++) {
119 /* this is safe even if someone messes with the address field def */
120 length
= PQgetlength(result
,row_nr
,0);
121 row
= PQgetvalue(result
,row_nr
,0);
122 if (subwrite(row
,length
) == -1) die_write(fatal
);
123 no
++; /* count for list-list fxn */