📄 smail.c
字号:
/* smail.c - MH interface to SendMail/SMTP *//* LINTLIBRARY *//* This module implements an interface to SendMail very similar to the MMDF mm_(3) routines. The sm_() routines herein talk SMTP to a sendmail process, mapping SMTP reply codes into RP_-style codes. */#ifdef BSD42/* Under 4.2BSD, the alarm handing stuff for time-outs will NOT work due to the way syscalls get restarted. This really is not crucial, since we expect SendMail to be well-behaved and not hang on us. The only time I've ever seen Sendmail hang was with a bogus configuration file... */#endif BSD42#ifdef SENDMAILBUG/* * It appears that some versions of Sendmail will return Code 451 * when they don't really want to indicate a failure. * "Code 451 almost always means sendmail has deferred; we don't * really want bomb out at this point since sendmail will rectify * things later." So, if you define SENDMAILBUG, Code 451 is * considered the same as Code 250. Yuck! */#ifndef SENDMAIL#undef SENDMAILBUG#endif not SENDMAIL#endif SENDMAILBUG#ifdef hpux /* HP-UX has this capability. It also handles (some) signals. */#define BSD42 #endif hpux#if !defined(BSD42) && !defined(SOCKETS)#undef SMTP#endif not BSD42 and not SOCKETS#ifdef SMTP#undef SENDMAIL#endif SMTP#include "../h/strings.h"#include <stdio.h>#include "smail.h"#include "../zotnet/mts.h"#include <ctype.h>#include <signal.h>#define NOTOK (-1)#define OK 0#define DONE 1#define TRUE 1#define FALSE 0#define NBITS ((sizeof (int)) * 8)#define min(a,b) ((a) < (b) ? (a) : (b))#define SM_OPEN 90 /* Changed from 30 in case of nameserver flakiness */#define SM_HELO 20#define SM_RSET 15#define SM_MAIL 40#define SM_RCPT 120#define SM_DATA 20#define SM_TEXT 120#define SM_DOT 120#define SM_QUIT 20#define SM_CLOS 10/* */static int alrmser ();static int sm_addrs = 0;static int sm_alarmed = 0;#ifndef SMTPstatic int sm_child = NOTOK;#endif not SMTPstatic int sm_debug = 0;static int sm_nl = TRUE;static int sm_verbose = 0;static FILE * sm_rfp = NULL;static FILE * sm_wfp = NULL;static char *sm_noreply = "No reply text given";static char *sm_moreply = "; ";struct smtp sm_reply; /* global... */void discard ();char *r1bindex ();static int rclient(), sm_ierror(), smtalk(), sm_wrecord(), sm_wstream();static int sm_werror(), smhear(), sm_rrecord(), sm_rerror();/* */#ifndef SMTP/* ARGSUSED */int sm_init (client, server, watch, verbose, debug)register char *client;char *server;register int watch, verbose, debug;{ register int i, result, vecp; int pdi[2], pdo[2]; char *vec[15]; if (watch) verbose = TRUE; sm_verbose = verbose; sm_debug = debug; if (sm_rfp != NULL && sm_wfp != NULL) return RP_OK; if (pipe (pdi) == NOTOK) return sm_ierror ("no pipes"); if (pipe (pdo) == NOTOK) { (void) close (pdi[0]); (void) close (pdi[1]); return sm_ierror ("no pipes"); } for (i = 0; (sm_child = fork ()) == NOTOK && i < 5; i++) sleep (5); switch (sm_child) { case NOTOK: (void) close (pdo[0]); (void) close (pdo[1]); (void) close (pdi[0]); (void) close (pdi[1]); return sm_ierror ("unable to fork"); case OK: if (pdo[0] != fileno (stdin)) (void) dup2 (pdo[0], fileno (stdin)); if (pdi[1] != fileno (stdout)) (void) dup2 (pdi[1], fileno (stdout)); if (pdi[1] != fileno (stderr)) (void) dup2 (pdi[1], fileno (stderr)); for (i = fileno (stderr) + 1; i < NBITS; i++) (void) close (i); vecp = 0; vec[vecp++] = r1bindex (sendmail, '/'); vec[vecp++] = "-bs"; vec[vecp++] = watch ? "-odi" : "-odb"; vec[vecp++] = "-oem"; vec[vecp++] = "-om";#ifndef RAND if (verbose) vec[vecp++] = "-ov";#endif not RAND vec[vecp++] = NULL; (void) setgid (getegid ()); (void) setuid (geteuid ()); execvp (sendmail, vec); fprintf (stderr, "unable to exec "); perror (sendmail); _exit (-1); /* NOTREACHED */ default: (void) signal (SIGALRM, alrmser); (void) signal (SIGPIPE, SIG_IGN); (void) close (pdi[1]); (void) close (pdo[0]); if ((sm_rfp = fdopen (pdi[0], "r")) == NULL || (sm_wfp = fdopen (pdo[1], "w")) == NULL) { (void) close (pdi[0]); (void) close (pdo[1]); sm_rfp = sm_wfp = NULL; return sm_ierror ("unable to fdopen"); } sm_alarmed = 0; (void) alarm (SM_OPEN); result = smhear (); (void) alarm (0); switch (result) { case 220: break; default: (void) sm_end (NOTOK); return RP_RPLY; } if (client && *client) switch (smtalk (SM_HELO, "HELO %s", client)) { case 250: break; default: (void) sm_end (NOTOK); return RP_RPLY; } return RP_OK; }}#else SMTP/* */int sm_init (client, server, watch, verbose, debug)register char *client, *server;register int watch, verbose, debug;{ register int result, sd1, sd2; if (watch) verbose = TRUE; sm_verbose = verbose; sm_debug = debug; if (sm_rfp != NULL && sm_wfp != NULL) return RP_OK;#if !defined(SENDMTS) || defined(MMDFII) if (client == NULL || *client == NULL) client = LocalName ();#endif if ((sd1 = rclient (server, "tcp", "smtp")) == NOTOK) return RP_BHST; if ((sd2 = dup (sd1)) == NOTOK) { (void) close (sd1); return sm_ierror ("unable to dup"); } (void) signal (SIGALRM, alrmser); (void) signal (SIGPIPE, SIG_IGN); if ((sm_rfp = fdopen (sd1, "r")) == NULL || (sm_wfp = fdopen (sd2, "w")) == NULL) { (void) close (sd1); (void) close (sd2); sm_rfp = sm_wfp = NULL; return sm_ierror ("unable to fdopen"); } sm_alarmed = 0; (void) alarm (SM_OPEN); result = smhear (); (void) alarm (0); switch (result) { case 220: break; default: (void) sm_end (NOTOK); return RP_RPLY; } if (client && *client) switch (smtalk (SM_HELO, "HELO %s", client)) { case 250: break; default: (void) sm_end (NOTOK); return RP_RPLY; } return RP_OK;}static int rclient (server, protocol, service)char *server, *protocol, *service;{ int sd; char response[BUFSIZ]; if ((sd = client (server, protocol, service, FALSE, response)) != NOTOK) return sd; (void) sm_ierror ("%s", response); return NOTOK;}#endif SMTP/* */int sm_winit (mode, from)register int mode;register char *from;{ switch (smtalk (SM_MAIL, "%s FROM:<%s>", mode == S_SEND ? "SEND" : mode == S_SOML ? "SOML" : mode == S_SAML ? "SAML" : "MAIL", from)) { case 250: sm_addrs = 0; return RP_OK; case 500: case 501: case 552: return RP_PARM; default: return RP_RPLY; }}/* */#ifdef BERK/* ARGUSED */#endif BERKint sm_wadr (mbox, host, path)register char *mbox;#ifndef BERKregister#endif not BERK char *host, *path;{#ifndef BERK switch (smtalk (SM_RCPT, host && *host ? "RCPT TO:<%s%s@%s>" : "RCPT TO:<%s%s>", path ? path : "", mbox, host)) {#else BERK switch (smtalk (SM_RCPT, "RCPT TO:%s", mbox)) {#endif BERK case 250: case 251: sm_addrs++; return RP_OK; case 451: #ifdef SENDMAILBUG sm_addrs++; return RP_OK;#endif SENDMAILBUG case 421: case 450: case 452: return RP_NO; case 500: case 501: return RP_PARM; case 550: case 551: case 552: case 553: return RP_USER; default: return RP_RPLY; }}/* */int sm_waend () { switch (smtalk (SM_DATA, "DATA")) { case 354: sm_nl = TRUE; return RP_OK; case 451: #ifdef SENDMAILBUG sm_nl = TRUE; return RP_OK;#endif SENDMAILBUG case 421: return RP_NO; case 500: case 501: case 503: case 554: return RP_NDEL; default: return RP_RPLY; }}/* */int sm_wtxt (buffer, len)register char *buffer;register int len;{ register int result; sm_alarmed = 0; (void) alarm (SM_TEXT); result = sm_wstream (buffer, len); (void) alarm (0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -