mirror of
https://github.com/wiiu-env/ftpiiu_plugin.git
synced 2024-11-16 17:59:19 +01:00
Add NLST command
This commit is contained in:
parent
60bab0735e
commit
3da67ce57a
@ -34,6 +34,7 @@ Supported Commands
|
|||||||
- LIST
|
- LIST
|
||||||
- MKD
|
- MKD
|
||||||
- MODE (no-op)
|
- MODE (no-op)
|
||||||
|
- NLST
|
||||||
- NOOP
|
- NOOP
|
||||||
- PASS (no-op)
|
- PASS (no-op)
|
||||||
- PASV
|
- PASV
|
||||||
@ -58,6 +59,5 @@ Planned Commands
|
|||||||
----------------
|
----------------
|
||||||
|
|
||||||
- ALLO
|
- ALLO
|
||||||
- NLST
|
|
||||||
- REST
|
- REST
|
||||||
- STOU
|
- STOU
|
||||||
|
158
source/ftp.c
158
source/ftp.c
@ -19,6 +19,7 @@
|
|||||||
#include <3ds.h>
|
#include <3ds.h>
|
||||||
#define lstat stat
|
#define lstat stat
|
||||||
#else
|
#else
|
||||||
|
#include <stdbool.h>
|
||||||
#define BIT(x) (1<<(x))
|
#define BIT(x) (1<<(x))
|
||||||
#endif
|
#endif
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
@ -94,6 +95,7 @@ typedef enum
|
|||||||
SESSION_RECV = BIT(3), /*!< data transfer in source mode */
|
SESSION_RECV = BIT(3), /*!< data transfer in source mode */
|
||||||
SESSION_SEND = BIT(4), /*!< data transfer in sink mode */
|
SESSION_SEND = BIT(4), /*!< data transfer in sink mode */
|
||||||
SESSION_RENAME = BIT(5), /*!< last command was RNFR and buffer contains path */
|
SESSION_RENAME = BIT(5), /*!< last command was RNFR and buffer contains path */
|
||||||
|
SESSION_NLST = BIT(6), /*!< list command is NLST */
|
||||||
} session_flags_t;
|
} session_flags_t;
|
||||||
|
|
||||||
/*! ftp session */
|
/*! ftp session */
|
||||||
@ -1389,22 +1391,30 @@ list_transfer(ftp_session_t *session)
|
|||||||
else
|
else
|
||||||
snprintf(session->buffer, sizeof(session->buffer),
|
snprintf(session->buffer, sizeof(session->buffer),
|
||||||
"%s/%s", session->cwd, dent->d_name);
|
"%s/%s", session->cwd, dent->d_name);
|
||||||
rc = lstat(session->buffer, &st);
|
if(session->flags & SESSION_NLST)
|
||||||
if(rc != 0)
|
|
||||||
{
|
{
|
||||||
console_print(RED "stat '%s': %d %s\n" RESET, session->buffer, errno, strerror(errno));
|
session->buffersize =
|
||||||
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
|
sprintf(session->buffer, "%s\r\n", dent->d_name);
|
||||||
ftp_send_response(session, 550, "unavailable\r\n");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = lstat(session->buffer, &st);
|
||||||
|
if(rc != 0)
|
||||||
|
{
|
||||||
|
console_print(RED "stat '%s': %d %s\n" RESET, session->buffer, errno, strerror(errno));
|
||||||
|
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
|
||||||
|
ftp_send_response(session, 550, "unavailable\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
session->buffersize =
|
session->buffersize =
|
||||||
sprintf(session->buffer,
|
sprintf(session->buffer,
|
||||||
"%crwxrwxrwx 1 3DS 3DS %llu Jan 1 1970 %s\r\n",
|
"%crwxrwxrwx 1 3DS 3DS %llu Jan 1 1970 %s\r\n",
|
||||||
S_ISDIR(st.st_mode) ? 'd' :
|
S_ISDIR(st.st_mode) ? 'd' :
|
||||||
S_ISLNK(st.st_mode) ? 'l' : '-',
|
S_ISLNK(st.st_mode) ? 'l' : '-',
|
||||||
(unsigned long long)st.st_size,
|
(unsigned long long)st.st_size,
|
||||||
dent->d_name);
|
dent->d_name);
|
||||||
|
}
|
||||||
session->bufferpos = 0;
|
session->bufferpos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1611,6 +1621,80 @@ ftp_xfer_file(ftp_session_t *session,
|
|||||||
return ftp_send_response(session, 503, "Bad sequence of commands\r\n");
|
return ftp_send_response(session, 503, "Bad sequence of commands\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! ftp_xfer_dir mode */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
XFER_DIR_LIST, /*!< Long list */
|
||||||
|
XFER_DIR_NLST, /*!< Short list */
|
||||||
|
} xfer_dir_mode_t;
|
||||||
|
|
||||||
|
/*! Transfer a directory
|
||||||
|
*
|
||||||
|
* @param[in] session ftp session
|
||||||
|
* @param[in] args ftp arguments
|
||||||
|
* @param[in] mode transfer mode
|
||||||
|
*
|
||||||
|
* @returns failure
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
ftp_xfer_dir(ftp_session_t *session,
|
||||||
|
const char *args,
|
||||||
|
xfer_dir_mode_t mode)
|
||||||
|
{
|
||||||
|
ssize_t rc;
|
||||||
|
|
||||||
|
if(ftp_session_open_cwd(session) != 0)
|
||||||
|
{
|
||||||
|
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
|
||||||
|
return ftp_send_response(session, 550, "unavailable\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(session->flags & SESSION_PORT)
|
||||||
|
{
|
||||||
|
ftp_session_set_state(session, DATA_TRANSFER_STATE, CLOSE_PASV);
|
||||||
|
rc = ftp_session_connect(session);
|
||||||
|
if(rc != 0)
|
||||||
|
{
|
||||||
|
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
|
||||||
|
return ftp_send_response(session, 425, "can't open data connection\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
session->flags &= ~(SESSION_RECV|SESSION_SEND);
|
||||||
|
session->flags |= SESSION_SEND;
|
||||||
|
|
||||||
|
if(mode == XFER_DIR_LIST)
|
||||||
|
session->flags &= ~SESSION_NLST;
|
||||||
|
else
|
||||||
|
session->flags |= SESSION_NLST;
|
||||||
|
|
||||||
|
session->transfer = list_transfer;
|
||||||
|
session->bufferpos = 0;
|
||||||
|
session->buffersize = 0;
|
||||||
|
|
||||||
|
return ftp_send_response(session, 150, "Ready\r\n");
|
||||||
|
}
|
||||||
|
else if(session->flags & SESSION_PASV)
|
||||||
|
{
|
||||||
|
session->flags &= ~(SESSION_RECV|SESSION_SEND);
|
||||||
|
session->flags |= SESSION_SEND;
|
||||||
|
|
||||||
|
if(mode == XFER_DIR_LIST)
|
||||||
|
session->flags &= ~SESSION_NLST;
|
||||||
|
else
|
||||||
|
session->flags |= SESSION_NLST;
|
||||||
|
|
||||||
|
session->transfer = list_transfer;
|
||||||
|
session->bufferpos = 0;
|
||||||
|
session->buffersize = 0;
|
||||||
|
|
||||||
|
ftp_session_set_state(session, DATA_CONNECT_STATE, CLOSE_DATA);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
|
||||||
|
return ftp_send_response(session, 503, "Bad sequence of commands\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
* *
|
* *
|
||||||
* F T P C O M M A N D S *
|
* F T P C O M M A N D S *
|
||||||
@ -1711,50 +1795,9 @@ FTP_DECLARE(FEAT)
|
|||||||
|
|
||||||
FTP_DECLARE(LIST)
|
FTP_DECLARE(LIST)
|
||||||
{
|
{
|
||||||
ssize_t rc;
|
|
||||||
|
|
||||||
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
||||||
|
|
||||||
if(ftp_session_open_cwd(session) != 0)
|
return ftp_xfer_dir(session, args, XFER_DIR_LIST);
|
||||||
{
|
|
||||||
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
|
|
||||||
return ftp_send_response(session, 550, "unavailable\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(session->flags & SESSION_PORT)
|
|
||||||
{
|
|
||||||
ftp_session_set_state(session, DATA_TRANSFER_STATE, CLOSE_PASV);
|
|
||||||
rc = ftp_session_connect(session);
|
|
||||||
if(rc != 0)
|
|
||||||
{
|
|
||||||
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
|
|
||||||
return ftp_send_response(session, 425, "can't open data connection\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
session->flags &= ~(SESSION_RECV|SESSION_SEND);
|
|
||||||
session->flags |= SESSION_SEND;
|
|
||||||
|
|
||||||
session->transfer = list_transfer;
|
|
||||||
session->bufferpos = 0;
|
|
||||||
session->buffersize = 0;
|
|
||||||
|
|
||||||
return ftp_send_response(session, 150, "Ready\r\n");
|
|
||||||
}
|
|
||||||
else if(session->flags & SESSION_PASV)
|
|
||||||
{
|
|
||||||
session->flags &= ~(SESSION_RECV|SESSION_SEND);
|
|
||||||
session->flags |= SESSION_SEND;
|
|
||||||
|
|
||||||
session->transfer = list_transfer;
|
|
||||||
session->bufferpos = 0;
|
|
||||||
session->buffersize = 0;
|
|
||||||
|
|
||||||
ftp_session_set_state(session, DATA_CONNECT_STATE, CLOSE_DATA);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
|
|
||||||
return ftp_send_response(session, 503, "Bad sequence of commands\r\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FTP_DECLARE(MKD)
|
FTP_DECLARE(MKD)
|
||||||
@ -1792,12 +1835,9 @@ FTP_DECLARE(MODE)
|
|||||||
|
|
||||||
FTP_DECLARE(NLST)
|
FTP_DECLARE(NLST)
|
||||||
{
|
{
|
||||||
/* TODO */
|
|
||||||
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
console_print(CYAN "%s %s\n" RESET, __func__, args ? args : "");
|
||||||
|
|
||||||
ftp_session_set_state(session, COMMAND_STATE, CLOSE_PASV | CLOSE_DATA);
|
return ftp_xfer_dir(session, args, XFER_DIR_NLST);
|
||||||
|
|
||||||
return ftp_send_response(session, 504, "unavailable\r\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FTP_DECLARE(NOOP)
|
FTP_DECLARE(NOOP)
|
||||||
|
Loading…
Reference in New Issue
Block a user