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