int
main(int argc, char **argv)
{
	char	**res, **p;

	argc--, argv++;
	while (argc--)  {
		printf("%s\n", *argv);
		res = ftpglob(*argv++);
		if (res == 0) {
			printf("=> %s\n", globerr);
			continue;
		}
		for (p = res; *p; p++) {
			printf("  %s\n", *p);
			free(*p);
		}
		free(res);
	}
	return 0;
}
FILE *
ftpd_popen(char *program, char *type, int closestderr)
{
    register char *cp;
    FILE *iop;
    int argc,
      gargc,
      pdes[2],
      pid;
    char **pop,
     *argv[100],
     *gargv[1000],
     *vv[2];
    extern char **ftpglob(register char *v),
    **copyblk(register char **v),
     *strspl(register char *cp, register char *dp);

    if (*type != 'r' && *type != 'w' || type[1])
        return (NULL);

    if (!pids) {
#ifndef HAVE_GETDTABLESIZE
        struct rlimit rlp;

		rlp.rlim_cur = rlp.rlim_max = RLIM_INFINITY;
		if (getrlimit( RLIMIT_NOFILE, &rlp ) )
			return(NULL);
		fds = rlp.rlim_cur;
#else
        if ((fds = getdtablesize()) <= 0)
            return (NULL);
#endif

        if ((pids = (int *) malloc((u_int) (fds * sizeof(int)))) == NULL)
              return (NULL);
#ifdef USG
        (void) memset((char *)pids, fds * sizeof(int), 0);
#else
        bzero((char *) pids, fds * sizeof(int));
#endif
    }
    if (pipe(pdes) < 0)
        return (NULL);

    /* break up string into pieces */
    for (argc = 0, cp = program;; cp = NULL)
        if (!(argv[argc++] = strtok(cp, " \t\n")))
            break;

    /* glob each piece */
    gargv[0] = argv[0];
    for (gargc = argc = 1; argv[argc]; argc++) {
        if (!(pop = ftpglob(argv[argc]))) { /* globbing failed */
            vv[0] = strspl(argv[argc], "");
            vv[1] = NULL;
            pop = copyblk(vv);
        }
        argv[argc] = (char *) pop;  /* save to free later */
        while (*pop && gargc < 1000)
            gargv[gargc++] = *pop++;
    }
    gargv[gargc] = NULL;

    iop = NULL;
    switch (pid = vfork()) {
    case -1:                    /* error */
        (void) close(pdes[0]);
        (void) close(pdes[1]);
        goto pfree;
        /* NOTREACHED */
    case 0:                 /* child */
        if (*type == 'r') {
            if (pdes[1] != 1) {
                dup2(pdes[1], 1);
                if (closestderr)
                    (void) close(2);
                else 
                    dup2(pdes[1], 2);  /* stderr, too! */
                (void) close(pdes[1]);
            }
            (void) close(pdes[0]);
        } else {
            if (pdes[0] != 0) {
                dup2(pdes[0], 0);
                (void) close(pdes[0]);
            }
            (void) close(pdes[1]);
        }
        execv(gargv[0], gargv);
        _exit(1);
    }
    /* parent; assume fdopen can't fail...  */
    if (*type == 'r') {
        iop = fdopen(pdes[0], type);
        (void) close(pdes[1]);
    } else {
        iop = fdopen(pdes[1], type);
        (void) close(pdes[0]);
    }
    pids[fileno(iop)] = pid;

  pfree:for (argc = 1; argv[argc] != NULL; argc++) {
        blkfree((char **) argv[argc]);
        free((char *) argv[argc]);
    }
    return (iop);
}