srvrsmtp.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 743 行 · 第 1/2 页
C
743 行
** Arrange to send to everyone. ** ** A note on error handling: ** Originally, sendmail did not mail back errors ** which ocurred during address verification. ** This code does. ** ** Since we returned a 250 in the Rcpt To: ** for an address which contained potentially ** bad addresses, we must honor EF_FATALERRS ** and mail back an error message. */ SmtpPhase = "delivery"; if (CurEnv->e_nrcpts != 1) { HoldErrs = TRUE; ErrorMode = EM_MAIL; } /* send to all recipients */ sendall(CurEnv, SM_DEFAULT); CurEnv->e_to = NULL; /* save statistics */ markstats(CurEnv, (ADDRESS *) NULL); /* issue success if appropriate and reset */ if (Errors == 0 || HoldErrs) message("250", "Ok"); /* * Was there an error expanding the alias? * If so, make sure we mail it back. */ if (aliaserror) CurEnv->e_flags |= EF_FATALERRS; /* if in a child, pop back to our parent */ if (InChild) finis(); /* clean up a bit */ hasmail = 0; dropenvelope(CurEnv); CurEnv = newenvelope(CurEnv); CurEnv->e_flags = BlankEnvelope.e_flags; break; case CMDRSET: /* rset -- reset state */ message("250", "Reset state"); if (InChild) finis(); break; case CMDVRFY: /* vrfy -- verify address */ if (runinchild("SMTP-VRFY") > 0) break; setproctitle("%s: %s", CurHostName, inp); vrfyqueue = NULL; QuickAbort = TRUE; sendtolist(p, (ADDRESS *) NULL, &vrfyqueue); if (Errors != 0) { if (InChild) finis(); break; } while (vrfyqueue != NULL) { register ADDRESS *a = vrfyqueue->q_next; char *code; while (a != NULL && bitset(QDONTSEND|QBADADDR, a->q_flags)) a = a->q_next; if (!bitset(QDONTSEND|QBADADDR, vrfyqueue->q_flags)) { if (a != NULL) code = "250-"; else code = "250"; if (vrfyqueue->q_fullname == NULL) message(code, "<%s>", vrfyqueue->q_paddr); else message(code, "%s <%s>", vrfyqueue->q_fullname, vrfyqueue->q_paddr); } else if (a == NULL) message("554", "Self destructive alias loop"); vrfyqueue = a; } if (InChild) finis(); break; case CMDHELP: /* help -- give user info */ if (*p == '\0') p = "SMTP"; help(p); break; case CMDNOOP: /* noop -- do nothing */ message("200", "OK"); break; case CMDQUIT: /* quit -- leave mail */ message("221", "%s closing connection", MyHostName); if (InChild) ExitStat = EX_QUIT; finis(); case CMDVERB: /* set verbose mode */ Verbose = TRUE; SendMode = SM_DELIVER; message("200", "Verbose mode"); break; case CMDONEX: /* doing one transaction only */ OneXact = TRUE; message("200", "Only one transaction"); break;# ifdef DEBUG case CMDDBGQSHOW: /* show queues */ printf("Send Queue="); printaddr(CurEnv->e_sendqueue, TRUE); break; case CMDDBGDEBUG: /* set debug mode */ tTsetup(tTdvect, sizeof tTdvect, "0-99.1"); tTflag(p); message("200", "Debug set"); break;# endif DEBUG# ifdef WIZ case CMDDBGKILL: /* kill the parent */ if (!iswiz()) break; if (kill(MotherPid, SIGTERM) >= 0) message("200", "Mother is dead"); else message("500", "Can't kill Mom"); break; case CMDDBGWIZ: /* become a wizard */ if (WizWord != NULL) { char seed[3]; extern char *crypt(); (void) strncpy(seed, WizWord, 2); if (strcmp(WizWord, crypt(p, seed)) == 0) { IsWiz = TRUE; message("200", "Please pass, oh mighty wizard"); break; } } message("500", "You are no wizard!"); break;# else WIZ case CMDDBGWIZ: /* try to become a wizard */ message("500", "You wascal wabbit! Wandering wizards won't win!"); break;# endif WIZ case CMDERROR: /* unknown command */ message("500", "Command unrecognized"); break; default: syserr("smtp: unknown code %d", c->cmdcode); break; } }}/*** SKIPWORD -- skip a fixed word.**** Parameters:** p -- place to start looking.** w -- word to skip.**** Returns:** p following w.** NULL on error.**** Side Effects:** clobbers the p data area.*/static char *skipword(p, w) register char *p; char *w;{ register char *q; extern bool sameword(); /* find beginning of word */ while (isspace(*p)) p++; q = p; /* find end of word */ while (*p != '\0' && *p != ':' && !isspace(*p)) p++; while (isspace(*p)) *p++ = '\0'; if (*p != ':') { syntax: message("501", "Syntax error"); Errors++; return (NULL); } *p++ = '\0'; while (isspace(*p)) p++; /* see if the input word matches desired word */ if (!sameword(q, w)) goto syntax; return (p);}/*** HELP -- implement the HELP command.**** Parameters:** topic -- the topic we want help for.**** Returns:** none.**** Side Effects:** outputs the help file to message output.*/help(topic) char *topic;{ register FILE *hf; int len; char buf[MAXLINE]; bool noinfo; if (HelpFile == NULL || (hf = fopen(HelpFile, "r")) == NULL) { /* no help */ errno = 0; message("502", "HELP not implemented"); return; } len = strlen(topic); makelower(topic); noinfo = TRUE; while (fgets(buf, sizeof buf, hf) != NULL) { if (strncmp(buf, topic, len) == 0) { register char *p; p = index(buf, '\t'); if (p == NULL) p = buf; else p++; fixcrlf(p, TRUE); message("214-", p); noinfo = FALSE; } } if (noinfo) message("504", "HELP topic unknown"); else message("214", "End of HELP info"); (void) fclose(hf);}/*** ISWIZ -- tell us if we are a wizard**** If not, print a nasty message.**** Parameters:** none.**** Returns:** TRUE if we are a wizard.** FALSE if we are not a wizard.**** Side Effects:** Prints a 500 exit stat if we are not a wizard.*/#ifdef WIZbooliswiz(){ if (!IsWiz) message("500", "Mere mortals musn't mutter that mantra"); return (IsWiz);}#endif WIZ/*** RUNINCHILD -- return twice -- once in the child, then in the parent again**** Parameters:** label -- a string used in error messages**** Returns:** zero in the child** one in the parent**** Side Effects:** none.*/runinchild(label) char *label;{ int childpid; if (!OneXact) { childpid = dofork(); if (childpid < 0) { syserr("%s: cannot fork", label); return (1); } if (childpid > 0) { auto int st; /* parent -- wait for child to complete */ st = waitfor(childpid); if (st == -1) syserr("%s: lost child", label); /* if we exited on a QUIT command, complete the process */ if (st == (EX_QUIT << 8)) finis(); return (1); } else { /* child */ InChild = TRUE; QuickAbort = FALSE; clearenvelope(CurEnv, FALSE); } } /* open alias database */ initaliases(AliasFile, FALSE); return (0);}# endif SMTP
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?