Removed remcap.
[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 *
cb956e54 5 * %sccs.include.redist.c%
051b1e55
DF
6 */
7
05862919 8#ifndef lint
59a45cf7 9static 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
21int quant[] = { 60, 60, 24 };
22
23char null = '\0';
24char *sep[] = { "second", "minute", "hour" };
25static char *argv[10]; /* argument vector for take and put */
26
981fd33c
KB
27void timeout(); /* timeout function called on alarm */
28void stopsnd(); /* SIGINT handler during file transfers */
29void intcopy(); /* interrupt routine for file transfers */
22daf918
BJ
30
31/*
32 * FTP - remote ==> local
33 * get a file from the remote host
34 */
35getfl(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 */
65cu_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 88static jmp_buf intbuf;
22daf918
BJ
89/*
90 * Bulk transfer routine --
91 * used by getfl(), cu_take(), and pipefile()
92 */
93transfer(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 */
161pipefile()
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 207void
22daf918
BJ
208stopsnd()
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 */
220sendfile(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 */
255transmit(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 }
333out:
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 */
353cu_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 */
386send(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
405tryagain:
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 419void
22daf918
BJ
420timeout()
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 */
430pipeout(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 */
481consh(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 */
530shell()
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 */
565setscript()
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 */
587chdirectory()
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 602tipabort(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
617finish()
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 628void
22daf918
BJ
629intcopy()
630{
631 raw();
632 quit = 1;
05862919 633 longjmp(intbuf, 1);
22daf918
BJ
634}
635
636execute(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
649args(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
673prtime(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
692variable()
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 738tandem(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 */
758genbrk()
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
769suspend(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
782char *
783expand(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
853anyof(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}