diff --git a/src/plugins/auth_sql/CMakeLists.txt b/src/plugins/auth_sql/CMakeLists.txt deleted file mode 100644 index 640b71d..0000000 --- a/src/plugins/auth_sql/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -target_link_libraries(${plugin} - PRIVATE - ${CMAKE_DL_LIBS} -) \ No newline at end of file diff --git a/src/plugins/auth_sql/auth_sql.cpp b/src/plugins/auth_sql/auth_sql.cpp deleted file mode 100644 index a4eb678..0000000 --- a/src/plugins/auth_sql/auth_sql.cpp +++ /dev/null @@ -1,375 +0,0 @@ -#include "plugin.h" -#include "filer.h" -#include -#include -#include -#include -#include -#include - -namespace fs = std::filesystem; - -class LocalFiler : public IPlugin, public Filer { -public: - LocalFiler() {} - - file_data setRoot(std::string _root) { - struct file_data fd; - try { - // Always convert to absolute path - fs::path new_root = fs::absolute(fs::weakly_canonical(_root)); - fd.path = new_root.string().c_str(); - - // Create directory if it doesn't exist - if (!fs::exists(new_root)) { - if (!fs::create_directories(new_root)) { - fd.error = {FilerStatusCodes::NoPermission, "Failed to create root directory"}; - return fd; - } - } - - // Set the absolute root path - root = new_root; - // Reset CWD to root-relative path - cwd = "/"; - - } catch (const fs::filesystem_error& ex) { - logger->print(LOGLEVEL_ERROR, "setRoot error: %s", ex.what()); - fd.error = {FilerStatusCodes::Exception, ex.what()}; - } - - return fd; - } - - file_data setCWD(std::string _cwd) { - struct file_data fd; - try { - // Always convert to absolute path - fs::path new_cwd = fs::weakly_canonical(_cwd); - fd.path = new_cwd.string().c_str(); - - // Create directory if it doesn't exist - if (!fs::exists(root / new_cwd)) { - if (!fs::create_directories(root / new_cwd)) { - fd.error = {FilerStatusCodes::NoPermission, "Failed to create cwd directory"}; - return fd; - } - } - - cwd = new_cwd; - } catch (const fs::filesystem_error& ex) { - logger->print(LOGLEVEL_ERROR, "setCWD error: %s", ex.what()); - fd.error = {FilerStatusCodes::Exception, ex.what()}; - } - - return fd; - } - - fs::path getRoot() { - return this->root; - } - - fs::path getCWD() { - return this->cwd; - } - - fs::path resolvePath(const std::string& path) { - try { - if (path.empty() || path == ".") { - return root / cwd.relative_path(); - } - - fs::path target_path; - if (path[0] == '/') { - // Absolute path relative to FTP root - target_path = root / path.substr(1); - } else { - // Relative to current directory - target_path = root / cwd.relative_path() / path; - } - - // Remove .. and . components - target_path = fs::weakly_canonical(target_path); - - // Make sure we haven't escaped the root - if (!target_path.string().starts_with(root.string())) { - return root / cwd.relative_path(); - } - - return target_path; - } catch (const std::exception& e) { - logger->print(LOGLEVEL_ERROR, "Path resolution error: %s", e.what()); - return root / cwd.relative_path(); - } - } - - file_data traverse(std::string dir) { - struct file_data fd; - try { - // Handle special cases - if (dir.empty() || dir == ".") { - fd.path = resolvePath(".").string().c_str(); - return fd; - } - - fs::path requested_path = resolvePath(dir); - - // Verify the requested path exists and is within root - if (!fs::exists(requested_path)) { - fd.error = file_error{FilerStatusCodes::NotFound, "Directory Not Found"}; - return fd; - } - - if (!fs::is_directory(requested_path)) { - fd.error = file_error{FilerStatusCodes::NotFound, "Not a Directory"}; - return fd; - } - - // Make sure path is within root directory - fs::path rel_path = fs::relative(requested_path, root); - if (rel_path.string().find("..") == 0) { - fd.error = file_error{FilerStatusCodes::NoPermission, "Invalid Permissions"}; - return fd; - } - - // Update current working directory relative to root - cwd = "/" + rel_path.string(); - fd.path = requested_path.string().c_str(); - - } catch (const fs::filesystem_error& ex) { - logger->print(LOGLEVEL_ERROR, "Path fallback: %s", ex.what()); - fd.error = file_error{FilerStatusCodes::Exception, ex.what()}; - } - return fd; - } - - file_data createDirectory(std::string dir) { - struct file_data fd; - try { - fs::path resolved = resolvePath(dir); - fd.path = resolved.string().c_str(); - - if (fs::exists(resolved)) { - fd.error = file_error{FilerStatusCodes::FileExists, "Directory Already Exists"}; - return fd; - } - - fs::create_directory(resolved); - } catch (const std::filesystem::filesystem_error& ex) { - logger->print(LOGLEVEL_ERROR, ex.what()); - fd.error = file_error{FilerStatusCodes::Exception, ex.what()}; - } - return fd; - } - - file_data fileSize(std::string name) { - struct file_data fd; - try { - fs::path resolved = resolvePath(name); - fd.path = resolved.string().c_str(); - - if (!fs::exists(resolved)) { - fd.error = file_error{FilerStatusCodes::NotFound, "File Not Found"}; - return fd; - } - - if (type == 'A') { - fd.error = file_error{FilerStatusCodes::InvalidTransferMode, "Refusing to transfer in ASCII mode"}; - return fd; - } - - std::ifstream infile(resolved, std::ios::in|std::ios::binary|std::ios::ate); - if (infile.is_open()) { - fd.size = infile.tellg(); - } else { - fd.error = file_error{FilerStatusCodes::NoPermission, "Unable to open file"}; - } - } catch (const std::filesystem::filesystem_error& ex) { - logger->print(LOGLEVEL_ERROR, ex.what()); - fd.error = file_error{FilerStatusCodes::Exception, ex.what()}; - } - return fd; - } - - file_data deleteFile(std::string name) { - struct file_data fd; - try { - fs::path resolved = resolvePath(name); - fd.path = resolved.string().c_str(); - - if (!fs::exists(resolved)) { - fd.error = file_error{FilerStatusCodes::NotFound, "File Not Found"}; - return fd; - } - - if (fs::is_directory(resolved) && !fs::is_empty(resolved)) { - fd.error = file_error{FilerStatusCodes::DirectoryNotEmpty, "Directory not empty"}; - return fd; - } - - if (!fs::remove(resolved)) { - fd.error = file_error{FilerStatusCodes::NoPermission, "Unable to delete file"}; - } - } catch (const std::filesystem::filesystem_error& ex) { - logger->print(LOGLEVEL_ERROR, ex.what()); - fd.error = file_error{FilerStatusCodes::Exception, ex.what()}; - } - return fd; - } - - file_data readFile(std::string name) { - struct file_data fd; - try { - fs::path resolved = resolvePath(name); - fd.path = resolved.string().c_str(); - - if (!fs::exists(resolved)) { - fd.error = file_error{FilerStatusCodes::NotFound, "File Not Found"}; - return fd; - } - - if (type != 'A') { - // Create a shared_ptr to manage the ifstream - fd.stream = std::make_shared(resolved, std::ios::in|std::ios::binary); - - if (fd.stream && fd.stream->is_open()) { - // Get file size - fd.stream->seekg(0, std::ios::end); - fd.size = fd.stream->tellg(); - fd.stream->seekg(0, std::ios::beg); - } else { - fd.error = file_error{FilerStatusCodes::NoPermission, "Unable to open file"}; - } - } else { - fd.error = file_error{FilerStatusCodes::InvalidTransferMode, "Refusing to transfer in ASCII mode"}; - } - } catch (const std::filesystem::filesystem_error& ex) { - logger->print(LOGLEVEL_ERROR, ex.what()); - fd.error = file_error{FilerStatusCodes::Exception, ex.what()}; - } - return fd; - } - - file_data writeFile(std::string name, unsigned char* data, int size, bool append = false) { - struct file_data fd; - try { - fs::path resolved = resolvePath(name); - fd.path = resolved.string().c_str(); - - std::ios_base::openmode omode = std::ios::out|std::ios::binary; - if (append) omode |= std::ios::app; - - std::ofstream outfile(resolved, omode); - if (outfile.is_open()) { - outfile.write((char *)data, size); - outfile.close(); - fd.size = size; - } else { - fd.error = file_error{FilerStatusCodes::NoPermission, "Unable to open file"}; - } - } catch (const std::filesystem::filesystem_error& ex) { - logger->print(LOGLEVEL_ERROR, ex.what()); - fd.error = file_error{FilerStatusCodes::Exception, ex.what()}; - } - return fd; - } - - struct file_data renameFile(const std::string& from, const std::string& to) { - struct file_data fd; - std::filesystem::path src_path = resolvePath(from); - std::filesystem::path dst_path = resolvePath(to); - - try { - // Check if destination already exists - if (std::filesystem::exists(dst_path)) { - fd.error = {FilerStatusCodes::FileExists, "Destination file already exists"}; - return fd; - } - - // Perform the rename operation - std::filesystem::rename(src_path, dst_path); - fd.error = {0, "OK"}; - - } catch (const std::filesystem::filesystem_error& e) { - fd.error = {FilerStatusCodes::AccessDenied, e.what()}; - } - - return fd; - } - - file_data list(std::string path = ".") { - struct file_data fd; - try { - fs::path resolved = resolvePath(path); - fd.path = resolved.string().c_str(); - - if (!fs::exists(resolved)) { - fd.error = file_error{FilerStatusCodes::NotFound, "File Not Found"}; - return fd; - } - - std::ostringstream listStream; - for(const auto& p : fs::directory_iterator(resolved, - fs::directory_options::follow_directory_symlink | - fs::directory_options::skip_permission_denied)) { - - struct stat fstat; - struct tm *time; - time_t rawtime; - char timebuff[80]; - - if (stat(p.path().c_str(), &fstat) == -1) { - fd.error = file_error{FilerStatusCodes::NoPermission, "Unable to stat file"}; - break; - } - - /* Convert time_t to tm struct */ - rawtime = fstat.st_mtime; - time = localtime(&rawtime); - strftime(timebuff, 80, "%b %d %H:%M", time); - - // God should've smitten me before I wrote such attrocities. - char* line; - fs::perms fperms = fs::status(p).permissions(); - asprintf( - &line, - "%c%c%c%c%c%c%c%c%c%c %4u %4u %4u %12u %s %s\r\n", - p.is_directory()?'d':'-', - (fperms & fs::perms::owner_read) != fs::perms::none?'r':'-', - (fperms & fs::perms::owner_write) != fs::perms::none?'w':'-', - (fperms & fs::perms::owner_exec) != fs::perms::none?'x':'-', - (fperms & fs::perms::group_read) != fs::perms::none?'r':'-', - (fperms & fs::perms::group_write) != fs::perms::none?'w':'-', - (fperms & fs::perms::group_exec) != fs::perms::none?'x':'-', - (fperms & fs::perms::others_read) != fs::perms::none?'r':'-', - (fperms & fs::perms::others_write) != fs::perms::none?'w':'-', - (fperms & fs::perms::others_exec) != fs::perms::none?'x':'-', - fs::hard_link_count(p), - fstat.st_uid, - fstat.st_gid, - fstat.st_size, - timebuff, - p.path().filename().c_str() - ); - - listStream << std::string(line); - free(line); - } - - fd.size = listStream.tellp(); - fd.bin = new char[fd.size]; - std::strncpy(fd.bin, listStream.str().c_str(), fd.size); - - } catch (const std::filesystem::filesystem_error& ex) { - logger->print(LOGLEVEL_ERROR, ex.what()); - fd.error = file_error{FilerStatusCodes::Exception, ex.what()}; - } - return fd; - } -private: - fs::path root; - fs::path cwd; - char type = 'I'; -}; - -IMPLEMENT_PLUGIN(LocalFiler, Filer, "local", "Local filesystem implementation", "1.0.0") \ No newline at end of file