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

📄 main.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that this notice is preserved and that due credit is given * to the University of California at Berkeley. The name of the University * may not be used to endorse or promote products derived from this * software without specific prior written permission. This software * is provided ``as is'' without express or implied warranty. * *  Sendmail *  Copyright (c) 1983  Eric P. Allman *  Berkeley, California */# define  _DEFINE# include <signal.h># include <sys/ioctl.h># include "sendmail.h"SCCSID(@(#)main.c 1.1 92/07/30 SMI); /* from UCB 5.17 4/19/88 */# ifdef lintchar	edata, end;# endif lint/***  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 tables read in from /etc/sendmail.cf**	(read by readcf.c).  Some more static configuration info,**	including some code that you may want to tailor for your**	installation, is in conf.c.  You may also want to touch**	daemon.c (if you have some other IPC mechanism), acct.c**	(to change your accounting), names.c (to adjust the name**	server mechanism).****	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 (from 11/81)**		The support of the INGRES Project and Britton-Lee is**			gratefully acknowledged.  Britton-Lee in**			particular had absolutely nothing 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 */ENVELOPE	MainEnvelope;	/* the envelope around the basic letter */ADDRESS		NullAddress =	/* a null address */		{ "", "", NULL, "" };/***  Pointers for setproctitle.**	This allows "ps" listings to give more useful information.**	These must be kept out of BSS for frozen configuration files**		to work.*/# ifdef SETPROCTITLEchar		**Argv = NULL;		/* pointer to argument vector */char		*LastArgv = NULL;	/* end of argv */# endif SETPROCTITLE# ifdef QUEUEint		OnlyRunId;	/* Queue ID from -M to run, or zero */char 		*OnlyRunRecip;	/* Recipient name from -R to run, or zero */# endif QUEUE#ifdef DAEMON#ifndef SMTPERROR %%%%   Cannot have daemon mode without SMTP   %%%% ERROR#endif SMTP#endif DAEMONmain(argc, argv, envp)	int argc;	char **argv;	char **envp;{	register char *p;	char **av;	extern int finis();	extern char Version[];	char *from;	typedef int (*fnptr)();	STAB *st;	register int i;	bool readconfig = TRUE;	bool queuemode = FALSE;		/* process queue requests */	bool nothaw;#ifdef vax	static bool reenter = FALSE;#endif vax	char jbuf[65];			/* holds MyHostName */	extern bool safefile();	extern time_t convtime();	extern putheader(), putbody();	extern ENVELOPE *newenvelope();	extern intsig();	extern char **myhostname();	extern char *arpadate();	extern char *macvalue();	extern char **environ;	extern int DtableSize;#ifdef INTER	setlocale(LC_ALL, "");#endif#ifdef vax	/*	**  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;#endif vax	/*	**  Be sure we have enough file descriptors.	*/	DtableSize = getdtablesize();	for (i = 3; i < DtableSize; i++)		(void) close(i);	errno = 0;	/*	**  Set default values for variables.	**	These cannot be in initialized data space.	*/	setdefaults();	/* set up the blank envelope */	BlankEnvelope.e_puthdr = putheader;	BlankEnvelope.e_putbody = putbody;	BlankEnvelope.e_xfp = NULL;	STRUCTCOPY(NullAddress, BlankEnvelope.e_from);	CurEnv = &BlankEnvelope;	STRUCTCOPY(NullAddress, MainEnvelope.e_from);	/*	**  Do a quick prescan of the argument list.	**	We do this to find out if we can potentially thaw the	**	configuration file.  If not, we do the thaw now so that	**	the argument processing applies to this run rather than	**	to the run that froze the configuration.	*/	argv[argc] = NULL;	av = argv;	nothaw = FALSE;	while ((p = *++av) != NULL)	{		if (strncmp(p, "-C", 2) == 0)		{			ConfFile = &p[2];			if (ConfFile[0] == '\0')				ConfFile = "sendmail.cf";			(void) setgid(getrgid());			(void) setuid(getruid());			nothaw = TRUE;		}		else if (strncmp(p, "-bz", 3) == 0)			nothaw = TRUE;# ifdef DEBUG		else if (strncmp(p, "-d", 2) == 0)		{			tTsetup(tTdvect, sizeof tTdvect, "0-99.1");			tTflag(&p[2]);			setbuf(stdout, (char *) NULL);			printf("Version %s\n", Version);		}# endif DEBUG	}	if (!nothaw)		readconfig = !thaw(FreezeFile);	/* reset the environment after the thaw */	for (i = 0; i < MAXUSERENVIRON && envp[i] != NULL; i++)		UserEnviron[i] = newstr(envp[i]);	UserEnviron[i] = NULL;	environ = UserEnviron;# ifdef SETPROCTITLE	/*	**  Save start and extent of argv for setproctitle.	*/	Argv = argv;	if (i > 0)		LastArgv = envp[i - 1] + strlen(envp[i - 1]);	else		LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);# endif SETPROCTITLE	/*	**  Now do basic initialization	*/	InChannel = stdin;	OutChannel = stdout;	if (signal(SIGINT, SIG_IGN) != SIG_IGN)		(void) signal(SIGINT, intsig);	if (signal(SIGHUP, SIG_IGN) != SIG_IGN)		(void) signal(SIGHUP, intsig);	(void) signal(SIGTERM, intsig);	(void) signal(SIGPIPE, SIG_IGN);	OldUmask = umask(0);	OpMode = MD_DELIVER;	MotherPid = getpid();	FullName = getenv("NAME");# ifdef LOG	openlog("sendmail", LOG_PID, LOG_MAIL);# endif LOG	errno = 0;	from = NULL;	if (readconfig)	{		/* initialize some macros, etc. */		initmacros();		initdomain();		/* hostname */		av = myhostname(jbuf, sizeof jbuf);		if (jbuf[0] != '\0')		{#ifdef DEBUG			if (tTd(0, 4))				printf("canonical name: %s\n", jbuf);#endif DEBUG			p = newstr(jbuf);			define('w', p, CurEnv);			setclass('w', p);		}		while (av != NULL && *av != NULL)		{#ifdef DEBUG			if (tTd(0, 4))				printf("\ta.k.a.: %s\n", *av);#endif DEBUG			setclass('w', *av++);		}		if ((p = index(jbuf, '.')) != NULL)		{		  /*		   * If the full domain name is used, then make sure that		   * the unqualified name is also recognized.		   */			*p = '\0';			st = stab(jbuf, ST_CLASS, ST_FIND);			if (st == NULL || !bitnset('w', st->s_class))			    setclass('w', jbuf);		}		/* version */		define('v', Version, CurEnv);	}	/* current time */	define('b', arpadate((char *) NULL), CurEnv);	/*	** Crack argv.	*/	av = argv;	p = rindex(*av, '/');	if (p++ == NULL)		p = *av;	if (strcmp(p, "newaliases") == 0)		OpMode = MD_INITALIAS;	else if (strcmp(p, "mailq") == 0)		OpMode = MD_PRINT;	else if (strcmp(p, "smtpd") == 0)		OpMode = MD_DAEMON;	while ((p = *++av) != NULL && p[0] == '-')	{		switch (p[1])		{		  case 'b':	/* operations mode */			switch (p[2])			{			  case MD_DAEMON:# ifndef DAEMON				syserr("Daemon mode not implemented");				break;# endif DAEMON			  case MD_SMTP:# ifndef SMTP				syserr("I don't speak SMTP");				break;# endif SMTP			  case MD_ARPAFTP:			  case MD_DELIVER:			  case MD_VERIFY:			  case MD_TEST:			  case MD_INITALIAS:			  case MD_PRINT:			  case MD_FREEZE:				OpMode = p[2];				break;			  default:				syserr("Invalid operation mode %c", p[2]);				break;			}			break;		  case 'C':	/* select configuration file (already done) */			break;#ifdef DEBUG		  case 'd':	/* debugging -- redo in case frozen */			tTsetup(tTdvect, sizeof tTdvect, "0-99.1");			tTflag(&p[2]);			setbuf(stdout, (char *) NULL);			break;#endif		  case 'f':	/* from address */		  case 'r':	/* obsolete -f flag */			p += 2;			if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))			{				errno = 0;				syserr("No \"from\" person");				av--;				break;			}			if (from != NULL)			{				errno = 0;				syserr("More than one \"from\" person");				break;			}			from = newstr(p);			break;		  case 'F':	/* set full name */			p += 2;			if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))			{				syserr("Bad -F flag");				av--;				break;			}			FullName = newstr(p);			break;		  case 'h':	/* hop count */			p += 2;			if (*p == '\0' && ((p = *++av) == NULL || !isdigit(*p)))			{				syserr("Bad hop count (%s)", p);				av--;				break;			}			CurEnv->e_hopcount = atoi(p);			break;				  case 'n':	/* don't alias */			NoAlias = TRUE;			break;		  case 'o':	/* set option */			setoption(p[2], &p[3], FALSE, TRUE);			break;		  case 'q':	/* run queue files at intervals */# ifdef QUEUE			queuemode = TRUE;			QueueIntvl = convtime(&p[2]);# else QUEUE			syserr("I don't know about queues");# endif QUEUE			break;		  case 't':	/* read recipients from message */			GrabTo = TRUE;			break;			/* compatibility flags */		  case 'c':	/* connect to non-local mailers */		  case 'e':	/* error message disposition */		  case 'i':	/* don't let dot stop me */		  case 'm':	/* send to me too */		  case 'T':	/* set timeout interval */		  case 'v':	/* give blow-by-blow description */			setoption(p[1], &p[2], FALSE, TRUE);			break;		  case 's':	/* save From lines in headers */			setoption('f', &p[2], FALSE, TRUE);			break;# ifdef DBM		  case 'I':	/* initialize alias DBM file */			OpMode = MD_INITALIAS;			break;# endif DBM# ifdef QUEUE		  case 'M':	/* Queue run takes Mail queue Id only */			p += 2;			if ((*p == '\0' && (p = *++av) == NULL)				 || !isdigit(*p))			{				errno = 0;				syserr("Mail-queue Id (%s) must be numeric", p);				if (p == NULL) av--;				break;			}			OnlyRunId = atoi(p);			queuemode = TRUE;			break;		  case 'R':	/* Queue run takes certain Recipients only */			OnlyRunRecip = newstr(p+2);			queuemode = TRUE;			break;# endif QUEUE		}	}	/*	**  Do basic initialization.	**	Read system control file.	**	Extract special fields for local use.	*/	if (OpMode == MD_FREEZE || readconfig)		readcf(ConfFile);		/*	 * Set the domain class here, in case it was re-defined in the cf 	 */	p = macvalue('m', CurEnv);	if (p)		setclass('m', p);	switch (OpMode)	{	  case MD_FREEZE:		/* this is critical to avoid forgeries of the frozen config */		(void) setgid(getgid());		(void) setuid(getuid());		/* freeze the configuration */		freeze(FreezeFile);		exit(EX_OK);	  case MD_INITALIAS:		Verbose = TRUE;		break;	}	/* do heuristic mode adjustment */	if (Verbose)	{		/* turn off noconnect option */		setoption('c', "F", TRUE, FALSE);		/* turn on interactive delivery */		setoption('d', "", TRUE, FALSE);	}	/* our name for SMTP codes */	expand("\001j", jbuf, &jbuf[sizeof jbuf - 1], CurEnv);	MyHostName = jbuf;	/* the indices of local and program mailers */	st = stab("local", ST_MAILER, ST_FIND);	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;	/* enable remote delivery mode if requested */	if (RemoteServer && RemoteServer[0]=='\0')	{		RemoteDefault();		} 	if (RemoteServer && OpMode == MD_DELIVER && !queuemode && !GrabTo	    && av[0] != NULL)	{		int r;		r = RemoteMode(from, av, NULL);		exit(r);	}	/* operate in queue directory */	if (chdir(QueueDir) < 0)	{		syserr("cannot chdir(%s)", QueueDir);		exit(EX_SOFTWARE);	}	/*	**  Do operation-mode-dependent initialization.	*/	switch (OpMode)	{	  case MD_PRINT:		/* print the queue */#ifdef QUEUE		dropenvelope(CurEnv);		printqueue();		exit(EX_OK);#else QUEUE		usrerr("No queue to print");		finis();#endif QUEUE	  case MD_INITALIAS:		/* initialize alias database */		initaliases(AliasFile, TRUE);		exit(EX_OK);	  case MD_DAEMON:		/* don't open alias database -- done in srvrsmtp */		break;	  default:		/* open the alias database */		initaliases(AliasFile, FALSE);		break;	}# ifdef DEBUG	if (tTd(0, 15))	{

⌨️ 快捷键说明

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