xref: /original-bsd/usr.sbin/sendmail/src/daemon.c (revision 99f7cf32)
17aa493c5Seric # include <errno.h>
27fa39d90Seric # include "sendmail.h"
37fa39d90Seric 
4d0a9e852Seric #ifndef DAEMON
5*99f7cf32Seric SCCSID(@(#)daemon.c	4.11		08/11/84	(w/o daemon mode));
6d0a9e852Seric #else
7d0a9e852Seric 
8d0a9e852Seric #include <sys/socket.h>
91c71e510Seric #include <netinet/in.h>
101c71e510Seric #include <netdb.h>
111e1663f7Swnj #include <sys/wait.h>
12d0a9e852Seric 
13*99f7cf32Seric SCCSID(@(#)daemon.c	4.11		08/11/84	(with daemon mode));
147fa39d90Seric 
157fa39d90Seric /*
167fa39d90Seric **  DAEMON.C -- routines to use when running as a daemon.
1747b12ae1Seric **
1847b12ae1Seric **	This entire file is highly dependent on the 4.2 BSD
1947b12ae1Seric **	interprocess communication primitives.  No attempt has
2047b12ae1Seric **	been made to make this file portable to Version 7,
2147b12ae1Seric **	Version 6, MPX files, etc.  If you should try such a
2247b12ae1Seric **	thing yourself, I recommend chucking the entire file
2347b12ae1Seric **	and starting from scratch.  Basic semantics are:
2447b12ae1Seric **
2547b12ae1Seric **	getrequests()
2647b12ae1Seric **		Opens a port and initiates a connection.
2747b12ae1Seric **		Returns in a child.  Must set InChannel and
2847b12ae1Seric **		OutChannel appropriately.
29b7d7afcbSeric **	clrdaemon()
30b7d7afcbSeric **		Close any open files associated with getting
31b7d7afcbSeric **		the connection; this is used when running the queue,
32b7d7afcbSeric **		etc., to avoid having extra file descriptors during
33b7d7afcbSeric **		the queue run and to avoid confusing the network
34b7d7afcbSeric **		code (if it cares).
3547b12ae1Seric **	makeconnection(host, port, outfile, infile)
3647b12ae1Seric **		Make a connection to the named host on the given
3747b12ae1Seric **		port.  Set *outfile and *infile to the files
3847b12ae1Seric **		appropriate for communication.  Returns zero on
3947b12ae1Seric **		success, else an exit status describing the
4047b12ae1Seric **		error.
4147b12ae1Seric **
4247b12ae1Seric **	The semantics of both of these should be clean.
437fa39d90Seric */
447fa39d90Seric /*
457fa39d90Seric **  GETREQUESTS -- open mail IPC port and get requests.
467fa39d90Seric **
477fa39d90Seric **	Parameters:
487fa39d90Seric **		none.
497fa39d90Seric **
507fa39d90Seric **	Returns:
517fa39d90Seric **		none.
527fa39d90Seric **
537fa39d90Seric **	Side Effects:
547fa39d90Seric **		Waits until some interesting activity occurs.  When
557fa39d90Seric **		it does, a child is created to process it, and the
567fa39d90Seric **		parent waits for completion.  Return from this
57147303b1Seric **		routine is always in the child.  The file pointers
58147303b1Seric **		"InChannel" and "OutChannel" should be set to point
59147303b1Seric **		to the communication channel.
607fa39d90Seric */
617fa39d90Seric 
62b7d7afcbSeric struct sockaddr_in	SendmailAddress;/* internet address of sendmail */
639478786eSeric 
64b7d7afcbSeric int	DaemonSocket	= -1;		/* fd describing socket */
65be388505Seric char	*NetName;			/* name of home (local?) network */
661c71e510Seric 
677fa39d90Seric getrequests()
687fa39d90Seric {
691c71e510Seric 	int t;
702554d49fSeric 	union wait status;
711c71e510Seric 	register struct servent *sp;
72eb889047Seric 
73a8268164Seric 	/*
741c71e510Seric 	**  Set up the address for the mailer.
75eb889047Seric 	*/
76eb889047Seric 
771c71e510Seric 	sp = getservbyname("smtp", "tcp");
781c71e510Seric 	if (sp == NULL)
79d0a9e852Seric 	{
801c71e510Seric 		syserr("server \"smtp\" unknown");
81a1961f2aSeric 		goto severe;
821c71e510Seric 	}
831c71e510Seric 	SendmailAddress.sin_family = AF_INET;
841c71e510Seric 	SendmailAddress.sin_addr.s_addr = INADDR_ANY;
85f43fa3c2Ssam 	SendmailAddress.sin_port = sp->s_port;
861c71e510Seric 
871c71e510Seric 	/*
881c71e510Seric 	**  Try to actually open the connection.
891c71e510Seric 	*/
901c71e510Seric 
911c71e510Seric # ifdef DEBUG
921c71e510Seric 	if (tTd(15, 1))
931c71e510Seric 		printf("getrequests: port 0x%x\n", SendmailAddress.sin_port);
941c71e510Seric # endif DEBUG
951c71e510Seric 
961c71e510Seric 	/* get a socket for the SMTP connection */
97b7d7afcbSeric 	DaemonSocket = socket(AF_INET, SOCK_STREAM, 0, 0);
98b7d7afcbSeric 	if (DaemonSocket < 0)
991c71e510Seric 	{
1001c71e510Seric 		/* probably another daemon already */
1011c71e510Seric 		syserr("getrequests: can't create socket");
1021c71e510Seric 	  severe:
103b0ba8827Seric # ifdef LOG
104b0ba8827Seric 		if (LogLevel > 0)
105b0ba8827Seric 			syslog(LOG_SALERT, "cannot get connection");
106b0ba8827Seric # endif LOG
10747b12ae1Seric 		finis();
108d0a9e852Seric 	}
1091b6e4a15Seric 
1101b6e4a15Seric #ifdef DEBUG
1111b6e4a15Seric 	/* turn on network debugging? */
1121b6e4a15Seric 	if (tTd(15, 15))
1131b6e4a15Seric 		(void) setsockopt(DaemonSocket, SOL_SOCKET, SO_DEBUG, 0, 0);
1141b6e4a15Seric #endif DEBUG
1151b6e4a15Seric 
116b7d7afcbSeric 	if (bind(DaemonSocket, &SendmailAddress, sizeof SendmailAddress, 0) < 0)
1171c71e510Seric 	{
1181c71e510Seric 		syserr("getrequests: cannot bind");
119b7d7afcbSeric 		(void) close(DaemonSocket);
1201c71e510Seric 		goto severe;
1211c71e510Seric 	}
122b7d7afcbSeric 	listen(DaemonSocket, 10);
1231c71e510Seric 
1241c71e510Seric # ifdef DEBUG
1251c71e510Seric 	if (tTd(15, 1))
126b7d7afcbSeric 		printf("getrequests: %d\n", DaemonSocket);
1271c71e510Seric # endif DEBUG
1281c71e510Seric 
1291c71e510Seric 	for (;;)
1301c71e510Seric 	{
1313a099713Seric 		register int pid;
132a44d5a5eSeric 		auto int lotherend;
133a44d5a5eSeric 		struct sockaddr_in otherend;
1343a099713Seric 		extern int RefuseLA;
1353a099713Seric 
1363a099713Seric 		/* see if we are rejecting connections */
1373a099713Seric 		while (getla() > RefuseLA)
1383a099713Seric 			sleep(5);
139a44d5a5eSeric 
1401c71e510Seric 		/* wait for a connection */
1411c71e510Seric 		do
1421c71e510Seric 		{
1431c71e510Seric 			errno = 0;
1441c71e510Seric 			lotherend = sizeof otherend;
145b7d7afcbSeric 			t = accept(DaemonSocket, &otherend, &lotherend, 0);
1461c71e510Seric 		} while (t < 0 && errno == EINTR);
1471c71e510Seric 		if (t < 0)
1481c71e510Seric 		{
1491c71e510Seric 			syserr("getrequests: accept");
1501c71e510Seric 			sleep(5);
1511c71e510Seric 			continue;
1521c71e510Seric 		}
153d0a9e852Seric 
154d0a9e852Seric 		/*
155d0a9e852Seric 		**  Create a subprocess to process the mail.
156d0a9e852Seric 		*/
157d0a9e852Seric 
158d0a9e852Seric # ifdef DEBUG
15961e4310fSeric 		if (tTd(15, 2))
1601c71e510Seric 			printf("getrequests: forking (fd = %d)\n", t);
161d0a9e852Seric # endif DEBUG
162eb889047Seric 
163a8268164Seric 		pid = fork();
164a8268164Seric 		if (pid < 0)
165a8268164Seric 		{
166a8268164Seric 			syserr("daemon: cannot fork");
167a8268164Seric 			sleep(10);
1681c71e510Seric 			(void) close(t);
169a8268164Seric 			continue;
170a8268164Seric 		}
171a8268164Seric 
172a8268164Seric 		if (pid == 0)
173a8268164Seric 		{
174a44d5a5eSeric 			extern struct hostent *gethostbyaddr();
175a44d5a5eSeric 			register struct hostent *hp;
176a44d5a5eSeric 			extern char *RealHostName;	/* srvrsmtp.c */
177a44d5a5eSeric 			char buf[MAXNAME];
178a44d5a5eSeric 
179a8268164Seric 			/*
180a8268164Seric 			**  CHILD -- return to caller.
181a44d5a5eSeric 			**	Collect verified idea of sending host.
182a8268164Seric 			**	Verify calling user id if possible here.
183a8268164Seric 			*/
184a8268164Seric 
185a44d5a5eSeric 			/* determine host name */
186a44d5a5eSeric 			hp = gethostbyaddr(&otherend.sin_addr, sizeof otherend.sin_addr, AF_INET);
187a44d5a5eSeric 			if (hp != NULL)
188be388505Seric 			{
189be388505Seric 				strcpy(buf, hp->h_name);
190be388505Seric 				if (NetName != NULL && NetName[0] != '\0' &&
1917dcf5c8cSeric 				    index(hp->h_name, '.') == NULL)
192be388505Seric 				{
193be388505Seric 					strcat(buf, ".");
194be388505Seric 					strcat(buf, NetName);
195be388505Seric 				}
196be388505Seric 			}
197a44d5a5eSeric 			else
19829dcf4baSeric 			{
19929dcf4baSeric 				extern char *inet_ntoa();
20029dcf4baSeric 
20129dcf4baSeric 				/* produce a dotted quad */
20229dcf4baSeric 				(void) sprintf(buf, "[%s]",
20329dcf4baSeric 					inet_ntoa(otherend.sin_addr));
20429dcf4baSeric 			}
20529dcf4baSeric 
20629dcf4baSeric 			/* should we check for illegal connection here? XXX */
20729dcf4baSeric 
208a44d5a5eSeric 			RealHostName = newstr(buf);
209a44d5a5eSeric 
210b7d7afcbSeric 			(void) close(DaemonSocket);
2111c71e510Seric 			InChannel = fdopen(t, "r");
2121c71e510Seric 			OutChannel = fdopen(t, "w");
213d0a9e852Seric # ifdef DEBUG
21461e4310fSeric 			if (tTd(15, 2))
215d0a9e852Seric 				printf("getreq: returning\n");
216d0a9e852Seric # endif DEBUG
217252c8a22Seric # ifdef LOG
218252c8a22Seric 			if (LogLevel > 11)
219252c8a22Seric 				syslog(LOG_DEBUG, "connected, pid=%d", getpid());
220252c8a22Seric # endif LOG
221a8268164Seric 			return;
222a8268164Seric 		}
223a8268164Seric 
224a8268164Seric 		/*
225a8268164Seric 		**  PARENT -- wait for child to terminate.
226a8268164Seric 		**	Perhaps we should allow concurrent processing?
227a8268164Seric 		*/
228a8268164Seric 
229d0a9e852Seric # ifdef DEBUG
23061e4310fSeric 		if (tTd(15, 2))
231d0a9e852Seric 		{
232d0a9e852Seric 			sleep(2);
233d0a9e852Seric 			printf("getreq: parent waiting\n");
234d0a9e852Seric 		}
235d0a9e852Seric # endif DEBUG
236d0a9e852Seric 
2372554d49fSeric 		/* close the port so that others will hang (for a while) */
2381c71e510Seric 		(void) close(t);
2392554d49fSeric 
240105e901cSeric 		/* pick up old zombies */
241105e901cSeric 		while (wait3(&status, WNOHANG, 0) > 0)
242105e901cSeric 			continue;
243a8268164Seric 	}
244147303b1Seric 	/*NOTREACHED*/
2457fa39d90Seric }
246d0a9e852Seric /*
247b7d7afcbSeric **  CLRDAEMON -- reset the daemon connection
248b7d7afcbSeric **
249b7d7afcbSeric **	Parameters:
250b7d7afcbSeric **		none.
251b7d7afcbSeric **
252b7d7afcbSeric **	Returns:
253b7d7afcbSeric **		none.
254b7d7afcbSeric **
255b7d7afcbSeric **	Side Effects:
256b7d7afcbSeric **		releases any resources used by the passive daemon.
257b7d7afcbSeric */
258b7d7afcbSeric 
259b7d7afcbSeric clrdaemon()
260b7d7afcbSeric {
261b7d7afcbSeric 	if (DaemonSocket >= 0)
262b7d7afcbSeric 		(void) close(DaemonSocket);
263b7d7afcbSeric 	DaemonSocket = -1;
264b7d7afcbSeric }
265b7d7afcbSeric /*
2667aa493c5Seric **  MAKECONNECTION -- make a connection to an SMTP socket on another machine.
2677aa493c5Seric **
2687aa493c5Seric **	Parameters:
2697aa493c5Seric **		host -- the name of the host.
27048ff0a9dSeric **		port -- the port number to connect to.
2717aa493c5Seric **		outfile -- a pointer to a place to put the outfile
2727aa493c5Seric **			descriptor.
2737aa493c5Seric **		infile -- ditto for infile.
2747aa493c5Seric **
2757aa493c5Seric **	Returns:
2767aa493c5Seric **		An exit code telling whether the connection could be
2777aa493c5Seric **			made and if not why not.
2787aa493c5Seric **
2797aa493c5Seric **	Side Effects:
2807aa493c5Seric **		none.
2817aa493c5Seric */
2827aa493c5Seric 
28348ff0a9dSeric makeconnection(host, port, outfile, infile)
2847aa493c5Seric 	char *host;
285210215eaSeric 	u_short port;
2867aa493c5Seric 	FILE **outfile;
2877aa493c5Seric 	FILE **infile;
2887aa493c5Seric {
2897aa493c5Seric 	register int s;
2907aa493c5Seric 
2917aa493c5Seric 	/*
2927aa493c5Seric 	**  Set up the address for the mailer.
29371096d12Seric 	**	Accept "[a.b.c.d]" syntax for host name.
2947aa493c5Seric 	*/
2957aa493c5Seric 
29671096d12Seric 	if (host[0] == '[')
29771096d12Seric 	{
298a44d5a5eSeric 		long hid;
299a44d5a5eSeric 		register char *p = index(host, ']');
30071096d12Seric 
301a44d5a5eSeric 		if (p != NULL)
30271096d12Seric 		{
303a44d5a5eSeric 			*p = '\0';
304a44d5a5eSeric 			hid = inet_addr(&host[1]);
305a44d5a5eSeric 			*p = ']';
30671096d12Seric 		}
307a44d5a5eSeric 		if (p == NULL || hid == -1)
30871096d12Seric 		{
30971096d12Seric 			usrerr("Invalid numeric domain spec \"%s\"", host);
31071096d12Seric 			return (EX_NOHOST);
31171096d12Seric 		}
31271096d12Seric 		SendmailAddress.sin_addr.s_addr = hid;
31371096d12Seric 	}
3141c71e510Seric 	else
3151c71e510Seric 	{
3161c71e510Seric 		register struct hostent *hp = gethostbyname(host);
3171c71e510Seric 
318a44d5a5eSeric 		if (hp == NULL)
3197aa493c5Seric 			return (EX_NOHOST);
32029dcf4baSeric 		bcopy(hp->h_addr, (char *) &SendmailAddress.sin_addr, hp->h_length);
3211c71e510Seric 	}
3221c71e510Seric 
3231c71e510Seric 	/*
3241c71e510Seric 	**  Determine the port number.
3251c71e510Seric 	*/
3261c71e510Seric 
327fd7c0790Seric 	if (port != 0)
328fd7c0790Seric 		SendmailAddress.sin_port = htons(port);
329fd7c0790Seric 	else
3301c71e510Seric 	{
3311c71e510Seric 		register struct servent *sp = getservbyname("smtp", "tcp");
3321c71e510Seric 
3331c71e510Seric 		if (sp == NULL)
3341c71e510Seric 		{
3351c71e510Seric 			syserr("makeconnection: server \"smtp\" unknown");
3361c71e510Seric 			return (EX_OSFILE);
3371c71e510Seric 		}
338fd7c0790Seric 		SendmailAddress.sin_port = sp->s_port;
3391c71e510Seric 	}
3407aa493c5Seric 
3417aa493c5Seric 	/*
3427aa493c5Seric 	**  Try to actually open the connection.
3437aa493c5Seric 	*/
3447aa493c5Seric 
3457aa493c5Seric # ifdef DEBUG
34661e4310fSeric 	if (tTd(16, 1))
3477aa493c5Seric 		printf("makeconnection (%s)\n", host);
3487aa493c5Seric # endif DEBUG
3497aa493c5Seric 
35010d42158Seric 	s = socket(AF_INET, SOCK_STREAM, 0, 0);
3517aa493c5Seric 	if (s < 0)
3527aa493c5Seric 	{
3537aa493c5Seric 		syserr("makeconnection: no socket");
3547aa493c5Seric 		goto failure;
3557aa493c5Seric 	}
3567aa493c5Seric 
3577aa493c5Seric # ifdef DEBUG
35861e4310fSeric 	if (tTd(16, 1))
3597aa493c5Seric 		printf("makeconnection: %d\n", s);
3601b6e4a15Seric 
3611b6e4a15Seric 	/* turn on network debugging? */
3621b6e4a15Seric 	if (tTd(16, 14))
3631b6e4a15Seric 		(void) setsockopt(s, SOL_SOCKET, SO_DEBUG, 0, 0);
3647aa493c5Seric # endif DEBUG
365877a6142Seric 	(void) fflush(CurEnv->e_xfp);			/* for debugging */
3664bd6a662Seric 	errno = 0;					/* for debugging */
3671c71e510Seric 	SendmailAddress.sin_family = AF_INET;
36810d42158Seric 	if (connect(s, &SendmailAddress, sizeof SendmailAddress, 0) < 0)
3697aa493c5Seric 	{
3707aa493c5Seric 		/* failure, decide if temporary or not */
3717aa493c5Seric 	failure:
3727aa493c5Seric 		switch (errno)
3737aa493c5Seric 		{
3747aa493c5Seric 		  case EISCONN:
3757aa493c5Seric 		  case ETIMEDOUT:
376292668b9Seric 		  case EINPROGRESS:
377292668b9Seric 		  case EALREADY:
378292668b9Seric 		  case EADDRINUSE:
37936bd23a8Seric 		  case EHOSTDOWN:
380292668b9Seric 		  case ENETDOWN:
381292668b9Seric 		  case ENETRESET:
382292668b9Seric 		  case ENOBUFS:
383a1645df8Seric 		  case ECONNREFUSED:
384efe49624Seric 		  case ECONNRESET:
385cae8261aSeric 		  case EHOSTUNREACH:
386dca8e1f7Seric 		  case ENETUNREACH:
3877aa493c5Seric 			/* there are others, I'm sure..... */
38829dcf4baSeric 			CurEnv->e_flags &= ~EF_FATALERRS;
3897aa493c5Seric 			return (EX_TEMPFAIL);
3907aa493c5Seric 
391a44d5a5eSeric 		  case EPERM:
392a44d5a5eSeric 			/* why is this happening? */
393a44d5a5eSeric 			syserr("makeconnection: funny failure, addr=%lx, port=%x",
394a44d5a5eSeric 				SendmailAddress.sin_addr.s_addr, SendmailAddress.sin_port);
3954bd6a662Seric 			return (EX_TEMPFAIL);
396a44d5a5eSeric 
3977aa493c5Seric 		  default:
3987aa493c5Seric 			return (EX_UNAVAILABLE);
3997aa493c5Seric 		}
4007aa493c5Seric 	}
4017aa493c5Seric 
4027aa493c5Seric 	/* connection ok, put it into canonical form */
4037aa493c5Seric 	*outfile = fdopen(s, "w");
4047aa493c5Seric 	*infile = fdopen(s, "r");
4057aa493c5Seric 
406dca8e1f7Seric 	return (EX_OK);
4077aa493c5Seric }
408444eaf03Seric /*
409444eaf03Seric **  MYHOSTNAME -- return the name of this host.
410444eaf03Seric **
411444eaf03Seric **	Parameters:
412444eaf03Seric **		hostbuf -- a place to return the name of this host.
413897f1869Seric **		size -- the size of hostbuf.
414444eaf03Seric **
415444eaf03Seric **	Returns:
416444eaf03Seric **		A list of aliases for this host.
417444eaf03Seric **
418444eaf03Seric **	Side Effects:
419444eaf03Seric **		none.
420444eaf03Seric */
421444eaf03Seric 
422444eaf03Seric char **
423897f1869Seric myhostname(hostbuf, size)
424444eaf03Seric 	char hostbuf[];
425897f1869Seric 	int size;
426444eaf03Seric {
427444eaf03Seric 	extern struct hostent *gethostbyname();
428a44d5a5eSeric 	struct hostent *hp;
429444eaf03Seric 
4309bc0e008Seric 	gethostname(hostbuf, size);
431a44d5a5eSeric 	hp = gethostbyname(hostbuf);
432a44d5a5eSeric 	if (hp != NULL)
4337364df9fSeric 	{
4347364df9fSeric 		strcpy(hostbuf, hp->h_name);
435a44d5a5eSeric 		return (hp->h_aliases);
4367364df9fSeric 	}
437444eaf03Seric 	else
438444eaf03Seric 		return (NULL);
439444eaf03Seric }
440*99f7cf32Seric /*
441*99f7cf32Seric **  MAPHOSTNAME -- turn a hostname into canonical form
442*99f7cf32Seric **
443*99f7cf32Seric **	Parameters:
444*99f7cf32Seric **		hbuf -- a buffer containing a hostname.
445*99f7cf32Seric **		hbsize -- the size of hbuf.
446*99f7cf32Seric **
447*99f7cf32Seric **	Returns:
448*99f7cf32Seric **		none.
449*99f7cf32Seric **
450*99f7cf32Seric **	Side Effects:
451*99f7cf32Seric **		Looks up the host specified in hbuf.  If it is not
452*99f7cf32Seric **		the canonical name for that host, replace it with
453*99f7cf32Seric **		the canonical name.  If the name is unknown, or it
454*99f7cf32Seric **		is already the canonical name, leave it unchanged.
455*99f7cf32Seric */
456444eaf03Seric 
457*99f7cf32Seric maphostname(hbuf, hbsize)
458*99f7cf32Seric 	char *hbuf;
459*99f7cf32Seric 	int hbsize;
460*99f7cf32Seric {
461*99f7cf32Seric 	register struct hostent *hp;
462*99f7cf32Seric 	extern struct hostent *gethostbyname();
463*99f7cf32Seric 
464*99f7cf32Seric 	makelower(hbuf);
465*99f7cf32Seric 	hp = gethostbyname(hbuf);
466*99f7cf32Seric 	if (hp != NULL)
467*99f7cf32Seric 	{
468*99f7cf32Seric 		int i = strlen(hp->h_name);
469*99f7cf32Seric 
470*99f7cf32Seric 		if (i >= hbsize)
471*99f7cf32Seric 			hp->h_name[--i] = '\0';
472*99f7cf32Seric 		strcpy(hbuf, hp->h_name);
473*99f7cf32Seric 	}
474*99f7cf32Seric }
475*99f7cf32Seric 
476444eaf03Seric # else DAEMON
477*99f7cf32Seric /* code for systems without sophisticated networking */
478444eaf03Seric 
479444eaf03Seric /*
480444eaf03Seric **  MYHOSTNAME -- stub version for case of no daemon code.
48121e9914dSeric **
48221e9914dSeric **	Can't convert to upper case here because might be a UUCP name.
483897f1869Seric **
484897f1869Seric **	Mark, you can change this to be anything you want......
485444eaf03Seric */
486444eaf03Seric 
487444eaf03Seric char **
488897f1869Seric myhostname(hostbuf, size)
489444eaf03Seric 	char hostbuf[];
490897f1869Seric 	int size;
491444eaf03Seric {
492444eaf03Seric 	register FILE *f;
493444eaf03Seric 
494444eaf03Seric 	hostbuf[0] = '\0';
495444eaf03Seric 	f = fopen("/usr/include/whoami", "r");
496444eaf03Seric 	if (f != NULL)
497444eaf03Seric 	{
498897f1869Seric 		(void) fgets(hostbuf, size, f);
499444eaf03Seric 		fixcrlf(hostbuf, TRUE);
500444eaf03Seric 		(void) fclose(f);
501444eaf03Seric 	}
502444eaf03Seric 	return (NULL);
503444eaf03Seric }
504*99f7cf32Seric /*
505*99f7cf32Seric **  MAPHOSTNAME -- turn a hostname into canonical form
506*99f7cf32Seric **
507*99f7cf32Seric **	Parameters:
508*99f7cf32Seric **		hbuf -- a buffer containing a hostname.
509*99f7cf32Seric **		hbsize -- the size of hbuf.
510*99f7cf32Seric **
511*99f7cf32Seric **	Returns:
512*99f7cf32Seric **		none.
513*99f7cf32Seric **
514*99f7cf32Seric **	Side Effects:
515*99f7cf32Seric **		Looks up the host specified in hbuf.  If it is not
516*99f7cf32Seric **		the canonical name for that host, replace it with
517*99f7cf32Seric **		the canonical name.  If the name is unknown, or it
518*99f7cf32Seric **		is already the canonical name, leave it unchanged.
519*99f7cf32Seric */
520*99f7cf32Seric 
521*99f7cf32Seric /*ARGSUSED*/
522*99f7cf32Seric maphostname(hbuf, hbsize)
523*99f7cf32Seric 	char *hbuf;
524*99f7cf32Seric 	int hbsize;
525*99f7cf32Seric {
526*99f7cf32Seric 	return;
527*99f7cf32Seric }
528*99f7cf32Seric 
529d0a9e852Seric 
530d0a9e852Seric #endif DAEMON
531