int main(int argc, char **argv) { struct moduledel *p; int waitstat; const char *cp; clog_open_syslog("courierfax"); if (chdir(getenv("COURIER_HOME"))) clog_msg_errno(); cp=getenv("MAXDELS"); if (!cp || atoi(cp) != 1) { clog_msg_start_err(); clog_msg_str("FATAL: courierfax module misconfiguration, MAXDELS must be 1"); clog_msg_send(); exit(0); } cp=getenv("MAXRCPT"); if (!cp || atoi(cp) != 1) { clog_msg_start_err(); clog_msg_str("FATAL: courierfax module misconfiguration, MAXRCPT must be 1"); clog_msg_send(); exit(0); } module_init(0); while ((p=module_getdel()) != NULL) { pid_t pid; unsigned delid; delid=atol(p->delid); if ((pid=module_fork(delid, 0)) == -1) { clog_msg_prerrno(); module_completed(delid, delid); continue; } if (pid == 0) { fax(p); exit(0); } } module_signal(SIGTERM); signal(SIGCHLD, SIG_DFL); signal(SIGALRM, killit); alarm(5); wait(&waitstat); alarm(0); return (0); }
int main(int argc, char **argv) { struct moduledel *p; clog_open_syslog("courierlocal"); if (chdir(courier_home=getenv("COURIER_HOME"))) clog_msg_errno(); if (atol(getenv("MAXRCPT")) > 1) { clog_msg_start_err(); clog_msg_str("Invalid configuration in config, set MAXRCPT=1"); clog_msg_send(); exit(1); } module_init(0); module_delivery_timeout(config_readtime("localtimeout", 15*60)); while ((p=module_getdel()) != NULL) { unsigned delid=atol(p->delid); unsigned rcptnum; struct ctlfile ctf; int pipe1[2], pipe2[2]; pid_t pid; int datfd; struct stat stat_buf; pid=module_fork(delid, 0); if (pid < 0) { clog_msg_prerrno(); module_completed(delid, delid); continue; } if (pid) continue; #if HAVE_SETPGRP #if SETPGRP_VOID setpgrp(); #else setpgrp(0, 0); #endif #endif if (p->nreceipients != 1) { clog_msg_start_err(); clog_msg_str("Invalid message from courierd."); clog_msg_send(); _exit(0); } rcptnum=atol(p->receipients[0]); if (ctlfile_openi(p->inum, &ctf, 0)) { clog_msg_errno(); _exit(0); } if (pipe(pipe1) < 0 || pipe(pipe2) < 0 || (pid=fork()) < 0) { clog_msg_prerrno(); ctlfile_append_reply(&ctf, rcptnum, "Can't run courierdeliver.", COMCTLFILE_DELDEFERRED, 0); ctlfile_close(&ctf); _exit(0); return (0); } if ((datfd=open(qmsgsdatname(p->inum), O_RDONLY)) < 0) { clog_msg_prerrno(); ctlfile_append_reply(&ctf, rcptnum, "Unable to read message file.", COMCTLFILE_DELDEFERRED, 0); ctlfile_close(&ctf); _exit(0); return (0); } if (pid == 0) { const char *host, *homedir, *maildir, *quota; char *buf, *s; char *username, *ext; uid_t u; gid_t g; close(pipe1[0]); close(pipe2[0]); dup2(pipe2[1], 2); close(pipe2[1]); dup2(pipe1[1], 1); close(pipe1[1]); close(0); if (dup(datfd) != 0) { clog_msg_start_err(); clog_msg_str("Unable to read message file."); clog_msg_send(); _exit(EX_TEMPFAIL); } close(ctf.fd); close(datfd); /* Contents of host: */ /* acct!ext!uid!gid!homedir!maildir!quota */ host=p->host; buf=strdup(host); if (!buf) { clog_msg_prerrno(); _exit(EX_TEMPFAIL); } s=strchr(buf, '!'); username=buf; if (s) *s++=0; ext=s; if (s) s=strchr(s, '!'); if (s) *s++=0; u=0; while (s && *s != '!') { if (isdigit((int)(unsigned char)*s)) u=u*10 + (*s - '0'); ++s; } if (s) *s++=0; g=0; while (s && *s != '!') { if (isdigit((int)(unsigned char)*s)) g=g*10 + (*s - '0'); ++s; } if (s) *s++=0; homedir=s; if (s) s=strchr(s, '!'); if (s) *s++=0; maildir=s; if (s) s=strchr(s, '!'); if (s) *s++=0; quota=s; if (!s) { clog_msg_start_err(); clog_msg_str("Invalid local recipient address."); clog_msg_send(); _exit(EX_TEMPFAIL); } if (chdir(homedir)) { clog_msg_str(homedir); clog_msg_str(": "); clog_msg_prerrno(); _exit(EX_TEMPFAIL); } libmail_changeuidgid(u, g); execl( MODULEDIR "/local/courierdeliver", "courierdeliver", username, homedir, ext, ctf.receipients[rcptnum], verp_getsender(&ctf, ctf.receipients[rcptnum]), quota, maildir, (const char *)0); clog_msg_start_err(); clog_msg_prerrno(); clog_msg_send(); _exit(EX_TEMPFAIL); } close(pipe1[1]); close(pipe2[1]); libmail_changeuidgid(MAILUID, MAILGID); if (fstat(datfd, &stat_buf) == 0) ctf.msgsize=stat_buf.st_size; close(datfd); wait_delivery(pid, &ctf, rcptnum, pipe2[0], pipe1[0], p->host, p->receipients[1]); ctlfile_close(&ctf); _exit(0); } return (0); }