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

📄 ftp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
		return;	}	oldintr = signal(SIGINT, abortrecv);	if (strcmp(local, "-") && *local != '|') {		if (access(local, 2) < 0) {			char *dir = strrchr(local, '/');			if (errno != ENOENT && errno != EACCES) {				warn("local: %s", local);				(void) signal(SIGINT, oldintr);				code = -1;				return;			}			if (dir != NULL)				*dir = 0;			d = access(dir ? local : ".", 2);			if (dir != NULL)				*dir = '/';			if (d < 0) {				warn("local: %s", local);				(void) signal(SIGINT, oldintr);				code = -1;				return;			}			if (!runique && errno == EACCES &&			    chmod(local, 0600) < 0) {				warn("local: %s", local);				(void) signal(SIGINT, oldintr);				(void) signal(SIGINT, oldintr);				code = -1;				return;			}			if (runique && errno == EACCES &&			   (local = gunique(local)) == NULL) {				(void) signal(SIGINT, oldintr);				code = -1;				return;			}		}		else if (runique && (local = gunique(local)) == NULL) {			(void) signal(SIGINT, oldintr);			code = -1;			return;		}	}	if (!is_retr) {		if (curtype != TYPE_A)			changetype(TYPE_A, 0);	} else if (curtype != type)		changetype(type, 0);	if (initconn()) {		(void) signal(SIGINT, oldintr);		code = -1;		return;	}	if (setjmp(recvabort))		goto abort;	if (is_retr && restart_point &&	    command("REST %ld", (long) restart_point) != CONTINUE)		return;	if (remote) {		if (command("%s %s", cmd, remote) != PRELIM) {			(void) signal(SIGINT, oldintr);			return;		}	} else {		if (command("%s", cmd) != PRELIM) {			(void) signal(SIGINT, oldintr);			return;		}	}	din = dataconn("r");	if (din == NULL)		goto abort;	if (strcmp(local, "-") == 0)		fout = stdout;	else if (*local == '|') {		oldintp = signal(SIGPIPE, SIG_IGN);		fout = popen(local + 1, "w");		if (fout == NULL) {			warn("%s", local+1);			goto abort;		}		closefunc = pclose;	} else {		fout = fopen(local, lmode);		if (fout == NULL) {			warn("local: %s", local);			goto abort;		}		closefunc = fclose;	}	if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)		st.st_blksize = BUFSIZ;	if (st.st_blksize > bufsize) {		if (buf)			(void) free(buf);		buf = malloc((unsigned)st.st_blksize);		if (buf == NULL) {			warn("malloc");			bufsize = 0;			goto abort;		}		bufsize = st.st_blksize;	}	(void) gettimeofday(&start, (struct timezone *)0);	switch (curtype) {	case TYPE_I:	case TYPE_L:		if (restart_point &&		    lseek(fileno(fout), restart_point, SEEK_SET) < 0) {			warn("local: %s", local);			if (closefunc != NULL)				(*closefunc)(fout);			return;		}		errno = d = 0;		while ((c = read(fileno(din), buf, bufsize)) > 0) {			if ((d = write(fileno(fout), buf, c)) != c)				break;			bytes += c;			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) {			if (errno != EPIPE)				warn("netin");			bytes = -1;		}		if (d < c) {			if (d < 0)				warn("local: %s", local);			else				warnx("%s: short write", local);		}		break;	case TYPE_A:		if (restart_point) {			int i, n, ch;			if (fseek(fout, 0L, SEEK_SET) < 0)				goto done;			n = restart_point;			for (i = 0; i++ < n;) {				if ((ch = getc(fout)) == EOF)					goto done;				if (ch == '\n')					i++;			}			if (fseek(fout, 0L, SEEK_CUR) < 0) {done:				warn("local: %s", local);				if (closefunc != NULL)					(*closefunc)(fout);				return;			}		}		while ((c = getc(din)) != EOF) {			if (c == '\n')				bare_lfs++;			while (c == '\r') {				while (hash && (bytes >= hashbytes)) {					(void) putchar('#');					(void) fflush(stdout);					hashbytes += HASHBYTES;				}				bytes++;				if ((c = getc(din)) != '\n' || tcrflag) {					if (ferror(fout))						goto break2;					(void) putc('\r', fout);					if (c == '\0') {						bytes++;						goto contin2;					}					if (c == EOF)						goto contin2;				}			}			(void) putc(c, fout);			bytes++;	contin2:	;		}break2:		if (bare_lfs) {			printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);			printf("File may not have transferred correctly.\n");		}		if (hash) {			if (bytes < hashbytes)				(void) putchar('#');			(void) putchar('\n');			(void) fflush(stdout);		}		if (ferror(din)) {			if (errno != EPIPE)				warn("netin");			bytes = -1;		}		if (ferror(fout))			warn("local: %s", local);		break;	}	if (closefunc != NULL)		(*closefunc)(fout);	(void) signal(SIGINT, oldintr);	if (oldintp)		(void) signal(SIGPIPE, oldintp);	(void) gettimeofday(&stop, (struct timezone *)0);	(void) fclose(din);	(void) getreply(0);	if (bytes > 0 && is_retr)		ptransfer("received", bytes, &start, &stop);	return;abort:/* abort using RFC959 recommended IP,SYNC sequence  */	(void) gettimeofday(&stop, (struct timezone *)0);	if (oldintp)		(void) signal(SIGPIPE, oldintr);	(void) signal(SIGINT, SIG_IGN);	if (!cpend) {		code = -1;		(void) signal(SIGINT, oldintr);		return;	}	abort_remote(din);	code = -1;	if (data >= 0) {		(void) close(data);		data = -1;	}	if (closefunc != NULL && fout != NULL)		(*closefunc)(fout);	if (din)		(void) fclose(din);	if (bytes > 0)		ptransfer("received", bytes, &start, &stop);	(void) signal(SIGINT, oldintr);}/* * Need to start a listen on the data channel before we send the command, * otherwise the server's connect may fail. */intinitconn(){	char *p, *a;	int result, len, tmpno = 0;	int on = 1;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) {		warn("socket");		if (tmpno)			sendport = 1;		return (1);	}	if (!sendport)		if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {			warn("setsockopt (reuse address)");			goto bad;		}	if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {		warn("bind");		goto bad;	}	if (options & SO_DEBUG &&	    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)		warn("setsockopt (ignored)");	len = sizeof (data_addr);	if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {		warn("getsockname");		goto bad;	}	if (listen(data, 1) < 0)		warn("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)		warn("setsockopt TOS (ignored)");#endif	return (0);bad:	(void) close(data), data = -1;	if (tmpno)		sendport = 1;	return (1);}FILE *dataconn(lmode)	char *lmode;{	struct sockaddr_in from;	int s, fromlen = sizeof (from), tos;	s = accept(data, (struct sockaddr *) &from, &fromlen);	if (s < 0) {		warn("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)		warn("setsockopt TOS (ignored)");#endif	return (fdopen(data, lmode));}voidptransfer(direction, bytes, t0, t1)	char *direction;	long bytes;	struct timeval *t0, *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 %.2g seconds (%.2g Kbytes/s)\n",		    bytes, direction, s, bs / 1024.);	}}/*voidtvadd(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;}*/voidtvsub(tdiff, t1, t0)	struct timeval *tdiff, *t1, *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;}voidpsabort(){	abrtflag++;}voidpswitch(flag)	int flag;{	sig_t oldintr;	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);	}}voidabortpt(){	printf("\n");	(void) fflush(stdout);	ptabflg++;	mflag = 0;	abrtflag = 0;	longjmp(ptabort, 1);}voidproxtrans(cmd, local, remote)	char *cmd, *local, *remote;{	sig_t oldintr;	int secndflag = 0, prox_type, nfnd;	char *cmd2;	struct 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 (setjmp(ptabort))		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) {				warn("abort");			}			if (ptabflg)				code = -1;			lostpeer();		}		(void) getreply(0);		(void) getreply(0);	}	if (proxy)		pswitch(0);	pswitch(1);	if (ptabflg)		code = -1;	(void) signal(SIGINT, oldintr);}voidreset(argc, argv)	int argc;	char *argv[];{	struct fd_set mask;	int nfnd = 1;	FD_ZERO(&mask);	while (nfnd > 0) {		FD_SET(fileno(cin), &mask);		if ((nfnd = empty(&mask,0)) < 0) {			warn("reset");			code = -1;			lostpeer();		}		else if (nfnd) {			(void) getreply(0);		}	}}char *gunique(local)	char *local;{	static char new[MAXPATHLEN];	char *cp = strrchr(local, '/');	int d, count=0;	char ext = '1';	if (cp)		*cp = '\0';	d = access(cp ? local : ".", 2);	if (cp)		*cp = '/';	if (d < 0) {		warn("local: %s", local);		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);}voidabort_remote(din)	FILE *din;{	char buf[BUFSIZ];	int nfnd;	struct 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)		warn("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) {			warn("abort");		}		if (ptabflg)			code = -1;		lostpeer();	}	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 + -