recalculate nvis after move
[unix-history] / usr / src / usr.bin / script / script.c
CommitLineData
784bcaee 1#ifndef lint
840fc587 2static char *sccsid = "@(#)script.c 4.5 (Berkeley) 83/07/02";
3481eb52 3#endif
4ca10280 4
3481eb52 5/*
784bcaee 6 * script
3481eb52 7 */
784bcaee
BJ
8#include <stdio.h>
9#include <signal.h>
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <sys/ioctl.h>
13#include <sgtty.h>
840fc587 14#include <sys/time.h>
784bcaee
BJ
15
16char *getenv();
17char *ctime();
18char *shell;
19FILE *fscript;
20int master;
21int slave;
22int child;
23char *fname = "typescript";
24int finish();
25
26struct sgttyb b;
27struct tchars tc;
28struct ltchars lc;
29int lb;
30int l;
31char *line = "/dev/ptyXX";
32int aflg;
33
34main(argc, argv)
35 int argc;
36 char *argv[];
37{
38 int f;
3481eb52 39
3481eb52 40 shell = getenv("SHELL");
784bcaee
BJ
41 if (shell == 0)
42 shell = "/bin/sh";
43 argc--, argv++;
44 while (argc > 0 && argv[0][0] == '-') {
45 switch (argv[0][1]) {
46
47 case 'a':
48 aflg++;
49 break;
50
51 default:
52 fprintf(stderr,
53 "usage: script [ -a ] [ typescript ]\n");
54 exit(1);
3481eb52 55 }
784bcaee 56 argc--, argv++;
3481eb52 57 }
784bcaee
BJ
58 if (argc > 0)
59 fname = argv[0];
60 if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) {
61 perror(fname);
3481eb52
BJ
62 fail();
63 }
784bcaee
BJ
64 getmaster();
65 printf("Script started, file is %s\n", fname);
3481eb52 66 fixtty();
3481eb52 67
784bcaee
BJ
68 (void) signal(SIGCHLD, finish);
69 child = fork();
70 if (child < 0) {
71 perror("fork");
72 fail();
73 }
74 if (child == 0) {
75 f = fork();
76 if (f < 0) {
77 perror("fork");
78 fail();
79 }
80 if (f)
3481eb52 81 dooutput();
784bcaee
BJ
82 else
83 doshell();
3481eb52 84 }
784bcaee 85 doinput();
3481eb52
BJ
86}
87
3481eb52
BJ
88doinput()
89{
784bcaee
BJ
90 char ibuf[BUFSIZ];
91 int cc;
3481eb52 92
784bcaee
BJ
93 (void) fclose(fscript);
94 while ((cc = read(0, ibuf, BUFSIZ)) > 0)
95 (void) write(master, ibuf, cc);
96 done();
97}
3481eb52 98
840fc587 99#include <sys/wait.h>
3481eb52 100
784bcaee
BJ
101finish()
102{
103 union wait status;
3481eb52 104
784bcaee
BJ
105 if (wait3(&status, WNOHANG, 0) != child)
106 return;
3481eb52
BJ
107 done();
108}
109
3481eb52
BJ
110dooutput()
111{
784bcaee
BJ
112 time_t tvec;
113 char obuf[BUFSIZ];
114 int cc;
115
116 (void) close(0);
117 tvec = time((time_t *)0);
118 fprintf(fscript, "Script started on %s", ctime(&tvec));
119 for (;;) {
120 cc = read(master, obuf, sizeof (obuf));
121 if (cc <= 0)
122 break;
123 (void) write(1, obuf, cc);
124 (void) fwrite(obuf, 1, cc, fscript);
3481eb52 125 }
784bcaee
BJ
126 tvec = time((time_t *)0);
127 fprintf(fscript,"\nscript done on %s", ctime(&tvec));
128 (void) fclose(fscript);
129 (void) close(master);
3481eb52
BJ
130 exit(0);
131}
132
3481eb52
BJ
133doshell()
134{
784bcaee 135 int t;
3481eb52 136
784bcaee
BJ
137 t = open("/dev/tty", 2);
138 if (t >= 0) {
139 ioctl(t, TIOCNOTTY, (char *)0);
140 (void) close(t);
141 }
142 getslave();
143 (void) close(master);
144 (void) fclose(fscript);
145 dup2(slave, 0);
146 dup2(slave, 1);
147 dup2(slave, 2);
148 (void) close(slave);
3481eb52 149 execl(shell, "sh", "-i", 0);
784bcaee 150 perror(shell);
3481eb52
BJ
151 fail();
152}
153
154fixtty()
155{
784bcaee 156 struct sgttyb sbuf;
3481eb52 157
784bcaee
BJ
158 sbuf = b;
159 sbuf.sg_flags |= RAW;
160 sbuf.sg_flags &= ~ECHO;
161 ioctl(0, TIOCSETP, (char *)&sbuf);
3481eb52
BJ
162}
163
164fail()
165{
166
784bcaee 167 (void) kill(0, SIGTERM);
3481eb52
BJ
168 done();
169}
170
171done()
172{
173
784bcaee
BJ
174 ioctl(0, TIOCSETP, (char *)&b);
175 printf("Script done, file is %s\n", fname);
176 exit(0);
3481eb52
BJ
177}
178
784bcaee
BJ
179getmaster()
180{
181 char c;
182 struct stat stb;
183 int i;
184
185 for (c = 'p'; c <= 's'; c++) {
186 line[strlen("/dev/pty")] = c;
187 line[strlen("/dev/ptyp")] = '0';
188 if (stat(line, &stb) < 0)
189 break;
190 for (i = 0; i < 16; i++) {
191 line[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
192 master = open(line, 2);
193 if (master >= 0) {
194 ioctl(0, TIOCGETP, (char *)&b);
195 ioctl(0, TIOCGETC, (char *)&tc);
196 ioctl(0, TIOCGETD, (char *)&l);
197 ioctl(0, TIOCGLTC, (char *)&lc);
198 ioctl(0, TIOCLGET, (char *)&lb);
199 return;
200 }
201 }
202 }
203 fprintf(stderr, "Out of pty's\n");
204 fail();
3481eb52 205}
3481eb52 206
784bcaee 207getslave()
3481eb52 208{
784bcaee
BJ
209
210 line[strlen("/dev/")] = 't';
211 slave = open(line, 2);
212 if (slave < 0) {
213 perror(line);
214 fail();
3481eb52 215 }
784bcaee
BJ
216 ioctl(slave, TIOCSETP, (char *)&b);
217 ioctl(slave, TIOCSETC, (char *)&tc);
218 ioctl(slave, TIOCSLTC, (char *)&lc);
219 ioctl(slave, TIOCLSET, (char *)&lb);
220 ioctl(slave, TIOCSETD, (char *)&l);
3481eb52 221}