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