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

📄 main.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		}

		if (uname(&utsname) >= 0)
			p = utsname.nodename;
		else
		{
			if (tTd(0, 22))
				dprintf("uname failed (%s)\n",
					errstring(errno));
			makelower(jbuf);
			p = jbuf;
		}
		if (tTd(0, 4))
			dprintf(" UUCP nodename: %s\n", p);
		p = newstr(p);
		define('k', p, CurEnv);
		setclass('k', p);
		setclass('w', p);
	}
	if (hp != NULL)
	{
		for (av = hp->h_aliases; av != NULL && *av != NULL; av++)
		{
			if (tTd(0, 4))
				dprintf("\ta.k.a.: %s\n", *av);
			setclass('w', *av);
		}
#if NETINET || NETINET6
		for (i = 0; hp->h_addr_list[i] != NULL; i++)
		{
# if NETINET6
			char *addr;
			char buf6[INET6_ADDRSTRLEN];
			struct in6_addr ia6;
# endif /* NETINET6 */
# if NETINET
			struct in_addr ia;
# endif /* NETINET */
			char ipbuf[103];

			ipbuf[0] = '\0';
			switch (hp->h_addrtype)
			{
# if NETINET
			  case AF_INET:
				if (hp->h_length != INADDRSZ)
					break;

				memmove(&ia, hp->h_addr_list[i], INADDRSZ);
				(void) snprintf(ipbuf,	 sizeof ipbuf,
						"[%.100s]", inet_ntoa(ia));
				break;
# endif /* NETINET */

# if NETINET6
			  case AF_INET6:
				if (hp->h_length != IN6ADDRSZ)
					break;

				memmove(&ia6, hp->h_addr_list[i], IN6ADDRSZ);
				addr = anynet_ntop(&ia6, buf6, sizeof buf6);
				if (addr != NULL)
					(void) snprintf(ipbuf, sizeof ipbuf,
							"[%.100s]", addr);
				break;
# endif /* NETINET6 */
			}
			if (ipbuf[0] == '\0')
				break;

			if (tTd(0, 4))
				dprintf("\ta.k.a.: %s\n", ipbuf);
			setclass('w', ipbuf);
		}
#endif /* NETINET || NETINET6 */
	}

	/* current time */
	define('b', arpadate((char *) NULL), CurEnv);
	/* current load average */
	CurrentLA = sm_getla(CurEnv);

	QueueLimitRecipient = (QUEUE_CHAR *) NULL;
	QueueLimitSender = (QUEUE_CHAR *) NULL;
	QueueLimitId = (QUEUE_CHAR *) NULL;

	/*
	**  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;
	else if (strcmp(p, "hoststat") == 0)
		OpMode = MD_HOSTSTAT;
	else if (strcmp(p, "purgestat") == 0)
		OpMode = MD_PURGESTAT;

	optind = 1;
	while ((j = getopt(argc, argv, OPTIONS)) != -1)
	{
		switch (j)
		{
		  case 'b':	/* operations mode */
			switch (j = *optarg)
			{
			  case MD_DAEMON:
			  case MD_FGDAEMON:
#if !DAEMON
				usrerr("Daemon mode not implemented");
				ExitStat = EX_USAGE;
				break;
#endif /* !DAEMON */
			  case MD_SMTP:
#if !SMTP
				usrerr("I don't speak SMTP");
				ExitStat = EX_USAGE;
				break;
#endif /* !SMTP */

			  case MD_INITALIAS:
			  case MD_DELIVER:
			  case MD_VERIFY:
			  case MD_TEST:
			  case MD_PRINT:
			  case MD_HOSTSTAT:
			  case MD_PURGESTAT:
			  case MD_ARPAFTP:
				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 = newstr(optarg);
			dp = drop_privileges(TRUE);
			setstat(dp);
			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(denlstring(optarg, TRUE, TRUE));
			if (strcmp(RealUserName, from) != 0)
				warn_f_flag = j;
			break;

		  case 'F':	/* set full name */
			FullName = newstr(optarg);
			break;

		  case 'G':	/* relay (gateway) submission */
			/* already set */
			break;

		  case 'h':	/* hop count */
			CurEnv->e_hopcount = (short) strtol(optarg, &ep, 10);
			if (*ep)
			{
				usrerr("Bad hop count (%s)", optarg);
				ExitStat = EX_USAGE;
			}
			break;

		  case 'L':	/* program label */
			/* already set */
			break;

		  case 'n':	/* don't alias */
			NoAlias = TRUE;
			break;

		  case 'N':	/* delivery status notifications */
			DefaultNotify |= QHASNOTIFY;
			define(macid("{dsn_notify}", NULL),
			       newstr(optarg), CurEnv);
			if (strcasecmp(optarg, "never") == 0)
				break;
			for (p = optarg; p != NULL; optarg = p)
			{
				p = strchr(p, ',');
				if (p != NULL)
					*p++ = '\0';
				if (strcasecmp(optarg, "success") == 0)
					DefaultNotify |= QPINGONSUCCESS;
				else if (strcasecmp(optarg, "failure") == 0)
					DefaultNotify |= QPINGONFAILURE;
				else if (strcasecmp(optarg, "delay") == 0)
					DefaultNotify |= QPINGONDELAY;
				else
				{
					usrerr("Invalid -N argument");
					ExitStat = EX_USAGE;
				}
			}
			break;

		  case 'o':	/* set option */
			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)
			{
				*p++ = '\0';
				if (*p != '\0')
				{
					ep = xalloc(strlen(p) + 1);
					cleanstrcpy(ep, p, MAXNAME);
					define('s', ep, CurEnv);
				}
			}
			if (*optarg != '\0')
			{
				ep = xalloc(strlen(optarg) + 1);
				cleanstrcpy(ep, optarg, MAXNAME);
				define('r', ep, CurEnv);
			}
			break;

		  case 'q':	/* run queue files at intervals */
