|
|
1.1 ! root 1: /* $Header: talkd.c,v 1.2 85/01/09 13:05:13 rcs 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: CTL_MSG swapmsg(); ! 29: struct hostent *gethostbyname(); ! 30: struct servent *getservbyname(); ! 31: ! 32: int vaxbyteorder; ! 33: int tonetmsg(); ! 34: int frnetmsg(); ! 35: int tonetresp(); ! 36: ! 37: int debug = 0; ! 38: ! 39: char *inet_ntoa(); ! 40: /*-------------------------------------------------------------- ! 41: Changes ! 42: . perform byte-ordering within messages as reported from ! 43: the usenet ! 44: -------------------------------------------------------------*/ ! 45: main(argc) ! 46: int argc; ! 47: { ! 48: struct sockaddr_in from; ! 49: int from_size; ! 50: int cc; ! 51: int name_length = sizeof(hostname); ! 52: struct servent *sp; ! 53: struct hostent *hp; ! 54: ! 55: NETCTL_RESPONSE netresp; /* to convert to net format */ ! 56: NETCTL_MSG netreq; ! 57: int swapped; ! 58: ! 59: if ( argc > 1 ) { ! 60: debug = 1; ! 61: } ! 62: ! 63: if ( !debug ) { ! 64: if (fork()) { ! 65: exit(0); ! 66: } ! 67: } ! 68: ! 69: gethostname(hostname, &name_length); ! 70: ! 71: hp = gethostbyname(hostname); ! 72: if (hp == (struct hostent *) 0) { ! 73: fprintf(stderr, "talkd: Cannot obtain local address\n"); ! 74: exit(1); ! 75: } ! 76: ! 77: #ifdef NTALK ! 78: sp = getservbyname("ntalk", "udp"); ! 79: #else ! 80: sp = getservbyname("talk", "udp"); ! 81: #endif ! 82: ! 83: if (sp == 0) { ! 84: fprintf(stderr, "talkd: udp/talk: unknown service\n"); ! 85: exit(1); ! 86: } ! 87: ! 88: if (getuid()) { ! 89: fprintf(stderr, "Talkd : not super user\n"); ! 90: exit(1); ! 91: } ! 92: ! 93: setup_desc(); ! 94: ! 95: sin.sin_port = sp->s_port; ! 96: sockt = socket(AF_INET, SOCK_DGRAM, 0, 0); ! 97: if (sockt < 0) { ! 98: print_error("talkd: socket"); ! 99: exit(1); ! 100: } ! 101: ! 102: if (bind(sockt, (caddr_t)&sin, sizeof (sin), 0) < 0) { ! 103: print_error("bind"); ! 104: exit(1); ! 105: } ! 106: ! 107: for (;;) { ! 108: ! 109: from_size = sizeof(from); ! 110: cc = recvfrom(sockt, (char *)&netreq, sizeof (netreq), 0, ! 111: &from, &from_size); ! 112: ! 113: if (debug) { ! 114: int i; ! 115: char *t = (char *)&netreq; ! 116: ! 117: printf("incoming request: "); ! 118: /* for (i = 0; i<sizeof(NETCTL_MSG); i++) { ! 119: /* printf("%x.", t[i] & 0xff); ! 120: /* } ! 121: /**/ ! 122: printf("\n"); ! 123: } ! 124: ! 125: if (cc != sizeof(netreq)) { ! 126: if (cc < 0 && errno != EINTR) { ! 127: print_error("receive"); ! 128: } ! 129: } else { ! 130: ! 131: swapped = frnetmsg(&netreq, &request); ! 132: if (debug) printf("Request is in VAX-byte-order == %d\n",swapped); ! 133: ! 134: if (debug) printf("Request received : \n"); ! 135: if (debug) print_request(&request); ! 136: ! 137: process_request(&request, &response); ! 138: ! 139: if (debug) printf("Response sent : \n"); ! 140: if (debug) print_response(&response); ! 141: ! 142: /* can block here, is this what I want? */ ! 143: ! 144: tonetresp(&response, &netresp, swapped ); ! 145: if (debug) { ! 146: printf("Send response to: "); ! 147: print_addr(request.ctlm_ctl_addr); ! 148: } ! 149: cc = sendto(sockt, (char *) &netresp, sizeof(netresp), 0, ! 150: &request.ctlm_ctl_addr, sizeof(request.ctlm_ctl_addr)); ! 151: ! 152: if (cc != sizeof(netresp)) { ! 153: print_error("Send"); ! 154: } ! 155: } ! 156: } ! 157: } ! 158: ! 159: /* disconnect all descriptors, remove ourself from the process ! 160: * group that spawned us ! 161: */ ! 162: ! 163: setup_desc() ! 164: { ! 165: int s; ! 166: ! 167: if (debug) return; ! 168: ! 169: for (s = 0; s < 10; s++) { ! 170: (void) close(s); ! 171: } ! 172: ! 173: (void) open("/dev/null", 0); ! 174: (void) dup2(0, 1); ! 175: (void) dup2(0, 2); ! 176: ! 177: s = open("/dev/tty", 2); ! 178: ! 179: if (s >= 0) { ! 180: ioctl(s, TIOCNOTTY, (struct sgttyb *) 0); ! 181: (void) close(s); ! 182: } ! 183: ! 184: (void) chdir("/dev"); ! 185: } ! 186: ! 187: extern int sys_nerr; ! 188: extern char *sys_errlist[]; ! 189: ! 190: print_error(string) ! 191: char *string; ! 192: { ! 193: FILE *cons; ! 194: char *err_dev = "/dev/console"; ! 195: char *sys; ! 196: int val, pid; ! 197: ! 198: if (debug) err_dev = "/dev/tty"; ! 199: ! 200: sys = "Unknown error"; ! 201: ! 202: if(errno < sys_nerr) { ! 203: sys = sys_errlist[errno]; ! 204: } ! 205: ! 206: /* don't ever open tty's directly, let a child do it */ ! 207: if ((pid = fork()) == 0) { ! 208: cons = fopen(err_dev, "a"); ! 209: if (cons != NULL) { ! 210: fprintf(cons, "Talkd : %s : %s(%d)\n\r", string, sys, ! 211: errno); ! 212: fclose(cons); ! 213: } ! 214: exit(0); ! 215: } else { ! 216: /* wait for the child process to return */ ! 217: do { ! 218: val = wait(0); ! 219: if (val == -1) { ! 220: if (errno == EINTR) { ! 221: continue; ! 222: } else if (errno == ECHILD) { ! 223: break; ! 224: } ! 225: } ! 226: } while (val != pid); ! 227: } ! 228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.