Annotation of researchv10no/cmd/ct/ct.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     ct - call terminal
        !             3:  */
        !             4: 
        !             5: #include <sgtty.h>
        !             6: #include <stdio.h>
        !             7: #include <signal.h>
        !             8: #include <utmp.h>
        !             9: 
        !            10: #define GETTY "/etc/getty"
        !            11: #define ROOT 0
        !            12: #define OTHER 1
        !            13: 
        !            14: extern int optind;
        !            15: extern char *optarg;
        !            16: 
        !            17: char *ttyname();
        !            18: 
        !            19: char *num, *class = "D1200";
        !            20: 
        !            21: int hangup = 0;
        !            22: char *verbose; FILE *tfile;
        !            23: int errflg = 0;
        !            24: int count = 5;         /* how many times to try to get through */
        !            25: int waitint = 60;      /* how many seconds to wait between attempts */
        !            26: 
        !            27: #define SCPYN(a, b)    strncpy(a, b, sizeof(a))
        !            28: #define SCMPN(a, b)    strncmp(a, b, sizeof(a))
        !            29: 
        !            30: char utmp[] = "/etc/utmp";
        !            31: char wtmpf[] = "/usr/adm/wtmp";
        !            32: char Usage[] = "usage: ct [-h] [-v file] [-c count] [-w interval] telno [class]";
        !            33: 
        !            34: struct utmp wtmp;
        !            35: 
        !            36: main (argc, argv)
        !            37:        int argc;
        !            38:        char **argv;
        !            39: {
        !            40:        register int c;
        !            41:        int p, pid, status, fd;
        !            42:        char *tty;
        !            43: 
        !            44:        if (argc < 2)
        !            45:                usage();
        !            46: 
        !            47:        while ((c = getopt (argc, argv, "hv:c:w:")) != EOF) {
        !            48:                switch (c) {
        !            49:                case 'h':
        !            50:                        hangup = 1; break;
        !            51:                case 'v':
        !            52:                        verbose = optarg; break;
        !            53:                case 'c':
        !            54:                        count = atoi (optarg); break;
        !            55:                case 'w':
        !            56:                        waitint = atoi (optarg); break;
        !            57:                case '?':
        !            58:                        errflg++; break;
        !            59:                }
        !            60:        }
        !            61: 
        !            62:        if (errflg || optind > argc-1)
        !            63:                usage();
        !            64: 
        !            65:        if (verbose) {
        !            66:                if (!(tfile = fopen(verbose, "w")))
        !            67:                        fatal("ct: could not fopen %s\n", verbose);
        !            68:        }
        !            69: 
        !            70:        num = argv[optind];
        !            71:        if (optind < argc-1)
        !            72:                class = argv[optind+1];
        !            73: 
        !            74:        /* hang up the phone if requested and standard input is a terminal */
        !            75:        if (hangup) {
        !            76:                struct ttydevb s;
        !            77:                if (ioctl(0, TIOCGDEV, &s) >= 0) {
        !            78:                        setsigs (SIG_IGN);
        !            79:                        s.ispeed = s.ospeed = 0;
        !            80:                        ioctl(0, TIOCSDEV, &s);
        !            81:                        trace("ct: hung up on fd 0\n");
        !            82:                        sleep (8);      /* let modems quiesce */
        !            83:                } else {
        !            84:                        hangup = 0;
        !            85:                        fatal("ct: hangup failed\n");
        !            86:                }
        !            87:        }
        !            88: 
        !            89:        while (--count >= 0) {
        !            90:                trace("ct: dialing %s %s\n", num, class);
        !            91:                fd = dialout (num, class);
        !            92:                trace("ct: got fd %d\n", fd);
        !            93:                if (fd >= 0)
        !            94:                        break;
        !            95:                if (count >= 0)
        !            96:                        sleep (waitint);
        !            97:        }
        !            98: 
        !            99:        if (fd < 0)
        !           100:                fatal("ct: connect failed\n");
        !           101: 
        !           102:        /* we don't want exclusive use of the line */
        !           103:        ioctl (fd, TIOCNXCL, 0);
        !           104: 
        !           105:        /* figure out the name we were given */
        !           106:        if (!(tty = ttyname (fd)))
        !           107:                fatal("ct: can't find tty\n");
        !           108:        
        !           109:        setsigs (SIG_IGN);
        !           110: 
        !           111:        trace("ct: connected\n");
        !           112:        session (fd);
        !           113:        trace("ct: session ended\n");
        !           114:        cleanup (tty);
        !           115: 
        !           116:        exit(0);
        !           117: }
        !           118: 
        !           119: /* conduct a terminal session on file "fd" */
        !           120: session (fd)
        !           121: register int fd;
        !           122: {
        !           123:        int status, pid;
        !           124:        register int p;
        !           125: 
        !           126:        switch (pid = fork()) {
        !           127:        default:        /* parent */
        !           128:                do {
        !           129:                        p = wait (&status);
        !           130:                } while (p >= 0 && p != pid);
        !           131:                trace("ct: session exit status %d\n", status);
        !           132:                break;
        !           133:        
        !           134:        case 0:         /* child */
        !           135:                /* Allow the terminal session to run unmasked */
        !           136:                setsigs (SIG_DFL);
        !           137: 
        !           138:                /* become the head of a new process group */
        !           139:                ioctl (fd, TIOCSPGRP, 0);
        !           140: 
        !           141:                /* set up standard input, output, error, tty */
        !           142:                for (p=0; p<4; p++)
        !           143:                        close (p);
        !           144:                for (p=0; p<4; p++)
        !           145:                        dup (fd);
        !           146:                for (; p<_NFILE; p++)
        !           147:                        close(p);
        !           148: 
        !           149:                /* start the session */
        !           150:                execl (GETTY, "-", strchr (class, '3')? "5": "3", 0);
        !           151:                exit (1);       /* exec failed */
        !           152:        
        !           153:        case -1:
        !           154:                exit (1);
        !           155:        }
        !           156:        return status;
        !           157: }
        !           158: 
        !           159: cleanup (dev)
        !           160:        char *dev;
        !           161: {
        !           162:        register f;
        !           163:        register char *line;
        !           164: 
        !           165:        line = dev;
        !           166:        if (strncmp(line, "/dev/", 5) == 0)
        !           167:                line += 5;
        !           168: 
        !           169:        /* indicate this user is no longer signed on */
        !           170:        f = open(utmp, 2);
        !           171:        if(f >= 0) {
        !           172:                while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
        !           173:                        if (SCMPN(wtmp.ut_line, line))
        !           174:                                continue;
        !           175:                        lseek(f, -(long)sizeof(wtmp), 1);
        !           176:                        SCPYN(wtmp.ut_name, "");
        !           177:                        time(&wtmp.ut_time);
        !           178:                        write(f, (char *)&wtmp, sizeof(wtmp));
        !           179:                }
        !           180:                close(f);
        !           181:        }
        !           182: 
        !           183:        /* write logout information for accounting */
        !           184:        f = open(wtmpf, 1);
        !           185:        if (f >= 0) {
        !           186:                SCPYN(wtmp.ut_line, line);
        !           187:                SCPYN(wtmp.ut_name, "");
        !           188:                time(&wtmp.ut_time);
        !           189:                lseek(f, (long)0, 2);
        !           190:                write(f, (char *)&wtmp, sizeof(wtmp));
        !           191:                close(f);
        !           192:        }
        !           193: 
        !           194:        /* reset device to pristine state */
        !           195:        chown (dev, ROOT, OTHER);
        !           196:        chmod (dev, 0666);
        !           197: }
        !           198: 
        !           199: /* set all important signals to f */
        !           200: setsigs (f)
        !           201:        register int (*f)();
        !           202: {
        !           203:        signal (SIGHUP, f);
        !           204:        signal (SIGINT, f);
        !           205:        signal (SIGQUIT, f);
        !           206: }
        !           207: 
        !           208: trace(a, b, c, d, e, f)
        !           209: {
        !           210:        long *ltime; char *ctime();
        !           211:        register char *tstr;
        !           212:        if (!tfile)
        !           213:                return;
        !           214:        time(&ltime);
        !           215:        tstr = ctime(&ltime);
        !           216:        fprintf(tfile, "[%.2s%.4s%.9s] ", tstr+8, tstr+3, tstr+10);
        !           217:        fprintf(tfile, a, b, c, d, e, f);
        !           218:        fflush(tfile);
        !           219: }
        !           220: 
        !           221: fatal(a, b, c, d, e, f)
        !           222: {
        !           223:        trace(a, b, c, d, e, f);
        !           224:        if (!hangup)
        !           225:                fprintf(stderr, a, b, c, d, e, f);
        !           226:        exit(1);
        !           227: }
        !           228: 
        !           229: usage()
        !           230: {
        !           231:        fprintf(stderr, "%s\n", Usage);
        !           232:        exit(1);
        !           233: }

unix.superglobalmegacorp.com

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