retry data connection (SO_REUSEADDR isn't enough); show directories
[unix-history] / usr / src / libexec / ftpd / popen.c
index 14d45e8..408b23f 100644 (file)
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * from this software without specific prior written permission.
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  *
- * static char sccsid[] = "@(#)popen.c 5.7 (Berkeley) 9/1/88";
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)popen.c    5.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)popen.c    5.7 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/types.h>
 #include <sys/signal.h>
 #endif /* not lint */
 
 #include <sys/types.h>
 #include <sys/signal.h>
+#include <sys/wait.h>
 #include <stdio.h>
 
 /*
 #include <stdio.h>
 
 /*
@@ -33,18 +33,18 @@ static char sccsid[] = "@(#)popen.c 5.2 (Berkeley) %G%";
  * 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.
  */
-static uid_t *pids;
+static int *pids;
 static int fds;
 
 FILE *
 static int fds;
 
 FILE *
-popen(program, type)
+ftpd_popen(program, type)
        char *program, *type;
 {
        register char *cp;
        FILE *iop;
        int argc, gargc, pdes[2], pid;
        char **pop, *argv[100], *gargv[1000], *vv[2];
        char *program, *type;
 {
        register char *cp;
        FILE *iop;
        int argc, gargc, pdes[2], pid;
        char **pop, *argv[100], *gargv[1000], *vv[2];
-       extern char **glob(), **copyblk(), *strtok();
+       extern char **glob(), **copyblk(), *strtok(), *malloc();
 
        if (*type != 'r' && *type != 'w' || type[1])
                return(NULL);
 
        if (*type != 'r' && *type != 'w' || type[1])
                return(NULL);
@@ -52,10 +52,9 @@ popen(program, type)
        if (!pids) {
                if ((fds = getdtablesize()) <= 0)
                        return(NULL);
        if (!pids) {
                if ((fds = getdtablesize()) <= 0)
                        return(NULL);
-               if (!(pids =
-                   (uid_t *)malloc((u_int)(fds * sizeof(uid_t)))))
+               if ((pids = (int *)malloc((u_int)(fds * sizeof(int)))) == NULL)
                        return(NULL);
                        return(NULL);
-               bzero(pids, fds * sizeof(uid_t));
+               bzero((char *)pids, fds * sizeof(int));
        }
        if (pipe(pdes) < 0)
                return(NULL);
        }
        if (pipe(pdes) < 0)
                return(NULL);
@@ -84,12 +83,13 @@ popen(program, type)
        case -1:                        /* error */
                (void)close(pdes[0]);
                (void)close(pdes[1]);
        case -1:                        /* error */
                (void)close(pdes[0]);
                (void)close(pdes[1]);
-               goto free;
+               goto pfree;
                /* NOTREACHED */
        case 0:                         /* child */
                if (*type == 'r') {
                        if (pdes[1] != 1) {
                                dup2(pdes[1], 1);
                /* NOTREACHED */
        case 0:                         /* child */
                if (*type == 'r') {
                        if (pdes[1] != 1) {
                                dup2(pdes[1], 1);
+                               dup2(pdes[1], 2);       /* stderr, too! */
                                (void)close(pdes[1]);
                        }
                        (void)close(pdes[0]);
                                (void)close(pdes[1]);
                        }
                        (void)close(pdes[0]);
@@ -113,29 +113,31 @@ popen(program, type)
        }
        pids[fileno(iop)] = pid;
 
        }
        pids[fileno(iop)] = pid;
 
-free:  for (argc = 1; argv[argc] != NULL; argc++)
+pfree: for (argc = 1; argv[argc] != NULL; argc++) {
                blkfree((char **)argv[argc]);
                blkfree((char **)argv[argc]);
+               free((char *)argv[argc]);
+       }
        return(iop);
 }
 
        return(iop);
 }
 
-pclose(iop)
+ftpd_pclose(iop)
        FILE *iop;
 {
        register int fdes;
        FILE *iop;
 {
        register int fdes;
-       long omask;
-       int pid, stat_loc;
-       u_int waitpid();
+       int omask;
+       union wait stat_loc;
+       int pid;
 
        /*
         * pclose returns -1 if stream is not associated with a
         * `popened' command, or, if already `pclosed'.
         */
 
        /*
         * pclose returns -1 if stream is not associated with a
         * `popened' command, or, if already `pclosed'.
         */
-       if (pids[fdes = fileno(iop)] == 0)
+       if (pids == 0 || pids[fdes = fileno(iop)] == 0)
                return(-1);
        (void)fclose(iop);
        omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
        while ((pid = wait(&stat_loc)) != pids[fdes] && pid != -1);
        (void)sigsetmask(omask);
        pids[fdes] = 0;
                return(-1);
        (void)fclose(iop);
        omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGHUP));
        while ((pid = wait(&stat_loc)) != pids[fdes] && pid != -1);
        (void)sigsetmask(omask);
        pids[fdes] = 0;
-       return(stat_loc);
+       return(pid == -1 ? -1 : stat_loc.w_status);
 }
 }