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

📄 cmds.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
		result = kErrInvalidDirParam;
		cip->errNo = kErrInvalidDirParam;
		return result;
	}

	if ((cdCwd[0] == '\0') || (strcmp(cdCwd, ".") == 0)) {
		result = 0;
		return (result);
	}

	cp = cip->buf;
	cp[cip->bufSize - 2] = '\0';
	if ((cdCwd[0] == '.') && (cdCwd[1] == '.') && ((cdCwd[2] == '\0') || IsLocalPathDelim(cdCwd[2]))) {
		PathCat(cip->buf, cip->bufSize, gRemoteCWD, cdCwd);
	} else {
		(void) Strncpy(cip->buf, cdCwd, cip->bufSize);
	}
	if (cp[cip->bufSize - 2] != '\0')
		return (kErrBadParameter);

	StrRemoveTrailingLocalPathDelim(cp);
	do {
		startcp = cp;
		cp = StrFindLocalPathDelim(cp + 0);
		if (cp != NULL) {
			*cp++ = '\0';
		}
		lastSubDir = (cp == NULL);
		result = nFTPChdirAndGetCWD(cip, (*startcp != '\0') ? startcp : "/", lastSubDir ? 0 : 1);
		if (result < 0) {
			cip->errNo = result;
		}
	} while ((!lastSubDir) && (result == 0));

	return (result);
}	/* Chdirs */




/* Remote change of working directory command. */
void
ChdirCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
{
	int result;
	LineList ll;
	LinePtr lp;

	ARGSUSED(gUnusedArg);

	if (argc <= 1) {
		if (gStartDir[0] != '\0') {
			(void) STRNCPY(gPrevRemoteCWD, gRemoteCWD);
			result = Chdirs(&gConn, gStartDir);
			if (result != kNoErr) {
				/* State is incoherent if this happens! */
				FTPPerror(&gConn, result, kErrCWDFailed, "Could not chdir to", gStartDir);
			}
		} else {
			PrintCmdUsage(cmdp);
		}
	} else {
		InitLineList(&ll);
		result = FTPRemoteGlob(&gConn, &ll, argv[1], (aip->noglobargv[1] != 0) ? kGlobNo: kGlobYes);
		if (result < 0) {
			FTPPerror(&gConn, result, kErrGlobFailed, argv[0], argv[1]);
		} else {
			lp = ll.first;
			if ((lp != NULL) && (lp->line != NULL)) {
				if ((strcmp(lp->line, "-") == 0) && (gPrevRemoteCWD[0] != '\0')) {
					free(lp->line);
					lp->line = StrDup(gPrevRemoteCWD);
					if (lp->line == NULL) {
						result = kErrMallocFailed;
						gConn.errNo = kErrMallocFailed;
					} else {
						(void) STRNCPY(gPrevRemoteCWD, gRemoteCWD);
						result = Chdirs(&gConn, lp->line);
					}
				} else {
					(void) STRNCPY(gPrevRemoteCWD, gRemoteCWD);
					result = Chdirs(&gConn, lp->line);
				}
				if (result != kNoErr)
					FTPPerror(&gConn, result, kErrCWDFailed, "Could not chdir to", lp->line);
			}
		}
		DisposeLineListContents(&ll);
	}
}	/* ChdirCmd */




