void strerr_warn(const char *x1, const char *x2, const char *x3, const char *x4, const char *x5, const char *x6, const struct strerr *se) { strerr_sysinit(); if (x1) substdio_puts(subfderr,x1); if (x2) substdio_puts(subfderr,x2); if (x3) substdio_puts(subfderr,x3); if (x4) substdio_puts(subfderr,x4); if (x5) substdio_puts(subfderr,x5); if (x6) substdio_puts(subfderr,x6); while(se) { if (se->x) substdio_puts(subfderr,se->x); if (se->y) substdio_puts(subfderr,se->y); if (se->z) substdio_puts(subfderr,se->z); se = se->who; } substdio_puts(subfderr,"\n"); substdio_flush(subfderr); }
void write_ulong(unsigned long num,unsigned long cum,unsigned long dat, const char *fn,const char *fnn) /* write num to "fnn" add ':' & cum if cum <>0, then move "fnn" to "fn" */ { int fd; fd = open_trunc(fnn); if (fd == -1) strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,fnn)); substdio_fdbuf(&ssnum,write,fd,numbuf,sizeof(numbuf)); if (substdio_put(&ssnum,strnum,fmt_ulong(strnum,num)) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn)); if (substdio_puts(&ssnum,":") == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn)); if (substdio_put(&ssnum,strnum,fmt_ulong(strnum,cum)) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn)); if (dat) { if (substdio_puts(&ssnum,":") == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn)); if (substdio_put(&ssnum,strnum,fmt_ulong(strnum,dat)) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn)); } if (substdio_puts(&ssnum,"\n") == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn)); if (substdio_flush(&ssnum) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_FLUSH,fnn)); if (fsync(fd) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_SYNC,fnn)); if (close(fd) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_CLOSE,fnn)); wrap_rename(fnn,fn); }
void die_alias() { substdio_puts(subfderr,"qmail-pw2u: fatal: unable to find "); substdio_puts(subfderr,auto_usera); substdio_puts(subfderr," user\n"); substdio_flush(subfderr); _exit(111); }
int main() { host[0] = 0; /* sigh */ gethostname(host,sizeof(host)); host[sizeof(host) - 1] = 0; substdio_puts(subfdoutsmall,host); substdio_puts(subfdoutsmall,"\n"); substdio_flush(subfdoutsmall); _exit(0); }
void doanddie(char *user, unsigned int userlen /* including 0 byte */, char *pass) { int child; int wstat; int pi[2]; close(3); if (pipe(pi) == -1) die_pipe(); if (pi[0] != 3) die_pipe(); switch(child = fork()) { case -1: die_fork(); case 0: close(pi[1]); sig_pipedefault(); execvp(*childargs,childargs); _exit(1); } close(pi[0]); substdio_fdbuf(&ssup,subwrite,pi[1],upbuf,sizeof upbuf); if (substdio_put(&ssup,user,userlen) == -1) die_write(); if (substdio_put(&ssup,pass,str_len(pass) + 1) == -1) die_write(); if (substdio_puts(&ssup,"<") == -1) die_write(); if (substdio_puts(&ssup,unique) == -1) die_write(); if (substdio_puts(&ssup,hostname) == -1) die_write(); if (substdio_put(&ssup,">",2) == -1) die_write(); if (substdio_flush(&ssup) == -1) die_write(); close(pi[1]); byte_zero(pass,str_len(pass)); byte_zero(upbuf,sizeof upbuf); if (wait_pid(&wstat,child) == -1) die(); if (wait_crashed(wstat)) die_childcrashed(); switch (wait_exitcode(wstat)) { case 0: die(); case 1: die_1(); case 2: die_2(); case 25: die_25(); case 3: die_3(); case 4: die_4(); case 5: die_5(); case 6: die_6(); case 61: die_61(); case 62: die_62(); case 7: die_7(); case 8: die_nomem(); default: die_unknown(); } die(); }
int temp_nfs(void) { if (substdio_puts(subfdout, "ZNFS failure in qmail-verify.") == -1) die_write(); if (substdio_putflush(subfdout, "", 1) == -1) die_write(); return -1; }
static void execute(const char *fn,const char *def) /* Load and execute a qmail command file. */ { stralloc file = {0,0,0}; int code; if (def != 0) env_put2("DEFAULT",def); else env_unset("DEFAULT"); if (slurp(fn,&file,256) != 1) strerr_die6sys(111,FATAL,ERR_READ_INPUT,basedir.s,"/",fn,": "); code = execute_file(fn,&file); substdio_puts(subfderr,"did 0+"); substdio_put(subfderr,strnum,fmt_ulong(strnum,did_forward)); substdio_puts(subfderr,"+"); substdio_put(subfderr,strnum,fmt_ulong(strnum,did_program)); substdio_putsflush(subfderr,"\n"); _exit(code); }
void die_cdb(void) { if (substdio_puts(subfdout, "ZTrouble reading users/cdb in qmail-verify.") == -1) die_write(); if (substdio_putflush(subfdout, "", 1) == -1) die_write(); _exit(111); }
void die_nomem(void) { cleanup(); if (substdio_puts(subfdout, "ZOut of memory in qmail-verify.") == -1) die_write(); if (substdio_putflush(subfdout, "", 1) == -1) die_write(); _exit(111); }
int call_puts(struct call *cc, const char *s) { if (cc->flagerr || cc->flagabort) return -1; if (cc->flagstar && str_diff(s, "*") == 0) { cc->flagabort = 1; return -1; } if (substdio_puts(&cc->ssto, s) == -1) { cc->flagerr = 1; return -1; } return 0; }
static void forward(const char *rcpt) { char buf[4096]; const char *dtline; const char *err; int r; if (qmail_open(&qq,0) == -1) strerr_die2sys(111,FATAL,MSG(ERR_QMAIL_QUEUE)); if ((dtline = env_get("DTLINE")) != 0) qmail_puts(&qq,dtline); while ((r = read(0,buf,sizeof buf)) > 0) qmail_put(&qq,buf,r); if (r == -1) strerr_die2sys(111,FATAL,MSG(ERR_READ_STDIN)); qmail_from(&qq,sender); qmail_to(&qq,rcpt); if (*(err = qmail_close(&qq)) != '\0') strerr_die4x(111,FATAL,MSG(ERR_TMP_QMAIL_QUEUE),": ",err + 1); strnum[fmt_ulong(strnum,qmail_qp(&qq))] = 0; substdio_puts(subfderr,"qp "); substdio_puts(subfderr,strnum); substdio_putsflush(subfderr,"\n"); ++did_forward; }
int main(int argc,char **argv) { const char *dir; const char *sender; const char *moddir; int opt; int ret = 0; unsigned int i,j; const char *program; stralloc *opts; stralloc cmds = {0}; int child; int ismod; umask(022); sig_pipeignore(); if (!stralloc_copys(&sendopt,"-")) die_nomem(); if (!stralloc_copys(&storeopt,"-")) die_nomem(); opt = getconfopt(argc,argv,options,1,&dir); /* storeopts to ezmlm-store only. Others to both (ezmlm-store may */ /* pass them on to ezmlm-send. */ if (!stralloc_catb(&storeopt,sendopt.s+1,sendopt.len-1)) die_nomem(); initsub(0); sender = get_sender(); ismod = 0; if (queryext) { getconf(&cmds,queryext,1); i = 0; for (j = 0;j < cmds.len; ++j) if (!cmds.s[j]) { switch (cmds.s[i]) { case '\0': case '#': break; /* ignore blank/comment */ case '|': ret = mailprog(cmds.s + i + 1); break; default: ret = mailprog(cmds.s + i); break; } if (ret) break; i = j + 1; } if (!ret || ret == 99) /* 111 => temp error */ ismod = 1; /* 0, 99 => post */ /* other => moderate */ } moddir = argv[opt++]; if (moddir && !ret) { /* if exit 0 and moddir, add issub */ ismod = 0; while (moddir && !ismod && sender) { ismod = issub(moddir,sender,0); closesub(); moddir = argv[opt++]; } } if (ismod) { program = "/ezmlm-send"; opts = &sendopt; } else { program = "/ezmlm-store"; opts = &storeopt; } if (dontact) { substdio_puts(subfderr, auto_bin()); substdio_puts(subfderr, program); substdio_put(subfderr, " ", 1); substdio_put(subfderr, opts->s, opts->len); substdio_put(subfderr, " ", 1); substdio_puts(subfderr, dir); substdio_putsflush(subfderr, "\n"); _exit(0); } if ((child = wrap_fork()) == 0) wrap_execbin(program, opts, dir); /* parent */ wrap_exitcode(child); _exit(0); }
void subputs(const char *s) { if (substdio_puts(subfdout,s) == -1) _exit(111); }
int main(int argc, char **argv) { int match; unsigned int at; log_init(STDERR, ~256, 0); if (read_controls(ctrls) == -1) die_control(); q = 0; do { if (getln(&ssin, &line, &match, '\0') != 0) { if (errno != error_timeout) die_read(); cleanup(); continue; } if (!match) { cleanup(); /* other side closed pipe */ break; } logit(32, "qmail-verfiy: verifying %S\n", &line); at = byte_rchr(line.s,line.len,'@'); if (at >= line.len) { if (substdio_puts(subfdout, "DSorry, address must " "include host name. (#5.1.3)") == -1) die_write(); if (substdio_putflush(subfdout, "", 1) == -1) die_write(); continue; } switch (lookup(&line)) { case 0: if (localdelivery()) { /* * Do the local address lookup. */ line.s[at] = '\0'; if (lookup_cdb(line.s) == 1) break; if (lookup_passwd(line.s) == 1) break; } /* Sorry, no mailbox here by that name. */ if (substdio_puts(subfdout, "DSorry, no mailbox here by that name. " "(#5.1.1)") == -1) die_write(); if (substdio_putflush(subfdout, "", 1) == -1) die_write(); break; case 1: default: break; } } while (1); return 0; }
int lookup(stralloc *mail) { const char *attrs[] = { LDAP_ISACTIVE, 0 }; char *f; int done; int status; int rv; if (q == 0) { q = qldap_new(); if (q == 0) die_nomem(); rv = qldap_open(q); if (rv != OK) die_temp(); rv = qldap_bind(q, 0, 0); if (rv != OK) die_temp(); } /* * this handles the "catch all" and "-default" extension * but also the normal eMail address. * Code handels also mail addresses with multiple '@' safely. * at = index to last @ sign in mail address * escaped = ldap escaped mailaddress * len = length of escaped mailaddress * i = position of current '-' or '@' */ done = 0; do { f = filter_mail(mail->s, &done); if (f == (char *)0) die_nomem(); logit(16, "ldapfilter: '%s'\n", f); /* do the search for the email address */ rv = qldap_lookup(q, f, attrs); switch (rv) { case OK: break; /* something found */ case TIMEOUT: /* temporary error but give up so that the * ldap server can recover */ die_timeout(); case TOOMANY: #ifdef DUPEALIAS if (substdio_putflush(subfdout, "K", 1) == -1) die_write(); qldap_free_results(q); #else /* admin error, also temporary */ temp_fail(); #endif return (-1); case FAILED: /* ... again temporary */ temp_fail(); return (-1); case NOSUCH: break; } } while (rv != OK && !done); /* reset filter_mail */ filter_mail(0, 0); /* nothing found, try a local lookup or a alias delivery */ if (rv == NOSUCH) { qldap_free_results(q); return (0); } /* check if the ldap entry is active */ rv = qldap_get_status(q, &status); if (rv != OK) { temp_fail(); return (-1); } if (status == STATUS_BOUNCE) { /* Mailaddress is administratively disabled. (#5.2.1) */ if (substdio_puts(subfdout, "DMailaddress is administratively disabled. " "(#5.2.1)") == -1) die_write(); if (substdio_putflush(subfdout, "", 1) == -1) die_write(); qldap_free_results(q); return (1); } else if (status == STATUS_DELETE) { /* Sorry, no mailbox here by that name. (#5.1.1) */ if (substdio_puts(subfdout, "DSorry, no mailbox here by that name. " "(#5.1.1)") == -1) die_write(); if (substdio_putflush(subfdout, "", 1) == -1) die_write(); qldap_free_results(q); return (1); } /* OK */ if (substdio_putflush(subfdout, "K", 1) == -1) die_write(); qldap_free_results(q); return (1); }
void main(int argc,char **argv) { char *dir; char *sender; char *moddir; const char *queryext = (char *) 0; int opt; int ret = 0; int dontact = 0; unsigned int i,j; const char *program; stralloc *opts; umask(022); sig_pipeignore(); /* storeopts to ezmlm-store only. Others to both (ezmlm-store may */ /* pass them on to ezmlm-send. */ if (!stralloc_copys(&sendopt,"-")) die_nomem(); if (!stralloc_copys(&storeopt,"-")) die_nomem(); while ((opt = getopt(argc,argv, "0cCmMpPq:Q:sSrRt:T:vVyY")) != opteof) switch(opt) { /* pass on unrecognized options */ case 'c': /* ezmlm-send flags */ case 'C': case 'r': case 'Q': case 'R': szchar[0] = opt; if (!stralloc_append(&sendopt,szchar)) die_nomem(); if (!stralloc_append(&storeopt,szchar)) die_nomem(); break; case 'm': /* ezmlm-store flags */ case 'M': case 'p': case 'P': case 's': case 'S': case 'y': case 'Y': szchar[0] = opt; if (!stralloc_append(&storeopt,szchar)) die_nomem(); break; case 'q': if (optarg) queryext = optarg; break; case 'v': case 'V': strerr_die2x(0,"ezmlm-gate version: ",auto_version); case '0': dontact = 1; break; default: /* ezmlm-store flags */ die_usage(); } startup(dir = argv[optind++]); sender = env_get("SENDER"); pmod = (char *) 0; if (queryext) { getconf(&cmds,queryext,1,dir); i = 0; for (j = 0;j < cmds.len; ++j) if (!cmds.s[j]) { switch (cmds.s[i]) { case '\0': case '#': break; /* ignore blank/comment */ case '|': ret = mailprog(cmds.s + i + 1); break; default: ret = mailprog(cmds.s + i); break; } if (ret) break; i = j + 1; } if (!ret || ret == 99) /* 111 => temp error */ pmod = ""; /* 0, 99 => post */ /* other => moderate */ } moddir = argv[optind++]; if (moddir && !ret) { /* if exit 0 and moddir, add issub */ pmod = (char *) 0; while (moddir && !pmod && sender) { pmod = (moddir[0] == '/') ? issub(moddir,0,sender) : issub(dir,moddir,sender); closesub(); moddir = argv[optind++]; } } if (pmod) { program = "/ezmlm-send"; opts = &sendopt; } else { program = "/ezmlm-store"; opts = &storeopt; } if (dontact) { substdio_puts(subfderr, auto_bin); substdio_puts(subfderr, program); substdio_put(subfderr, " ", 1); substdio_put(subfderr, opts->s, opts->len); substdio_put(subfderr, " ", 1); substdio_puts(subfderr, dir); substdio_putsflush(subfderr, "\n"); _exit(0); } if ((child = wrap_fork()) == 0) wrap_execbin(program, opts, dir); /* parent */ wrap_exitcode(child); _exit(0); }
void putstr(const char *s) { substdio_puts(&ssout,s); }
int main(int argc,char **argv) { unsigned long max; int fd; int fdlock; msgentry *msgtable; subentry *subtable; authentry *authtable; dateentry *datetable; (void) umask(022); sig_pipeignore(); getconfopt(argc,argv,options,1,0); if (flagsyncall) flagsync = 1; else if (flagcreate) flagsync = 0; archnum = (archnum / 100) * 100; /* Lock list to assure that no ezmlm-send is working on it */ /* and that the "num" message is final */ fdlock = lockfile("lock"); /* get num */ if (!getconf_ulong(&max,"num",0) || max == 0) strerr_die1x(100,MSG(ERR_EMPTY_LIST)); (void) close(fdlock); if (!optto || optto > max) optto = max; fdlock = lockfile("archive/lock"); /* lock index */ if (!flagcreate && !archnum) { /* adjust archnum (from) / to */ if (getconf_ulong(&archnum,"archnum",0)) ++archnum; else archnum = 0; } if (archnum > optto) _exit(0); /* nothing to do */ if (mkdir("archive/threads",0755) == -1) if (errno != error_exist) strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,"archive/threads")); if (mkdir("archive/subjects",0755) == -1) if (errno != error_exist) strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,"archive/subjects")); if (mkdir("archive/authors",0755) == -1) if (errno != error_exist) strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,"archive/authors")); /* do the subject threading */ idx_mkthreads(&msgtable,&subtable,&authtable,&datetable,archnum,optto,max,0); /* update the index */ write_threads(msgtable,subtable,authtable,datetable,archnum,optto); /* update archnum */ if ((fd = open_trunc("archnumn")) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,"archnumn")); substdio_fdbuf(&ssnum,write,fd,numbuf,sizeof(numbuf)); if (substdio_put(&ssnum,strnum,fmt_ulong(strnum,optto)) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); if (substdio_puts(&ssnum,"\n") == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn.s)); close_proper(&ssnum,"archnum","archnumn"); switch (flagerror) { case 0: _exit(0); /* go bye-bye */ case -1: strerr_die2x(99,WARNING,"threads entry with illegal format"); case -2: strerr_die2x(99,WARNING,"thread in index, but threadfile missing"); case -3: strerr_die2x(99,WARNING,"a subject file lacks subject"); case -4: strerr_die2x(99,WARNING,"an author file lacks author/hash"); case -5: strerr_die2x(99,WARNING,"threads entry lacks message count"); default: strerr_die2x(99,WARNING,"something happened that isn't quite right"); } }