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

📄 daemon.c

📁 < linux网络编程工具>>配套源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			{
# if NETINET
			  case AF_INET:
				if (!isascii(*v) || !isdigit(*v) ||
				    ((d->d_addr.sin.sin_addr.s_addr = inet_addr(v)) == INADDR_NONE))
				{
					register struct hostent *hp;

					hp = sm_gethostbyname(v, AF_INET);
					if (hp == NULL)
						syserr("554 5.3.0 host \"%s\" unknown",
						       v);
					else
					{
						while (*(hp->h_addr_list) &&
						       hp->h_addrtype != AF_INET)
							hp->h_addr_list++;
						if (*(hp->h_addr_list) == NULL)
							syserr("554 5.3.0 host \"%s\" unknown",
							       v);
						else
							memmove(&d->d_addr.sin.sin_addr,
								*(hp->h_addr_list),
								INADDRSZ);
					}
				}
				break;
# endif /* NETINET */

# if NETINET6
			  case AF_INET6:
				if (!isascii(*v) || !isxdigit(*v) ||
				    inet_pton(AF_INET6, v,
					      &d->d_addr.sin6.sin6_addr) != 1)
				{
					register struct hostent *hp;

					hp = sm_gethostbyname(v, AF_INET6);
					if (hp == NULL)
						syserr("554 5.3.0 host \"%s\" unknown",
						       v);
					else
					{
						while (*(hp->h_addr_list) &&
						       hp->h_addrtype != AF_INET6)
							hp->h_addr_list++;
						if (*(hp->h_addr_list) == NULL)
							syserr("554 5.3.0 host \"%s\" unknown",
							       v);
						else
							memmove(&d->d_addr.sin6.sin6_addr,
								*(hp->h_addr_list),
								IN6ADDRSZ);
					}
				}
				break;
# endif /* NETINET6 */

			  default:
				syserr("554 5.3.5 address= option unsupported for family %d",
				       d->d_addr.sa.sa_family);
				break;
			}
			break;

		  case 'P':		/* port */
			switch (d->d_addr.sa.sa_family)
			{
# if NETINET
			  case AF_INET:
				if (isascii(*v) && isdigit(*v))
					d->d_addr.sin.sin_port = htons((u_short)atoi((const char *)v));
				else
				{
#  ifdef NO_GETSERVBYNAME
					syserr("554 5.3.5 invalid port number: %s",
					       v);
#  else /* NO_GETSERVBYNAME */
					register struct servent *sp;

					sp = getservbyname(v, "tcp");
					if (sp == NULL)
						syserr("554 5.3.5 service \"%s\" unknown",
						       v);
					else
						d->d_addr.sin.sin_port = sp->s_port;
#  endif /* NO_GETSERVBYNAME */
				}
				break;
# endif /* NETINET */

# if NETINET6
			  case AF_INET6:
				if (isascii(*v) && isdigit(*v))
					d->d_addr.sin6.sin6_port = htons((u_short)atoi(v));
				else
				{
#  ifdef NO_GETSERVBYNAME
					syserr("554 5.3.5 invalid port number: %s",
					       v);
#  else /* NO_GETSERVBYNAME */
					register struct servent *sp;

					sp = getservbyname(v, "tcp");
					if (sp == NULL)
						syserr("554 5.3.5 service \"%s\" unknown",
						       v);
					else
						d->d_addr.sin6.sin6_port = sp->s_port;
#  endif /* NO_GETSERVBYNAME */
				}
				break;
# endif /* NETINET6 */

# if NETISO
			  case AF_ISO:
				/* assume two byte transport selector */
				if (isascii(*v) && isdigit(*v))
					port = htons((u_short)atoi(v));
				else
				{
#  ifdef NO_GETSERVBYNAME
					syserr("554 5.3.5 invalid port number: %s",
					       v);
#  else /* NO_GETSERVBYNAME */
					register struct servent *sp;

					sp = getservbyname(v, "tcp");
					if (sp == NULL)
						syserr("554 5.3.5 service \"%s\" unknown",
						       v);
					else
						port = sp->s_port;
#  endif /* NO_GETSERVBYNAME */
				}
				memmove(TSEL(&d->d_addr.siso),
					(char *) &port, 2);
				break;
# endif /* NETISO */

			  default:
				syserr("554 5.3.5 Port= option unsupported for family %d",
				       d->d_addr.sa.sa_family);
				break;
			}
			break;

		  case 'L':		/* listen queue size */
			d->d_listenqueue = atoi(v);
			break;

		  case 'M':		/* modifiers (flags) */
			l = 3 * strlen(v) + 3;
			h = v;
			flags = xalloc(l);
			d->d_mflags = flags;
			for (; *h != '\0'; h++)
			{
				if (!(isascii(*h) && isspace(*h)))
				{
					if (flags != d->d_mflags)
						*flags++ = ' ';
					*flags++ = *h;
					if (isupper(*h))
						*flags++ = *h;
				}
			}
			*flags++ = '\0';
			for (; *v != '\0'; v++)
				if (!(isascii(*v) && isspace(*v)))
					setbitn(*v, d->d_flags);
			break;

		  case 'S':		/* send buffer size */
			d->d_tcpsndbufsize = atoi(v);
			break;

		  case 'R':		/* receive buffer size */
			d->d_tcprcvbufsize = atoi(v);
			break;

		  case 'N':		/* name */
			d->d_name = v;
			break;

		  default:
			syserr("554 5.3.5 PortOptions parameter \"%s\" unknown",
			       f);
		}
	}
}
/*
**  SETDAEMONOPTIONS -- set options for running the MTA daemon
**
**	Parameters:
**		p -- the options line.
**
**	Returns:
**		TRUE if successful, FALSE otherwise.
*/

bool
setdaemonoptions(p)
	register char *p;
{
	if (ndaemons >= MAXDAEMONS)
		return FALSE;
	Daemons[ndaemons].d_socket = -1;
	Daemons[ndaemons].d_listenqueue = 10;
	clrbitmap(Daemons[ndaemons].d_flags);
	setsockaddroptions(p, &Daemons[ndaemons]);

	if (Daemons[ndaemons].d_name != NULL)
		Daemons[ndaemons].d_name = newstr(Daemons[ndaemons].d_name);
	else
	{
		char num[30];

		snprintf(num, sizeof num, "Daemon%d", ndaemons);
		Daemons[ndaemons].d_name = newstr(num);
	}

	if (tTd(37, 1))
	{
		dprintf("Daemon %s flags: ", Daemons[ndaemons].d_name);
		if (bitnset(D_ETRNONLY, Daemons[ndaemons].d_flags))
			dprintf("ETRNONLY ");
		if (bitnset(D_NOETRN, Daemons[ndaemons].d_flags))
			dprintf("NOETRN ");
		dprintf("\n");
	}
	++ndaemons;
	return TRUE;
}
/*
**  INITDAEMON -- initialize daemon if not yet done.
**
**	Parameters:
**		none
**
**	Returns:
**		none
**
**	Side Effects:
**		initializes structure for one daemon.
*/
void
initdaemon()
{
	if (ndaemons == 0)
	{
		Daemons[ndaemons].d_socket = -1;
		Daemons[ndaemons].d_listenqueue = 10;
		Daemons[ndaemons].d_name = "Daemon0";
		ndaemons = 1;
	}
}
/*
**  SETCLIENTOPTIONS -- set options for running the client
**
**	Parameters:
**		p -- the options line.
**
**	Returns:
**		none.
*/

static SOCKADDR	ClientAddr;		/* address for client */

void
setclientoptions(p)
	register char *p;
{
	struct daemon d;
	extern ENVELOPE BlankEnvelope;

	memset(&d, '\0', sizeof d);
	setsockaddroptions(p, &d);

	/* grab what we need */
	memcpy(&ClientAddr, &d.d_addr, sizeof ClientAddr);
	TcpSndBufferSize = d.d_tcpsndbufsize;
	TcpRcvBufferSize = d.d_tcprcvbufsize;
	if (d.d_mflags != NULL)
		define(macid("{client_flags}", NULL), d.d_mflags,
		       &BlankEnvelope);
	else
		define(macid("{client_flags}", NULL), "", &BlankEnvelope);
}
/*
**  ADDR_FAMILY -- determine address family from address
**
**	Parameters:
**		addr -- the string representation of the address
**
**	Returns:
**		AF_INET, AF_INET6 or AF_UNSPEC
**
**	Side Effects:
**		none.
*/

