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