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

📄 cmds.c

📁 这是 FTP协议的 0。17版本的源代码 在一定程度上是比较适用的
💻 C
📖 第 1 页 / 共 4 页
字号:
			continue;		}		gargs = ftpglob(argv[i]);		if (globerr != NULL) {			printf("%s\n", globerr);			if (gargs) {				blkfree(gargs);				free((char *)gargs);			}			continue;		}		for (cpp = gargs; cpp && *cpp != NULL; cpp++) {			if (mflag && confirm(argv[0], *cpp)) {				tp = (ntflag) ? dotrans(*cpp) : *cpp;				tp = (mapflag) ? domap(tp) : tp;				sendrequest((sunique) ? "STOU" : "STOR",				    *cpp, tp, *cpp != tp || !interactive);				if (!mflag && fromatty) {					ointer = interactive;					interactive = 1;					if (confirm("Continue with","mput")) {						mflag++;					}					interactive = ointer;				}			}		}		if (gargs != NULL) {			blkfree(gargs);			free((char *)gargs);		}	}	(void) signal(SIGINT, oldintr);	mflag = 0;}voidreget(int argc, char *argv[]){	(void) getit(argc, argv, 1, "r+w");}voidget(int argc, char *argv[]){	(void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );}/* * Receive one file. */static intgetit(int argc, char *argv[], int restartit, const char *modestr){	int loc = 0;	char *oldargv1, *oldargv2;	if (argc == 2) {		argc++;		/* 		 * Protect the user from accidentally retrieving special		 * local names.		 */		argv[2] = pipeprotect(argv[1]);		if (!argv[2]) {			code = -1;			return 0;		}		loc++;	}	if (argc < 2 && !another(&argc, &argv, "remote-file"))		goto usage;	if (argc < 3 && !another(&argc, &argv, "local-file")) {usage:		printf("usage: %s remote-file [ local-file ]\n", argv[0]);		code = -1;		return (0);	}	oldargv1 = argv[1];	oldargv2 = argv[2];	argv[2] = globulize(argv[2]);	if (!argv[2]) {		code = -1;		return (0);	}	if (loc && mcase) {		char *tp = argv[1], *tp2, tmpbuf[PATH_MAX];		while (*tp && !islower(*tp)) {			tp++;		}		if (!*tp) {			tp = argv[2];			tp2 = tmpbuf;			while ((*tp2 = *tp) != '\0') {				if (isupper(*tp2)) {					*tp2 = 'a' + *tp2 - 'A';				}				tp++;				tp2++;			}			argv[2] = tmpbuf;		}	}	if (loc && ntflag)		argv[2] = dotrans(argv[2]);	if (loc && mapflag)		argv[2] = domap(argv[2]);	if (restartit) {		struct stat stbuf;		int ret;		ret = stat(argv[2], &stbuf);		if (restartit == 1) {			if (ret < 0) {				fprintf(stderr, "local: %s: %s\n", argv[2],					strerror(errno));				return (0);			}			restart_point = stbuf.st_size;		} else {			if (ret == 0) {				int overbose;				overbose = verbose;				if (debug == 0)					verbose = -1;				if (command("MDTM %s", argv[1]) == COMPLETE) {					int yy, mo, day, hour, min, sec;					struct tm *tm;					verbose = overbose;					sscanf(reply_string,					    "%*s %04d%02d%02d%02d%02d%02d",					    &yy, &mo, &day, &hour, &min, &sec);					tm = gmtime(&stbuf.st_mtime);					tm->tm_mon++;/* Indentation is misleading, but changes keep small. *//*  * I think the indentation and braces are now correct. Whoever put this * in the way it was originally should be prohibited by law. */					if (tm->tm_year+1900 > yy)					    	return (1);					if (tm->tm_year+1900 == yy) {					   if (tm->tm_mon > mo)					      return (1);					   if (tm->tm_mon == mo) {					      if (tm->tm_mday > day)						 return (1);					      if (tm->tm_mday == day) {						 if (tm->tm_hour > hour)							return (1);						 if (tm->tm_hour == hour) {						    if (tm->tm_min > min)						       return (1);						    if (tm->tm_min == min) {						       if (tm->tm_sec > sec)							  return (1);						    }						 }					      }					   }					}				} else {					printf("%s\n", reply_string);					verbose = overbose;					return (0);				}			}		}	}	recvrequest("RETR", argv[2], argv[1], modestr,		    argv[1] != oldargv1 || argv[2] != oldargv2);	restart_point = 0;	return (0);}voidmabort(int ignore){	int ointer;	(void)ignore;	printf("\n");	(void) fflush(stdout);	if (mflag && fromatty) {		ointer = interactive;		interactive = 1;		if (confirm("Continue with", mname)) {			interactive = ointer;			siglongjmp(jabort,0);		}		interactive = ointer;	}	mflag = 0;	siglongjmp(jabort,0);}/* * Get multiple files. */voidmget(int argc, char **argv){	void (*oldintr)(int);	int ointer;	char *cp, *tp, *tp2, tmpbuf[PATH_MAX];	if (argc < 2 && !another(&argc, &argv, "remote-files")) {		printf("usage: %s remote-files\n", argv[0]);		code = -1;		return;	}	mname = argv[0];	mflag = 1;	oldintr = signal(SIGINT,mabort);	(void) sigsetjmp(jabort, 1);	while ((cp = remglob(argv,proxy)) != NULL) {		if (*cp == '\0') {			mflag = 0;			continue;		}		if (mflag && confirm(argv[0], cp)) {			tp = cp;			if (mcase) {				while (*tp && !islower(*tp)) {					tp++;				}				if (!*tp) {					tp = cp;					tp2 = tmpbuf;					while ((*tp2 = *tp) != '\0') {						if (isupper(*tp2)) {							*tp2 = 'a' + *tp2 - 'A';						}						tp++;						tp2++;					}				}				tp = tmpbuf;			}			if (ntflag) {				tp = dotrans(tp);			}			if (mapflag) {				tp = domap(tp);			}			/* Reject embedded ".." */			tp = pathprotect(tp);			/* Prepend ./ to "-" or "!*" or leading "/" */			tp = pipeprotect(tp);			if (tp == NULL) {				/* hmm... how best to handle this? */				mflag = 0;			}			else {				recvrequest("RETR", tp, cp, "w",					    tp != cp || !interactive);			}			if (!mflag && fromatty) {				ointer = interactive;				interactive = 1;				if (confirm("Continue with","mget")) {					mflag++;				}				interactive = ointer;			}		}	}	(void) signal(SIGINT,oldintr);	mflag = 0;}char *remglob(char *argv[], int doswitch){	char temp[16];	static char buf[PATH_MAX];	static FILE *ftemp = NULL;	static char **args;	int oldverbose, oldhash, badglob = 0;	char *cp;	if (!mflag) {		if (!doglob) {			args = NULL;		}		else {			if (ftemp) {				(void) fclose(ftemp);				ftemp = NULL;			}		}		return(NULL);	}	if (!doglob) {		if (args == NULL)			args = argv;		if ((cp = *++args) == NULL)			args = NULL;		return (cp);	}	if (ftemp == NULL) {		int oldumask, fd;		(void) strcpy(temp, _PATH_TMP);		/* libc 5.2.18 creates with mode 0666, which is dumb */		oldumask = umask(077);		fd = mkstemp(temp);		umask(oldumask);		if (fd<0) {			printf("Error creating temporary file, oops\n");			return NULL;		}				oldverbose = verbose, verbose = 0;		oldhash = hash, hash = 0;		if (doswitch) {			pswitch(!proxy);		}		while (*++argv != NULL) {			int	dupfd = dup(fd);			recvrequest ("NLST", temp, *argv, "a", 0);			if (!checkglob(dupfd, *argv)) {				badglob = 1;				break;			}		}		unlink(temp);		if (doswitch) {			pswitch(!proxy);		}		verbose = oldverbose; hash = oldhash;		if (badglob) {			printf("Refusing to handle insecure file list\n");			close(fd);			return NULL;		}		ftemp = fdopen(fd, "r");		if (ftemp == NULL) {			printf("fdopen failed, oops\n");			return NULL;		}		rewind(ftemp);	}	if (fgets(buf, sizeof (buf), ftemp) == NULL) {		(void) fclose(ftemp), ftemp = NULL;		return (NULL);	}	if ((cp = index(buf, '\n')) != NULL)		*cp = '\0';	return (buf);}/* * Check whether given pattern matches `..' * We assume only a glob pattern starting with a dot will match * dot entries on the server. */static intisdotdotglob(const char *pattern){	int	havedot = 0;	char	c;	if (*pattern++ != '.')		return 0;	while ((c = *pattern++) != '\0' && c != '/') {		if (c == '*' || c == '?')			continue;		if (c == '.' && havedot++)			return 0;	}	return 1;}/* * This function makes sure the list of globbed files returned from * the server doesn't contain anything dangerous such as * /home/<yourname>/.forward, or ../.forward, * or |mail foe@doe </etc/passwd, etc. * Covered areas: *  -	returned name starts with / but glob pattern doesn't *  -	glob pattern starts with / but returned name doesn't *  -	returned name starts with | *  -	returned name contains .. in a position where glob *	pattern doesn't match .. *	I.e. foo/.* allows foo/../bar but not foo/.bar/../fly * * Note that globbed names starting with / should really be stored * under the current working directory; this is handled in mget above. *						--okir */static intcheckglob(int fd, const char *pattern){	const char	*sp;	char		buffer[MAXPATHLEN], dotdot[MAXPATHLEN];	int		okay = 1, nrslash, initial, nr;	FILE		*fp;	/* Find slashes in glob pattern, and verify whether component	 * matches `..'	 */	initial = (pattern[0] == '/');	for (sp = pattern, nrslash = 0; sp != 0; sp = strchr(sp, '/')) {		while (*sp == '/')			sp++;		if (nrslash >= MAXPATHLEN) {			printf("Incredible pattern: %s\n", pattern);			return 0;		}		dotdot[nrslash++] = isdotdotglob(sp);	}	fp = fdopen(fd, "r");	while (okay && fgets(buffer, sizeof(buffer), fp) != NULL) {		char	*sp;		if ((sp = strchr(buffer, '\n')) != 0) {			*sp = '\0';		} else {			printf("Extremely long filename from server: %s",				buffer);			okay = 0;			break;		}		if (buffer[0] == '|'		 || (buffer[0] != '/' && initial)		 || (buffer[0] == '/' && !initial))			okay = 0;		for (sp = buffer, nr = 0; sp; sp = strchr(sp, '/'), nr++) {			while (*sp == '/')				sp++;			if (sp[0] == '.' && !strncmp(sp, "../", 3)			 && (nr >= nrslash || !dotdot[nr]))				okay = 0;		}	}	if (!okay)		printf("Filename provided by server "		       "doesn't match pattern `%s': %s\n", pattern, buffer);	fclose(fp);	return okay;}static const char *onoff(int bool){	return (bool ? "on" : "off");}/* * Show status. */voidstatus(void){	int i;	if (connected)		printf("Connected to %s.\n", hostname);	else		printf("Not connected.\n");	if (!proxy) {		pswitch(1);		if (connected) {			printf("Connected for proxy commands to %s.\n", hostname);		}		else {			printf("No proxy connection.\n");		}		pswitch(0);	}	printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",		modename, typename, formname, structname);	printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 		onoff(verbose), onoff(bell), onoff(interactive),		onoff(doglob));	printf("Store unique: %s; Receive unique: %s\n", onoff(sunique),		onoff(runique));	printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag));	if (ntflag) {		printf("Ntrans: (in) %s (out) %s\n", ntin,ntout);	}	else {		printf("Ntrans: off\n");	}	if (mapflag) {		printf("Nmap: (in) %s (out) %s\n", mapin, mapout);	}	else {		printf("Nmap: off\n");	}	printf("Hash mark printing: %s; Use of PORT cmds: %s\n",		onoff(hash), onoff(sendport));	printf("Tick counter printing: %s\n", onoff(tick));	if (macnum > 0) {		printf("Macros:\n");		for (i=0; i<macnum; i++) {			printf("\t%s\n",macros[i].mac_name);		}	}	code = 0;}/* * Set beep on cmd completed mode. */voidsetbell(void){	bell = !bell;	printf("Bell mode %s.\n", onoff(bell));	code = bell;}/* * Turn on packet tracing. */voidsettrace(void){	traceflag = !traceflag;	printf("Packet tracing %s.\n", onoff(traceflag));	code = traceflag;}/* * Toggle hash mark printing during transfers. */voidsethash(void){	hash = !hash;	if (hash && tick)		settick(); 	printf("Hash mark printing %s", onoff(hash));	code = hash;	if (hash)		printf(" (%d bytes/hash mark)", 1024);	printf(".\n");}/* * Toggle tick counter printing during transfers. */voidsettick(void){	tick = !tick;	if (hash && tick)		sethash();	printf("Tick counter printing %s", onoff(tick));	code = tick;	if (tick)		printf(" (%d bytes/tick increment)", TICKBYTES);	printf(".\n");}/* * Turn on printing of server echos. */voidsetverbose(void){	verbose = !verbose;	printf("Verbose mode %s.\n", onoff(verbose));	code = verbose;}/* * Toggle PORT cmd use before each data connection. */voidsetport(void){	sendport = !sendport;	printf("Use of PORT cmds %s.\n", onoff(sendport));	code = sendport;}/* * Turn on interactive prompting * during mget, mput, and mdelete.

⌨️ 快捷键说明

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