116366Skarels #ifndef lint 2*16467Slayer static char sccsid[] = "@(#)talkd.c 1.3 (Berkeley) 05/11/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; 24*16467Slayer 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; 39*16467Slayer 40*16467Slayer if (debug) 41*16467Slayer 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); 63*16467Slayer swapmsg(&request); 64*16467Slayer if (debug) print_request(&request, fp); 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 } 73*16467Slayer if (debug) close (debugout); 7416360Skarels } 7516360Skarels 7616366Skarels timeout() 7716360Skarels { 7816360Skarels 7916366Skarels if (time(0) - lastmsgtime >= MAXIDLE) 8016366Skarels exit(0); 8116366Skarels alarm(TIMEOUT); 8216360Skarels } 83*16467Slayer 84*16467Slayer #define swapshort(a) (((a << 8) | ((unsigned short) a >> 8)) & 0xffff) 85*16467Slayer #define swaplong(a) ((swapshort(a) << 16) | (swapshort(((unsigned)a >> 16)))) 86*16467Slayer 87*16467Slayer /* 88*16467Slayer * heuristic to detect if need to swap bytes 89*16467Slayer */ 90*16467Slayer 91*16467Slayer swapmsg(req) 92*16467Slayer CTL_MSG *req; 93*16467Slayer { 94*16467Slayer if (req->ctl_addr.sin_family == swapshort(AF_INET)) { 95*16467Slayer req->id_num = swaplong(req->id_num); 96*16467Slayer req->pid = swaplong(req->pid); 97*16467Slayer req->addr.sin_family = swapshort(req->addr.sin_family); 98*16467Slayer req->ctl_addr.sin_family = 99*16467Slayer swapshort(req->ctl_addr.sin_family); 100*16467Slayer } 101*16467Slayer } 102