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

📄 qmail-qmtpd.c

📁 linux下qmail的源码 本人加了一些注释
💻 C
字号:
//接受远程主机发来的qmtp连接请求

#include "stralloc.h"#include "substdio.h"#include "qmail.h"#include "now.h"#include "str.h"#include "fmt.h"#include "env.h"#include "sig.h"#include "rcpthosts.h"#include "auto_qmail.h"#include "readwrite.h"#include "control.h"#include "received.h"void badproto() { _exit(100); }void resources() { _exit(111); }int safewrite(fd,buf,len) int fd; char *buf; int len;{  int r;  r = write(fd,buf,len);  if (r <= 0) _exit(0);  return r;}char ssoutbuf[256];substdio ssout = SUBSTDIO_FDBUF(safewrite,1,ssoutbuf,sizeof ssoutbuf);int saferead(fd,buf,len) int fd; char *buf; int len;{  int r;  substdio_flush(&ssout);  r = read(fd,buf,len);  if (r <= 0) _exit(0);  return r;}char ssinbuf[512];substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof ssinbuf);unsigned long getlen(){  unsigned long len = 0;  char ch;  for (;;) {    substdio_get(&ssin,&ch,1);    if (ch == ':') return len;    if (len > 200000000) resources();    len = 10 * len + (ch - '0');  }}void getcomma(){  char ch;  substdio_get(&ssin,&ch,1);  if (ch != ',') badproto();}unsigned int databytes = 0;unsigned int bytestooverflow = 0;struct qmail qq;char buf[1000];char buf2[100];char *remotehost;char *remoteinfo;char *remoteip;char *local;stralloc failure = {0};char *relayclient;int relayclientlen;main(){  char ch;  int i;  unsigned long biglen;  unsigned long len;  int flagdos;  int flagsenderok;  int flagbother;  unsigned long qp;  char *result;  char *x;  unsigned long u;   sig_pipeignore();  sig_alarmcatch(resources);  alarm(3600);   if (chdir(auto_qmail) == -1) resources();   if (control_init() == -1) resources();  if (rcpthosts_init() == -1) resources();  relayclient = env_get("RELAYCLIENT");  relayclientlen = relayclient ? str_len(relayclient) : 0;   if (control_readint(&databytes,"control/databytes") == -1) resources();  x = env_get("DATABYTES");  if (x) { scan_ulong(x,&u); databytes = u; }  if (!(databytes + 1)) --databytes;   remotehost = env_get("TCPREMOTEHOST");  if (!remotehost) remotehost = "unknown";  remoteinfo = env_get("TCPREMOTEINFO");  remoteip = env_get("TCPREMOTEIP");  if (!remoteip) remoteip = "unknown";  local = env_get("TCPLOCALHOST");  if (!local) local = env_get("TCPLOCALIP");  if (!local) local = "unknown";   for (;;) {    if (!stralloc_copys(&failure,"")) resources();    flagsenderok = 1;     len = getlen();    if (len == 0) badproto();     if (databytes) bytestooverflow = databytes + 1;    if (qmail_open(&qq) == -1) resources();    qp = qmail_qp(&qq);     substdio_get(&ssin,&ch,1);    --len;    if (ch == 10) flagdos = 0;    else if (ch == 13) flagdos = 1;    else badproto();     received(&qq,"QMTP",local,remoteip,remotehost,remoteinfo,(char *) 0);     /* XXX: check for loops? only if len is big? */     if (flagdos)      while (len > 0) {        substdio_get(&ssin,&ch,1);        --len;        while ((ch == 13) && len) {          substdio_get(&ssin,&ch,1);          --len;          if (ch == 10) break;          if (bytestooverflow) if (!--bytestooverflow) qmail_fail(&qq);          qmail_put(&qq,"\015",1);        }        if (bytestooverflow) if (!--bytestooverflow) qmail_fail(&qq);        qmail_put(&qq,&ch,1);      }    else {      if (databytes)        if (len > databytes) {          bytestooverflow = 0;          qmail_fail(&qq);        }      while (len > 0) { /* XXX: could speed this up, obviously */        substdio_get(&ssin,&ch,1);        --len;        qmail_put(&qq,&ch,1);      }    }    getcomma();     len = getlen();     if (len >= 1000) {      buf[0] = 0;      flagsenderok = 0;      for (i = 0;i < len;++i)        substdio_get(&ssin,&ch,1);    }    else {      for (i = 0;i < len;++i) {        substdio_get(&ssin,buf + i,1);        if (!buf[i]) flagsenderok = 0;      }      buf[len] = 0;    }    getcomma();     flagbother = 0;    qmail_from(&qq,buf);    if (!flagsenderok) qmail_fail(&qq);     biglen = getlen();    while (biglen > 0) {      if (!stralloc_append(&failure,"")) resources();       len = 0;      for (;;) {        if (!biglen) badproto();        substdio_get(&ssin,&ch,1);        --biglen;        if (ch == ':') break;        if (len > 200000000) resources();        len = 10 * len + (ch - '0');      }      if (len >= biglen) badproto();      if (len + relayclientlen >= 1000) {        failure.s[failure.len - 1] = 'L';        for (i = 0;i < len;++i)          substdio_get(&ssin,&ch,1);      }      else {        for (i = 0;i < len;++i) {          substdio_get(&ssin,buf + i,1);          if (!buf[i]) failure.s[failure.len - 1] = 'N';        }        buf[len] = 0;         if (relayclient)          str_copy(buf + len,relayclient);        else          switch(rcpthosts(buf,len)) {            case -1: resources();            case 0: failure.s[failure.len - 1] = 'D';          }         if (!failure.s[failure.len - 1]) {          qmail_to(&qq,buf);          flagbother = 1;        }      }      getcomma();      biglen -= (len + 1);    }    getcomma();     if (!flagbother) qmail_fail(&qq);    result = qmail_close(&qq);    if (!flagsenderok) result = "Dunacceptable sender (#5.1.7)";    if (databytes) if (!bytestooverflow) result = "Dsorry, that message size exceeds my databytes limit (#5.3.4)";     if (*result)      len = str_len(result);    else {      /* success! */      len = 0;      len += fmt_str(buf2 + len,"Kok ");      len += fmt_ulong(buf2 + len,(unsigned long) now());      len += fmt_str(buf2 + len," qp ");      len += fmt_ulong(buf2 + len,qp);      buf2[len] = 0;      result = buf2;    }          len = fmt_ulong(buf,len);    buf[len++] = ':';    len += fmt_str(buf + len,result);    buf[len++] = ',';     for (i = 0;i < failure.len;++i)      switch(failure.s[i]) {        case 0:          substdio_put(&ssout,buf,len);          break;        case 'D':          substdio_puts(&ssout,"66:Dsorry, that domain isn't in my list of allowed rcpthosts (#5.7.1),");          break;        default:          substdio_puts(&ssout,"46:Dsorry, I can't handle that recipient (#5.1.3),");          break;      }     /* ssout will be flushed when we read from the network again */  }}

⌨️ 快捷键说明

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