home *** CD-ROM | disk | FTP | other *** search
- /*
- * Do file name expansion with 'native' shell. Using the native shell
- * (as described in the SHELL environmental variable) allows for csh or
- * ksh abbreviations that sh doesn't recognize.
- */
-
- #include <stdio.h>
- #include <signal.h>
-
- char *
- expand(input)
- char *input;
- {
- FILE *pfp, *native_popen();
- char *ans, buf[1024], *strpbrk(), *strdup();
- extern char *null_ptr;
- void free_ptr();
-
- /* same rules as strdup() */
- if (input == NULL)
- return(NULL);
- if (*input == NULL)
- return(null_ptr);
- /* any thing to expand ? */
- ans = strdup(input);
- if (!strpbrk(input, "$*{}[]\\?~"))
- return(ans);
- /* popen an echo */
- sprintf(buf, "echo %s", input);
-
- pfp = native_popen(buf, "r");
- fgets(buf, 1024, pfp);
- native_pclose(pfp);
-
- if (!strlen(buf))
- return(ans);
- /* zap the line feed */
- buf[strlen(buf)-1] = NULL;
-
- free_ptr(ans);
- ans = strdup(buf);
- return(ans);
- }
-
- #define tst(a,b) (*mode == 'r'? (b) : (a))
- #define RDR 0
- #define WTR 1
- static int popen_pid[20];
-
- FILE *
- native_popen(cmd, mode)
- char *cmd, *mode;
- {
- int myside, hisside, pid, p[2];
- char *shellpath, *shell, *flags, *getenv(), *strrchr();
- void _exit();
-
- if (pipe(p) < 0)
- return NULL;
-
- myside = tst(p[WTR], p[RDR]);
- hisside = tst(p[RDR], p[WTR]);
- /* get the environmental variable */
- shellpath = getenv("SHELL");
- if (shellpath == NULL || strlen(shellpath) == 0)
- shellpath = "/bin/sh";
-
- shell = strrchr(shellpath, '/') + 1;
- /* fix up the flags */
- if (!strcmp(shell, "csh"))
- flags = "-fc";
- else
- flags = "-c"; /* Korn shell too */
-
- if (!(pid = fork())) {
- int stdio;
- /* no error messages please */
- close(2);
- #ifdef SGID
- setgid(getgid());
- #endif /* SGID */
- stdio = tst(0, 1);
- close(myside);
- close(stdio);
- fcntl(hisside, 0, stdio);
- close(hisside);
- execl(shellpath, shell, flags, cmd, 0);
- _exit(1);
- }
- if (pid == -1) {
- close(myside);
- close(hisside);
- return NULL;
- }
-
- popen_pid[myside] = pid;
-
- close(hisside);
- return(fdopen(myside, mode));
- }
-
- native_pclose(ptr)
- FILE *ptr;
- {
- int f, r, (*hstat)(), (*istat)(), (*qstat)(), status;
-
- f = fileno(ptr);
- fclose(ptr);
- istat = signal(SIGINT, SIG_IGN);
- qstat = signal(SIGQUIT, SIG_IGN);
- hstat = signal(SIGHUP, SIG_IGN);
-
- while ((r = wait(&status)) != popen_pid[f] && r != -1)
- ;
-
- if (r == -1)
- status = -1;
-
- signal(SIGINT, istat);
- signal(SIGQUIT, qstat);
- signal(SIGHUP, hstat);
- return(status);
- }
-