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:
parent
dfc666dd75
commit
9cb170f97f
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user