我分析的代码没有“夜未眠”大哥的好,可能还有的不正确,就请各位多多指教,谢谢 [code:1:c552cb0758]#include #include #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); }/*删除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/");/*将"tmp/"拷到s中*/ s += fmt_ulong(s,time); *s++ = '.';/*将时间转化为字符串*/ s += fmt_ulong(s,pid); *s++ = '.'; s += fmt_strn(s,host,sizeof(host)); *s++ = 0; if (stat(fntmptph,%26amp;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"); //时间为24小时 alarm(86400); fd = open_excl(fntmptph); if (fd == -1) _exit(1); /////////////////////////////////////////////////// substdio_fdbuf(%26amp;ss,read,0,buf,sizeof(buf)); substdio_fdbuf(%26amp;ssout,write,fd,outbuf,sizeof(outbuf)); //dtline:邮件头Delivered-To部分 //rpline:邮件头返回路径 //无需"From "头部 if (substdio_put(%26amp;ssout,rpline.s,rpline.len) == -1) goto fail; if (substdio_put(%26amp;ssout,dtline.s,dtline.len) == -1) goto fail; //将邮件写到文件fd中 switch(substdio_copy(%26amp;ssout,%26amp;ss)) { case -2: tryunlinktmp(); _exit(4); case -3: goto fail; }
if (substdio_flush(%26amp;ssout) == -1) goto fail; //将fd所指文件数据由系统缓冲区写回磁盘正确返回0,错误返回-1 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 */ //maildir 格式邮箱的邮件投递,不要锁定 void maildir(fn) char *fn; { int child; int wstat; //#define seek_begin(fd) (seek_set((fd),(seek_pos) 0)) //指向文件0的开头 if (seek_begin(0) == -1) temp_rewind();
switch(child = fork()) { case -1: temp_fork(); case 0: maildir_child(fn);///////////////////////////////////// _exit(111); } //返回子进程fd的结束状态值于wstat中 wait_pid(%26amp;wstat,child); //#define wait_crashed(w) ((w) %26amp; 127) if (wait_crashed(wstat)) temp_childcrashed(); //#define wait_exitcode(w) ((w) >> 8) 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)"); } }
如果您对本文有任何疑问或者建议,请到讨论区发表您的意见:
>>
论坛入口 <<
上一篇:qmail-send代码分析 下一篇:qmail sendmail postfix 三种MTA的分析比较
【文章评论】
【收藏本文】
【推荐好友】
【打印本文】
【我要投稿】 【论坛讨论】
更多相关文章
|
|