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

📄 ftp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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. * 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. */#ifndef lintstatic char sccsid[] = "@(#)ftp.c	8.4 (Berkeley) 4/6/94";#endif /* not lint */#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/in_systm.h>#include <netinet/ip.h>#include <arpa/inet.h>#include <arpa/ftp.h>#include <arpa/telnet.h>#include <ctype.h>#include <err.h>#include <errno.h>#include <fcntl.h>#include <netdb.h>#include <pwd.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <varargs.h>#include "ftp_var.h"extern int h_errno;struct	sockaddr_in hisctladdr;struct	sockaddr_in data_addr;int	data = -1;int	abrtflag = 0;jmp_buf	ptabort;int	ptabflg;int	ptflag = 0;struct	sockaddr_in myctladdr;off_t	restart_point = 0;FILE	*cin, *cout;char *hookup(host, port)	char *host;	int port;{	struct hostent *hp = 0;	int s, len, tos;	static char hostnamebuf[80];	memset((char *)&hisctladdr, 0, sizeof (hisctladdr));	hisctladdr.sin_addr.s_addr = inet_addr(host);	if (hisctladdr.sin_addr.s_addr != -1) {		hisctladdr.sin_family = AF_INET;		(void) strncpy(hostnamebuf, host, sizeof(hostnamebuf));	} else {		hp = gethostbyname(host);		if (hp == NULL) {			warnx("%s: %s", host, hstrerror(h_errno));			code = -1;			return ((char *) 0);		}		hisctladdr.sin_family = hp->h_addrtype;		memmove((caddr_t)&hisctladdr.sin_addr,				hp->h_addr_list[0], hp->h_length);		(void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));	}	hostname = hostnamebuf;	s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);	if (s < 0) {		warn("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;			char *ia;			ia = inet_ntoa(hisctladdr.sin_addr);			errno = oerrno;			warn("connect to address %s", ia);			hp->h_addr_list++;			memmove((caddr_t)&hisctladdr.sin_addr,					hp->h_addr_list[0], 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) {				warn("socket");				code = -1;				return (0);			}			continue;		}		warn("connect");		code = -1;		goto bad;	}	len = sizeof (myctladdr);	if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {		warn("getsockname");		code = -1;		goto bad;	}#ifdef IP_TOS	tos = IPTOS_LOWDELAY;	if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)		warn("setsockopt TOS (ignored)");#endif	cin = fdopen(s, "r");	cout = fdopen(s, "w");	if (cin == NULL || cout == NULL) {		warnx("fdopen failed.");		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) {			warn("setsockopt");		}	}#endif /* SO_OOBINLINE */	return (hostname);bad:	(void) close(s);	return ((char *)0);}intlogin(host)	char *host;{	char tmp[80];	char *user, *pass, *acct;	int n, aflag = 0;	user = pass = acct = 0;	if (ruserpass(host, &user, &pass, &acct) < 0) {		code = -1;		return (0);	}	while (user == 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')			user = myname;		else			user = tmp;	}	n = command("USER %s", user);	if (n == CONTINUE) {		if (pass == NULL)			pass = getpass("Password:");		n = command("PASS %s", pass);	}	if (n == CONTINUE) {		aflag++;		acct = getpass("Account:");		n = command("ACCT %s", acct);	}	if (n != COMPLETE) {		warnx("Login failed.");		return (0);	}	if (!aflag && acct != NULL)		(void) command("ACCT %s", acct);	if (proxy)		return (1);	for (n = 0; n < macnum; ++n) {		if (!strcmp("init", macros[n].mac_name)) {			(void) strcpy(line, "$init");			makeargv();			domacro(margc, margv);			break;		}	}	return (1);}voidcmdabort(){	printf("\n");	(void) fflush(stdout);	abrtflag++;	if (ptflag)		longjmp(ptabort,1);}/*VARARGS*/intcommand(va_alist)va_dcl{	va_list ap;	char *fmt;	int r;	sig_t oldintr;	abrtflag = 0;	if (debug) {		printf("---> ");		va_start(ap);		fmt = va_arg(ap, char *);		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) {		warn("No control connection for command");		code = -1;		return (0);	}	oldintr = signal(SIGINT, cmdabort);	va_start(ap);	fmt = va_arg(ap, char *);	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 */intgetreply(expecteof)	int expecteof;{	int c, n;	int dig;	int originalcode = 0, continuation = 0;	sig_t oldintr;	int pflag = 0;	char *cp, *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();				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();		if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)			(*oldintr)(SIGINT);		return (n - '0');	}}intempty(mask, sec)	struct fd_set *mask;	int sec;{	struct timeval t;	t.tv_sec = (long) sec;	t.tv_usec = 0;	return (select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t));}jmp_buf	sendabort;voidabortsend(){	mflag = 0;	abrtflag = 0;	printf("\nsend aborted\nwaiting for remote to finish abort\n");	(void) fflush(stdout);	longjmp(sendabort, 1);}#define HASHBYTES 1024voidsendrequest(cmd, local, remote, printnames)	char *cmd, *local, *remote;	int printnames;{	struct stat st;	struct timeval start, stop;	int c, d;	FILE *fin, *dout = 0, *popen();	int (*closefunc) __P((FILE *));	sig_t oldintr, oldintp;	long bytes = 0, hashbytes = HASHBYTES;	char *lmode, buf[BUFSIZ], *bufp;	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 (setjmp(sendabort)) {		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) {			warn("%s", local + 1);			(void) signal(SIGINT, oldintr);			(void) signal(SIGPIPE, oldintp);			code = -1;			return;		}		closefunc = pclose;	} else {		fin = fopen(local, "r");		if (fin == NULL) {			warn("local: %s", local);			(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);			code = -1;			return;		}	}	if (initconn()) {		(void) signal(SIGINT, oldintr);		if (oldintp)			(void) signal(SIGPIPE, oldintp);		code = -1;		if (closefunc != NULL)			(*closefunc)(fin);		return;	}	if (setjmp(sendabort))		goto abort;	if (restart_point &&	    (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {		int rc;		switch (curtype) {		case TYPE_A:			rc = fseek(fin, (long) restart_point, SEEK_SET);			break;		case TYPE_I:		case TYPE_L:			rc = lseek(fileno(fin), restart_point, SEEK_SET);			break;		}		if (rc < 0) {			warn("local: %s", local);			restart_point = 0;			if (closefunc != NULL)				(*closefunc)(fin);			return;		}		if (command("REST %ld", (long) restart_point)			!= CONTINUE) {			restart_point = 0;			if (closefunc != NULL)				(*closefunc)(fin);			return;		}		restart_point = 0;		lmode = "r+w";	}	if (remote) {		if (command("%s %s", cmd, remote) != PRELIM) {			(void) signal(SIGINT, oldintr);			if (oldintp)				(void) signal(SIGPIPE, oldintp);			if (closefunc != NULL)				(*closefunc)(fin);			return;		}	} else		if (command("%s", cmd) != PRELIM) {			(void) signal(SIGINT, oldintr);			if (oldintp)				(void) signal(SIGPIPE, oldintp);			if (closefunc != NULL)				(*closefunc)(fin);			return;		}	dout = dataconn(lmode);	if (dout == NULL)		goto abort;	(void) gettimeofday(&start, (struct timezone *)0);	oldintp = signal(SIGPIPE, SIG_IGN);	switch (curtype) {	case TYPE_I:	case TYPE_L:		errno = d = 0;		while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {			bytes += c;			for (bufp = buf; c > 0; c -= d, bufp += d)				if ((d = write(fileno(dout), bufp, c)) <= 0)					break;			if (hash) {				while (bytes >= hashbytes) {					(void) putchar('#');					hashbytes += HASHBYTES;				}				(void) fflush(stdout);			}		}		if (hash && bytes > 0) {			if (bytes < HASHBYTES)				(void) putchar('#');			(void) putchar('\n');			(void) fflush(stdout);		}		if (c < 0)			warn("local: %s", local);		if (d < 0) {			if (errno != EPIPE) 				warn("netout");			bytes = -1;		}		break;	case TYPE_A:		while ((c = getc(fin)) != EOF) {			if (c == '\n') {				while (hash && (bytes >= hashbytes)) {					(void) putchar('#');					(void) fflush(stdout);					hashbytes += HASHBYTES;				}				if (ferror(dout))					break;				(void) putc('\r', dout);				bytes++;			}			(void) putc(c, dout);			bytes++;	/*		if (c == '\r') {			  	*/	/*		(void)	putc('\0', dout);  // this violates rfc */	/*			bytes++;				*/	/*		}                          			*/			}		if (hash) {			if (bytes < hashbytes)				(void) putchar('#');			(void) putchar('\n');			(void) fflush(stdout);		}		if (ferror(fin))			warn("local: %s", local);		if (ferror(dout)) {			if (errno != EPIPE)				warn("netout");			bytes = -1;		}		break;	}	(void) gettimeofday(&stop, (struct timezone *)0);	if (closefunc != NULL)		(*closefunc)(fin);	(void) fclose(dout);	(void) getreply(0);	(void) signal(SIGINT, oldintr);	if (oldintp)		(void) signal(SIGPIPE, oldintp);	if (bytes > 0)		ptransfer("sent", bytes, &start, &stop);	return;abort:	(void) gettimeofday(&stop, (struct timezone *)0);	(void) signal(SIGINT, oldintr);	if (oldintp)		(void) signal(SIGPIPE, oldintp);	if (!cpend) {		code = -1;		return;	}	if (data >= 0) {		(void) close(data);		data = -1;	}	if (dout)		(void) fclose(dout);	(void) getreply(0);	code = -1;	if (closefunc != NULL && fin != NULL)		(*closefunc)(fin);	if (bytes > 0)		ptransfer("sent", bytes, &start, &stop);}jmp_buf	recvabort;voidabortrecv(){	mflag = 0;	abrtflag = 0;	printf("\nreceive aborted\nwaiting for remote to finish abort\n");	(void) fflush(stdout);	longjmp(recvabort, 1);}voidrecvrequest(cmd, local, remote, lmode, printnames)	char *cmd, *local, *remote, *lmode;	int printnames;{	FILE *fout, *din = 0;	int (*closefunc) __P((FILE *));	sig_t oldintr, oldintp;	int c, d, is_retr, tcrflag, bare_lfs = 0;	static int bufsize;	static char *buf;	long bytes = 0, hashbytes = HASHBYTES;	struct timeval start, stop;	struct stat st;	is_retr = strcmp(cmd, "RETR") == 0;	if (is_retr && verbose && printnames) {		if (local && *local != '-')			printf("local: %s ", local);		if (remote)			printf("remote: %s\n", remote);	}	if (proxy && is_retr) {		proxtrans(cmd, local, remote);		return;	}	closefunc = NULL;	oldintr = NULL;	oldintp = NULL;	tcrflag = !crflag && is_retr;	if (setjmp(recvabort)) {		while (cpend) {			(void) getreply(0);		}		if (data >= 0) {			(void) close(data);			data = -1;		}		if (oldintr)			(void) signal(SIGINT, oldintr);		code = -1;

⌨️ 快捷键说明

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