|
|
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.