main.c
上传用户:xu_441
上传日期:2007-01-04
资源大小:1640k
文件大小:67k
- /*
- * Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
- * All rights reserved.
- * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
- * Copyright (c) 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * By using this file, you agree to the terms and conditions set
- * forth in the LICENSE file which can be found at the top level of
- * the sendmail distribution.
- *
- */
- #ifndef lint
- static char copyright[] =
- "@(#) Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.n
- All rights reserved.n
- Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.n
- Copyright (c) 1988, 1993n
- The Regents of the University of California. All rights reserved.n";
- #endif /* ! lint */
- #ifndef lint
- static char id[] = "@(#)$Id: main.c,v 8.469 1999/11/24 08:44:36 gshapiro Exp $";
- #endif /* ! lint */
- #define _DEFINE
- #include <sendmail.h>
- #if NETINET || NETINET6
- # include <arpa/inet.h>
- #endif /* NETINET || NETINET6 */
- static void dump_class __P((STAB *, int));
- static void obsolete __P((char **));
- static void testmodeline __P((char *, ENVELOPE *));
- /*
- ** SENDMAIL -- Post mail to a set of destinations.
- **
- ** This is the basic mail router. All user mail programs should
- ** call this routine to actually deliver mail. Sendmail in
- ** turn calls a bunch of mail servers that do the real work of
- ** delivering the mail.
- **
- ** Sendmail is driven by settings read in from /etc/mail/sendmail.cf
- ** (read by readcf.c).
- **
- ** Usage:
- ** /usr/lib/sendmail [flags] addr ...
- **
- ** See the associated documentation for details.
- **
- ** Author:
- ** Eric Allman, UCB/INGRES (until 10/81).
- ** Britton-Lee, Inc., purveyors of fine
- ** database computers (11/81 - 10/88).
- ** International Computer Science Institute
- ** (11/88 - 9/89).
- ** UCB/Mammoth Project (10/89 - 7/95).
- ** InReference, Inc. (8/95 - 1/97).
- ** Sendmail, Inc. (1/98 - present).
- ** The support of the my employers is gratefully acknowledged.
- ** Few of them (Britton-Lee in particular) have had
- ** anything to gain from my involvement in this project.
- */
- int NextMailer; /* "free" index into Mailer struct */
- char *FullName; /* sender's full name */
- ENVELOPE BlankEnvelope; /* a "blank" envelope */
- static ENVELOPE MainEnvelope; /* the envelope around the basic letter */
- ADDRESS NullAddress = /* a null address */
- { "", "", NULL, "" };
- 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 */
- static int MissingFds = 0; /* bit map of fds missing on startup */
- #ifdef NGROUPS_MAX
- GIDSET_T InitialGidSet[NGROUPS_MAX];
- #endif /* NGROUPS_MAX */
- #if DAEMON && !SMTP
- ERROR %%%% Cannot have DAEMON mode without SMTP %%%% ERROR
- #endif /* DAEMON && !SMTP */
- #if SMTP && !QUEUE
- ERROR %%%% Cannot have SMTP mode without QUEUE %%%% ERROR
- #endif /* SMTP && !QUEUE */
- #define MAXCONFIGLEVEL 9 /* highest config version level known */
- /* Flags for submitmode */
- #define SUBMIT_UNKNOWN 0x0000 /* unknown agent type */
- #define SUBMIT_MTA 0x0001 /* act like a message transfer agent */
- #define SUBMIT_MSA 0x0002 /* act like a message submission agent */
- #if SASL
- static sasl_callback_t srvcallbacks[] = {
- { SASL_CB_VERIFYFILE, &safesaslfile, NULL },
- { SASL_CB_PROXY_POLICY, &proxy_policy, NULL },
- { SASL_CB_LIST_END, NULL, NULL }
- };
- #endif /* SASL */
- int
- main(argc, argv, envp)
- int argc;
- char **argv;
- char **envp;
- {
- register char *p;
- char **av;
- extern char Version[];
- char *ep, *from;
- STAB *st;
- register int i;
- int j;
- int submitmode = SUBMIT_UNKNOWN;
- bool safecf = TRUE;
- BITMAP256 *p_flags = NULL; /* daemon flags */
- bool warn_C_flag = FALSE;
- bool auth = TRUE; /* whether to set e_auth_param */
- char warn_f_flag = ' ';
- bool run_in_foreground = FALSE; /* -bD mode */
- static bool reenter = FALSE;
- struct passwd *pw;
- struct hostent *hp;
- char *nullserver = NULL;
- char *authinfo = NULL;
- char *sysloglabel = NULL; /* label for syslog */
- bool forged;
- struct stat traf_st; /* for TrafficLog FIFO check */
- char jbuf[MAXHOSTNAMELEN]; /* holds MyHostName */
- static char rnamebuf[MAXNAME]; /* holds RealUserName */
- char *emptyenviron[1];
- QUEUE_CHAR *new;
- extern int DtableSize;
- extern int optind;
- extern int opterr;
- extern char *optarg;
- extern char **environ;
- /*
- ** Check to see if we reentered.
- ** This would normally happen if e_putheader or e_putbody
- ** were NULL when invoked.
- */
- if (reenter)
- {
- syserr("main: reentered!");
- abort();
- }
- reenter = TRUE;
- /* avoid null pointer dereferences */
- TermEscape.te_rv_on = TermEscape.te_rv_off = "";
- /* do machine-dependent initializations */
- init_md(argc, argv);
- /* in 4.4BSD, the table can be huge; impose a reasonable limit */
- DtableSize = getdtsize();
- if (DtableSize > 256)
- DtableSize = 256;
- /*
- ** Be sure we have enough file descriptors.
- ** But also be sure that 0, 1, & 2 are open.
- */
- fill_fd(STDIN_FILENO, NULL);
- fill_fd(STDOUT_FILENO, NULL);
- fill_fd(STDERR_FILENO, NULL);
- i = DtableSize;
- while (--i > 0)
- {
- if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO)
- (void) close(i);
- }
- errno = 0;
- #if LOG
- # ifdef LOG_MAIL
- openlog("sendmail", LOG_PID, LOG_MAIL);
- # else /* LOG_MAIL */
- openlog("sendmail", LOG_PID);
- # endif /* LOG_MAIL */
- #endif /* LOG */
- if (MissingFds != 0)
- {
- char mbuf[MAXLINE];
- mbuf[0] = ' ';
- if (bitset(1 << STDIN_FILENO, MissingFds))
- (void) strlcat(mbuf, ", stdin", sizeof mbuf);
- if (bitset(1 << STDOUT_FILENO, MissingFds))
- (void) strlcat(mbuf, ", stdout", sizeof mbuf);
- if (bitset(1 << STDERR_FILENO, MissingFds))
- (void) strlcat(mbuf, ", stderr", sizeof mbuf);
- syserr("File descriptors missing on startup: %s", &mbuf[2]);
- }
- /* reset status from syserr() calls for missing file descriptors */
- Errors = 0;
- ExitStat = EX_OK;
- #if XDEBUG
- checkfd012("after openlog");
- #endif /* XDEBUG */
- /*
- ** Seed the random number generator.
- ** Used for queue file names, picking a queue directory, and
- ** MX randomization.
- */
- seed_random();
- tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
- #ifdef NGROUPS_MAX
- /* save initial group set for future checks */
- i = getgroups(NGROUPS_MAX, InitialGidSet);
- if (i == 0)
- InitialGidSet[0] = (GID_T) -1;
- while (i < NGROUPS_MAX)
- InitialGidSet[i++] = InitialGidSet[0];
- #endif /* NGROUPS_MAX */
- /* drop group id privileges (RunAsUser not yet set) */
- (void) drop_privileges(FALSE);
- #ifdef SIGUSR1
- /* arrange to dump state on user-1 signal */
- (void) setsignal(SIGUSR1, sigusr1);
- #endif /* SIGUSR1 */
- /* initialize for setproctitle */
- initsetproctitle(argc, argv, envp);
- /* Handle any non-getoptable constructions. */
- obsolete(argv);
- /*
- ** Do a quick prescan of the argument list.
- */
- #if defined(__osf__) || defined(_AIX3)
- # define OPTIONS "B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtUV:vX:x"
- #endif /* defined(__osf__) || defined(_AIX3) */
- #if defined(sony_news)
- # define OPTIONS "B:b:C:cd:E:e:F:f:Gh:IiJ:L:M:mN:nO:o:p:q:R:r:sTtUV:vX:"
- #endif /* defined(sony_news) */
- #ifndef OPTIONS
- # define OPTIONS "B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtUV:vX:"
- #endif /* ! OPTIONS */
- opterr = 0;
- while ((j = getopt(argc, argv, OPTIONS)) != -1)
- {
- switch (j)
- {
- case 'd':
- /* hack attack -- see if should use ANSI mode */
- if (strcmp(optarg, "ANSI") == 0)
- {
- TermEscape.te_rv_on = "