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