156575Sbostic /* 256575Sbostic * Copyright (c) 1983 Regents of the University of California. 356575Sbostic * All rights reserved. The Berkeley software License Agreement 456575Sbostic * specifies the terms and conditions for redistribution. 556575Sbostic */ 656575Sbostic 756575Sbostic #ifndef lint 856575Sbostic char copyright[] = 956575Sbostic "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1056575Sbostic All rights reserved.\n"; 1156575Sbostic #endif not lint 1256575Sbostic 1356575Sbostic #ifndef lint 1456575Sbostic static char sccsid[] = "@(#)talkd.c 5.1 (Berkeley) 6/6/85"; 1556575Sbostic #endif not lint 1656575Sbostic 1756575Sbostic /* 1856575Sbostic * The top level of the daemon, the format is heavily borrowed 1956575Sbostic * from rwhod.c. Basically: find out who and where you are; 2056575Sbostic * disconnect all descriptors and ttys, and then endless 2156575Sbostic * loop on waiting for and processing requests 2256575Sbostic */ 2356575Sbostic #include <stdio.h> 2456575Sbostic #include <errno.h> 2556575Sbostic #include <signal.h> 2656575Sbostic 2756575Sbostic #include "ctl.h" 2856575Sbostic 2956575Sbostic struct sockaddr_in sin = { AF_INET }; 3056575Sbostic 3156575Sbostic CTL_MSG request; 3256575Sbostic CTL_RESPONSE response; 3356575Sbostic 3456575Sbostic int sockt; 3556575Sbostic int debug = 0; 3656575Sbostic FILE *debugout; 37*56579Sbostic void timeout(); 3856575Sbostic long lastmsgtime; 3956575Sbostic 4056575Sbostic char hostname[32]; 4156575Sbostic 4256575Sbostic #define TIMEOUT 30 4356575Sbostic #define MAXIDLE 120 4456575Sbostic 4556575Sbostic main(argc, argv) 4656575Sbostic int argc; 4756575Sbostic char *argv[]; 4856575Sbostic { 4956575Sbostic struct sockaddr_in from; 5056575Sbostic int fromlen, cc; 5156575Sbostic 5256575Sbostic if (debug) 5356575Sbostic debugout = (FILE *)fopen ("/usr/tmp/talkd.msgs", "w"); 5456575Sbostic 5556575Sbostic if (getuid()) { 5656575Sbostic fprintf(stderr, "Talkd : not super user\n"); 5756575Sbostic exit(1); 5856575Sbostic } 5956575Sbostic gethostname(hostname, sizeof (hostname)); 6056575Sbostic (void) chdir("/dev"); 6156575Sbostic signal(SIGALRM, timeout); 6256575Sbostic alarm(TIMEOUT); 6356575Sbostic for (;;) { 6456575Sbostic extern int errno; 6556575Sbostic 6656575Sbostic fromlen = sizeof(from); 67*56579Sbostic cc = recvfrom(0, (char *) &request, sizeof (request), 0, 68*56579Sbostic (struct sockaddr *)&from, &fromlen); 6956575Sbostic if (cc != sizeof(request)) { 7056575Sbostic if (cc < 0 && errno != EINTR) 7156575Sbostic perror("recvfrom"); 7256575Sbostic continue; 7356575Sbostic } 7456575Sbostic lastmsgtime = time(0); 7556575Sbostic swapmsg(&request); 7656575Sbostic if (debug) print_request(&request); 7756575Sbostic process_request(&request, &response); 7856575Sbostic /* can block here, is this what I want? */ 7956575Sbostic cc = sendto(sockt, (char *) &response, 80*56579Sbostic sizeof (response), 0, (struct sockaddr *)&request.ctl_addr, 8156575Sbostic sizeof (request.ctl_addr)); 8256575Sbostic if (cc != sizeof(response)) 8356575Sbostic perror("sendto"); 8456575Sbostic } 8556575Sbostic } 8656575Sbostic 87*56579Sbostic void 8856575Sbostic timeout() 8956575Sbostic { 9056575Sbostic 9156575Sbostic if (time(0) - lastmsgtime >= MAXIDLE) 9256575Sbostic exit(0); 9356575Sbostic alarm(TIMEOUT); 9456575Sbostic } 9556575Sbostic 9656575Sbostic /* 9756575Sbostic * heuristic to detect if need to swap bytes 9856575Sbostic */ 9956575Sbostic 10056575Sbostic swapmsg(req) 10156575Sbostic CTL_MSG *req; 10256575Sbostic { 10356575Sbostic if (req->ctl_addr.sin_family == ntohs(AF_INET)) { 10456575Sbostic req->id_num = ntohl(req->id_num); 10556575Sbostic req->pid = ntohl(req->pid); 10656575Sbostic req->addr.sin_family = ntohs(req->addr.sin_family); 10756575Sbostic req->ctl_addr.sin_family = 10856575Sbostic ntohs(req->ctl_addr.sin_family); 10956575Sbostic } 11056575Sbostic } 111