void getmess() { int match; if (slurpclose(0,&message,1024) == -1) die_read(); strnum[fmt_uint(strnum,message.len)] = 0; if (!stralloc_copys(&beforemessage,strnum)) nomem(); if (!stralloc_cats(&beforemessage,":")) nomem(); if (!stralloc_copys(&aftermessage,",")) nomem(); if (getln(&envelope,&line,&match,'\0') == -1) die_read(); if (!match) die_format(); if (line.len < 2) die_format(); if (line.s[0] != 'F') die_format(); strnum[fmt_uint(strnum,line.len - 2)] = 0; if (!stralloc_cats(&aftermessage,strnum)) nomem(); if (!stralloc_cats(&aftermessage,":")) nomem(); if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem(); if (!stralloc_cats(&aftermessage,",")) nomem(); for (;;) { if (getln(&envelope,&line,&match,'\0') == -1) die_read(); if (!match) die_format(); if (line.len < 2) break; if (line.s[0] != 'T') die_format(); strnum[fmt_uint(strnum,line.len - 2)] = 0; if (!stralloc_cats(&aftermessage,strnum)) nomem(); if (!stralloc_cats(&aftermessage,":")) nomem(); if (!stralloc_catb(&aftermessage,line.s + 1,line.len - 2)) nomem(); if (!stralloc_cats(&aftermessage,",")) nomem(); } }
unsigned int fmt_uint0(char *s,unsigned int u,unsigned int n) { unsigned int len; len = fmt_uint(FMT_LEN,u); while (len < n) { if (s) *s++ = '0'; ++len; } if (s) fmt_uint(s,u); return len; }
int main(void) { char *str; str = buf; str += fmt_uint(str, 100); str += fmt_nstr(str, " multiplied by ", 15); str += fmt_uint(str, 256); str += fmt_str(str, " is "); str += fmt_uint(str, 256 * 100); str += fmt_str(str, "."); *str = 0; test_assert(str_same(buf, exp)); return 0; }
/* Creates an entry for message num and the list listno and code "done". * Returns NULL on success, and the error string on error. */ const char *sub_sql_logmsg(struct subdbinfo *info, unsigned long num, unsigned long listno, unsigned long subs, int done) { char *s; char strnum[FMT_ULONG]; stralloc_copys(&query,"INSERT INTO "); stralloc_cats(&query,info->base_table); stralloc_cats(&query,"_mlog (msgnum,listno,subs,done) VALUES "); stralloc_cats(&query,sql_logmsg_values_defn); stralloc_copyb(¶ms[0],strnum,fmt_ulong(strnum,num)); stralloc_copyb(¶ms[1],strnum,fmt_ulong(strnum,listno)); stralloc_copyb(¶ms[2],strnum,fmt_ulong(strnum,subs)); s = strnum; if (done < 0) { done = - done; *s++ = '-'; } s[fmt_uint(s,done)] = 0; stralloc_copys(¶ms[3],s); sql_exec(info,&query,4,params); /* ignore dups */ return 0; }
void pop3_greet(void) { char *s; s = unique; s += fmt_uint(s,getpid()); *s++ = '.'; s += fmt_ulong(s,(unsigned long) now()); *s++ = '@'; *s++ = 0; putstr("+OK <"); putstr(unique); putstr(hostname); putstr(">\r\n"); flush(); }
/* Creates an entry for message num and the list listno and code "done". * Returns NULL on success, and the error string on error. */ static const char *_logmsg(struct subdbinfo *info, unsigned long num, unsigned long listno, unsigned long subs, int done) { sqlite3_stmt *stmt; int res; if (!stralloc_copys(&logline,"INSERT INTO ")) die_nomem(); if (!stralloc_cats(&logline,info->base_table)) die_nomem(); if (!stralloc_cats(&logline,"_mlog (msgnum,listno,tai,subs,done) VALUES (")) die_nomem(); if (!stralloc_catb(&logline,strnum,fmt_ulong(strnum,num))) die_nomem(); if (!stralloc_cats(&logline,",")) die_nomem(); if (!stralloc_catb(&logline,strnum,fmt_ulong(strnum,listno))) die_nomem(); if (!stralloc_cats(&line,",")) die_nomem(); if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,now()))) die_nomem(); if (!stralloc_cats(&line,",'")) die_nomem(); if (!stralloc_catb(&logline,strnum,fmt_ulong(strnum,subs))) die_nomem(); if (!stralloc_cats(&logline,",")) die_nomem(); if (done < 0) { done = - done; if (!stralloc_append(&logline,"-")) die_nomem(); } if (!stralloc_catb(&logline,strnum,fmt_uint(strnum,done))) die_nomem(); if (!stralloc_append(&logline,")")) die_nomem(); if (!stralloc_0(&logline)) die_nomem(); if ((stmt = _sqlquery(info, &logline)) == NULL) /* log query */ return sqlite3_errmsg((sqlite3*)info->conn); res = sqlite3_step(stmt); sqlite3_finalize(stmt); if (res != SQLITE_DONE) { if (res != SQLITE_CONSTRAINT) /* ignore dups */ return sqlite3_errmsg((sqlite3*)info->conn); } return 0; }
static char *to_str(u16_t i) { static char x[6]; fmt_uint(x, i); return x; }
const char *logmsg(const char *dir, unsigned long num, unsigned long listno, unsigned long subs, int done) /* creates an entry for message num and the list listno and code "done". */ /* Returns NULL on success, "" if dir/sql was not found, and the error */ /* string on error. NOTE: This routine does nothing for non-sql lists! */ { const char *table; const char *ret; PGresult *result; PGresult *result2; if ((ret = opensub(dir,0,&table))) { if (*ret) return ret; else return (char *) 0; /* no SQL => success */ } if (!stralloc_copys(&logline,"INSERT INTO ")) return ERR_NOMEM; if (!stralloc_cats(&logline,table)) return ERR_NOMEM; if (!stralloc_cats(&logline,"_mlog (msgnum,listno,subs,done) VALUES (")) return ERR_NOMEM; if (!stralloc_catb(&logline,strnum,fmt_ulong(strnum,num))) return ERR_NOMEM; if (!stralloc_cats(&logline,",")) return ERR_NOMEM; if (!stralloc_catb(&logline,strnum,fmt_ulong(strnum,listno))) return ERR_NOMEM; if (!stralloc_cats(&logline,",")) return ERR_NOMEM; if (!stralloc_catb(&logline,strnum,fmt_ulong(strnum,subs))) return ERR_NOMEM; if (!stralloc_cats(&logline,",")) return ERR_NOMEM; if (done < 0) { done = - done; if (!stralloc_append(&logline,"-")) return ERR_NOMEM; } if (!stralloc_catb(&logline,strnum,fmt_uint(strnum,done))) return ERR_NOMEM; if (!stralloc_append(&logline,")")) return ERR_NOMEM; if (!stralloc_0(&logline)) return ERR_NOMEM; result = PQexec(pgsql,logline.s); if(result==NULL) return (PQerrorMessage(pgsql)); if(PQresultStatus(result) != PGRES_COMMAND_OK) { /* Check if duplicate */ if (!stralloc_copys(&logline,"SELECT msgnum FROM ")) return ERR_NOMEM; if (!stralloc_cats(&logline,table)) return ERR_NOMEM; if (!stralloc_cats(&logline,"_mlog WHERE msgnum = ")) return ERR_NOMEM; if (!stralloc_catb(&logline,strnum,fmt_ulong(strnum,num))) return ERR_NOMEM; if (!stralloc_cats(&logline," AND listno = ")) return ERR_NOMEM; if (!stralloc_catb(&logline,strnum,fmt_ulong(strnum,listno))) return ERR_NOMEM; if (!stralloc_cats(&logline," AND done = ")) return ERR_NOMEM; if (!stralloc_catb(&logline,strnum,fmt_ulong(strnum,done))) return ERR_NOMEM; /* Query */ if (!stralloc_0(&logline)) return ERR_NOMEM; result2 = PQexec(pgsql,logline.s); if (result2 == NULL) return (PQerrorMessage(pgsql)); if (PQresultStatus(result2) != PGRES_TUPLES_OK) return (char *) (PQresultErrorMessage(result2)); /* No duplicate, return ERROR from first query */ if (PQntuples(result2)<1) return (char *) (PQresultErrorMessage(result)); PQclear(result2); } PQclear(result); return (char *) 0; }
void write_threads(const msgentry *msgtable, subentry *subtable, const authentry *authtable, const dateentry *datetable, unsigned long from,unsigned long to) /* Add the current threading data to the thread database without dups */ /* Writes the subject index first, then processes the individual files */ { const msgentry *pmsgt; subentry *psubt,*psubtm; subentry *presubt = (subentry *)0; const authentry *pautht; const dateentry *pdatet; const char *cp; unsigned int cp1; unsigned long msg; unsigned long ulmsginthread; unsigned long subnum; unsigned long authnum; unsigned long msgnum; unsigned int pos; unsigned int startdate,nextdate; unsigned int startmsg,nextmsg; int fd = -1; int fdn = -1; int match; int ffound; int lineno; int res; psubtm = subtable; /* now for new threads */ pdatet = datetable; startmsg = nextmsg = 0L; nextdate = pdatet->date; while (psubtm->sub) { /* these are in msgnum order */ if (!presubt) /* for rewind */ if (psubtm->lastmsg >= nextmsg) presubt = psubtm; /* this thread extends beyond current month */ if (psubtm->firstmsg >= nextmsg) { /* done with this month */ if (fdn != -1) close_proper(&ssout,fn.s,fnn.s); if (presubt) /* need to rewind? */ psubtm = presubt; /* do it */ psubt = psubtm; /* tmp pointer to reset done flag */ presubt = (subentry *)0; /* reset rewind pointer */ pdatet++; /* next month */ startdate = nextdate; /* startdate */ nextdate = pdatet->date; /* end date */ startmsg = nextmsg; /* first message in month */ nextmsg = pdatet->msg; /* first message in next month */ stralloc_copys(&fn,"archive/threads/"); stralloc_catb(&fn,strnum,fmt_uint(strnum,startdate)); stralloc_copy(&fnn,&fn); stralloc_0(&fn); stralloc_cats(&fnn,"n"); stralloc_0(&fnn); if ((fdn = open_trunc(fnn.s)) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,fnn.s)); substdio_fdbuf(&ssout,write,fdn,outbuf,sizeof(outbuf)); if ((fd = open_read(fn.s)) == -1) { if (errno != error_noent) strerr_die2sys(111,FATAL,MSG1(ERR_OPEN,fn.s)); } else { substdio_fdbuf(&ssin,read,fd,inbuf,sizeof(inbuf)); for (;;) { if (getln(&ssin,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,MSG1(ERR_READ,fn.s)); if (!match) break; pos = scan_ulong(line.s,&msgnum); pos++; /* skip ':' */ if (msgnum >= from) continue; /* ignore entries from threading range */ if (line.len < pos + HASHLEN) { flagerror = -1; /* and bad ones */ continue; } psubt = subtable; cp = line.s + pos; ffound = 0; /* search among already known subjects */ for (;;) { res = str_diffn(psubt->sub,cp,HASHLEN); if (res < 0) { if (psubt->higher) psubt = psubt->higher; else break; } else if (res > 0) { if (psubt->lower) psubt = psubt->lower; else break; } else { ffound = 1; break; } } if (!ffound) { if (substdio_put(&ssout,line.s,line.len) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); } else { /* new # of msg in thread */ cp += HASHLEN; /* HASHLEN [#] Subject always \n at end */ if (*(cp++) == ' ' && *(cp++) == '[') { cp += scan_ulong(cp,&ulmsginthread); if (*cp == ']') { psubt->msginthread += (unsigned char) (ulmsginthread & 0xff); } } else flagerror = -5; } } close(fd); } continue; } if (psubtm->firstmsg < nextmsg && psubtm->lastmsg >= startmsg) { stralloc_copyb(&line,strnum,fmt_ulong(strnum,psubtm->lastmsg)); stralloc_cats(&line,":"); stralloc_catb(&line,psubtm->sub,HASHLEN); stralloc_cats(&line," ["); stralloc_catb(&line,strnum,fmt_ulong(strnum,(unsigned long) psubtm->msginthread)); stralloc_cats(&line,"]"); stralloc_catb(&line,psubtm->sub + HASHLEN,psubtm->sublen - HASHLEN); /* has \n */ if (substdio_put(&ssout,line.s,line.len) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); } psubtm++; } if (fdn != -1) close_proper(&ssout,fn.s,fnn.s); psubt = subtable; while (psubt->sub) { /* now the threads */ stralloc_copys(&fn,"archive/subjects/"); stralloc_catb(&fn,psubt->sub,2); stralloc_0(&fn); if (mkdir(fn.s,0755) == -1) if (errno != error_exist) strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,fn.s)); fn.s[fn.len - 1] = '/'; stralloc_catb(&fn,psubt->sub+2,HASHLEN-2); stralloc_copy(&fnn,&fn); stralloc_cats(&fnn,"n"); stralloc_0(&fn); stralloc_0(&fnn); if ((fdn = open_trunc(fnn.s)) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,fnn.s)); substdio_fdbuf(&ssout,write,fdn,outbuf,sizeof(outbuf)); if ((fd = open_read(fn.s)) == -1) { if (errno != error_noent) strerr_die2sys(111,FATAL,MSG1(ERR_OPEN,fn.s)); if (substdio_put(&ssout,psubt->sub,psubt->sublen) == -1) /* write subject */ strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); } else { /* copy data */ substdio_fdbuf(&ssin,read,fd,inbuf,sizeof(inbuf)); lineno = 0; for (;;) { if (getln(&ssin,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,MSG1(ERR_READ,fn.s)); if (!match) break; if (!lineno) { /* write subject */ if (line.len < HASHLEN + 1 || line.s[HASHLEN] != ' ') flagerror = -3; if (substdio_put(&ssout,line.s,line.len) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); lineno = 1; continue; } (void) scan_ulong(line.s,&msgnum); if (msgnum >= from) break; if (substdio_put(&ssout,line.s,line.len) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); } (void) close(fd); /* close old index */ } subnum = (unsigned long) (psubt - subtable + 1); /* idx of this subj */ pmsgt = msgtable + psubt->firstmsg - from; /* first message entry */ for (msg = psubt->firstmsg; msg <= psubt->lastmsg; msg++) { if (pmsgt->subnum == subnum) { stralloc_copyb(&line,strnum,fmt_ulong(strnum,msg)); stralloc_cats(&line,":"); stralloc_catb(&line,strnum,fmt_uint(strnum,pmsgt->date)); stralloc_cats(&line,":"); if (pmsgt->authnum) { pautht = authtable + pmsgt->authnum - 1; cp1 = byte_chr(pautht->auth,pautht->authlen,' '); if (cp1 != HASHLEN) strerr_die1x(100,MSG(ERR_BAD_INDEX)); stralloc_catb(&line,pautht->auth,pautht->authlen); /* hash */ } else stralloc_cats(&line,"\n"); if (substdio_put(&ssout,line.s,line.len) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); } pmsgt++; } close_proper(&ssout,fn.s,fnn.s); psubt++; } /* (no master author index) */ pautht = authtable; while (pautht->auth) { /* now the authors */ stralloc_copys(&fn,"archive/authors/"); stralloc_catb(&fn,pautht->auth,2); stralloc_0(&fn); if (mkdir(fn.s,0755) == -1) if (errno != error_exist) strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,fn.s)); fn.s[fn.len - 1] = '/'; stralloc_catb(&fn,pautht->auth+2,HASHLEN-2); stralloc_copy(&fnn,&fn); stralloc_cats(&fnn,"n"); stralloc_0(&fn); stralloc_0(&fnn); if ((fdn = open_trunc(fnn.s)) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,fnn.s)); substdio_fdbuf(&ssout,write,fdn,outbuf,sizeof(outbuf)); if ((fd = open_read(fn.s)) == -1) { if (errno != error_noent) strerr_die2sys(111,FATAL,MSG1(ERR_OPEN,fn.s)); else { /* didn't exist before: write author */ if (substdio_put(&ssout,pautht->auth,pautht->authlen) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); } } else { /* copy data */ substdio_fdbuf(&ssin,read,fd,inbuf,sizeof(inbuf)); lineno = 0; for (;;) { if (getln(&ssin,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,MSG1(ERR_READ,fn.s)); if (!match) break; if (!lineno) { /* write author */ if (line.len < HASHLEN + 1 || line.s[HASHLEN] != ' ') flagerror = - 4; if (substdio_put(&ssout,line.s,line.len) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); lineno = 1; continue; } (void) scan_ulong(line.s,&msgnum); if (msgnum >= from) break; if (substdio_put(&ssout,line.s,line.len) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); } (void) close(fd); /* close old index */ } authnum = (unsigned long) (pautht - authtable + 1); /* idx of this auth */ pmsgt = msgtable + pautht->firstmsg - from; /* first message entry */ for (msg = pautht->firstmsg; msg <= to; msg++) { if (pmsgt->authnum == authnum) { stralloc_copyb(&line,strnum,fmt_ulong(strnum,msg)); stralloc_cats(&line,":"); stralloc_catb(&line,strnum,fmt_uint(strnum,pmsgt->date)); stralloc_cats(&line,":"); if (pmsgt->subnum) { psubt = subtable + pmsgt->subnum - 1; stralloc_catb(&line,psubt->sub,psubt->sublen); } if (substdio_put(&ssout,line.s,line.len) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); } pmsgt++; } close_proper(&ssout,fn.s,fnn.s); pautht++; } }