#if QUEUE
			/* sanity check */
			if (OpMode != MD_DELIVER &&
			    OpMode != MD_DAEMON &&
			    OpMode != MD_FGDAEMON &&
			    OpMode != MD_PRINT &&
			    OpMode != MD_QUEUERUN)
			{
				usrerr("Can not use -q with -b%c", OpMode);
				ExitStat = EX_USAGE;
				break;
			}

			/* don't override -bd, -bD or -bp */
			if (OpMode == MD_DELIVER)
				OpMode = MD_QUEUERUN;

			FullName = NULL;

			switch (optarg[0])
			{
			  case 'I':
				new = (QUEUE_CHAR *) xalloc(sizeof *new);
				new->queue_match = newstr(&optarg[1]);
				new->queue_next = QueueLimitId;
				QueueLimitId = new;
				break;

			  case 'R':
				new = (QUEUE_CHAR *) xalloc(sizeof *new);
				new->queue_match = newstr(&optarg[1]);
				new->queue_next = QueueLimitRecipient;
				QueueLimitRecipient = new;
				break;

			  case 'S':
				new = (QUEUE_CHAR *) xalloc(sizeof *new);
				new->queue_match = newstr(&optarg[1]);
				new->queue_next = QueueLimitSender;
				QueueLimitSender = new;
				break;

			  default:
				i = Errors;
				QueueIntvl = convtime(optarg, 'm');

				/* check for bad conversion */
				if (i < Errors)
					ExitStat = EX_USAGE;
				break;
			}
#else /* QUEUE */
			usrerr("I don't know about queues");
			ExitStat = EX_USAGE;
#endif /* QUEUE */
			break;

		  case 'R':	/* DSN RET: what to return */
			if (bitset(EF_RET_PARAM, CurEnv->e_flags))
			{
				usrerr("Duplicate -R flag");
				ExitStat = EX_USAGE;
				break;
			}
			CurEnv->e_flags |= EF_RET_PARAM;
			if (strcasecmp(optarg, "hdrs") == 0)
				CurEnv->e_flags |= EF_NO_BODY_RETN;
			else if (strcasecmp(optarg, "full") != 0)
			{
				usrerr("Invalid -R value");
				ExitStat = EX_USAGE;
			}
			define(macid("{dsn_ret}", NULL),
			       newstr(optarg), CurEnv);
			break;

		  case 't':	/* read recipients from message */
			GrabTo = TRUE;
			break;

		  case 'U':	/* initial (user) submission */
			/* already set */
			break;

		  case 'V':	/* DSN ENVID: set "original" envelope id */
			if (!xtextok(optarg))
			{
				usrerr("Invalid syntax in -V flag");
				ExitStat = EX_USAGE;
			}
			else
			{
				CurEnv->e_envid = newstr(optarg);
				define(macid("{dsn_envid}", NULL),
				       newstr(optarg), CurEnv);
			}
			break;

		  case 'X':	/* traffic log file */
			dp = drop_privileges(TRUE);
			setstat(dp);
			if (stat(optarg, &traf_st) == 0 &&
			    S_ISFIFO(traf_st.st_mode))
				TrafficLogFile = fopen(optarg, "w");
			else
				TrafficLogFile = fopen(optarg, "a");
			if (TrafficLogFile == NULL)
			{
				syserr("cannot open %s", optarg);
				ExitStat = EX_CANTCREAT;
				break;
			}
#if HASSETVBUF
			(void) setvbuf(TrafficLogFile, NULL, _IOLBF, 0);
#else /* HASSETVBUF */
			(void) setlinebuf(TrafficLogFile);
