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

📄 cmds.c

📁 linux下ftp client程序的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1985, 1989, 1993, 1994 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)cmds.c	8.6 (Berkeley) 10/9/94";#endif /* not lint *//* * FTP User Program -- Command Routines. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <sys/param.h>#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/ftp.h>#include <ctype.h>#include <error.h>#include <errno.h>#include <netdb.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H#  include <sys/time.h># else#  include <time.h># endif#endif#include <unistd.h>/* Include glob.h last, because it may define "const" which breaks   system headers on some platforms. */#include <glob.h>#include "ftp_var.h"/* Returns true if STR is entirely lower case.  */static intall_lower (str)	char *str;{	while (*str)		if (isupper (*str++))			return 0;	return 1;}/* Returns true if STR is entirely upper case.  */static intall_upper (str)	char *str;{	while (*str)		if (islower (*str++))			return 0;	return 1;}/* Destructively converts STR to upper case.  */static char *strup (str)	char *str;{	char *p;	for (p = str; *p; p++)		if (islower (*p))			*p = toupper (*p);	return str;}/* Destructively converts STR to lower case.  */static char *strdown (str)	char *str;{	char *p;	for (p = str; *p; p++)		if (isupper (*p))			*p = tolower (*p);	return str;}jmp_buf	jabort;char   *mname;char   *home = "/";char *mapin = 0;char *mapout = 0;/* * `Another' gets another argument, and stores the new argc and argv. * It reverts to the top level (via main.c's intr()) on EOF/error. * * Returns false if no new arguments have been added. */intanother(pargc, pargv, prompt)	int *pargc;	char ***pargv;	char *prompt;{	int len = strlen(line), ret;	if (len >= sizeof(line) - 3) {		printf("sorry, arguments too long\n");		intr();	}	printf("(%s) ", prompt);	line[len++] = ' ';	if (fgets(&line[len], sizeof(line) - len, stdin) == NULL)		intr();	len += strlen(&line[len]);	if (len > 0 && line[len - 1] == '\n')		line[len - 1] = '\0';	makeargv();	ret = margc > *pargc;	*pargc = margc;	*pargv = margv;	return (ret);}/* * Connect to peer server and * auto-login, if possible. */voidsetpeer(argc, argv)	int argc;	char *argv[];{	char *host;	int port;	if (connected) {		printf("Already connected to %s, use close first.\n",			hostname);		code = -1;		return;	}	if (argc < 2)		(void) another(&argc, &argv, "to");	if (argc < 2 || argc > 3) {		printf("usage: %s host-name [port]\n", argv[0]);		code = -1;		return;	}	port = sp->s_port;	if (argc > 2) {		port = atoi(argv[2]);		if (port <= 0 || port > 65535 ) {			printf("%s: bad port number-- %s\n", argv[1], argv[2]);			printf ("usage: %s host-name [port]\n", argv[0]);			code = -1;			return;		}		port = htons(port);	}	host = hookup(argv[1], port);	if (host) {		int overbose;		connected = 1;		/*		 * Set up defaults for FTP.		 */		(void) strcpy(typename, "ascii"), type = TYPE_A;		curtype = TYPE_A;		(void) strcpy(formname, "non-print"), form = FORM_N;		(void) strcpy(modename, "stream"), mode = MODE_S;		(void) strcpy(structname, "file"), stru = STRU_F;		(void) strcpy(bytename, "8"), bytesize = 8;		if (autologin)			(void) login(argv[1]);#if defined(unix) && NBBY == 8/* * this ifdef is to keep someone form "porting" this to an incompatible * system and not checking this out. This way they have to think about it. */		overbose = verbose;		if (debug == 0)			verbose = -1;		if (command("SYST") == COMPLETE && overbose) {			char *cp, c;			cp = strchr(reply_string+4, ' ');			if (cp == NULL)				cp = strchr(reply_string+4, '\r');			if (cp) {				if (cp[-1] == '.')					cp--;				c = *cp;				*cp = '\0';			}			printf("Remote system type is %s.\n",				reply_string+4);			if (cp)				*cp = c;		}		if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) {			if (proxy)				unix_proxy = 1;			else				unix_server = 1;			/*			 * Set type to 0 (not specified by user),			 * meaning binary by default, but don't bother			 * telling server.  We can use binary			 * for text files unless changed by the user.			 */			type = 0;			(void) strcpy(typename, "binary");			if (overbose)			    printf("Using %s mode to transfer files.\n",				typename);		} else {			if (proxy)				unix_proxy = 0;			else				unix_server = 0;			if (overbose &&			    !strncmp(reply_string, "215 TOPS20", 10))				printf("Remember to set tenex mode when transfering binary files from this machine.\n");		}		verbose = overbose;#endif /* unix */	}}struct	types {	char	*t_name;	char	*t_mode;	int	t_type;	char	*t_arg;} types[] = {	{ "ascii",	"A",	TYPE_A,	0 },	{ "binary",	"I",	TYPE_I,	0 },	{ "image",	"I",	TYPE_I,	0 },	{ "ebcdic",	"E",	TYPE_E,	0 },	{ "tenex",	"L",	TYPE_L,	bytename },	{ NULL }};/* * Set transfer type. */voidsettype(argc, argv)	int argc;	char *argv[];{	struct types *p;	int comret;	if (argc > 2) {		char *sep;		printf("usage: %s [", argv[0]);		sep = " ";		for (p = types; p->t_name; p++) {			printf("%s%s", sep, p->t_name);			sep = " | ";		}		printf(" ]\n");		code = -1;		return;	}	if (argc < 2) {		printf("Using %s mode to transfer files.\n", typename);		code = 0;		return;	}	for (p = types; p->t_name; p++)		if (strcmp(argv[1], p->t_name) == 0)			break;	if (p->t_name == 0) {		printf("%s: unknown mode\n", argv[1]);		code = -1;		return;	}	if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))		comret = command ("TYPE %s %s", p->t_mode, p->t_arg);	else		comret = command("TYPE %s", p->t_mode);	if (comret == COMPLETE) {		(void) strcpy(typename, p->t_name);		curtype = type = p->t_type;	}}/* * Internal form of settype; changes current type in use with server * without changing our notion of the type for data transfers. * Used to change to and from ascii for listings. */voidchangetype(newtype, show)	int newtype, show;{	struct types *p;	int comret, oldverbose = verbose;	if (newtype == 0)		newtype = TYPE_I;	if (newtype == curtype)		return;	if (debug == 0 && show == 0)		verbose = 0;	for (p = types; p->t_name; p++)		if (newtype == p->t_type)			break;	if (p->t_name == 0) {		printf("ftp: internal error: unknown type %d\n", newtype);		return;	}	if (newtype == TYPE_L && bytename[0] != '\0')		comret = command("TYPE %s %s", p->t_mode, bytename);	else		comret = command("TYPE %s", p->t_mode);	if (comret == COMPLETE)		curtype = newtype;	verbose = oldverbose;}char *stype[] = {	"type",	"",	0};/* * Set binary transfer type. *//*VARARGS*/voidsetbinary(argc, argv)	int argc;	char **argv;{	stype[1] = "binary";	settype(2, stype);}/* * Set ascii transfer type. *//*VARARGS*/voidsetascii(argc, argv)	int argc;	char *argv[];{	stype[1] = "ascii";	settype(2, stype);}/* * Set tenex transfer type. *//*VARARGS*/voidsettenex(argc, argv)	int argc;	char *argv[];{	stype[1] = "tenex";	settype(2, stype);}/* * Set file transfer mode. *//*ARGSUSED*/voidsetftmode(argc, argv)	int argc;	char *argv[];{	printf("We only support %s mode, sorry.\n", modename);	code = -1;}/* * Set file transfer format. *//*ARGSUSED*/voidsetform(argc, argv)	int argc;	char *argv[];{	printf("We only support %s format, sorry.\n", formname);	code = -1;}/* * Set file transfer structure. *//*ARGSUSED*/voidsetstruct(argc, argv)	int argc;	char *argv[];{	printf("We only support %s structure, sorry.\n", structname);	code = -1;}/* * Send a single file. */voidput(argc, argv)	int argc;	char *argv[];{	char *cmd, *local, *remote;	int loc = 0;	if (argc == 2) {		argc++;		argv[2] = argv[1];		loc++;	}	if (argc < 2 && !another(&argc, &argv, "local-file"))		goto usage;	if (argc < 3 && !another(&argc, &argv, "remote-file")) {usage:		printf("usage: %s local-file remote-file\n", argv[0]);		code = -1;		return;	}	local = globulize (argv[1]);	if (! local) {		code = -1;		return;	}	/*	 * If "globulize" modifies argv[1], and argv[2] is a copy of	 * the old argv[1], make it a copy of the new argv[1].	 */	if (loc)		remote = strdup (local);	else		remote = strdup (argv[2]);	cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");	if (loc && ntflag) {		char *new = dotrans(remote);		free (remote);		remote = new;	}	if (loc && mapflag) {		char *new = domap(remote);		free (remote);		remote = new;	}	sendrequest(cmd, local, remote,		    strcmp (argv[1], local) != 0		    || strcmp (argv[2], remote) != 0);	free (local);	free (remote);}/* * Send multiple files. */voidmput(argc, argv)	int argc;	char **argv;{	int i;	sig_t oldintr;	int ointer;	if (argc < 2 && !another(&argc, &argv, "local-files")) {		printf("usage: %s local-files\n", argv[0]);		code = -1;		return;	}	mname = argv[0];	mflag = 1;	oldintr = signal(SIGINT, mabort);	(void) setjmp(jabort);	if (proxy) {		char *cp;		while ((cp = remglob(argv,0)) != NULL) {			if (*cp == 0)				mflag = 0;			if (mflag && confirm(argv[0], cp)) {				char *tp = cp;				if (mcase) {					if (all_upper (tp))						tp = strdown (strdup (tp));				}				if (ntflag) {					char *new = dotrans(tp);					if (tp != cp)						free (tp);					tp = new;				}				if (mapflag) {					char *new = domap(tp);					if (tp != cp)						free (tp);					tp = new;				}				sendrequest((sunique) ? "STOU" : "STOR",				    cp, tp, cp != tp || !interactive);				if (!mflag && fromatty) {					ointer = interactive;					interactive = 1;					if (confirm("Continue with","mput")) {						mflag++;					}					interactive = ointer;				}				if (tp != cp)					free (tp);			}			free (cp);		}		(void) signal(SIGINT, oldintr);		mflag = 0;		return;	}	for (i = 1; i < argc; i++) {		char **cpp, **gargs;		glob_t gl;		int flags;		if (!doglob) {			if (mflag && confirm(argv[0], argv[i])) {				char *tp = argv[i];				if (ntflag)					tp = dotrans (tp);				if (mapflag) {					char *new = domap (tp);					if (tp != argv[i])						free (tp);					tp = new;				}				sendrequest((sunique) ? "STOU" : "STOR",				    argv[i], tp, tp != argv[i] || !interactive);				if (!mflag && fromatty) {					ointer = interactive;					interactive = 1;					if (confirm("Continue with","mput")) {						mflag++;					}					interactive = ointer;				}				if (tp != argv[i])					free (tp);			}			continue;		}		memset(&gl, 0, sizeof(gl));		flags = GLOB_NOCHECK;#ifdef GLOB_BRACE		flags |= GLOB_BRACE;#endif#ifdef GLOB_TILDE		flags |= GLOB_TILDE;#endif#ifdef GLOB_QUOTE		flags |= GLOB_QUOTE;#endif		if (glob(argv[i], flags, NULL, &gl) || gl.gl_pathc == 0) {			error (0, 0, "%s: not found", argv[i]);			globfree(&gl);			continue;		}		for (cpp = gl.gl_pathv; cpp && *cpp != NULL; cpp++) {			if (mflag && confirm(argv[0], *cpp)) {				char *tp = *cpp;				if (ntflag)					tp = dotrans (tp);				if (mapflag) {					char *new = domap (tp);					if (tp != *cpp)						free (tp);					tp = new;				}				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 (tp != *cpp)					free (tp);			}		}		globfree(&gl);	}	(void) signal(SIGINT, oldintr);	mflag = 0;}voidreget(argc, argv)	int argc;	char *argv[];{	(void) getit(argc, argv, 1, "r+w");}voidget(argc, argv)	int argc;	char *argv[];{	(void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );}/* * Receive one file. */intgetit(argc, argv, restartit, mode)	int argc;	char *argv[];	char *mode;	int restartit;{	int loc = 0;	char *local;	if (argc == 2) {		argc++;		argv[2] = argv[1];		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);	}	local = globulize (argv[2]);	if (! local) {		code = -1;		return (0);	}	if (loc && mcase && all_upper (local))		strdown (local);	if (loc && ntflag) {		char *new = dotrans(local);		free (local);		local = new;	}	if (loc && mapflag) {		char *new = domap(local);		free (local);		local = new;	}	if (restartit) {		struct stat stbuf;		int ret;		ret = stat(local, &stbuf);		if (restartit == 1) {			if (ret < 0) {				error (0, errno, "local: %s", local);				free (local);				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++;					if (tm->tm_year + 1900 > yy) {						free (local);						return (1);					}					if ((tm->tm_year + 1900 == yy &&					    tm->tm_mon > mo) ||					   (tm->tm_mon == mo &&					    tm->tm_mday > day) ||					   (tm->tm_mday == day &&					    tm->tm_hour > hour) ||					   (tm->tm_hour == hour &&					    tm->tm_min > min) ||					   (tm->tm_min == min &&					    tm->tm_sec > sec)) {						free (local);						return (1);					}				} else {					printf("%s\n", reply_string);					verbose = overbose;					free (local);					return (0);				}			}		}	}	recvrequest("RETR", local, argv[1], mode, strcmp (local, argv[2]) != 0);	restart_point = 0;	free (local);	return (0);}/* ARGSUSED */RETSIGTYPEmabort(int signo ARG_UNUSED){	int ointer;	printf("\n");	(void) fflush(stdout);	if (mflag && fromatty) {		ointer = interactive;		interactive = 1;		if (confirm("Continue with", mname)) {			interactive = ointer;			longjmp(jabort,0);		}		interactive = ointer;	}	mflag = 0;	longjmp(jabort,0);

⌨️ 快捷键说明

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