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