#endif /* HASSETVBUF */
			break;

			/* compatibility flags */
		  case 'c':	/* connect to non-local mailers */
		  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(j, "T", FALSE, TRUE, CurEnv);
			break;

		  case 'e':	/* error message disposition */
		  case 'M':	/* define macro */
			setoption(j, optarg, FALSE, TRUE, CurEnv);
			break;

		  case 's':	/* save From lines in headers */
			setoption('f', "T", FALSE, TRUE, CurEnv);
			break;

#ifdef DBM
		  case 'I':	/* initialize alias DBM file */
			OpMode = MD_INITALIAS;
			break;
#endif /* DBM */

#if defined(__osf__) || defined(_AIX3)
		  case 'x':	/* random flag that OSF/1 & AIX mailx passes */
			break;
#endif /* defined(__osf__) || defined(_AIX3) */
#if defined(sony_news)
		  case 'E':
		  case 'J':	/* ignore flags for Japanese code conversion
				   implemented on Sony NEWS */
			break;
#endif /* defined(sony_news) */

		  default:
			finis(TRUE, EX_USAGE);
			break;
		}
	}
	av += optind;

	if (bitset(SUBMIT_MTA, SubmitMode) &&
	    bitset(SUBMIT_MSA, SubmitMode))
	{
		/* sanity check */
		errno = 0;	/* reset to avoid bogus error messages */
		syserr("Cannot use both -G and -U together");
	}
	else if (bitset(SUBMIT_MTA, SubmitMode))
		define(macid("{daemon_flags}", NULL), "CC f", CurEnv);
	else if (bitset(SUBMIT_MSA, SubmitMode))
	{
		define(macid("{daemon_flags}", NULL), "c u", CurEnv);

		/* check for wrong OpMode */
		if (OpMode != MD_DELIVER && OpMode != MD_SMTP)
		{
			errno = 0;	/* reset to avoid bogus error msgs */
			syserr("Cannot use -U and -b%c", OpMode);
		}
	}
	else
	{
#if _FFR_DEFAULT_SUBMIT_TO_MSA
		define(macid("{daemon_flags}", NULL), "c u", CurEnv);
#else /* _FFR_DEFAULT_SUBMIT_TO_MSA */
		/* EMPTY */
#endif /* _FFR_DEFAULT_SUBMIT_TO_MSA */
	}

	/*
	**  Do basic initialization.
	**	Read system control file.
	**	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
	checkfd012("before readcf");
#endif /* XDEBUG */
	vendor_pre_defaults(CurEnv);

	readcf(getcfname(), safecf, CurEnv);
	ConfigFileRead = TRUE;
	vendor_post_defaults(CurEnv);

	/* 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();

	/* avoid denial-of-service attacks */
	resetlimits();

	if (OpMode != MD_DAEMON && OpMode != MD_FGDAEMON)
	{
		/* drop privileges -- daemon mode done after socket/bind */
		dp = drop_privileges(FALSE);
		setstat(dp);
	}

#if NAMED_BIND
	_res.retry = TimeOuts.res_retry[RES_TO_DEFAULT];
	_res.retrans = TimeOuts.res_retrans[RES_TO_DEFAULT];
#endif /* NAMED_BIND */

	/*
	**  Find our real host name for future logging.
	*/

	authinfo = getauthinfo(STDIN_FILENO, &forged);
	define('_', authinfo, 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);

	/* probe interfaces and locate any additional names */
	if (!DontProbeInterfaces)
		load_if_names();

	if (tTd(0, 1))
	{
		dprintf("\n============ SYSTEM IDENTITY (after readcf) ============");
		dprintf("\n      (short domain name) $w = ");
		xputs(macvalue('w', CurEnv));
		dprintf("\n  (canonical domain name) $j = ");
		xputs(macvalue('j', CurEnv));
		dprintf("\n         (subdomain name) $m = ");
		xputs(macvalue('m', CurEnv));
		dprintf("\n              (node name) $k = ");
		xputs(macvalue('k', CurEnv));
		dprintf("\n========================================================\n\n");
	}

	/*
	**  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 */
	if (warn_C_flag)
		auth_warning(CurEnv, "Processed by %s with -C %s",
			RealUserName, ConfFile);
	if (Warn_Q_option && !wordinclass(RealUserName, 't'))
		auth_warning(CurEnv, "Processed from queue %s", QueueDir);

	/* check body type for legality */
	if (CurEnv->e_bodytype == NULL)
		/* EMPTY */
		/* nothing */ ;
	else if (strcasecmp(CurEnv->e_bodytype, "7BIT") == 0)
		SevenBitInput = TRUE;
	else if (strcasecmp(CurEnv->e_bodytype, "8BITMIME") == 0)
		SevenBitInput = FALSE;
	else
	{

⌨️ 快捷键说明

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