talkd.c revision 45422
11592Srgrimes/*
21592Srgrimes * Copyright (c) 1983, 1993
31592Srgrimes *	The Regents of the University of California.  All rights reserved.
41592Srgrimes *
51592Srgrimes * Redistribution and use in source and binary forms, with or without
61592Srgrimes * modification, are permitted provided that the following conditions
71592Srgrimes * are met:
81592Srgrimes * 1. Redistributions of source code must retain the above copyright
91592Srgrimes *    notice, this list of conditions and the following disclaimer.
101592Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111592Srgrimes *    notice, this list of conditions and the following disclaimer in the
121592Srgrimes *    documentation and/or other materials provided with the distribution.
131592Srgrimes * 3. All advertising materials mentioning features or use of this software
141592Srgrimes *    must display the following acknowledgement:
151592Srgrimes *	This product includes software developed by the University of
161592Srgrimes *	California, Berkeley and its contributors.
171592Srgrimes * 4. Neither the name of the University nor the names of its contributors
181592Srgrimes *    may be used to endorse or promote products derived from this software
191592Srgrimes *    without specific prior written permission.
201592Srgrimes *
211592Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221592Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231592Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241592Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251592Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261592Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271592Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281592Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291592Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301592Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311592Srgrimes * SUCH DAMAGE.
321592Srgrimes */
331592Srgrimes
341592Srgrimes#ifndef lint
3531491Scharnierstatic const char copyright[] =
361592Srgrimes"@(#) Copyright (c) 1983, 1993\n\
371592Srgrimes	The Regents of the University of California.  All rights reserved.\n";
381592Srgrimes#endif /* not lint */
391592Srgrimes
401592Srgrimes#ifndef lint
4131491Scharnier#if 0
421592Srgrimesstatic char sccsid[] = "@(#)talkd.c	8.1 (Berkeley) 6/4/93";
4331491Scharnier#endif
4431491Scharnierstatic const char rcsid[] =
4545422Sbrian	"$Id: talkd.c,v 1.9 1998/12/01 21:12:57 dillon Exp $";
461592Srgrimes#endif /* not lint */
471592Srgrimes
481592Srgrimes/*
491592Srgrimes * The top level of the daemon, the format is heavily borrowed
508870Srgrimes * from rwhod.c. Basically: find out who and where you are;
511592Srgrimes * disconnect all descriptors and ttys, and then endless
521592Srgrimes * loop on waiting for and processing requests
531592Srgrimes */
541592Srgrimes#include <sys/types.h>
551592Srgrimes#include <sys/socket.h>
565111Sache#include <sys/param.h>
571592Srgrimes#include <protocols/talkd.h>
5831491Scharnier#include <err.h>
5931491Scharnier#include <errno.h>
6031491Scharnier#include <paths.h>
611592Srgrimes#include <signal.h>
6231491Scharnier#include <stdio.h>
6331491Scharnier#include <stdlib.h>
6431491Scharnier#include <string.h>
651592Srgrimes#include <syslog.h>
661592Srgrimes#include <time.h>
671592Srgrimes#include <unistd.h>
681592Srgrimes
691592SrgrimesCTL_MSG		request;
701592SrgrimesCTL_RESPONSE	response;
711592Srgrimes
721592Srgrimesint	sockt;
731592Srgrimesint	debug = 0;
741592Srgrimeslong	lastmsgtime;
751592Srgrimes
7645422Sbrianchar    hostname[MAXHOSTNAMELEN];
771592Srgrimes
781592Srgrimes#define TIMEOUT 30
791592Srgrimes#define MAXIDLE 120
801592Srgrimes
8131491Scharniervoid process_request __P((CTL_MSG *, CTL_RESPONSE *));
8231491Scharniervoid timeout();
8331491Scharnier
8431491Scharnierint
851592Srgrimesmain(argc, argv)
861592Srgrimes	int argc;
871592Srgrimes	char *argv[];
881592Srgrimes{
891592Srgrimes	register CTL_MSG *mp = &request;
901592Srgrimes	int cc;
911592Srgrimes
9241440Sdillon#ifdef NOTDEF
9341440Sdillon	/*
9441440Sdillon	 * removed so ntalkd can run in tty sandbox
9541440Sdillon	 */
9631491Scharnier	if (getuid())
9731491Scharnier		errx(1, "getuid: not super-user");
9841440Sdillon#endif
991592Srgrimes	openlog("talkd", LOG_PID, LOG_DAEMON);
10045422Sbrian	if (gethostname(hostname, sizeof(hostname) - 1) < 0) {
1011592Srgrimes		syslog(LOG_ERR, "gethostname: %m");
1021592Srgrimes		_exit(1);
1031592Srgrimes	}
10445422Sbrian	hostname[sizeof(hostname) - 1] = '\0';
1051592Srgrimes	if (chdir(_PATH_DEV) < 0) {
1061592Srgrimes		syslog(LOG_ERR, "chdir: %s: %m", _PATH_DEV);
1071592Srgrimes		_exit(1);
1081592Srgrimes	}
1091592Srgrimes	if (argc > 1 && strcmp(argv[1], "-d") == 0)
1101592Srgrimes		debug = 1;
1111592Srgrimes	signal(SIGALRM, timeout);
1121592Srgrimes	alarm(TIMEOUT);
1131592Srgrimes	for (;;) {
1141592Srgrimes		cc = recv(0, (char *)mp, sizeof (*mp), 0);
1151592Srgrimes		if (cc != sizeof (*mp)) {
1161592Srgrimes			if (cc < 0 && errno != EINTR)
1171592Srgrimes				syslog(LOG_WARNING, "recv: %m");
1181592Srgrimes			continue;
1191592Srgrimes		}
1201592Srgrimes		lastmsgtime = time(0);
1211592Srgrimes		process_request(mp, &response);
1221592Srgrimes		/* can block here, is this what I want? */
12321838Spst		mp->ctl_addr.sa_family = htons(mp->ctl_addr.sa_family);
1241592Srgrimes		cc = sendto(sockt, (char *)&response,
1251592Srgrimes		    sizeof (response), 0, (struct sockaddr *)&mp->ctl_addr,
1261592Srgrimes		    sizeof (mp->ctl_addr));
1271592Srgrimes		if (cc != sizeof (response))
1281592Srgrimes			syslog(LOG_WARNING, "sendto: %m");
1291592Srgrimes	}
1301592Srgrimes}
1311592Srgrimes
1321592Srgrimesvoid
1331592Srgrimestimeout()
1341592Srgrimes{
1351592Srgrimes
1361592Srgrimes	if (time(0) - lastmsgtime >= MAXIDLE)
1371592Srgrimes		_exit(0);
1381592Srgrimes	alarm(TIMEOUT);
1391592Srgrimes}
140