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

📄 main.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1983 Eric P. Allman * Copyright (c) 1988, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1988, 1993\n\	The Regents of the University of California.  All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)main.c	8.55 (Berkeley) 4/15/94";#endif /* not lint */#define	_DEFINE#include "sendmail.h"#if NAMED_BIND#include <arpa/nameser.h>#include <resolv.h>#endif#include <pwd.h># 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 /usr/lib/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)**			     Now back at UCB at the Mammoth project.**		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, "" };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 *//***  Pointers for setproctitle.**	This allows "ps" listings to give more useful information.*/# ifdef SETPROCTITLEchar		**Argv = NULL;		/* pointer to argument vector */char		*LastArgv = NULL;	/* end of argv */# endif /* SETPROCTITLE */static void	obsolete();#ifdef DAEMON#ifndef SMTPERROR %%%%   Cannot have daemon mode without SMTP   %%%% ERROR#endif /* SMTP */#endif /* DAEMON */#define MAXCONFIGLEVEL	5	/* highest config version level known */main(argc, argv, envp)	int argc;	char **argv;	char **envp;{	register char *p;	char **av;	extern int finis();	extern char Version[];	char *ep, *from;	typedef int (*fnptr)();	STAB *st;	register int i;	int j;	bool queuemode = FALSE;		/* process queue requests */	bool safecf = TRUE;	bool warn_C_flag = FALSE;	char warn_f_flag = '\0';	static bool reenter = FALSE;	char *argv0 = argv[0];	struct passwd *pw;	struct stat stb;	char jbuf[MAXHOSTNAMELEN];	/* holds MyHostName */	extern int DtableSize;	extern int optind;	extern time_t convtime();	extern putheader(), putbody();	extern void intsig();	extern char **myhostname();	extern char *arpadate();	extern char *getauthinfo();	extern char *getcfname();	extern char *optarg;	extern char **environ;	extern void sigusr1();	/*	**  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;	/* do machine-dependent initializations */	init_md(argc, argv);	/* arrange to dump state on signal */#ifdef SIGUSR1	setsignal(SIGUSR1, sigusr1);#endif	/* 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.	*/	i = open("/dev/null", O_RDWR, 0);	if (fstat(STDIN_FILENO, &stb) < 0 && errno != EOPNOTSUPP)		(void) dup2(i, STDIN_FILENO);	if (fstat(STDOUT_FILENO, &stb) < 0 && errno != EOPNOTSUPP)		(void) dup2(i, STDOUT_FILENO);	if (fstat(STDERR_FILENO, &stb) < 0 && errno != EOPNOTSUPP)		(void) dup2(i, STDERR_FILENO);	if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO)		(void) close(i);	i = DtableSize;	while (--i > 0)	{		if (i != STDIN_FILENO && i != STDOUT_FILENO && i != STDERR_FILENO)			(void) close(i);	}	errno = 0;#ifdef LOG# ifdef LOG_MAIL	openlog("sendmail", LOG_PID, LOG_MAIL);# else 	openlog("sendmail", LOG_PID);# endif#endif 	/* 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);	/*	**  Set default values for variables.	**	These cannot be in initialized data space.	*/	setdefaults(&BlankEnvelope);	RealUid = getuid();	RealGid = getgid();	pw = getpwuid(RealUid);	if (pw != NULL)		(void) strcpy(RealUserName, pw->pw_name);	else		(void) sprintf(RealUserName, "Unknown UID %d", RealUid);	/* save command line arguments */	i = 0;	for (av = argv; *av != NULL; )		i += strlen(*av++) + 1;	CommandLineArgs = xalloc(i);	p = CommandLineArgs;	for (av = argv; *av != NULL; )	{		if (av != argv)			*p++ = ' ';		strcpy(p, *av++);		p += strlen(p);	}	/* 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: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(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:Iimno:p:q:r:sTtvX:"#endif	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;		}	}	InChannel = stdin;	OutChannel = stdout;	/*	**  Move the environment so setproctitle can use the space at	**  the top of memory.	*/	for (i = j = 0; j < MAXUSERENVIRON && (p = envp[i]) != NULL; i++)	{		if (strncmp(p, "FS=", 3) == 0 || strncmp(p, "LD_", 3) == 0)			continue;		UserEnviron[j++] = newstr(p);	}	UserEnviron[j] = 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 */	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);	OpMode = MD_DELIVER;	FullName = getenv("NAME");#if NAMED_BIND	if (tTd(8, 8))		_res.options |= RES_DEBUG;#endif	errno = 0;	from = NULL;	/* initialize some macros, etc. */	initmacros(CurEnv);	/* version */	define('v', Version, CurEnv);	/* hostname */	av = myhostname(jbuf, sizeof jbuf);	if (jbuf[0] != '\0')	{		struct	utsname	utsname;		if (tTd(0, 4))			printf("canonical name: %s\n", jbuf);		define('w', newstr(jbuf), CurEnv);	/* must be new string */		define('j', newstr(jbuf), CurEnv);		setclass('w', jbuf);		p = strchr(jbuf, '.');		if (p != NULL)		{			if (p[1] != '\0')			{				define('m', newstr(&p[1]), CurEnv);				setclass('m', &p[1]);			}			while (p != NULL && strchr(&p[1], '.') != NULL)			{				*p = '\0';				setclass('w', jbuf);				*p++ = '.';				p = strchr(p, '.');			}		}		if (uname(&utsname) >= 0)			p = utsname.nodename;		else		{			if (tTd(0, 22))				printf("uname failed (%s)\n", errstring(errno));			makelower(jbuf);			p = jbuf;		}		if (tTd(0, 4))			printf("UUCP nodename: %s\n", p);		p = newstr(p);		define('k', p, CurEnv);		setclass('k', p);		setclass('w', p);	}	while (av != NULL && *av != NULL)	{		if (tTd(0, 4))			printf("\ta.k.a.: %s\n", *av);		setclass('w', *av++);	}	/* current time */	define('b', arpadate((char *) NULL), CurEnv);	/*	**  Find our real host name for future logging.	*/	p = getauthinfo(STDIN_FILENO);	define('_', p, CurEnv);	/*	** Crack argv.	*/	av = argv;	p = strrchr(*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;	optind = 1;	while ((j = getopt(argc, argv, OPTIONS)) != EOF)	{		switch (j)		{		  case 'b':	/* operations mode */			switch (j = *optarg)			{			  case MD_DAEMON:# ifdef DAEMON				if (RealUid != 0) {					usrerr("Permission denied");					exit (EX_USAGE);				}				(void) unsetenv("HOSTALIASES");# else				usrerr("Daemon mode not implemented");				ExitStat = EX_USAGE;				break;# endif /* DAEMON */			  case MD_SMTP:# ifndef SMTP				usrerr("I don't speak SMTP");				ExitStat = EX_USAGE;				break;# endif /* SMTP */			  case MD_DELIVER:			  case MD_VERIFY:			  case MD_TEST:			  case MD_INITALIAS:			  case MD_PRINT:#ifdef MAYBE_NEXT_RELEASE			  case MD_ARPAFTP:#endif				OpMode = j;				break;			  case MD_FREEZE:				usrerr("Frozen configurations unsupported");				ExitStat = EX_USAGE;				break;			  default:				usrerr("Invalid operation mode %c", j);				ExitStat = EX_USAGE;				break;			}			break;		  case 'B':	/* body type */			CurEnv->e_bodytype = newstr(optarg);			break;		  case 'C':	/* select configuration file (already done) */			if (RealUid != 0)				warn_C_flag = TRUE;			ConfFile = optarg;			(void) setgid(RealGid);			(void) setuid(RealUid);			safecf = FALSE;			break;		  case 'd':	/* debugging -- already done */			break;		  case 'f':	/* from address */		  case 'r':	/* obsolete -f flag */			if (from != NULL)			{				usrerr("More than one \"from\" person");				ExitStat = EX_USAGE;				break;			}			from = newstr(optarg);			if (strcmp(RealUserName, from) != 0)				warn_f_flag = j;			break;		  case 'F':	/* set full name */

⌨️ 快捷键说明

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