Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->Linux程序设计 ->正文

程序员眼中的qmail(qmail源代码分析)

来源:5dmail.net 作者:未知  时间:2007-04-22 点击: [收藏] [投稿]

  { "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/ 用户id,进程id,mailfrom,rcptto

  queue/todo/ 是intd目录下文件的复本.

  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 线性编程工具包(线性优化简介)

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章
Power by linux-cn.com 粤ICP备05006655号