date and time created 87/02/05 15:19:17 by slatteng
[unix-history] / usr / src / usr.bin / tip / cmds.c
CommitLineData
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 8static 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
18int quant[] = { 60, 60, 24 };
19
20char null = '\0';
21char *sep[] = { "second", "minute", "hour" };
22static char *argv[10]; /* argument vector for take and put */
23
24int timeout(); /* timeout function called on alarm */
25int stopsnd(); /* SIGINT handler during file transfers */
26int intprompt(); /* used in handling SIG_INT during prompt */
27int intcopy(); /* interrupt routine for file transfers */
28
29/*
30 * FTP - remote ==> local
31 * get a file from the remote host
32 */
33getfl(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 */
63cu_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 86static jmp_buf intbuf;
22daf918
BJ
87/*
88 * Bulk transfer routine --
89 * used by getfl(), cu_take(), and pipefile()
90 */
91transfer(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 */
157pipefile()
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 */
203stopsnd()
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 */
215sendfile(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 */
250transmit(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 }
328out:
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 */
348cu_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 */
381send(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
400tryagain:
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
414timeout()
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 */
424pipeout(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 */
477consh(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 */
526shell()
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 */
560setscript()
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 */
582chdirectory()
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
597abort(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
613finish()
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
624intcopy()
625{
05862919 626
22daf918
BJ
627 raw();
628 quit = 1;
05862919 629 longjmp(intbuf, 1);
22daf918
BJ
630}
631
632execute(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
644args(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
668prtime(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
687variable()
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 733tandem(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 */
753genbrk()
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
764suspend(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
777char *
778expand(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
847anyof(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}