cmds.c

来自「一个类似windows」· C语言 代码 · 共 2,374 行 · 第 1/4 页

C
2,374
字号
/*
 * Copyright (c) 1985, 1989 Regents of the University of California.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by the University of California, Berkeley.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifndef lint
static char sccsid[] = "@(#)cmds.c	5.18 (Berkeley) 4/20/89";
#endif /* not lint */

/*
 * FTP User Program -- Command Routines.
 */
//#include <sys/param.h>
//#include <sys/wait.h>
#include <sys/stat.h>
#ifndef _WIN32
#include <sys/socket.h>
#include <arpa/ftp.h>
#include <netinet/in.h>
#include <netdb.h>
#else
#include <winsock.h>
#endif

#include <signal.h>
#include <direct.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>

#include "ftp_var.h"
#include "pathnames.h"
#include "prototypes.h"

extern	char *globerr;
extern	char home[];
extern	char *remglob();
extern	char *getenv();
extern	int allbinary;
extern off_t restart_point;
extern char reply_string[];

const char *mname;
jmp_buf jabort;
const char *dotrans(), *domap();

extern short portnum;
extern char *hostname;
extern int autologin;
/*
 * Connect to peer server and
 * auto-login, if possible.
 */
void setpeer(int argc, const char *argv[])
{
	char *host;

	if (connected) {
		printf("Already connected to %s, use close first.\n",
			hostname);
		(void) fflush(stdout);
		code = -1;
		return;
	}
	if (argc < 2) {
		(void) strcat(line, " ");
		printf("(to) ");
		(void) fflush(stdout);
		(void) gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc > 3) {
		printf("usage: %s host-name [port]\n", argv[0]);
		(void) fflush(stdout);
		code = -1;
		return;
	}
	if (argc > 2) {
		portnum = atoi(argv[2]);
		if (portnum <= 0) {
			printf("%s: bad port number-- %s\n", argv[1], argv[2]);
			printf ("usage: %s host-name [port]\n", argv[0]);
			(void) fflush(stdout);
			code = -1;
			return;
		}
		portnum = htons(portnum);
	}
	host = hookup(argv[1], portnum);
	if (host) {
#if defined(unix) && NBBY == 8
		int overbose;
#endif
		connected = 1;
		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;
		allbinary = 0;
		if (command("SYST") == COMPLETE && overbose) {
			register char *cp, c;
			cp = index(reply_string+4, ' ');
			if (cp == NULL)
				cp = index(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)) {
			setbinary();
			/* allbinary = 1; this violates the RFC */
			if (overbose)
			    printf("Using %s mode to transfer files.\n",
				typename);
		} else 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 */
	}
	(void) fflush(stdout);
}

struct	types {
	const char	*t_name;
	const 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 },
	{0 }
};

/*
 * Set transfer type.
 */
void settype(argc, argv)
	const char *argv[];
{
	register struct types *p;
	int comret;

	if (argc > 2) {
		const char *sep;

		printf("usage: %s [", argv[0]);
		sep = " ";
		for (p = types; p->t_name; p++) {
			printf("%s%s", sep, p->t_name);
			if (*sep == ' ')
				sep = " | ";
		}
		printf(" ]\n");
		(void) fflush(stdout);
		code = -1;
		return;
	}
	if (argc < 2) {
		printf("Using %s mode to transfer files.\n", typename);
		(void) fflush(stdout);
		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]);
		(void) fflush(stdout);
		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);
		type = p->t_type;
	}
}

const char *stype[] = {
	"type",
	"",
	0
};

/*
 * Set binary transfer type.
 */
/*VARARGS*/
void setbinary()
{
	stype[1] = "binary";
	settype(2, stype);
}

/*
 * Set ascii transfer type.
 */
/*VARARGS*/
void setascii()
{
	stype[1] = "ascii";
	settype(2, stype);
}

/*
 * Set tenex transfer type.
 */
/*VARARGS*/
void settenex()
{
	stype[1] = "tenex";
	settype(2, stype);
}

/*
 * Set ebcdic transfer type.
 */
/*VARARGS*/
void setebcdic()
{
	stype[1] = "ebcdic";
	settype(2, stype);
}

/*
 * Set file transfer mode.
 */

/*ARGSUSED*/
void fsetmode(argc, argv)
	char *argv[];
{

	printf("We only support %s mode, sorry.\n", modename);
	(void) fflush(stdout);
	code = -1;
}


/*
 * Set file transfer format.
 */
/*ARGSUSED*/
void setform(argc, argv)
	char *argv[];
{

	printf("We only support %s format, sorry.\n", formname);
	(void) fflush(stdout);
	code = -1;
}

/*
 * Set file transfer structure.
 */
/*ARGSUSED*/
void setstruct(argc, argv)
	char *argv[];
{

	printf("We only support %s structure, sorry.\n", structname);
	(void) fflush(stdout);
	code = -1;
}

/*
 * Send a single file.
 */
void put(argc, argv)
	int argc;
	const char *argv[];
{
	const char *cmd;
	int loc = 0;
	const char *oldargv1, *oldargv2;

	if (argc == 2) {
		argc++;
		argv[2] = argv[1];
		loc++;
	}
	if (argc < 2) {
		(void) strcat(line, " ");
		printf("(local-file) ");
		(void) fflush(stdout);
		(void) gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
usage:
		printf("usage:%s local-file remote-file\n", argv[0]);
		(void) fflush(stdout);
		code = -1;
		return;
	}
	if (argc < 3) {
		(void) strcat(line, " ");
		printf("(remote-file) ");
		(void) fflush(stdout);
		(void) gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 3)
		goto usage;
	oldargv1 = argv[1];
	oldargv2 = argv[2];
	if (!globulize(&argv[1])) {
		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 (argv[1] != oldargv1 && argv[2] == oldargv1) {
		argv[2] = argv[1];
	}
	cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
	if (loc && ntflag) {
		argv[2] = dotrans(argv[2]);
	}
	if (loc && mapflag) {
		argv[2] = domap(argv[2]);
	}
	sendrequest(cmd, argv[1], argv[2],
	    argv[1] != oldargv1 || argv[2] != oldargv2);
}

/*
 * Send multiple files.
 */
void mput(argc, argv)
	const char *argv[];
{
	register int i;
	int ointer;
	extern jmp_buf jabort;
	const char *tp;

	if (argc < 2) {
		(void) strcat(line, " ");
		printf("(local-files) ");
		(void) fflush(stdout);
		(void) gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		printf("usage:%s local-files\n", argv[0]);
		(void) fflush(stdout);
		code = -1;
		return;
	}
	mname = argv[0];
	mflag = 1;
//	oldintr = signal(SIGINT, mabort);
	(void) setjmp(jabort);
	if (proxy) {
		char *cp, *tp2, tmpbuf[MAXPATHLEN];

		while ((cp = remglob(argv,0)) != 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) != (int) NULL) {
						     if (isupper(*tp2)) {
						        *tp2 = 'a' + *tp2 - 'A';
						     }
						     tp++;
						     tp2++;
						}
					}
					tp = tmpbuf;
				}
				if (ntflag) {
					tp = dotrans(tp);
				}
				if (mapflag) {
					tp = domap(tp);
				}
				sendrequest((sunique) ? "STOU" : "STOR",
				    cp, tp, cp != tp || !interactive);
				if (!mflag && fromatty) {
					ointer = interactive;
					interactive = 1;
					if (confirm("Continue with","mput")) {
						mflag++;
					}
					interactive = ointer;
				}
			}
		}
//		(void) signal(SIGINT, oldintr);
		mflag = 0;
		return;
	}
	for (i = 1; i < argc; i++) {
		register char **cpp, **gargs;

		if (!doglob) {
			if (mflag && confirm(argv[0], argv[i])) {
				tp = (ntflag) ? dotrans(argv[i]) : argv[i];
				tp = (mapflag) ? domap(tp) : tp;
				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;
				}
			}
			continue;
		}
		gargs = glob(argv[i]);
		if (globerr != NULL) {
			printf("%s\n", globerr);
			(void) fflush(stdout);
			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;
}

void reget(argc, argv)
	const char *argv[];
{
	(void) getit(argc, argv, 1, "r+w");
}

void get(argc, argv)
	const char *argv[];
{
	(void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );
}

/*
 * Receive one file.
 */
int getit(argc, argv, restartit, mode)
	const char *argv[];
	const char *mode;
{
	int loc = 0;
	const char *oldargv1, *oldargv2;

	if (argc == 2) {
		argc++;
		argv[2] = argv[1];
		loc++;
	}
	if (argc < 2) {
		(void) strcat(line, " ");
		printf("(remote-file) ");
		(void) fflush(stdout);
		(void) gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
usage:
		printf("usage: %s remote-file [ local-file ]\n", argv[0]);
		(void) fflush(stdout);
		code = -1;
		return (0);
	}
	if (argc < 3) {
		(void) strcat(line, " ");
		printf("(local-file) ");
		(void) fflush(stdout);
		(void) gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 3)
		goto usage;
	oldargv1 = argv[1];
	oldargv2 = argv[2];
	if (!globulize(&argv[2])) {
		code = -1;
		return (0);
	}
	if (loc && mcase) {
		const char *tp = argv[1];
        char *tp2, tmpbuf[MAXPATHLEN];

		while (*tp && !islower(*tp)) {
			tp++;
		}
		if (!*tp) {
			tp = argv[2];
			tp2 = tmpbuf;
			while ((*tp2 = *tp) != (int) NULL) {
				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;

⌨️ 快捷键说明

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