static int
addr_family(addr)
	char *addr;
{
# if NETINET6
	SOCKADDR clt_addr;
# endif /* NETINET6 */

# if NETINET
	if (inet_addr(addr) != INADDR_NONE)
	{
		if (tTd(16, 9))
			printf("addr_family(%s): INET\n", addr);
		return AF_INET;
	}
# endif /* NETINET */
# if NETINET6
	if (inet_pton(AF_INET6, addr, &clt_addr.sin6.sin6_addr) == 1)
	{
		if (tTd(16, 9))
			printf("addr_family(%s): INET6\n", addr);
		return AF_INET6;
	}
# endif /* NETINET6 */
	if (tTd(16, 9))
		printf("addr_family(%s): UNSPEC\n", addr);
	return AF_UNSPEC;
}
/*
**  MAKECONNECTION -- make a connection to an SMTP socket on a machine.
**
**	Parameters:
**		host -- the name of the host.
**		port -- the port number to connect to.
**		mci -- a pointer to the mail connection information
**			structure to be filled in.
**		e -- the current envelope.
**
**	Returns:
**		An exit code telling whether the connection could be
**			made and if not why not.
**
**	Side Effects:
**		none.
*/

static jmp_buf	CtxConnectTimeout;

SOCKADDR	CurHostAddr;		/* address of current host */

