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

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

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

  }

  char ssinbuf[1024];

  substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof ssinbuf);

  struct qmail qqt;

  unsigned int bytestooverflow = 0;

  void put(ch)

  char *ch;

  {

  if (bytestooverflow)

  if (!--bytestooverflow)

  qmail_fail(&qqt);

  qmail_put(&qqt,ch,1);

  }

  void blast(hops)

  int *hops;

  {

  char ch;

  int state;

  int flaginheader;

  int pos; /* number of bytes since most recent \n, if fih */

  int flagmaybex; /* 1 if this line might match RECEIVED, if fih */

  int flagmaybey; /* 1 if this line might match \r\n, if fih */

  int flagmaybez; /* 1 if this line might match DELIVERED, if fih */

  state = 1;

  *hops = 0;

  flaginheader = 1;

  pos = 0; flagmaybex = flagmaybey = flagmaybez = 1;

  for (;;) {

  substdio_get(&ssin,&ch,1);//从标准输入(也就是网络)读邮件内容直到读到仅有一个点的行.

  if (flaginheader) {

  if (pos < 9) {

  if (ch != "delivered"[pos]) if (ch != "DELIVERED"[pos]) flagmaybez = 0;

  if (flagmaybez) if (pos == 8) ++*hops;

  if (pos < 8)

  if (ch != "received"[pos]) if (ch != "RECEIVED"[pos]) flagmaybex = 0;

  if (flagmaybex) if (pos == 7) ++*hops;

  if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0;

  if (flagmaybey) if (pos == 1) flaginheader = 0;

  }

  ++pos;

  if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; }

  }

  switch(state) {

  case 0:

  if (ch == '\n') straynewline();

  if (ch == '\r') { state = 4; continue; }

  break;

  case 1: /* \r\n */

  if (ch == '\n') straynewline();

  if (ch == '.') { state = 2; continue; }

  if (ch == '\r') { state = 4; continue; }

  state = 0;

  break;

  case 2: /* \r\n + . */

  if (ch == '\n') straynewline();

  if (ch == '\r') { state = 3; continue; }

  state = 0;

  break;

  case 3: /* \r\n + .\r */

  if (ch == '\n') return;

  put(".");

  put("\r");

  if (ch == '\r') { state = 4; continue; }

  state = 0;

  break;

  case 4: /* + \r */

  if (ch == '\n') { state = 1; break; }

  if (ch != '\r') { put("\r"); state = 0; }

  }

  put(&ch);

  }

  }

  char accept_buf[FMT_ULONG];

  void acceptmessage(qp) unsigned long qp;

  {

  datetime_sec when;

  when = now();

  out("250 ok ");

  accept_buf[fmt_ulong(accept_buf,(unsigned long) when)] = 0;

  out(accept_buf);

  out(" qp ");

  accept_buf[fmt_ulong(accept_buf,qp)] = 0;

  out(accept_buf);

  out("\r\n");

  }

  //data 命令解释程式

  //完成向qmail-queue投递邮件

  void smtp_data() {

  int hops;

  unsigned long qp;

  char *qqx;

  if (!seenmail) { err_wantmail(); return; } //如果没有执行过mail命令,出错返回

  if (!rcptto.len) { err_wantrcpt(); return; } //如果没有执行rcpt命令,出错返回

  seenmail = 0; //将mail命令标志失效,

  //databytes 邮件最大长度,如果没有指定那么它的值将是0

  if (databytes) bytestooverflow = databytes + 1;

  if (qmail_open(&qqt) == -1) { err_qqt(); return; }//建立子进程执行qmail-queue

  qp = qmail_qp(&qqt); //qp 为qmail-queue process缩写,it's a process id.

  out("354 go ahead\r\n");

  //向新建立的进程传送邮件头

  received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo);

  blast(&hops);

  hops = (hops >= MAXHOPS);

  if (hops) qmail_fail(&qqt);

  //向qmail-queue传送邮件头信息.

  //如果hong@hg.org 向 lyx@hg.org发送邮件,那么向qmail-queue传送的字符串将是

  // Fhong@hg.orgTlyx@hg.org

  qmail_from(&qqt,mailfrom.s);

  qmail_put(&qqt,rcptto.s,rcptto.len);

  qqx = qmail_close(&qqt);

  if (!*qqx) { acceptmessage(qp); return; }//如果接收成功

  if (hops) { out("554 too many hops, this message is looping (#5.4.6)\r\n"); return; }

  if (databytes) if (!bytestooverflow) { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return; }

  if (*qqx == 'D') out("554 "); else out("451 ");

  out(qqx + 1);

  out("\r\n");

  }

  //smtp命令处理函数表

  struct commands smtpcommands[] = {

 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



上一篇:使用 Flex 和 Bison 更好地进行错误处理   下一篇:GNU 线性编程工具包(线性优化简介)

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