Annotation of 42BSD/ucb/talk/talkd.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.