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. */
|
* number otherwise. */
|
||||||
static int
|
static int
|
||||||
get_ftp_response(struct connection *conn, struct read_buffer *rb, int part,
|
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 *eol;
|
||||||
unsigned char *num_end;
|
unsigned char *num_end;
|
||||||
@ -259,6 +259,14 @@ ok:
|
|||||||
pos = i;
|
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)
|
if (part != 2)
|
||||||
kill_buffer_data(rb, pos + 1);
|
kill_buffer_data(rb, pos + 1);
|
||||||
|
|
||||||
@ -365,7 +373,7 @@ static void
|
|||||||
ftp_got_info(struct socket *socket, struct read_buffer *rb)
|
ftp_got_info(struct socket *socket, struct read_buffer *rb)
|
||||||
{
|
{
|
||||||
struct connection *conn = socket->conn;
|
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) {
|
if (response == -1) {
|
||||||
abort_connection(conn, connection_state(S_FTP_ERROR));
|
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)
|
ftp_got_user_info(struct socket *socket, struct read_buffer *rb)
|
||||||
{
|
{
|
||||||
struct connection *conn = socket->conn;
|
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) {
|
if (response == -1) {
|
||||||
abort_connection(conn, connection_state(S_FTP_ERROR));
|
abort_connection(conn, connection_state(S_FTP_ERROR));
|
||||||
@ -483,7 +491,7 @@ static void
|
|||||||
ftp_pass_info(struct socket *socket, struct read_buffer *rb)
|
ftp_pass_info(struct socket *socket, struct read_buffer *rb)
|
||||||
{
|
{
|
||||||
struct connection *conn = socket->conn;
|
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) {
|
if (response == -1) {
|
||||||
abort_connection(conn, connection_state(S_FTP_ERROR));
|
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. */
|
/* Commands to get a file. */
|
||||||
|
|
||||||
ftp->dir = 0;
|
ftp->dir = 0;
|
||||||
ftp->pending_commands = 3;
|
ftp->pending_commands = 4;
|
||||||
|
|
||||||
if (!add_to_string(&command, "TYPE I") /* BINARY */
|
if (!add_to_string(&command, "TYPE I") /* BINARY */
|
||||||
|| !add_crlf_to_string(&command)
|
|| !add_crlf_to_string(&command)
|
||||||
@ -782,6 +790,13 @@ add_file_cmd_to_str(struct connection *conn)
|
|||||||
ftp->pending_commands++;
|
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 ")
|
if (!add_to_string(&command, "RETR ")
|
||||||
|| !add_string_to_string(&command, &pathname)
|
|| !add_string_to_string(&command, &pathname)
|
||||||
|| !add_crlf_to_string(&command)) {
|
|| !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 connection *conn = socket->conn;
|
||||||
struct ftp_connection_info *ftp = conn->info;
|
struct ftp_connection_info *ftp = conn->info;
|
||||||
int response;
|
int response;
|
||||||
|
off_t size = -1;
|
||||||
|
|
||||||
if (ftp->pending_commands > 1) {
|
if (ftp->pending_commands > 1) {
|
||||||
struct sockaddr_storage sa;
|
struct sockaddr_storage sa;
|
||||||
|
|
||||||
response = get_ftp_response(conn, rb, 0, &sa);
|
response = get_ftp_response(conn, rb, 0, &sa, &size);
|
||||||
|
|
||||||
if (response == -1) {
|
if (response == -1) {
|
||||||
abort_connection(conn, connection_state(S_FTP_ERROR));
|
abort_connection(conn, connection_state(S_FTP_ERROR));
|
||||||
@ -1000,7 +1016,10 @@ ftp_retr_file(struct socket *socket, struct read_buffer *rb)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: /* REST / CWD */
|
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) {
|
if (ftp->dir) {
|
||||||
abort_connection(conn,
|
abort_connection(conn,
|
||||||
connection_state(S_FTP_NO_FILE));
|
connection_state(S_FTP_NO_FILE));
|
||||||
@ -1031,7 +1050,7 @@ ftp_retr_file(struct socket *socket, struct read_buffer *rb)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
response = get_ftp_response(conn, rb, 2, NULL);
|
response = get_ftp_response(conn, rb, 2, NULL, NULL);
|
||||||
|
|
||||||
if (response == -1) {
|
if (response == -1) {
|
||||||
abort_connection(conn, connection_state(S_FTP_ERROR));
|
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 connection *conn = socket->conn;
|
||||||
struct ftp_connection_info *ftp = conn->info;
|
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) {
|
if (response == -1) {
|
||||||
abort_connection(conn, connection_state(S_FTP_ERROR));
|
abort_connection(conn, connection_state(S_FTP_ERROR));
|
||||||
|
Loading…
Reference in New Issue
Block a user