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

📄 ftp.c

📁 UNIX FTP client
💻 C
📖 第 1 页 / 共 3 页
字号:
 * otherwise the server's connect may fail. */static intinitconn(void){	register char *p, *a;	int result, tmpno = 0;	size_t len;	int on = 1;	int tos;	u_long a1,a2,a3,a4,p1,p2;	if (passivemode) {		data = socket(AF_INET, SOCK_STREAM, 0);		if (data < 0) {			perror("ftp: socket");			return(1);		}		if (options & SO_DEBUG &&		    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,			       sizeof (on)) < 0)			perror("ftp: setsockopt (ignored)");		if (command("PASV") != COMPLETE) {			printf("Passive mode refused.\n");			return(1);		}		/*		 * What we've got at this point is a string of comma separated		 * one-byte unsigned integer values, separated by commas.		 * The first four are the an IP address. The fifth is the MSB		 * of the port number, the sixth is the LSB. From that we'll		 * prepare a sockaddr_in.		 */		if (sscanf(pasv,"%ld,%ld,%ld,%ld,%ld,%ld",			   &a1,&a2,&a3,&a4,&p1,&p2)		    != 6) 		{			printf("Passive mode address scan failure. Shouldn't happen!\n");			return(1);		}		data_addr.sin_family = AF_INET;		data_addr.sin_addr.s_addr = htonl((a1 << 24) | (a2 << 16) |						  (a3 << 8) | a4);		data_addr.sin_port = htons((p1 << 8) | p2);		if (connect(data, (struct sockaddr *) &data_addr,		    sizeof(data_addr))<0) {			perror("ftp: connect");			return(1);		}#ifdef IP_TOS		tos = IPTOS_THROUGHPUT;		if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos,		    sizeof(tos)) < 0)			perror("ftp: setsockopt TOS (ignored)");#endif		return(0);	}noport:	data_addr = myctladdr;	if (sendport)		data_addr.sin_port = 0;	/* let system pick one */ 	if (data != -1)		(void) close(data);	data = socket(AF_INET, SOCK_STREAM, 0);	if (data < 0) {		perror("ftp: socket");		if (tmpno)			sendport = 1;		return (1);	}	if (!sendport)		if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {			perror("ftp: setsockopt (reuse address)");			goto bad;		}	if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {		perror("ftp: bind");		goto bad;	}	if (options & SO_DEBUG &&	    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)		perror("ftp: setsockopt (ignored)");	len = sizeof (data_addr);	if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {		perror("ftp: getsockname");		goto bad;	}	if (listen(data, 1) < 0)		perror("ftp: listen");	if (sendport) {		a = (char *)&data_addr.sin_addr;		p = (char *)&data_addr.sin_port;#define	UC(b)	(((int)b)&0xff)		result =		    command("PORT %d,%d,%d,%d,%d,%d",		      UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),		      UC(p[0]), UC(p[1]));		if (result == ERROR && sendport == -1) {			sendport = 0;			tmpno = 1;			goto noport;		}		return (result != COMPLETE);	}	if (tmpno)		sendport = 1;#ifdef IP_TOS	on = IPTOS_THROUGHPUT;	if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)		perror("ftp: setsockopt TOS (ignored)");#endif	return (0);bad:	(void) close(data), data = -1;	if (tmpno)		sendport = 1;	return (1);}static FILE *dataconn(const char *lmode){	struct sockaddr_in from;	int s, tos;	size_t fromlen = sizeof(from);        if (passivemode)            return (fdopen(data, lmode));	s = accept(data, (struct sockaddr *) &from, &fromlen);	if (s < 0) {		perror("ftp: accept");		(void) close(data), data = -1;		return (NULL);	}	(void) close(data);	data = s;#ifdef IP_TOS	tos = IPTOS_THROUGHPUT;	if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)		perror("ftp: setsockopt TOS (ignored)");#endif	return (fdopen(data, lmode));}static voidptransfer(const char *direction, long bytes, 	  const struct timeval *t0, 	  const struct timeval *t1){	struct timeval td;	float s, bs;	if (verbose) {		tvsub(&td, t1, t0);		s = td.tv_sec + (td.tv_usec / 1000000.);#define	nz(x)	((x) == 0 ? 1 : (x))		bs = bytes / nz(s);		printf("%ld bytes %s in %.3g secs (%.2g Kbytes/sec)\n",		    bytes, direction, s, bs / 1024.0);	}}#if 0tvadd(tsum, t0)	struct timeval *tsum, *t0;{	tsum->tv_sec += t0->tv_sec;	tsum->tv_usec += t0->tv_usec;	if (tsum->tv_usec > 1000000)		tsum->tv_sec++, tsum->tv_usec -= 1000000;}#endifstatic voidtvsub(struct timeval *tdiff,       const struct timeval *t1,       const struct timeval *t0){	tdiff->tv_sec = t1->tv_sec - t0->tv_sec;	tdiff->tv_usec = t1->tv_usec - t0->tv_usec;	if (tdiff->tv_usec < 0)		tdiff->tv_sec--, tdiff->tv_usec += 1000000;}static voidpsabort(int ignore){	(void)ignore;	abrtflag++;}voidpswitch(int flag){	void (*oldintr)(int);	static struct comvars {		int connect;		char name[MAXHOSTNAMELEN];		struct sockaddr_in mctl;		struct sockaddr_in hctl;		FILE *in;		FILE *out;		int tpe;		int curtpe;		int cpnd;		int sunqe;		int runqe;		int mcse;		int ntflg;		char nti[17];		char nto[17];		int mapflg;		char mi[MAXPATHLEN];		char mo[MAXPATHLEN];	} proxstruct, tmpstruct;	struct comvars *ip, *op;	abrtflag = 0;	oldintr = signal(SIGINT, psabort);	if (flag) {		if (proxy)			return;		ip = &tmpstruct;		op = &proxstruct;		proxy++;	} 	else {		if (!proxy)			return;		ip = &proxstruct;		op = &tmpstruct;		proxy = 0;	}	ip->connect = connected;	connected = op->connect;	if (hostname) {		(void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);		ip->name[strlen(ip->name)] = '\0';	} 	else {		ip->name[0] = 0;	}	hostname = op->name;	ip->hctl = hisctladdr;	hisctladdr = op->hctl;	ip->mctl = myctladdr;	myctladdr = op->mctl;	ip->in = cin;	cin = op->in;	ip->out = cout;	cout = op->out;	ip->tpe = type;	type = op->tpe;	ip->curtpe = curtype;	curtype = op->curtpe;	ip->cpnd = cpend;	cpend = op->cpnd;	ip->sunqe = sunique;	sunique = op->sunqe;	ip->runqe = runique;	runique = op->runqe;	ip->mcse = mcase;	mcase = op->mcse;	ip->ntflg = ntflag;	ntflag = op->ntflg;	(void) strncpy(ip->nti, ntin, 16);	(ip->nti)[strlen(ip->nti)] = '\0';	(void) strcpy(ntin, op->nti);	(void) strncpy(ip->nto, ntout, 16);	(ip->nto)[strlen(ip->nto)] = '\0';	(void) strcpy(ntout, op->nto);	ip->mapflg = mapflag;	mapflag = op->mapflg;	(void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);	(ip->mi)[strlen(ip->mi)] = '\0';	(void) strcpy(mapin, op->mi);	(void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);	(ip->mo)[strlen(ip->mo)] = '\0';	(void) strcpy(mapout, op->mo);	(void) signal(SIGINT, oldintr);	if (abrtflag) {		abrtflag = 0;		(*oldintr)(SIGINT);	}}staticvoidabortpt(int ignore){	(void)ignore;	printf("\n");	fflush(stdout);	ptabflg++;	mflag = 0;	abrtflag = 0;	siglongjmp(ptabort, 1);}static voidproxtrans(const char *cmd, char *local, char *remote){	void (*volatile oldintr)(int);	volatile int secndflag = 0, prox_type, nfnd;	const char *volatile cmd2;	fd_set mask;	if (strcmp(cmd, "RETR"))		cmd2 = "RETR";	else		cmd2 = runique ? "STOU" : "STOR";	if ((prox_type = type) == 0) {		if (unix_server && unix_proxy)			prox_type = TYPE_I;		else			prox_type = TYPE_A;	}	if (curtype != prox_type)		changetype(prox_type, 1);	if (command("PASV") != COMPLETE) {		printf("proxy server does not support third party transfers.\n");		return;	}	pswitch(0);	if (!connected) {		printf("No primary connection\n");		pswitch(1);		code = -1;		return;	}	if (curtype != prox_type)		changetype(prox_type, 1);	if (command("PORT %s", pasv) != COMPLETE) {		pswitch(1);		return;	}	if (sigsetjmp(ptabort, 1))		goto abort;	oldintr = signal(SIGINT, abortpt);	if (command("%s %s", cmd, remote) != PRELIM) {		(void) signal(SIGINT, oldintr);		pswitch(1);		return;	}	sleep(2);	pswitch(1);	secndflag++;	if (command("%s %s", cmd2, local) != PRELIM)		goto abort;	ptflag++;	(void) getreply(0);	pswitch(0);	(void) getreply(0);	(void) signal(SIGINT, oldintr);	pswitch(1);	ptflag = 0;	printf("local: %s remote: %s\n", local, remote);	return;abort:	(void) signal(SIGINT, SIG_IGN);	ptflag = 0;	if (strcmp(cmd, "RETR") && !proxy)		pswitch(1);	else if (!strcmp(cmd, "RETR") && proxy)		pswitch(0);	if (!cpend && !secndflag) {  /* only here if cmd = "STOR" (proxy=1) */		if (command("%s %s", cmd2, local) != PRELIM) {			pswitch(0);			if (cpend)				abort_remote((FILE *) NULL);		}		pswitch(1);		if (ptabflg)			code = -1;		(void) signal(SIGINT, oldintr);		return;	}	if (cpend)		abort_remote((FILE *) NULL);	pswitch(!proxy);	if (!cpend && !secndflag) {  /* only if cmd = "RETR" (proxy=1) */		if (command("%s %s", cmd2, local) != PRELIM) {			pswitch(0);			if (cpend)				abort_remote((FILE *) NULL);			pswitch(1);			if (ptabflg)				code = -1;			(void) signal(SIGINT, oldintr);			return;		}	}	if (cpend)		abort_remote((FILE *) NULL);	pswitch(!proxy);	if (cpend) {		FD_ZERO(&mask);		FD_SET(fileno(cin), &mask);		if ((nfnd = empty(&mask, 10)) <= 0) {			if (nfnd < 0) {				perror("abort");			}			if (ptabflg)				code = -1;			lostpeer(0);		}		(void) getreply(0);		(void) getreply(0);	}	if (proxy)		pswitch(0);	pswitch(1);	if (ptabflg)		code = -1;	(void) signal(SIGINT, oldintr);}voidreset(void){	fd_set mask;	int nfnd = 1;	FD_ZERO(&mask);	while (nfnd > 0) {		FD_SET(fileno(cin), &mask);		if ((nfnd = empty(&mask,0)) < 0) {			perror("reset");			code = -1;			lostpeer(0);		}		else if (nfnd) {			(void) getreply(0);		}	}}static char *gunique(char *local){	static char new[MAXPATHLEN];	char *cp = rindex(local, '/');	int d, count=0;	char ext = '1';	if (cp)		*cp = '\0';	d = access(cp ? local : ".", 2);	if (cp)		*cp = '/';	if (d < 0) {		fprintf(stderr, "local: %s: %s\n", local, strerror(errno));		return((char *) 0);	}	(void) strcpy(new, local);	cp = new + strlen(new);	*cp++ = '.';	while (!d) {		if (++count == 100) {			printf("runique: can't find unique file name.\n");			return((char *) 0);		}		*cp++ = ext;		*cp = '\0';		if (ext == '9')			ext = '0';		else			ext++;		if ((d = access(new, 0)) < 0)			break;		if (ext != '0')			cp--;		else if (*(cp - 2) == '.')			*(cp - 1) = '1';		else {			*(cp - 2) = *(cp - 2) + 1;			cp--;		}	}	return(new);}static voidabort_remote(FILE *din){	char buf[BUFSIZ];	int nfnd;	fd_set mask;	/*	 * send IAC in urgent mode instead of DM because 4.3BSD places oob mark	 * after urgent byte rather than before as is protocol now	 */	sprintf(buf, "%c%c%c", IAC, IP, IAC);	if (send(fileno(cout), buf, 3, MSG_OOB) != 3)		perror("abort");	fprintf(cout,"%cABOR\r\n", DM);	(void) fflush(cout);	FD_ZERO(&mask);	FD_SET(fileno(cin), &mask);	if (din) { 		FD_SET(fileno(din), &mask);	}	if ((nfnd = empty(&mask, 10)) <= 0) {		if (nfnd < 0) {			perror("abort");		}		if (ptabflg)			code = -1;		lostpeer(0);	}	if (din && FD_ISSET(fileno(din), &mask)) {		while (read(fileno(din), buf, BUFSIZ) > 0)			/* LOOP */;	}	if (getreply(0) == ERROR && code == 552) {		/* 552 needed for nic style abort */		(void) getreply(0);	}	(void) getreply(0);}

⌨️ 快捷键说明

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