/* Chmod files on the remote host, if it supports it. */
void
ChmodCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
{
	int i, result;

	ARGSUSED(gUnusedArg);
	for (i=2; i<argc; i++) {
		result = FTPChmod(
				&gConn, argv[i], argv[1],
				(aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes
			);
		if (result < 0) {
			FTPPerror(&gConn, result, kErrChmodFailed, "chmod", argv[i]);
			/* but continue */
		}
	}

	/* Really should just flush only the modified directories... */
	FlushLsCache();
}	/* ChmodCmd */




/* Close the current session to a remote FTP server. */
void
CloseCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
{
	ARGSUSED(gUnusedArg);
	if (gConn.connected == 0)
		(void) printf("Already closed.\n");
	else
		CloseHost();
}	/* CloseCmd */



/* User interface to the program's debug-mode setting. */
void
DebugCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
{
	ARGSUSED(gUnusedArg);
	if (argc > 1)
		SetDebug(atoi(argv[1]));
	else
		SetDebug(!gDebug);
}	/* DebugCmd */




/* Delete files on the remote host. */
void
DeleteCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
{
	int result;
	int i, c;
	int recursive = kRecursiveNo;

	ARGSUSED(gUnusedArg);
	GetoptReset();
	while ((c = Getopt(argc, argv, "rf")) > 0) switch(c) {
		case 'r':
			recursive = kRecursiveYes;
			break;
		case 'f':
			/* ignore */
			break;
		default:
			PrintCmdUsage(cmdp);
			return;
	}

	for (i=gOptInd; i<argc; i++) {
		result = FTPDelete(
				&gConn, argv[i], recursive,
				(aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes
			);
		if (result < 0) {
			FTPPerror(&gConn, result, kErrDELEFailed, "delete", argv[i]);
			/* but continue */
		}
	}

	/* Really should just flush only the modified directories... */
	FlushLsCache();
}	/* DeleteCmd */




/* Command shell echo command.  This is mostly useful for testing the command
 * shell, as a sample command which prints some output.
 */
void
EchoCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
{
	int i;
	int result;
	int np = 0;
	LineList ll;
	LinePtr lp;

	ARGSUSED(gUnusedArg);
	for (i=1; i<argc; i++) {
		InitLineList(&ll);
		result = FTPLocalGlob(&gConn, &ll, argv[i], (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes);
		if (result < 0) {
			FTPPerror(&gConn, result, kErrGlobFailed, "local glob", argv[i]);
		} else {
			for (lp = ll.first; lp != NULL; lp = lp->next) {
				if (lp->line != NULL) {
					if (np > 0)
						(void) printf(" ");
					(void) printf("%s", lp->line);
					np++;
				}
			}
		}
		DisposeLineListContents(&ll);
	}
	(void) printf("\n");
}	/* EchoCmd */




static int
NcFTPConfirmResumeDownloadProc(
	const char *volatile *localpath,
	volatile longest_int localsize,
	volatile time_t localmtime,
	const char *volatile remotepath,
	volatile longest_int remotesize,
	volatile time_t remotemtime,
	volatile longest_int *volatile startPoint)
{
	int zaction = kConfirmResumeProcSaidBestGuess;
	char tstr[80], ans[32];
	static char newname[128];	/* arrggh... static. */

	if (gResumeAnswerAll != kConfirmResumeProcNotUsed)
		return (gResumeAnswerAll);

	if (gAutoResume != 0)
		return (kConfirmResumeProcSaidBestGuess);

	tstr[sizeof(tstr) - 1] = '\0';
	(void) strftime(tstr, sizeof(tstr) - 1, "%c", localtime((time_t *) &localmtime));
	(void) printf(
#if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
		"\nThe local file \"%s\" already exists.\n\tLocal:  %12lld bytes, dated %s.\n",
#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
		"\nThe local file \"%s\" already exists.\n\tLocal:  %12qd bytes, dated %s.\n",
#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
		"\nThe local file \"%s\" already exists.\n\tLocal:  %12I64d bytes, dated %s.\n",
#else
		"\nThe local file \"%s\" already exists.\n\tLocal:  %12ld bytes, dated %s.\n",
#endif
		*localpath,
		localsize,
		tstr
	);

	if ((remotemtime != kModTimeUnknown) && (remotesize != kSizeUnknown)) {
		(void) strftime(tstr, sizeof(tstr) - 1, "%c", localtime((time_t *) &remotemtime));
		(void) printf(
#if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
			"\tRemote: %12lld bytes, dated %s.\n",
#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
			"\tRemote: %12qd bytes, dated %s.\n",
#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
			"\tRemote: %12I64d bytes, dated %s.\n",
#else
			"\tRemote: %12ld bytes, dated %s.\n",
#endif
			remotesize,
			tstr
		);
		if ((remotemtime == localmtime) && (remotesize == localsize)) {
			(void) printf("\t(Files are identical, skipped)\n\n");
			return (kConfirmResumeProcSaidSkip);
		}
	} else if (remotesize != kSizeUnknown) {
		(void) printf(
#if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
			"\tRemote: %12lld bytes, date unknown.\n",
#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
			"\tRemote: %12qd bytes, date unknown.\n",
#elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
			"\tRemote: %12I64d bytes, date unknown.\n",
#else
			"\tRemote: %12ld bytes, date unknown.\n",
#endif
			remotesize
		);
	} else if (remotemtime != kModTimeUnknown) {
		(void) strftime(tstr, sizeof(tstr) - 1, "%c", localtime((time_t *) &remotemtime));
		(void) printf(
			"\tRemote: size unknown, dated %s.\n",
			tstr
		);
	}

	printf("\n");
	(void) memset(ans, 0, sizeof(ans));
	for (;;) {
		(void) printf("\t[O]verwrite?");
		if ((gConn.hasREST == kCommandAvailable) && (remotesize != kSizeUnknown) && (remotesize > localsize))
			printf("  [R]esume?");
		printf("  [A]ppend to?  [S]kip?  [N]ew Name?\n");
		(void) printf("\t[O!]verwrite all?");
		if ((gConn.hasREST == kCommandAvailable) && (remotesize != kSizeUnknown) && (remotesize > localsize))
			printf("  [R!]esume all?");
		printf("  [S!]kip all?  [C]ancel  > ");
		fflush(stdin);
		(void) fgets(ans, sizeof(ans) - 1, stdin);
		switch ((int) ans[0]) {
			case 'c':
			case 'C':
				ans[0] = 'C';
				ans[1] = '\0';
				zaction = kConfirmResumeProcSaidCancel;
				break;
			case 'o':
			case 'O':
				ans[0] = 'O';
				zaction = kConfirmResumeProcSaidOverwrite;
				break;
			case 'r':
			case 'R':
				if ((gConn.hasREST != kCommandAvailable) || (remotesize == kSizeUnknown)) {
					printf("\tResume is not available on this server.\n\n");
					ans[0] = '\0';
					break;
				} else if (remotesize < localsize) {
					printf("\tCannot resume when local file is already larger than the remote file.\n\n");
					ans[0] = '\0';
					break;
				} else if (remotesize <= localsize) {
					printf("\tLocal file is already the same size as the remote file.\n\n");
					ans[0] = '\0';
					break;
				}
				ans[0] = 'R';
				*startPoint = localsize;
				zaction = kConfirmResumeProcSaidResume;
				if (OneTimeMessage("auto-resume") != 0) {
					printf("\n\tNOTE: If you want NcFTP to guess automatically, \"set auto-resume yes\"\n\n");
				}
				break;
			case 's':
			case 'S':
				ans[0] = 'S';
				zaction = kConfirmResumeProcSaidSkip;
				break;
			case 'n':
			case 'N':
				ans[0] = 'N';
				ans[1] = '\0';
				zaction = kConfirmResumeProcSaidOverwrite;
				break;
			case 'a':
			case 'A':
				ans[0] = 'A';
				ans[1] = '\0';
				zaction = kConfirmResumeProcSaidAppend;
				break;
			case 'g':
			case 'G':
				ans[0] = 'G';
				zaction = kConfirmResumeProcSaidBestGuess;
				break;
			default:
				ans[0] = '\0';
		}
		if (ans[0] != '\0')
			break;
	}

	if (ans[0] == 'N') {
		(void) memset(newname, 0, sizeof(newname));
		printf("\tSave as:  ");
		fflush(stdin);
		(void) fgets(newname, sizeof(newname) - 1, stdin);
		newname[strlen(newname) - 1] = '\0';
		if (newname[0] == '\0') {
			/* Nevermind. */
			printf("Skipped %s.\n", remotepath);
			zaction = kConfirmResumeProcSaidSkip;
		} else {
			*localpath = newname;
		}
	}

	if (ans[1] == '!')
		gResumeAnswerAll = zaction;
	return (zaction);
}	/* NcFTPConfirmResumeDownloadProc */




/* Download files from the remote system. */
void
GetCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
{
	int opt;
	int renameMode = 0;
	int recurseFlag = kRecursiveNo;
	int appendFlag = kAppendNo;
	int resumeFlag = kResumeYes;
	int tarflag = kTarYes;
	const char *dstdir = NULL;
	int rc;
	int i;
	int doGlob;
	int xtype = gBm.xferType;
	int nD = 0;
	int deleteFlag = kDeleteNo;
	char pattern[256];
	vsigproc_t osigint;
	ConfirmResumeDownloadProc confirmProc;

	confirmProc = NcFTPConfirmResumeDownloadProc;
	gResumeAnswerAll = kConfirmResumeProcNotUsed;	/* Ask at least once each time */
	ARGSUSED(gUnusedArg);
	GetoptReset();
	while ((opt = Getopt(argc, argv, "aAzfrRTD")) >= 0) switch (opt) {
		case 'a':
			xtype = kTypeAscii;
			break;
		case 'A':
			/* Append to local files, instead of truncating
			 * them first.
			 */
			appendFlag = kAppendYes;
			break;
		case 'f':
		case 'Z':
			/* Do not try to resume a download, even if it
			 * appeared that some of the file was transferred
			 * already.
			 */
			resumeFlag = kResumeNo;
			confirmProc = NoConfirmResumeDownloadProc;
			break;
		case 'z':
			/* Special flag that lets you specify the
			 * destination file.  Normally a "get" will
			 * write the file by the same name as the
			 * remote file's basename.
			 */
			renameMode = 1;
			break;
		case 'r':
		case 'R':
			/* If the item is a directory, get the
			 * directory and all its contents.
			 */
			recurseFlag = kRecursiveYes;
			break;
		case 'T':
			/* If they said "-R", they may want to
			 * turn off TAR mode if they are trying
			 * to resume the whole directory.
			 * The disadvantage to TAR mode is that
			 * it always downloads the whole thing,
			 * which is why there is a flag to
			 * disable this.
			 */
			tarflag = kTarNo;
			break;
		case 'D':
			/* You can delete the remote file after
			 * you downloaded it successfully by using
			 * the -DD option.  It requires two -D's
			 * to minimize the odds of accidentally
			 * using a single -D.
			 */
			nD++;
			break;
		default:
			PrintCmdUsage(cmdp);
			return;
	}

	if (nD >= 2)
		deleteFlag = kDeleteYes;

	if (renameMode != 0) {
		if (gOptInd > argc - 2) {
			PrintCmdUsage(cmdp);
			(void) fprintf(stderr, "\nFor get with rename, try \"get -z remote-path-name local-path-name\".\n");
			return;
		}
		osigint = NcSignal(SIGINT, XferCanceller);
		rc = FTPGetOneFile3(&gConn, argv[gOptInd], argv[gOptInd + 1], xtype, (-1), resumeFlag, appendFlag, deleteFlag, NoConfirmResumeDownloadProc, 0);
		if (rc < 0)
			FTPPerror(&gConn, rc, kErrCouldNotStartDataTransfer, "get", argv[gOptInd]);
	} else {
		osigint = NcSignal(SIGINT, XferCanceller);
		for (i=gOptInd; i<argc; i++) {
			doGlob = (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes;
			STRNCPY(pattern, argv[i]);
			StrRemoveTrailingSlashes(pattern);
			rc = FTPGetFiles3(&gConn, pattern, dstdir, recurseFlag, doGlob, xtype, resumeFlag, appendFlag, deleteFlag, tarflag, confirmProc, 0);
			if (rc < 0)
				FTPPerror(&gConn, rc, kErrCouldNotStartDataTransfer, "get", argv[i]);
		}
	}
	(void) NcSignal(SIGINT, osigint);
	(void) fflush(stdin);

	if (deleteFlag == kDeleteYes) {
		/* Directory is now out of date */
		FlushLsCache();
	}
}	/* GetCmd */

⌨️ 快捷键说明

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