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

📄 ftp.c

📁 UNIX FTP client
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1985, 1989 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. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 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. *//*  * From: @(#)ftp.c	5.38 (Berkeley) 4/22/91 */char ftp_rcsid[] =   "$Id: ftp.c,v 1.15 1997/03/21 02:02:05 dholland Exp $";#include <sys/param.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/file.h>#include <netinet/in.h>#include <netinet/ip.h>#include <arpa/ftp.h>#include <arpa/inet.h>#include <arpa/telnet.h>#include <stdio.h>#include <signal.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <netdb.h>#include <fcntl.h>#include <pwd.h>#include <stdarg.h>#include "ftp_var.h"#include "cmds.h"#include "../version.h"int data = -1;off_t restart_point = 0;static struct sockaddr_in hisctladdr;static struct sockaddr_in data_addr;static struct sockaddr_in myctladdr;static int ptflag = 0;static sigjmp_buf recvabort;static sigjmp_buf sendabort;static sigjmp_buf ptabort;static int ptabflg = 0;static int abrtflag = 0;void lostpeer(int);extern int connected;static char *gunique(char *);static void proxtrans(const char *cmd, char *local, char *remote);static int initconn(void);static void ptransfer(const char *direction, long bytes, 		      const struct timeval *t0, 		      const struct timeval *t1);static void tvsub(struct timeval *tdiff, 		  const struct timeval *t1, 		  const struct timeval *t0);static void abort_remote(FILE *din);FILE *cin, *cout;static FILE *dataconn(const char *);char *hookup(char *host, int port){	register struct hostent *hp = 0;	int s, tos;	size_t len;	static char hostnamebuf[256];	memset(&hisctladdr, 0, sizeof(hisctladdr));	if (inet_aton(host, &hisctladdr.sin_addr)) {		hisctladdr.sin_family = AF_INET;		strncpy(hostnamebuf, host, sizeof(hostnamebuf));		hostnamebuf[sizeof(hostnamebuf)-1]=0;	} 	else {		hp = gethostbyname(host);		if (hp == NULL) {			fprintf(stderr, "ftp: %s: ", host);			herror((char *)NULL);			code = -1;			return((char *) 0);		}		hisctladdr.sin_family = hp->h_addrtype;		if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {			hp->h_length = sizeof(hisctladdr.sin_addr);		}		memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length);		(void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));		hostnamebuf[sizeof(hostnamebuf)-1] = 0;	}	hostname = hostnamebuf;	s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);	if (s < 0) {		perror("ftp: socket");		code = -1;		return (0);	}	hisctladdr.sin_port = port;	while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {		if (hp && hp->h_addr_list[1]) {			int oerrno = errno;			fprintf(stderr, "ftp: connect to address %s: ",				inet_ntoa(hisctladdr.sin_addr));			errno = oerrno;			perror((char *) 0);			hp->h_addr_list++;			bcopy(hp->h_addr_list[0],			     (caddr_t)&hisctladdr.sin_addr, hp->h_length);			fprintf(stdout, "Trying %s...\n",				inet_ntoa(hisctladdr.sin_addr));			(void) close(s);			s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);			if (s < 0) {				perror("ftp: socket");				code = -1;				return (0);			}			continue;		}		perror("ftp: connect");		code = -1;		goto bad;	}	len = sizeof (myctladdr);	if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {		perror("ftp: getsockname");		code = -1;		goto bad;	}#ifdef IP_TOS	tos = IPTOS_LOWDELAY;	if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)		perror("ftp: setsockopt TOS (ignored)");#endif	cin = fdopen(s, "r");	cout = fdopen(s, "w");	if (cin == NULL || cout == NULL) {		fprintf(stderr, "ftp: fdopen failed.\n");		if (cin)			(void) fclose(cin);		if (cout)			(void) fclose(cout);		code = -1;		goto bad;	}	if (verbose)		printf("Connected to %s.\n", hostname);	if (getreply(0) > 2) { 	/* read startup message from server */		if (cin)			(void) fclose(cin);		if (cout)			(void) fclose(cout);		code = -1;		goto bad;	}#ifdef SO_OOBINLINE	{	int on = 1;	if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on))		< 0 && debug) {			perror("ftp: setsockopt");		}	}#endif /* SO_OOBINLINE */	return (hostname);bad:	(void) close(s);	return ((char *)0);}intdologin(const char *host){	char tmp[80];	char *luser, *pass, *zacct;	int n, aflag = 0;	luser = pass = zacct = 0;	if (xruserpass(host, &luser, &pass, &zacct) < 0) {		code = -1;		return(0);	}	while (luser == NULL) {		char *myname = getlogin();		if (myname == NULL) {			struct passwd *pp = getpwuid(getuid());			if (pp != NULL)				myname = pp->pw_name;		}		if (myname)			printf("Name (%s:%s): ", host, myname);		else			printf("Name (%s): ", host);		(void) fgets(tmp, sizeof(tmp) - 1, stdin);		tmp[strlen(tmp) - 1] = '\0';		if (*tmp == '\0')			luser = myname;		else			luser = tmp;	}	n = command("USER %s", luser);	if (n == CONTINUE) {		if (pass == NULL) {			/* fflush(stdout); */			pass = getpass("Password:");		}		n = command("PASS %s", pass);	}	if (n == CONTINUE) {		aflag++;		/* fflush(stdout); */		zacct = getpass("Account:");		n = command("ACCT %s", zacct);	}	if (n != COMPLETE) {		fprintf(stderr, "Login failed.\n");		return (0);	}	if (!aflag && zacct != NULL)		(void) command("ACCT %s", zacct);	if (proxy)		return(1);	for (n = 0; n < macnum; ++n) {		if (!strcmp("init", macros[n].mac_name)) {			int margc;			char **margv;			strcpy(line, "$init");			margv = makeargv(&margc, NULL);			domacro(margc, margv);			break;		}	}	return (1);}static voidcmdabort(int ignore){	(void)ignore;	printf("\n");	fflush(stdout);	abrtflag++;	if (ptflag) siglongjmp(ptabort,1);}intcommand(const char *fmt, ...){	va_list ap;	int r;	void (*oldintr)(int);	abrtflag = 0;	if (debug) {		printf("---> ");		va_start(ap, fmt);		if (strncmp("PASS ", fmt, 5) == 0)			printf("PASS XXXX");		else 			vfprintf(stdout, fmt, ap);		va_end(ap);		printf("\n");		(void) fflush(stdout);	}	if (cout == NULL) {		perror ("No control connection for command");		code = -1;		return (0);	}	oldintr = signal(SIGINT, cmdabort);	va_start(ap, fmt);	vfprintf(cout, fmt, ap);	va_end(ap);	fprintf(cout, "\r\n");	(void) fflush(cout);	cpend = 1;	r = getreply(!strcmp(fmt, "QUIT"));	if (abrtflag && oldintr != SIG_IGN)		(*oldintr)(SIGINT);	(void) signal(SIGINT, oldintr);	return(r);}char reply_string[BUFSIZ];		/* last line of previous reply */#include <ctype.h>intgetreply(int expecteof){	register int c, n;	register int dig;	register char *cp;	int originalcode = 0, continuation = 0;	void (*oldintr)(int);	int pflag = 0;	char *pt = pasv;	oldintr = signal(SIGINT, cmdabort);	for (;;) {		dig = n = code = 0;		cp = reply_string;		while ((c = getc(cin)) != '\n') {			if (c == IAC) {     /* handle telnet commands */				switch (c = getc(cin)) {				case WILL:				case WONT:					c = getc(cin);					fprintf(cout, "%c%c%c", IAC, DONT, c);					(void) fflush(cout);					break;				case DO:				case DONT:					c = getc(cin);					fprintf(cout, "%c%c%c", IAC, WONT, c);					(void) fflush(cout);					break;				default:					break;				}				continue;			}			dig++;			if (c == EOF) {				if (expecteof) {					(void) signal(SIGINT,oldintr);					code = 221;					return (0);				}				lostpeer(0);				if (verbose) {					printf("421 Service not available, remote server has closed connection\n");					(void) fflush(stdout);				}				code = 421;				return(4);			}			if (c != '\r' && (verbose > 0 ||			    (verbose > -1 && n == '5' && dig > 4))) {				if (proxflag &&				   (dig == 1 || (dig == 5 && verbose == 0)))					printf("%s:",hostname);				(void) putchar(c);			}			if (dig < 4 && isdigit(c))				code = code * 10 + (c - '0');			if (!pflag && code == 227)				pflag = 1;			if (dig > 4 && pflag == 1 && isdigit(c))				pflag = 2;			if (pflag == 2) {				if (c != '\r' && c != ')')					*pt++ = c;				else {					*pt = '\0';					pflag = 3;				}			}			if (dig == 4 && c == '-') {				if (continuation)					code = 0;				continuation++;			}			if (n == 0)				n = c;			if (cp < &reply_string[sizeof(reply_string) - 1])				*cp++ = c;		}		if (verbose > 0 || (verbose > -1 && n == '5')) {			(void) putchar(c);			(void) fflush (stdout);		}		if (continuation && code != originalcode) {			if (originalcode == 0)				originalcode = code;			continue;		}		*cp = '\0';		if (n != '1')			cpend = 0;		(void) signal(SIGINT,oldintr);		if (code == 421 || originalcode == 421)			lostpeer(0);		if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)			(*oldintr)(SIGINT);		return (n - '0');	}}static intempty(fd_set *mask, int sec){	struct timeval t;	t.tv_sec = (long) sec;	t.tv_usec = 0;	return(select(32, mask, (fd_set *) 0, (fd_set *) 0, &t));}static voidabortsend(int ignore){	(void)ignore;	mflag = 0;	abrtflag = 0;	printf("\nsend aborted\nwaiting for remote to finish abort\n");	(void) fflush(stdout);	siglongjmp(sendabort, 1);}#define HASHBYTES 1024voidsendrequest(const char *cmd, char *local, char *remote, int printnames){	struct stat st;	struct timeval start, stop;	register int c, d;	FILE *volatile fin, *volatile dout = 0;	int (*volatile closefunc)(FILE *);	void (*volatile oldintr)(int);	void (*volatile oldintp)(int);	volatile long bytes = 0, hashbytes = HASHBYTES;	char buf[BUFSIZ], *bufp;	const char *volatile lmode;	if (verbose && printnames) {		if (local && *local != '-')			printf("local: %s ", local);		if (remote)			printf("remote: %s\n", remote);	}	if (proxy) {		proxtrans(cmd, local, remote);		return;	}	if (curtype != type)		changetype(type, 0);	closefunc = NULL;	oldintr = NULL;	oldintp = NULL;	lmode = "w";	if (sigsetjmp(sendabort, 1)) {		while (cpend) {			(void) getreply(0);		}		if (data >= 0) {			(void) close(data);			data = -1;		}		if (oldintr)			(void) signal(SIGINT,oldintr);		if (oldintp)			(void) signal(SIGPIPE,oldintp);		code = -1;		return;	}	oldintr = signal(SIGINT, abortsend);	if (strcmp(local, "-") == 0)		fin = stdin;	else if (*local == '|') {		oldintp = signal(SIGPIPE,SIG_IGN);		fin = popen(local + 1, "r");		if (fin == NULL) {			perror(local + 1);			(void) signal(SIGINT, oldintr);			(void) signal(SIGPIPE, oldintp);			code = -1;			return;		}		closefunc = pclose;	} else {		fin = fopen(local, "r");		if (fin == NULL) {			fprintf(stderr, "local: %s: %s\n", local,				strerror(errno));			(void) signal(SIGINT, oldintr);			code = -1;			return;		}		closefunc = fclose;		if (fstat(fileno(fin), &st) < 0 ||		    (st.st_mode&S_IFMT) != S_IFREG) {			fprintf(stdout, "%s: not a plain file.\n", local);			(void) signal(SIGINT, oldintr);			fclose(fin);

⌨️ 快捷键说明

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