Beispiel #1
0
Datei: Get.c Projekt: aosm/ncftp
/* View one or more remote files through your pager. */
int CatCmd(int argc, char **argv)
{
	int i, result, errs;
	LineList globFiles;
	LinePtr globFile;

	MultiLineInit();
	for (i=1, errs=0; i<argc; i++) {
		InitLineList(&globFiles);
		RemoteGlob(&globFiles, argv[i], kListNoFlags);
		for (globFile = globFiles.first; globFile != NULL;
			globFile = globFile->next)
		{
			result = DoCat(globFile->line);
			if (result < 0)
				--errs;
			if (gXferAbortFlag == SIGINT)
				break;	/* Don't get rest of files if you interrupted. */
			if (argc > 2)
				MultiLinePrintF("### End of file %s ###\n", globFile->line);
		}
		DisposeLineListContents(&globFiles);
	}

	return (errs);
}	/* CatCmd */
Beispiel #2
0
/* May need this later. */
static void
CheckForLS_d(FTPCIPtr cip)
{
	FTPLineList lines;
	char *cp;

	if (cip->hasNLST_d == kCommandAvailabilityUnknown) {
		if (FTPListToMemory2(cip, ".", &lines, "-d ", 0, (int *) 0) == kNoErr) {
			if ((lines.first != NULL) && (lines.first == lines.last)) {
				/* If we have only one item in the list, see if it really was
				 * an error message we would recognize.
				 */
				cp = strchr(lines.first->line, ':');
				if ((cp != NULL) && STREQ(cp, ": No such file or directory")) {
					cip->hasNLST_d = kCommandNotAvailable;
				} else {
					cip->hasNLST_d = kCommandAvailable;
				}
			} else {
				cip->hasNLST_d = kCommandNotAvailable;
			}
		} else {
			cip->hasNLST_d = kCommandNotAvailable;
		}
		DisposeLineListContents(&lines);
	}
}	/* CheckForLS_d */
Beispiel #3
0
Datei: Get.c Projekt: aosm/ncftp
int DoGetWithGlobbingAndRecursion(GetOptionsPtr gopt)
{
	int err;
	LineList globFiles;
	LinePtr globFile;
	char *cp;
	int fType;
	int result;
	longstring rcwd;
		
	err = 0;
	InitLineList(&globFiles);
	RemoteGlob(&globFiles, gopt->rName, kListNoFlags);
	
	for (globFile = globFiles.first; globFile != NULL;
		globFile = globFile->next)
	{
		if (gXferAbortFlag == SIGINT)
			break;	/* Don't get rest of files if you interrupted. */
		if (gopt->recursive) {
			fType = RemoteFileType(globFile->line);
			if (fType == 'd') {
				if ((cp = strrchr(globFile->line, '/')) != NULL) {
					/* If the user said something like
					 * "get -R /pub/a/b/c/d" we want to just write the
					 * contents of the 'd' as a subdirectory of the local
					 * directory, and not create ./pub, ./pub/a, etc.
					 */
					STRNCPY(rcwd, gRemoteCWD);
					*cp++ = '\0';
					if (DoChdir(globFile->line) == 0) {
						GetDir(gopt, cp, gRemoteCWD, gLocalCWD);
					}
					/* Restore the directory we were in before. */
					(void) DoChdir(rcwd);
				} else {
					/* Otherwise, the user gave a simple path, so it was
					 * something like "get -R pub"
					 */
					GetDir(gopt, globFile->line, gRemoteCWD, gLocalCWD);
				}
			} else if (fType == 'l') {
				EPrintF("Ignoring symbolic link '%s'\n",
					globFile->line);
			} else if (fType == '-') {
				goto regFile;
			}
		} else {
regFile:
			gopt->rName = globFile->line;
			gopt->lName = NULL;	/* Make it later. */
			result = DoGet(gopt);
			if (result < 0)
				err = -1;
		}
	}
	DisposeLineListContents(&globFiles);
	
	return (err);
}	/* DoGetWithGlobbingAndRecursion */
Beispiel #4
0
Datei: Get.c Projekt: aosm/ncftp
static
int GetSymLinkInfo(char *dst, size_t siz, char *rLink)
{
	LineList fileList;
	char *cp;
	int result;

	result = -1;
	*dst = '\0';
	InitLineList(&fileList);
	ListToMemory(&fileList, "LIST", kListDirNamesOnlyMode, rLink);
	if (fileList.first != NULL) {
		cp = fileList.first->line;
		*cp++ = '\0';
		for (cp += strlen(cp) - 1; ; cp--) {
			if (*cp == '\0')
				goto done;
			if ((cp[0] == '>') && (cp[-1] == '-'))
				break;
		}
		(void) Strncpy(dst, cp + 2, siz);
		result = 0;
	}
done:
	DisposeLineListContents(&fileList);
	return (result);
}	/* GetSymLinkInfo */
Beispiel #5
0
int
FTPDelete(const FTPCIPtr cip, const char *const pattern, const int recurse, const int doGlob)
{
	FTPLineList fileList;
	FTPLinePtr filePtr;
	char *file;
	int onceResult, batchResult;

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

	batchResult = FTPRemoteGlob(cip, &fileList, pattern, doGlob);
	if (batchResult != kNoErr)
		return (batchResult);

	for (batchResult = kNoErr, filePtr = fileList.first;
		filePtr != NULL;
		filePtr = filePtr->next)
	{
		file = filePtr->line;
		if (file == NULL) {
			batchResult = kErrBadLineList;
			cip->errNo = kErrBadLineList;
			break;
		}
		onceResult = FTPCmd(cip, "DELE %s", file);
		if (onceResult < 0) {
			batchResult = onceResult;
			break;
		}
		if (onceResult != 2) {
			if (recurse != kRecursiveYes) {
				batchResult = kErrDELEFailed;
				cip->errNo = kErrDELEFailed;
			} else {
				onceResult = FTPCmd(cip, "RMD %s", file); 	
				if (onceResult < 0) {
					batchResult = onceResult;
					break;
				}
				if (onceResult != 2) {
					onceResult = FTPRmdirRecursive(cip, file);
					if (onceResult < 0) {
						batchResult = kErrRMDFailed;
						cip->errNo = kErrRMDFailed;
					}
				}
			}
		}
	}
	DisposeLineListContents(&fileList);
	return (batchResult);
}	/* FTPDelete */
Beispiel #6
0
Datei: Get.c Projekt: aosm/ncftp
/* View one or more remote files through your pager. */
int PageCmd(int argc, char **argv)
{
	int i, result, errs;
	LineList globFiles;
	LinePtr globFile;
	char *pagerProg;

	if (STREQ(argv[1], "-b") && (gWinInit > 0) && (argc > 2)) {
		/* A hack to let you use the built-in pager like you
		 * can with the lpage command.
		 */
		pagerProg = NULL;	/* Use built-in */
		i = 2;
	} else {
		if (gPager[0] == '\0') {
			EPrintF("You haven't specified a program to use as a pager.\n");
			EPrintF("You can set this from the preferences screen (prefs command).\n");
			return -1;
		}
		pagerProg = gPager;
		i = 1;
	}

	for (errs=0; i<argc; i++) {
		InitLineList(&globFiles);
		RemoteGlob(&globFiles, argv[i], kListNoFlags);
		for (globFile = globFiles.first; globFile != NULL;
			globFile = globFile->next)
		{
			if (pagerProg == NULL)
				result = DoCat(globFile->line);
			else
				result = DoPage(globFile->line);
			if (result < 0)
				--errs;
			if (gXferAbortFlag == SIGINT)
				break;	/* Don't get rest of files if you interrupted. */
		}
		DisposeLineListContents(&globFiles);
	}

	return (errs);
}	/* PageCmd */
Beispiel #7
0
Datei: Glob.c Projekt: aosm/ncftp
int RGlobCmd(int argc, char **argv)
{
	LineList globFiles;
	LinePtr globFile;
	int i;

	MultiLineInit();	
	for (i=1; i<argc; i++) {
		InitLineList(&globFiles);
		RemoteGlob(&globFiles, argv[i], kListNoFlags);

		for (globFile = globFiles.first; globFile != NULL;
			globFile = globFile->next)
		{
			MultiLinePrintF("%s\n", globFile->line);
		}
		DisposeLineListContents(&globFiles);
	}
	return (0);
}	/* RGlobCmd */
Beispiel #8
0
int
FTPChmod(const FTPCIPtr cip, const char *const pattern, const char *const mode, const int doGlob)
{
	FTPLineList fileList;
	FTPLinePtr filePtr;
	char *file;
	int onceResult, batchResult;

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

	batchResult = FTPRemoteGlob(cip, &fileList, pattern, doGlob);
	if (batchResult != kNoErr)
		return (batchResult);

	for (batchResult = kNoErr, filePtr = fileList.first;
		filePtr != NULL;
		filePtr = filePtr->next)
	{
		file = filePtr->line;
		if (file == NULL) {
			batchResult = kErrBadLineList;
			cip->errNo = kErrBadLineList;
			break;
		}
		onceResult = FTPCmd(cip, "SITE CHMOD %s %s", mode, file); 	
		if (onceResult < 0) {
			batchResult = onceResult;
			break;
		}
		if (onceResult != 2) {
			batchResult = kErrChmodFailed;
			cip->errNo = kErrChmodFailed;
		}
	}
	DisposeLineListContents(&fileList);
	return (batchResult);
}	/* FTPChmod */
Beispiel #9
0
Datei: Get.c Projekt: aosm/ncftp
int RemoteFileType(char *fName)
{
	LineList fileList;
	char *cp;
	int result;
	int i;

	result = 0;
	InitLineList(&fileList);
	ListToMemory(&fileList, "LIST", kListDirNamesOnlyMode, fName);
	if (fileList.first != NULL) {
		cp = fileList.first->line;
		/* Do a quick check and see if it looks like a unix ls line. */
		for (i=1; i<=3; i++)
			if ((cp[i] != 'r') && (cp[i] != 'w') && (cp[i] != 'x') && (cp[i] != '-'))
				goto done;
		result = (int) cp[0];
	}
done:
	DisposeLineListContents(&fileList);
	return (result);
}	/* RemoteFileType */
Beispiel #10
0
static void
FTPDeallocateHost(const FTPCIPtr cip)
{
	/* Requires the cip->bufSize field set,
	 * and the cip->buf set if the
	 * buffer is allocated.
	 */
	if (cip->buf != NULL) {
		(void) memset(cip->buf, 0, cip->bufSize);
		free(cip->buf);
		cip->buf = NULL;
	}

	if (cip->startingWorkingDirectory != NULL) {
		free(cip->startingWorkingDirectory);
		cip->startingWorkingDirectory = NULL;
	}

#if USE_SIO
	DisposeSReadlineInfo(&cip->ctrlSrl);
#endif
	DisposeLineListContents(&cip->lastFTPCmdResultLL);
}	/* FTPDeallocateHost */
Beispiel #11
0
/* This mess is essentially the local version of Ftw with FTP
 * grafted onto it, so see that and grok that before studying this.
 */
