1*22401Sdist /* 2*22401Sdist * Copyright (c) 1983 Regents of the University of California. 3*22401Sdist * All rights reserved. The Berkeley software License Agreement 4*22401Sdist * specifies the terms and conditions for redistribution. 5*22401Sdist */ 6*22401Sdist 716366Skarels #ifndef lint 8*22401Sdist char copyright[] = 9*22401Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10*22401Sdist All rights reserved.\n"; 11*22401Sdist #endif not lint 1216360Skarels 13*22401Sdist #ifndef lint 14*22401Sdist static char sccsid[] = "@(#)talkd.c 5.1 (Berkeley) 06/06/85"; 15*22401Sdist #endif not lint 16*22401Sdist 1716366Skarels /* 1816366Skarels * The top level of the daemon, the format is heavily borrowed 1916366Skarels * from rwhod.c. Basically: find out who and where you are; 2016366Skarels * disconnect all descriptors and ttys, and then endless 2116366Skarels * loop on waiting for and processing requests 2216360Skarels */ 2316360Skarels #include <stdio.h> 2416360Skarels #include <errno.h> 2516366Skarels #include <signal.h> 2616360Skarels 2716366Skarels #include "ctl.h" 2816360Skarels 2916360Skarels struct sockaddr_in sin = { AF_INET }; 3016360Skarels 3116366Skarels CTL_MSG request; 3216366Skarels CTL_RESPONSE response; 3316360Skarels 3416366Skarels int sockt; 3516366Skarels int debug = 0; 3616467Slayer FILE *debugout; 3716366Skarels int timeout(); 3816366Skarels long lastmsgtime; 3916360Skarels 4016366Skarels char hostname[32]; 4116360Skarels 4216366Skarels #define TIMEOUT 30 4316366Skarels #define MAXIDLE 120 4416366Skarels 4516366Skarels main(argc, argv) 4616366Skarels int argc; 4716366Skarels char *argv[]; 4816360Skarels { 4916366Skarels struct sockaddr_in from; 5016366Skarels int fromlen, cc; 5116467Slayer 5216467Slayer if (debug) 5316467Slayer debugout = (FILE *)fopen ("/usr/tmp/talkd.msgs", "w"); 5416360Skarels 5516366Skarels if (getuid()) { 5616366Skarels fprintf(stderr, "Talkd : not super user\n"); 5716366Skarels exit(1); 5816360Skarels } 5916366Skarels gethostname(hostname, sizeof (hostname)); 6016366Skarels (void) chdir("/dev"); 6116366Skarels signal(SIGALRM, timeout); 6216366Skarels alarm(TIMEOUT); 6316366Skarels for (;;) { 6416366Skarels extern int errno; 6516360Skarels 6616366Skarels fromlen = sizeof(from); 6716366Skarels cc = recvfrom(0, (char *)&request, sizeof (request), 0, 6816366Skarels &from, &fromlen); 6916366Skarels if (cc != sizeof(request)) { 7016366Skarels if (cc < 0 && errno != EINTR) 7116366Skarels perror("recvfrom"); 7216366Skarels continue; 7316366Skarels } 7416366Skarels lastmsgtime = time(0); 7516467Slayer swapmsg(&request); 7617567Sbloom if (debug) print_request(&request); 7716366Skarels process_request(&request, &response); 7816360Skarels /* can block here, is this what I want? */ 7916366Skarels cc = sendto(sockt, (char *) &response, 8016366Skarels sizeof (response), 0, &request.ctl_addr, 8116366Skarels sizeof (request.ctl_addr)); 8216366Skarels if (cc != sizeof(response)) 8316366Skarels perror("sendto"); 8416360Skarels } 8516360Skarels } 8616360Skarels 8716366Skarels timeout() 8816360Skarels { 8916360Skarels 9016366Skarels if (time(0) - lastmsgtime >= MAXIDLE) 9116366Skarels exit(0); 9216366Skarels alarm(TIMEOUT); 9316360Skarels } 9416467Slayer 9516467Slayer /* 9616467Slayer * heuristic to detect if need to swap bytes 9716467Slayer */ 9816467Slayer 9916467Slayer swapmsg(req) 10016467Slayer CTL_MSG *req; 10116467Slayer { 10217567Sbloom if (req->ctl_addr.sin_family == ntohs(AF_INET)) { 10317567Sbloom req->id_num = ntohl(req->id_num); 10417567Sbloom req->pid = ntohl(req->pid); 10517567Sbloom req->addr.sin_family = ntohs(req->addr.sin_family); 10616467Slayer req->ctl_addr.sin_family = 10717567Sbloom ntohs(req->ctl_addr.sin_family); 10816467Slayer } 10916467Slayer } 110