add Berkeley specific header; trim trailing spaces from configuration
[unix-history] / usr / src / usr.bin / script / script.c
CommitLineData
22e155fc
DF
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
784bcaee 13#ifndef lint
adbf409e 14static char sccsid[] = "@(#)script.c 5.4 (Berkeley) %G%";
22e155fc 15#endif not lint
4ca10280 16
3481eb52 17/*
784bcaee 18 * script
3481eb52 19 */
784bcaee
BJ
20#include <stdio.h>
21#include <signal.h>
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <sys/ioctl.h>
25#include <sgtty.h>
840fc587 26#include <sys/time.h>
bdd96e2c 27#include <sys/file.h>
784bcaee
BJ
28
29char *getenv();
30char *ctime();
31char *shell;
32FILE *fscript;
33int master;
34int slave;
35int child;
5e497b6f 36int subchild;
784bcaee
BJ
37char *fname = "typescript";
38int finish();
39
40struct sgttyb b;
41struct tchars tc;
42struct ltchars lc;
5266af34 43struct winsize win;
784bcaee
BJ
44int lb;
45int l;
46char *line = "/dev/ptyXX";
47int aflg;
48
49main(argc, argv)
50 int argc;
51 char *argv[];
52{
3481eb52 53
3481eb52 54 shell = getenv("SHELL");
784bcaee
BJ
55 if (shell == 0)
56 shell = "/bin/sh";
57 argc--, argv++;
58 while (argc > 0 && argv[0][0] == '-') {
59 switch (argv[0][1]) {
60
61 case 'a':
62 aflg++;
63 break;
64
65 default:
66 fprintf(stderr,
67 "usage: script [ -a ] [ typescript ]\n");
68 exit(1);
3481eb52 69 }
784bcaee 70 argc--, argv++;
3481eb52 71 }
784bcaee
BJ
72 if (argc > 0)
73 fname = argv[0];
74 if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) {
75 perror(fname);
3481eb52
BJ
76 fail();
77 }
784bcaee
BJ
78 getmaster();
79 printf("Script started, file is %s\n", fname);
3481eb52 80 fixtty();
3481eb52 81
784bcaee
BJ
82 (void) signal(SIGCHLD, finish);
83 child = fork();
84 if (child < 0) {
85 perror("fork");
86 fail();
87 }
88 if (child == 0) {
5e497b6f
JB
89 subchild = child = fork();
90 if (child < 0) {
784bcaee
BJ
91 perror("fork");
92 fail();
93 }
5e497b6f 94 if (child)
3481eb52 95 dooutput();
784bcaee
BJ
96 else
97 doshell();
3481eb52 98 }
784bcaee 99 doinput();
3481eb52
BJ
100}
101
3481eb52
BJ
102doinput()
103{
784bcaee
BJ
104 char ibuf[BUFSIZ];
105 int cc;
3481eb52 106
784bcaee
BJ
107 (void) fclose(fscript);
108 while ((cc = read(0, ibuf, BUFSIZ)) > 0)
109 (void) write(master, ibuf, cc);
110 done();
111}
3481eb52 112
840fc587 113#include <sys/wait.h>
3481eb52 114
784bcaee
BJ
115finish()
116{
117 union wait status;
5e497b6f
JB
118 register int pid;
119 register int die = 0;
3481eb52 120
5e497b6f
JB
121 while ((pid = wait3(&status, WNOHANG, 0)) > 0)
122 if (pid == child)
123 die = 1;
124
125 if (die)
126 done();
3481eb52
BJ
127}
128
3481eb52
BJ
129dooutput()
130{
784bcaee
BJ
131 time_t tvec;
132 char obuf[BUFSIZ];
133 int cc;
134
135 (void) close(0);
136 tvec = time((time_t *)0);
137 fprintf(fscript, "Script started on %s", ctime(&tvec));
138 for (;;) {
139 cc = read(master, obuf, sizeof (obuf));
140 if (cc <= 0)
141 break;
142 (void) write(1, obuf, cc);
143 (void) fwrite(obuf, 1, cc, fscript);
3481eb52 144 }
f640284e 145 done();
3481eb52
BJ
146}
147
3481eb52
BJ
148doshell()
149{
784bcaee 150 int t;
3481eb52 151
bdd96e2c 152 t = open("/dev/tty", O_RDWR);
784bcaee 153 if (t >= 0) {
7ca67030 154 (void) ioctl(t, TIOCNOTTY, (char *)0);
784bcaee
BJ
155 (void) close(t);
156 }
157 getslave();
158 (void) close(master);
159 (void) fclose(fscript);
7ca67030
JB
160 (void) dup2(slave, 0);
161 (void) dup2(slave, 1);
162 (void) dup2(slave, 2);
784bcaee 163 (void) close(slave);
3481eb52 164 execl(shell, "sh", "-i", 0);
784bcaee 165 perror(shell);
3481eb52
BJ
166 fail();
167}
168
169fixtty()
170{
784bcaee 171 struct sgttyb sbuf;
3481eb52 172
784bcaee
BJ
173 sbuf = b;
174 sbuf.sg_flags |= RAW;
175 sbuf.sg_flags &= ~ECHO;
7ca67030 176 (void) ioctl(0, TIOCSETP, (char *)&sbuf);
3481eb52
BJ
177}
178
179fail()
180{
181
784bcaee 182 (void) kill(0, SIGTERM);
3481eb52
BJ
183 done();
184}
185
186done()
187{
f640284e 188 time_t tvec;
3481eb52 189
f640284e
S
190 if (subchild) {
191 tvec = time((time_t *)0);
192 fprintf(fscript,"\nscript done on %s", ctime(&tvec));
193 (void) fclose(fscript);
194 (void) close(master);
195 } else {
7ca67030 196 (void) ioctl(0, TIOCSETP, (char *)&b);
5e497b6f
JB
197 printf("Script done, file is %s\n", fname);
198 }
784bcaee 199 exit(0);
3481eb52
BJ
200}
201
784bcaee
BJ
202getmaster()
203{
bdd96e2c 204 char *pty, *bank, *cp;
784bcaee 205 struct stat stb;
784bcaee 206
bdd96e2c
SL
207 pty = &line[strlen("/dev/ptyp")];
208 for (bank = "pqrs"; *bank; bank++) {
209 line[strlen("/dev/pty")] = *bank;
210 *pty = '0';
784bcaee
BJ
211 if (stat(line, &stb) < 0)
212 break;
bdd96e2c
SL
213 for (cp = "0123456789abcdef"; *cp; cp++) {
214 *pty = *cp;
215 master = open(line, O_RDWR);
784bcaee 216 if (master >= 0) {
bdd96e2c
SL
217 char *tp = &line[strlen("/dev/")];
218 int ok;
219
220 /* verify slave side is usable */
221 *tp = 't';
222 ok = access(line, R_OK|W_OK) == 0;
223 *tp = 'p';
224 if (ok) {
7ca67030
JB
225 (void) ioctl(0, TIOCGETP, (char *)&b);
226 (void) ioctl(0, TIOCGETC, (char *)&tc);
227 (void) ioctl(0, TIOCGETD, (char *)&l);
228 (void) ioctl(0, TIOCGLTC, (char *)&lc);
229 (void) ioctl(0, TIOCLGET, (char *)&lb);
230 (void) ioctl(0, TIOCGWINSZ, (char *)&win);
bdd96e2c
SL
231 return;
232 }
7ca67030 233 (void) close(master);
784bcaee
BJ
234 }
235 }
236 }
237 fprintf(stderr, "Out of pty's\n");
238 fail();
3481eb52 239}
3481eb52 240
784bcaee 241getslave()
3481eb52 242{
784bcaee
BJ
243
244 line[strlen("/dev/")] = 't';
bdd96e2c 245 slave = open(line, O_RDWR);
784bcaee
BJ
246 if (slave < 0) {
247 perror(line);
248 fail();
3481eb52 249 }
7ca67030
JB
250 (void) ioctl(slave, TIOCSETP, (char *)&b);
251 (void) ioctl(slave, TIOCSETC, (char *)&tc);
252 (void) ioctl(slave, TIOCSLTC, (char *)&lc);
253 (void) ioctl(slave, TIOCLSET, (char *)&lb);
254 (void) ioctl(slave, TIOCSETD, (char *)&l);
255 (void) ioctl(slave, TIOCSWINSZ, (char *)&win);
3481eb52 256}