1*56575Sbostic /* 2*56575Sbostic * Copyright (c) 1983 Regents of the University of California. 3*56575Sbostic * All rights reserved. The Berkeley software License Agreement 4*56575Sbostic * specifies the terms and conditions for redistribution. 5*56575Sbostic */ 6*56575Sbostic 7*56575Sbostic #ifndef lint 8*56575Sbostic char copyright[] = 9*56575Sbostic "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10*56575Sbostic All rights reserved.\n"; 11*56575Sbostic #endif not lint 12*56575Sbostic 13*56575Sbostic #ifndef lint 14*56575Sbostic static char sccsid[] = "@(#)talkd.c 5.1 (Berkeley) 6/6/85"; 15*56575Sbostic #endif not lint 16*56575Sbostic 17*56575Sbostic /* 18*56575Sbostic * The top level of the daemon, the format is heavily borrowed 19*56575Sbostic * from rwhod.c. Basically: find out who and where you are; 20*56575Sbostic * disconnect all descriptors and ttys, and then endless 21*56575Sbostic * loop on waiting for and processing requests 22*56575Sbostic */ 23*56575Sbostic #include <stdio.h> 24*56575Sbostic #include <errno.h> 25*56575Sbostic #include <signal.h> 26*56575Sbostic 27*56575Sbostic #include "ctl.h" 28*56575Sbostic 29*56575Sbostic struct sockaddr_in sin = { AF_INET }; 30*56575Sbostic 31*56575Sbostic CTL_MSG request; 32*56575Sbostic CTL_RESPONSE response; 33*56575Sbostic 34*56575Sbostic int sockt; 35*56575Sbostic int debug = 0; 36*56575Sbostic FILE *debugout; 37*56575Sbostic int timeout(); 38*56575Sbostic long lastmsgtime; 39*56575Sbostic 40*56575Sbostic char hostname[32]; 41*56575Sbostic 42*56575Sbostic #define TIMEOUT 30 43*56575Sbostic #define MAXIDLE 120 44*56575Sbostic 45*56575Sbostic main(argc, argv) 46*56575Sbostic int argc; 47*56575Sbostic char *argv[]; 48*56575Sbostic { 49*56575Sbostic struct sockaddr_in from; 50*56575Sbostic int fromlen, cc; 51*56575Sbostic 52*56575Sbostic if (debug) 53*56575Sbostic debugout = (FILE *)fopen ("/usr/tmp/talkd.msgs", "w"); 54*56575Sbostic 55*56575Sbostic if (getuid()) { 56*56575Sbostic fprintf(stderr, "Talkd : not super user\n"); 57*56575Sbostic exit(1); 58*56575Sbostic } 59*56575Sbostic gethostname(hostname, sizeof (hostname)); 60*56575Sbostic (void) chdir("/dev"); 61*56575Sbostic signal(SIGALRM, timeout); 62*56575Sbostic alarm(TIMEOUT); 63*56575Sbostic for (;;) { 64*56575Sbostic extern int errno; 65*56575Sbostic 66*56575Sbostic fromlen = sizeof(from); 67*56575Sbostic cc = recvfrom(0, (char *)&request, sizeof (request), 0, 68*56575Sbostic &from, &fromlen); 69*56575Sbostic if (cc != sizeof(request)) { 70*56575Sbostic if (cc < 0 && errno != EINTR) 71*56575Sbostic perror("recvfrom"); 72*56575Sbostic continue; 73*56575Sbostic } 74*56575Sbostic lastmsgtime = time(0); 75*56575Sbostic swapmsg(&request); 76*56575Sbostic if (debug) print_request(&request); 77*56575Sbostic process_request(&request, &response); 78*56575Sbostic /* can block here, is this what I want? */ 79*56575Sbostic cc = sendto(sockt, (char *) &response, 80*56575Sbostic sizeof (response), 0, &request.ctl_addr, 81*56575Sbostic sizeof (request.ctl_addr)); 82*56575Sbostic if (cc != sizeof(response)) 83*56575Sbostic perror("sendto"); 84*56575Sbostic } 85*56575Sbostic } 86*56575Sbostic 87*56575Sbostic timeout() 88*56575Sbostic { 89*56575Sbostic 90*56575Sbostic if (time(0) - lastmsgtime >= MAXIDLE) 91*56575Sbostic exit(0); 92*56575Sbostic alarm(TIMEOUT); 93*56575Sbostic } 94*56575Sbostic 95*56575Sbostic /* 96*56575Sbostic * heuristic to detect if need to swap bytes 97*56575Sbostic */ 98*56575Sbostic 99*56575Sbostic swapmsg(req) 100*56575Sbostic CTL_MSG *req; 101*56575Sbostic { 102*56575Sbostic if (req->ctl_addr.sin_family == ntohs(AF_INET)) { 103*56575Sbostic req->id_num = ntohl(req->id_num); 104*56575Sbostic req->pid = ntohl(req->pid); 105*56575Sbostic req->addr.sin_family = ntohs(req->addr.sin_family); 106*56575Sbostic req->ctl_addr.sin_family = 107*56575Sbostic ntohs(req->ctl_addr.sin_family); 108*56575Sbostic } 109*56575Sbostic } 110