1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

ftp: Get filesize from SIZE command instead of guess it from RETR command.

This commit is contained in:
witekfl 2011-03-22 17:51:13 +01:00
parent dfc666dd75
commit 9cb170f97f

View File

@ -190,7 +190,7 @@ parse_psv_resp(unsigned char *data, int *n, int max_value)
* number otherwise. */
static int
get_ftp_response(struct connection *conn, struct read_buffer *rb, int part,
struct sockaddr_storage *sa)
struct sockaddr_storage *sa, off_t *est_length)
{
unsigned char *eol;
unsigned char *num_end;
@ -259,6 +259,14 @@ ok:
pos = i;
}
if (response == 213 && est_length) {
off_t size = strtoull(num_end + 1, NULL, 10);
if (errno) {
return -1;
}
*est_length = size;
}
if (part != 2)
kill_buffer_data(rb, pos + 1);
@ -365,7 +373,7 @@ static void
ftp_got_info(struct socket *socket, struct read_buffer *rb)
{
struct connection *conn = socket->conn;
int response = get_ftp_response(conn, rb, 0, NULL);
int response = get_ftp_response(conn, rb, 0, NULL, NULL);
if (response == -1) {
abort_connection(conn, connection_state(S_FTP_ERROR));
@ -397,7 +405,7 @@ static void
ftp_got_user_info(struct socket *socket, struct read_buffer *rb)
{
struct connection *conn = socket->conn;
int response = get_ftp_response(conn, rb, 0, NULL);
int response = get_ftp_response(conn, rb, 0, NULL, NULL);
if (response == -1) {
abort_connection(conn, connection_state(S_FTP_ERROR));
@ -483,7 +491,7 @@ static void
ftp_pass_info(struct socket *socket, struct read_buffer *rb)
{
struct connection *conn = socket->conn;
int response = get_ftp_response(conn, rb, 0, NULL);
int response = get_ftp_response(conn, rb, 0, NULL, NULL);
if (response == -1) {
abort_connection(conn, connection_state(S_FTP_ERROR));
@ -756,7 +764,7 @@ add_file_cmd_to_str(struct connection *conn)
/* Commands to get a file. */
ftp->dir = 0;
ftp->pending_commands = 3;
ftp->pending_commands = 4;
if (!add_to_string(&command, "TYPE I") /* BINARY */
|| !add_crlf_to_string(&command)
@ -782,6 +790,13 @@ add_file_cmd_to_str(struct connection *conn)
ftp->pending_commands++;
}
if (!add_to_string(&command, "SIZE ")
|| !add_string_to_string(&command, &pathname)
|| !add_crlf_to_string(&command)) {
abort_connection(conn, connection_state(S_OUT_OF_MEM));
goto ret;
}
if (!add_to_string(&command, "RETR ")
|| !add_string_to_string(&command, &pathname)
|| !add_crlf_to_string(&command)) {
@ -954,11 +969,12 @@ ftp_retr_file(struct socket *socket, struct read_buffer *rb)
struct connection *conn = socket->conn;
struct ftp_connection_info *ftp = conn->info;
int response;
off_t size = -1;
if (ftp->pending_commands > 1) {
struct sockaddr_storage sa;
response = get_ftp_response(conn, rb, 0, &sa);
response = get_ftp_response(conn, rb, 0, &sa, &size);
if (response == -1) {
abort_connection(conn, connection_state(S_FTP_ERROR));
@ -1000,7 +1016,10 @@ ftp_retr_file(struct socket *socket, struct read_buffer *rb)
break;
case 3: /* REST / CWD */
if (response >= 400) {
case 4: /* SIZE */
if (response == 213 && size != -1 && conn->est_length == -1) {
conn->est_length = size;
} else if (response >= 400) {
if (ftp->dir) {
abort_connection(conn,
connection_state(S_FTP_NO_FILE));
@ -1031,7 +1050,7 @@ ftp_retr_file(struct socket *socket, struct read_buffer *rb)
return;
}
response = get_ftp_response(conn, rb, 2, NULL);
response = get_ftp_response(conn, rb, 2, NULL, NULL);
if (response == -1) {
abort_connection(conn, connection_state(S_FTP_ERROR));
@ -1090,7 +1109,7 @@ ftp_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);
int response = get_ftp_response(conn, rb, 0, NULL, NULL);
if (response == -1) {
abort_connection(conn, connection_state(S_FTP_ERROR));