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

📄 ftp.c

📁 elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, elinks也是gentoo安装过程中默认使用的浏览器, 这是elinks源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
					 * feature. */					if (response == 350)						conn->from = conn->progress->start;					/* Come on, don't be nervous ;-). */					if (conn->progress->start >= 0) {						/* Update to the real value						 * which we've got from						 * Content-Range. */						conn->progress->seek = conn->from;					}					conn->progress->start = conn->from;				}				break;			default:				INTERNAL("WHAT???");		}		ftp_send_retr_req(conn, S_GETH);		return;	}	response = get_ftp_response(conn, rb, 2, NULL);	if (response == -1) {		abort_connection(conn, S_FTP_ERROR);		return;	}	if (!response) {		read_from_socket(conn->socket, rb, S_GETH, ftp_retr_file);		return;	}	if (response >= 100 && response < 200) {		/* We only need to parse response after RETR to		 * get filesize if needed. */		if (!ftp->dir && conn->est_length == -1) {			off_t file_len;			file_len = get_filesize_from_RETR(rb->data, rb->length);			if (file_len > 0) {				/* FIXME: ..when downloads resuming				 * implemented.. */				conn->est_length = file_len + conn->progress->start;			}		}	}	set_handlers(conn->data_socket->fd, (select_handler_T) ftp_data_accept,		     NULL, NULL, conn);	/* read_from_socket(conn->socket, rb, ftp_got_final_response); */	ftp_got_final_response(socket, rb);}static voidftp_got_final_response(struct socket *socket, struct read_buffer *rb){	struct connection *conn = socket->conn;	struct ftp_connection_info *ftp = conn->info;	int response = get_ftp_response(conn, rb, 0, NULL);	if (response == -1) {		abort_connection(conn, S_FTP_ERROR);		return;	}	if (!response) {		enum connection_state state = conn->state != S_TRANS					    ? S_GETH : conn->state;		read_from_socket(conn->socket, rb, state, ftp_got_final_response);		return;	}	if (response >= 550 || response == 450) {		/* Requested action not taken.		 * File unavailable (e.g., file not found, no access). */		if (!conn->cached)			conn->cached = get_cache_entry(conn->uri);		if (!conn->cached		    || !redirect_cache(conn->cached, "/", 1, 0)) {			abort_connection(conn, S_OUT_OF_MEM);			return;		}		abort_connection(conn, S_OK);		return;	}	if (response >= 400) {		abort_connection(conn, S_FTP_FILE_ERROR);		return;	}	if (ftp->conn_state == 2) {		ftp_end_request(conn, S_OK);	} else {		ftp->conn_state = 1;		if (conn->state != S_TRANS)			set_connection_state(conn, S_GETH);	}}/* Display directory entry formatted in HTML. */static intdisplay_dir_entry(struct cache_entry *cached, off_t *pos, int *tries,		  int colorize_dir, unsigned char *dircolor,		  struct ftp_file_info *ftp_info){	struct string string;	unsigned char permissions[10] = "---------";	if (!init_string(&string)) return -1;	add_char_to_string(&string, ftp_info->type);	if (ftp_info->permissions) {		mode_t p = ftp_info->permissions;#define FTP_PERM(perms, buffer, flag, index, id) \	if ((perms) & (flag)) (buffer)[(index)] = (id);		FTP_PERM(p, permissions, S_IRUSR, 0, 'r');		FTP_PERM(p, permissions, S_IWUSR, 1, 'w');		FTP_PERM(p, permissions, S_IXUSR, 2, 'x');		FTP_PERM(p, permissions, S_ISUID, 2, (p & S_IXUSR ? 's' : 'S'));		FTP_PERM(p, permissions, S_IRGRP, 3, 'r');		FTP_PERM(p, permissions, S_IWGRP, 4, 'w');		FTP_PERM(p, permissions, S_IXGRP, 5, 'x');		FTP_PERM(p, permissions, S_ISGID, 5, (p & S_IXGRP ? 's' : 'S'));		FTP_PERM(p, permissions, S_IROTH, 6, 'r');		FTP_PERM(p, permissions, S_IWOTH, 7, 'w');		FTP_PERM(p, permissions, S_IXOTH, 8, 'x');		FTP_PERM(p, permissions, S_ISVTX, 8, (p & 0001 ? 't' : 'T'));#undef FTP_PERM	}	add_to_string(&string, permissions);	add_char_to_string(&string, ' ');	add_to_string(&string, "   1 ftp      ftp ");	if (ftp_info->size != FTP_SIZE_UNKNOWN) {		add_format_to_string(&string, "%12lu ", ftp_info->size);	} else {		add_to_string(&string, "           - ");	}#ifdef HAVE_STRFTIME	if (ftp_info->mtime > 0) {		time_t current_time = time(NULL);		time_t when = ftp_info->mtime;		struct tm *when_tm;	       	unsigned char *fmt;		unsigned char date[13];		int wr;		if (ftp_info->local_time_zone)			when_tm = localtime(&when);		else			when_tm = gmtime(&when);		if (current_time > when + 6L * 30L * 24L * 60L * 60L		    || current_time < when - 60L * 60L)			fmt = "%b %e  %Y";		else			fmt = "%b %e %H:%M";		wr = strftime(date, sizeof(date), fmt, when_tm);		while (wr < sizeof(date) - 1) date[wr++] = ' ';		date[sizeof(date) - 1] = '\0';		add_to_string(&string, date);	} else#endif	add_to_string(&string, "            ");	add_char_to_string(&string, ' ');	if (ftp_info->type == FTP_FILE_DIRECTORY && colorize_dir) {		add_to_string(&string, "<font color=\"");		add_to_string(&string, dircolor);		add_to_string(&string, "\"><b>");	}	add_to_string(&string, "<a href=\"");	add_html_to_string(&string, ftp_info->name.source, ftp_info->name.length);	if (ftp_info->type == FTP_FILE_DIRECTORY)		add_char_to_string(&string, '/');	add_to_string(&string, "\">");	add_html_to_string(&string, ftp_info->name.source, ftp_info->name.length);	add_to_string(&string, "</a>");	if (ftp_info->type == FTP_FILE_DIRECTORY && colorize_dir) {		add_to_string(&string, "</b></font>");	}	if (ftp_info->symlink.length) {		add_to_string(&string, " -&gt; ");		add_html_to_string(&string, ftp_info->symlink.source,				ftp_info->symlink.length);	}	add_char_to_string(&string, '\n');	if (add_fragment(cached, *pos, string.source, string.length)) *tries = 0;	*pos += string.length;	done_string(&string);	return 0;}/* List a directory in html format. */static intftp_process_dirlist(struct cache_entry *cached, off_t *pos,		    unsigned char *buffer, int buflen, int last,		    int *tries, int colorize_dir, unsigned char *dircolor){	int ret = 0;	while (1) {		struct ftp_file_info ftp_info = INIT_FTP_FILE_INFO;		unsigned char *buf = buffer + ret;		int bufl = buflen - ret;		int bufp;		int newline = 0;		/* Newline quest. */		for (bufp = 0; bufp < bufl; bufp++) {			if (buf[bufp] == ASCII_LF) {				newline = 1;				break;			}		}		if (newline) {			ret += bufp + 1;			if (bufp && buf[bufp - 1] == ASCII_CR) bufp--;		} else {			if (!bufp || (!last && bufl < FTP_BUF_SIZE)) {				return ret;			}			ret += bufp;		}		/* Process line whose end we've already found. */		if (parse_ftp_file_info(&ftp_info, buf, bufp)) {			int retv;			if ((ftp_info.name.length == 1 && ftp_info.name.source[0] == '.')			    || (ftp_info.name.length == 2 && ftp_info.name.source[0] == '.'				&& ftp_info.name.source[1] == '.'))				continue;			retv = display_dir_entry(cached, pos, tries, colorize_dir,						dircolor, &ftp_info);			if (retv < 0) {				return ret;			}		}#ifdef DEBUG_FTP_PARSER		else {			ERROR("Error parsing: [%.*s]", bufp, buf);		}#endif	}}static voidftp_data_accept(struct connection *conn){	struct ftp_connection_info *ftp = conn->info;	int newsock;	set_connection_timeout(conn);	clear_handlers(conn->data_socket->fd);	if ((conn->socket->protocol_family != EL_PF_INET6 && ftp->use_pasv)#ifdef CONFIG_IPV6	    || (conn->socket->protocol_family == EL_PF_INET6 && ftp->use_epsv)#endif	   ) {		newsock = conn->data_socket->fd;	} else {		newsock = accept(conn->data_socket->fd, NULL, NULL);		if (newsock < 0) {			retry_connection(conn, -errno);			return;		}		close(conn->data_socket->fd);	}	conn->data_socket->fd = newsock;	set_handlers(newsock,		     (select_handler_T) got_something_from_data_connection,		     NULL, NULL, conn);}static voidgot_something_from_data_connection(struct connection *conn){	struct ftp_connection_info *ftp = conn->info;	unsigned char dircolor[8];	int colorize_dir = 0;	ssize_t len;	/* XXX: This probably belongs rather to connect.c ? */	set_connection_timeout(conn);	if (!conn->cached) conn->cached = get_cache_entry(conn->uri);	if (!conn->cached) {out_of_mem:		abort_connection(conn, S_OUT_OF_MEM);		return;	}	if (ftp->dir) {		colorize_dir = get_opt_bool("document.browse.links.color_dirs");		if (colorize_dir) {			color_to_string(get_opt_color("document.colors.dirs"),					(unsigned char *) &dircolor);		}	}	if (ftp->dir && !conn->from) {		struct string string;		unsigned char *uristring;		if (!conn->uri->data) {			abort_connection(conn, S_FTP_ERROR);			return;		}		uristring = get_uri_string(conn->uri, URI_PUBLIC);		if (!uristring) goto out_of_mem;		if (!init_string(&string)) {			mem_free(uristring);			goto out_of_mem;		}		add_html_to_string(&string, uristring, strlen(uristring));		mem_free(uristring);#define ADD_CONST(str) { \	add_fragment(conn->cached, conn->from, str, sizeof(str) - 1); \	conn->from += (sizeof(str) - 1); }#define ADD_STRING() { \	add_fragment(conn->cached, conn->from, string.source, string.length); \	conn->from += string.length; }		ADD_CONST("<html>\n<head><title>");		ADD_STRING();		ADD_CONST("</title></head>\n<body>\n<h2>FTP directory ");		ADD_STRING();		ADD_CONST("</h2>\n<pre>");		done_string(&string);		if (conn->uri->datalen) {			struct ftp_file_info ftp_info = INIT_FTP_FILE_INFO_ROOT;			display_dir_entry(conn->cached, &conn->from, &conn->tries,					  colorize_dir, dircolor, &ftp_info);		}		mem_free_set(&conn->cached->content_type, stracpy("text/html"));	}	len = safe_read(conn->data_socket->fd, ftp->ftp_buffer + ftp->buf_pos,		        FTP_BUF_SIZE - ftp->buf_pos);	if (len < 0) {		retry_connection(conn, -errno);		return;	}	if (len > 0) {		conn->received += len;		if (!ftp->dir) {			if (add_fragment(conn->cached, conn->from,					 ftp->ftp_buffer, len) == 1)				conn->tries = 0;			conn->from += len;		} else {			int proceeded;			proceeded = ftp_process_dirlist(conn->cached,							&conn->from,							ftp->ftp_buffer,							len + ftp->buf_pos,							0, &conn->tries,							colorize_dir,							(unsigned char *) dircolor);			if (proceeded == -1) goto out_of_mem;			ftp->buf_pos += len - proceeded;			memmove(ftp->ftp_buffer, ftp->ftp_buffer + proceeded,				ftp->buf_pos);		}		set_connection_state(conn, S_TRANS);		return;	}	if (ftp_process_dirlist(conn->cached, &conn->from,				ftp->ftp_buffer, ftp->buf_pos, 1,				&conn->tries, colorize_dir,				(unsigned char *) dircolor) == -1)		goto out_of_mem;	if (ftp->dir) ADD_CONST("</pre>\n<hr>\n</body>\n</html>");	close_socket(conn->data_socket);	if (ftp->conn_state == 1) {		ftp_end_request(conn, S_OK);	} else {		ftp->conn_state = 2;		set_connection_state(conn, S_TRANS);	}}static voidftp_end_request(struct connection *conn, enum connection_state state){	set_connection_state(conn, state);	if (conn->state == S_OK && conn->cached) {		normalize_cache_entry(conn->cached, conn->from);	}	add_keepalive_connection(conn, FTP_KEEPALIVE_TIMEOUT, NULL);}

⌨️ 快捷键说明

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