亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? qmail-send.c

?? linux下qmail的源碼 本人加了一些注釋
?? C
?? 第 1 頁 / 共 3 頁
字號:
//	qmail-send用來檢測隊列中每一個郵件的狀態(tài),并調(diào)用相應的程序進行處理。
//例如一個目的為本地的郵件將會被qmail-send調(diào)用qmail-lspawn處理

#include <sys/types.h>#include <sys/stat.h>#include "readwrite.h"#include "sig.h"#include "direntry.h"#include "control.h"#include "select.h"#include "open.h"#include "seek.h"#include "exit.h"#include "lock.h"#include "ndelay.h"#include "now.h"#include "getln.h"#include "substdio.h"#include "alloc.h"#include "error.h"#include "stralloc.h"#include "str.h"#include "byte.h"#include "fmt.h"#include "scan.h"#include "case.h"#include "auto_qmail.h"#include "trigger.h"#include "newfield.h"#include "quote.h"#include "qmail.h"#include "qsutil.h"#include "prioq.h"#include "constmap.h"#include "fmtqfn.h"#include "readsubdir.h"/* critical timing feature #1: if not triggered, do not busy-loop *//* critical timing feature #2: if triggered, respond within fixed time *//* important timing feature: when triggered, respond instantly */#define SLEEP_TODO 1500 /* check todo/ every 25 minutes in any case */#define SLEEP_FUZZ 1 /* slop a bit on sleeps to avoid zeno effect */#define SLEEP_FOREVER 86400 /* absolute maximum time spent in select() */#define SLEEP_CLEANUP 76431 /* time between cleanups */#define SLEEP_SYSFAIL 123#define OSSIFIED 129600 /* 36 hours; _must_ exceed q-q's DEATH (24 hours) */int lifetime = 604800;
//	在UUCP協(xié)議中帶有%并在percenthack中列出的地址將會被轉(zhuǎn)換為一個標準的DNS格式主機名stralloc percenthack = {0};struct constmap mappercenthack;

//	用來為qmail指明位于本地的郵件地址。qmail-send利用此文件來判斷收件人地址是否是
//一個本地地址,qmail-send檢測到隊列中有發(fā)送給本地地址的郵件的時候,就會調(diào)用
//qmail-lspawn來進行本地投送stralloc locals = {0};struct constmap maplocals;stralloc vdoms = {0};struct constmap mapvdoms;

//	qmail-send用來給沒有主機名的郵件收件人制定一個主機名,通常并沒有必要,qmail-send
//總是使用me中的域名stralloc envnoathost = {0};

//	默認情況下,退回給原始發(fā)送方的郵件的發(fā)件人地址為MAILER-DAEMON@HOSTNAME,
//如果想修改MAILER-DAEMON,需要修改bouncefrom
//如果想修改HOSTNAME,需要修改bouncehoststralloc bouncefrom = {0};stralloc bouncehost = {0};

//	類似與上面的關系,doublebouncehost指定主機名,doublebounceto指定用戶名。
//功能是為一個被退回兩次的郵件制定一條出路。stralloc doublebounceto = {0};stralloc doublebouncehost = {0};char strnum2[FMT_ULONG];char strnum3[FMT_ULONG];#define CHANNELS 2char *chanaddr[CHANNELS] = { "local/", "remote/" };char *chanstatusmsg[CHANNELS] = { " local ", " remote " };char *tochan[CHANNELS] = { " to local ", " to remote " };int chanfdout[CHANNELS] = { 1, 3 };int chanfdin[CHANNELS] = { 2, 4 };int chanskip[CHANNELS] = { 10, 20 };int flagexitasap = 0; void sigterm() { flagexitasap = 1; }int flagrunasap = 0; void sigalrm() { flagrunasap = 1; }int flagreadasap = 0; void sighup() { flagreadasap = 1; }void cleandied() { log1("alert: oh no! lost qmail-clean connection! dying...\n"); flagexitasap = 1; }int flagspawnalive[CHANNELS];void spawndied(c) int c; { log1("alert: oh no! lost spawn connection! dying...\n"); flagspawnalive[c] = 0; flagexitasap = 1; }#define REPORTMAX 10000datetime_sec recent;/* this file is too long ----------------------------------------- FILENAMES */stralloc fn = {0};stralloc fn2 = {0};char fnmake_strnum[FMT_ULONG];void fnmake_init(){ while (!stralloc_ready(&fn,FMTQFN)) nomem(); while (!stralloc_ready(&fn2,FMTQFN)) nomem();}void fnmake_info(id) unsigned long id; { fn.len = fmtqfn(fn.s,"info/",id,1); }void fnmake_todo(id) unsigned long id; { fn.len = fmtqfn(fn.s,"todo/",id,0); }void fnmake_mess(id) unsigned long id; { fn.len = fmtqfn(fn.s,"mess/",id,1); }void fnmake_foop(id) unsigned long id; { fn.len = fmtqfn(fn.s,"foop/",id,0); }void fnmake_split(id) unsigned long id; { fn.len = fmtqfn(fn.s,"",id,1); }void fnmake2_bounce(id) unsigned long id;{ fn2.len = fmtqfn(fn2.s,"bounce/",id,0); }void fnmake_chanaddr(id,c) unsigned long id; int c;{ fn.len = fmtqfn(fn.s,chanaddr[c],id,1); }/* this file is too long ----------------------------------------- REWRITING */stralloc rwline = {0};/* 1 if by land, 2 if by sea, 0 if out of memory. not allowed to barf. *//* may trash recip. must set up rwline, between a T and a \0. */int rewrite(recip)char *recip;{  int i;  int j;  char *x;  static stralloc addr = {0};  int at;  if (!stralloc_copys(&rwline,"T")) return 0;  if (!stralloc_copys(&addr,recip)) return 0;  i = byte_rchr(addr.s,addr.len,'@');  if (i == addr.len) {    if (!stralloc_cats(&addr,"@")) return 0;    if (!stralloc_cat(&addr,&envnoathost)) return 0;  }  while (constmap(&mappercenthack,addr.s + i + 1,addr.len - i - 1)) {    j = byte_rchr(addr.s,i,'%');    if (j == i) break;    addr.len = i;    i = j;    addr.s[i] = '@';  }  at = byte_rchr(addr.s,addr.len,'@');  if (constmap(&maplocals,addr.s + at + 1,addr.len - at - 1)) {    if (!stralloc_cat(&rwline,&addr)) return 0;    if (!stralloc_0(&rwline)) return 0;    return 1;  }  for (i = 0;i <= addr.len;++i)    if (!i || (i == at + 1) || (i == addr.len) || ((i > at) && (addr.s[i] == '.')))      if (x = constmap(&mapvdoms,addr.s + i,addr.len - i)) {        if (!*x) break;        if (!stralloc_cats(&rwline,x)) return 0;        if (!stralloc_cats(&rwline,"-")) return 0;        if (!stralloc_cat(&rwline,&addr)) return 0;        if (!stralloc_0(&rwline)) return 0;        return 1;      }   if (!stralloc_cat(&rwline,&addr)) return 0;  if (!stralloc_0(&rwline)) return 0;  return 2;}void senderadd(sa,sender,recip)stralloc *sa;char *sender;char *recip;{ int i; int j; int k; i = str_len(sender); if (i >= 4)   if (str_equal(sender + i - 4,"-@[]"))    {     j = byte_rchr(sender,i - 4,'@');     k = str_rchr(recip,'@');     if (recip[k] && (j + 5 <= i))      {       /* owner-@host-@[] -> owner-recipbox=reciphost@host */       while (!stralloc_catb(sa,sender,j)) nomem();       while (!stralloc_catb(sa,recip,k)) nomem();       while (!stralloc_cats(sa,"=")) nomem();       while (!stralloc_cats(sa,recip + k + 1)) nomem();       while (!stralloc_cats(sa,"@")) nomem();       while (!stralloc_catb(sa,sender + j + 1,i - 5 - j)) nomem();       return;      }    } while (!stralloc_cats(sa,sender)) nomem();}/* this file is too long ---------------------------------------------- INFO */int getinfo(sa,dt,id)stralloc *sa;datetime_sec *dt;unsigned long id;{ int fdinfo; struct stat st; static stralloc line = {0}; int match; substdio ss; char buf[128]; fnmake_info(id); fdinfo = open_read(fn.s); if (fdinfo == -1) return 0; if (fstat(fdinfo,&st) == -1) { close(fdinfo); return 0; } substdio_fdbuf(&ss,read,fdinfo,buf,sizeof(buf)); if (getln(&ss,&line,&match,'\0') == -1) { close(fdinfo); return 0; } close(fdinfo); if (!match) return 0; if (line.s[0] != 'F') return 0; *dt = st.st_mtime; while (!stralloc_copys(sa,line.s + 1)) nomem(); while (!stralloc_0(sa)) nomem(); return 1;}/* this file is too long ------------------------------------- COMMUNICATION */substdio sstoqc; char sstoqcbuf[1024];substdio ssfromqc; char ssfromqcbuf[1024];stralloc comm_buf[CHANNELS] = { {0}, {0} };int comm_pos[CHANNELS];void comm_init(){ int c; substdio_fdbuf(&sstoqc,write,5,sstoqcbuf,sizeof(sstoqcbuf)); substdio_fdbuf(&ssfromqc,read,6,ssfromqcbuf,sizeof(ssfromqcbuf)); for (c = 0;c < CHANNELS;++c)   if (ndelay_on(chanfdout[c]) == -1)   /* this is so stupid: NDELAY semantics should be default on write */     spawndied(c); /* drastic, but better than risking deadlock */}int comm_canwrite(c)int c;{ /* XXX: could allow a bigger buffer; say 10 recipients */ if (comm_buf[c].s && comm_buf[c].len) return 0; return 1;}void comm_write(c,delnum,id,sender,recip)int c;int delnum;unsigned long id;char *sender;char *recip;{ char ch; if (comm_buf[c].s && comm_buf[c].len) return; while (!stralloc_copys(&comm_buf[c],"")) nomem(); ch = delnum; while (!stralloc_append(&comm_buf[c],&ch)) nomem(); fnmake_split(id); while (!stralloc_cats(&comm_buf[c],fn.s)) nomem(); while (!stralloc_0(&comm_buf[c])) nomem(); senderadd(&comm_buf[c],sender,recip); while (!stralloc_0(&comm_buf[c])) nomem(); while (!stralloc_cats(&comm_buf[c],recip)) nomem(); while (!stralloc_0(&comm_buf[c])) nomem(); comm_pos[c] = 0;}void comm_selprep(nfds,wfds)int *nfds;fd_set *wfds;{ int c; for (c = 0;c < CHANNELS;++c)   if (flagspawnalive[c])     if (comm_buf[c].s && comm_buf[c].len)      {       FD_SET(chanfdout[c],wfds);       if (*nfds <= chanfdout[c])         *nfds = chanfdout[c] + 1;      }}void comm_do(wfds)fd_set *wfds;{ int c; for (c = 0;c < CHANNELS;++c)   if (flagspawnalive[c])     if (comm_buf[c].s && comm_buf[c].len)       if (FD_ISSET(chanfdout[c],wfds))        {         int w;         int len;         len = comm_buf[c].len;         w = write(chanfdout[c],comm_buf[c].s + comm_pos[c],len - comm_pos[c]);         if (w <= 0)	  {	   if ((w == -1) && (errno == error_pipe))	     spawndied(c);	   else	     continue; /* kernel select() bug; can't avoid busy-looping */	  }	 else	  {	   comm_pos[c] += w;	   if (comm_pos[c] == len)	     comm_buf[c].len = 0;	  }        }}/* this file is too long ------------------------------------------ CLEANUPS */int flagcleanup; /* if 1, cleanupdir is initialized and ready */readsubdir cleanupdir;datetime_sec cleanuptime;void cleanup_init(){ flagcleanup = 0; cleanuptime = now();}void cleanup_selprep(wakeup)datetime_sec *wakeup;{ if (flagcleanup) *wakeup = 0; if (*wakeup > cleanuptime) *wakeup = cleanuptime;}void cleanup_do(){ char ch; struct stat st; unsigned long id; if (!flagcleanup)  {   if (recent < cleanuptime) return;   readsubdir_init(&cleanupdir,"mess",pausedir);   flagcleanup = 1;  } switch(readsubdir_next(&cleanupdir,&id))  {   case 1:     break;   case 0:     flagcleanup = 0;     cleanuptime = recent + SLEEP_CLEANUP;   default:     return;  } fnmake_mess(id); if (stat(fn.s,&st) == -1) return; /* probably qmail-queue deleted it */ if (recent <= st.st_atime + OSSIFIED) return; fnmake_info(id); if (stat(fn.s,&st) == 0) return; if (errno != error_noent) return; fnmake_todo(id); if (stat(fn.s,&st) == 0) return; if (errno != error_noent) return; fnmake_foop(id); if (substdio_putflush(&sstoqc,fn.s,fn.len) == -1) { cleandied(); return; } if (substdio_get(&ssfromqc,&ch,1) != 1) { cleandied(); return; } if (ch != '+')   log3("warning: qmail-clean unable to clean up ",fn.s,"\n");}/* this file is too long ----------------------------------- PRIORITY QUEUES */prioq pqdone = {0}; /* -todo +info; HOPEFULLY -local -remote */prioq pqchan[CHANNELS] = { {0}, {0} };/* pqchan 0: -todo +info +local ?remote *//* pqchan 1: -todo +info ?local +remote */prioq pqfail = {0}; /* stat() failure; has to be pqadded again */void pqadd(id)unsigned long id;{ struct prioq_elt pe; struct prioq_elt pechan[CHANNELS]; int flagchan[CHANNELS]; struct stat st; int c;#define CHECKSTAT if (errno != error_noent) goto fail; fnmake_info(id); if (stat(fn.s,&st) == -1)  {   CHECKSTAT   return; /* someone yanking our chain */  } fnmake_todo(id); if (stat(fn.s,&st) != -1) return; /* look, ma, dad crashed writing info! */ CHECKSTAT for (c = 0;c < CHANNELS;++c)  {   fnmake_chanaddr(id,c);   if (stat(fn.s,&st) == -1) { flagchan[c] = 0; CHECKSTAT }   else { flagchan[c] = 1; pechan[c].id = id; pechan[c].dt = st.st_mtime; }  } for (c = 0;c < CHANNELS;++c)   if (flagchan[c])     while (!prioq_insert(&pqchan[c],&pechan[c])) nomem(); for (c = 0;c < CHANNELS;++c) if (flagchan[c]) break; if (c == CHANNELS)  {   pe.id = id; pe.dt = now();   while (!prioq_insert(&pqdone,&pe)) nomem();  } return; fail: log3("warning: unable to stat ",fn.s,"; will try again later\n"); pe.id = id; pe.dt = now() + SLEEP_SYSFAIL; while (!prioq_insert(&pqfail,&pe)) nomem();}void pqstart(){ readsubdir rs; int x; unsigned long id; readsubdir_init(&rs,"info",pausedir); while (x = readsubdir_next(&rs,&id))   if (x > 0)     pqadd(id);}void pqfinish(){ int c; struct prioq_elt pe; time_t ut[2]; /* XXX: more portable than utimbuf, but still worrisome */ for (c = 0;c < CHANNELS;++c)   while (prioq_min(&pqchan[c],&pe))    {     prioq_delmin(&pqchan[c]);     fnmake_chanaddr(pe.id,c);     ut[0] = ut[1] = pe.dt;     if (utime(fn.s,ut) == -1)       log3("warning: unable to utime ",fn.s,"; message will be retried too soon\n");    }}void pqrun(){ int c; int i; for (c = 0;c < CHANNELS;++c)   if (pqchan[c].p)     if (pqchan[c].len)       for (i = 0;i < pqchan[c].len;++i)	 pqchan[c].p[i].dt = recent;}/* this file is too long ---------------------------------------------- JOBS */struct job {  int refs; /* if 0, this struct is unused */  unsigned long id;  int channel;  datetime_sec retry;  stralloc sender;  int numtodo;  int flaghiteof;  int flagdying; };int numjobs;struct job *jo;void job_init(){ int j; while (!(jo = (struct job *) alloc(numjobs * sizeof(struct job)))) nomem(); for (j = 0;j < numjobs;++j)  {   jo[j].refs = 0;   jo[j].sender.s = 0;  }}int job_avail(){ int j; for (j = 0;j < numjobs;++j) if (!jo[j].refs) return 1; return 0;}int job_open(id,channel)unsigned long id;int channel;{ int j; for (j = 0;j < numjobs;++j) if (!jo[j].refs) break; if (j == numjobs) return -1; jo[j].refs = 1; jo[j].id = id; jo[j].channel = channel; jo[j].numtodo = 0; jo[j].flaghiteof = 0; return j;}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
99re这里都是精品| 精品国产一区二区三区久久影院 | 久久中文字幕电影| 国产拍欧美日韩视频二区| 成人在线视频一区二区| 秋霞国产午夜精品免费视频| 中文字幕一区二区三区精华液| 欧美一区二区网站| 欧美优质美女网站| 成人中文字幕电影| 国内成人精品2018免费看| 午夜精品成人在线| 亚洲精品成人a在线观看| 久久久91精品国产一区二区三区| 欧美高清精品3d| 99久久免费精品高清特色大片| 激情成人综合网| 视频一区国产视频| 亚洲线精品一区二区三区| 亚洲欧洲性图库| 久久精品一区二区三区不卡| 欧美成人video| 8x8x8国产精品| 欧美日本在线看| 在线观看日韩一区| 色呦呦国产精品| 亚洲精品在线观看网站| 制服丝袜一区二区三区| 欧美亚洲国产一区二区三区va| 99re6这里只有精品视频在线观看| 国产精品一区二区x88av| 激情五月激情综合网| 另类的小说在线视频另类成人小视频在线| 亚洲愉拍自拍另类高清精品| 亚洲女女做受ⅹxx高潮| 亚洲日韩欧美一区二区在线| 成人欧美一区二区三区黑人麻豆| 国产精品毛片a∨一区二区三区| 久久精品一区二区三区不卡| 国产亚洲成aⅴ人片在线观看| 久久午夜国产精品| 国产亚洲欧美在线| 国产欧美日韩卡一| 国产精品国产三级国产三级人妇| 中文在线一区二区| 中文字幕一区日韩精品欧美| 亚洲另类春色校园小说| 亚洲乱码一区二区三区在线观看| 亚洲免费在线电影| 亚洲高清久久久| 蜜臀av性久久久久蜜臀aⅴ四虎| 美日韩一级片在线观看| 国产在线不卡一卡二卡三卡四卡| 国产福利一区二区三区在线视频| 高清在线不卡av| 一本一道波多野结衣一区二区| 在线一区二区观看| 911精品国产一区二区在线| 欧美一区二区三区免费| 久久―日本道色综合久久| 久久精品日韩一区二区三区| 中文字幕一区二区三区精华液 | 欧美撒尿777hd撒尿| 91精品欧美久久久久久动漫| 精品国产麻豆免费人成网站| 欧美激情资源网| 亚洲一区av在线| 美腿丝袜亚洲三区| 成人h版在线观看| 欧美日韩国产综合久久| 欧美精品一区二区三区四区| 国产精品久久久久精k8| 亚洲一线二线三线久久久| 蜜臀av性久久久久蜜臀av麻豆| 国产成人8x视频一区二区 | 欧美日韩免费观看一区三区| 日韩欧美一二三四区| 欧美激情在线看| 亚洲成人自拍网| 国产精品1区2区| 欧美亚洲国产一区二区三区va| 精品久久国产老人久久综合| **性色生活片久久毛片| 日本免费在线视频不卡一不卡二 | 91麻豆免费看片| 欧美一区午夜视频在线观看| 国产精品久久久久天堂| 午夜精品爽啪视频| av资源网一区| 欧美电影免费观看高清完整版在线观看 | 亚洲蜜臀av乱码久久精品| 日本不卡一二三| 成人黄色免费短视频| 欧美福利电影网| 国产精品美女视频| 久久精品国产99国产精品| 91污在线观看| 久久久国产精品麻豆| 日韩在线一区二区三区| 99久久精品免费看国产 | 国产精品久久久久影视| 久久精品国产亚洲高清剧情介绍| 色悠久久久久综合欧美99| 久久综合丝袜日本网| 亚洲国产精品自拍| av不卡在线观看| 久久综合色婷婷| 毛片av一区二区| 欧美图区在线视频| 亚洲伦理在线免费看| 成人黄色a**站在线观看| 2022国产精品视频| 捆绑变态av一区二区三区| 欧美午夜精品理论片a级按摩| 国产精品久久久久天堂| 国产精品资源在线看| 欧美大片一区二区三区| 日日夜夜一区二区| 欧美丝袜丝nylons| 亚洲一区免费观看| 91免费版pro下载短视频| 中文字幕久久午夜不卡| 精品一二三四在线| 日韩精品一区二区三区在线播放| 日本在线播放一区二区三区| 欧美在线观看视频一区二区| 亚洲精品第一国产综合野| 色呦呦网站一区| 亚洲精品久久久久久国产精华液 | 日韩欧美一区二区久久婷婷| 亚洲成精国产精品女| 欧美性猛交一区二区三区精品| 一区二区三区在线免费观看| 91丨九色丨蝌蚪丨老版| 亚洲欧洲精品天堂一级| www.性欧美| 亚洲精品中文在线| 欧美亚洲一区二区在线观看| 一区二区三区四区在线| 在线观看区一区二| 午夜精品爽啪视频| 欧美一区二区性放荡片| 精品一区二区在线播放| 久久综合av免费| 成人激情动漫在线观看| 亚洲欧美偷拍三级| 欧美体内she精视频| 日韩av电影一区| 日韩久久免费av| 国产伦精品一区二区三区在线观看| 国产亚洲精久久久久久| www.日韩av| 亚洲成av人影院| 日韩免费观看高清完整版在线观看| 久久国产生活片100| 久久久精品影视| 99免费精品视频| 亚洲午夜精品一区二区三区他趣| 欧美丰满美乳xxx高潮www| 免费观看30秒视频久久| 国产亚洲成aⅴ人片在线观看| 99久久国产综合色|国产精品| 亚洲自拍欧美精品| 日韩欧美在线1卡| 国产不卡在线播放| 亚洲美女视频在线| 欧美精品v国产精品v日韩精品 | 成人av影视在线观看| 一区二区激情视频| 日韩欧美在线不卡| 成人福利视频在线| 婷婷久久综合九色综合绿巨人 | 日韩欧美一区二区三区在线| 高清免费成人av| 亚洲成a人片综合在线| 久久久久久综合| 欧美日韩性生活| 国内成+人亚洲+欧美+综合在线| 亚洲欧美二区三区| 久久综合久久鬼色中文字| av男人天堂一区| 久久99精品久久久久| 一区二区三区四区激情| 久久亚洲精精品中文字幕早川悠里 | 久久成人羞羞网站| 一区二区三区在线不卡| 欧美成人video| 色噜噜久久综合| 国产一区二区在线观看免费| 亚洲自拍偷拍麻豆| 中文字幕乱码亚洲精品一区| 欧美一区三区二区| 色综合天天综合| 国产大陆a不卡| 日本不卡一区二区三区| 综合久久久久综合| 久久毛片高清国产| 在线播放亚洲一区| 色欧美乱欧美15图片| 成人免费视频网站在线观看|