showterm 0.1.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/bin/showterm CHANGED
@@ -15,9 +15,7 @@ end
15
15
 
16
16
  sf, tf = Showterm.record! *ARGV
17
17
  begin
18
- Showterm.upload! sf, tf, ENV['COLUMNS'] || 80
19
- File.unlink sf
20
- File.unlink tf
18
+ Showterm.upload! sf, tf
21
19
  rescue => e
22
20
  puts [e] + e.backtrace
23
21
  puts "DON'T PANIC"
data/ext/Makefile ADDED
@@ -0,0 +1,34 @@
1
+ CC = gcc
2
+ CFLAGS = -O2
3
+ VERSION = 1.0.8
4
+
5
+ TARGET = ttyrec ttyplay ttytime
6
+
7
+ DIST = ttyrec.c ttyplay.c ttyrec.h io.c io.h ttytime.c\
8
+ README Makefile ttyrec.1 ttyplay.1 ttytime.1
9
+
10
+ all: $(TARGET)
11
+
12
+ ttyrec: ttyrec.o io.o
13
+ $(CC) $(CFLAGS) -o ttyrec ttyrec.o io.o
14
+
15
+ ttyplay: ttyplay.o io.o
16
+ $(CC) $(CFLAGS) -o ttyplay ttyplay.o io.o
17
+
18
+ ttytime: ttytime.o io.o
19
+ $(CC) $(CFLAGS) -o ttytime ttytime.o io.o
20
+
21
+ clean:
22
+ rm -f *.o $(TARGET) ttyrecord *~
23
+
24
+ dist:
25
+ rm -rf ttyrec-$(VERSION)
26
+ rm -f ttyrec-$(VERSION).tar.gz
27
+
28
+ mkdir ttyrec-$(VERSION)
29
+ cp $(DIST) ttyrec-$(VERSION)
30
+ tar zcf ttyrec-$(VERSION).tar.gz ttyrec-$(VERSION)
31
+ rm -rf ttyrec-$(VERSION)
32
+
33
+ install:
34
+ :
data/ext/README ADDED
@@ -0,0 +1,27 @@
1
+ ttyrec is a tty recorder. ttyplay is a tty player.
2
+
3
+ Installation:
4
+
5
+ % make
6
+
7
+ or if your system is SVR4 system (Solaris etc.),
8
+
9
+ % make CFLAGS=-DSVR4
10
+
11
+ or if your system supports getpt(3),
12
+
13
+ % make CFLAGS=-DHAVE_getpt
14
+
15
+ HAVE_getpt is required if your linux system uses devfs.
16
+
17
+
18
+ Usage:
19
+
20
+ % ttyrec
21
+ (In the excuted shell, do whatever you want and exit)
22
+
23
+ % ttyplay ttyrecord
24
+
25
+ Have fun!
26
+
27
+ -- Satoru Takabayashi <satoru@namazu.org>
data/ext/extconf.rb ADDED
File without changes
data/ext/io.c ADDED
@@ -0,0 +1,161 @@
1
+ /*
2
+ * Copyright (c) 2000 Satoru Takabayashi <satoru@namazu.org>
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ * 3. All advertising materials mentioning features or use of this software
14
+ * must display the following acknowledgement:
15
+ * This product includes software developed by the University of
16
+ * California, Berkeley and its contributors.
17
+ * 4. Neither the name of the University nor the names of its contributors
18
+ * may be used to endorse or promote products derived from this software
19
+ * without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
+ * SUCH DAMAGE.
32
+ */
33
+
34
+ #include <assert.h>
35
+ #include <errno.h>
36
+ #include <stdio.h>
37
+ #include <stdlib.h>
38
+ #include <string.h>
39
+ #include <unistd.h>
40
+
41
+ #include "ttyrec.h"
42
+
43
+ #define SWAP_ENDIAN(val) ((unsigned int) ( \
44
+ (((unsigned int) (val) & (unsigned int) 0x000000ffU) << 24) | \
45
+ (((unsigned int) (val) & (unsigned int) 0x0000ff00U) << 8) | \
46
+ (((unsigned int) (val) & (unsigned int) 0x00ff0000U) >> 8) | \
47
+ (((unsigned int) (val) & (unsigned int) 0xff000000U) >> 24)))
48
+
49
+ static int
50
+ is_little_endian ()
51
+ {
52
+ static int retval = -1;
53
+
54
+ if (retval == -1) {
55
+ int n = 1;
56
+ char *p = (char *)&n;
57
+ char x[] = {1, 0, 0, 0};
58
+
59
+ assert(sizeof(int) == 4);
60
+
61
+ if (memcmp(p, x, 4) == 0) {
62
+ retval = 1;
63
+ } else {
64
+ retval = 0;
65
+ }
66
+ }
67
+
68
+ return retval;
69
+ }
70
+
71
+ static int
72
+ convert_to_little_endian (int x)
73
+ {
74
+ if (is_little_endian()) {
75
+ return x;
76
+ } else {
77
+ return SWAP_ENDIAN(x);
78
+ }
79
+ }
80
+
81
+ int
82
+ read_header (FILE *fp, Header *h)
83
+ {
84
+ int buf[3];
85
+
86
+ if (fread(buf, sizeof(int), 3, fp) == 0) {
87
+ return 0;
88
+ }
89
+
90
+ h->tv.tv_sec = convert_to_little_endian(buf[0]);
91
+ h->tv.tv_usec = convert_to_little_endian(buf[1]);
92
+ h->len = convert_to_little_endian(buf[2]);
93
+
94
+ return 1;
95
+ }
96
+
97
+ int
98
+ write_header (FILE *fp, Header *h)
99
+ {
100
+ int buf[3];
101
+
102
+ buf[0] = convert_to_little_endian(h->tv.tv_sec);
103
+ buf[1] = convert_to_little_endian(h->tv.tv_usec);
104
+ buf[2] = convert_to_little_endian(h->len);
105
+
106
+ if (fwrite(buf, sizeof(int), 3, fp) == 0) {
107
+ return 0;
108
+ }
109
+
110
+ return 1;
111
+ }
112
+
113
+ static char *progname = "";
114
+ void
115
+ set_progname (const char *name)
116
+ {
117
+ progname = strdup(name);
118
+ }
119
+
120
+ FILE *
121
+ efopen (const char *path, const char *mode)
122
+ {
123
+ FILE *fp = fopen(path, mode);
124
+ if (fp == NULL) {
125
+ fprintf(stderr, "%s: %s: %s\n", progname, path, strerror(errno));
126
+ exit(EXIT_FAILURE);
127
+ }
128
+ return fp;
129
+ }
130
+
131
+ int
132
+ edup (int oldfd)
133
+ {
134
+ int fd = dup(oldfd);
135
+ if (fd == -1) {
136
+ fprintf(stderr, "%s: dup failed: %s\n", progname, strerror(errno));
137
+ exit(EXIT_FAILURE);
138
+ }
139
+ return fd;
140
+ }
141
+
142
+ int
143
+ edup2 (int oldfd, int newfd)
144
+ {
145
+ int fd = dup2(oldfd, newfd);
146
+ if (fd == -1) {
147
+ fprintf(stderr, "%s: dup2 failed: %s\n", progname, strerror(errno));
148
+ exit(EXIT_FAILURE);
149
+ }
150
+ return fd;
151
+ }
152
+
153
+ FILE *
154
+ efdopen (int fd, const char *mode)
155
+ {
156
+ FILE *fp = fdopen(fd, mode);
157
+ if (fp == NULL) {
158
+ fprintf(stderr, "%s: fdopen failed: %s\n", progname, strerror(errno));
159
+ exit(EXIT_FAILURE);
160
+ }
161
+ }
data/ext/io.h ADDED
@@ -0,0 +1,13 @@
1
+ #ifndef __TTYREC_IO_H__
2
+ #define __TTYREC_IO_H__
3
+
4
+ #include "ttyrec.h"
5
+
6
+ int read_header (FILE *fp, Header *h);
7
+ int write_header (FILE *fp, Header *h);
8
+ FILE* efopen (const char *path, const char *mode);
9
+ int edup (int oldfd);
10
+ int edup2 (int oldfd, int newfd);
11
+ FILE* efdopen (int fd, const char *mode);
12
+
13
+ #endif
data/ext/ttyplay.1 ADDED
@@ -0,0 +1,62 @@
1
+ .\"
2
+ .\" This manual page is written by NAKANO Takeo <nakano@webmasters.gr.jp>
3
+ .\"
4
+ .TH TTYPLAY 1
5
+ .SH NAME
6
+ ttyplay \- player of the tty session recorded by ttyrec
7
+ .SH SYNOPSIS
8
+ .br
9
+ .B ttyplay
10
+ .I [\-s SPEED] [\-n] [\-p] file
11
+ .br
12
+ .SH DESCRIPTION
13
+ .B Ttyplay
14
+ plays the tty session in
15
+ .IR file ,
16
+ which was recorded previously by
17
+ .BR ttyrec (1).
18
+ .PP
19
+ When
20
+ .B \-p
21
+ option is given,
22
+ .B ttyplay
23
+ output the
24
+ .I file
25
+ as it grows.
26
+ It means that you can see the "live" shell session
27
+ running by another user.
28
+ .PP
29
+ If you hit any key during playback, it will go right to the next
30
+ character typed. This is handy when examining sessions where a user
31
+ spends a lot of time at a prompt.
32
+ .PP
33
+ Additionally, there are some special keys defined:
34
+ .TP
35
+ .BI + " or " f
36
+ double the speed of playback.
37
+ .TP
38
+ .BI \- " or " s
39
+ halve the speed of playback.
40
+ .TP
41
+ .BI 1
42
+ set playback to speed 1.0 again.
43
+
44
+ .SH OPTIONS
45
+ .TP
46
+ .BI \-s " SPEED"
47
+ multiple the playing speed by
48
+ .I SPEED
49
+ (default is 1).
50
+ .TP
51
+ .B \-n
52
+ no wait mode.
53
+ Ignore the timing information in
54
+ .IR file .
55
+ .TP
56
+ .B \-p
57
+ peek another person's tty session.
58
+ .SH "SEE ALSO"
59
+ .BR script (1),
60
+ .BR ttyrec (1),
61
+ .BR ttytime (1)
62
+
data/ext/ttyplay.c ADDED
@@ -0,0 +1,312 @@
1
+ /*
2
+ * Copyright (c) 2000 Satoru Takabayashi <satoru@namazu.org>
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ * 3. All advertising materials mentioning features or use of this software
14
+ * must display the following acknowledgement:
15
+ * This product includes software developed by the University of
16
+ * California, Berkeley and its contributors.
17
+ * 4. Neither the name of the University nor the names of its contributors
18
+ * may be used to endorse or promote products derived from this software
19
+ * without specific prior written permission.
20
+ *
21
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
+ * SUCH DAMAGE.
32
+ */
33
+
34
+ #include <stdio.h>
35
+ #include <stdlib.h>
36
+ #include <assert.h>
37
+ #include <unistd.h>
38
+ #include <termios.h>
39
+ #include <sys/time.h>
40
+ #include <string.h>
41
+
42
+ #include "ttyrec.h"
43
+ #include "io.h"
44
+
45
+ typedef double (*WaitFunc) (struct timeval prev,
46
+ struct timeval cur,
47
+ double speed);
48
+ typedef int (*ReadFunc) (FILE *fp, Header *h, char **buf);
49
+ typedef void (*WriteFunc) (char *buf, int len);
50
+ typedef void (*ProcessFunc) (FILE *fp, double speed,
51
+ ReadFunc read_func, WaitFunc wait_func);
52
+
53
+ struct timeval
54
+ timeval_diff (struct timeval tv1, struct timeval tv2)
55
+ {
56
+ struct timeval diff;
57
+
58
+ diff.tv_sec = tv2.tv_sec - tv1.tv_sec;
59
+ diff.tv_usec = tv2.tv_usec - tv1.tv_usec;
60
+ if (diff.tv_usec < 0) {
61
+ diff.tv_sec--;
62
+ diff.tv_usec += 1000000;
63
+ }
64
+
65
+ return diff;
66
+ }
67
+
68
+ struct timeval
69
+ timeval_div (struct timeval tv1, double n)
70
+ {
71
+ double x = ((double)tv1.tv_sec + (double)tv1.tv_usec / 1000000.0) / n;
72
+ struct timeval div;
73
+
74
+ div.tv_sec = (int)x;
75
+ div.tv_usec = (x - (int)x) * 1000000;
76
+
77
+ return div;
78
+ }
79
+
80
+ double
81
+ ttywait (struct timeval prev, struct timeval cur, double speed)
82
+ {
83
+ static struct timeval drift = {0, 0};
84
+ struct timeval start;
85
+ struct timeval diff = timeval_diff(prev, cur);
86
+ fd_set readfs;
87
+
88
+ gettimeofday(&start, NULL);
89
+
90
+ assert(speed != 0);
91
+ diff = timeval_diff(drift, timeval_div(diff, speed));
92
+ if (diff.tv_sec < 0) {
93
+ diff.tv_sec = diff.tv_usec = 0;
94
+ }
95
+
96
+ FD_SET(STDIN_FILENO, &readfs);
97
+ /*
98
+ * We use select() for sleeping with subsecond precision.
99
+ * select() is also used to wait user's input from a keyboard.
100
+ *
101
+ * Save "diff" since select(2) may overwrite it to {0, 0}.
102
+ */
103
+ struct timeval orig_diff = diff;
104
+ select(1, &readfs, NULL, NULL, &diff);
105
+ diff = orig_diff; /* Restore the original diff value. */
106
+ if (FD_ISSET(0, &readfs)) { /* a user hits a character? */
107
+ char c;
108
+ read(STDIN_FILENO, &c, 1); /* drain the character */
109
+ switch (c) {
110
+ case '+':
111
+ case 'f':
112
+ speed *= 2;
113
+ break;
114
+ case '-':
115
+ case 's':
116
+ speed /= 2;
117
+ break;
118
+ case '1':
119
+ speed = 1.0;
120
+ break;
121
+ }
122
+ drift.tv_sec = drift.tv_usec = 0;
123
+ } else {
124
+ struct timeval stop;
125
+ gettimeofday(&stop, NULL);
126
+ /* Hack to accumulate the drift */
127
+ if (diff.tv_sec == 0 && diff.tv_usec == 0) {
128
+ diff = timeval_diff(drift, diff); // diff = 0 - drift.
129
+ }
130
+ drift = timeval_diff(diff, timeval_diff(start, stop));
131
+ }
132
+ return speed;
133
+ }
134
+
135
+ double
136
+ ttynowait (struct timeval prev, struct timeval cur, double speed)
137
+ {
138
+ /* do nothing */
139
+ return 0; /* Speed isn't important. */
140
+ }
141
+
142
+ int
143
+ ttyread (FILE *fp, Header *h, char **buf)
144
+ {
145
+ if (read_header(fp, h) == 0) {
146
+ return 0;
147
+ }
148
+
149
+ *buf = malloc(h->len);
150
+ if (*buf == NULL) {
151
+ perror("malloc");
152
+ }
153
+
154
+ if (fread(*buf, 1, h->len, fp) == 0) {
155
+ perror("fread");
156
+ }
157
+ return 1;
158
+ }
159
+
160
+ int
161
+ ttypread (FILE *fp, Header *h, char **buf)
162
+ {
163
+ /*
164
+ * Read persistently just like tail -f.
165
+ */
166
+ while (ttyread(fp, h, buf) == 0) {
167
+ struct timeval w = {0, 250000};
168
+ select(0, NULL, NULL, NULL, &w);
169
+ clearerr(fp);
170
+ }
171
+ return 1;
172
+ }
173
+
174
+ void
175
+ ttywrite (char *buf, int len)
176
+ {
177
+ fwrite(buf, 1, len, stdout);
178
+ }
179
+
180
+ void
181
+ ttynowrite (char *buf, int len)
182
+ {
183
+ /* do nothing */
184
+ }
185
+
186
+ void
187
+ ttyplay (FILE *fp, double speed, ReadFunc read_func,
188
+ WriteFunc write_func, WaitFunc wait_func)
189
+ {
190
+ int first_time = 1;
191
+ struct timeval prev;
192
+
193
+ setbuf(stdout, NULL);
194
+ setbuf(fp, NULL);
195
+
196
+ while (1) {
197
+ char *buf;
198
+ Header h;
199
+
200
+ if (read_func(fp, &h, &buf) == 0) {
201
+ break;
202
+ }
203
+
204
+ if (!first_time) {
205
+ speed = wait_func(prev, h.tv, speed);
206
+ }
207
+ first_time = 0;
208
+
209
+ write_func(buf, h.len);
210
+ prev = h.tv;
211
+ free(buf);
212
+ }
213
+ }
214
+
215
+ void
216
+ ttyskipall (FILE *fp)
217
+ {
218
+ /*
219
+ * Skip all records.
220
+ */
221
+ ttyplay(fp, 0, ttyread, ttynowrite, ttynowait);
222
+ }
223
+
224
+ void ttyplayback (FILE *fp, double speed,
225
+ ReadFunc read_func, WaitFunc wait_func)
226
+ {
227
+ ttyplay(fp, speed, ttyread, ttywrite, wait_func);
228
+ }
229
+
230
+ void ttypeek (FILE *fp, double speed,
231
+ ReadFunc read_func, WaitFunc wait_func)
232
+ {
233
+ ttyskipall(fp);
234
+ ttyplay(fp, speed, ttypread, ttywrite, ttynowait);
235
+ }
236
+
237
+
238
+ void
239
+ usage (void)
240
+ {
241
+ printf("Usage: ttyplay [OPTION] [FILE]\n");
242
+ printf(" -s SPEED Set speed to SPEED [1.0]\n");
243
+ printf(" -n No wait mode\n");
244
+ printf(" -p Peek another person's ttyrecord\n");
245
+ exit(EXIT_FAILURE);
246
+ }
247
+
248
+ /*
249
+ * We do some tricks so that select(2) properly works on
250
+ * STDIN_FILENO in ttywait().
251
+ */
252
+ FILE *
253
+ input_from_stdin (void)
254
+ {
255
+ FILE *fp;
256
+ int fd = edup(STDIN_FILENO);
257
+ edup2(STDOUT_FILENO, STDIN_FILENO);
258
+ return efdopen(fd, "r");
259
+ }
260
+
261
+ int
262
+ main (int argc, char **argv)
263
+ {
264
+ double speed = 1.0;
265
+ ReadFunc read_func = ttyread;
266
+ WaitFunc wait_func = ttywait;
267
+ ProcessFunc process = ttyplayback;
268
+ FILE *input = NULL;
269
+ struct termios old, new;
270
+
271
+ set_progname(argv[0]);
272
+ while (1) {
273
+ int ch = getopt(argc, argv, "s:np");
274
+ if (ch == EOF) {
275
+ break;
276
+ }
277
+ switch (ch) {
278
+ case 's':
279
+ if (optarg == NULL) {
280
+ perror("-s option requires an argument");
281
+ exit(EXIT_FAILURE);
282
+ }
283
+ sscanf(optarg, "%lf", &speed);
284
+ break;
285
+ case 'n':
286
+ wait_func = ttynowait;
287
+ break;
288
+ case 'p':
289
+ process = ttypeek;
290
+ break;
291
+ default:
292
+ usage();
293
+ }
294
+ }
295
+
296
+ if (optind < argc) {
297
+ input = efopen(argv[optind], "r");
298
+ } else {
299
+ input = input_from_stdin();
300
+ }
301
+ assert(input != NULL);
302
+
303
+ tcgetattr(0, &old); /* Get current terminal state */
304
+ new = old; /* Make a copy */
305
+ new.c_lflag &= ~(ICANON | ECHO | ECHONL); /* unbuffered, no echo */
306
+ tcsetattr(0, TCSANOW, &new); /* Make it current */
307
+
308
+ process(input, speed, read_func, wait_func);
309
+ tcsetattr(0, TCSANOW, &old); /* Return terminal state */
310
+
311
+ return 0;
312
+ }
data/ext/ttyrec.1 ADDED
@@ -0,0 +1,76 @@
1
+ .\"
2
+ .\" This manual page is written by NAKANO Takeo <nakano@webmasters.gr.jp>
3
+ .\"
4
+ .TH TTYREC 1
5
+ .SH NAME
6
+ ttyrec \- a tty recorder
7
+ .SH SYNOPSIS
8
+ .br
9
+ .B ttyrec
10
+ .I "[\-a][\-u] [file]"
11
+ .br
12
+ .SH DESCRIPTION
13
+ .B Ttyrec
14
+ is a tty recorder.
15
+ It is a derivative of
16
+ .BR script (1)
17
+ command for recording timing information with microsecond accuracy as well.
18
+ It can record emacs -nw, vi, lynx, or any programs running on tty.
19
+ .PP
20
+ .B Ttyrec
21
+ invokes a shell and records the session until the shell exits.
22
+ Recorded data can be played back with
23
+ .BR ttyplay (1).
24
+ If the argument
25
+ .I file
26
+ is given, the session will be recorded in that file.
27
+ Otherwise,
28
+ .I ttyrecord
29
+ is used as default.
30
+ .SH OPTIONS
31
+ .TP
32
+ .B \-a
33
+ Append the output to
34
+ .I file
35
+ or
36
+ .IR ttyrecord ,
37
+ rather than overwriting it.
38
+ .TP
39
+ .B \-u
40
+ With this option,
41
+ .B ttyrec
42
+ automatically calls
43
+ .BR uudecode (1)
44
+ and saves its output when uuencoded data appear on the session.
45
+ It allow you to transfer files from remote host.
46
+ You can call
47
+ .B ttyrec
48
+ with this option, login to the remote host
49
+ and invoke
50
+ .BR uuencode (1)
51
+ on it for the file you want to transfer.
52
+ .TP
53
+ .BI \-e " command"
54
+ Invoke
55
+ .I command
56
+ when ttyrec starts.
57
+
58
+
59
+ .SH ENVIRONMENT
60
+ .TP
61
+ .I SHELL
62
+ If the variable
63
+ .I SHELL
64
+ exists, the shell forked by
65
+ .B ttyrec
66
+ will be that shell.
67
+ If it's not set,
68
+ the Bourne shell is assumed.
69
+ (Most shells set this variable automatically).
70
+ .SH "SEE ALSO"
71
+ .BR script (1),
72
+ .BR ttyplay (1),
73
+ .BR ttytime (1),
74
+ .BR uuencode (1),
75
+ .BR uudecode (1)
76
+