程序员眼中的qmail(qmail源代码分析){ "rcpt", smtp_rcpt, 0 } , { "mail", smtp_mail, 0 } , { "data", smtp_data, flush } //建立子进程执行qamil-queue,并向其传送邮件. , { "quit", smtp_quit, flush } , { "helo", smtp_helo, flush } , { "ehlo", smtp_ehlo, flush } , { "rset", smtp_rset, 0 } , { "help", smtp_help, flush } , { "noop", err_noop, flush } //实际上未实现的命令, { "vrfy", err_vrfy, flush } //实际上未实现的命令, { 0, err_unimpl, flush } //命令错误 } ; /* qmail-smtpd 是由tcpserver,或tcp-env之类的程式启动 tcpserver,tcp-env将来自网络的连接重定向到qmail-smtpd的标准输入及标准输出.这些程式建立一些环境变量(如TCPREMOTEHOST,TCPREMOTEIP)将由setup()函数使用 */ void main() { sig_pipeignore();//忽略信号. if (chdir(auto_qmail) == -1) die_control();//改变当前目录到 /var/qmail. setup();//读控制文件及相应的环境变量. if (ipme_init() != 1) die_ipme(); //取本地接口的IP地址: smtp_greet("220 "); //显示欢迎信息. out(" ESMTP\r\n"); //从标准输入(网络连接)读入smtp命令. if (commands(&ssin,&smtpcommands) == 0) die_read(); die_nomem(); } ==完== qmail-queue源代码分析 Programmer:夜未眠 Comefrom:ChongQing Gearbox co.,ltd 程序主要完成的功能是: 1.生成自已的邮件首部,也就是你在邮件头中见到的类似下面的东西 Recevied (qmail 855 invoked by uid 0); 2 May 2003 12:18:09 -0000 2.建立3个文件 queue/mess/ queue/intd/ queue/todo/ 3.写命名管道lock/trigger通知新邮件 代码: #define DEATH 86400 /* 24 hours; _must_ be below q-s's OSSIFIED (36 hours) */ #define ADDR 1003 char inbuf[2048]; struct substdio ssin; char outbuf[256]; struct substdio ssout; datetime_sec starttime; struct datetime dt; unsigned long mypid; unsigned long uid; char *pidfn; struct stat pidst; unsigned long messnum; char *messfn; char *todofn; char *intdfn; int messfd; int intdfd; int flagmademess = 0; int flagmadeintd = 0; //错误清理 void cleanup() { if (flagmadeintd) { seek_trunc(intdfd,0); if (unlink(intdfn) == -1) return; } if (flagmademess) { seek_trunc(messfd,0); if (unlink(messfn) == -1) return; } } void die(e) int e; { _exit(e); } void die_write() { cleanup(); die(53); } void die_read() { cleanup(); die(54); } void sigalrm() { /* thou shalt not clean up here */ die(52); } void sigbug() { die(81); } unsigned int receivedlen; char *received; static unsigned int receivedfmt(s) char *s; { unsigned int i; unsigned int len; len = 0; /*生成 /* "Received: (qmail-queue invoked by alias); 26 Sep 1995 04:46:54 -0000\n" */ [日 月 年 时 分 秒] 的形式. */ i = fmt_str(s,"Received: (qmail "); len += i; if (s) s += i; i = fmt_ulong(s,mypid); len += i; if (s) s += i; i = fmt_str(s," invoked "); len += i; if (s) s += i; if (uid == auto_uida) { i = fmt_str(s,"by alias"); len += i; if (s) s += i; } else if (uid == auto_uidd) { i = fmt_str(s,"from network"); len += i; if (s) s += i; } else if (uid == auto_uids) { i = fmt_str(s,"for bounce"); len += i; if (s) s += i; } else { i = fmt_str(s,"by uid "); len += i; if (s) s += i; i = fmt_ulong(s,uid); len += i; if (s) s += i; } i = fmt_str(s,"); "); len += i; if (s) s += i; i = date822fmt(s,&dt); len += i; if (s) s += i; return len; } void received_setup() { receivedlen = receivedfmt((char *) 0); received = alloc(receivedlen + 1); if (!received) die(51); receivedfmt(received); } unsigned int pidfmt(s,seq) char *s; unsigned long seq; { unsigned int i; unsigned int len; //生成类型pid/3434.34242424.1的字符串到s中 //这个字符串实际上就是/var/qmail/queue/pid目录下一个文件名。指示当前进程的pid. 上一篇:使用 Flex 和 Bison 更好地进行错误处理 下一篇:GNU 线性编程工具包(线性优化简介) 更多相关文章
|
推荐文章
精彩文章
|