⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smail.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* smail.c - MH interface to SendMail/SMTP */#ifndef	lintstatic char ident[] = "@(#)$Id: smail.c,v 1.28 1994/03/23 23:24:51 jromine Exp $";#endif/* 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>#ifndef	TYPESIG#define	TYPESIG	int#endif#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))		/* these codes must all be different! */#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	150#define	SM_DOT	180#define	SM_QUIT	 30#define	SM_CLOS	 10/*  */static TYPESIG	alrmser ();static int  sm_addrs = 0;static int  sm_alarmed = 0;#ifndef	SMTPstatic int  sm_child = NOTOK;#endif	/* not SMTP */static int  sm_debug = 0;static int  sm_nl = TRUE;static int  sm_verbose = 0;static  FILE * sm_rfp = NULL;static  FILE * sm_wfp = NULL;#ifdef	MPOPstatic	int  sm_ispool = 0;static	char sm_tmpfil[BUFSIZ];#endif /* MPOP */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();#ifdef	MPOPextern	int	errno;#ifndef	BSD44extern	int	sys_nerr;extern	char   *sys_errlist[];#endifextern	char  **brkstring (), **copyip (), *getcpy ();#endifstatic	int	doingEHLO;#define	MAXEHLO	10char   *EHLOkeys[MAXEHLO + 1];char   *EHLOset ();/*  */#ifndef	SMTP/* ARGSUSED */int     sm_init (client, server, watch, verbose, debug, onex, queued)char   *client,       *server;int	watch,	verbose,	debug,	onex,    	queued;{    register int    i,                    result,                    vecp;    int     pdi[2],            pdo[2];    char   *vec[15];    if (watch)#ifndef	SUN40	verbose = TRUE;#else	/* to show the transaction, -watch must imply -snoop */	debug = verbose = TRUE;#endif    sm_verbose = verbose;    sm_debug = debug;    if (sm_rfp != NULL && sm_wfp != NULL)	return RP_OK;    if (client == NULL || *client == '\0')	client = clientname;#ifdef ZMAILER    if (client == NULL || *client == '\0')	client = "localhost";#endif    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";#ifndef ZMAILER	    vec[vecp++] = watch ? "-odi" : queued ? "-odq" : "-odb";	    vec[vecp++] = "-oem";	    vec[vecp++] = "-om";#ifndef	RAND	    if (verbose)		vec[vecp++] = "-ov";#endif	/* not RAND */#endif	/* not ZMAILER */	    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) {		doingEHLO = 1;		result = smtalk (SM_HELO, "EHLO %s", client);		doingEHLO = 0;		if (500 <= result && result <= 599)		    result = smtalk (SM_HELO, "HELO %s", client);		switch (result) {		    case 250:		        break;		    default:			(void) sm_end (NOTOK);			return RP_RPLY;		}	    }#ifndef	ZMAILER	    if (onex)		(void) smtalk (SM_HELO, "ONEX");#endif	    if (watch)		(void) smtalk (SM_HELO, "VERB on");	    return RP_OK;    }}#else	/* SMTP *//*  */int     sm_init (client, server, watch, verbose, debug, onex, queued)char   *client,       *server;int	watch,	verbose,	debug,	onex,	queued;{    register int    result,                    sd1,                    sd2;    if (watch)#if	!defined(SUN40) || defined(MMDFII)	verbose = TRUE;#else	/* to show the transaction, -watch must imply -snoop */	debug = verbose = TRUE;#endif    sm_verbose = verbose;    sm_debug = debug;#ifdef	MPOP    if (sm_ispool)	goto all_done;#endif    if (sm_rfp != NULL && sm_wfp != NULL)	goto send_options;    if (client == NULL || *client == '\0')	if (clientname)	    client = clientname;	else	    client = LocalName ();	/* no clientname -> LocalName */#ifdef ZMAILER    if (client == NULL || *client == '\0')	client = "localhost";#endif	/* not ZMAILER */    if ((sd1 = rclient (server, "tcp", "smtp")) == NOTOK)	return RP_BHST;#ifdef	MPOP    if (sm_ispool) {	if (sm_rfp) {	    (void) alarm (SM_CLOS);	    (void) fclose (sm_rfp);	    (void) alarm (0);	    sm_rfp = NULL;	}	if ((sm_wfp = fdopen (sd1, "w")) == NULL) {	    (void) unlink (sm_tmpfil);	    (void) close (sd1);	    return sm_ierror ("unable to fdopen");	}all_done: ;	sm_reply.text[sm_reply.length = 0] = NULL;	return (sm_reply.code = RP_OK);    }#endif /* MPOP */    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) {	doingEHLO = 1;	result = smtalk (SM_HELO, "EHLO %s", client);	doingEHLO = 0;	if (500 <= result && result <= 599)	    result = smtalk (SM_HELO, "HELO %s", client);	switch (result) {	    case 250: 		break;	    default: 		(void) sm_end (NOTOK);		return RP_RPLY;	}    }send_options: ;    if (watch && EHLOset ("XVRB"))	(void) smtalk (SM_HELO, "VERB on");    if (onex && EHLOset ("XONE"))	(void) smtalk (SM_HELO, "ONEX");    if (queued && EHLOset ("XQUE"))	(void) smtalk (SM_HELO, "QUED");    return RP_OK;}#ifdef	MPOP#define	MAXARGS	1000#endif /* MPOP */static int rclient (server, protocol, service)char   *server,       *protocol,       *service;{    int     sd;    char    response[BUFSIZ];#ifdef	MPOP    char   *cp;#endif /* MPOP */    if ((sd = client (server, protocol, service, FALSE, response)) != NOTOK)	return sd;#ifdef	MPOP    if (!server && servers && (cp = index (servers, '/'))) {	register char  **ap;	char   *arguments[MAXARGS];	(void) copyip (brkstring (cp = getcpy (servers), " ", "\n"),		       arguments);	for (ap = arguments; *ap; ap++)	    if (**ap == '/') {		register char *dp;		if ((dp = rindex (*ap, '/')) && *++dp == NULL)		    *--dp = NULL;		(void) sprintf (sm_tmpfil, "%s/smtpXXXXXX", *ap);		(void) mktemp (sm_tmpfil);		if ((sd = creat (sm_tmpfil, 0600)) != NOTOK) {		    sm_ispool = 1;		    break;		}	    }	free (cp);	if (sd != NOTOK)	    return sd;    }#endif /* MPOP */    (void) sm_ierror ("%s", response);    return NOTOK;}#endif	/* SMTP *//*  */int     sm_winit (mode, from)register int	mode;register char   *from;{#ifdef	MPOP    if (sm_ispool && !sm_wfp) {	(void) strlen (strcpy (sm_reply.text,			       "unable to create new spool file"));	sm_reply.code = NOTOK;	return RP_BHST;    }#endif /* MPOP */    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	/* BERK */int     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: 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -