设置首页  |   加入收藏  |  联系我们   
您的位置: 主页>网络应用>邮件服务>正文
qmail源代码分析之qmail-queue
文章来源:Linuxdby.com  编辑:  发布时间:2007-11-20

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,%26amp;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.
len = 0;
i = fmt_str(s,"pid/"); len += i; if (s) s += i;
i = fmt_ulong(s,mypid); len += i; if (s) s += i;
i = fmt_str(s,"."); len += i; if (s) s += i;
i = fmt_ulong(s,starttime); len += i; if (s) s += i;
i = fmt_str(s,"."); len += i; if (s) s += i;
i = fmt_ulong(s,seq); len += i; if (s) s += i;
++len; if (s) *s++ = 0;

return len;
}

char *fnnum(dirslash,flagsplit)
char *dirslash;
int flagsplit;
{
char *s;

s = alloc(fmtqfn((char *) 0,dirslash,messnum,flagsplit));
if (!s) die(51);
fmtqfn(s,dirslash,messnum,flagsplit);
return s;
}

void pidopen() //建立类似/var/run/inet.pid之类的进程id文件.
{
unsigned int len;
unsigned long seq;

seq = 1;
len = pidfmt((char *) 0,seq);
pidfn = alloc(len);
if (!pidfn) die(51);

for (seq = 1;seq < 10;++seq)
{
if (pidfmt((char *) 0,seq) > len) die(81); /* paranoia */
pidfmt(pidfn,seq);
messfd = open_excl(pidfn);
if (messfd != -1) return;
}

die(63);
}

char tmp[FMT_ULONG];

void main()
{
unsigned int len;
char ch;

sig_blocknone();
umask(033);
if (chdir(auto_qmail) == -1) die(61);
if (chdir("queue") == -1) die(62);//改变工作目录到/var/qmail/queue

mypid = getpid();
uid = getuid();
starttime = now();
datetime_tai(%26amp;dt,starttime);//将起始时间转换为可读年月日时分秒的形式
//生成自已的邮件头存入缓存reseived中
//例如: received="Received: (qmail 3434 invoked by 34434); Apr 27 2003 14:55:34"
received_setup();

sig_pipeignore();
sig_miscignore();
sig_alarmcatch(sigalrm);//捕捉alarm信号,控制超时
sig_bugcatch(sigbug);

alarm(DEATH); //超时秒数,缺省值是86400(24小时) 后错误返回52

pidopen();//建立进程id文件
if (fstat(messfd,%26amp;pidst) == -1) die(63);

messnum = pidst.st_ino; //进程id文件的inode节点号


/*生成将要建立的文件的文件名
几个文件都是根据刚才建立的pid文件的inode节点号命名的.inode不可能被两个文件同时占用,这保证了邮件唯一性。
其中mess目录下的文件放置有一个%23的问题,
tips: 因为是%23所以该目录名最大的可能只有22,明白queue/mess目录下目录为什么最大只22了吧

 
Tags:分析 源代码 if len char int unsigned // die 文件 fmt_str
Google
 
上一篇: qmail的控制文件祥解   下一篇: LINUX操作系统下的网络邮件安全问题
【返回顶部】 【打印】 【大】 【中】 【小】 【关闭】

 我来说两句
用户名: 新注册) 密码: 匿名评论 [论坛讨论]
评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
 相关文章
 热门文章

 
版权所有  2005-2006  Linux集中营  闽ICP备07500055号