|
|
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(<ime); ! 215: tstr = ctime(<ime); ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.