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