Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement REST command #46

Merged
merged 1 commit into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/libs/ftpd/ftp_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,10 @@ FRESULT ftps_f_write(FIL *fp, const void *buffer, uint32_t buflen, uint32_t *wri
return res;
}

FRESULT ftps_f_read(FIL *fp, void *buffer, uint32_t len, uint32_t *read)
FRESULT ftps_f_read(FIL *fp, void *buffer, uint32_t len, uint32_t *read, uint32_t position)
{
HANDLE hfile = fp->h;
SetFilePointer(hfile, position, NULL, FILE_BEGIN);
return (ReadFile(hfile, (LPVOID)buffer, len, (LPDWORD)read, NULL)) ? FR_OK : FR_INVALID_PARAMETER;
}

Expand Down
2 changes: 1 addition & 1 deletion src/libs/ftpd/ftp_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ FRESULT ftps_f_open(FIL *fp, const char *path, uint8_t mode);
size_t ftps_f_size(FIL *fp);
FRESULT ftps_f_close(FIL *fp);
FRESULT ftps_f_write(FIL *fp, const void *buffer, uint32_t len, uint32_t *written);
FRESULT ftps_f_read(FIL *fp, void *buffer, uint32_t len, uint32_t *read);
FRESULT ftps_f_read(FIL *fp, void *buffer, uint32_t len, uint32_t *read, uint32_t position);
FRESULT ftps_f_mkdir(const char *path);
FRESULT ftps_f_rename(const char *from, const char *to);
FRESULT ftps_f_utime(const char *path, const FILINFO *fno);
Expand Down
52 changes: 39 additions & 13 deletions src/libs/ftpd/ftp_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ static void ftp_cmd_retr(ftp_data_t *ftp)
return;
}

// does the chosen file exists?
// does the chosen file exist?
if (ftps_f_stat(ftp->path, &ftp->finfo) != FR_OK)
{
// go up a level again
Expand Down Expand Up @@ -899,23 +899,33 @@ static void ftp_cmd_retr(ftp_data_t *ftp)
// go up a level again
path_up_a_level(ftp->path);

// send error to client
ftp_send(ftp, "425 Can't create connection\r\n");

// close file
ftps_f_close(&ftp->file);

// send error to client
ftp_send(ftp, "425 Can't create connection\r\n");

// go back
return;
}

// feedback
FTP_CONN_DEBUG(ftp, "Sending %s\r\n", ftp->parameters);

// grab the optional start position and reset it for next time
uint32_t restart_position = ftp->file_restart_pos;
if (restart_position > ftp->finfo.fsize)
{
ftp_send(ftp, "530 Invalid restart position\r\n");
goto done;
}
ftp->file_restart_pos = 0;

// send accept to client
ftp_send(ftp, "150 Connected to port %u, %lu bytes to download\r\n", ftp->data_port, ftps_f_size(&ftp->file));
ftp_send(ftp, "150 Connected to port %u, %lu bytes to download\r\n", ftp->data_port, ftp->finfo.fsize - restart_position);

// variables used in loop
uint32_t total_bytes_read = 0;
uint32_t bytes_transferred = 0;
uint32_t bytes_read;

Expand All @@ -924,15 +934,17 @@ static void ftp_cmd_retr(ftp_data_t *ftp)
{
// read from file ok?
bytes_read = 0;
if (ftps_f_read(&ftp->file, ftp->file.cache_buf[0], FILE_CACHE_SIZE, &bytes_read) != FR_OK)
if (ftps_f_read(&ftp->file, ftp->file.cache_buf[0], FILE_CACHE_SIZE, &bytes_read, restart_position + total_bytes_read) != FR_OK)
{
ftp_send(ftp, "451 Communication error during transfer\r\n");
ftp_send(ftp, "550 File read failure\r\n");
break;
}
total_bytes_read += bytes_read;

//Done with file
// done with file
if(bytes_read == 0)
{
ftp_send(ftp, "226 File successfully transferred\r\n");
break;
}

Expand All @@ -945,12 +957,14 @@ static void ftp_cmd_retr(ftp_data_t *ftp)
err_t con_err = netconn_write(ftp->dataconn, &ftp->file.cache_buf[0][bytes_transferred], xfer_len, NETCONN_COPY);
if (con_err != ERR_OK)
{
ftp_send(ftp, "426 Error during file transfer: %d\r\n", con_err);
break;
ftp_send(ftp, "426 LWIP network error code %d, transfer aborted\r\n", con_err);
goto done;
}
bytes_transferred += xfer_len;
}
}
done:

// feedback
FTP_CONN_DEBUG(ftp, "Sent %u bytes\r\n", bytes_transferred);

Expand All @@ -962,9 +976,6 @@ static void ftp_cmd_retr(ftp_data_t *ftp)

// close data socket
data_con_close(ftp);

// stop transfer
ftp_send(ftp, "226 File successfully transferred\r\n");
}

static void ftp_cmd_stor(ftp_data_t *ftp)
Expand Down Expand Up @@ -1470,6 +1481,18 @@ static void ftp_cmd_pass(ftp_data_t *ftp)
}
}

static void ftp_cmd_rest(ftp_data_t *ftp)
{
// are we not yet logged in?
if (!FTP_IS_LOGGED_IN(ftp))
return;

// sets the restart file position
uint32_t pos = strtoul(ftp->parameters, NULL, 0);
ftp->file_restart_pos = pos;
ftp_send(ftp, "350 Restarting at %d\r\n", pos);
}

static ftp_cmd_t ftpd_commands[] = {
//
{"PWD", ftp_cmd_pwd}, //
Expand Down Expand Up @@ -1500,6 +1523,7 @@ static ftp_cmd_t ftpd_commands[] = {
{"AUTH", ftp_cmd_auth}, //
{"USER", ftp_cmd_user}, //
{"PASS", ftp_cmd_pass}, //
{"REST", ftp_cmd_rest}, //
{NULL, NULL} //
};

Expand Down Expand Up @@ -1529,6 +1553,8 @@ static uint8_t ftp_process_command(ftp_data_t *ftp)
cmd++;
}

// TODO: only allow RETR to follow a REST

// did we find a command?
if (cmd->cmd != NULL && cmd->func != NULL)
cmd->func(ftp);
Expand Down
3 changes: 3 additions & 0 deletions src/libs/ftpd/ftp_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ typedef struct {

// data connection mode state
dcm_type data_conn_mode;

// file restart position
uint32_t file_restart_pos;
} ftp_data_t;

// structure for ftp commands
Expand Down