Fix FTP/550 (ENODEV) for clients using "LIST -a"

The test for additional switches to the LIST command
must be performed before the path is joined. Otherwise,
the path will never be empty and the test will be skipped.
Fixes ENODEV error (FTP/550) on clients using "LIST -a".
This commit is contained in:
Erik Kunze 2024-11-22 15:38:29 +01:00 committed by Maschell
parent 618b2fb136
commit a3bbc1265e

View File

@ -43,9 +43,6 @@
#include <cerrno> #include <cerrno>
#include <chrono> #include <chrono>
#include <cinttypes> #include <cinttypes>
#ifdef __WIIU__
#include <coreinit/filesystem_fsa.h>
#endif
#include <cstdarg> #include <cstdarg>
#include <cstring> #include <cstring>
#include <ctime> #include <ctime>
@ -1432,21 +1429,28 @@ void FtpSession::xferDir (char const *const args_, XferDirMode const mode_, bool
if (std::strlen (args_) > 0) if (std::strlen (args_) > 0)
{ {
// work around broken clients that think LIST -a/-l is valid
auto const needWorkaround = workaround_ && args_[0] == '-' &&
(args_[1] == 'a' || args_[1] == 'l') &&
(args_[2] == '\0' || args_[2] == ' ');
// an argument was provided // an argument was provided
// work around broken clients that think LIST -a/-l is valid
if (workaround_)
{
if (args_[0] == '-' && (args_[1] == 'a' || args_[1] == 'l'))
{
char const *args = &args_[2];
if (*args == '\0' || *args == ' ')
{
if (*args == ' ')
++args;
xferDir (args, mode_, false);
return;
}
}
}
auto const path = buildResolvedPath (m_cwd, args_); auto const path = buildResolvedPath (m_cwd, args_);
if (path.empty ()) if (path.empty ())
{ {
if (needWorkaround)
{
xferDir (args_ + 2 + (args_[2] == ' '), mode_, false);
return;
}
sendResponse ("550 %s\r\n", std::strerror (errno)); sendResponse ("550 %s\r\n", std::strerror (errno));
setState (State::COMMAND, true, true); setState (State::COMMAND, true, true);
return; return;
@ -1455,12 +1459,6 @@ void FtpSession::xferDir (char const *const args_, XferDirMode const mode_, bool
stat_t st; stat_t st;
if (tzStat (path.c_str (), &st) != 0) if (tzStat (path.c_str (), &st) != 0)
{ {
if (needWorkaround)
{
xferDir (args_ + 2 + (args_[2] == ' '), mode_, false);
return;
}
sendResponse ("550 %s\r\n", std::strerror (errno)); sendResponse ("550 %s\r\n", std::strerror (errno));
setState (State::COMMAND, true, true); setState (State::COMMAND, true, true);
return; return;