⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmds.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* cmds.c
 *
 * Copyright (c) 1996-2001 Mike Gleason, NCEMRSoft.
 * All rights reserved.
 *
 */

#include "syshdrs.h"

int
FTPChdir(const FTPCIPtr cip, const char *const cdCwd)
{
	int result;

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

	if (cdCwd == NULL) {
		result = kErrInvalidDirParam;
		cip->errNo = kErrInvalidDirParam;
	} else {
		if (cdCwd[0] == '\0')	/* But allow FTPChdir(cip, ".") to go through. */
			result = 2;
		else if (strcmp(cdCwd, "..") == 0)
			result = FTPCmd(cip, "CDUP");
		else
			result = FTPCmd(cip, "CWD %s", cdCwd);
		if (result >= 0) {
			if (result == 2) {
				result = kNoErr;
			} else {
				result = kErrCWDFailed;
				cip->errNo = kErrCWDFailed;
			}
		}
	}
	return (result);
}	/* FTPChdir */




int
FTPChmod(const FTPCIPtr cip, const char *const pattern, const char *const mode, const int doGlob)
{
	LineList fileList;
	LinePtr 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 */




static int
FTPRmdirRecursiveL2(const FTPCIPtr cip)
{
	LineList fileList;
	LinePtr filePtr;
	char *file;
	int result;

	result = FTPRemoteGlob(cip, &fileList, "**", kGlobYes);
	if (result != kNoErr) {
		return (result);
	}

	for (filePtr = fileList.first;
		filePtr != NULL;
		filePtr = filePtr->next)
	{
		file = filePtr->line;
		if (file == NULL) {
			cip->errNo = kErrBadLineList;
			break;
		}

		if ((file[0] == '.') && ((file[1] == '\0') || ((file[1] == '.') && (file[2] == '\0'))))
			continue;	/* Skip . and .. */

		if (FTPChdir(cip, file) == kNoErr) {
			/* It was a directory.
			 * Go in and wax it.
			 */
			result = FTPRmdirRecursiveL2(cip);

			if (FTPChdir(cip, "..") != kNoErr) {
				/* Panic -- we can no longer
				 * cd back to the directory
				 * we were in before.
				 */
				result = kErrCannotGoToPrevDir;
				cip->errNo = kErrCannotGoToPrevDir;
				return (result);
			}

			if ((result < 0) && (result != kErrGlobNoMatch))
				return (result);

			result = FTPRmdir(cip, file, kRecursiveNo, kGlobNo);
			if (result != kNoErr) {
				/* Well, we couldn't remove the empty
				 * directory.  Perhaps we screwed up
				 * and the directory wasn't empty.
				 */
				return (result);
			}
		} else {
			/* Assume it was a file -- remove it. */
			result = FTPDelete(cip, file, kRecursiveNo, kGlobNo);
			/* Try continuing to remove the rest,
			 * even if this failed.
			 */
		}
	}
	DisposeLineListContents(&fileList);

	return (result);
} 	/* FTPRmdirRecursiveL2 */



static int
FTPRmdirRecursive(const FTPCIPtr cip, const char *const dir)
{
	int result, result2;

	/* Preserve old working directory. */
	(void) FTPGetCWD(cip, cip->buf, cip->bufSize);

	result = FTPChdir(cip, dir);
	if (result != kNoErr) {
		return (result);
	}

	result = FTPRmdirRecursiveL2(cip);

	if (FTPChdir(cip, cip->buf) != kNoErr) {
		/* Could not cd back to the original user directory -- bad. */
		if (result != kNoErr) {
			result = kErrCannotGoToPrevDir;
			cip->errNo = kErrCannotGoToPrevDir;
		}
		return (result);
	}

	/* Now rmdir the last node, the root of the tree
	 * we just went through.
	 */
	result2 = FTPRmdir(cip, dir, kRecursiveNo, kGlobNo);
	if ((result2 != kNoErr) && (result == kNoErr))
		result = result2;

	return (result);
}	/* FTPRmdirRecursive */




int
FTPDelete(const FTPCIPtr cip, const char *const pattern, const int recurse, const int doGlob)
{
	LineList fileList;
	LinePtr 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 */




int
FTPGetCWD(const FTPCIPtr cip, char *const newCwd, const size_t newCwdSize)
{
	ResponsePtr rp;
	char *l, *r;
	int result;

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

	if ((newCwd == NULL) || (newCwdSize == 0)) {
		result = kErrInvalidDirParam;
		cip->errNo = kErrInvalidDirParam;
	} else {
		rp = InitResponse();
		if (rp == NULL) {
			result = kErrMallocFailed;
			cip->errNo = kErrMallocFailed;
			Error(cip, kDontPerror, "Malloc failed.\n");
		} else {
			result = RCmd(cip, rp, "PWD");
			if (result == 2) {
				if ((r = strrchr(rp->msg.first->line, '"')) != NULL) {
					/* "xxxx" is current directory.
					 * Strip out just the xxxx to copy into the remote cwd.
					 */
					l = strchr(rp->msg.first->line, '"');
					if ((l != NULL) && (l != r)) {
						*r = '\0';
						++l;
						(void) Strncpy(newCwd, l, newCwdSize);
						*r = '"';	/* Restore, so response prints correctly. */
					}
				} else {
					/* xxxx is current directory.
					 * Mostly for VMS.
					 */
					if ((r = strchr(rp->msg.first->line, ' ')) != NULL) {
						*r = '\0';
						(void) Strncpy(newCwd, (rp->msg.first->line), newCwdSize);
						*r = ' ';	/* Restore, so response prints correctly. */
					}
				}
				result = kNoErr;
			} else if (result > 0) {
				result = kErrPWDFailed;
				cip->errNo = kErrPWDFailed;
			}
			DoneWithResponse(cip, rp);
		}
	}
	return (result);
}	/* FTPGetCWD */




int
FTPChdirAndGetCWD(const FTPCIPtr cip, const char *const cdCwd, char *const newCwd, const size_t newCwdSize)
{
	ResponsePtr rp;
	char *l, *r;
	int result;

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

	if ((newCwd == NULL) || (cdCwd == NULL)) {
		result = kErrInvalidDirParam;
		cip->errNo = kErrInvalidDirParam;
	} else {
		if (cdCwd[0] == '\0') {	/* But allow FTPChdir(cip, ".") to go through. */
			result = FTPGetCWD(cip, newCwd, newCwdSize);
			return (result);
		}
		rp = InitResponse();
		if (rp == NULL) {
			result = kErrMallocFailed;
			cip->errNo = kErrMallocFailed;
			Error(cip, kDontPerror, "Malloc failed.\n");
		} else {
			if (strcmp(cdCwd, "..") == 0)
				result = RCmd(cip, rp, "CDUP");
			else
				result = RCmd(cip, rp, "CWD %s", cdCwd);
			if (result == 2) {
				l = strchr(rp->msg.first->line, '"');
				if ((l == rp->msg.first->line) && ((r = strrchr(rp->msg.first->line, '"')) != NULL) && (l != r)) {
					/* "xxxx" is current directory.
					 * Strip out just the xxxx to copy into the remote cwd.
					 *
					 * This is nice because we didn't have to do a PWD.
					 */
					*r = '\0';
					++l;
					(void) Strncpy(newCwd, l, newCwdSize);
					*r = '"';	/* Restore, so response prints correctly. */
					DoneWithResponse(cip, rp);
					result = kNoErr;
				} else {
					DoneWithResponse(cip, rp);
					result = FTPGetCWD(cip, newCwd, newCwdSize);
				}
			} else if (result > 0) {
				result = kErrCWDFailed;
				cip->errNo = kErrCWDFailed;
				DoneWithResponse(cip, rp);
			} else {
				DoneWithResponse(cip, rp);
			}
		}
	}
	return (result);
}	/* FTPChdirAndGetCWD */




int
FTPChdir3(FTPCIPtr cip, const char *const cdCwd, char *const newCwd, const size_t newCwdSize, int flags)
{
	char *cp, *startcp;
	int result;
	int lastSubDir;
	int mkd, pwd;

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

	if (cdCwd == NULL) {
		result = kErrInvalidDirParam;
		cip->errNo = kErrInvalidDirParam;
		return result;
	}

	if (flags == kChdirOnly)
		return (FTPChdir(cip, cdCwd));
	if (flags == kChdirAndGetCWD) {
		return (FTPChdirAndGetCWD(cip, cdCwd, newCwd, newCwdSize));
	} else if (flags == kChdirAndMkdir) {
		result = FTPMkdir(cip, cdCwd, kRecursiveYes);
		if (result == kNoErr)
			result = FTPChdir(cip, cdCwd);
		return result;
	} else if (flags == (kChdirAndMkdir|kChdirAndGetCWD)) {
		result = FTPMkdir(cip, cdCwd, kRecursiveYes);
		if (result == kNoErr)
			result = FTPChdirAndGetCWD(cip, cdCwd, newCwd, newCwdSize);
		return result;
	}

	/* else: (flags | kChdirOneSubdirAtATime) == true */

	cp = cip->buf;
	cp[cip->bufSize - 1] = '\0';
	(void) Strncpy(cip->buf, cdCwd, cip->bufSize);
	if (cp[cip->bufSize - 1] != '\0')
		return (kErrBadParameter);

	mkd = (flags & kChdirAndMkdir);
	pwd = (flags & kChdirAndGetCWD);

	if ((cdCwd[0] == '\0') || (strcmp(cdCwd, ".") == 0)) {
		result = 0;
		if (flags == kChdirAndGetCWD)
			result = FTPGetCWD(cip, newCwd, newCwdSize);
		return (result);
	}

	lastSubDir = 0;
	do {
		startcp = cp;
		cp = StrFindLocalPathDelim(cp);
		if (cp != NULL) {
			/* If this is the first slash in an absolute
			 * path, then startcp will be empty.  We will
			 * use this below to treat this as the root
			 * directory.
			 */
			*cp++ = '\0';
		} else {
			lastSubDir = 1;
		}
		if (strcmp(startcp, ".") == 0) {
			result = 0;
			if ((lastSubDir != 0) && (pwd != 0))
				result = FTPGetCWD(cip, newCwd, newCwdSize);
		} else if ((lastSubDir != 0) && (pwd != 0)) {
			result = FTPChdirAndGetCWD(cip, (*startcp != '\0') ? startcp : "/", newCwd, newCwdSize);
		} else {
			result = FTPChdir(cip, (*startcp != '\0') ? startcp : "/");
		}
		if (result < 0) {
			if ((mkd != 0) && (*startcp != '\0')) {
				if (FTPCmd(cip, "MKD %s", startcp) == 2) {
					result = FTPChdir(cip, startcp);
				} else {
					/* couldn't change nor create */
					cip->errNo = result;
				}
			} else {
				cip->errNo = result;
			}
		}
	} while ((!lastSubDir) && (result == 0));

	return (result);
}	/* FTPChdir3 */




int
FTPMkdir2(const FTPCIPtr cip, const char *const newDir, const int recurse, const char *const curDir)
{
	int result, result2;
	char *cp, *newTreeStart, *cp2;
	char dir[512];
	char dir2[512];
	char c;

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

	if ((newDir == NULL) || (newDir[0] == '\0')) {
		cip->errNo = kErrInvalidDirParam;
		return (kErrInvalidDirParam);
	}

	/* Preserve old working directory. */
	if ((curDir == NULL) || (curDir[0] == '\0')) {
		/* This hack is nice so you can eliminate an
		 * unnecessary "PWD" command on the server,
		 * since if you already knew what directory
		 * you're in.  We want to minimize the number
		 * of client-server exchanges when feasible.
		 */
		(void) FTPGetCWD(cip, cip->buf, cip->bufSize);
	}

	result = FTPChdir(cip, newDir);
	if (result == kNoErr) {
		/* Directory already exists -- but we
		 * must now change back to where we were.
		 */
		result2 = FTPChdir(cip, ((curDir == NULL) || (curDir[0] == '\0')) ? cip->buf : curDir);
		if (result2 < 0) {
			result = kErrCannotGoToPrevDir;
			cip->errNo = kErrCannotGoToPrevDir;
			return (result);
		}

		/* Don't need to create it. */
		return (kNoErr);
	}

	if (recurse == kRecursiveNo) {
		result = FTPCmd(cip, "MKD %s", newDir);
		if (result > 0) {
			if (result != 2) {
				Error(cip, kDontPerror, "MKD %s failed; [%s]\n", newDir, cip->lastFTPCmdResultStr);
				result = kErrMKDFailed;
				cip->errNo = kErrMKDFailed;
				return (result);
			} else {
				result = kNoErr;
			}
		}
	} else {
		(void) STRNCPY(dir, newDir);

		/* Strip trailing slashes. */
		cp = dir + strlen(dir) - 1;
		for (;;) {
			if (cp <= dir) {
				if ((newDir == NULL) || (newDir[0] == '\0')) {
					cip->errNo = kErrInvalidDirParam;
					result = kErrInvalidDirParam;
					return (result);
				}
			}
			if ((*cp != '/') && (*cp != '\\')) {
				cp[1] = '\0';
				break;
			}
			--cp;
		}
		(void) STRNCPY(dir2, dir);

		if ((strrchr(dir, '/') == dir) || (strrchr(dir, '\\') == dir)) {
			/* Special case "mkdir /subdir" */
			result = FTPCmd(cip, "MKD %s", dir);
			if (result < 0) {
				return (result);
			}
			if (result != 2) {
				Error(cip, kDontPerror, "MKD %s failed; [%s]\n", dir, cip->lastFTPCmdResultStr);
				result = kErrMKDFailed;
				cip->errNo = kErrMKDFailed;
				return (result);
			}
			/* Haven't chdir'ed, don't need to goto goback. */
			return (kNoErr);
		}

		for (;;) {
			cp = strrchr(dir, '/');

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -