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