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

📄 main.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* print configuration table (or at least part of it) */		printrules();		for (i = 0; i < MAXMAILERS; i++)		{			register struct mailer *m = Mailer[i];			int j;			if (m == NULL)				continue;			printf("mailer %d (%s): P=%s S=%d R=%d M=%ld F=", i, m->m_name,				m->m_mailer, m->m_s_rwset, m->m_r_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);			printf("\n");		}	}# endif DEBUG	/*	**  Switch to the main envelope.	*/	MainEnvelope.e_from = NullAddress;	CurEnv = newenvelope(&MainEnvelope);	MainEnvelope.e_flags = BlankEnvelope.e_flags;	/*	**  If test mode, read addresses from stdin and process.	*/	if (OpMode == MD_TEST)	{		char buf[MAXLINE];		printf("ADDRESS TEST MODE\nEnter <ruleset> <address>\n");		for (;;)		{			register char **pvp;			char *q;			extern char *DelimChar;			printf("> ");			(void) fflush(stdout);			if (fgets(buf, sizeof buf, stdin) == NULL)				finis();			for (p = buf; isspace(*p); *p++)				continue;			q = p;			while (*p != '\0' && !isspace(*p))				p++;			if (*p == '\0')				continue;			*p = '\0';			do			{				extern char **prescan();				char pvpbuf[PSBUFSIZE];				pvp = prescan(++p, ',', pvpbuf);				if (pvp == NULL)					continue;				rewrite(pvp, 3);				p = q;				while (*p != '\0')				{					rewrite(pvp, atoi(p));					while (*p != '\0' && *p++ != ',')						continue;				}			} while (*(p = DelimChar) != '\0');		}	}# ifdef QUEUE	/*	**  If collecting stuff from the queue, go start doing that.	*/	if (queuemode && OpMode != MD_DAEMON && QueueIntvl == 0)	{		runqueue(FALSE);		finis();	}# endif QUEUE	/*	**  If a daemon, wait for a request.	**	getrequests will always return in a child.	**	If we should also be processing the queue, start	**		doing it in background.	**	We check for any errors that might have happened	**		during startup.	*/	if (OpMode == MD_DAEMON || QueueIntvl != 0)	{		if (!tTd(0, 1))		{			/* put us in background */			i = fork();			if (i < 0)				syserr("daemon: cannot fork");			if (i != 0)				exit(0);			/* get our pid right */			MotherPid = getpid();			/* disconnect from our controlling tty */			disconnect(TRUE);		}# ifdef QUEUE		if (queuemode)		{			runqueue(TRUE);			if (OpMode != MD_DAEMON)				for (;;)					pause();		}# endif QUEUE		dropenvelope(CurEnv);#ifdef DAEMON		getrequests();		/* at this point we are in a child: reset state */		OpMode = MD_SMTP;		(void) newenvelope(CurEnv);		openxscript(CurEnv);#endif DAEMON	}	# ifdef SMTP	/*	**  If running SMTP protocol, start collecting and executing	**  commands.  This will never return.	*/	if (OpMode == MD_SMTP)		smtp();# endif SMTP	/*	**  Do basic system initialization and set the sender	*/	initsys();	setsender(from);	if (OpMode != MD_ARPAFTP && *av == NULL && !GrabTo)	{		usrerr("Recipient names must be specified");		/* collect body for UUCP return */		if (OpMode != MD_VERIFY)			collect(FALSE);		finis();	}	if (GrabTo && RemoteServer)		NoAlias = TRUE;	if (OpMode == MD_VERIFY)		SendMode = SM_VERIFY;	/*	**  Scan argv and deliver the message to everyone.	*/	sendtoargv(av);	/* if we have had errors sofar, arrange a meaningful exit stat */	if (Errors > 0 && ExitStat == EX_OK)		ExitStat = EX_USAGE;	/*	**  Read the input mail.	*/	CurEnv->e_to = NULL;	if (OpMode != MD_VERIFY || GrabTo)		collect(FALSE);	if (GrabTo && RemoteServer && OpMode == MD_DELIVER)	{		ExitStat = RemoteMode(from, NULL, CurEnv->e_sendqueue);		finis();	}	errno = 0;	/* collect statistics */	if (OpMode != MD_VERIFY)		markstats(CurEnv, (ADDRESS *) NULL);# ifdef DEBUG	if (tTd(1, 1))		printf("From person = \"%s\"\n", CurEnv->e_from.q_paddr);# endif DEBUG	/*	**  Actually send everything.	**	If verifying, just ack.	*/	CurEnv->e_from.q_flags |= QDONTSEND;	CurEnv->e_to = NULL;	sendall(CurEnv, SM_DEFAULT);	/*	** All done.	*/	finis();}/***  FINIS -- Clean up and exit.****	Parameters:**		none****	Returns:**		never****	Side Effects:**		exits sendmail*/finis(){# ifdef DEBUG	if (tTd(2, 1))		printf("\n====finis: stat %d e_flags %o\n", ExitStat, CurEnv->e_flags);# endif DEBUG	/* clean up temp files */	CurEnv->e_to = NULL;	dropenvelope(CurEnv);	/* post statistics */	poststats(StatFile);	/* and exit */# ifdef LOG	if (LogLevel > 11)		syslog(LOG_DEBUG, "finis, pid=%d", getpid());# endif LOG	if (ExitStat == EX_TEMPFAIL)		ExitStat = EX_OK;	exit(ExitStat);}/***  INTSIG -- clean up on interrupt****	This just arranges to exit.  It pessimises in that it**	may resend a message.****	Parameters:**		none.****	Returns:**		none.****	Side Effects:**		Requeues the current job.*/intsig(){	register ADDRESS *q;	FileName = NULL;	q = CurEnv->e_sendqueue;	if (q != NULL && !bitset(EF_INQUEUE,CurEnv->e_flags) &&		OpMode != MD_VERIFY) 	{		for (; q != NULL; q = q->q_next)			if (q != &CurEnv->e_from)				q->q_flags &= ~QDONTSEND;		queueup(CurEnv, TRUE, Verbose);	}	unlockqueue(CurEnv);	exit(EX_OK);}/***  INITMACROS -- initialize the macro system****	This just involves defining some macros that are actually**	used internally as metasymbols to be themselves.****	Parameters:**		none.****	Returns:**		none.****	Side Effects:**		initializes several macros to be themselves.*/struct metamac	MetaMacros[] ={	/* LHS pattern matching characters */	'*', MATCHZANY,	'+', MATCHANY,	'-', MATCHONE,	'=', MATCHCLASS,	'~', MATCHNCLASS,	'%', MATCHYELLOW, '!', MATCHNYELLOW,	/* these are RHS metasymbols */	'#', CANONNET,	'@', CANONHOST,	':', CANONUSER,	'>', CALLSUBR,	/* the conditional operations */	'?', CONDIF,	'|', CONDELSE,	'.', CONDFI,	/*  the NIS lookup characters */	'{', YELLOWBEGIN,	'}', YELLOWEND,	/* and finally the hostname lookup characters */	'[', HOSTBEGIN,	']', HOSTEND,	'\0'};initmacros(){	register struct metamac *m;	char buf[5];	register int c;	for (m = MetaMacros; m->metaname != '\0'; m++)	{		buf[0] = m->metaval;		buf[1] = '\0';		define(m->metaname, newstr(buf), CurEnv);	}	buf[0] = MATCHREPL;	buf[2] = '\0';	for (c = '0'; c <= '9'; c++)	{		buf[1] = c;		define(c, newstr(buf), CurEnv);	}}/***  FREEZE -- freeze BSS & allocated memory****	This will be used to efficiently load the configuration file.****	Parameters:**		freezefile -- the name of the file to freeze to.****	Returns:**		none.****	Side Effects:**		Writes BSS and malloc'ed memory to freezefile*/union frz{	char		frzpad[BUFSIZ];	/* insure we are on a BUFSIZ boundary */	struct	{		time_t	frzstamp;	/* timestamp on this freeze */		char	*frzbrk;	/* the current break */		char	*frzedata;	/* address of edata */		char	*frzend;	/* address of end */		char	frzver[252];	/* sendmail version */	} frzinfo;};freeze(freezefile)	char *freezefile;{	int f;	union frz fhdr;	extern char edata, end;	extern char *sbrk();	extern char Version[];	if (freezefile == NULL)		return;	/* try to open the freeze file */	f = creat(freezefile, FreezeMode);	if (f < 0)	{		syserr("Cannot freeze");		errno = 0;		return;	}	/* build the freeze header */	fhdr.frzinfo.frzstamp = curtime();	fhdr.frzinfo.frzbrk = sbrk(0);	fhdr.frzinfo.frzedata = &edata;	fhdr.frzinfo.frzend = &end;	(void) strcpy(fhdr.frzinfo.frzver, Version);	/* write out the freeze header */	if (write(f, (char *) &fhdr, sizeof fhdr) != sizeof fhdr ||	    write(f, (char *) &edata, (int) (fhdr.frzinfo.frzbrk - &edata)) !=					(int) (fhdr.frzinfo.frzbrk - &edata))	{		syserr("Cannot freeze");	}	/* fine, clean up */	(void) close(f);}/***  THAW -- read in the frozen configuration file.****	Parameters:**		freezefile -- the name of the file to thaw from.****	Returns:**		TRUE if it successfully read the freeze file.**		FALSE otherwise.****	Side Effects:**		reads freezefile in to BSS area.*/thaw(freezefile)	char *freezefile;{	int f;	union frz fhdr;	extern char edata;	extern char Version[];	extern caddr_t brk();	if (freezefile == NULL)		return (FALSE);	/* open the freeze file */	f = open(freezefile, 0);	if (f < 0)	{		errno = 0;		return (FALSE);	}	/* read in the header */	if (read(f, (char *) &fhdr, sizeof fhdr) < sizeof fhdr ||	    fhdr.frzinfo.frzedata != &edata ||	    fhdr.frzinfo.frzend != &end ||	    strcmp(fhdr.frzinfo.frzver, Version) != 0)	{		(void) close(f);		return (FALSE);	}	/* arrange to have enough space */	if (brk(fhdr.frzinfo.frzbrk) == (caddr_t) -1)	{		syserr("Cannot break to %x", fhdr.frzinfo.frzbrk);		(void) close(f);		return (FALSE);	}	/* now read in the freeze file */	if (read(f, (char *) &edata, (int) (fhdr.frzinfo.frzbrk - &edata)) !=					(int) (fhdr.frzinfo.frzbrk - &edata))	{		/* oops!  we have trashed memory..... */		(void) write(2, "Cannot read freeze file\n", 24);		_exit(EX_SOFTWARE);	}	(void) close(f);	return (TRUE);}/***  DISCONNECT -- remove our connection with any foreground process****	Parameters:**		fulldrop -- if set, we should also drop the controlling**			TTY if possible -- this should only be done when**			setting up the daemon since otherwise UUCP can**			leave us trying to open a dialin, and we will**			wait for the carrier.****	Returns:**		none****	Side Effects:**		Trys to insure that we are immune to vagaries of**		the controlling tty.*/disconnect(fulldrop)	bool fulldrop;{	int fd;#ifdef DEBUG	if (tTd(52, 1))		printf("disconnect: In %d Out %d\n", fileno(InChannel),						fileno(OutChannel));	if (tTd(52, 5))	{		printf("don't\n");		return;	}#endif DEBUG	/* be sure we don't get nasty signals */	(void) signal(SIGHUP, SIG_IGN);	(void) signal(SIGINT, SIG_IGN);	(void) signal(SIGQUIT, SIG_IGN);	/* we can't communicate with our caller, so.... */	HoldErrs = TRUE;	ErrorMode = EM_MAIL;	Verbose = FALSE;	/* all input from /dev/null */	if (InChannel != stdin)	{		(void) fclose(InChannel);		InChannel = stdin;	}	(void) freopen("/dev/null", "r", stdin);	/* output to the transcript */	if (OutChannel != stdout)	{		(void) fclose(OutChannel);		OutChannel = stdout;	}	if (CurEnv->e_xfp == NULL)		CurEnv->e_xfp = fopen("/dev/null", "w");	(void) fflush(stdout);	(void) close(1);	(void) close(2);	if (CurEnv->e_xfp != NULL)	    while ((fd = dup(fileno(CurEnv->e_xfp))) < 2 && fd > 0)		continue;#ifdef TIOCNOTTY	/* drop our controlling TTY completely if possible */	if (fulldrop)	{		fd = open("/dev/tty", 2);		if (fd >= 0)		{			(void) ioctl(fd, (int) TIOCNOTTY, (char *) 0);			(void) close(fd);		}		(void) setpgrp(0, 0);		errno = 0;	}#endif TIOCNOTTY# ifdef LOG	if (LogLevel > 11)		syslog(LOG_DEBUG, "in background, pid=%d", getpid());# endif LOG	errno = 0;}

⌨️ 快捷键说明

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