ºÜ¾ÃÒÔǰ±ã¼ûµ½CUÂÛ̳ÉÏÓÐһƪ¹ØÓÚqmailÔ´Âë×¢Ê͵ÄÎÄÕ£¬¿Éϧµ±Ê±×÷ÕßֻдÁËsmtpdµÄ²¿·Ö£¬²¢Ã»ÓÐÉæ¼°qmailµÄÕû¸öÔËÐлúÀí¡£±ÊÕß×î½üÓÉÓÚ¹¤×÷µÄÔÒò£¬Ñо¿ÁËÒ»ÏÂqmail£¬ÓÉÓÚqmailµÄ´úÂëºÜ»ìÂÒ£¬ÓÖûÓкܺõÄ×¢ÊÍ£¬µÄÈ´ÊÇ»ÞɬÄѶ®£¬±ÊÕß»¨ÁËÒ»¸öÐÇÆÚ²ÅÃãÇ¿°ÑËüµÄ´óÖÂÔÀí¸ãÇå³þ£¬Ï£ÍûÕâÆªÎÄÕÂÄܹ»¸ø¿ÊÍûÁ˽âqmail´úÂëµÄÅóÓÑÃÇÒ»µã°ïÖú¡£
¹ØÓÚsmtpdµÄ²¿·Ö£¬¿É²Î¿´±¾°æµÄ¾«»ªÇø¡£±¾ÎĽ«»áÌø¹ýsmtpd£¬½éÉÜqmailµÄºËÐijÌÐòqmail-send¡£
Ê×ÏÈÎÒÃÇÀ´¿´Ò»ÏÂqmailµÄÈë¶Ó¹ý³Ì£¨¾ÍÊǽ«ÊÕÏÂÒ»·âÓʼþ²¢½«Æä±£´æµ½qmailµÄ´ÅÅ̶ÓÁÐÖÐÒѱ»ÓÃÓÚºóÐøµÄͶµÝ£©¡£µ±Ò»·âÓʼþ±»qmail-smtpdÊÕÏÂÀ´Ê±ÎÒÃDz¢²»ÄܳƸÃÓʼþÒѾÈë¶ÓÁË£¬ÔÚqmailÖÐÓʼþµÄÈë¶ÓÊÇÓÉÒ»¸öÁÙʱµÄÃûΪqmail-queueµÄ½ø³ÌÀ´Íê³ÉµÄ£¬ÆäʵÕâ¸ö½ø³ÌҲû¸ÉʲôÊ£¬¾ÍÊǽ«Óʼþ±£´æµ½¶ÓÁеÄmessĿ¼Ï£¨Ãû³ÆÒÔÊý×ÖmsgIDÀ´ÃèÊö£©£¬mess¹ËÃû˼Òå¾ÍÊÇmessageµÄÒâ˼£¬Ö¸µÃÊÇÕû·âÓʼþ£¬µ±È»½ö½ö±£´æÕâ·âÓʼþ»¹ÊDz»¹»µÄ£¬qmail-queue»¹½«Õâ·âÓʼþµÄÐÅ·âÐÅÏ¢£¬¼´MAIL FROM, RCPT TO°´ÕÕÒ»¶¨µÄ¸ñʽдÈëµ½intdĿ¼Ï£¬²¢½«¸ÃÎļþlinkµ½todoĿ¼Ï£¬ÖÁ´Ë£¬Õû¸öqmailµÄÈë¶Ó¹¤×÷ÒѾÍê³É£¬´Ëʱqmail-queue»áͨ¹ýunixϵÄÃüÃû¹ÜµÀ֪ͨqmail-sendÓÐÐÂÏûÏ¢À´ÁË¡£
½ÓÏÂÈ¥¾ÍÊDZ¾ÎÄ×ÅÖØÒª½éÉܵÄqmail-sendµÄ¹¤×÷ÁË¡£qmail-sendµÄ¹¤×÷¾ÍÊǶÔÈë¶ÓÁ˵ÄÏûÏ¢½øÐÐÔ¤´¦Àí£¬½«ÏûÏ¢·ÖÅɵ½±¾µØ»òÔ¶³ÌÁ½¸ö¶ÓÁÐÖУ¬Í¬Ê±qmail-sendÒ²ÊÇÕû¸öqmailͶµÝ¹ý³ÌͨÐŵĺËÐĽø³Ì¡£
ºÍqmail-sendͨÐŵÄÓÐlog½ø³Ì£¬clean½ø³Ì£¬lspawn¼°rspawnµÈ½ø³Ì£¬logÊÇÓÃÀ´¼Ç¼ÈÕÖ¾µÄ£¬cleanÊÇɾ³ý¶ÓÁÐÖÐÏûÏ¢µÄ£¬lspawn,rspawnºÜÏÔÈ»¾ÍÊÇÓÃÀ´²úÉúÒ»¸ö±¾µØ»òÕßÔ¶³ÌµÄͶµÝ½ø³ÌµÄ¡£
Õû¸öͨÐŹý³Ì¶¼ÊÇͨ¹ýÄäÃû¹ÜµÀÀ´Íê³ÉµÄ¡£qmail½«¹ÜµÀ»úÖÆ´¦ÀíµÄ¼«ÆäÓÅÑÅ£¬¶ÔÓÚqmail-send¶øÑÔ£¬ÎļþÃèÊö·û0, 1, 2, 3, 4, 5, 6 ·Ö±ðΪÏàÓ¦µÄ¹ÜµÀ£¬0ÊÇÈÕÖ¾¹ÜµÀ£¬¾ÍÊÇÏòlog½ø³Ì·¢ËÍÈÕÖ¾µÄ£¬ÔÚlog½ø³ÌÖнÓÊÜÈÕÖ¾µÄÎļþÃèÊö·ûͬÑùÒ²ÊÇ0¡£¶ÔÓÚÆäËû½ø³Ìclean, lspawn, rspawn¶øÑÔ£¬ËûÃÇ·Ö±ð´ÓÎļþÃèÊö·û0ÖжÁÈ¡À´×Ôqmail-sendµÄѶϢ£¬²¢½«´¦Àí½á¹ûͨ¹ýÎļþÃèÊö·û1·µ»Ø¸øqmail-send¡£
qmail-send
qmail-log 0 ------------------------ 0
qmail-local 0 ------------------------ 1
1 ------------------------ 2
qmail-remote 0 ------------------------ 3
1 ------------------------ 4
qmail-clean 0 ------------------------- 5
1 ------------------------- 6
OK£¬½²ÁËÕâô¶àµÄ·Ï»°ÎÒÃÇ»¹ÊÇ¿ªÊ¼·ÖÎöqmail-sendµÄ´úÂë°É£¬µ±È»ÔÚÕâÀïÎÒ²¢²»Ïë°ÑËùÓеĴúÂë¶¼Ìù³öÀ´£¬±Ï¾¹Óнü2000ÐеĴúÂ룬ÎÒÖ÷ÒªÊÇÏë½éÉÜÒ»ÏÂÒÔÏÂ5¸öº¯Êý£º
comm_do(&wfds);
del_do(&rfds);
todo_do(&rfds);
pass_do();
cleanup_do();
ÕâÎå¸öº¯Êý³öÏÖÔÚÖ÷Ñ»·whileÖУ¬ÊÇqmail-send²»¶ÏÔÚÖ´ÐеÄÊÂÇ飬°ÑÕâÎå¸öº¯Êý¸ãÇå³þÁËÒ²¾Í´óÖÂÄÜÁ˽âqmailÊÇÈçºÎ¹¤×÷µÄÁË¡£
void comm_do(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 avoidbusy-looping */
}
} else {
comm_pos[c] += w;
if (comm_pos[c] == len)
comm_buf[c].len = 0;
}
}
}
}
}
}
CHANNELS=2£¬¶ÔÓ¦lspawnºÍrspawn½ø³Ì£¬Õâ¸öº¯ÊýºÜ¼òµ¥£¬ËüÖ»Êǽ«ÐèҪͶµÝµÄÐÅϢдÈëµ½ÏàÓ¦¹ÜµÀÖÐÈ¥£¬ÖÁÓÚÕâЩͶµÝÐÅÏ¢ÊÇÈçºÎ²úÉúµÄ£¬ÎÒ½«»áÔÚÏÂÃæ½éÉÜ¡£
void del_do(fd_set *rfds)
{
int c;
for (c = 0; c < CHANNELS; ++c) {
if (flagspawnalive[c])
if (FD_ISSET(chanfdin[c],rfds))
del_dochan(c);
}
}
OH,SHIT!ÕâÓÖÊÇÒ»¸ö¼òµ¥µÄº¯Êý£¬ËüÖ»ÊǸºÔð´ÓÏàÓ¦µÄlspawnºÍrspawn¹ÜµÀÖжÁȡͶµÝ³É¹¦»òʧ°ÜµÄÐÅÏ¢¡£
void todo_do(fd_set *rfds)´úÂëÊÇÔÚÌ«³¤ÁË£¬ÎÒ²»Ïë°ÑËüÈ«²¿Ìù³öÀ´£¬ÔÚÕâÀïÎÒÊ¡ÂÔÁËһЩ´íÎóµÄ´¦Àí¡£
todo_doµÄ¹¤×÷ÊÇʲô£¿ Ç°ÃæÎÒÃÇÒѾ˵¹ýÈë¶ÓµÄ¹ý³Ì£¬µ±Ò»·âÓʼþÈë¶Óºóqmail²¢²»ÊÇÂíÉϾÍȥͶµÝËüÁË£¬ÎÒÃÇÐèÒª¶ÔËü½øÐÐһЩԤ´¦Àí£¬Ê×ÏÈÎÒÃÇ´ÓtodoĿ¼ÏÂѰÕÒÊÇ·ñÓÐеÄÓʼþÈë¶ÓÁË£¬Èç¹ûÓÐÎÒÃǶÁÈ¡¸ÃÎļþ»ñµÃËüµÄÐÅ·âÐÅÏ¢£¬½«MAIL FROMÐÅϢдÈëµ½infoĿ¼Ï£¬²¢ÅжÏRCPT TOÓʼþµØÖ·ÊDZ¾µØ»¹ÊÇÔ¶³ÌµÄ£¬Èç¹ûÊDZ¾µØµÄ¾ÍÒÑÏàÓ¦µÄmsgID×÷ΪÎļþÃûдÈëµ½localĿ¼Ï£¬Í¬ÑùÈç¹ûÊÇÔ¶³ÌµÄ£¬Ôò»áдÈëµ½remoteĿ¼Ï£¬Ëæºóqmailͨ¹ýqmail-clean½«todoĿ¼ÏµĸÃÎļþɾ³ý£¬ÖÁ´Ë¸ÃÏûÏ¢µÄÔ¤´¦Àí¾ÍËã½áÊøÁË¡£
//
// »ñÈ¡todoĿ¼ÏÂÒ»ÌõѶϢµÄÎļþÃû
//
d = readdir(tododir);
len = scan_ulong(d->d_name, &id);
//
// ×éºÏ³ÉtodoĿ¼Ï¸ÃÎļþµÄÍêÕû·¾¶£¬²¢½«Æä´ò¿ª
// ¸ÃÎļþµÄÄÚÈÝÎÒÃÇÔÚÉÏÃæÒѾ½éÉܹý£¬Ëü´æ´¢µÄ¾ÍÊÇ
// ¶ÔÓ¦¸ÃmsgIDµÄÓʼþµÄMAIL FROMºÍRCPT TO
// µÄÄÚÈÝ
fnmake_todo(id);
fd = open_read(fn.s);
//
// ×éºÏ³ÉinfoĿ¼Ï¸Ãmsg¶ÔÓ¦µÄÍêÕû·¾¶Ãû
//
fnmake_info(id);
//
// ÒÔд·½Ê½´´½¨²¢´ò¿ª¸ÃÎļþ
//
fdinfo = open_excl(fn.s);
//
// ³õʼ»¯¶ÔÕâÁ½¸öÎļþ½øÐжÁдµÄbuffer¹¤¾ßº¯Êý¡£
//
substdio_fdbuf(&ss,read,fd,todobuf,sizeof(todobuf)); substdio_fdbuf(&ssinfo,write,fdinfo,todobufinfo,sizeof(todobufinfo));
for ( ; ; ) // ´Ótodo/id ÖжÁÈ¡ÐÅÏ¢£¬Ã¿´ÎÒ»¸ö¼Ç¼£¬ÒÔ¡¯\0¡¯Îª·Ö¸î·û
{
if (getln(&ss, &todoline, &match, '\0') == -1)
{
goto fail;
}
if (!match) break;
switch(todoline.s[0])
{
case 'u': // »ñÈ¡¸ÃmsgµÄuid
scan_ulong(todoline.s + 1,&uid);
break;
case 'p': // »ñÈ¡¸ÃmsgµÄpid
scan_ulong(todoline.s + 1,&pid);
break;
case 'F': // ½« MAIL FROMÐÅϢдÈëµ½info/idÎļþÖÐÈ¥
if (substdio_putflush(&ssinfo,todoline.s,todoline.len) == -1)
{
goto fail;
}
break;
case 'T': // ½«RCPT TOÐÅϢдÈëµ½local/split/id»òÕß
// remote/split/id
//
// дÈërwline buffer²¢ÅжϸÃRCPT TOÊDZ¾µØµÄ»¹ÊÇÔ¶³ÌµÄ£¬
// c = 0 ´ú±í±¾µØ£¬ 1´ú±íremoteµÄ
//
switch(rewrite(todoline.s + 1))
{
case 0: nomem(); goto fail;
case 2: c = 1; break;
default: c = 0; break;
}
if (fdchan[c] == -1)
{
//
// ¸ù¾ÝcºÍmsgid×é×°³ölocal/split/id»òÕßremote/split/id
// ÕâÑùµÄÍêÕû·¾¶Ãû
//
fnmake_chanaddr(id,c);
//
// ´ò¿ªÎļþ²¢³õʼ»¯bufferдÈëµÄ¹¤¾ßº¯Êý
//
fdchan[c] = open_excl(fn.s);
if (fdchan[c] == -1)
{
goto fail;
}
substdio_fdbuf(&sschan[c], write, fdchan[c],
todobufchan[c],sizeof(todobufchan[c]));
flagchan[c] = 1;
}
//
// ½«RCPT TOÐÅϢдÈëµ½¶ÔÓ¦µÄÎļþÖÐÈ¥¡£
//
if (substdio_bput(&sschan[c],rwline.s,rwline.len) == -1)
{
fnmake_chanaddr(id,c);
log3("warning: trouble writing to ",fn.s,"\n"); goto fail;
}
break;
}
}
//
// ÒÔÏÂÕâô¶à´úÂëÖ»ÊǸÉÁËͬ²½ÎļþºÍbuffer²¢½«Îļþ¹Ø±ÕÕâһЩ¼òµ¥µÄÊÂÇé¡£
//
close(fd);
fd = -1;
fnmake_info(id);
if (substdio_flush(&ssinfo) == -1)
{
goto fail;
}
if (fsync(fdinfo) == -1)
{
goto fail;
}
close(fdinfo);
fdinfo = -1;
for (c = 0;c < CHANNELS;++c)
if (fdchan[c] != -1)
{
fnmake_chanaddr(id,c);
if (substdio_flush(&sschan[c]) == -1)
{
goto fail;
}
if (fsync(fdchan[c]) == -1)
{
goto fail;
}
close(fdchan[c]);
fdchan[c] = -1;
}
////////////////////////////////////////////////////////////////////
fnmake_todo(id);
//
// ½«todoĿ¼ÏµÄtodo/id·¾¶Ð´Èëµ½qmail-cleanµÄ¹ÜµÀÖÐÈ¥£¬Ò²¾ÍÊÇÈÃ
// qmail-clean ȥɾ³ýtodo/idÕâ¸öÎļþ
//
if (substdio_putflush(&sstoqc,fn.s,fn.len) == -1)
{
cleandied();
return;
}
//
// µÈ´ýqmail-cleanµÄ·µ»Ø£¬ÎÒÃǴӹܵÀÖжÁȡһ¸ö×Ö·û£¬ ¡®+¡¯ ±íʾɾ³ý³É¹¦
//
if (substdio_get(&ssfromqc,&ch,1) != 1)
{
cleandied();
return;
}
if (ch != '+')
{
return;
}
//
// peΪÓÅÏȼ¶¼¶¶ÓÁеĽڵ㣬qmailÔÚÄÚ´æÖб£´æÁ˺ü¸ÌõÒÔʱ¼äÅÅÐòµÄÓÅÏȼ¶¶ÓÁÐ
//
pe.id = id;
pe.dt = now(); // timestampΪµ±Ç°Ê±¼ä
//
// ½«¸Ã½Úµã²åÈëµ½ÏàÓ¦local»òÕßremoteµÄÓÅÏȼ¶¶ÓÁÐÖÐÈ¥£¬ÖÁÓÚ¸ÃÓÅÏȼ¶¶ÓÁÐ
// ʹÓõĵ½µ×ÊÇ×îС¶ÑÅÅÐò»¹ÊÇÆäËû£¬ÎÒÔÚÕâÀï²»Ïë׸Êö£¬ÎÒÃÇÖ»ÒªÖªµÀËüÊÇÒ»
// ¸öÒÔʱ¼äΪÓÅÏȼ¶µÄ´ÓСµ½´óÅÅÁеĶÓÁоͿÉÒÔÁË¡£
//
for (c = 0; c < CHANNELS; ++c)
if (flagchan[c])
while (!prioq_insert(&pqchan[c],&pe))
nomem();
for (c = 0; c < CHANNELS; ++c)
if (flagchan[c])
break;
//
// Õâ¸ö»ù±¾ÊDz»¿ÉÄÜ·¢ÉúµÄflagchan[0] flagchan[1]¶¼Îª0£¬OH SHIT!
//
if (c == CHANNELS)
while (!prioq_insert(&pqdone,&pe))
nomem();
return;
´ýÐø.................................................................................
ǰһ²¿·Ö½éÉÜÁËÒ»·âÓʼþÔÚqmailÖеÄÈë¶Ó¹ý³ÌÒÔ¼°Ô¤´¦Àí¹ý³Ì, µ±Óʼþ±»smtpd½ÓÊÕϺóËüÖ»ÊDZ»±£´æÔÚ¶ÔÓ¦pidµÄÁÙʱĿ¼Ï£¬qmail-queue¸ºÔð½«ËüдÈëµ½messĿ¼Ï£¬²¢½«Õâ·âÐŵÄÐÅ·âÐÅϢдÈëµ½intdÏ£¬Í¬Ê±½«¸ÃÎļþlinkµ½todoĿ¼Ï£¬²¢¸æÖªqmail-sendÒѾÓÐÐÂÓʼþÀ´ÁË¡£qmail-send»áɨÃètodoĿ¼£¬ÌáÈ¡mail fromºÍrcpt toÐÅÏ¢£¬½«mail from±£´æÔÚinfoĿ¼ÏµĶÔÓ¦ÎļþÖУ¬rcpt toдÈëlocal»òÕßremoteĿ¼µÄ¶ÔÓ¦ÎļþÖÐÈ¥£¬Ëæºó֪ͨqmail-cleanɾ³ýtodoϵĸÃÎļþ£¬²¢½«¸Ãid²åÈëµ½ÄÚ´æ¶ÓÁÐÖÐÈ¥£¬ÖÁ´ËÎÒÃÇ˵qmailµÄÈë¶ÓµÄÔ¤´¦ÀíÒѾ»ù±¾Íê³ÉÁË¡£
½ÓÏÂÈ¥¾ÍÊÇҪ֪ͨqmail-lspawn»òÕßqmail-rspawnȥͶµÝÓʼþÁË£¬comm_doËù×÷µÄ¾ÍÊǽ«Í¶µÝµÄÐÅϢͨ¹ý¹ÜµÀ´«µÝ¸ølspawn»òÕßrspawn²¢ÓÉËûÃDzúÉú³öÒ»¸öеĽø³ÌÈ¥×öʵ¼ÊµÄÓʼþͶµÝ¡£µ«ÊÇÎÒÃÇ»¹Ã»¼ûµ½ÕâЩͶµÝÐÅÏ¢ÊÇÔõô²úÉúÁË£¬ÊÇ˰ÑËûдÈëµ½comm_bufÖÐÈ¥µÄ£¬ÎÒÏëÓ¦¸Ã¾ÍÊÇÔÚÏÂÃæÕâ¸öº¯ÊýÖаɣ¡
void pass_do()
{
int c;
struct prioq_elt pe;
for (c = 0;c < CHANNELS;++c)
pass_dochan(c);
//
// pqfailΪÓÉÓÚϵͳ´íÎóµ¼ÖµÄÎÞ·¨ÔÝʱÎÞ·¨Í¶µÝµÄ¶ÓÁÐ
//
if (prioq_min(&pqfail,&pe))
if (pe.dt <= recent)
{
prioq_delmin(&pqfail);
// ×ö¼òÒªµÄÒ»ÖÂÐÔ¼ì²â£¬Èç¹ûûʲôÎÊÌâ¾Í½«Ëü¼ÓÈëÄÚ´æÍ¶µÝ¶ÓÁÐ
// ·ñÔòÔò±»¼ÓÈëµ½Íê³É¶ÓÁÐÖÐ
pqadd(pe.id);
}
if (prioq_min(&pqdone,&pe))
if (pe.dt <= recent)
{
prioq_delmin(&pqdone);
// È·ÈϸÃmsgÊÇ·ñÒѾÍê³ÉÁË£¬Èç¹ûÊǼì²âÊÇ·ñÐèÒªbounce,ͬʱ×Ô¼º
// ɾ³ýinfoϵĶÔÓ¦Îļþ£¬×îºóͨ¹ý¹ÜµÀ¸æÖªqmail-cleanȥɾ³ýmess
// Ŀ¼ÏµÄÓʼþ±¾Éí
messdone(pe.id);
}
}
Õ§¿´Ò»Ï»¹Õæ¿´²»³öÀ´£¬ÄǾÍÂýÂý·ÖÎö°É¡£ÏÈ¿´¿´pass_dochan×öÁËʲô¡£
void pass_dochan(int c)
{
datetime_sec birth;
struct prioq_elt pe;
static stralloc line = {0};
int match;
//
// qmailÿ´ÎֻͶµÝÒ»¸öÓû§£¬¶ÔÓÚÓжà¸örcpt toµÄÓʼþqmail»áͶµÝ¶à´Î
// ´Ë´¦ÅжÏÏ൱ÓÚÅжÏÊÇ·ñÒѾ°ÑËùÓеÄrcpt to¶¼Í¶ÍêÁË£¬Èç¹ûÊǾͿªÆô
// Ò»¸öеÄÈÎÎñ£¬Èç¹ûûÓУ¬go on do it
//
if (!pass[c].id)
{
//
// ÅжÏÊÇ·ñ»¹ÓÐfreeµÄjob item, job¶ÔÓ¦ÓÚlocal/split/id»òÕß
// remote/split/idµÄͶµÝÈÎÎñ, jobÓÐÒ»¸öÒýÓüÆÊýºÍnumtodo,
// numtodoÆäʵ¾ÍÊǶÔÓ¦µÄÎļþÖÐÓжàÉÙ¸öÐèҪͶµÝµÄÓû§
//
if (!job_avail())
return;
//
// »ñÈ¡ÏàÓ¦µÄlocal»òÕßremoteÄÚ´æÓÅÏȼ¶¶ÓÁÐÖеÄÓÅÏȼ¶×î¸ßµÄ£¬Ò²¾Í
// ÊÇʱ¼ä×îСµÄÄÇÏî
//
if (!prioq_min(&pqchan[c],&pe))
return;
//
// Ó뵱ǰʱ¼ä×ö±È½Ï£¬ÊÇ·ñ¿ÉÒÔfireÁË
//
if (pe.dt > recent)
return;
//
// ×é×°³ölocal/split/id»òÕßremote/split/id
//
fnmake_chanaddr(pe.id,c);
//
// ½«¸Ã½Úµã´ÓÄÚ´æ¶ÓÁÐÖÐɾ³ý
//
prioq_delmin(&pqchan[c]);
//
// ³õʼ»¯pass½á¹¹
//
pass[c].mpos = 0;
// ÎļþÃèÊö·ûÖ¸ÏòµÄÊÇ´æÓÐRCPT TOµÄÎļþlocal/split/id,»òÕß
// remote/split/id
pass[c].fd = open_read(fn.s);
//
// ´ÓinfoĿ¼ÏµĶÔÓ¦ÎļþÖжÁÈ¡mail fromÐÅÏ¢£¬½«mail fromдµ½
// line bufferÖÐÈ¥£¬Í¬Ê±½«¸ÃÎļþµÄ´´½¨Ê±¼äͨ¹ýbirth±£´æ£¬qmail
// ͨ¹ý¸Ãʱ¼äÅжÏÓʼþÔÚ¶ÓÁÐÖÐפÁôµÄʱ¼ä
if (!getinfo(&line,&birth,pe.id))
{
goto trouble;
}
pass[c].id = pe.id;
//
// ³õʼ»¯local/split/id»òÕßremote/split/idÎļþµÄbuffer¹¤¾ßº¯Êý
//
substdio_fdbuf(&pass[c].ss,read,pass[c].fd,pass[c].buf,sizeof(pass[c].buf));
//
// ¿ªÆôÒ»¸öеÄjob,´ÓjobÊý×éÖÐѰÕÒÒ»¸öÉÐδ±»Õ¼ÓõÄjob,±êʶÒѱ»
// ref,ͬʱ³õʼ»¯Ò»Ð©ÆäËû±äÁ¿
//
pass[c].j = job_open(pe.id,c);
//
// ¼ÆËãÏÂÒ»´ÎÖØÊÔµÄʱ¼ä£¬Èç¹ûÕâ·âÓʼþÔÚ¶ÓÁÐÖдôÁËÌ«³¤Ê±¼ä£¬¾Í
// ½«flagdyingÖÃΪ1
//
jo[pass[c].j].retry = nextretry(birth,c);
jo[pass[c].j].flagdying = (recent > birth + lifetime);
//
// ½«mail fromÐÅÏ¢copyµ½¶ÔÓ¦job½á¹¹ÏµÄsenderÖÐ
//
while (!stralloc_copy(&jo[pass[c].j].sender,&line))
nomem();
}
// ÅжÏspawn½ø³ÌÊÇ·ñ»¹alive,comm_bufÊÇ·ñÄܹ»Ð´È룬²¢·¢ÊýÊÇ
// ·ñµ½´ïÁËÉèÖÃÊý
if (!del_avail(c)) return;
// ¶Áȡһ¸örcpt to
if (getln(&pass[c].ss,&line,&match,'\0') == -1)
{
...
return;
}
switch(line.s[0])
{
case 'T':
++jo[pass[c].j].numtodo;
//
// ½«Í¶µÝµÄÐÅϢдÈëµ½comm_bufÖÐÈ¥
del_start(pass[c].j,pass[c].mpos,line.s + 1);
break;
case 'D':
break;
default:
...
return;
}
// ±êʶÏÂÒ»¸örcpt toµÄλÖÃ
pass[c].mpos += line.len;
return;
trouble:
...
}
void del_start(int j, seek_pos mpos, char *recip)
{
int i;
int c;
//
// local»¹ÊÇremoteµÄchannel
//
c = jo[j].channel;
//
// ·ÖÅäÒ»¸ödel ½á¹¹
//
for (i = 0;i < concurrency[c];++i)
if (!d[c][i].used)
break;
if (i == concurrency[c]) return;
//
// copy ½ÓÊÕÕßµØÖ·µ½del½á¹¹ÖÐ
//
if (!stralloc_copys(&d[c][i].recip,recip))
{
nomem();
return;
}
if (!stralloc_0(&d[c][i].recip))
{
nomem();
return;
}
// ÉèÖøÃdel½á¹¹µÄÏà¹Ø±äÁ¿
d[c][i].j = j; ++jo[j].refs;
d[c][i].delid = masterdelid++;
d[c][i].mpos = mpos;
d[c][i].used = 1; ++concurrencyused[c];
//
// ½«Í¶µÝÐÅϢдÈëµ½comm_bufÖÐÈ¥
//
comm_write(c, i, jo[j].id, jo[j]. sender.s, recip);
del_status();
}
×¼±¸ºÃÁËÐèҪͶµÝµÄÐÅÏ¢£¬²¢Í¨¹ýÎÒÃÇÉÏÃæËùÌáµ½µÄcomm_do(&wfds)½«Í¶µÝÐÅϢͨ¹ýpipe´«µÝ¸ølspawn»òÕßrspawn. del_do²»¶ÏµÄ¼àÌýÀ´×Ôspawn½ø³ÌµÄ»Ø¸´½á¹û£¬Ëüͨ¹ýµ÷ÓÃdel_dochanÀ´ÊµÏֵġ£
void del_dochan(int c)
{
char ch;
int delnum;
int test_i = 0;
int i, r;
// ¶ÁÈ¡À´×Ôspawn processµÄÐÅÏ¢
r = read(chanfdin[c], delbuf, sizeof(delbuf));
/* handle every character read from the spawn */
for (i = 0; i < r; ++i) {
ch = delbuf[i];
while (!stralloc_append(&dline[c],&ch)) nomem();
if (dline[c].len > REPORTMAX) {
dline[c].len = REPORTMAX;
}
/* qmail-lspawn and qmail-rspawn are responsible for keeping it
short */
/* but from a security point of view, we don't trust rspawn */
if (!ch && (dline[c].len > 1)) {
delnum = (unsigned int) (unsigned char) dline[c].s[0];
if ((delnum < 0) || (delnum >= concurrency[c])
|| !d[c][delnum].used) {
/* delnum out of range exception, maybe pipe broken */
...
}
else {
strnum3[fmt_ulong(strnum3,d[c][delnum].delid)] = 0;
//
// Z´ú±íÐèÒª³¢ÊÔÖØÊÔ£¬´ËʱÎÒÃÇÐèÒªÅжÏflagdyingÊÇ·ñ±»ÖÃΪ1£¬
// Èç¹ûΪ1Ôò´ú±íͶ¸øÌض¨Óû§µÄ¸ÃÓʼþÔÚ¶ÓÁÐÖÐפÁôÁËÌ«³¤Ê±¼ä£¬
// ¿ÉÄÜÒѾ¶à´Î³¢ÊÔͶµÝµ«¶¼Ê§°ÜÁË£¬´ËʱҪ½«Æä±ê¼ÇΪͶµÝʧ°Ü'D'
//
if (dline[c].s[1] == 'Z') {
if (jo[d[c][delnum].j].flagdying) {
dline[c].s[1] = 'D';
--dline[c].len; /* strip the last LF */
while (!stralloc_cats(&dline[c], DSN_QUEUE_TOO_LONG)) nomem();
while (!stralloc_0(&dline[c])) nomem();
}
}
switch(dline[c].s[1]) {
case 'K': // Ê××ÖĸΪK´ú±íͶµÝ³É¹¦
// ±êʾ·¢ÍùÌØ¶¨Óû§µÄÓʼþÒѾ³É¹¦£¬ÔÚÏàÓ¦µÄ
// local/split/id»òÕßremote/split/idÎļþÖиÃrcpt to
// ±»ÖÃΪD
markdone(c, jo[d[c][delnum].j].id,
d[c][delnum].mpos);
--jo[d[c][delnum].j].numtodo;
break;
case 'Z': // ÐèÒªÖØÊÔ
break;
case 'D': // ͶµÝʧ°Ü
//
// ¼ÓÈëµ½bounceÖÐ
//
addbounce(jo[d[c][delnum].j].id,
d[c][delnum].recip.s, dline[c].s + 2);
//
// ±êʶÏàÓ¦µÄͶµÝÒѾ½áÊø
//
markdone(c,jo[d[c][delnum].j].id,
d[c][delnum].mpos);
--jo[d[c][delnum].j].numtodo;
break;
default:
}
//
// Èç¹û¸ÃjobµÄÒýÓüÆÊýΪ1£¬Í¬Ê±ËùÓеÄÓû§¶¼ÒѾͶËͳɹ¦£¬
// ÏàÓ¦µÄÉÏÃæÎÒÃÇËù˵µÄ¶ÔÓ¦¸ÃjobµÄÎļþ¾Í»á±»É¾³ý£¬Ëü»¹»á
// ¼ì²âÁíÒ»¸ö¶ÔӦĿ¼ÏµÄÎļþ£¨ÀýÈçlocal/split/id£©ÊÇ·ñÒÑ
// ¾²»´æÔÚÁËÈç¹ûÊÇ,µ±// È»Õû·âÓʼþÒѾͶµÝ½áÊø£¬¾ÍÍùÍê³É
// ¶ÓÁÐÖвåÈëÒ»Ìõ¼Ç¼£¬ ·ñÔòµÄ»°¼ÌÐø½«Ëü¼ÓÈëµ½ÄÚ´æÍ¶µÝ¶Ó
// ÁÐÖУ¬Ö»ÊÇʱ¼ä±äΪÏÂÒ»´ÎÖØÊÔµÄʱ¼ä
job_close(d[c][delnum].j);
d[c][delnum].used = 0;
--concurrencyused[c];
del_status();
}
dline[c].len = 0; /*reset the dline */
}
}
}
.........................................................................................
cleanup_do() Æäʵ¾ÍÊǽ«¶ÓÁÐmessĿ¼ÏÂһЩÒѾͶµÝ³É¹¦µ«ÉÐδɾ³ýµÄÓʼþɾµô¡£
ÏÖÔÚÎÒÃÇ´óÖ¿ÉÒԵóöqmail¶ÔÓʼþµÄ´¦Àí¹ý³Ì£¬ÓÉǰ¶ËsmtpdÊÕÏÂÓʼþ£¬Í¨¹ýÁãʱ½ø³Ìqmail-queue½«ÓʼþÈë¶Ó¡£qmail-queueÊ×ÏÈÔÚpidĿ¼Ï´´½¨Ò»¸öinode,ÒÔÕâ¸öinodeµÄÐòÁкÅ×÷Ϊ¸Ãmail messageµÄid£¬Ëæºó½«¸ÃinodeÓ²Á¬½Óµ½messĿ¼Ï£¬Ð´ÈëÓʼþµÄÄÚÈÝ£¬²¢ÔÚintdĿ¼Ï´´½¨Ò»¸öͬÃûµÄÎļþ£¬Ð´ÈëMAIL FROMºÍRCPT TOµÈÐÅÏ¢ºóÓÖ½«¸ÃÎļþlinkµ½todoĿ¼Ï¡£ÖÁ´Ë,Õû¸öÓʼþµÄÈë¶Ó¹ý³ÌÍê³É¡£
qmail-send²»¶ÏɨÃètodoĿ¼£¬Èç¹ûÓÐÐÂÓʼþ,Ëü½«todoÎļþÖеÄMAIL FROMдÈëµ½infoĿ¼ÏµÄͬÃûÎļþÖУ¬RCPT TO·Ö±ðдÈëµ½localºÍremoteĿ¼ÏÂ,ɾ³ýtodoϵÄÎļþËæºó½«¸Ãid¼ÓÈëµ½remote»òÕßlocalµÄÄÚ´æ¶ÓÁÐÖÐ.£¨Ô¤´¦ÀíÍê³É£©¡£ qmailÔÚÄÚ´æÖÐÓÐËÄÌõ¶ÓÁУ¬·Ö±ðÎªÇ°ÃæËù˵µÄÁ½Ìõ£¬ºÍÒ»Ìõ±êʾÒѾÍê³ÉÒ»·ÝÓʼþ´¦ÀíµÄ¶ÓÁÐÒÔ¼°Ò»ÌõÎļþϵͳ·¢Éú´íÎóʱ²Å»á±»Ê¹Óõ½µÄ¶ÓÁÐ. job¶ÔÓ¦Ò»¸ölocal»òÕßremoteϱ£´ærcpt toµÄÎļþ,rcpt toµÄµØÖ·ÒÔT×÷Ϊ¿ªÍ·,µ±Íù¸ÃÓû§³É¹¦Í¶µÝºóqmail¾Í½«T¸ÄΪD±êʾͶµÝ³É¹¦»òÕßÓÀ¾ÃÐÔʧ°Ü.
qmail-send²»¶Ï´Óremote»òÕßlocalµÄÄÚ´æ¶ÓÁÐÖÐÈ¡ÏÂÒ»¸öid,¸øËü·ÖÅäÒ»¸ö¶ÔÓ¦µÄjob,²¢´ÓÏàÓ¦µÄinfo, local»òÕßremoteĿ¼ÏÂÈ¡µ½MAIL FROMºÍRCPT TO²¢½«Ëüдµ½¹ÜµÀµÄbufferÖÐ,×îºó²Å±»Ð´Èë¹ÜµÀ. ¹ÜµÀÊÇqmail-sendÓÃÀ´ÓëÁ½¸ö³¤×¤½ø³ÌrspawnºÍlspawnͨÐŵķ½Ê½.rspawn»òÕßlspawnÊÕµ½À´×Ôqmail-sendµÄͶµÝÐÅÏ¢ºó´´½¨Ò»¸öеĽø³ÌȥͶµÝ,rspawn»òÕßlspawnͨ¹ýwaitÕâ¸ö½ø³Ì½áÊøÊ±µÄexit codeÀ´È·¶¨Í¶µÝµÄ³É¹¦Óë·ñ.È»ºóÔÙͨ¹ý¹ÜµÀ½«½á¹û·µ»Ø¸øqmail-send. qmail-send¼ì²éͶµÝµÄ½á¹û,Èç¹û³É¹¦¾ÍÈçÉÏÃæËù˵µÄ½«rcpt±êʾΪD,·ñÔòÈ·¶¨ÊÇÒªÖØÊÔ»¹ÊǶà´Î³¢ÊÔʧ°Ü·ÅÆú¡£µ±Ò»¸öjobÖÐËùÓеÄRCPT TO¶¼±»´¦ÀíÍêºó,qmail-send½«ÏàÓ¦µÄlocal»òÕßremoteĿ¼ÏµÄÎļþɾ³ý£¬µ±Ò»¸ömsgid¶ÔÓ¦µÄlocal»òÕßremoteÏ嵀 rcpt toÈ«±»´¦ÀíÍêʱ(¼´Õ⼸¸öÎļþÒѾ²»´æÔÚÁË)£¬Ôò¸Ãid»á±»¼ÓÈëµ½Íê³É¶ÓÁÐÖÐÈ¥. qmail-sendÒ²»á²»¶Ï¼ì²âÕâ¸öÍê³É¶ÓÁÐ,È¡ÏÂÒ»¸öid£¬Í¨¹ý¼ì²âbounceĿ¼ÏÂÊÇ·ñÓжÔÓ¦µÄÎļþÀ´¾ö¶¨ÊÇ·ñÐèÒªbounce£¬²¢É¾³ýinfoĿ¼ÏµĶÔÓ¦Îļþ×îºóÌá½»¸øqmail-clean½«messĿ¼ÏµÄÎļþɾ³ý¡£
ÕâЩӦ¸Ã¾ÍÊÇÒ»·âÓʼþÔÚqmailÖд¦ÀíµÄ´óÖ¹ý³Ì£¬µ±È»qmail-send ²¢²»ÏñÎÒËù˵µÄÄÇÑùÏßÐÔµØÖ´ÐÐÏÂÀ´µÄ£¬ËüÊÇͨ¹ýÒ»¸öÑ»·²»¶ÏµØÖ´ÐÐÇ°ÃæËù˵µÄÄÇÎå¸öº¯ÊýÀ´ÊµÏÖÕâÒ»¹ý³ÌµÄ¡£,