summaryrefslogtreecommitdiffstats
path: root/usr.sbin/sendmail/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/src/main.c')
-rw-r--r--usr.sbin/sendmail/src/main.c1087
1 files changed, 242 insertions, 845 deletions
diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c
index 5e352f2..bae41d5 100644
--- a/usr.sbin/sendmail/src/main.c
+++ b/usr.sbin/sendmail/src/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983, 1995 Eric P. Allman
+ * Copyright (c) 1983 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -39,15 +39,17 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)main.c 8.162 (Berkeley) 11/18/95";
+static char sccsid[] = "@(#)main.c 8.55.1.7 (Berkeley) 3/5/95";
#endif /* not lint */
#define _DEFINE
#include "sendmail.h"
#if NAMED_BIND
+#include <arpa/nameser.h>
#include <resolv.h>
#endif
+#include <pwd.h>
# ifdef lint
char edata, end;
@@ -92,9 +94,21 @@ ENVELOPE BlankEnvelope; /* a "blank" envelope */
ENVELOPE MainEnvelope; /* the envelope around the basic letter */
ADDRESS NullAddress = /* a null address */
{ "", "", NULL, "" };
+char *UserEnviron[MAXUSERENVIRON + 2];
+ /* saved user environment */
+char RealUserName[256]; /* the actual user id on this host */
char *CommandLineArgs; /* command line args for pid file */
bool Warn_Q_option = FALSE; /* warn about Q option use */
-char **SaveArgv; /* argument vector for re-execing */
+
+/*
+** Pointers for setproctitle.
+** This allows "ps" listings to give more useful information.
+*/
+
+# ifdef SETPROCTITLE
+char **Argv = NULL; /* pointer to argument vector */
+char *LastArgv = NULL; /* end of argv */
+# endif /* SETPROCTITLE */
static void obsolete();
@@ -104,9 +118,8 @@ ERROR %%%% Cannot have daemon mode without SMTP %%%% ERROR
#endif /* SMTP */
#endif /* DAEMON */
-#define MAXCONFIGLEVEL 6 /* highest config version level known */
+#define MAXCONFIGLEVEL 5 /* highest config version level known */
-int
main(argc, argv, envp)
int argc;
char **argv;
@@ -114,6 +127,7 @@ main(argc, argv, envp)
{
register char *p;
char **av;
+ extern int finis();
extern char Version[];
char *ep, *from;
typedef int (*fnptr)();
@@ -125,25 +139,22 @@ main(argc, argv, envp)
bool warn_C_flag = FALSE;
char warn_f_flag = '\0';
static bool reenter = FALSE;
+ char *argv0 = argv[0];
struct passwd *pw;
struct stat stb;
- struct hostent *hp;
char jbuf[MAXHOSTNAMELEN]; /* holds MyHostName */
- static char rnamebuf[MAXNAME]; /* holds RealUserName */
extern int DtableSize;
extern int optind;
- extern int opterr;
extern time_t convtime();
+ extern putheader(), putbody();
extern void intsig();
- extern struct hostent *myhostname();
+ extern char **myhostname();
extern char *arpadate();
extern char *getauthinfo();
extern char *getcfname();
extern char *optarg;
extern char **environ;
extern void sigusr1();
- extern void sighup();
- extern void initmacros __P((ENVELOPE *));
/*
** Check to see if we reentered.
@@ -161,8 +172,8 @@ main(argc, argv, envp)
/* do machine-dependent initializations */
init_md(argc, argv);
+ /* arrange to dump state on signal */
#ifdef SIGUSR1
- /* arrange to dump state on user-1 signal */
setsignal(SIGUSR1, sigusr1);
#endif
@@ -197,12 +208,10 @@ main(argc, argv, envp)
#ifdef LOG
# ifdef LOG_MAIL
openlog("sendmail", LOG_PID, LOG_MAIL);
-# else
+# else
openlog("sendmail", LOG_PID);
# endif
-#endif
-
- tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
+#endif
/* set up the blank envelope */
BlankEnvelope.e_puthdr = putheader;
@@ -222,29 +231,25 @@ main(argc, argv, envp)
RealUid = getuid();
RealGid = getgid();
- pw = sm_getpwuid(RealUid);
+ pw = getpwuid(RealUid);
if (pw != NULL)
- (void) strcpy(rnamebuf, pw->pw_name);
+ (void) strcpy(RealUserName, pw->pw_name);
else
- (void) sprintf(rnamebuf, "Unknown UID %d", RealUid);
- RealUserName = rnamebuf;
+ (void) sprintf(RealUserName, "Unknown UID %d", RealUid);
/* save command line arguments */
i = 0;
for (av = argv; *av != NULL; )
i += strlen(*av++) + 1;
- SaveArgv = (char **) xalloc(sizeof (char *) * (argc + 1));
CommandLineArgs = xalloc(i);
p = CommandLineArgs;
- for (av = argv, i = 0; *av != NULL; )
+ for (av = argv; *av != NULL; )
{
- SaveArgv[i++] = newstr(*av);
if (av != argv)
*p++ = ' ';
strcpy(p, *av++);
p += strlen(p);
}
- SaveArgv[i] = NULL;
/* Handle any non-getoptable constructions. */
obsolete(argv);
@@ -254,98 +259,63 @@ main(argc, argv, envp)
*/
#if defined(__osf__) || defined(_AIX3)
-# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mnO:o:p:q:r:sTtvX:x"
+# define OPTIONS "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvX:x"
+#endif
+#if defined(ultrix)
+# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mno:p:q:r:sTtvX:"
#endif
-#if defined(sony_news)
-# define OPTIONS "B:b:C:cd:E:e:F:f:h:IiJ:M:mnO:o:p:q:r:sTtvX:"
+#if defined(NeXT)
+# define OPTIONS "B:b:C:cd:e:F:f:h:IimnOo:p:q:r:sTtvX:"
#endif
#ifndef OPTIONS
-# define OPTIONS "B:b:C:cd:e:F:f:h:IiM:mnO:o:p:q:r:sTtvX:"
+# define OPTIONS "B:b:C:cd:e:F:f:h:Iimno:p:q:r:sTtvX:"
#endif
- opterr = 0;
while ((j = getopt(argc, argv, OPTIONS)) != EOF)
{
switch (j)
{
case 'd':
+ tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
tTflag(optarg);
setbuf(stdout, (char *) NULL);
+ printf("Version %s\n", Version);
break;
}
}
- opterr = 1;
- if (tTd(0, 1))
- {
- int ll;
- extern char *CompileOptions[];
+ InChannel = stdin;
+ OutChannel = stdout;
- printf("Version %s\n Compiled with:", Version);
- av = CompileOptions;
- ll = 7;
- while (*av != NULL)
- {
- if (ll + strlen(*av) > 63)
- {
- putchar('\n');
- ll = 0;
- }
- if (ll == 0)
- {
- putchar('\t');
- putchar('\t');
- }
- else
- putchar(' ');
- printf("%s", *av);
- ll += strlen(*av++) + 1;
- }
- putchar('\n');
- }
- if (tTd(0, 10))
- {
- int ll;
- extern char *OsCompileOptions[];
+ /*
+ ** Move the environment so setproctitle can use the space at
+ ** the top of memory.
+ */
- printf(" OS Defines:", Version);
- av = OsCompileOptions;
- ll = 7;
- while (*av != NULL)
- {
- if (ll + strlen(*av) > 63)
- {
- putchar('\n');
- ll = 0;
- }
- if (ll == 0)
- {
- putchar('\t');
- putchar('\t');
- }
- else
- putchar(' ');
- printf("%s", *av);
- ll += strlen(*av++) + 1;
- }
- putchar('\n');
-#ifdef _PATH_UNIX
- printf("Kernel symbols:\t%s\n", _PATH_UNIX);
-#endif
- printf(" Config file:\t%s\n", getcfname());
- printf(" Pid file:\t%s\n", PidFile);
+ for (i = j = 0; j < MAXUSERENVIRON && (p = envp[i]) != NULL; i++)
+ {
+ if (strncmp(p, "IFS=", 4) == 0 || strncmp(p, "LD_", 3) == 0)
+ continue;
+ UserEnviron[j++] = newstr(p);
}
+ UserEnviron[j] = NULL;
+ environ = UserEnviron;
- InChannel = stdin;
- OutChannel = stdout;
-
- /* initialize for setproctitle */
- initsetproctitle(argc, argv, envp);
+# ifdef SETPROCTITLE
+ /*
+ ** Save start and extent of argv for setproctitle.
+ */
- /* prime the child environment */
- setuserenv("AGENT", "sendmail");
+ Argv = argv;
+ if (i > 0)
+ LastArgv = envp[i - 1] + strlen(envp[i - 1]);
+ else
+ LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
+# endif /* SETPROCTITLE */
if (setsignal(SIGINT, SIG_IGN) != SIG_IGN)
(void) setsignal(SIGINT, intsig);
+ if (setsignal(SIGHUP, SIG_IGN) != SIG_IGN)
+ (void) setsignal(SIGHUP, intsig);
(void) setsignal(SIGTERM, intsig);
(void) setsignal(SIGPIPE, SIG_IGN);
OldUmask = umask(022);
@@ -365,13 +335,12 @@ main(argc, argv, envp)
/* initialize some macros, etc. */
initmacros(CurEnv);
- init_vendor_macros(CurEnv);
/* version */
define('v', Version, CurEnv);
/* hostname */
- hp = myhostname(jbuf, sizeof jbuf);
+ av = myhostname(jbuf, sizeof jbuf);
if (jbuf[0] != '\0')
{
struct utsname utsname;
@@ -388,6 +357,7 @@ main(argc, argv, envp)
if (p[1] != '\0')
{
define('m', newstr(&p[1]), CurEnv);
+ setclass('m', &p[1]);
}
while (p != NULL && strchr(&p[1], '.') != NULL)
{
@@ -408,42 +378,19 @@ main(argc, argv, envp)
p = jbuf;
}
if (tTd(0, 4))
- printf(" UUCP nodename: %s\n", p);
+ printf("UUCP nodename: %s\n", p);
p = newstr(p);
define('k', p, CurEnv);
setclass('k', p);
setclass('w', p);
}
- if (hp != NULL)
+ while (av != NULL && *av != NULL)
{
- for (av = hp->h_aliases; av != NULL && *av != NULL; av++)
- {
- if (tTd(0, 4))
- printf("\ta.k.a.: %s\n", *av);
- setclass('w', *av);
- }
-#if NETINET
- if (hp->h_addrtype == AF_INET && hp->h_length == INADDRSZ)
- {
- register int i;
-
- for (i = 0; hp->h_addr_list[i] != NULL; i++)
- {
- char ipbuf[103];
-
- sprintf(ipbuf, "[%.100s]",
- inet_ntoa(*((struct in_addr *) hp->h_addr_list[i])));
- if (tTd(0, 4))
- printf("\ta.k.a.: %s\n", ipbuf);
- setclass('w', ipbuf);
- }
- }
-#endif
+ if (tTd(0, 4))
+ printf("\ta.k.a.: %s\n", *av);
+ setclass('w', *av++);
}
- /* probe interfaces and locate any additional names */
- load_if_names();
-
/* current time */
define('b', arpadate((char *) NULL), CurEnv);
@@ -500,7 +447,9 @@ main(argc, argv, envp)
case MD_TEST:
case MD_INITALIAS:
case MD_PRINT:
+#ifdef MAYBE_NEXT_RELEASE
case MD_ARPAFTP:
+#endif
OpMode = j;
break;
@@ -517,14 +466,17 @@ main(argc, argv, envp)
break;
case 'B': /* body type */
- CurEnv->e_bodytype = optarg;
+ if (strcasecmp(optarg, "7bit") == 0 ||
+ strcasecmp(optarg, "8bitmime") == 0)
+ CurEnv->e_bodytype = newstr(optarg);
+ else
+ usrerr("Illegal body type %s", optarg);
break;
case 'C': /* select configuration file (already done) */
if (RealUid != 0)
warn_C_flag = TRUE;
ConfFile = optarg;
- endpwent();
(void) setgid(RealGid);
(void) setuid(RealUid);
safecf = FALSE;
@@ -559,7 +511,7 @@ main(argc, argv, envp)
break;
}
break;
-
+
case 'n': /* don't alias */
NoAlias = TRUE;
break;
@@ -568,10 +520,6 @@ main(argc, argv, envp)
setoption(*optarg, optarg + 1, FALSE, TRUE, CurEnv);
break;
- case 'O': /* set option (long form) */
- setoption(' ', optarg, FALSE, TRUE, CurEnv);
- break;
-
case 'p': /* set protocol */
p = strchr(optarg, ':');
if (p != NULL)
@@ -626,7 +574,6 @@ main(argc, argv, envp)
break;
case 'X': /* traffic log file */
- endpwent();
setgid(RealGid);
setuid(RealUid);
TrafficLogFile = fopen(optarg, "a");
@@ -652,7 +599,9 @@ main(argc, argv, envp)
break;
case 'e': /* error message disposition */
+# if defined(ultrix)
case 'M': /* define macro */
+# endif
setoption(j, optarg, FALSE, TRUE, CurEnv);
break;
@@ -670,10 +619,8 @@ main(argc, argv, envp)
case 'x': /* random flag that OSF/1 & AIX mailx passes */
break;
# endif
-# if defined(sony_news)
- case 'E':
- case 'J': /* ignore flags for Japanese code conversion
- impremented on Sony NEWS */
+# if defined(NeXT)
+ case 'O': /* random flag that NeXT Mail.app passes */
break;
# endif
@@ -691,42 +638,23 @@ main(argc, argv, envp)
** Extract special fields for local use.
*/
- /* set up ${opMode} for use in config file */
- {
- char mbuf[2];
-
- mbuf[0] = OpMode;
- mbuf[1] = '\0';
- define(MID_OPMODE, newstr(mbuf), CurEnv);
- }
-
-#if XDEBUG
+#ifdef XDEBUG
checkfd012("before readcf");
#endif
- vendor_pre_defaults(CurEnv);
readcf(getcfname(), safecf, CurEnv);
- vendor_post_defaults(CurEnv);
-
- /* suppress error printing if errors mailed back or whatever */
- if (CurEnv->e_errormode != EM_PRINT)
- HoldErrs = TRUE;
-
- /* set up the $=m class now, after .cf has a chance to redefine $m */
- expand("\201m", jbuf, sizeof jbuf, CurEnv);
- setclass('m', jbuf);
if (tTd(0, 1))
{
- printf("\n============ SYSTEM IDENTITY (after readcf) ============");
- printf("\n (short domain name) $w = ");
+ printf("SYSTEM IDENTITY (after readcf):");
+ printf("\n\t (short domain name) $w = ");
xputs(macvalue('w', CurEnv));
- printf("\n (canonical domain name) $j = ");
+ printf("\n\t(canonical domain name) $j = ");
xputs(macvalue('j', CurEnv));
- printf("\n (subdomain name) $m = ");
+ printf("\n\t (subdomain name) $m = ");
xputs(macvalue('m', CurEnv));
- printf("\n (node name) $k = ");
+ printf("\n\t (node name) $k = ");
xputs(macvalue('k', CurEnv));
- printf("\n========================================================\n\n");
+ printf("\n");
}
/*
@@ -734,48 +662,47 @@ main(argc, argv, envp)
*/
#if NAMED_BIND
- if (UseNameServer && !bitset(RES_INIT, _res.options))
+ if (!bitset(RES_INIT, _res.options))
res_init();
-# ifdef RES_NOALIASES
- _res.options |= RES_NOALIASES;
-# endif
#endif
/*
- ** Do more command line checking -- these are things that
- ** have to modify the results of reading the config file.
+ ** Process authorization warnings from command line.
*/
- /* process authorization warnings from command line */
if (warn_C_flag)
auth_warning(CurEnv, "Processed by %s with -C %s",
RealUserName, ConfFile);
+/*
+ if (warn_f_flag != '\0')
+ auth_warning(CurEnv, "%s set sender to %s using -%c",
+ RealUserName, from, warn_f_flag);
+*/
if (Warn_Q_option)
auth_warning(CurEnv, "Processed from queue %s", QueueDir);
- /* check body type for legality */
- if (CurEnv->e_bodytype == NULL)
- /* nothing */ ;
- else if (strcasecmp(CurEnv->e_bodytype, "7BIT") == 0)
- SevenBitInput = TRUE;
- else if (strcasecmp(CurEnv->e_bodytype, "8BITMIME") == 0)
- SevenBitInput = FALSE;
- else
- {
- usrerr("Illegal body type %s", CurEnv->e_bodytype);
- CurEnv->e_bodytype = NULL;
- }
-
/* Enforce use of local time (null string overrides this) */
if (TimeZoneSpec == NULL)
unsetenv("TZ");
else if (TimeZoneSpec[0] != '\0')
- setuserenv("TZ", TimeZoneSpec);
- else
- setuserenv("TZ", NULL);
- tzset();
+ {
+ char **evp = UserEnviron;
+ char tzbuf[100];
+
+ strcpy(tzbuf, "TZ=");
+ strcpy(&tzbuf[3], TimeZoneSpec);
+
+ while (*evp != NULL && strncmp(*evp, "TZ=", 3) != 0)
+ evp++;
+ if (*evp == NULL)
+ {
+ *evp++ = newstr(tzbuf);
+ *evp = NULL;
+ }
+ else
+ *evp++ = newstr(tzbuf);
+ }
- /* check for sane configuration level */
if (ConfigLevel > MAXCONFIGLEVEL)
{
syserr("Warning: .cf version level (%d) exceeds program functionality (%d)",
@@ -785,24 +712,32 @@ main(argc, argv, envp)
if (MeToo)
BlankEnvelope.e_flags |= EF_METOO;
- switch (OpMode)
+# ifdef QUEUE
+ if (queuemode && RealUid != 0 && bitset(PRIV_RESTRICTQRUN, PrivacyFlags))
{
- case MD_DAEMON:
- /* remove things that don't make sense in daemon mode */
- FullName = NULL;
- GrabTo = FALSE;
+ struct stat stbuf;
- /* arrange to restart on hangup signal */
- setsignal(SIGHUP, sighup);
- break;
+ /* check to see if we own the queue directory */
+ if (stat(QueueDir, &stbuf) < 0)
+ syserr("main: cannot stat %s", QueueDir);
+ if (stbuf.st_uid != RealUid)
+ {
+ /* nope, really a botch */
+ usrerr("You do not have permission to process the queue");
+ exit (EX_NOPERM);
+ }
+ }
+# endif /* QUEUE */
+ switch (OpMode)
+ {
case MD_INITALIAS:
Verbose = TRUE;
- /* fall through... */
+ break;
- default:
- /* arrange to exit cleanly on hangup signal */
- setsignal(SIGHUP, intsig);
+ case MD_DAEMON:
+ /* remove things that don't make sense in daemon mode */
+ FullName = NULL;
break;
}
@@ -825,56 +760,31 @@ main(argc, argv, envp)
UseErrorsTo = TRUE;
}
- /* set options that were previous macros */
- if (SmtpGreeting == NULL)
- {
- if (ConfigLevel < 7 && (p = macvalue('e', CurEnv)) != NULL)
- SmtpGreeting = newstr(p);
- else
- SmtpGreeting = "\201j Sendmail \201v ready at \201b";
- }
- if (UnixFromLine == NULL)
- {
- if (ConfigLevel < 7 && (p = macvalue('l', CurEnv)) != NULL)
- UnixFromLine = newstr(p);
- else
- UnixFromLine = "From \201g \201d";
- }
-
/* our name for SMTP codes */
- expand("\201j", jbuf, sizeof jbuf, CurEnv);
+ expand("\201j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);
MyHostName = jbuf;
- if (strchr(jbuf, '.') == NULL)
- message("WARNING: local host name (%s) is not qualified; fix $j in config file",
- jbuf);
/* make certain that this name is part of the $=w class */
setclass('w', MyHostName);
/* the indices of built-in mailers */
st = stab("local", ST_MAILER, ST_FIND);
- if (st != NULL)
- LocalMailer = st->s_mailer;
- else if (OpMode != MD_TEST || !warn_C_flag)
+ if (st == NULL)
syserr("No local mailer defined");
+ else
+ LocalMailer = st->s_mailer;
st = stab("prog", ST_MAILER, ST_FIND);
if (st == NULL)
syserr("No prog mailer defined");
else
- {
ProgMailer = st->s_mailer;
- clrbitn(M_MUSER, ProgMailer->m_flags);
- }
st = stab("*file*", ST_MAILER, ST_FIND);
if (st == NULL)
syserr("No *file* mailer defined");
else
- {
FileMailer = st->s_mailer;
- clrbitn(M_MUSER, FileMailer->m_flags);
- }
st = stab("*include*", ST_MAILER, ST_FIND);
if (st == NULL)
@@ -882,39 +792,6 @@ main(argc, argv, envp)
else
InclMailer = st->s_mailer;
- if (ConfigLevel < 6)
- {
- /* heuristic tweaking of local mailer for back compat */
- if (LocalMailer != NULL)
- {
- setbitn(M_ALIASABLE, LocalMailer->m_flags);
- setbitn(M_HASPWENT, LocalMailer->m_flags);
- setbitn(M_TRYRULESET5, LocalMailer->m_flags);
- setbitn(M_CHECKINCLUDE, LocalMailer->m_flags);
- setbitn(M_CHECKPROG, LocalMailer->m_flags);
- setbitn(M_CHECKFILE, LocalMailer->m_flags);
- setbitn(M_CHECKUDB, LocalMailer->m_flags);
- }
- if (ProgMailer != NULL)
- setbitn(M_RUNASRCPT, ProgMailer->m_flags);
- if (FileMailer != NULL)
- setbitn(M_RUNASRCPT, FileMailer->m_flags);
-
- /* propogate some envariables into children */
- setuserenv("ISP", NULL);
- setuserenv("SYSTYPE", NULL);
- }
-
- /* MIME Content-Types that cannot be transfer encoded */
- setclass('n', "multipart/signed");
-
- /* MIME message/* subtypes that can be treated as messages */
- setclass('s', "rfc822");
-
- /* MIME Content-Transfer-Encodings that can be encoded */
- setclass('e', "7bit");
- setclass('e', "8bit");
- setclass('e', "binary");
/* operate in queue directory */
if (OpMode != MD_TEST && chdir(QueueDir) < 0)
@@ -923,32 +800,14 @@ main(argc, argv, envp)
ExitStat = EX_SOFTWARE;
}
-# ifdef QUEUE
- if (queuemode && RealUid != 0 && bitset(PRIV_RESTRICTQRUN, PrivacyFlags))
- {
- struct stat stbuf;
-
- /* check to see if we own the queue directory */
- if (stat(".", &stbuf) < 0)
- syserr("main: cannot stat %s", QueueDir);
- if (stbuf.st_uid != RealUid)
- {
- /* nope, really a botch */
- usrerr("You do not have permission to process the queue");
- exit (EX_NOPERM);
- }
- }
-# endif /* QUEUE */
-
/* if we've had errors so far, exit now */
if (ExitStat != EX_OK && OpMode != MD_TEST)
{
- endpwent();
setuid(RealUid);
exit(ExitStat);
}
-#if XDEBUG
+#ifdef XDEBUG
checkfd012("before main() initmaps");
#endif
@@ -963,7 +822,6 @@ main(argc, argv, envp)
#ifdef QUEUE
dropenvelope(CurEnv);
printqueue();
- endpwent();
setuid(RealUid);
exit(EX_OK);
#else /* QUEUE */
@@ -974,12 +832,10 @@ main(argc, argv, envp)
case MD_INITALIAS:
/* initialize alias database */
initmaps(TRUE, CurEnv);
- endpwent();
setuid(RealUid);
exit(EX_OK);
case MD_DAEMON:
- case MD_SMTP:
/* don't open alias database -- done in srvrsmtp */
break;
@@ -992,12 +848,35 @@ main(argc, argv, envp)
if (tTd(0, 15))
{
/* print configuration table (or at least part of it) */
- if (tTd(0, 90))
- printrules();
+ printrules();
for (i = 0; i < MAXMAILERS; i++)
{
- if (Mailer[i] != NULL)
- printmailer(Mailer[i]);
+ register struct mailer *m = Mailer[i];
+ int j;
+
+ if (m == NULL)
+ continue;
+ printf("mailer %d (%s): P=%s S=%d/%d R=%d/%d M=%ld F=", i, m->m_name,
+ m->m_mailer, m->m_se_rwset, m->m_sh_rwset,
+ m->m_re_rwset, m->m_rh_rwset, m->m_maxsize);
+ for (j = '\0'; j <= '\177'; j++)
+ if (bitnset(j, m->m_flags))
+ (void) putchar(j);
+ printf(" E=");
+ xputs(m->m_eol);
+ if (m->m_argv != NULL)
+ {
+ char **a = m->m_argv;
+
+ printf(" A=");
+ while (*a != NULL)
+ {
+ if (a != m->m_argv)
+ printf(" ");
+ xputs(*a++);
+ }
+ }
+ printf("\n");
}
}
@@ -1015,7 +894,6 @@ main(argc, argv, envp)
if (OpMode == MD_TEST)
{
char buf[MAXLINE];
- void intindebug();
if (isatty(fileno(stdin)))
Verbose = TRUE;
@@ -1025,24 +903,69 @@ main(argc, argv, envp)
printf("ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)\n");
printf("Enter <ruleset> <address>\n");
}
- if (setjmp(TopFrame) > 0)
- printf("\n");
- (void) setsignal(SIGINT, intindebug);
for (;;)
{
- extern void testmodeline __P((char *, ENVELOPE *));
+ register char **pvp;
+ char *q;
+ auto char *delimptr;
+ extern bool invalidaddr();
+ extern char *crackaddr();
if (Verbose)
printf("> ");
(void) fflush(stdout);
if (fgets(buf, sizeof buf, stdin) == NULL)
finis();
- p = strchr(buf, '\n');
- if (p != NULL)
- *p = '\0';
if (!Verbose)
- printf("> %s\n", buf);
- testmodeline(buf, CurEnv);
+ printf("> %s", buf);
+ switch (buf[0])
+ {
+ case '#':
+ continue;
+
+#ifdef MAYBENEXTRELEASE
+ case 'C': /* try crackaddr */
+ q = crackaddr(&buf[1]);
+ xputs(q);
+ printf("\n");
+ continue;
+#endif
+ }
+
+ for (p = buf; isascii(*p) && isspace(*p); p++)
+ continue;
+ q = p;
+ while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ p++;
+ if (*p == '\0')
+ {
+ printf("No address!\n");
+ continue;
+ }
+ *p = '\0';
+ if (invalidaddr(p + 1, NULL))
+ continue;
+ do
+ {
+ char pvpbuf[PSBUFSIZE];
+
+ pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf,
+ &delimptr);
+ if (pvp == NULL)
+ continue;
+ p = q;
+ while (*p != '\0')
+ {
+ int stat;
+
+ stat = rewrite(pvp, atoi(p), 0, CurEnv);
+ if (stat != EX_OK)
+ printf("== Ruleset %s status %d\n",
+ p, stat);
+ while (*p != '\0' && *p++ != ',')
+ continue;
+ }
+ } while (*(p = delimptr) != '\0');
}
}
@@ -1053,7 +976,6 @@ main(argc, argv, envp)
if (queuemode && OpMode != MD_DAEMON && QueueIntvl == 0)
{
- (void) unsetenv("HOSTALIASES");
runqueue(FALSE);
finis();
}
@@ -1072,7 +994,7 @@ main(argc, argv, envp)
{
char dtype[200];
- if (!tTd(99, 100))
+ if (!tTd(0, 1))
{
/* put us in background */
i = fork();
@@ -1129,7 +1051,7 @@ main(argc, argv, envp)
#endif /* DAEMON */
}
-
+
# ifdef SMTP
/*
** If running SMTP protocol, start collecting and executing
@@ -1144,12 +1066,11 @@ main(argc, argv, envp)
{
CurEnv->e_sendmode = SM_VERIFY;
CurEnv->e_errormode = EM_QUIET;
- PostMasterCopy = NULL;
}
else
{
/* interactive -- all errors are global */
- CurEnv->e_flags |= EF_GLOBALERRS|EF_LOGSENDER;
+ CurEnv->e_flags |= EF_GLOBALERRS;
}
/*
@@ -1157,9 +1078,6 @@ main(argc, argv, envp)
*/
initsys(CurEnv);
- if (warn_f_flag != '\0' && !wordinclass(RealUserName, 't'))
- auth_warning(CurEnv, "%s set sender to %s using -%c",
- RealUserName, from, warn_f_flag);
setsender(from, CurEnv, NULL, FALSE);
if (macvalue('s', CurEnv) == NULL)
define('s', RealHostName, CurEnv);
@@ -1171,7 +1089,7 @@ main(argc, argv, envp)
/* collect body for UUCP return */
if (OpMode != MD_VERIFY)
- collect(InChannel, FALSE, FALSE, NULL, CurEnv);
+ collect(FALSE, FALSE, CurEnv);
finis();
}
@@ -1193,7 +1111,7 @@ main(argc, argv, envp)
if (OpMode != MD_VERIFY || GrabTo)
{
CurEnv->e_flags |= EF_GLOBALERRS;
- collect(InChannel, FALSE, FALSE, NULL, CurEnv);
+ collect(FALSE, FALSE, CurEnv);
}
errno = 0;
@@ -1221,15 +1139,6 @@ main(argc, argv, envp)
finis();
}
-
-
-void
-intindebug()
-{
- longjmp(TopFrame, 1);
-}
-
-
/*
** FINIS -- Clean up and exit.
**
@@ -1243,18 +1152,12 @@ intindebug()
** exits sendmail
*/
-void
finis()
{
if (tTd(2, 1))
- {
- extern void printenvflags();
-
- printf("\n====finis: stat %d e_id=%s e_flags=",
- ExitStat,
+ printf("\n====finis: stat %d e_flags %o, e_id=%s\n",
+ ExitStat, CurEnv->e_flags,
CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id);
- printenvflags(CurEnv);
- }
if (tTd(2, 9))
printopenfds(FALSE);
@@ -1275,11 +1178,10 @@ finis()
if (LogLevel > 78)
syslog(LOG_DEBUG, "finis, pid=%d", getpid());
# endif /* LOG */
- if (ExitStat == EX_TEMPFAIL || CurEnv->e_errormode == EM_BERKNET)
+ if (ExitStat == EX_TEMPFAIL)
ExitStat = EX_OK;
/* reset uid for process accounting */
- endpwent();
setuid(RealUid);
exit(ExitStat);
@@ -1310,7 +1212,6 @@ intsig()
#endif
/* reset uid for process accounting */
- endpwent();
setuid(RealUid);
exit(EX_OK);
@@ -1354,18 +1255,12 @@ struct metamac MetaMacros[] =
'\0'
};
-#define MACBINDING(name, mid) \
- stab(name, ST_MACRO, ST_ENTER)->s_macro = mid; \
- MacroName[mid] = name;
-
-void
initmacros(e)
register ENVELOPE *e;
{
register struct metamac *m;
- register int c;
char buf[5];
- extern char *MacroName[256];
+ register int c;
for (m = MetaMacros; m->metaname != '\0'; m++)
{
@@ -1382,11 +1277,11 @@ initmacros(e)
}
/* set defaults for some macros sendmail will use later */
+ define('e', "\201j Sendmail \201v ready at \201b", e);
+ define('l', "From \201g \201d", e);
define('n', "MAILER-DAEMON", e);
-
- /* set up external names for some internal macros */
- MACBINDING("opMode", MID_OPMODE);
- /*XXX should probably add equivalents for all short macros here XXX*/
+ define('o', ".:@[]", e);
+ define('q', "<\201g>", e);
}
/*
** DISCONNECT -- remove our connection with any foreground process
@@ -1408,7 +1303,6 @@ initmacros(e)
** the controlling tty.
*/
-void
disconnect(droplev, e)
int droplev;
register ENVELOPE *e;
@@ -1418,13 +1312,14 @@ disconnect(droplev, e)
if (tTd(52, 1))
printf("disconnect: In %d Out %d, e=%x\n",
fileno(InChannel), fileno(OutChannel), e);
- if (tTd(52, 100))
+ if (tTd(52, 5))
{
printf("don't\n");
return;
}
/* be sure we don't get nasty signals */
+ (void) setsignal(SIGHUP, SIG_IGN);
(void) setsignal(SIGINT, SIG_IGN);
(void) setsignal(SIGQUIT, SIG_IGN);
@@ -1468,7 +1363,7 @@ disconnect(droplev, e)
errno = 0;
}
-#if XDEBUG
+#ifdef XDEBUG
checkfd012("disconnect");
#endif
@@ -1496,11 +1391,7 @@ obsolete(argv)
/* skip over options that do have a value */
op = strchr(OPTIONS, ap[1]);
if (op != NULL && *++op == ':' && ap[2] == '\0' &&
- ap[1] != 'd' &&
-#if defined(sony_news)
- ap[1] != 'E' && ap[1] != 'J' &&
-#endif
- argv[1] != NULL && argv[1][0] != '-')
+ ap[1] != 'd' && argv[1] != NULL && argv[1][0] != '-')
{
argv++;
continue;
@@ -1523,16 +1414,6 @@ obsolete(argv)
/* if -d doesn't have an argument, use 0-99.1 */
if (ap[1] == 'd' && ap[2] == '\0')
*argv = "-d0-99.1";
-
-# if defined(sony_news)
- /* if -E doesn't have an argument, use -EC */
- if (ap[1] == 'E' && ap[2] == '\0')
- *argv = "-EC";
-
- /* if -J doesn't have an argument, use -JJ */
- if (ap[1] == 'J' && ap[2] == '\0')
- *argv = "-JJ";
-# endif
}
}
/*
@@ -1564,7 +1445,7 @@ auth_warning(e, msg, va_alist)
{
register char *p;
static char hostbuf[48];
- extern struct hostent *myhostname();
+ extern char **myhostname();
if (hostbuf[0] == '\0')
(void) myhostname(hostbuf, sizeof hostbuf);
@@ -1572,69 +1453,12 @@ auth_warning(e, msg, va_alist)
(void) sprintf(buf, "%s: ", hostbuf);
p = &buf[strlen(buf)];
VA_START(msg);
- vsnprintf(p, sizeof buf - (p - buf), msg, ap);
+ vsprintf(p, msg, ap);
VA_END;
- addheader("X-Authentication-Warning", buf, &e->e_header);
-#ifdef LOG
- if (LogLevel > 3)
- syslog(LOG_INFO, "%s: Authentication-Warning: %.400s",
- e->e_id == NULL ? "[NOQUEUE]" : e->e_id, buf);
-#endif
+ addheader("X-Authentication-Warning", buf, e);
}
}
/*
-** SETUSERENV -- set an environment in the propogated environment
-**
-** Parameters:
-** envar -- the name of the environment variable.
-** value -- the value to which it should be set. If
-** null, this is extracted from the incoming
-** environment. If that is not set, the call
-** to setuserenv is ignored.
-**
-** Returns:
-** none.
-*/
-
-void
-setuserenv(envar, value)
- const char *envar;
- const char *value;
-{
- int i;
- char **evp = UserEnviron;
- char *p;
-
- if (value == NULL)
- {
- value = getenv(envar);
- if (value == NULL)
- return;
- }
-
- i = strlen(envar);
- p = (char *) xalloc(strlen(value) + i + 2);
- strcpy(p, envar);
- p[i++] = '=';
- strcpy(&p[i], value);
-
- while (*evp != NULL && strncmp(*evp, p, i) != 0)
- evp++;
- if (*evp != NULL)
- {
- *evp++ = p;
- }
- else if (evp < &UserEnviron[MAXUSERENVIRON])
- {
- *evp++ = p;
- *evp = NULL;
- }
-
- /* make sure it is in our environment as well */
- if (putenv(p) < 0)
- syserr("setuserenv: putenv(%s) failed", p);
-}
- /*
** DUMPSTATE -- dump state
**
** For debugging.
@@ -1646,16 +1470,17 @@ dumpstate(when)
{
#ifdef LOG
register char *j = macvalue('j', CurEnv);
+ register STAB *s;
syslog(LOG_DEBUG, "--- dumping state on %s: $j = %s ---",
when,
j == NULL ? "<NULL>" : j);
if (j != NULL)
{
- if (!wordinclass(j, 'w'))
+ s = stab(j, ST_CLASS, ST_FIND);
+ if (s == NULL || !bitnset('w', s->s_class))
syslog(LOG_DEBUG, "*** $j not in $=w ***");
}
- syslog(LOG_DEBUG, "CurChildren = %d", CurChildren);
syslog(LOG_DEBUG, "--- open file descriptors: ---");
printopenfds(TRUE);
syslog(LOG_DEBUG, "--- connection cache: ---");
@@ -1683,431 +1508,3 @@ sigusr1()
{
dumpstate("user signal");
}
-
-
-void
-sighup()
-{
-#ifdef LOG
- if (LogLevel > 3)
- syslog(LOG_INFO, "restarting %s on signal", SaveArgv[0]);
-#endif
- releasesignal(SIGHUP);
- execv(SaveArgv[0], (ARGV_T) SaveArgv);
-#ifdef LOG
- if (LogLevel > 0)
- syslog(LOG_ALERT, "could not exec %s: %m", SaveArgv[0]);
-#endif
- exit(EX_OSFILE);
-}
- /*
-** TESTMODELINE -- process a test mode input line
-**
-** Parameters:
-** line -- the input line.
-** e -- the current environment.
-** Syntax:
-** # a comment
-** .X process X as a configuration line
-** =X dump a configuration item (such as mailers)
-** $X dump a macro or class
-** /X try an activity
-** X normal process through rule set X
-*/
-
-void
-testmodeline(line, e)
- char *line;
- ENVELOPE *e;
-{
- register char *p;
- char *q;
- auto char *delimptr;
- int mid;
- int i, rs;
- STAB *map;
- char **s;
- struct rewrite *rw;
- ADDRESS a;
- static int tryflags = RF_COPYNONE;
- char exbuf[MAXLINE];
- extern bool invalidaddr __P((char *, char *));
- extern char *crackaddr __P((char *));
- extern void dump_class __P((STAB *, int));
- extern void translate_dollars __P((char *));
-
- switch (line[0])
- {
- case '#':
- case 0:
- return;
-
- case '?':
- help("-bt");
- return;
-
- case '.': /* config-style settings */
- switch (line[1])
- {
- case 'D':
- mid = macid(&line[2], &delimptr);
- if (mid == '\0')
- return;
- translate_dollars(delimptr);
- define(mid, newstr(delimptr), e);
- break;
-
- case 'C':
- if (line[2] == '\0') /* not to call syserr() */
- return;
-
- mid = macid(&line[2], &delimptr);
- if (mid == '\0')
- return;
- translate_dollars(delimptr);
- expand(delimptr, exbuf, sizeof exbuf, e);
- p = exbuf;
- while (*p != '\0')
- {
- register char *wd;
- char delim;
-
- while (*p != '\0' && isascii(*p) && isspace(*p))
- p++;
- wd = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
- p++;
- delim = *p;
- *p = '\0';
- if (wd[0] != '\0')
- setclass(mid, wd);
- *p = delim;
- }
- break;
-
- case '\0':
- printf("Usage: .[DC]macro value(s)\n");
- break;
-
- default:
- printf("Unknown \".\" command %s\n", line);
- break;
- }
- return;
-
- case '=': /* config-style settings */
- switch (line[1])
- {
- case 'S': /* dump rule set */
- rs = strtorwset(&line[2], NULL, ST_FIND);
- if (rs < 0)
- return;
- rw = RewriteRules[rs];
- if (rw == NULL)
- return;
- do
- {
- putchar('R');
- s = rw->r_lhs;
- while (*s != NULL)
- {
- xputs(*s++);
- putchar(' ');
- }
- putchar('\t');
- putchar('\t');
- s = rw->r_rhs;
- while (*s != NULL)
- {
- xputs(*s++);
- putchar(' ');
- }
- putchar('\n');
- } while (rw = rw->r_next);
- break;
-
- case 'M':
- for (i = 0; i < MAXMAILERS; i++)
- {
- if (Mailer[i] != NULL)
- printmailer(Mailer[i]);
- }
- break;
-
- case '\0':
- printf("Usage: =Sruleset or =M\n");
- break;
-
- default:
- printf("Unknown \"=\" command %s\n", line);
- break;
- }
- return;
-
- case '-': /* set command-line-like opts */
- switch (line[1])
- {
- case 'd':
- tTflag(&line[2]);
- break;
-
- case '\0':
- printf("Usage: -d{debug arguments}\n");
- break;
-
- default:
- printf("Unknown \"-\" command %s\n", line);
- break;
- }
- return;
-
- case '$':
- if (line[1] == '=')
- {
- mid = macid(&line[2], NULL);
- if (mid != '\0')
- stabapply(dump_class, mid);
- return;
- }
- mid = macid(&line[1], NULL);
- if (mid == '\0')
- return;
- p = macvalue(mid, e);
- if (p == NULL)
- printf("Undefined\n");
- else
- {
- xputs(p);
- printf("\n");
- }
- return;
-
- case '/': /* miscellaneous commands */
- p = &line[strlen(line)];
- while (--p >= line && isascii(*p) && isspace(*p))
- *p = '\0';
- p = strpbrk(line, " \t");
- if (p != NULL)
- {
- while (isascii(*p) && isspace(*p))
- *p++ = '\0';
- }
- else
- p = "";
- if (line[1] == '\0')
- {
- printf("Usage: /[canon|map|mx|parse|try|tryflags]\n");
- return;
- }
- if (strcasecmp(&line[1], "mx") == 0)
- {
-#if NAMED_BIND
- /* look up MX records */
- int nmx;
- auto int rcode;
- char *mxhosts[MAXMXHOSTS + 1];
-
- if (*p == '\0')
- {
- printf("Usage: /mx address\n");
- return;
- }
- nmx = getmxrr(p, mxhosts, FALSE, &rcode);
- printf("getmxrr(%s) returns %d value(s):\n", p, nmx);
- for (i = 0; i < nmx; i++)
- printf("\t%s\n", mxhosts[i]);
-#else
- printf("No MX code compiled in\n");
-#endif
- }
- else if (strcasecmp(&line[1], "canon") == 0)
- {
- auto int rcode = EX_OK;
- char host[MAXHOSTNAMELEN];
-
- if (*p == '\0')
- {
- printf("Usage: /canon address\n");
- return;
- }
- strcpy(host, p);
- getcanonname(host, sizeof(host), HasWildcardMX, &rcode);
- printf("getcanonname(%s) returns %s (%d)\n",
- p, host, rcode);
- }
- else if (strcasecmp(&line[1], "map") == 0)
- {
- auto int rcode = EX_OK;
-
- if (*p == '\0')
- {
- printf("Usage: /map mapname key\n");
- return;
- }
- for (q = p; *q != '\0' && !isspace(*q); q++)
- continue;
- if (*q == '\0')
- {
- printf("No key specified\n");
- return;
- }
- *q++ = '\0';
- map = stab(p, ST_MAP, ST_FIND);
- if (map == NULL)
- {
- printf("Map named \"%s\" not found\n", p);
- return;
- }
- printf("map_lookup: %s (%s) ", p, q);
- p = (*map->s_map.map_class->map_lookup)
- (&map->s_map, q, NULL, &rcode);
- if (p == NULL)
- printf("no match (%d)\n", rcode);
- else
- printf("returns %s (%d)\n", p, rcode);
- }
- else if (strcasecmp(&line[1], "try") == 0)
- {
- MAILER *m;
- STAB *s;
- auto int rcode = EX_OK;
-
- q = strpbrk(p, " \t");
- if (q != NULL)
- {
- while (isascii(*q) && isspace(*q))
- *q++ = '\0';
- }
- if (q == NULL || *q == '\0')
- {
- printf("Usage: /try mailer address\n");
- return;
- }
- s = stab(p, ST_MAILER, ST_FIND);
- if (s == NULL)
- {
- printf("Unknown mailer %s\n", p);
- return;
- }
- m = s->s_mailer;
- printf("Trying %s %s address %s for mailer %s\n",
- bitset(RF_HEADERADDR, tryflags) ? "header" : "envelope",
- bitset(RF_SENDERADDR, tryflags) ? "sender" : "recipient",
- q, p);
- p = remotename(q, m, tryflags, &rcode, CurEnv);
- printf("Rcode = %d, addr = %s\n",
- rcode, p == NULL ? "<NULL>" : p);
- }
- else if (strcasecmp(&line[1], "tryflags") == 0)
- {
- if (*p == '\0')
- {
- printf("Usage: /tryflags [Hh|Ee][Ss|Rr]\n");
- return;
- }
- for (; *p != '\0'; p++)
- {
- switch (*p)
- {
- case 'H':
- case 'h':
- tryflags |= RF_HEADERADDR;
- break;
-
- case 'E':
- case 'e':
- tryflags &= ~RF_HEADERADDR;
- break;
-
- case 'S':
- case 's':
- tryflags |= RF_SENDERADDR;
- break;
-
- case 'R':
- case 'r':
- tryflags &= ~RF_SENDERADDR;
- break;
- }
- }
- }
- else if (strcasecmp(&line[1], "parse") == 0)
- {
- if (*p == '\0')
- {
- printf("Usage: /parse address\n");
- return;
- }
- q = crackaddr(p);
- printf("Cracked address = ");
- xputs(q);
- printf("\nParsing %s %s address\n",
- bitset(RF_HEADERADDR, tryflags) ? "header" : "envelope",
- bitset(RF_SENDERADDR, tryflags) ? "sender" : "recipient");
- if (parseaddr(p, &a, tryflags, '\0', NULL, e) == NULL)
- printf("Cannot parse\n");
- else if (a.q_host != NULL && a.q_host[0] != '\0')
- printf("mailer %s, host %s, user %s\n",
- a.q_mailer->m_name, a.q_host, a.q_user);
- else
- printf("mailer %s, user %s\n",
- a.q_mailer->m_name, a.q_user);
- }
- else
- {
- printf("Unknown \"/\" command %s\n", line);
- }
- return;
- }
-
- for (p = line; isascii(*p) && isspace(*p); p++)
- continue;
- q = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
- p++;
- if (*p == '\0')
- {
- printf("No address!\n");
- return;
- }
- *p = '\0';
- if (invalidaddr(p + 1, NULL))
- return;
- do
- {
- register char **pvp;
- char pvpbuf[PSBUFSIZE];
-
- pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf,
- &delimptr, NULL);
- if (pvp == NULL)
- continue;
- p = q;
- while (*p != '\0')
- {
- int stat;
- int rs = strtorwset(p, NULL, ST_FIND);
-
- if (rs < 0)
- break;
- stat = rewrite(pvp, rs, 0, e);
- if (stat != EX_OK)
- printf("== Ruleset %s (%d) status %d\n",
- p, rs, stat);
- while (*p != '\0' && *p++ != ',')
- continue;
- }
- } while (*(p = delimptr) != '\0');
-}
-
-
-void
-dump_class(s, id)
- register STAB *s;
- int id;
-{
- if (s->s_type != ST_CLASS)
- return;
- if (bitnset(id & 0xff, s->s_class))
- printf("%s\n", s->s_name);
-}
OpenPOWER on IntegriCloud