Annotation of researchv10no/cmd/ct/ct.c, revision 1.1.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.