|
|
1.1 ! root 1: /* $Header: talkd.c 1.5 83/05/10 13:57:29 moore Exp $ */ ! 2: ! 3: /* The top level of the daemon, the format is heavily borrowed ! 4: from rwhod.c. Basically: find out who and where you are; ! 5: disconnect all descriptors and ttys, and then endless ! 6: loop on waiting for and processing requests ! 7: */ ! 8: ! 9: #include "ctl.h" ! 10: ! 11: #include <stdio.h> ! 12: #include <errno.h> ! 13: #include <sgtty.h> ! 14: #include <sys/ioctl.h> ! 15: ! 16: #define MAX_ERR 20 /* Number of times to attempt to open the ! 17: control socket */ ! 18: ! 19: extern errno; ! 20: ! 21: struct sockaddr_in sin = { AF_INET }; ! 22: ! 23: CTL_MSG request; ! 24: CTL_RESPONSE response; ! 25: int sockt; ! 26: char hostname[HOST_NAME_LENGTH]; ! 27: ! 28: struct hostent *gethostbyname(); ! 29: struct servent *getservbyname(); ! 30: ! 31: int debug = 0; ! 32: ! 33: main(argc) ! 34: int argc; ! 35: { ! 36: struct sockaddr_in from; ! 37: int from_size; ! 38: int cc; ! 39: int name_length = sizeof(hostname); ! 40: struct servent *sp; ! 41: struct hostent *hp; ! 42: ! 43: ! 44: if ( argc > 1 ) { ! 45: debug = 1; ! 46: } ! 47: ! 48: if ( !debug ) { ! 49: if (fork()) { ! 50: exit(0); ! 51: } ! 52: } ! 53: ! 54: gethostname(hostname, &name_length); ! 55: ! 56: hp = gethostbyname(hostname); ! 57: if (hp == (struct hostent *) 0) { ! 58: fprintf(stderr, "talkd: Cannot obtain local address\n"); ! 59: exit(1); ! 60: } ! 61: ! 62: #ifdef NTALK ! 63: sp = getservbyname("ntalk", "udp"); ! 64: #else ! 65: sp = getservbyname("talk", "udp"); ! 66: #endif ! 67: ! 68: if (sp == 0) { ! 69: fprintf(stderr, "talkd: udp/talk: unknown service\n"); ! 70: exit(1); ! 71: } ! 72: ! 73: if (getuid()) { ! 74: fprintf(stderr, "Talkd : not super user\n"); ! 75: exit(1); ! 76: } ! 77: ! 78: setup_desc(); ! 79: ! 80: sin.sin_port = sp->s_port; ! 81: sockt = socket(AF_INET, SOCK_DGRAM, 0, 0); ! 82: if (sockt < 0) { ! 83: print_error("talkd: socket"); ! 84: exit(1); ! 85: } ! 86: ! 87: if (bind(sockt, (caddr_t)&sin, sizeof (sin), 0) < 0) { ! 88: print_error("bind"); ! 89: exit(1); ! 90: } ! 91: ! 92: for (;;) { ! 93: ! 94: from_size = sizeof(from); ! 95: cc = recvfrom(sockt, (char *)&request, sizeof (request), 0, ! 96: &from, &from_size); ! 97: ! 98: if (cc != sizeof(request)) { ! 99: if (cc < 0 && errno != EINTR) { ! 100: print_error("receive"); ! 101: } ! 102: } else { ! 103: ! 104: if (debug) printf("Request received : \n"); ! 105: if (debug) print_request(&request); ! 106: ! 107: process_request(&request, &response); ! 108: ! 109: if (debug) printf("Response sent : \n"); ! 110: if (debug) print_response(&response); ! 111: ! 112: /* can block here, is this what I want? */ ! 113: ! 114: cc = sendto(sockt, (char *) &response, sizeof(response), 0, ! 115: &request.ctl_addr, sizeof(request.ctl_addr)); ! 116: ! 117: if (cc != sizeof(response)) { ! 118: print_error("Send"); ! 119: } ! 120: } ! 121: } ! 122: } ! 123: ! 124: /* disconnect all descriptors, remove ourself from the process ! 125: * group that spawned us ! 126: */ ! 127: ! 128: setup_desc() ! 129: { ! 130: int s; ! 131: ! 132: if (debug) return; ! 133: ! 134: for (s = 0; s < 10; s++) { ! 135: (void) close(s); ! 136: } ! 137: ! 138: (void) open("/dev/null", 0); ! 139: (void) dup2(0, 1); ! 140: (void) dup2(0, 2); ! 141: ! 142: s = open("/dev/tty", 2); ! 143: ! 144: if (s >= 0) { ! 145: ioctl(s, TIOCNOTTY, (struct sgttyb *) 0); ! 146: (void) close(s); ! 147: } ! 148: ! 149: (void) chdir("/dev"); ! 150: } ! 151: ! 152: extern int sys_nerr; ! 153: extern char *sys_errlist[]; ! 154: ! 155: print_error(string) ! 156: char *string; ! 157: { ! 158: FILE *cons; ! 159: char *err_dev = "/dev/console"; ! 160: char *sys; ! 161: int val, pid; ! 162: ! 163: if (debug) err_dev = "/dev/tty"; ! 164: ! 165: sys = "Unknown error"; ! 166: ! 167: if(errno < sys_nerr) { ! 168: sys = sys_errlist[errno]; ! 169: } ! 170: ! 171: /* don't ever open tty's directly, let a child do it */ ! 172: if ((pid = fork()) == 0) { ! 173: cons = fopen(err_dev, "a"); ! 174: if (cons != NULL) { ! 175: fprintf(cons, "Talkd : %s : %s(%d)\n\r", string, sys, ! 176: errno); ! 177: fclose(cons); ! 178: } ! 179: exit(0); ! 180: } else { ! 181: /* wait for the child process to return */ ! 182: do { ! 183: val = wait(0); ! 184: if (val == -1) { ! 185: if (errno == EINTR) { ! 186: continue; ! 187: } else if (errno == ECHILD) { ! 188: break; ! 189: } ! 190: } ! 191: } while (val != pid); ! 192: } ! 193: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.