int
makeconnection(host, port, mci, e)
	char *host;
	volatile u_int port;
	register MCI *mci;
	ENVELOPE *e;
{
	register volatile int addrno = 0;
	register volatile int s;
	register struct hostent *volatile hp = (struct hostent *)NULL;
	SOCKADDR addr;
	SOCKADDR clt_addr;
	int save_errno = 0;
	volatile SOCKADDR_LEN_T addrlen;
	volatile bool firstconnect;
	EVENT *volatile ev = NULL;
# if NETINET6
	volatile bool v6found = FALSE;
# endif /* NETINET6 */
	volatile int family = InetMode;
	SOCKADDR_LEN_T len;
	volatile SOCKADDR_LEN_T socksize = 0;
	volatile bool clt_bind;
	BITMAP256 d_flags;
	char *p;
	extern ENVELOPE BlankEnvelope;

	/* retranslate ${daemon_flags} into bitmap */
	clrbitmap(d_flags);
	if ((p = macvalue(macid("{daemon_flags}", NULL), e)) != NULL)
	{
		for (; *p != '\0'; p++)
		{
			if (!(isascii(*p) && isspace(*p)))
				setbitn(*p, d_flags);
		}
	}

	/* "add" ${client_flags} to bitmap */
	if ((p = macvalue(macid("{client_flags}", NULL), e)) != NULL)
	{
		for (; *p != '\0'; p++)
		{
			/* look for just this one flag */
			if (*p == D_IFNHELO)
			{
				setbitn(*p, d_flags);
				break;
			}
		}
	}

# if NETINET6
 v4retry:
# endif /* NETINET6 */
	clt_bind = FALSE;

	/* Set up the address for outgoing connection. */
	if (bitnset(D_BINDIF, d_flags) &&
	    (p = macvalue(macid("{if_addr}", NULL), e)) != NULL)
	{
# if NETINET6
		char p6[INET6_ADDRSTRLEN];
# endif /* NETINET6 */

		memset(&clt_addr, '\0', sizeof clt_addr);

		/* infer the address family from the address itself */
		clt_addr.sa.sa_family = addr_family(p);
		switch (clt_addr.sa.sa_family)
		{
# if NETINET
		  case AF_INET:
			if ((clt_addr.sin.sin_addr.s_addr = inet_addr(p))
			    != INADDR_NONE)
			{
				clt_bind = TRUE;
				socksize = sizeof (struct sockaddr_in);
			}
			else if (clt_addr.sin.sin_port != 0)
			{
				clt_addr.sin.sin_addr.s_addr = INADDR_ANY;
				clt_bind = TRUE;
				socksize = sizeof (struct sockaddr_in);
			}
			break;
# endif /* NETINET */

# if NETINET6
		  case AF_INET6:
			if (inet_addr(p) != INADDR_NONE)
				snprintf(p6, sizeof p6, "::ffff:%s", p);
			else
				strlcpy(p6, p, sizeof p6);
			if (inet_pton(AF_INET6, p6,
				      &clt_addr.sin6.sin6_addr) == 1)
			{
				clt_bind = TRUE;
				socksize = sizeof (struct sockaddr_in6);
			}
			else if (clt_addr.sin6.sin6_port != 0)
			{
				if (IN6_IS_ADDR_UNSPECIFIED(&clt_addr.sin6.sin6_addr))
					clt_addr.sin6.sin6_addr = in6addr_any;
				clt_bind = TRUE;
				socksize = sizeof (struct sockaddr_in6);
			}
			break;
# endif /* NETINET6 */

# if 0
		  default:
			syserr("554 5.3.5 Address= option unsupported for family %d",
			       clt_addr.sa.sa_family);
			break;
# endif /* 0 */
		}
		if (clt_bind)
			family = clt_addr.sa.sa_family;
	}
	else
	{
		STRUCTCOPY(ClientAddr, clt_addr);
		if (clt_addr.sa.sa_family == AF_UNSPEC)
			clt_addr.sa.sa_family = InetMode;
		switch (clt_addr.sa.sa_family)
		{
# if NETINET
		  case AF_INET:
			if (clt_addr.sin.sin_addr.s_addr == 0)
				clt_addr.sin.sin_addr.s_addr = INADDR_ANY;
			else
				clt_bind = TRUE;
			if (clt_addr.sin.sin_port != 0)
				clt_bind = TRUE;
			socksize = sizeof (struct sockaddr_in);
			break;
# endif /* NETINET */
# if NETINET6
		  case AF_INET6:
			if (IN6_IS_ADDR_UNSPECIFIED(&clt_addr.sin6.sin6_addr))
				clt_addr.sin6.sin6_addr = in6addr_any;
			else
				clt_bind = TRUE;
			socksize = sizeof (struct sockaddr_in6);
			if (clt_addr.sin6.sin6_port != 0)
				clt_bind = TRUE;
			break;
# endif /* NETINET6 */
# if NETISO
		  case AF_ISO:
			socksize = sizeof clt_addr.siso;
			clt_bind = TRUE;
			break;
# endif /* NETISO */
		  default:
			break;
		}
	}

	/*
	**  Set up the address for the mailer.
	**	Accept "[a.b.c.d]" syntax for host name.
	*/

# if NAMED_BIND
	h_errno = 0;
# endif /* NAMED_BIND */
	errno = 0;
	memset(&CurHostAddr, '\0', sizeof CurHostAddr);
	memset(&addr, '\0', sizeof addr);
	SmtpPhase = mci->mci_phase = "initial connection";
	CurHostName = host;

	if (host[0] == '[')
	{
		p = strchr(host, ']');
		if (p != NULL)
		{
# if NETINET
			unsigned long hid = INADDR_NONE;
# endif /* NETINET */
# if NETINET6
			struct sockaddr_in6 hid6;
# endif /* NETINET6 */

			*p = '\0';
# if NETINET6
			memset(&hid6, '\0', sizeof hid6);
# endif /* NETINET6 */
# if NETINET
			if (family == AF_INET &&
			    (hid = inet_addr(&host[1])) != INADDR_NONE)
			{
				addr.sin.sin_family = AF_INET;
				addr.sin.sin_addr.s_addr = hid;
			}
			else
# endif /* NETINET */
# if NETINET6
			if (family == AF_INET6 &&
			    inet_pton(AF_INET6, &host[1],
				      &hid6.sin6_addr) == 1)

⌨️ 快捷键说明

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