ezmlmx 0.68
ezmlmx
Loading...
Searching...
No Matches
putsubs.c
Go to the documentation of this file.
1#include "getln.h"
2#include "error.h"
3#include "logmsg.h"
4#include "readwrite.h"
5#include "str.h"
6#include "fmt.h"
7#include "stralloc.h"
8#include "open.h"
9#include "buffer.h"
10#include "case.h"
11#include "errtxt.h"
12#include "subscribe.h"
13#include "qmail.h"
14#include "idx.h"
15#include <unistd.h>
16#include <libpq-fe.h>
17
23
24extern PGconn *pgsql;
25
26static buffer bi;
27static char inbuf[512];
28char strnum[FMT_ULONG];
29static stralloc line = {0};
30static stralloc fn = {0};
31
32static void die_write(void) { logmsg(WHO,111,FATAL,B("ERR_WRITE :","stdout")); }
33
49
50unsigned long putsubs(const char *dbname,unsigned long hash_lo,unsigned long hash_hi,int subwrite(),int flagsql)
51{
52 PGresult *result;
53 int row_nr;
54 int length;
55 char *row;
56 const char *table = (char *) 0;
57
58 unsigned int i;
59 int fd;
60 unsigned long no = 0L;
61 int match;
62 unsigned int hashpos;
63 const char *ret = (char *) 0;
64
65 if (!flagsql || (ret = opensql(dbname,&table))) {
66 if (flagsql && *ret) logmsg(WHO,111,FATAL,ret); /* fallback to local db */
67
68 if (!stralloc_copys(&fn,dbname)) die_nomem();
69 if (!stralloc_catb(&fn,"/subscribers/?",15)) die_nomem(); /* NOTE: Also copies terminal '\0' */
70 hashpos = fn.len - 2;
71 if (hash_lo > 52) hash_lo = 52;
72 if (hash_hi > 52) hash_hi = 52;
74
75 for (i = hash_lo; i <= hash_hi; ++i) {
76 fn.s[hashpos] = 64 + i; /* hash range 0-52 */
77 fd = open_read(fn.s);
78 if (fd == -1) {
79 if (errno != ENOENT)
80 logmsg(WHO,111,FATAL,B("ERR_READ :",fn.s));
81 } else {
82 buffer_init(&bi,buffer_unixread,fd,inbuf,sizeof(inbuf));
83
84 for (;;) {
85 if (getln(&bi,&line,&match,'\0') == -1)
86 logmsg(WHO,111,FATAL,B("ERR_READ :",fn.s));
87 if (!match)
88 break;
89 if (subwrite(line.s + 1,line.len - 2) == -1) die_write();
90 no++;
91 }
92 close(fd);
93 }
94 }
95 return no;
96
97 } else { /* SQL Version main query */
98 if (!stralloc_copys(&line,"SELECT address FROM ")) die_nomem();
99 if (!stralloc_cats(&line,table)) die_nomem();
100 if (!stralloc_cats(&line," WHERE hash BETWEEN ")) die_nomem();
101 if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,hash_lo))) die_nomem();
102 if (!stralloc_cats(&line," AND ")) die_nomem();
103 if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,hash_hi))) die_nomem();
104 if (!stralloc_0(&line)) die_nomem();
105
106 result = PQexec(pgsql,line.s);
107 if (result == NULL)
108 logmsg(WHO,111,FATAL,PQerrorMessage(pgsql));
109
110 if (PQresultStatus(result) != PGRES_TUPLES_OK)
111 logmsg(WHO,111,FATAL,PQresultErrorMessage(result));
112
113 /* Next statements are safe even if someone messes with the address field def */
114
115 no = 0;
116 for (row_nr = 0; row_nr < PQntuples(result); row_nr++) {
117 length = PQgetlength(result,row_nr,0);
118 row = PQgetvalue(result,row_nr,0);
119 if (subwrite(row,length) == -1) die_write();
120 no++; /* count for list-list fxn */
121 }
122 PQclear(result);
123 return no;
124 }
125}
Error messages. If you translate these, I would urge you to keep the English version as well....
const char * opensql(const char *dir, const char **table)
Definition opensql.c:13
void die_nomem()
Definition getconf.c:17
#define WHO
Definition author.c:1
stralloc fn
char inbuf[1024]
buffer bi
unsigned long putsubs(const char *dbname, unsigned long hash_lo, unsigned long hash_hi, int subwrite(), int flagsql)
Definition putsubs.c:49
unsigned long hash_lo
Definition ezmlm-send.c:87
unsigned long hash_hi
Definition ezmlm-send.c:88
int fd
Definition ezmlm-cgi.c:141
int match
Definition ezmlm-cgi.c:140
int subwrite(char *s, unsigned int l)
Definition ezmlm-list.c:29
PGconn * pgsql
Definition opensql.c:22
const char * logmsg(const char *dir, unsigned long num, unsigned long listno, unsigned long subs, int done)
Definition loginfo.c:32
void die_write(void)
Definition subscribe.c:41