⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qmail-local.c

📁 linux下qmail的源码 本人加了一些注释
💻 C
📖 第 1 页 / 共 2 页
字号:
//向本地邮件系统上的用户投递消息

#include <sys/types.h>#include <sys/stat.h>#include "readwrite.h"#include "sig.h"#include "env.h"#include "byte.h"#include "exit.h"#include "fork.h"#include "open.h"#include "wait.h"#include "lock.h"#include "seek.h"#include "substdio.h"#include "getln.h"#include "strerr.h"#include "subfd.h"#include "sgetopt.h"#include "alloc.h"#include "error.h"#include "stralloc.h"#include "fmt.h"#include "str.h"#include "now.h"#include "case.h"#include "quote.h"#include "qmail.h"#include "slurpclose.h"#include "myctime.h"#include "gfrom.h"#include "auto_patrn.h"void usage() { strerr_die1x(100,"qmail-local: usage: qmail-local [ -nN ] user homedir local dash ext domain sender aliasempty"); }void temp_nomem() { strerr_die1x(111,"Out of memory. (#4.3.0)"); }void temp_rewind() { strerr_die1x(111,"Unable to rewind message. (#4.3.0)"); }void temp_childcrashed() { strerr_die1x(111,"Aack, child crashed. (#4.3.0)"); }void temp_fork() { strerr_die3x(111,"Unable to fork: ",error_str(errno),". (#4.3.0)"); }void temp_read() { strerr_die3x(111,"Unable to read message: ",error_str(errno),". (#4.3.0)"); }void temp_slowlock(){ strerr_die1x(111,"File has been locked for 30 seconds straight. (#4.3.0)"); }void temp_qmail(fn) char *fn;{ strerr_die5x(111,"Unable to open ",fn,": ",error_str(errno),". (#4.3.0)"); }int flagdoit;int flag99;char *user;char *homedir;char *local;char *dash;char *ext;char *host;char *sender;char *aliasempty;stralloc safeext = {0};stralloc ufline = {0};stralloc rpline = {0};stralloc envrecip = {0};stralloc dtline = {0};stralloc qme = {0};stralloc ueo = {0};stralloc cmds = {0};stralloc messline = {0};stralloc foo = {0};char buf[1024];char outbuf[1024];/* child process */char fntmptph[80 + FMT_ULONG * 2];char fnnewtph[80 + FMT_ULONG * 2];void tryunlinktmp() { unlink(fntmptph); }void sigalrm() { tryunlinktmp(); _exit(3); }void maildir_child(dir)char *dir;{ unsigned long pid; unsigned long time; char host[64]; char *s; int loop; struct stat st; int fd; substdio ss; substdio ssout; sig_alarmcatch(sigalrm); if (chdir(dir) == -1) { if (error_temp(errno)) _exit(1); _exit(2); } pid = getpid(); host[0] = 0; gethostname(host,sizeof(host)); for (loop = 0;;++loop)  {   time = now();   s = fntmptph;   s += fmt_str(s,"tmp/");   s += fmt_ulong(s,time); *s++ = '.';   s += fmt_ulong(s,pid); *s++ = '.';   s += fmt_strn(s,host,sizeof(host)); *s++ = 0;   if (stat(fntmptph,&st) == -1) if (errno == error_noent) break;   /* really should never get to this point */   if (loop == 2) _exit(1);   sleep(2);  } str_copy(fnnewtph,fntmptph); byte_copy(fnnewtph,3,"new"); alarm(86400); fd = open_excl(fntmptph); if (fd == -1) _exit(1); substdio_fdbuf(&ss,read,0,buf,sizeof(buf)); substdio_fdbuf(&ssout,write,fd,outbuf,sizeof(outbuf)); if (substdio_put(&ssout,rpline.s,rpline.len) == -1) goto fail; if (substdio_put(&ssout,dtline.s,dtline.len) == -1) goto fail; switch(substdio_copy(&ssout,&ss))  {   case -2: tryunlinktmp(); _exit(4);   case -3: goto fail;  } if (substdio_flush(&ssout) == -1) goto fail; if (fsync(fd) == -1) goto fail; if (close(fd) == -1) goto fail; /* NFS dorks */ if (link(fntmptph,fnnewtph) == -1) goto fail;   /* if it was error_exist, almost certainly successful; i hate NFS */ tryunlinktmp(); _exit(0); fail: tryunlinktmp(); _exit(1);}/* end child process */void maildir(fn)char *fn;{ int child; int wstat; if (seek_begin(0) == -1) temp_rewind(); switch(child = fork())  {   case -1:     temp_fork();   case 0:     maildir_child(fn);     _exit(111);  } wait_pid(&wstat,child); if (wait_crashed(wstat))   temp_childcrashed(); 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)");  }}void mailfile(fn)char *fn;{ int fd; substdio ss; substdio ssout; int match; seek_pos pos; int flaglocked; if (seek_begin(0) == -1) temp_rewind(); fd = open_append(fn); if (fd == -1)   strerr_die5x(111,"Unable to open ",fn,": ",error_str(errno),". (#4.2.1)"); sig_alarmcatch(temp_slowlock); alarm(30); flaglocked = (lock_ex(fd) != -1); alarm(0); sig_alarmdefault(); seek_end(fd); pos = seek_cur(fd); substdio_fdbuf(&ss,read,0,buf,sizeof(buf)); substdio_fdbuf(&ssout,write,fd,outbuf,sizeof(outbuf)); if (substdio_put(&ssout,ufline.s,ufline.len)) goto writeerrs; if (substdio_put(&ssout,rpline.s,rpline.len)) goto writeerrs; if (substdio_put(&ssout,dtline.s,dtline.len)) goto writeerrs; for (;;)  {   if (getln(&ss,&messline,&match,'\n') != 0)     {     strerr_warn3("Unable to read message: ",error_str(errno),". (#4.3.0)",0);     if (flaglocked) seek_trunc(fd,pos); close(fd);     _exit(111);    }   if (!match && !messline.len) break;   if (gfrom(messline.s,messline.len))     if (substdio_bput(&ssout,">",1)) goto writeerrs;   if (substdio_bput(&ssout,messline.s,messline.len)) goto writeerrs;   if (!match)    {     if (substdio_bputs(&ssout,"\n")) goto writeerrs;     break;    }  } if (substdio_bputs(&ssout,"\n")) goto writeerrs; if (substdio_flush(&ssout)) goto writeerrs; if (fsync(fd) == -1) goto writeerrs; close(fd); return; writeerrs: strerr_warn5("Unable to write ",fn,": ",error_str(errno),". (#4.3.0)",0); if (flaglocked) seek_trunc(fd,pos); close(fd); _exit(111);}void mailprogram(prog)char *prog;{ int child; char *(args[4]); int wstat; if (seek_begin(0) == -1) temp_rewind(); switch(child = fork())  {   case -1:     temp_fork();   case 0:     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)");  } wait_pid(&wstat,child); if (wait_crashed(wstat))   temp_childcrashed(); switch(wait_exitcode(wstat))  {   case 100:   case 64: case 65: case 70: case 76: case 77: case 78: case 112: _exit(100);   case 0: break;   case 99: flag99 = 1; break;   default: _exit(111);  }}unsigned long mailforward_qp = 0;void mailforward(recips)char **recips;{ struct qmail qqt; char *qqx; substdio ss; int match; if (seek_begin(0) == -1) temp_rewind(); substdio_fdbuf(&ss,read,0,buf,sizeof(buf)); if (qmail_open(&qqt) == -1) temp_fork(); mailforward_qp = qmail_qp(&qqt); qmail_put(&qqt,dtline.s,dtline.len); do  {   if (getln(&ss,&messline,&match,'\n') != 0) { qmail_fail(&qqt); break; }   qmail_put(&qqt,messline.s,messline.len);  } while (match); qmail_from(&qqt,ueo.s); while (*recips) qmail_to(&qqt,*recips++); qqx = qmail_close(&qqt); if (!*qqx) return; strerr_die3x(*qqx == 'D' ? 100 : 111,"Unable to forward message: ",qqx + 1,".");}void bouncexf(){ int match; substdio ss; if (seek_begin(0) == -1) temp_rewind(); substdio_fdbuf(&ss,read,0,buf,sizeof(buf)); for (;;)  {   if (getln(&ss,&messline,&match,'\n') != 0) temp_read();   if (!match) break;   if (messline.len <= 1)     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)");  }}void checkhome(){ struct stat st; if (stat(".",&st) == -1)   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)"); if (st.st_mode & 01000)   if (flagdoit)     strerr_die1x(111,"Home directory is sticky: user is editing his .qmail file. (#4.2.1)");   else     strerr_warn1("Warning: home directory is sticky.",0);}int qmeox(dashowner)char *dashowner;{ struct stat st; if (!stralloc_copys(&qme,".qmail")) temp_nomem(); if (!stralloc_cats(&qme,dash)) temp_nomem(); if (!stralloc_cat(&qme,&safeext)) temp_nomem(); if (!stralloc_cats(&qme,dashowner)) temp_nomem(); if (!stralloc_0(&qme)) temp_nomem(); if (stat(qme.s,&st) == -1)  {   if (error_temp(errno)) temp_qmail(qme.s);   return -1;  } return 0;}int qmeexists(fd,cutable)int *fd;int *cutable;{  struct stat st;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -