?? qmail-inject.c
字號:
// 接受本地郵件消息后檢測郵件頭是否符合RFC822標(biāo)準(zhǔn),并傳送給qmail-queue排進(jìn)隊列
#include "sig.h"#include "substdio.h"#include "stralloc.h"#include "subfd.h"#include "sgetopt.h"#include "getln.h"#include "alloc.h"#include "str.h"#include "fmt.h"#include "hfield.h"#include "token822.h"#include "control.h"#include "env.h"#include "gen_alloc.h"#include "gen_allocdefs.h"#include "error.h"#include "qmail.h"#include "now.h"#include "exit.h"#include "quote.h"#include "headerbody.h"#include "auto_qmail.h"#include "newfield.h"#include "constmap.h"#define LINELEN 80datetime_sec starttime;char *qmopts;int flagdeletesender = 0;int flagdeletefrom = 0;int flagdeletemessid = 0;int flagnamecomment = 0;int flaghackmess = 0;int flaghackrecip = 0;char *mailhost;char *mailuser;int mailusertokentype;char *mailrhost;char *mailruser;stralloc control_idhost = {0};stralloc control_defaultdomain = {0};stralloc control_defaulthost = {0};stralloc control_plusdomain = {0};stralloc sender = {0};stralloc envsbuf = {0};token822_alloc envs = {0};int flagrh;int flagqueue;struct qmail qqt;void put(s,len) char *s; int len;{ if (flagqueue) qmail_put(&qqt,s,len); else substdio_put(subfdout,s,len); }void puts(s) char *s; { put(s,str_len(s)); }void perm() { _exit(100); }void temp() { _exit(111); }void die_nomem() { substdio_putsflush(subfderr,"qmail-inject: fatal: out of memory\n"); temp(); }void die_invalid(sa) stralloc *sa; { substdio_putsflush(subfderr,"qmail-inject: fatal: invalid header field: "); substdio_putflush(subfderr,sa->s,sa->len); perm(); }void die_qqt() { substdio_putsflush(subfderr,"qmail-inject: fatal: unable to run qmail-queue\n"); temp(); }void die_chdir() { substdio_putsflush(subfderr,"qmail-inject: fatal: internal bug\n"); temp(); }void die_read() { if (errno == error_nomem) die_nomem(); substdio_putsflush(subfderr,"qmail-inject: fatal: read error\n"); temp(); }void doordie(sa,r) stralloc *sa; int r; { if (r == 1) return; if (r == -1) die_nomem(); substdio_putsflush(subfderr,"qmail-inject: fatal: unable to parse this line:\n"); substdio_putflush(subfderr,sa->s,sa->len); perm(); }GEN_ALLOC_typedef(saa,stralloc,sa,len,a)GEN_ALLOC_readyplus(saa,stralloc,sa,len,a,i,n,x,10,saa_readyplus)static stralloc sauninit = {0};saa savedh = {0};saa hrlist = {0};saa tocclist = {0};saa hrrlist = {0};saa reciplist = {0};int flagresent;void exitnicely(){ char *qqx; if (!flagqueue) substdio_flush(subfdout); if (flagqueue) { int i; if (!stralloc_0(&sender)) die_nomem(); qmail_from(&qqt,sender.s); for (i = 0;i < reciplist.len;++i) { if (!stralloc_0(&reciplist.sa[i])) die_nomem(); qmail_to(&qqt,reciplist.sa[i].s); } if (flagrh) if (flagresent) for (i = 0;i < hrrlist.len;++i) { if (!stralloc_0(&hrrlist.sa[i])) die_nomem(); qmail_to(&qqt,hrrlist.sa[i].s); } else for (i = 0;i < hrlist.len;++i) { if (!stralloc_0(&hrlist.sa[i])) die_nomem(); qmail_to(&qqt,hrlist.sa[i].s); } qqx = qmail_close(&qqt); if (*qqx) if (*qqx == 'D') { substdio_puts(subfderr,"qmail-inject: fatal: "); substdio_puts(subfderr,qqx + 1); substdio_puts(subfderr,"\n"); substdio_flush(subfderr); perm(); } else { substdio_puts(subfderr,"qmail-inject: fatal: "); substdio_puts(subfderr,qqx + 1); substdio_puts(subfderr,"\n"); substdio_flush(subfderr); temp(); } } _exit(0);}void savedh_append(h)stralloc *h;{ if (!saa_readyplus(&savedh,1)) die_nomem(); savedh.sa[savedh.len] = sauninit; if (!stralloc_copy(savedh.sa + savedh.len,h)) die_nomem(); ++savedh.len;}void savedh_print(){ int i; for (i = 0;i < savedh.len;++i) put(savedh.sa[i].s,savedh.sa[i].len);}stralloc defaultdomainbuf = {0};
// defaultdomain 用來向那些沒有使用正確的username@hostname.domain格式的郵件中增加
//郵件地址的,默認(rèn)情況下,如果主機地址中沒有結(jié)束符".",qmail-inject將給主機名后面
//添加defaultdomain的內(nèi)容,如果該文件不存在,將使用me文件中的值代替token822_alloc defaultdomain = {0};stralloc defaulthostbuf = {0};
// 用來定義主機名,用來向地址中不含主機名的郵件補足郵件地址的。類似與defaultdomaintoken822_alloc defaulthost = {0};stralloc plusdomainbuf = {0};
// 用來將其值添加在任何一個以一個+號結(jié)尾的地址token822_alloc plusdomain = {0};void rwroute(addr)token822_alloc *addr;{ if (addr->t[addr->len - 1].type == TOKEN822_AT) while (addr->len) if (addr->t[--addr->len].type == TOKEN822_COLON) return;}void rwextraat(addr)token822_alloc *addr;{ int i; if (addr->t[0].type == TOKEN822_AT) { --addr->len; for (i = 0;i < addr->len;++i) addr->t[i] = addr->t[i + 1]; }}void rwextradot(addr)token822_alloc *addr;{ int i; if (addr->t[0].type == TOKEN822_DOT) { --addr->len; for (i = 0;i < addr->len;++i) addr->t[i] = addr->t[i + 1]; }}void rwnoat(addr)token822_alloc *addr;{ int i; int shift; for (i = 0;i < addr->len;++i) if (addr->t[i].type == TOKEN822_AT) return; shift = defaulthost.len; if (!token822_readyplus(addr,shift)) die_nomem(); for (i = addr->len - 1;i >= 0;--i) addr->t[i + shift] = addr->t[i]; addr->len += shift; for (i = 0;i < shift;++i) addr->t[i] = defaulthost.t[shift - 1 - i];}void rwnodot(addr)token822_alloc *addr;{ int i; int shift; for (i = 0;i < addr->len;++i) { if (addr->t[i].type == TOKEN822_DOT) return; if (addr->t[i].type == TOKEN822_AT) break; } for (i = 0;i < addr->len;++i) { if (addr->t[i].type == TOKEN822_LITERAL) return; if (addr->t[i].type == TOKEN822_AT) break; } shift = defaultdomain.len; if (!token822_readyplus(addr,shift)) die_nomem(); for (i = addr->len - 1;i >= 0;--i) addr->t[i + shift] = addr->t[i]; addr->len += shift; for (i = 0;i < shift;++i) addr->t[i] = defaultdomain.t[shift - 1 - i];}void rwplus(addr)token822_alloc *addr;{ int i; int shift; if (addr->t[0].type != TOKEN822_ATOM) return; if (!addr->t[0].slen) return; if (addr->t[0].s[addr->t[0].slen - 1] != '+') return; --addr->t[0].slen; /* remove + */ shift = plusdomain.len; if (!token822_readyplus(addr,shift)) die_nomem(); for (i = addr->len - 1;i >= 0;--i) addr->t[i + shift] = addr->t[i]; addr->len += shift; for (i = 0;i < shift;++i) addr->t[i] = plusdomain.t[shift - 1 - i];}void rwgeneric(addr)token822_alloc *addr;{ if (!addr->len) return; /* don't rewrite <> */ if (addr->len >= 2) if (addr->t[1].type == TOKEN822_AT) if (addr->t[0].type == TOKEN822_LITERAL) if (!addr->t[0].slen) /* don't rewrite <foo@[]> */ return; rwroute(addr); if (!addr->len) return; /* <@foo:> -> <> */ rwextradot(addr); if (!addr->len) return; /* <.> -> <> */ rwextraat(addr); if (!addr->len) return; /* <@> -> <> */ rwnoat(addr); rwplus(addr); rwnodot(addr);}int setreturn(addr)token822_alloc *addr;{ if (!sender.s) { token822_reverse(addr); if (token822_unquote(&sender,addr) != 1) die_nomem(); if (flaghackrecip) if (!stralloc_cats(&sender,"-@[]")) die_nomem(); token822_reverse(addr); } return 1;}int rwreturn(addr)token822_alloc *addr;{ rwgeneric(addr); setreturn(addr); return 1;}int rwsender(addr)token822_alloc *addr;{ rwgeneric(addr); return 1;}void rwappend(addr,xl)token822_alloc *addr;saa *xl;{ token822_reverse(addr); if (!saa_readyplus(xl,1)) die_nomem(); xl->sa[xl->len] = sauninit; if (token822_unquote(&xl->sa[xl->len],addr) != 1) die_nomem(); ++xl->len; token822_reverse(addr);}int rwhrr(addr) token822_alloc *addr;{ rwgeneric(addr); rwappend(addr,&hrrlist); return 1; }int rwhr(addr) token822_alloc *addr;{ rwgeneric(addr); rwappend(addr,&hrlist); return 1; }int rwtocc(addr) token822_alloc *addr;{ rwgeneric(addr); rwappend(addr,&hrlist); rwappend(addr,&tocclist); return 1; }int htypeseen[H_NUM];stralloc hfbuf = {0};token822_alloc hfin = {0};token822_alloc hfrewrite = {0};token822_alloc hfaddr = {0};void doheaderfield(h)stralloc *h;{ int htype; int (*rw)() = 0; htype = hfield_known(h->s,h->len); if (flagdeletefrom) if (htype == H_FROM) return; if (flagdeletemessid) if (htype == H_MESSAGEID) return; if (flagdeletesender) if (htype == H_RETURNPATH) return; if (htype) htypeseen[htype] = 1; else if (!hfield_valid(h->s,h->len)) die_invalid(h); switch(htype) { case H_TO: case H_CC: rw = rwtocc; break; case H_BCC: case H_APPARENTLYTO: rw = rwhr; break; case H_R_TO: case H_R_CC: case H_R_BCC: rw = rwhrr; break; case H_RETURNPATH: rw = rwreturn; break; case H_SENDER: case H_FROM: case H_REPLYTO: case H_RETURNRECEIPTTO: case H_ERRORSTO: case H_R_SENDER: case H_R_FROM: case H_R_REPLYTO: rw = rwsender; break; } if (rw) { doordie(h,token822_parse(&hfin,h,&hfbuf)); doordie(h,token822_addrlist(&hfrewrite,&hfaddr,&hfin,rw)); if (token822_unparse(h,&hfrewrite,LINELEN) != 1) die_nomem(); } if (htype == H_BCC) return; if (htype == H_R_BCC) return; if (htype == H_RETURNPATH) return; if (htype == H_CONTENTLENGTH) return; /* some things are just too stupid */ savedh_append(h);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -