Annotation of 42BSD/ucb/talk/talkd.c, revision 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.