nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 7347f3a3a5b9163b3904c004b2a825db89a852ec
parent 9ad6a37c6faaedbb5767f04b4cb141a81c06dcb6
Author: Ellenor Bjornsdottir <ellenor@umbrellix.net>
Date:   Fri, 21 Oct 2022 11:15:52 +0000

convert a few error messages from HCMSSC to QESC, add features to pw2u, scaffolding for future 'probe' delivery mode of qmlocal

Diffstat:
Msrc/qmail-local.c | 57+++++++++++++++++++++++++++++----------------------------
Msrc/qmail-pw2u.c | 44+++++++++++++++++++++++++++++++-------------
Msrc/spawn.c | 32++++++++++++++++----------------
3 files changed, 76 insertions(+), 57 deletions(-)

diff --git a/src/qmail-local.c b/src/qmail-local.c @@ -31,19 +31,19 @@ #include "gfrom.h" #include "auto_patrn.h" -void _noreturn_ usage() { strerr_die1x(100,"qmail-local: usage: qmail-local [ -nN ] user homedir local dash ext domain sender aliasempty"); } +void _noreturn_ usage() { strerr_die1x(100,"qmail-local: usage: qmail-local [ -nNT ] user homedir local dash ext domain sender aliasempty"); } -void _noreturn_ temp_nomem() { strerr_die1x(111,"Out of memory. (#4.3.0)"); } -void _noreturn_ temp_rewind() { strerr_die1x(111,"Unable to rewind message. (#4.3.0)"); } -void _noreturn_ temp_childcrashed() { strerr_die1x(111,"Aack, child crashed. (#4.3.0)"); } -void _noreturn_ temp_fork() { strerr_die3x(111,"Unable to fork: ",error_str(errno),". (#4.3.0)"); } -void _noreturn_ temp_read() { strerr_die3x(111,"Unable to read message: ",error_str(errno),". (#4.3.0)"); } +void _noreturn_ temp_nomem() { strerr_die1x(111,"4.3.0 Out of memory."); } +void _noreturn_ temp_rewind() { strerr_die1x(111,"4.3.0 Unable to rewind message."); } +void _noreturn_ temp_childcrashed() { strerr_die1x(111,"4.3.0 Aack, child crashed."); } +void _noreturn_ temp_fork() { strerr_die3x(111,"4.3.0 Unable to fork: ",error_str(errno),"."); } +void _noreturn_ temp_read() { strerr_die3x(111,"4.3.0 Unable to read message: ",error_str(errno),"."); } void _noreturn_ temp_slowlock() -{ strerr_die1x(111,"File has been locked for 30 seconds straight. (#4.3.0)"); } +{ strerr_die1x(111,"4.3.0 File has been locked for 30 seconds straight."); } void _noreturn_ temp_qmail(char *fn) -{ strerr_die5x(111,"Unable to open ",fn,": ",error_str(errno),". (#4.3.0)"); } +{ strerr_die5x(111,"4.3.0 Unable to open ",fn,": ",error_str(errno)," ."); } -int flagdoit; +int flagdoit = 0; int flag99; char *user; @@ -163,10 +163,10 @@ char *fn; switch(wait_exitcode(wstat)) { case 0: break; - case 2: strerr_die1x(111,"Unable to chdir to maildir. (#4.2.1)"); - case 3: strerr_die1x(111,"Timeout on maildir delivery. (#4.3.0)"); - case 4: strerr_die1x(111,"Unable to read message. (#4.3.0)"); - default: strerr_die1x(111,"Temporary error on maildir delivery. (#4.3.0)"); + case 2: strerr_die1x(111,"4.2.1 Unable to chdir to maildir. "); + case 3: strerr_die1x(111,"4.3.0 Timeout on maildir delivery. "); + case 4: strerr_die1x(111,"4.3.0 Unable to read message. "); + default: strerr_die1x(111,"4.3.0 Temporary error on maildir delivery. "); } } @@ -184,7 +184,7 @@ char *fn; fd = open_append(fn); if (fd == -1) - strerr_die5x(111,"Unable to open ",fn,": ",error_str(errno),". (#4.2.1)"); + strerr_die5x(111,"Unable to open ",fn,": ",error_str(errno),"4.2.1 . "); sig_alarmcatch(temp_slowlock); alarm(30); @@ -204,7 +204,7 @@ char *fn; { if (getln(&ss,&messline,&match,'\n') != 0) { - strerr_warn3("Unable to read message: ",error_str(errno),". (#4.3.0)",0); + strerr_warn3("Unable to read message: ",error_str(errno),"4.3.0 . ",0); if (flaglocked) seek_trunc(fd,pos); close(fd); _exit(111); } @@ -225,7 +225,7 @@ char *fn; return; writeerrs: - strerr_warn5("Unable to write ",fn,": ",error_str(errno),". (#4.3.0)",0); + strerr_warn5("Unable to write ",fn,": ",error_str(errno),"4.3.0 . ",0); if (flaglocked) seek_trunc(fd,pos); close(fd); _exit(111); @@ -248,7 +248,7 @@ char *prog; args[0] = "/bin/sh"; args[1] = "-c"; args[2] = prog; args[3] = 0; sig_pipedefault(); execv(*args,args); - strerr_die3x(111,"Unable to run /bin/sh: ",error_str(errno),". (#4.3.0)"); + strerr_die3x(111,"Unable to run /bin/sh: ",error_str(errno),"4.3.0 . "); } wait_pid(&wstat,child); @@ -308,7 +308,7 @@ void bouncexf() break; if (messline.len == dtline.len) if (!str_diffn(messline.s,dtline.s,dtline.len)) - strerr_die1x(100,"This message is looping: it already has my Delivered-To line. (#5.4.6)"); + strerr_die1x(100,"5.4.6 This message is looping: it already has my Delivered-To line. "); } } @@ -317,12 +317,12 @@ void checkhome() struct stat st; if (stat(".",&st) == -1) - strerr_die3x(111,"Unable to stat home directory: ",error_str(errno),". (#4.3.0)"); + strerr_die3x(111,"Unable to stat home directory: ",error_str(errno),"4.3.0 . "); if (st.st_mode & auto_patrn) - strerr_die1x(111,"Uh-oh: home directory is writable. (#4.7.0)"); + strerr_die1x(111,"4.7.0 Uh-oh: home directory is writable. "); if (st.st_mode & 01000) { if (flagdoit) - strerr_die1x(111,"Home directory is sticky: user is editing his .qmail file. (#4.2.1)"); + strerr_die1x(111,"4.2.1 Home directory is sticky: user is editing their .qmail file. "); else strerr_warn1("Warning: home directory is sticky.",0); } @@ -365,7 +365,7 @@ int *cutable; if (fstat(*fd,&st) == -1) temp_qmail(qme.s); if ((st.st_mode & S_IFMT) == S_IFREG) { if (st.st_mode & auto_patrn) - strerr_die1x(111,"Uh-oh: .qmail file is writable. (#4.7.0)"); + strerr_die1x(111,"4.7.0 Uh-oh: .qmail file is writable. "); *cutable = !!(st.st_mode & 0100); return 1; } @@ -464,11 +464,12 @@ int main(int argc, char **argv) if (!env_init()) temp_nomem(); flagdoit = 1; - while ((opt = getopt(argc,argv,"nN")) != opteof) + while ((opt = getopt(argc,argv,"nNT")) != opteof) switch(opt) { case 'n': flagdoit = 0; break; case 'N': flagdoit = 1; break; + case 'T': flagdoit = 0; flagprobe = 1; break; default: usage(); } @@ -487,7 +488,7 @@ int main(int argc, char **argv) if (homedir[0] != '/') usage(); if (chdir(homedir) == -1) - strerr_die5x(111,"Unable to switch to ",homedir,": ",error_str(errno),". (#4.3.0)"); + strerr_die5x(111,"4.3.0 Unable to switch to ",homedir,": ",error_str(errno),"."); checkhome(); if (!env_put2("HOST",host)) temp_nomem(); @@ -586,7 +587,7 @@ int main(int argc, char **argv) qmesearch(&fd,&flagforwardonly); if (fd == -1) if (*dash) - strerr_die1x(100,"Sorry, no mailbox here by that name. (#5.1.1)"); + strerr_die1x(100,"5.1.1 Sorry, no mailbox here by that name."); if (!stralloc_copys(&ueo,sender)) temp_nomem(); if (str_diff(sender,"")) @@ -651,13 +652,13 @@ int main(int argc, char **argv) { case 0: /* k == i */ if (i) break; - strerr_die1x(111,"Uh-oh: first line of .qmail file is blank. (#4.2.1)"); + strerr_die1x(111,"4.2.1 Uh-oh: first line of .qmail file is blank."); case '#': break; case '.': case '/': ++count_file; - if (flagforwardonly) strerr_die1x(111,"Uh-oh: .qmail has file delivery but has x bit set. (#4.7.0)"); + if (flagforwardonly) strerr_die1x(111,"4.7.0 Uh-oh: .qmail has file delivery but has x bit set."); if (cmds.s[k - 1] == '/') if (flagdoit) maildir(cmds.s + i); else sayit("maildir ",cmds.s + i,k - i); @@ -667,7 +668,7 @@ int main(int argc, char **argv) break; case '|': ++count_program; - if (flagforwardonly) strerr_die1x(111,"Uh-oh: .qmail has prog delivery but has x bit set. (#4.7.0)"); + if (flagforwardonly) strerr_die1x(111,"4.7.0 Uh-oh: .qmail has prog delivery but has x bit set."); if (flagdoit) mailprogram(cmds.s + i + 1); else sayit("program ",cmds.s + i + 1,k - i - 1); break; diff --git a/src/qmail-pw2u.c b/src/qmail-pw2u.c @@ -77,6 +77,8 @@ int homestrategy = 2; /* 1: stop if home does not exist; skip if home is not owned by user */ /* 0: don't worry about home */ +int dotend = 1, onlybreak = 0; // 1 if to output with a terminal dot, 1 if only to output breaked users + int okincl; stralloc incl = {0}; struct constmap mapincl; int okexcl; stralloc excl = {0}; struct constmap mapexcl; int okmana; stralloc mana = {0}; struct constmap mapmana; @@ -174,11 +176,13 @@ void doaccount() i = str_chr(mailnames,':'); - if (substdio_puts(subfdout,"=") == -1) die_write(); - if (substdio_put(subfdout,mailnames,i) == -1) die_write(); - if (substdio_put(subfdout,uugh.s,uugh.len) == -1) die_write(); - if (substdio_puts(subfdout,"::\n") == -1) die_write(); - + if (!onlybreak) { + if (substdio_puts(subfdout,"=") == -1) die_write(); + if (substdio_put(subfdout,mailnames,i) == -1) die_write(); + if (substdio_put(subfdout,uugh.s,uugh.len) == -1) die_write(); + if (substdio_puts(subfdout,"::\n") == -1) die_write(); + } + if (*auto_break) { if (substdio_puts(subfdout,"+") == -1) die_write(); if (substdio_put(subfdout,mailnames,i) == -1) die_write(); @@ -208,12 +212,14 @@ void dosubuser() if (!u) die_user(x,i); ++i; x += i; xlen -= i; i = byte_chr(x,xlen,':'); if (i == xlen) return; - if (substdio_puts(subfdout,"=") == -1) die_write(); - if (substdio_put(subfdout,sub.s,sub.len) == -1) die_write(); - if (substdio_puts(subfdout,u) == -1) die_write(); - if (substdio_puts(subfdout,dashcolon) == -1) die_write(); - if (substdio_put(subfdout,x,i) == -1) die_write(); - if (substdio_puts(subfdout,":\n") == -1) die_write(); + if (!onlybreak) { + if (substdio_puts(subfdout,"=") == -1) die_write(); + if (substdio_put(subfdout,sub.s,sub.len) == -1) die_write(); + if (substdio_puts(subfdout,u) == -1) die_write(); + if (substdio_puts(subfdout,dashcolon) == -1) die_write(); + if (substdio_put(subfdout,x,i) == -1) die_write(); + if (substdio_puts(subfdout,":\n") == -1) die_write(); + } if (*auto_break) { if (substdio_puts(subfdout,"+") == -1) die_write(); @@ -229,20 +235,31 @@ void dosubuser() int fd; substdio ss; char ssbuf[SUBSTDIO_INSIZE]; +stralloc scolon; int main(int argc, char **argv) { int opt; int match; - while ((opt = getopt(argc,argv,"/ohHuUc:C")) != opteof) + while ((opt = getopt(argc,argv,"/ohHuUs:dDkKc:C")) != opteof) switch(opt) { case '/': dashcolon = "-/:"; break; + case 's': + if (!stralloc_copys(&scolon, optarg)) die_nomem(); + if (!stralloc_cats(&scolon, ":")) die_nomem(); + if (!stralloc_0(&scolon)) die_nomem(); + dashcolon = scolon.s; + break; case 'o': homestrategy = 2; break; case 'h': homestrategy = 1; break; case 'H': homestrategy = 0; break; case 'u': flagnoupper = 0; break; case 'U': flagnoupper = 1; break; + case 'd': dotend = 1; break; + case 'D': dotend = 0; break; + case 'k': onlybreak = 1; break; + case 'K': onlybreak = 0; break; case 'c': *auto_break = *optarg; break; case 'C': *auto_break = 0; break; case '?': @@ -306,7 +323,8 @@ int main(int argc, char **argv) } } - if (substdio_puts(subfdout,".\n") == -1) die_write(); + if (dotend) if (substdio_puts(subfdout,".\n") == -1) die_write(); + else if (substdio_puts(subfdout,"\n") == -1) die_write(); if (substdio_flush(subfdout) == -1) die_write(); return 0; } diff --git a/src/spawn.c b/src/spawn.c @@ -85,44 +85,44 @@ void docmd() int pi[2]; struct stat st; - if (flagabort) { err("Zqmail-spawn out of memory. (#4.3.0)\n"); return; } - if (delnum < 0) { err("ZInternal error: delnum negative. (#4.3.5)\n"); return; } - if (delnum >= auto_spawn) { err("ZInternal error: delnum too big. (#4.3.5)\n"); return; } - if (d[delnum].used) { err("ZInternal error: delnum in use. (#4.3.5)\n"); return; } + if (flagabort) { err("Z4.3.0 qmail-spawn out of memory.\n"); return; } + if (delnum < 0) { err("Z4.3.5 Internal error: delnum negative.\n"); return; } + if (delnum >= auto_spawn) { err("Z4.3.5 Internal error: delnum too big.\n"); return; } + if (d[delnum].used) { err("Z4.3.5 Internal error: delnum in use.\n"); return; } for (i = 0;i < messid.len;++i) if (messid.s[i]) if (!i || (messid.s[i] != '/')) if ((unsigned char) (messid.s[i] - '0') > 9) - { err("DInternal error: messid has nonnumerics. (#5.3.5)\n"); return; } - if (messid.len > 100) { err("DInternal error: messid too long. (#5.3.5)\n"); return; } - if (!messid.s[0]) { err("DInternal error: messid too short. (#5.3.5)\n"); return; } + { err("D5.3.5 Internal error: messid has nonnumerics.\n"); return; } + if (messid.len > 100) { err("D5.3.5 Internal error: messid too long.\n"); return; } + if (!messid.s[0]) { err("D5.3.5 Internal error: messid too short.\n"); return; } if (!stralloc_copys(&d[delnum].output,"")) - { err("Zqmail-spawn out of memory. (#4.3.0)\n"); return; } + { err("Z4.3.0 qmail-spawn out of memory.\n"); return; } j = byte_rchr(recip.s,recip.len,'@'); - if (j >= recip.len) { err("DSorry, address must include host name. (#5.1.3)\n"); return; } + if (j >= recip.len) { err("D5.1.3 Sorry, address must include host name.\n"); return; } fdmess = open_read(messid.s); - if (fdmess == -1) { err("Zqmail-spawn unable to open message. (#4.3.0)\n"); return; } + if (fdmess == -1) { err("Z4.3.0 qmail-spawn unable to open message.\n"); return; } if (fstat(fdmess,&st) == -1) - { close(fdmess); err("Zqmail-spawn unable to fstat message. (#4.3.0)\n"); return; } + { close(fdmess); err("Z4.3.0 qmail-spawn unable to fstat message.\n"); return; } if ((st.st_mode & S_IFMT) != S_IFREG) - { close(fdmess); err("ZSorry, message has wrong type. (#4.3.5)\n"); return; } + { close(fdmess); err("Z4.3.5 Sorry, message has wrong type.\n"); return; } if (st.st_uid != auto_uidq) /* aaack! qmailq has to be trusted! */ /* your security is already toast at this point. damage control... */ - { close(fdmess); err("ZSorry, message has wrong owner. (#4.3.5)\n"); return; } + { close(fdmess); err("Z4.3.5 Sorry, message has wrong owner.\n"); return; } if (pipe(pi) == -1) - { close(fdmess); err("Zqmail-spawn unable to create pipe. (#4.3.0)\n"); return; } + { close(fdmess); err("Z4.3.0 qmail-spawn unable to create pipe.\n"); return; } coe(pi[0]); f = spawn(fdmess,pi[1],sender.s,recip.s,j); close(fdmess); if (f == -1) - { close(pi[0]); close(pi[1]); err("Zqmail-spawn unable to fork. (#4.3.0)\n"); return; } + { close(pi[0]); close(pi[1]); err("Z4.3.0 qmail-spawn unable to fork.\n"); return; } d[delnum].fdin = pi[0]; d[delnum].fdout = pi[1]; coe(pi[1]); @@ -241,7 +241,7 @@ int main(int argc, char **argv) close(d[i].fdin); d[i].used = 0; continue; } - while (!stralloc_readyplus(&d[i].output,r)) sleep(10); /*XXX*/ + while (!stralloc_readyplus(&d[i].output,r)) sleep(10); /*XXX sleep until we can get memory*/ byte_copy(d[i].output.s + d[i].output.len,r,inbuf); d[i].output.len += r; if (truncreport > 100)