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

📄 betaftpd_complete.patch

📁 linux下编译交叉工具链的工具源码
💻 PATCH
📖 第 1 页 / 共 5 页
字号:
+ +-			del_fd(f->sock);++    assert((f->state == FTRAN_STATE_CONNECTING) || (f->state == FTRAN_STATE_TRANSFERING));+ +-			if (tempsock == -1) {+-				destroy_ftran(f);+-				continue;+-			}++    assert(f->sock == e->fd);++++/* Normally we would close the connection if we receive a POLLHUP,++ * but there seems to be a bug in epoll in which it sends spurious POLLHUP++ */++    if (e->revents & (rn_POLLERR /* | rn_POLLHUP */ )) { ++	destroy_ftran(f);++	return 0;++    }++++    if ((f->state == FTRAN_STATE_CONNECTING)) {++	/* FIXME: should retrieve the status of the non blocking connect before initiating++	 * transfer++	 */++	init_file_transfer(f);+ +-			f->sock = tempsock;+-			ioctl(f->sock, FIONBIO, &one);+-			init_file_transfer(f);+-#if WANT_UPLOAD+-	                if (f->upload) continue;+-#endif+-		}+-		if (f->state < 5) {+-			init_file_transfer(f);+ #if WANT_UPLOAD+-	                if (f->upload) continue;++	if (f->upload)++	    return 0;	/* FIXME */+ #endif+-		}++    }++++    assert(f->state == FTRAN_STATE_TRANSFERING);++++    do {+ +-		/* for download, we send the first packets right away */+ #if WANT_UPLOAD+-		if (f->upload) {+-			if (do_upload(f)) continue;+-		} else++	    if (f->upload) {++		transfer_status = do_upload(f);++	    } else+ #endif+-			if (do_download(f)) continue;++	    transfer_status = do_download(f);+ +-		/* do_{upload,download} returned 0, the transfer is complete */+-                if (!numeric(f->owner, 226, "Transfer complete."))+-			continue;+-                time(&(f->owner->last_transfer));++	    if (transfer_status == FTRAN_IORESULT_BLOCKED)++		    return;++	}++        while (transfer_status == FTRAN_IORESULT_PARTIAL);++++        assert((transfer_status == FTRAN_IORESULT_COMPLETE) || (transfer_status == FTRAN_IORESULT_FAILED));++++        if (transfer_status == FTRAN_IORESULT_COMPLETE) {++	    /* do_{upload,download} returned TRANSFER_STATUS_COMPLETE, the transfer is complete */++	    if (!numeric(f->owner, 226, "Transfer complete"))++		return 1;++	    time(&(f->owner->last_transfer));++	}++	else {++	     if (!numeric(f->owner, 550, "Transfer Failed"))++		  return 1;++	}+ + #if WANT_XFERLOG+-                if (!f->dir_listing) {+-			write_xferlog(f);+-		}++    if (!f->dir_listing)++	write_xferlog(f);+ #endif+ +-		destroy_ftran(f);++    destroy_ftran(f);+++ #if WANT_FULLSCREEN+-                update_display(first_conn);++    update_display(first_conn);+ #endif+-        }+ +-        return checked_through;++    return 0;+ }+ + #if WANT_UPLOAD+-int do_upload(struct ftran *f)++enum ftran_ioready do_upload(struct ftran *f)+ {+ 	char upload_buf[16384];++	enum ftran_ioresult upload_status;+ 	int size;+ #if WANT_ASCII+ 	/* keep buffer size small in ascii transfers +@@ -714,26 +807,39 @@+ 		size = ascii_uploadfilter(upload_buf, size);+ 	}+ #endif+-	if (size > 0 && (write(f->local_file, upload_buf, size) == size)) {+-		return 1;+-	} else if (size == -1) {+-		/* don't write xferlog... or? */+-		numeric(f->owner, 426, strerror(errno));+-		destroy_ftran(f);+-		return 1;+-	}+-	return 0;++	 if ((size == -1) && (errno == EWOULDBLOCK))++	      upload_status = FTRAN_IORESULT_BLOCKED;++	 else if ((size == -1) && (errno != EWOULDBLOCK)) {++	      upload_status = FTRAN_IORESULT_FAILED;++	      /* don't write xferlog... or? */++	      numeric(f->owner, 426, strerror(errno));++	 }++	 else if (size > 0) {++	     if (write(f->local_file, upload_buf, size) == size)++		 upload_status = FTRAN_IORESULT_PARTIAL;++	     else++		 upload_status = FTRAN_IORESULT_FAILED;++	 }++        else if (size == 0) ++ 	     upload_status = FTRAN_IORESULT_COMPLETE;++	 ++	 DPRINT("f->sock %d, size %d, upload status %d\n",f->sock,size,f->pos,upload_status);++	 return upload_status;+ } + #endif+ +-int do_download(struct ftran *f)++/* Return TRUE if there is more to send, FALSE if the caller++ * can destroy the ftran.++ * On exit, the ftran is never destroyed, that's the caller's job.++ */++enum ftran_ioresult do_download(struct ftran *f)+ {+ #if defined(TCP_CORK) && defined(SOL_TCP)+ 	unsigned int zero = 0;+ #endif+ 	char *sendfrom_buf;+-	int bytes_to_send;+-	int more_to_send = 0;++	int bytes_to_send,nbytes;++	enum ftran_ioresult download_status;+ + #if !HAVE_MMAP+ 	char buf[MAX_BLOCK_SIZE];+@@ -749,8 +854,8 @@+ 	 * Here we use a rather simplified sending `algorithm',+ 	 * leaving most of the quirks to the system calls.+ 	 */++	/* FIXME: don't activate this if WANT_ASCII && (f->ascii_mode == 1) */+ 	if (sendfile_supported == 1 && f->dir_listing == 0) {+-		int err;+ 		size = f->size - f->pos;+ + 		if (size > f->block_size) size = f->block_size;+@@ -758,30 +863,39 @@+ + #ifdef TCP_CORK+ 		if (size != f->block_size) {+-                	setsockopt(f->sock, SOL_TCP, TCP_CORK, (void *)&zero, sizeof(zero));++                	err=setsockopt(f->sock, SOL_TCP, TCP_CORK, (void *)&zero, sizeof(zero));+         	}	+ #endif+ +-       		err = sendfile(f->sock, f->local_file, &f->pos, size);+-		return (f->pos < f->size) && (err > -1);++       		nbytes = sendfile(f->sock, f->local_file, &f->pos, size);++		if (nbytes == -1) assert(errno != EINTR);++		if (f->pos == f->size) ++		    download_status = FTRAN_IORESULT_COMPLETE;++		else if (nbytes > -1)++		    download_status = FTRAN_IORESULT_PARTIAL;++		else if (errno == EWOULDBLOCK)++		    download_status = FTRAN_IORESULT_BLOCKED;++		else++		    download_status = FTRAN_IORESULT_FAILED;++++		DPRINT("f->sock %d, f->local_file %d, f->pos %d, size %d, bytes sent %d download_status %d\n",f->sock,f->local_file,f->pos,size,nbytes,download_status);++++		return download_status;+ 	}+ #endif+ + #if HAVE_MMAP+         size = f->size - f->pos;+-+         if (size > f->block_size) size = f->block_size;+         if (size < 0) size = 0;+ + 	bytes_to_send = size;+ 	sendfrom_buf = f->file_data + f->pos;+ #else+-	bytes_to_send = read(f->local_file, buf, f->block_size);++	bytes_to_send = pread(f->local_file, buf, f->block_size,f->pos);+ 	sendfrom_buf = buf;+ #endif+ +-	if (bytes_to_send == f->block_size) more_to_send = 1;+-+ #if WANT_ASCII+ 	if (f->ascii_mode == 1) {+ 		bytes_to_send = ascii_downloadfilter(sendfrom_buf,+@@ -790,27 +904,35 @@+        	}+ #endif /* WANT_ASCII */+ +-#if defined(TCP_CORK) && defined(SOL_TCP)+-	/* if we believe this is the last packet, unset TCP_CORK */+-	if (more_to_send == 0) {+-		setsockopt(f->sock, SOL_TCP, TCP_CORK, (void *)&zero, sizeof(zero));+-	}+-#endif+-+-	size = send(f->sock, sendfrom_buf, bytes_to_send, 0);+-	if (size < bytes_to_send) more_to_send = 1;++	nbytes = send(f->sock, sendfrom_buf, bytes_to_send, 0);+ + #if WANT_ASCII+-	if (f->ascii_mode == 1 && size < bytes_to_send && size > 0) {+-		size = ascii_findlength(sendfrom_buf, size);++	if (f->ascii_mode == 1 && nbytes < bytes_to_send && nbytes > 0) {++		size = ascii_findlength(sendfrom_buf, nbytes);+ 	}+ #endif+ +-#if HAVE_MMAP+ 	if (size > 0) f->pos += size;++++	if (f->pos == f->size)++	    download_status = FTRAN_IORESULT_COMPLETE;++	else if ( ((nbytes == bytes_to_send) && (f->pos < f->size)) || ((nbytes < bytes_to_send) && (nbytes > -1)) )++	    download_status = FTRAN_IORESULT_PARTIAL;++	else if (errno == EWOULDBLOCK)++	    download_status = FTRAN_IORESULT_BLOCKED;++	else ++	    download_status = FTRAN_IORESULT_FAILED;++++	DPRINT("send returns %d, bytes to send %d, with errno %d, transfer status = %d\n",nbytes,bytes_to_send,errno,download_status);++++#if defined(TCP_CORK) && defined(SOL_TCP)++	/* if we believe this is the last packet, unset TCP_CORK */++	if (download_status == FTRAN_IORESULT_COMPLETE) {++		int err=setsockopt(f->sock, SOL_TCP, TCP_CORK, (void *)&zero, sizeof(zero));++	}+ #endif+ +-	return more_to_send;++	return download_status;+ }+ + #if WANT_XFERLOG+@@ -875,40 +997,31 @@+ int main(void)+ {+ 	int server_sock;++	struct rlimit rlimit;+ +-#if HAVE_POLL+-	/* the sets are declared globally if we use poll() */+-#else+-	fd_set fds, fds_send;+-#endif++	getrlimit(RLIMIT_NOFILE,&rlimit);++	FD_MAX = rlimit.rlim_max;++	printf("FD_MAX set to %d\n",FD_MAX);+ + 	/*setlinebuf(stdout);*/+ 	setvbuf(stdout, (char *)NULL, _IOLBF, 0); + + 	signal(SIGPIPE, SIG_IGN);+ +++ 	printf("BetaFTPD version %s, Copyright (C) 1999-2000 Steinar H. Gunderson\n", VERSION);+ 	puts("BetaFTPD comes with ABSOLUTELY NO WARRANTY; for details see the file");+ 	puts("COPYING. This is free software, and you are welcome to redistribute it");+ 	puts("under certain conditions; again see the file COPYING for details.");+ 	puts("");+ ++	+ 	/* we don't need stdin */+ 	close(0);+ +-#if HAVE_POLL+-	{+-		int i;+-		for (i = 0; i < FD_MAX; i++) {+-			fds[i].fd = -1;+-			fds[i].events = 0;+-		}+-	}+-#else+-	FD_ZERO(&master_fds);+-	FD_ZERO(&master_send_fds);+-#endif+-++	own_pid=getpid();++	rn_init(&rns,FD_MAX);++	rn_setSignum(&rns,SIGRTMIN);+ 	server_sock = create_server_socket();+ + #if WANT_FULLSCREEN+@@ -916,6 +1029,7 @@+ #endif+ + 	/* init dummy first connection */+++ 	first_conn = alloc_new_conn(-1);+ 	first_ftran = alloc_new_ftran(0, NULL);+ #if WANT_DCACHE+@@ -968,102 +1082,42 @@+ 		if (errno == ENOSYS) sendfile_supported = 0;+ 	}+ #endif++	/* create the header of the list containing all the deleted objects++	 * (both conn and ftran). ++	 */+ +-	for ( ;; ) {+-		int i;+-#ifndef HAVE_POLL+-		struct timeval timeout;+-#endif+-+-		/*screw_clients();       //look for memory errors */++	destroyed_list_header = (struct list_element *) calloc(1,sizeof(struct list_element));+ ++	for ( ;; ) {++		int i,err;++		+ #if WANT_FULLSCREEN+ 	        update_display(first_conn);+ #endif+-+-#if HAVE_POLL+-		i = poll(fds, highest_fds + 1, 60000);+-#if 0+-		{+-			int j;+-			for (j=0; j<=highest_fds; j++) {+-				if (fds[j].revents) printf("fds[%d].fd %d, .revents %x\n", j, fds[j].fd, fds[j].revents);++		++		err=rn_waitAndDispatchEvents(&rns,100000);++		if (err) {++			if (err == EBADF) {++			/* fill in here later */+ 			}+-		}+-#endif+-#else+-		/* reset fds (gets changed by select()) */+-		fds = master_fds;+-		fds_send = master_send_fds;+-+-		/*+-		 * wait up to 60 secs for any activity +-		 */+-		timeout.tv_sec = 60;+-		timeout.tv_usec = 0;+-+-		i = select(FD_SETSIZE, &fds, &fds_send, NULL, &timeout);+-#endif+-+-		if (i == -1) {+-			if (errno == EBADF) {+-#if !HAVE_POLL+-				/* don't like this, but we have to */+-				clear_bad_fds(&server_sock);+-#endif+-			} else if (errno != EINTR) {+-#if HAVE_POLL+-				perror("poll()");+-#else+-				perror("select()");+-#endif++			else if (err == EWOULDBLOCK) {+ 				continue;+ 			}+ 		}++		++		/* once waitAndDispatchEvents has returned, we can delete ++		 * the list of destroyed objects.++		 */+ +-#if HAVE_POLL+-		/* fix an invalid server socket */+-		if (fds[server_sock].revents & POLLERR) {+-			del_fd(server_sock);+-			server_sock = create_server_socket();+-		}+-#endif+-++		purge_destroyed_list();		++				+ 		/* remove any timed out sockets */+ 		if (time_to_check) {+ 			time_out_sockets();+ #if WANT_DCACHE+-			time_out_dcache();++		time_out_dcache();+ #endif+-			time_to_check = 0;+-		}+-+-		if (i <= 0) continue;+-+-#if HAVE_POLL+-		i -= process_all_sendfiles(i);+-		process_all_clients(i);+-#else+-		/* sends are given highest `priority' */+-		i -= process_all_sendfiles(&fds_send, i);+-+-		/* incoming PASV connections and uploads */+-		i -= process_all_sendfiles(&fds, i);+-+-		/*+-		 * check the incoming PASV connections first, so+-		 * process_all_clients() won't be confused.+-		 */ +-		process_all_clients(&fds, i);+-#endif+-+-#if HAVE_POLL+-		if (fds[server_sock].revents & POLLIN) {+-#else+-		if (FD_ISSET(server_sock, &fds)) {+-#endif+-			accept_new_client(&server_sock);+-			i--;++		time_to_check = 0;

⌨️ 快捷键说明

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