static int
FTPFtwTraverse(const FtwInfoPtr ftwip, size_t dirPathLen, int depth)
{
	char *cp;
	size_t fnLen;
	mode_t m;
	char *filename;
	char *newBuf;
	char *path = ftwip->curPath;
	int nSubdirs;
	FtwSubDirListPtr head = NULL, tail = NULL, sdp, nextsdp;
	int rc = (-1);
	int lsl, mls, unlsrc;
	FTPCIPtr cip = (FTPCIPtr) ftwip->cip;
	FTPLineList ll;
	FTPFileInfoList fil;
	FTPLinePtr filePtr;
	FTPFileInfoPtr fip;
	int result;
	int isRootDir;
	longest_int sz;

	isRootDir = ((dirPathLen == 1) && ((path[0] == '/') || (path[0] == '\\'))) ? 1 : 0;
	filePtr = NULL;
	fip = NULL;
	mls = 0;
	lsl = 0;

	if (cip->hasMLSD == kCommandAvailable) {
		mls = 1;
		if (((result = FTPListToMemory2(cip, dirPathLen ? path : ".", &ll, "-a", 0, &mls)) < 0) || (ll.first == NULL)) {
			/* Not an error unless the first directory could not be opened. */
			DisposeLineListContents(&ll);
			return (0);
		}

		/* "MLSD" succeeded */
		unlsrc = UnMlsD(cip, &fil, &ll);
		if (unlsrc < 0) {
			DisposeLineListContents(&ll);
			return (cip->errNo = kErrInvalidMLSTResponse);
		} else if (unlsrc == 0) {
			/* empty */
			DisposeLineListContents(&ll);
			return (0);
		}
		fip = fil.first;
		DisposeLineListContents(&ll);
	} else {
		if (((result = FTPListToMemory2(cip, dirPathLen ? path : ".", &ll, "-la", 0, &mls)) < 0) || (ll.first == NULL)) {
			DisposeLineListContents(&ll);
			if (((result = FTPListToMemory2(cip, dirPathLen ? path : ".", &ll, (cip->hasNLST_a == kCommandNotAvailable) ? "" : "-a", 0, &mls)) < 0) || (ll.first == NULL)) {
				DisposeLineListContents(&ll);
				return (0);
			} else {
				/* "NLST -a" succeeded */
				RemoteGlobCollapse(cip, path, &ll);
				filePtr = ll.first;
			}
		} else {
			/* "LIST -a" succeeded */
			lsl = 1;
			unlsrc = UnLslR(cip, &fil, &ll, cip->serverType);
			if (unlsrc < 0) {
				DisposeLineListContents(&ll);
				return (cip->errNo = kErrInvalidMLSTResponse);
			} else if (unlsrc == 0) {
				/* empty */
				DisposeLineListContents(&ll);
				return (0);
			}
			fip = fil.first;
			DisposeLineListContents(&ll);
		}
	}

	nSubdirs = 0;
	++ftwip->numDirs;
	ftwip->depth = depth;
	if (ftwip->maxDepth < ftwip->depth) {
		ftwip->maxDepth = ftwip->depth;
	}
	filename = path + dirPathLen;
	if (isRootDir == 0) {	/* Root directory is a separator. */
		*filename++ = (char) ftwip->dirSeparator;
		dirPathLen++;
	}
	*filename = '\0';
	/* Path now contains dir/  */

	for (;;) {
		if ((mls != 0) || (lsl != 0)) {
			if (fip == NULL)
				break;
			cp = fip->relname;
		} else {
			if (filePtr == NULL)
				break;
			cp = filePtr->line;
		}
		if ((cp[0] == '.') && ((cp[1] == '\0') || ((cp[1] == '.') && (cp[2] == '\0'))))
			goto nxt;	/* Skip . and .. */

		ftwip->rlinkto = NULL;
		*filename = '\0';
		fnLen = strlen(cp) + 1	/* include \0 */;
		if ((fnLen + dirPathLen) > ftwip->curPathAllocSize) {
			if (ftwip->autoGrow == kFtwNoAutoGrowAndFail) {
				goto panic;
			} else if (ftwip->autoGrow == kFtwNoAutoGrowButContinue) {
				goto nxt;
			}
			newBuf = (char *) realloc(ftwip->curPath, fnLen + dirPathLen + 30 + 2 /* room for / and \0 */);
			if (newBuf == NULL)
				goto panic;
			ftwip->curPath = newBuf;
			ftwip->curPathAllocSize = fnLen + dirPathLen + 30;
			path = ftwip->curPath;
			filename = path + dirPathLen;
			if (isRootDir == 0)	/* Root directory is a separator. */
				*filename++ = (char) ftwip->dirSeparator;
			*filename = '\0';
		}
		memcpy(filename, cp, fnLen);
		ftwip->curPathLen = dirPathLen + fnLen - 1;
		ftwip->curFile = filename;
		ftwip->curFileLen = fnLen - 1;

		memset(&ftwip->curStat, 0, sizeof(ftwip->curStat));
		if (mls != 0) {
			ftwip->curType = fip->type;
			if (fip->type == 'd') {
				ftwip->curStat.st_mode = S_IFDIR;
				ftwip->curStat.st_size = (longest_int) -1;
#ifdef S_IFLNK
			} else if (fip->type == 'l') {
				ftwip->curStat.st_mode = S_IFLNK;
				ftwip->rlinkto = fip->rlinkto;
#endif
			} else if (fip->type == '-') {
				ftwip->curStat.st_mode = S_IFREG;
				ftwip->curStat.st_size = fip->size;
			} else {
				/* unknown type, skip */
				goto nxt;
			}
			if (fip->mode != (-1))
				ftwip->curStat.st_mode |= (fip->mode & 00777);
			ftwip->curStat.st_mtime = fip->mdtm;
		} else if (lsl != 0) {
			ftwip->curType = fip->type;
			if (fip->type == 'd') {
				ftwip->curStat.st_mode = S_IFDIR;
				ftwip->curStat.st_size = (longest_int) -1;
#ifdef S_IFLNK
			} else if (fip->type == 'l') {
				ftwip->curStat.st_mode = S_IFLNK;
				ftwip->rlinkto = fip->rlinkto;
#endif
			} else if (fip->type == '-') {
				ftwip->curStat.st_mode = S_IFREG;
				ftwip->curStat.st_size = fip->size;
			} else {
				/* unknown type, skip */
				goto nxt;
			}
			if (fip->mode != (-1))
				ftwip->curStat.st_mode |= (fip->mode & 00777);
			ftwip->curStat.st_mtime = fip->mdtm;

			/* Override local times in LS output! */
			result = FTPFileModificationTime(cip, path, &fip->mdtm);
			if (fip->mdtm != kModTimeUnknown) {
				ftwip->curStat.st_mtime = fip->mdtm;
			}
		} else {
			result = FTPIsDir(cip, path);
			if (result < 0) {
				/* error */
				/* could be just a stat error, so continue */
				goto nxt;
			} else if (result == 1) {
				/* directory */
				ftwip->curType = 'd';
				ftwip->curStat.st_mode = S_IFDIR | 00755;
				result = FTPFileModificationTime(cip, path, &ftwip->curStat.st_mtime);
			} else {
				/* file */
				ftwip->curType = '-';
				ftwip->curStat.st_mode = S_IFREG | 00644;
				result = FTPFileSizeAndModificationTime(cip, path, &sz, kTypeBinary, &ftwip->curStat.st_mtime);
#if defined(TRU64UNIX) || defined(DIGITAL_UNIX)
				ftwip->curStat.st_size = (off_t) sz;
#else
				ftwip->curStat.st_size = sz;
#endif
			}
		}

		{
			m = ftwip->curStat.st_mode;
			if (S_ISREG(m)) {
				++ftwip->numFiles;
				ftwip->curType = '-';
				if ((*ftwip->proc)(ftwip) < 0) {
					goto panic;
				}
			} else if (S_ISLNK(m)) {
				++ftwip->numLinks;
				ftwip->curType = 'l';
				if ((*ftwip->proc)(ftwip) < 0) {
					goto panic;
				}
			} else if (S_ISDIR(m)) {
				/* We delay entering the subdirectories
				 * until we have closed this directory.
				 * This will conserve file descriptors
				 * and also have the effect of having
				 * the files processed first.
				 */
				sdp = (FtwSubDirListPtr) malloc(sizeof(FtwSubDirList) + fnLen);
				if (sdp == NULL)
					goto panic;
				memcpy(&sdp->st, &ftwip->curStat, sizeof(sdp->st));
				memcpy(sdp->name, cp, fnLen);
				sdp->fnLen = fnLen;
				sdp->next = NULL;
				if (head == NULL) {
					head = tail = sdp;
				} else {
					tail->next = sdp;
					tail = sdp;
				}
				nSubdirs++;
			}
		}
nxt:
		if ((mls != 0) || (lsl != 0)) {
			fip = fip->next;
		} else {
			filePtr = filePtr->next;
		}
	}

	if ((mls != 0) || (lsl != 0)) {
		DisposeFileInfoListContents(&fil);
	} else {
		DisposeLineListContents(&ll);
	}

	/* Now enter each subdirectory. */
	for (sdp = head; sdp != NULL; sdp = nextsdp) {
		nextsdp = sdp->next;
		memcpy(&ftwip->curStat, &sdp->st, sizeof(ftwip->curStat));
		fnLen = sdp->fnLen;
		memcpy(filename, sdp->name, fnLen);
		ftwip->curFile = filename;
		ftwip->curFileLen = fnLen - 1;
		ftwip->curPathLen = dirPathLen + fnLen - 1;
		head = nextsdp;
		free(sdp);

		ftwip->curType = 'd';
		if ((*ftwip->proc)(ftwip) < 0) {
			goto panic;
		}
		if (FTPFtwTraverse(ftwip, dirPathLen + fnLen - 1, depth + 1) < 0)
			goto panic;

		/* Reset these, since buffer could have
		 * been reallocated.
		 */
		path = ftwip->curPath;
		filename = path + dirPathLen;
		*filename = '\0';
	}
	head = NULL;
	rc = 0;

panic:
	if (mls != 0) {
		DisposeFileInfoListContents(&fil);
	} else {
		DisposeLineListContents(&ll);
	}

	for (sdp = head; sdp != NULL; sdp = nextsdp) {
		nextsdp = sdp->next;
		free(sdp);
	}

	return (rc);
}	/* FTPFtwTraverse */
Beispiel #12
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 */
Beispiel #13
0
int
FTPPutFiles3(
    const FTPCIPtr cip,
    const char *const pattern,
    const char *const dstdir1,
    const int recurse,
    const int doGlob,
    const int xtype,
    int appendflag,
    const char *const tmppfx,
    const char *const tmpsfx,
    const int resumeflag,
    const int deleteflag,
    const FTPConfirmResumeUploadProc resumeProc,
    int UNUSED(reserved))
{
    FTPLineList globList;
    FTPFileInfoList files;
    FTPFileInfoPtr filePtr;
    int batchResult;
    int result;
    const char *dstdir;
    char dstdir2[512];

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

    if (dstdir1 == NULL)
    {
        dstdir = NULL;
    }
    else
    {
        dstdir = STRNCPY(dstdir2, dstdir1);
        StrRemoveTrailingLocalPathDelim(dstdir2);
    }

    (void) FTPLocalGlob(cip, &globList, pattern, doGlob);
    if (recurse == kRecursiveYes)
    {
        appendflag = kAppendNo;
        (void) FTPLocalRecursiveFileList(cip, &globList, &files);
        if (files.first == NULL)
        {
            cip->errNo = kErrNoValidFilesSpecified;
            return (kErrNoValidFilesSpecified);
        }
        (void) ComputeRNames(&files, dstdir, 0, 1);
    }
    else
    {
        (void) LineListToFileInfoList(&globList, &files);
        (void) ComputeLNames(&files, NULL, NULL, 1);
        (void) ComputeRNames(&files, dstdir, 0, 0);
    }
    DisposeLineListContents(&globList);

#if 0
    for (filePtr = files.first; filePtr != NULL; filePtr = filePtr->next)
    {
        PrintF(cip, "  R=%s, L=%s, 2=%s, size=%lld, mdtm=%u, type=%c\n",
               filePtr->rname,
               filePtr->lname,
               filePtr->rlinkto ? filePtr->rlinkto : "",
               filePtr->size,
               (unsigned int) filePtr->mdtm,
               filePtr->type
              );
    }
#endif

    batchResult = kNoErr;
    for (filePtr = files.first; filePtr != NULL; filePtr = filePtr->next)
    {
        if (cip->connected == 0)
        {
            if (batchResult == kNoErr)
                batchResult = kErrRemoteHostClosedConnection;
            break;
        }
        if (filePtr->type == 'd')
        {
            /* mkdir */
            StrRemoveTrailingLocalPathDelim(filePtr->rname);
            result = FTPMkdir(cip, filePtr->rname, kRecursiveNo);
            if (result != kNoErr)
                batchResult = result;
#ifdef HAVE_SYMLINK
        }
        else if (filePtr->type == 'l')
        {
            /* symlink */
            /* no RFC way to create the link, though. */
            if ((filePtr->rlinkto != NULL) && (filePtr->rlinkto[0] != '\0'))
                (void) FTPSymlink(cip, filePtr->rname, filePtr->rlinkto);
#endif
        }
        else if (recurse != kRecursiveYes)
        {
            result = FTPPutOneF(cip, filePtr->lname, filePtr->rname, xtype, -1, appendflag, tmppfx, tmpsfx, resumeflag, deleteflag, resumeProc);
            if (files.nFileInfos == 1)
            {
                if (result != kNoErr)
                    batchResult = result;
            }
            else
            {
                if ((result != kNoErr) && (result != kErrLocalFileNewer) && (result != kErrRemoteFileNewer) && (result != kErrRemoteSameAsLocal))
                    batchResult = result;
            }
            if (result == kErrUserCanceled)
                cip->cancelXfer = 1;
            if (cip->cancelXfer > 0)
                break;
        }
        else
        {
            result = FTPPutOneF(cip, filePtr->lname, filePtr->rname, xtype, -1, appendflag, tmppfx, tmpsfx, resumeflag, deleteflag, resumeProc);
            if (files.nFileInfos == 1)
            {
                if (result != kNoErr)
                    batchResult = result;
            }
            else
            {
                if ((result != kNoErr) && (result != kErrLocalFileNewer) && (result != kErrRemoteFileNewer) && (result != kErrRemoteSameAsLocal))
                    batchResult = result;
            }
            if (result == kErrUserCanceled)
                cip->cancelXfer = 1;
            if (cip->cancelXfer > 0)
                break;
        }
    }
    DisposeFileInfoListContents(&files);
    if (batchResult < 0)
        cip->errNo = batchResult;
    return (batchResult);
}	/* FTPPutFiles3 */
Beispiel #14
0
Datei: Get.c Projekt: aosm/ncftp
int GetDir(GetOptionsPtr gopt, char *dName, char *rRoot, char *lRoot)
{
	LineList dirFiles;
	LinePtr dirFile;
	char *rd;	/* Remote directory path. */
	char *ld;	/* Local directory path. */
	char *rf;	/* Complete remote pathname for an item. */
	char *lf;	/* Complete local pathname for an item. */ 
	char *sl;	/* What a symlink points to. */
	char *iName;
	int fType;

	rd = NULL;
	ld = NULL;
	rf = NULL;
	lf = NULL;
	
	if ((rd = StrDup(rRoot)) == NULL)
		goto fail;
	if ((rd = PtrCatSlash(rd, dName)) == NULL)
		goto fail;

	if ((ld = StrDup(lRoot)) == NULL)
		goto fail;
	if ((ld = PtrCatSlash(ld, dName)) == NULL)
		goto fail;
	
	/* Create this directory on the local host first. */
	if (MkDirs(ld)) {
		EPrintF("Could not create directory '%s.'\n", ld);
		goto fail;
	}
	
	/* Get the names of all files and subdirs. */
	InitLineList(&dirFiles);
	GetFileList(&dirFiles, rd);

	/* Get all the files first. */
	for (dirFile = dirFiles.first; dirFile != NULL; dirFile = dirFile->next) {
		fType = (int) dirFile->line[0];
		if ((fType == '-') || (fType == 'l')) {
			iName = dirFile->line + 1;
			if ((rf = StrDup(rd)) == NULL)
				goto fail;
			if ((rf = PtrCatSlash(rf, iName)) == NULL)
				goto fail;
			if ((lf = StrDup(ld)) == NULL)
				goto fail;
			if ((lf = PtrCatSlash(lf, iName)) == NULL)
				goto fail;
			if (fType == '-') {
				gopt->rName = rf;
				gopt->lName = lf;
				DoGet(gopt);
			} else {
#ifdef HAVE_SYMLINK
				sl = (char *) malloc(SZ(512));
				if (sl != NULL) {
					if (GetSymLinkInfo(sl, SZ(512), rf) == 0)
						(void) symlink(sl, lf);
					free(sl);
				}
#endif	/* HAVE_SYMLINK */
			}
			free(rf);
			free(lf);
			rf = NULL;
			lf = NULL;
		}
		if (gXferAbortFlag == SIGINT)
			break;	/* Don't get rest of files if you interrupted. */
	}
	
	/* Now get subdirectories. */
	for (dirFile = dirFiles.first; dirFile != NULL; dirFile = dirFile->next) {
		if (gXferAbortFlag == SIGINT)
			break;	/* Don't get rest of files if you interrupted. */
		fType = (int) dirFile->line[0];
		if (fType == 'd') {
			iName = dirFile->line + 1;
			if (GetDir(gopt, iName, rd, ld) < 0)
				break;
		}
	}

	free(ld);
	free(rd);
	DisposeLineListContents(&dirFiles);
	return (0);
	
fail:
	if (rd != NULL)
		free(rd);
	if (ld != NULL)
		free(ld);
	if (rf != NULL)
		free(rf);
	if (lf != NULL)
		free(lf);
	return (-1);
}	/* GetDir */