BSD 4_4_Lite1 release
[unix-history] / usr / src / libexec / ftpd / popen.c
index 3d69ae4..b26732e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1988, 1993
+ * Copyright (c) 1988, 1993, 1994
  *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software written by Ken Arnold and
  *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software written by Ken Arnold and
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)popen.c    8.1 (Berkeley) 6/4/93";
+static char sccsid[] = "@(#)popen.c    8.3 (Berkeley) 4/6/94";
 #endif /* not lint */
 
 #include <sys/types.h>
 #include <sys/wait.h>
 
 #endif /* not lint */
 
 #include <sys/types.h>
 #include <sys/wait.h>
 
+#include <errno.h>
+#include <glob.h>
 #include <signal.h>
 #include <signal.h>
-#include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+
 #include "extern.h"
 
 /*
 #include "extern.h"
 
 /*
- * Special version of popen which avoids call to shell.  This insures noone
+ * Special version of popen which avoids call to shell.  This ensures noone
  * may create a pipe to a hidden program as a side effect of a list or dir
  * command.
  */
  * may create a pipe to a hidden program as a side effect of a list or dir
  * command.
  */
@@ -61,23 +64,23 @@ FILE *
 ftpd_popen(program, type)
        char *program, *type;
 {
 ftpd_popen(program, type)
        char *program, *type;
 {
-       register char *cp;
+       char *cp;
        FILE *iop;
        int argc, gargc, pdes[2], pid;
        FILE *iop;
        int argc, gargc, pdes[2], pid;
-       char **pop, *argv[100], *gargv[1000], *vv[2];
+       char **pop, *argv[100], *gargv[1000];
 
        if (*type != 'r' && *type != 'w' || type[1])
 
        if (*type != 'r' && *type != 'w' || type[1])
-               return(NULL);
+               return (NULL);
 
        if (!pids) {
                if ((fds = getdtablesize()) <= 0)
 
        if (!pids) {
                if ((fds = getdtablesize()) <= 0)
-                       return(NULL);
+                       return (NULL);
                if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
                if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
-                       return(NULL);
+                       return (NULL);
                memset(pids, 0, fds * sizeof(int));
        }
        if (pipe(pdes) < 0)
                memset(pids, 0, fds * sizeof(int));
        }
        if (pipe(pdes) < 0)
-               return(NULL);
+               return (NULL);
 
        /* break up string into pieces */
        for (argc = 0, cp = program;; cp = NULL)
 
        /* break up string into pieces */
        for (argc = 0, cp = program;; cp = NULL)
@@ -87,14 +90,16 @@ ftpd_popen(program, type)
        /* glob each piece */
        gargv[0] = argv[0];
        for (gargc = argc = 1; argv[argc]; argc++) {
        /* glob each piece */
        gargv[0] = argv[0];
        for (gargc = argc = 1; argv[argc]; argc++) {
-               if (!(pop = ftpglob(argv[argc]))) {     /* globbing failed */
-                       vv[0] = argv[argc];
-                       vv[1] = NULL;
-                       pop = copyblk(vv);
-               }
-               argv[argc] = (char *)pop;               /* save to free later */
-               while (*pop && gargc < 1000)
-                       gargv[gargc++] = *pop++;
+               glob_t gl;
+               int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
+
+               memset(&gl, 0, sizeof(gl));
+               if (glob(argv[argc], flags, NULL, &gl))
+                       gargv[gargc++] = strdup(argv[argc]);
+               else
+                       for (pop = gl.gl_pathv; *pop; pop++)
+                               gargv[gargc++] = strdup(*pop);
+               globfree(&gl);
        }
        gargv[gargc] = NULL;
 
        }
        gargv[gargc] = NULL;
 
@@ -107,15 +112,15 @@ ftpd_popen(program, type)
                /* NOTREACHED */
        case 0:                         /* child */
                if (*type == 'r') {
                /* NOTREACHED */
        case 0:                         /* child */
                if (*type == 'r') {
-                       if (pdes[1] != 1) {
-                               dup2(pdes[1], 1);
-                               dup2(pdes[1], 2);       /* stderr, too! */
+                       if (pdes[1] != STDOUT_FILENO) {
+                               dup2(pdes[1], STDOUT_FILENO);
                                (void)close(pdes[1]);
                        }
                                (void)close(pdes[1]);
                        }
+                       dup2(STDOUT_FILENO, STDERR_FILENO); /* stderr too! */
                        (void)close(pdes[0]);
                } else {
                        (void)close(pdes[0]);
                } else {
-                       if (pdes[0] != 0) {
-                               dup2(pdes[0], 0);
+                       if (pdes[0] != STDIN_FILENO) {
+                               dup2(pdes[0], STDIN_FILENO);
                                (void)close(pdes[0]);
                        }
                        (void)close(pdes[1]);
                                (void)close(pdes[0]);
                        }
                        (void)close(pdes[1]);
@@ -133,32 +138,34 @@ ftpd_popen(program, type)
        }
        pids[fileno(iop)] = pid;
 
        }
        pids[fileno(iop)] = pid;
 
-pfree: for (argc = 1; argv[argc] != NULL; argc++) {
-               blkfree((char **)argv[argc]);
-               free((char *)argv[argc]);
-       }
-       return(iop);
+pfree: for (argc = 1; gargv[argc] != NULL; argc++)
+               free(gargv[argc]);
+
+       return (iop);
 }
 
 int
 ftpd_pclose(iop)
        FILE *iop;
 {
 }
 
 int
 ftpd_pclose(iop)
        FILE *iop;
 {
-       register int fdes;
-       int omask;
-       union wait stat_loc;
-       int pid;
+       int fdes, omask, status;
+       pid_t pid;
 
        /*
         * pclose returns -1 if stream is not associated with a
         * `popened' command, or, if already `pclosed'.
         */
        if (pids == 0 || pids[fdes = fileno(iop)] == 0)
 
        /*
         * pclose returns -1 if stream is not associated with a
         * `popened' command, or, if already `pclosed'.
         */
        if (pids == 0 || pids[fdes = fileno(iop)] == 0)
-               return(-1);
+               return (-1);
        (void)fclose(iop);
        omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
        (void)fclose(iop);
        omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
-       while ((pid = wait((int *)&stat_loc)) != pids[fdes] && pid != -1);
+       while ((pid = waitpid(pids[fdes], &status, 0)) < 0 && errno == EINTR)
+               continue;
        (void)sigsetmask(omask);
        pids[fdes] = 0;
        (void)sigsetmask(omask);
        pids[fdes] = 0;
-       return(pid == -1 ? -1 : stat_loc.w_status);
+       if (pid < 0)
+               return (pid);
+       if (WIFEXITED(status))
+               return (WEXITSTATUS(status));
+       return (1);
 }
 }