116366Skarels #ifndef lint 2*17567Sbloom static char sccsid[] = "@(#)talkd.c 1.4 (Berkeley) 12/20/84"; 316366Skarels #endif 416360Skarels 516366Skarels /* 616366Skarels * The top level of the daemon, the format is heavily borrowed 716366Skarels * from rwhod.c. Basically: find out who and where you are; 816366Skarels * disconnect all descriptors and ttys, and then endless 916366Skarels * loop on waiting for and processing requests 1016360Skarels */ 1116360Skarels #include <stdio.h> 1216360Skarels #include <errno.h> 1316366Skarels #include <signal.h> 1416360Skarels 1516366Skarels #include "ctl.h" 1616360Skarels 1716360Skarels struct sockaddr_in sin = { AF_INET }; 1816360Skarels 1916366Skarels CTL_MSG request; 2016366Skarels CTL_RESPONSE response; 2116360Skarels 2216366Skarels int sockt; 2316366Skarels int debug = 0; 2416467Slayer FILE *debugout; 2516366Skarels int timeout(); 2616366Skarels long lastmsgtime; 2716360Skarels 2816366Skarels char hostname[32]; 2916360Skarels 3016366Skarels #define TIMEOUT 30 3116366Skarels #define MAXIDLE 120 3216366Skarels 3316366Skarels main(argc, argv) 3416366Skarels int argc; 3516366Skarels char *argv[]; 3616360Skarels { 3716366Skarels struct sockaddr_in from; 3816366Skarels int fromlen, cc; 3916467Slayer 4016467Slayer if (debug) 4116467Slayer debugout = (FILE *)fopen ("/usr/tmp/talkd.msgs", "w"); 4216360Skarels 4316366Skarels if (getuid()) { 4416366Skarels fprintf(stderr, "Talkd : not super user\n"); 4516366Skarels exit(1); 4616360Skarels } 4716366Skarels gethostname(hostname, sizeof (hostname)); 4816366Skarels (void) chdir("/dev"); 4916366Skarels signal(SIGALRM, timeout); 5016366Skarels alarm(TIMEOUT); 5116366Skarels for (;;) { 5216366Skarels extern int errno; 5316360Skarels 5416366Skarels fromlen = sizeof(from); 5516366Skarels cc = recvfrom(0, (char *)&request, sizeof (request), 0, 5616366Skarels &from, &fromlen); 5716366Skarels if (cc != sizeof(request)) { 5816366Skarels if (cc < 0 && errno != EINTR) 5916366Skarels perror("recvfrom"); 6016366Skarels continue; 6116366Skarels } 6216366Skarels lastmsgtime = time(0); 6316467Slayer swapmsg(&request); 64*17567Sbloom if (debug) print_request(&request); 6516366Skarels process_request(&request, &response); 6616360Skarels /* can block here, is this what I want? */ 6716366Skarels cc = sendto(sockt, (char *) &response, 6816366Skarels sizeof (response), 0, &request.ctl_addr, 6916366Skarels sizeof (request.ctl_addr)); 7016366Skarels if (cc != sizeof(response)) 7116366Skarels perror("sendto"); 7216360Skarels } 7316360Skarels } 7416360Skarels 7516366Skarels timeout() 7616360Skarels { 7716360Skarels 7816366Skarels if (time(0) - lastmsgtime >= MAXIDLE) 7916366Skarels exit(0); 8016366Skarels alarm(TIMEOUT); 8116360Skarels } 8216467Slayer 8316467Slayer /* 8416467Slayer * heuristic to detect if need to swap bytes 8516467Slayer */ 8616467Slayer 8716467Slayer swapmsg(req) 8816467Slayer CTL_MSG *req; 8916467Slayer { 90*17567Sbloom if (req->ctl_addr.sin_family == ntohs(AF_INET)) { 91*17567Sbloom req->id_num = ntohl(req->id_num); 92*17567Sbloom req->pid = ntohl(req->pid); 93*17567Sbloom req->addr.sin_family = ntohs(req->addr.sin_family); 9416467Slayer req->ctl_addr.sin_family = 95*17567Sbloom ntohs(req->ctl_addr.sin_family); 9616467Slayer } 9716467Slayer } 98