1 /* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char copyright[] = 10 "@(#) Copyright (c) 1983, 1993\n\ 11 The Regents of the University of California. All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)talkd.c 8.1 (Berkeley) 06/04/93"; 16 #endif /* not lint */ 17 18 /* 19 * The top level of the daemon, the format is heavily borrowed 20 * from rwhod.c. Basically: find out who and where you are; 21 * disconnect all descriptors and ttys, and then endless 22 * loop on waiting for and processing requests 23 */ 24 #include <sys/types.h> 25 #include <sys/socket.h> 26 #include <protocols/talkd.h> 27 #include <signal.h> 28 #include <syslog.h> 29 #include <time.h> 30 #include <errno.h> 31 #include <unistd.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <paths.h> 36 37 CTL_MSG request; 38 CTL_RESPONSE response; 39 40 int sockt; 41 int debug = 0; 42 void timeout(); 43 long lastmsgtime; 44 45 char hostname[32]; 46 47 #define TIMEOUT 30 48 #define MAXIDLE 120 49 50 main(argc, argv) 51 int argc; 52 char *argv[]; 53 { 54 register CTL_MSG *mp = &request; 55 int cc; 56 57 if (getuid()) { 58 fprintf(stderr, "%s: getuid: not super-user\n", argv[0]); 59 exit(1); 60 } 61 openlog("talkd", LOG_PID, LOG_DAEMON); 62 if (gethostname(hostname, sizeof (hostname) - 1) < 0) { 63 syslog(LOG_ERR, "gethostname: %m"); 64 _exit(1); 65 } 66 if (chdir(_PATH_DEV) < 0) { 67 syslog(LOG_ERR, "chdir: %s: %m", _PATH_DEV); 68 _exit(1); 69 } 70 if (argc > 1 && strcmp(argv[1], "-d") == 0) 71 debug = 1; 72 signal(SIGALRM, timeout); 73 alarm(TIMEOUT); 74 for (;;) { 75 extern int errno; 76 77 cc = recv(0, (char *)mp, sizeof (*mp), 0); 78 if (cc != sizeof (*mp)) { 79 if (cc < 0 && errno != EINTR) 80 syslog(LOG_WARNING, "recv: %m"); 81 continue; 82 } 83 lastmsgtime = time(0); 84 process_request(mp, &response); 85 /* can block here, is this what I want? */ 86 cc = sendto(sockt, (char *)&response, 87 sizeof (response), 0, (struct sockaddr *)&mp->ctl_addr, 88 sizeof (mp->ctl_addr)); 89 if (cc != sizeof (response)) 90 syslog(LOG_WARNING, "sendto: %m"); 91 } 92 } 93 94 void 95 timeout() 96 { 97 98 if (time(0) - lastmsgtime >= MAXIDLE) 99 _exit(0); 100 alarm(TIMEOUT); 101 } 102