Commit | Line | Data |
---|---|---|
051b1e55 | 1 | /* |
c9686c12 KB |
2 | * Copyright (c) 1983 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
cb956e54 | 5 | * %sccs.include.redist.c% |
051b1e55 DF |
6 | */ |
7 | ||
05862919 | 8 | #ifndef lint |
59a45cf7 | 9 | static char sccsid[] = "@(#)cmds.c 5.17 (Berkeley) %G%"; |
c9686c12 | 10 | #endif /* not lint */ |
05862919 | 11 | |
22daf918 | 12 | #include "tip.h" |
435e8dff KB |
13 | #include "pathnames.h" |
14 | ||
22daf918 BJ |
15 | /* |
16 | * tip | |
17 | * | |
18 | * miscellaneous commands | |
19 | */ | |
20 | ||
21 | int quant[] = { 60, 60, 24 }; | |
22 | ||
23 | char null = '\0'; | |
24 | char *sep[] = { "second", "minute", "hour" }; | |
25 | static char *argv[10]; /* argument vector for take and put */ | |
26 | ||
981fd33c KB |
27 | void timeout(); /* timeout function called on alarm */ |
28 | void stopsnd(); /* SIGINT handler during file transfers */ | |
29 | void intcopy(); /* interrupt routine for file transfers */ | |
22daf918 BJ |
30 | |
31 | /* | |
32 | * FTP - remote ==> local | |
33 | * get a file from the remote host | |
34 | */ | |
35 | getfl(c) | |
36 | char c; | |
37 | { | |
05862919 | 38 | char buf[256], *cp, *expand(); |
22daf918 BJ |
39 | |
40 | putchar(c); | |
41 | /* | |
42 | * get the UNIX receiving file's name | |
43 | */ | |
44 | if (prompt("Local file name? ", copyname)) | |
45 | return; | |
05862919 SL |
46 | cp = expand(copyname); |
47 | if ((sfd = creat(cp, 0666)) < 0) { | |
22daf918 BJ |
48 | printf("\r\n%s: cannot creat\r\n", copyname); |
49 | return; | |
50 | } | |
51 | ||
52 | /* | |
53 | * collect parameters | |
54 | */ | |
55 | if (prompt("List command for remote system? ", buf)) { | |
56 | unlink(copyname); | |
57 | return; | |
58 | } | |
59 | transfer(buf, sfd, value(EOFREAD)); | |
60 | } | |
61 | ||
62 | /* | |
63 | * Cu-like take command | |
64 | */ | |
65 | cu_take(cc) | |
66 | char cc; | |
67 | { | |
68 | int fd, argc; | |
05862919 | 69 | char line[BUFSIZ], *expand(), *cp; |
22daf918 BJ |
70 | |
71 | if (prompt("[take] ", copyname)) | |
72 | return; | |
73 | if ((argc = args(copyname, argv)) < 1 || argc > 2) { | |
74 | printf("usage: <take> from [to]\r\n"); | |
75 | return; | |
76 | } | |
77 | if (argc == 1) | |
78 | argv[1] = argv[0]; | |
05862919 SL |
79 | cp = expand(argv[1]); |
80 | if ((fd = creat(cp, 0666)) < 0) { | |
22daf918 BJ |
81 | printf("\r\n%s: cannot create\r\n", argv[1]); |
82 | return; | |
83 | } | |
6b46907f | 84 | sprintf(line, "cat %s;echo \01", argv[0]); |
22daf918 BJ |
85 | transfer(line, fd, "\01"); |
86 | } | |
87 | ||
05862919 | 88 | static jmp_buf intbuf; |
22daf918 BJ |
89 | /* |
90 | * Bulk transfer routine -- | |
91 | * used by getfl(), cu_take(), and pipefile() | |
92 | */ | |
93 | transfer(buf, fd, eofchars) | |
94 | char *buf, *eofchars; | |
95 | { | |
96 | register int ct; | |
97 | char c, buffer[BUFSIZ]; | |
98 | register char *p = buffer; | |
99 | register int cnt, eof; | |
100 | time_t start; | |
981fd33c | 101 | sig_t f; |
79ddb7e1 | 102 | char r; |
22daf918 | 103 | |
6b46907f | 104 | pwrite(FD, buf, size(buf)); |
22daf918 | 105 | quit = 0; |
22daf918 BJ |
106 | kill(pid, SIGIOT); |
107 | read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */ | |
108 | ||
109 | /* | |
110 | * finish command | |
111 | */ | |
79ddb7e1 KB |
112 | r = '\r'; |
113 | pwrite(FD, &r, 1); | |
22daf918 BJ |
114 | do |
115 | read(FD, &c, 1); | |
116 | while ((c&0177) != '\n'); | |
117 | ioctl(0, TIOCSETC, &defchars); | |
118 | ||
ab76a038 | 119 | (void) setjmp(intbuf); |
05862919 | 120 | f = signal(SIGINT, intcopy); |
22daf918 BJ |
121 | start = time(0); |
122 | for (ct = 0; !quit;) { | |
123 | eof = read(FD, &c, 1) <= 0; | |
124 | c &= 0177; | |
125 | if (quit) | |
126 | continue; | |
127 | if (eof || any(c, eofchars)) | |
128 | break; | |
129 | if (c == 0) | |
130 | continue; /* ignore nulls */ | |
131 | if (c == '\r') | |
132 | continue; | |
133 | *p++ = c; | |
134 | ||
135 | if (c == '\n' && boolean(value(VERBOSE))) | |
136 | printf("\r%d", ++ct); | |
137 | if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) { | |
138 | if (write(fd, buffer, cnt) != cnt) { | |
139 | printf("\r\nwrite error\r\n"); | |
140 | quit = 1; | |
141 | } | |
142 | p = buffer; | |
143 | } | |
144 | } | |
145 | if (cnt = (p-buffer)) | |
146 | if (write(fd, buffer, cnt) != cnt) | |
147 | printf("\r\nwrite error\r\n"); | |
148 | ||
149 | if (boolean(value(VERBOSE))) | |
150 | prtime(" lines transferred in ", time(0)-start); | |
151 | ioctl(0, TIOCSETC, &tchars); | |
152 | write(fildes[1], (char *)&ccc, 1); | |
ab76a038 | 153 | signal(SIGINT, f); |
22daf918 BJ |
154 | close(fd); |
155 | } | |
156 | ||
157 | /* | |
158 | * FTP - remote ==> local process | |
159 | * send remote input to local process via pipe | |
160 | */ | |
161 | pipefile() | |
162 | { | |
163 | int cpid, pdes[2]; | |
164 | char buf[256]; | |
165 | int status, p; | |
166 | extern int errno; | |
167 | ||
168 | if (prompt("Local command? ", buf)) | |
169 | return; | |
170 | ||
171 | if (pipe(pdes)) { | |
172 | printf("can't establish pipe\r\n"); | |
173 | return; | |
174 | } | |
175 | ||
176 | if ((cpid = fork()) < 0) { | |
177 | printf("can't fork!\r\n"); | |
178 | return; | |
179 | } else if (cpid) { | |
180 | if (prompt("List command for remote system? ", buf)) { | |
181 | close(pdes[0]), close(pdes[1]); | |
182 | kill (cpid, SIGKILL); | |
183 | } else { | |
184 | close(pdes[0]); | |
185 | signal(SIGPIPE, intcopy); | |
186 | transfer(buf, pdes[1], value(EOFREAD)); | |
187 | signal(SIGPIPE, SIG_DFL); | |
188 | while ((p = wait(&status)) > 0 && p != cpid) | |
189 | ; | |
190 | } | |
191 | } else { | |
192 | register int f; | |
193 | ||
194 | dup2(pdes[0], 0); | |
195 | close(pdes[0]); | |
196 | for (f = 3; f < 20; f++) | |
197 | close(f); | |
198 | execute(buf); | |
199 | printf("can't execl!\r\n"); | |
200 | exit(0); | |
201 | } | |
202 | } | |
203 | ||
204 | /* | |
205 | * Interrupt service routine for FTP | |
206 | */ | |
981fd33c | 207 | void |
22daf918 BJ |
208 | stopsnd() |
209 | { | |
05862919 | 210 | |
22daf918 BJ |
211 | stop = 1; |
212 | signal(SIGINT, SIG_IGN); | |
213 | } | |
214 | ||
215 | /* | |
216 | * FTP - local ==> remote | |
217 | * send local file to remote host | |
218 | * terminate transmission with pseudo EOF sequence | |
219 | */ | |
220 | sendfile(cc) | |
221 | char cc; | |
222 | { | |
223 | FILE *fd; | |
6b46907f RC |
224 | char *fnamex; |
225 | char *expand(); | |
22daf918 BJ |
226 | |
227 | putchar(cc); | |
228 | /* | |
229 | * get file name | |
230 | */ | |
231 | if (prompt("Local file name? ", fname)) | |
232 | return; | |
233 | ||
234 | /* | |
235 | * look up file | |
236 | */ | |
6b46907f RC |
237 | fnamex = expand(fname); |
238 | if ((fd = fopen(fnamex, "r")) == NULL) { | |
22daf918 BJ |
239 | printf("%s: cannot open\r\n", fname); |
240 | return; | |
241 | } | |
242 | transmit(fd, value(EOFWRITE), NULL); | |
a2c6551c SL |
243 | if (!boolean(value(ECHOCHECK))) { |
244 | struct sgttyb buf; | |
245 | ||
246 | ioctl(FD, TIOCGETP, &buf); /* this does a */ | |
247 | ioctl(FD, TIOCSETP, &buf); /* wflushtty */ | |
248 | } | |
22daf918 BJ |
249 | } |
250 | ||
251 | /* | |
252 | * Bulk transfer routine to remote host -- | |
253 | * used by sendfile() and cu_put() | |
254 | */ | |
255 | transmit(fd, eofchars, command) | |
256 | FILE *fd; | |
257 | char *eofchars, *command; | |
258 | { | |
6b46907f | 259 | char *pc, lastc; |
22daf918 BJ |
260 | int c, ccount, lcount; |
261 | time_t start_t, stop_t; | |
981fd33c | 262 | sig_t f; |
22daf918 BJ |
263 | |
264 | kill(pid, SIGIOT); /* put TIPOUT into a wait state */ | |
22daf918 | 265 | stop = 0; |
ab76a038 | 266 | f = signal(SIGINT, stopsnd); |
22daf918 BJ |
267 | ioctl(0, TIOCSETC, &defchars); |
268 | read(repdes[0], (char *)&ccc, 1); | |
269 | if (command != NULL) { | |
270 | for (pc = command; *pc; pc++) | |
271 | send(*pc); | |
a2c6551c SL |
272 | if (boolean(value(ECHOCHECK))) |
273 | read(FD, (char *)&c, 1); /* trailing \n */ | |
274 | else { | |
275 | struct sgttyb buf; | |
276 | ||
277 | ioctl(FD, TIOCGETP, &buf); /* this does a */ | |
278 | ioctl(FD, TIOCSETP, &buf); /* wflushtty */ | |
279 | sleep(5); /* wait for remote stty to take effect */ | |
280 | } | |
22daf918 BJ |
281 | } |
282 | lcount = 0; | |
283 | lastc = '\0'; | |
284 | start_t = time(0); | |
3f48242d | 285 | while (1) { |
22daf918 BJ |
286 | ccount = 0; |
287 | do { | |
288 | c = getc(fd); | |
289 | if (stop) | |
290 | goto out; | |
291 | if (c == EOF) | |
292 | goto out; | |
6b46907f | 293 | if (c == 0177 && !boolean(value(RAWFTP))) |
22daf918 BJ |
294 | continue; |
295 | lastc = c; | |
296 | if (c < 040) { | |
6b46907f RC |
297 | if (c == '\n') { |
298 | if (!boolean(value(RAWFTP))) | |
299 | c = '\r'; | |
300 | } | |
22daf918 | 301 | else if (c == '\t') { |
6b46907f RC |
302 | if (!boolean(value(RAWFTP))) { |
303 | if (boolean(value(TABEXPAND))) { | |
22daf918 | 304 | send(' '); |
6b46907f RC |
305 | while ((++ccount % 8) != 0) |
306 | send(' '); | |
307 | continue; | |
308 | } | |
22daf918 | 309 | } |
6b46907f | 310 | } else |
929cebaa | 311 | if (!boolean(value(RAWFTP))) |
6b46907f | 312 | continue; |
22daf918 BJ |
313 | } |
314 | send(c); | |
6b46907f | 315 | } while (c != '\r' && !boolean(value(RAWFTP))); |
22daf918 BJ |
316 | if (boolean(value(VERBOSE))) |
317 | printf("\r%d", ++lcount); | |
a2c6551c | 318 | if (boolean(value(ECHOCHECK))) { |
a2c6551c | 319 | timedout = 0; |
010bfa9a | 320 | alarm((int)value(ETIMEOUT)); |
a2c6551c | 321 | do { /* wait for prompt */ |
6b46907f | 322 | read(FD, (char *)&c, 1); |
a2c6551c SL |
323 | if (timedout || stop) { |
324 | if (timedout) | |
325 | printf("\r\ntimed out at eol\r\n"); | |
326 | alarm(0); | |
327 | goto out; | |
328 | } | |
6b46907f | 329 | } while ((c&0177) != character(value(PROMPT))); |
a2c6551c SL |
330 | alarm(0); |
331 | } | |
22daf918 BJ |
332 | } |
333 | out: | |
6b46907f | 334 | if (lastc != '\n' && !boolean(value(RAWFTP))) |
22daf918 BJ |
335 | send('\r'); |
336 | for (pc = eofchars; *pc; pc++) | |
337 | send(*pc); | |
338 | stop_t = time(0); | |
339 | fclose(fd); | |
ab76a038 | 340 | signal(SIGINT, f); |
22daf918 | 341 | if (boolean(value(VERBOSE))) |
6b46907f RC |
342 | if (boolean(value(RAWFTP))) |
343 | prtime(" chars transferred in ", stop_t-start_t); | |
344 | else | |
345 | prtime(" lines transferred in ", stop_t-start_t); | |
22daf918 BJ |
346 | write(fildes[1], (char *)&ccc, 1); |
347 | ioctl(0, TIOCSETC, &tchars); | |
348 | } | |
349 | ||
350 | /* | |
351 | * Cu-like put command | |
352 | */ | |
353 | cu_put(cc) | |
354 | char cc; | |
355 | { | |
356 | FILE *fd; | |
357 | char line[BUFSIZ]; | |
358 | int argc; | |
6b46907f RC |
359 | char *expand(); |
360 | char *copynamex; | |
22daf918 BJ |
361 | |
362 | if (prompt("[put] ", copyname)) | |
363 | return; | |
364 | if ((argc = args(copyname, argv)) < 1 || argc > 2) { | |
365 | printf("usage: <put> from [to]\r\n"); | |
366 | return; | |
367 | } | |
368 | if (argc == 1) | |
369 | argv[1] = argv[0]; | |
6b46907f RC |
370 | copynamex = expand(argv[0]); |
371 | if ((fd = fopen(copynamex, "r")) == NULL) { | |
372 | printf("%s: cannot open\r\n", copynamex); | |
22daf918 BJ |
373 | return; |
374 | } | |
a2c6551c | 375 | if (boolean(value(ECHOCHECK))) |
6b46907f | 376 | sprintf(line, "cat>%s\r", argv[1]); |
a2c6551c | 377 | else |
6b46907f | 378 | sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]); |
22daf918 BJ |
379 | transmit(fd, "\04", line); |
380 | } | |
381 | ||
382 | /* | |
383 | * FTP - send single character | |
384 | * wait for echo & handle timeout | |
385 | */ | |
386 | send(c) | |
387 | char c; | |
388 | { | |
96ad7152 | 389 | char cc; |
22daf918 BJ |
390 | int retry = 0; |
391 | ||
392 | cc = c; | |
6b46907f RC |
393 | pwrite(FD, &cc, 1); |
394 | #ifdef notdef | |
395 | if (number(value(CDELAY)) > 0 && c != '\r') | |
396 | nap(number(value(CDELAY))); | |
397 | #endif | |
398 | if (!boolean(value(ECHOCHECK))) { | |
399 | #ifdef notdef | |
400 | if (number(value(LDELAY)) > 0 && c == '\r') | |
401 | nap(number(value(LDELAY))); | |
402 | #endif | |
a2c6551c | 403 | return; |
6b46907f | 404 | } |
22daf918 BJ |
405 | tryagain: |
406 | timedout = 0; | |
010bfa9a | 407 | alarm((int)value(ETIMEOUT)); |
6b46907f | 408 | read(FD, &cc, 1); |
22daf918 BJ |
409 | alarm(0); |
410 | if (timedout) { | |
411 | printf("\r\ntimeout error (%s)\r\n", ctrl(c)); | |
412 | if (retry++ > 3) | |
413 | return; | |
6b46907f | 414 | pwrite(FD, &null, 1); /* poke it */ |
22daf918 BJ |
415 | goto tryagain; |
416 | } | |
417 | } | |
418 | ||
981fd33c | 419 | void |
22daf918 BJ |
420 | timeout() |
421 | { | |
422 | signal(SIGALRM, timeout); | |
423 | timedout = 1; | |
424 | } | |
425 | ||
67d9cc23 DS |
426 | /* |
427 | * Stolen from consh() -- puts a remote file on the output of a local command. | |
428 | * Identical to consh() except for where stdout goes. | |
429 | */ | |
430 | pipeout(c) | |
431 | { | |
432 | char buf[256]; | |
433 | int cpid, status, p; | |
434 | time_t start; | |
435 | ||
436 | putchar(c); | |
437 | if (prompt("Local command? ", buf)) | |
438 | return; | |
439 | kill(pid, SIGIOT); /* put TIPOUT into a wait state */ | |
440 | signal(SIGINT, SIG_IGN); | |
441 | signal(SIGQUIT, SIG_IGN); | |
442 | ioctl(0, TIOCSETC, &defchars); | |
443 | read(repdes[0], (char *)&ccc, 1); | |
444 | /* | |
445 | * Set up file descriptors in the child and | |
446 | * let it go... | |
447 | */ | |
448 | if ((cpid = fork()) < 0) | |
449 | printf("can't fork!\r\n"); | |
450 | else if (cpid) { | |
451 | start = time(0); | |
452 | while ((p = wait(&status)) > 0 && p != cpid) | |
453 | ; | |
454 | } else { | |
455 | register int i; | |
456 | ||
457 | dup2(FD, 1); | |
458 | for (i = 3; i < 20; i++) | |
459 | close(i); | |
460 | signal(SIGINT, SIG_DFL); | |
461 | signal(SIGQUIT, SIG_DFL); | |
462 | execute(buf); | |
463 | printf("can't find `%s'\r\n", buf); | |
464 | exit(0); | |
465 | } | |
466 | if (boolean(value(VERBOSE))) | |
467 | prtime("away for ", time(0)-start); | |
468 | write(fildes[1], (char *)&ccc, 1); | |
469 | ioctl(0, TIOCSETC, &tchars); | |
470 | signal(SIGINT, SIG_DFL); | |
471 | signal(SIGQUIT, SIG_DFL); | |
472 | } | |
473 | ||
22daf918 BJ |
474 | #ifdef CONNECT |
475 | /* | |
476 | * Fork a program with: | |
59a45cf7 MT |
477 | * 0 <-> remote tty in |
478 | * 1 <-> remote tty out | |
22daf918 | 479 | * 2 <-> local tty out |
22daf918 BJ |
480 | */ |
481 | consh(c) | |
482 | { | |
483 | char buf[256]; | |
484 | int cpid, status, p; | |
485 | time_t start; | |
486 | ||
487 | putchar(c); | |
488 | if (prompt("Local command? ", buf)) | |
489 | return; | |
490 | kill(pid, SIGIOT); /* put TIPOUT into a wait state */ | |
491 | signal(SIGINT, SIG_IGN); | |
492 | signal(SIGQUIT, SIG_IGN); | |
493 | ioctl(0, TIOCSETC, &defchars); | |
494 | read(repdes[0], (char *)&ccc, 1); | |
495 | /* | |
496 | * Set up file descriptors in the child and | |
497 | * let it go... | |
498 | */ | |
499 | if ((cpid = fork()) < 0) | |
500 | printf("can't fork!\r\n"); | |
501 | else if (cpid) { | |
502 | start = time(0); | |
503 | while ((p = wait(&status)) > 0 && p != cpid) | |
504 | ; | |
505 | } else { | |
506 | register int i; | |
507 | ||
59a45cf7 MT |
508 | dup2(FD, 0); |
509 | dup2(3, 1); | |
510 | for (i = 3; i < 20; i++) | |
22daf918 BJ |
511 | close(i); |
512 | signal(SIGINT, SIG_DFL); | |
513 | signal(SIGQUIT, SIG_DFL); | |
514 | execute(buf); | |
515 | printf("can't find `%s'\r\n", buf); | |
516 | exit(0); | |
517 | } | |
518 | if (boolean(value(VERBOSE))) | |
519 | prtime("away for ", time(0)-start); | |
520 | write(fildes[1], (char *)&ccc, 1); | |
521 | ioctl(0, TIOCSETC, &tchars); | |
522 | signal(SIGINT, SIG_DFL); | |
523 | signal(SIGQUIT, SIG_DFL); | |
524 | } | |
525 | #endif | |
526 | ||
527 | /* | |
528 | * Escape to local shell | |
529 | */ | |
530 | shell() | |
531 | { | |
532 | int shpid, status; | |
533 | extern char **environ; | |
534 | char *cp; | |
535 | ||
536 | printf("[sh]\r\n"); | |
537 | signal(SIGINT, SIG_IGN); | |
538 | signal(SIGQUIT, SIG_IGN); | |
539 | unraw(); | |
540 | if (shpid = fork()) { | |
541 | while (shpid != wait(&status)); | |
542 | raw(); | |
543 | printf("\r\n!\r\n"); | |
544 | signal(SIGINT, SIG_DFL); | |
545 | signal(SIGQUIT, SIG_DFL); | |
546 | return; | |
547 | } else { | |
548 | signal(SIGQUIT, SIG_DFL); | |
549 | signal(SIGINT, SIG_DFL); | |
550 | if ((cp = rindex(value(SHELL), '/')) == NULL) | |
551 | cp = value(SHELL); | |
552 | else | |
553 | cp++; | |
45d9e9af | 554 | shell_uid(); |
22daf918 BJ |
555 | execl(value(SHELL), cp, 0); |
556 | printf("\r\ncan't execl!\r\n"); | |
557 | exit(1); | |
558 | } | |
559 | } | |
560 | ||
561 | /* | |
562 | * TIPIN portion of scripting | |
563 | * initiate the conversation with TIPOUT | |
564 | */ | |
565 | setscript() | |
566 | { | |
567 | char c; | |
568 | /* | |
569 | * enable TIPOUT side for dialogue | |
570 | */ | |
571 | kill(pid, SIGEMT); | |
572 | if (boolean(value(SCRIPT))) | |
573 | write(fildes[1], value(RECORD), size(value(RECORD))); | |
574 | write(fildes[1], "\n", 1); | |
575 | /* | |
576 | * wait for TIPOUT to finish | |
577 | */ | |
578 | read(repdes[0], &c, 1); | |
579 | if (c == 'n') | |
580 | printf("can't create %s\r\n", value(RECORD)); | |
581 | } | |
582 | ||
583 | /* | |
584 | * Change current working directory of | |
585 | * local portion of tip | |
586 | */ | |
587 | chdirectory() | |
588 | { | |
05862919 | 589 | char dirname[80]; |
22daf918 BJ |
590 | register char *cp = dirname; |
591 | ||
05862919 | 592 | if (prompt("[cd] ", dirname)) { |
22daf918 BJ |
593 | if (stoprompt) |
594 | return; | |
05862919 SL |
595 | cp = value(HOME); |
596 | } | |
22daf918 BJ |
597 | if (chdir(cp) < 0) |
598 | printf("%s: bad directory\r\n", cp); | |
599 | printf("!\r\n"); | |
600 | } | |
601 | ||
149fe345 | 602 | tipabort(msg) |
e2326c44 | 603 | char *msg; |
22daf918 | 604 | { |
6b46907f | 605 | |
22daf918 | 606 | kill(pid, SIGTERM); |
e2326c44 SL |
607 | disconnect(msg); |
608 | if (msg != NOSTR) | |
609 | printf("\r\n%s", msg); | |
22daf918 | 610 | printf("\r\n[EOT]\r\n"); |
45d9e9af | 611 | daemon_uid(); |
5d369851 | 612 | (void)uu_unlock(uucplock); |
22daf918 BJ |
613 | unraw(); |
614 | exit(0); | |
615 | } | |
616 | ||
e2326c44 SL |
617 | finish() |
618 | { | |
619 | char *dismsg; | |
620 | ||
621 | if ((dismsg = value(DISCONNECT)) != NOSTR) { | |
622 | write(FD, dismsg, strlen(dismsg)); | |
623 | sleep(5); | |
624 | } | |
149fe345 | 625 | tipabort(NOSTR); |
e2326c44 SL |
626 | } |
627 | ||
981fd33c | 628 | void |
22daf918 BJ |
629 | intcopy() |
630 | { | |
631 | raw(); | |
632 | quit = 1; | |
05862919 | 633 | longjmp(intbuf, 1); |
22daf918 BJ |
634 | } |
635 | ||
636 | execute(s) | |
637 | char *s; | |
638 | { | |
639 | register char *cp; | |
640 | ||
641 | if ((cp = rindex(value(SHELL), '/')) == NULL) | |
642 | cp = value(SHELL); | |
643 | else | |
644 | cp++; | |
29eaa516 | 645 | shell_uid(); |
22daf918 BJ |
646 | execl(value(SHELL), cp, "-c", s, 0); |
647 | } | |
648 | ||
649 | args(buf, a) | |
650 | char *buf, *a[]; | |
651 | { | |
652 | register char *p = buf, *start; | |
653 | register char **parg = a; | |
654 | register int n = 0; | |
655 | ||
656 | do { | |
657 | while (*p && (*p == ' ' || *p == '\t')) | |
658 | p++; | |
659 | start = p; | |
660 | if (*p) | |
661 | *parg = p; | |
662 | while (*p && (*p != ' ' && *p != '\t')) | |
663 | p++; | |
664 | if (p != start) | |
665 | parg++, n++; | |
666 | if (*p) | |
667 | *p++ = '\0'; | |
668 | } while (*p); | |
669 | ||
670 | return(n); | |
671 | } | |
672 | ||
673 | prtime(s, a) | |
674 | char *s; | |
675 | time_t a; | |
676 | { | |
677 | register i; | |
678 | int nums[3]; | |
679 | ||
680 | for (i = 0; i < 3; i++) { | |
681 | nums[i] = (int)(a % quant[i]); | |
682 | a /= quant[i]; | |
683 | } | |
684 | printf("%s", s); | |
685 | while (--i >= 0) | |
ab76a038 | 686 | if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0) |
22daf918 BJ |
687 | printf("%d %s%c ", nums[i], sep[i], |
688 | nums[i] == 1 ? '\0' : 's'); | |
689 | printf("\r\n!\r\n"); | |
690 | } | |
691 | ||
692 | variable() | |
693 | { | |
694 | char buf[256]; | |
695 | ||
696 | if (prompt("[set] ", buf)) | |
697 | return; | |
698 | vlex(buf); | |
699 | if (vtable[BEAUTIFY].v_access&CHANGED) { | |
700 | vtable[BEAUTIFY].v_access &= ~CHANGED; | |
3463e9c6 | 701 | kill(pid, SIGSYS); |
22daf918 BJ |
702 | } |
703 | if (vtable[SCRIPT].v_access&CHANGED) { | |
704 | vtable[SCRIPT].v_access &= ~CHANGED; | |
705 | setscript(); | |
7367df0e SL |
706 | /* |
707 | * So that "set record=blah script" doesn't | |
708 | * cause two transactions to occur. | |
709 | */ | |
710 | if (vtable[RECORD].v_access&CHANGED) | |
711 | vtable[RECORD].v_access &= ~CHANGED; | |
22daf918 BJ |
712 | } |
713 | if (vtable[RECORD].v_access&CHANGED) { | |
714 | vtable[RECORD].v_access &= ~CHANGED; | |
715 | if (boolean(value(SCRIPT))) | |
716 | setscript(); | |
717 | } | |
6b46907f RC |
718 | if (vtable[TAND].v_access&CHANGED) { |
719 | vtable[TAND].v_access &= ~CHANGED; | |
720 | if (boolean(value(TAND))) | |
721 | tandem("on"); | |
722 | else | |
723 | tandem("off"); | |
724 | } | |
725 | if (vtable[LECHO].v_access&CHANGED) { | |
726 | vtable[LECHO].v_access &= ~CHANGED; | |
727 | HD = boolean(value(LECHO)); | |
728 | } | |
729 | if (vtable[PARITY].v_access&CHANGED) { | |
730 | vtable[PARITY].v_access &= ~CHANGED; | |
731 | setparity(); | |
732 | } | |
733 | } | |
734 | ||
735 | /* | |
05862919 | 736 | * Turn tandem mode on or off for remote tty. |
6b46907f | 737 | */ |
6b46907f | 738 | tandem(option) |
05862919 | 739 | char *option; |
6b46907f RC |
740 | { |
741 | struct sgttyb rmtty; | |
742 | ||
743 | ioctl(FD, TIOCGETP, &rmtty); | |
744 | if (strcmp(option,"on") == 0) { | |
745 | rmtty.sg_flags |= TANDEM; | |
746 | arg.sg_flags |= TANDEM; | |
05862919 | 747 | } else { |
6b46907f RC |
748 | rmtty.sg_flags &= ~TANDEM; |
749 | arg.sg_flags &= ~TANDEM; | |
750 | } | |
751 | ioctl(FD, TIOCSETP, &rmtty); | |
752 | ioctl(0, TIOCSETP, &arg); | |
22daf918 | 753 | } |
061754f3 SL |
754 | |
755 | /* | |
756 | * Send a break. | |
061754f3 SL |
757 | */ |
758 | genbrk() | |
759 | { | |
05862919 | 760 | |
061754f3 SL |
761 | ioctl(FD, TIOCSBRK, NULL); |
762 | sleep(1); | |
763 | ioctl(FD, TIOCCBRK, NULL); | |
061754f3 | 764 | } |
3f48242d | 765 | |
3f48242d SL |
766 | /* |
767 | * Suspend tip | |
768 | */ | |
72b2a7a5 SL |
769 | suspend(c) |
770 | char c; | |
3f48242d | 771 | { |
05862919 | 772 | |
3f48242d | 773 | unraw(); |
3cd1a53c | 774 | kill(c == CTRL('y') ? getpid() : 0, SIGTSTP); |
3f48242d SL |
775 | raw(); |
776 | } | |
6b46907f RC |
777 | |
778 | /* | |
779 | * expand a file name if it includes shell meta characters | |
780 | */ | |
781 | ||
782 | char * | |
783 | expand(name) | |
784 | char name[]; | |
785 | { | |
786 | static char xname[BUFSIZ]; | |
787 | char cmdbuf[BUFSIZ]; | |
788 | register int pid, l, rc; | |
789 | register char *cp, *Shell; | |
790 | int s, pivec[2], (*sigint)(); | |
791 | ||
792 | if (!anyof(name, "~{[*?$`'\"\\")) | |
793 | return(name); | |
794 | /* sigint = signal(SIGINT, SIG_IGN); */ | |
795 | if (pipe(pivec) < 0) { | |
796 | perror("pipe"); | |
797 | /* signal(SIGINT, sigint) */ | |
798 | return(name); | |
799 | } | |
800 | sprintf(cmdbuf, "echo %s", name); | |
801 | if ((pid = vfork()) == 0) { | |
802 | Shell = value(SHELL); | |
803 | if (Shell == NOSTR) | |
435e8dff | 804 | Shell = _PATH_BSHELL; |
6b46907f RC |
805 | close(pivec[0]); |
806 | close(1); | |
807 | dup(pivec[1]); | |
808 | close(pivec[1]); | |
809 | close(2); | |
45d9e9af | 810 | shell_uid(); |
6b46907f RC |
811 | execl(Shell, Shell, "-c", cmdbuf, 0); |
812 | _exit(1); | |
813 | } | |
814 | if (pid == -1) { | |
815 | perror("fork"); | |
816 | close(pivec[0]); | |
817 | close(pivec[1]); | |
818 | return(NOSTR); | |
819 | } | |
820 | close(pivec[1]); | |
821 | l = read(pivec[0], xname, BUFSIZ); | |
822 | close(pivec[0]); | |
823 | while (wait(&s) != pid); | |
824 | ; | |
825 | s &= 0377; | |
826 | if (s != 0 && s != SIGPIPE) { | |
827 | fprintf(stderr, "\"Echo\" failed\n"); | |
828 | return(NOSTR); | |
829 | } | |
830 | if (l < 0) { | |
831 | perror("read"); | |
832 | return(NOSTR); | |
833 | } | |
834 | if (l == 0) { | |
835 | fprintf(stderr, "\"%s\": No match\n", name); | |
836 | return(NOSTR); | |
837 | } | |
838 | if (l == BUFSIZ) { | |
839 | fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); | |
840 | return(NOSTR); | |
841 | } | |
842 | xname[l] = 0; | |
843 | for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) | |
844 | ; | |
845 | *++cp = '\0'; | |
846 | return(xname); | |
847 | } | |
848 | ||
849 | /* | |
850 | * Are any of the characters in the two strings the same? | |
851 | */ | |
852 | ||
853 | anyof(s1, s2) | |
854 | register char *s1, *s2; | |
855 | { | |
856 | register int c; | |
857 | ||
858 | while (c = *s1++) | |
859 | if (any(c, s2)) | |
860 | return(1); | |
861 | return(0); | |
862 | } |