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