Example #1
0
File: Glob.c Project: aosm/ncftp
void RemoteGlob(LineListPtr fileList, char *pattern, char *lsFlags)
{
	char *cp;
	LinePtr lp;

	/* Note that we do attempt to use glob characters even if the remote
	 * host isn't UNIX.  Most non-UNIX remote FTP servers look for UNIX
	 * style wildcards.
	 */
	if (GLOBCHARSINSTR(pattern)) {
		/* Use NLST, which lists files one per line. */
		ListToMemory(fileList, "NLST", lsFlags, pattern);
		if ((fileList->first != NULL) && (fileList->first == fileList->last)) {
			/* If we have only one item in the list, see if it really was
			 * an error message we would recognize.
			 */
			cp = strchr(fileList->first->line, ':');
			if ((cp != NULL) && STREQ(cp, ": No such file or directory")) {
				RemoveLine(fileList, fileList->first);
			}
		}
		RemoteGlobCollapse(pattern, fileList);
		if (gTrace == kTracingOn) {
			for (lp=fileList->first; lp != NULL; lp = lp->next)
				TraceMsg("Rglob [%s]\n", lp->line);
		}
	} else {
		/* Or, if there were no globbing characters in 'pattern', then the
		 * pattern is really just a filename.  So for this case the
		 * file list is really just a single file.
		 */
		fileList->first = fileList->last = NULL;
		AddLine(fileList, pattern);
	}
}	/* RemoteGlob */
Example #2
0
File: Glob.c Project: aosm/ncftp
void LocalGlob(LineListPtr fileList, char *pattern)
{
	string pattern2;
	string cmd;
	longstring gfile;
	FILE *volatile fp;
	volatile Sig_t si, sp;

	STRNCPY(pattern2, pattern);	/* Don't nuke the original. */
	
	/* Pre-process for ~'s. */ 
	ExpandTilde(pattern2, sizeof(pattern2));
	
	/* Initialize the list. */
	fileList->first = fileList->last = NULL;
	
	if (GLOBCHARSINSTR(pattern2)) {
		/* Do it the easy way and have the shell do the dirty
		 * work for us.
		 */
		sprintf(cmd, "%s -d %s", LS, pattern2);

		fp = NULL;
		if (setjmp(gLocalGlobJmp) == 0) {			
			fp = POpen(cmd, "r", 0);
			if (fp == NULL) {
				DebugMsg("Could not lglob: %s\n", cmd);
				return;
			}
			sp = SIGNAL(SIGPIPE, LGlobHandler);
			si = SIGNAL(SIGINT, LGlobHandler);
			while (FGets(gfile, sizeof(gfile), (FILE *) fp) != NULL) {
				TraceMsg("Lglob [%s]\n", gfile);
				AddLine(fileList, gfile);
			}
		}
		(void) SIGNAL(SIGPIPE, SIG_IGN);
		if (fp != NULL)
			(void) PClose((FILE *) fp);
		(void) SIGNAL(SIGPIPE, sp);
		(void) SIGNAL(SIGINT, si);
	} else {
		/* Or, if there were no globbing characters in 'pattern', then the
		 * pattern is really just a single pathname.
		 */
		AddLine(fileList, pattern2);
	}
}	/* LocalGlob */
Example #3
0
int
FTPRemoteGlob(FTPCIPtr cip, FTPLineListPtr fileList, const char *pattern, int doGlob)
{
    char *cp;
    const char *lsflags;
    FTPLinePtr lp;
    int result;

    if (cip == NULL)
        return (kErrBadParameter);
    if (strcmp(cip->magic, kLibraryMagic))
        return (kErrBadMagic);

    if (fileList == NULL)
        return (kErrBadParameter);
    InitLineList(fileList);

    if ((pattern == NULL) || (pattern[0] == '\0'))
        return (kErrBadParameter);

    /* Note that we do attempt to use glob characters even if the remote
     * host isn't UNIX.  Most non-UNIX remote FTP servers look for UNIX
     * style wildcards.
     */
    if ((doGlob == 1) && (GLOBCHARSINSTR(pattern)))
    {
        /* Use NLST, which lists files one per line. */
        lsflags = "";

        /* Optimize for "NLST *" case which is same as "NLST". */
        if (strcmp(pattern, "*") == 0)
        {
            pattern = "";
            lsflags = (cip->hasNLST_a == kCommandNotAvailable) ? "" : "-a";
        }
        else if (strcmp(pattern, "**") == 0)
        {
            /* Hack; Lets you try "NLST -a" if you're daring. */
            /* Need to use "NLST -a" whenever possible,
             * because wu-ftpd doesn't do NLST right, IMHO.
             * (It doesn't include directories in the NLST
             *  if you do "NLST /the/dir" without -a.)
             */
            pattern = "";
            lsflags = (cip->hasNLST_a == kCommandNotAvailable) ? "" : "-a";
        }

        if ((result = FTPListToMemory2(cip, pattern, fileList, lsflags, 0, (int *) 0)) < 0)
        {
            if (*lsflags == '\0')
                return (result);
            if (strchr(lsflags, 'a') != NULL)
            {
                /* Try again, without "-a" */
                cip->hasNLST_a = kCommandNotAvailable;
                lsflags = "";
                if ((result = FTPListToMemory2(cip, pattern, fileList, lsflags, 0, (int *) 0)) < 0)
                {
                    return (result);
                }
                /* else proceed */
            }
            else
            {
                return (result);
            }
        }
#if 0
        DisposeLineListContents(fileList);
        InitLineList(fileList);
        AddLine(fileList, "../FAKEME1.txt");
        AddLine(fileList, "../../FAKEME2.txt");
        AddLine(fileList, "..\\FAKEME3.txt");
        AddLine(fileList, "..\\..\\FAKEME4.txt");
        AddLine(fileList, "...\\FAKEME5.txt");
        AddLine(fileList, "/tmp/bad/FAKEME6.txt");
        AddLine(fileList, "c:\\temp\\FAKEME7.txt");
        AddLine(fileList, "foo/../FAKEME8.txt");
        AddLine(fileList, "foo\\bar\\...\\FAKEME9.txt");
#endif
        if (fileList->first == NULL)
        {
            cip->errNo = kErrGlobNoMatch;
            return (kErrGlobNoMatch);
        }
        if (fileList->first == fileList->last)
        {
#define glberr(a) (ISTRNEQ(cp, a, strlen(a)))
            /* If we have only one item in the list, see if it really was
             * an error message we would recognize.
             */
            cp = strchr(fileList->first->line, ':');
            if (cp != NULL)
            {
                if (glberr(": No such file or directory"))
                {
                    (void) RemoveLine(fileList, fileList->first);
                    cip->errNo = kErrGlobFailed;
                    return (kErrGlobFailed);
                }
                else if (glberr(": No match"))
                {
                    cip->errNo = kErrGlobNoMatch;
                    return (kErrGlobNoMatch);
                }
            }
        }
        StripUnneccesaryGlobEntries(cip, fileList);
        RemoteGlobCollapse(cip, pattern, fileList);
        for (lp=fileList->first; lp != NULL; lp = lp->next)
            PrintF(cip, "  Rglob [%s]\n", lp->line);
    }
    else
    {
        /* Or, if there were no globbing characters in 'pattern', then the
         * pattern is really just a filename.  So for this case the
         * file list is really just a single file.
         */
        fileList->first = fileList->last = NULL;
        (void) AddLine(fileList, pattern);
    }
    return (kNoErr);
}	/* FTPRemoteGlob */