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

📄 daemon.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
**		port -- the port number to connect to.**		outfile -- a pointer to a place to put the outfile**			descriptor.**		infile -- ditto for infile.****	Returns:**		An exit code telling whether the connection could be**			made and if not why not.****	Side Effects:**		On an error, global <errno> is set describing the error.**		A previously existing connection will be reused.**		Previously cached data will be used to find the host**			and determine its status.  This cache is updated**			with the host's current status.*/makeconnection(host, port, outfile, infile)	char *host;	u_short port;	FILE **outfile;	FILE **infile;{	register struct hostinfo *hp;	extern char *inet_ntoa();	int s;	struct sockaddr_in	addr;	/* Remember who we're talking to, for error messages */	RealHostName = newstr(host);	/*	**  Determine the address of the host.	**  If we have tried to connect before and failed, don't try,	**  Unless this is the last attempt.	*/	setproctitle("%s To %s", CurEnv->e_id, RealHostName);	AlreadyKnown = FALSE;	hp = lookuphost(host);	errno = 0;	if (!hp->h_exists)		return (EX_NOHOST);	if (hp->h_down && (curtime() < CurEnv->e_ctime + TimeOut))	{		errno = hp->h_errno;	/* for a better message */		return (EX_TEMPFAIL);	}	addr.sin_family = AF_INET;	addr.sin_addr = hp->h_addrlist[hp->h_index];	/*	**  Determine the port number.	*/	if (port != 0)		addr.sin_port = htons(port);	else		addr.sin_port = htons(IPPORT_SMTP);	if (!hp->h_open || hp->h_port != port)	{		s = openhost(hp, addr);		if (s != EX_OK) return s;	}	*outfile = fdopen(hp->h_fd, "w");	*infile = fdopen(dup(hp->h_fd), "r");	return (EX_OK);}intopenhost(hp, addr)	struct hostinfo *hp;	struct sockaddr_in	addr;{	register int s;	int error_code;	int on = 1;	/*	**  Try to actually open the connection.	*/# ifdef DEBUG	if (tTd(16, 1))		printf("openhost (%x)\n", hp->h_addrlist[hp->h_index].s_addr);# endif DEBUG	if (hp->h_addrlist[hp->h_index].s_addr == INADDR_ANY)		 /*		  * restart the address list search if we hit the end,		  * otherwise use the last one that worked.		  */		hp->h_index = 0;	for ( ;*(int *)&(hp->h_addrlist[hp->h_index]);hp->h_index++) {	addr.sin_addr = hp->h_addrlist[hp->h_index];	s = socket(AF_INET, SOCK_STREAM, 0);	if (s < 0)	{		error_code = errno;	/* Save errno for <failure> */		syserr("makeconnection: no socket");		errno = error_code;	/* Save errno for <failure> */		goto failure;	}# ifdef DEBUG	if (tTd(16, 1))		printf("makeconnection: %d\n", s);	/* turn on network debugging? */	if (tTd(16, 14))	{		int on = 1;		(void) setsockopt(DaemonSocket, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof on);	}# endif DEBUG	if (Verbose) {		printf("Trying %s... ", inet_ntoa(addr.sin_addr) );		fflush(stdout);	}	(void) setsockopt(DaemonSocket, SOL_SOCKET, SO_KEEPALIVE,				 on, sizeof(on));	if (CurEnv->e_xfp)	    (void) fflush(CurEnv->e_xfp);	errno = 0;					/* for debugging */	hp->h_tried = 1;		/* We are trying to connect */	if (connect(s, &addr, sizeof addr) < 0)	{		/* failure, decide if temporary or not */	failure:		error_code = errno;		(void) close(s);	/* Free the socket */		if (Verbose)		    printf("%s\r\n", errstring(error_code) );		errno = error_code;		switch (errno)		{		  case ETIMEDOUT:		  	errno = EHOSTDOWN;	/* for a better message */		  case EISCONN:		  case EINPROGRESS:		  case EALREADY:		  case EADDRINUSE:		  case EHOSTDOWN:		  case ENETDOWN:		  case ENETRESET:		  case ENOBUFS:		  case ECONNREFUSED:		  case ECONNRESET:		  case EHOSTUNREACH:		  case ENETUNREACH:		  case EPERM:			/* there are others, I'm sure..... */			continue;		  default:			return (EX_UNAVAILABLE);		}	}	if (Verbose)	    printf(" connected.\r\n");	/* connection ok, put it into canonical form */	host_from_fd[s] = hp;	/* Create cross reference pointer */	hp->h_port = addr.sin_port;	hp->h_fd = s;		/* Save file descriptor */	hp->h_open = 1;		/* And indicate that it's open */	return (EX_OK);	}		hp->h_down = 1;		/* Mark down host */	hp->h_errno = errno;	/*	** Note that the down flag is never turned off.	** We depend on sendmail's exiting to throw away	** this information.  It should apply to one	** queue run only.	*/	return (EX_TEMPFAIL);}/***  CLOSECONNECTION -- mark an open connection as closed.****	Parameters:**		fd -- the file descriptor of the connection.****	Returns:**		none.****	Side Effects:**		Marks the host (which had a connection opened via**		makeconnection()) as not having a current connection.**		Note that this does not actually close the file**		descriptor.  That's the caller's responsibility.**		Also frees the memory allocated by RealHostName in the**		"newstr()" call above; otherwise queue runners are swap hogs.*/closeconnection(fd)	int fd;{	register struct hostinfo *hp;	if (fd < NOFILE) {		hp = host_from_fd[fd];		if (hp != NULL && hp->h_open) {			hp->h_open = 0;		}		host_from_fd[fd] = NULL;		if (RealHostName && RealHostName[0] != '\0') {			free(RealHostName);			RealHostName = "";		}	}}/***  MYHOSTNAME -- return the name of this host.****	Parameters:**		hostbuf -- a place to return the name of this host.**		size -- the size of hostbuf.****	Returns:**		A list of aliases for this host.****	Side Effects:**		none.*/char **myhostname(hostbuf, size)	char hostbuf[];	int size;{	extern struct hostent *gethostbyname();	struct hostent *hp;	static char *nicknames[MAXATOM];	register char **avp, *thisname;	int s, n;        struct ifconf ifc;        struct ifreq *ifr;	char interfacebuf[1024];	if (gethostname(hostbuf, size) < 0)	{		(void) strcpy(hostbuf, "localhost");	}	hp = gethostbyname(hostbuf);	if (hp == NULL)		return (NULL);	(void) strncpy(hostbuf, hp->h_name, size-1);	for (avp=nicknames;*hp->h_aliases;)		*avp++ = *hp->h_aliases++;	*avp = NULL;	s = socket(AF_INET, SOCK_DGRAM, 0);	if (s == -1)		return (nicknames);        ifc.ifc_len = sizeof(interfacebuf);        ifc.ifc_buf = interfacebuf;	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0)		return (nicknames);        ifr = ifc.ifc_req;        for (n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) {		char thisbuf[256];				if (ifr->ifr_addr.sa_family != AF_INET)			continue;		(void) sprintf(thisbuf, "[%s]", inet_ntoa(	((struct sockaddr_in *)(&ifr->ifr_addr))->sin_addr));		thisname = newstr(thisbuf);		*avp++ = thisname;	}	*avp = NULL;	return (nicknames);}/* *  MAPHOSTNAME -- turn a hostname into canonical form * *	Parameters: *		hbuf -- a buffer containing a hostname. *		hbsize -- the size of hbuf. * *	Returns: *		none. * *	Side Effects: *		Looks up the host specified in hbuf.  If it is not *		the canonical name for that host, replace it with *		the canonical name.  If the name is unknown, or it *		is already the canonical name, leave it unchanged. */maphostname(hbuf, hbsize)	char *hbuf;	int hbsize;{	register struct hostent *hp;	extern struct hostent *gethostbyname();	EVENT *ev;	/*	 *  If first character is a bracket, then it is an address	 *  lookup.  Address is copied into a temporary buffer to	 *  strip the brackets and to preserve hbuf if address is	 *  unknown.	*/	if (*hbuf == '[')	{		extern struct hostent *gethostbyaddr();		u_long in_addr;		char ptr[256];		char *bptr;		(void) strcpy(ptr, hbuf);		bptr = index(ptr,']');		*bptr = '\0';		in_addr = inet_addr(&ptr[1]);		if (setjmp(NameTimeout) != 0) {			hp = NULL;		}		else {			ev = setevent(nametime, nametimeout, 0);			hp = gethostbyaddr((char *) &in_addr, 				sizeof(struct in_addr), AF_INET);			clrevent(ev);		}	}	else	{		makelower(hbuf);#ifdef MXDOMAIN		getcanonname(hbuf, hbsize);		return;#else MXDOMAIN		/* determine host name with timeout */		if (setjmp(NameTimeout) != 0) {			hp = NULL;		}		else {			ev = setevent(nametime, nametimeout, 0);			hp = gethostbyname(hbuf);			clrevent(ev);		}#endif	}	if (hp != NULL)	{		int i = strlen(hp->h_name);		if (i >= hbsize)			hp->h_name[hbsize - 1] = '\0';		(void) strcpy(hbuf, hp->h_name);	}}# else DAEMON/* code for systems without sophisticated networking *//* *  MYHOSTNAME -- stub version for case of no daemon code. * *	Can't convert to upper case here because might be a UUCP name. * *	Mark, you can change this to be anything you want...... */char **myhostname(hostbuf, size)	char hostbuf[];	int size;{	register FILE *f;	hostbuf[0] = '\0';	f = fopen("/usr/include/whoami", "r");	if (f != NULL)	{		(void) fgets(hostbuf, size, f);		fixcrlf(hostbuf, TRUE);		(void) fclose(f);	}	return (NULL);}/* *  MAPHOSTNAME -- turn a hostname into canonical form * *	Parameters: *		hbuf -- a buffer containing a hostname. *		hbsize -- the size of hbuf. * *	Returns: *		none. * *	Side Effects: *		Looks up the host specified in hbuf.  If it is not *		the canonical name for that host, replace it with *		the canonical name.  If the name is unknown, or it *		is already the canonical name, leave it unchanged. *//*ARGSUSED*/maphostname(hbuf, hbsize)	char *hbuf;	int hbsize;{	return;}#endif DAEMON

⌨️ 快捷键说明

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