mirror of
https://github.com/mtheall/ftpd.git
synced 2024-11-23 01:29:51 +00:00
Skip failed entries in dir listing
This commit is contained in:
parent
6f5ccc3793
commit
55ea4f6201
@ -99,7 +99,7 @@ if(NINTENDO_SWITCH)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(FindPkgConfig)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(CURL libcurl IMPORTED_TARGET)
|
||||
pkg_check_modules(ZSTD libzstd IMPORTED_TARGET)
|
||||
|
||||
@ -207,7 +207,7 @@ elseif(NINTENDO_3DS)
|
||||
ANTI_ALIAS=1
|
||||
)
|
||||
|
||||
include(FindPkgConfig)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(CURL libcurl IMPORTED_TARGET)
|
||||
|
||||
target_link_libraries(${FTPD_TARGET} PRIVATE
|
||||
|
@ -1192,25 +1192,19 @@ 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
|
||||
auto const path = buildResolvedPath (m_cwd, args_);
|
||||
if (path.empty ())
|
||||
{
|
||||
// work around broken clients that think LIST -a/-l is valid
|
||||
if (workaround_)
|
||||
if (needWorkaround)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
xferDir (args_ + 2 + (args_[2] == ' '), mode_, false);
|
||||
return;
|
||||
}
|
||||
|
||||
sendResponse ("550 %s\r\n", std::strerror (errno));
|
||||
@ -1221,6 +1215,12 @@ void FtpSession::xferDir (char const *const args_, XferDirMode const mode_, bool
|
||||
struct stat st;
|
||||
if (::stat (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;
|
||||
@ -1616,7 +1616,7 @@ void FtpSession::sendResponse (std::string_view const response_)
|
||||
bool FtpSession::listTransfer ()
|
||||
{
|
||||
// check if we sent all available data
|
||||
if (m_xferBuffer.empty ())
|
||||
while (m_xferBuffer.empty ())
|
||||
{
|
||||
m_xferBuffer.clear ();
|
||||
|
||||
@ -1646,7 +1646,7 @@ bool FtpSession::listTransfer ()
|
||||
|
||||
// I think we are supposed to return entries for . and ..
|
||||
if (std::strcmp (dent->d_name, ".") == 0 || std::strcmp (dent->d_name, "..") == 0)
|
||||
return true;
|
||||
continue; // just skip it
|
||||
|
||||
// check if this was NLST
|
||||
if (m_xferDirMode == XferDirMode::NLST)
|
||||
@ -1717,51 +1717,18 @@ bool FtpSession::listTransfer ()
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// lstat the entry
|
||||
if (::lstat (fullPath.c_str (), &st) != 0)
|
||||
{
|
||||
#ifndef __SWITCH__
|
||||
sendResponse ("550 %s\r\n", std::strerror (errno));
|
||||
setState (State::COMMAND, true, true);
|
||||
return false;
|
||||
#else
|
||||
// probably archive bit set; list name with dummy stats
|
||||
std::memset (&st, 0, sizeof (st));
|
||||
error ("%s: type %u\n", dent->d_name, dent->d_type);
|
||||
switch (dent->d_type)
|
||||
{
|
||||
case DT_BLK:
|
||||
st.st_mode = S_IFBLK;
|
||||
break;
|
||||
|
||||
case DT_CHR:
|
||||
st.st_mode = S_IFCHR;
|
||||
break;
|
||||
|
||||
case DT_DIR:
|
||||
st.st_mode = S_IFDIR;
|
||||
break;
|
||||
|
||||
case DT_FIFO:
|
||||
st.st_mode = S_IFIFO;
|
||||
break;
|
||||
|
||||
case DT_LNK:
|
||||
st.st_mode = S_IFLNK;
|
||||
break;
|
||||
|
||||
case DT_REG:
|
||||
case DT_UNKNOWN:
|
||||
st.st_mode = S_IFREG;
|
||||
break;
|
||||
|
||||
case DT_SOCK:
|
||||
st.st_mode = S_IFSOCK;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
// lstat the entry
|
||||
if (::lstat (fullPath.c_str (), &st) != 0)
|
||||
{
|
||||
error ("Skipping %s: %s\n", fullPath.c_str (), std::strerror (errno));
|
||||
std::fprintf (stderr, "Skipping %s: %s\n", fullPath.c_str (), std::strerror (errno));
|
||||
continue; // just skip it
|
||||
}
|
||||
#ifdef __3DS__
|
||||
}
|
||||
#endif
|
||||
|
||||
auto const path = encodePath (dent->d_name);
|
||||
auto const rc = fillDirent (st, path);
|
||||
|
Loading…
Reference in New Issue
Block a user