From 1cad4a2354a849a934fe52bff1a935a2d9594c5c Mon Sep 17 00:00:00 2001 From: Erik Kunze Date: Fri, 22 Nov 2024 15:38:29 +0100 Subject: [PATCH] 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". --- source/ftpSession.cpp | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/source/ftpSession.cpp b/source/ftpSession.cpp index 23fa45a..1935d6a 100644 --- a/source/ftpSession.cpp +++ b/source/ftpSession.cpp @@ -43,9 +43,6 @@ #include #include #include -#ifdef __WIIU__ -#include -#endif #include #include #include @@ -1432,21 +1429,28 @@ void FtpSession::xferDir (char const *const args_, XferDirMode const mode_, bool 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 + + // 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_); if (path.empty ()) { - if (needWorkaround) - { - xferDir (args_ + 2 + (args_[2] == ' '), mode_, false); - return; - } - sendResponse ("550 %s\r\n", std::strerror (errno)); setState (State::COMMAND, true, true); return; @@ -1455,12 +1459,6 @@ void FtpSession::xferDir (char const *const args_, XferDirMode const mode_, bool stat_t st; 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)); setState (State::COMMAND, true, true); return;