#include "system_utils.h" #include #include #include #include #ifdef _WIN32 #include #include #include // Evitar conflictos con macros de Windows #ifdef ERROR_ALREADY_EXISTS #undef ERROR_ALREADY_EXISTS #endif #else #include #include #endif namespace SystemUtils { // Función auxiliar para crear una carpeta individual Result createSingleFolder(const std::string& path, int permissions) { struct stat st = {0}; // Verificar si ya existe if (stat(path.c_str(), &st) == 0) { return Result::SUCCESS; // Ya existe, no es error por defecto } // Intentar crear la carpeta int result; #ifdef _WIN32 result = _mkdir(path.c_str()); #else result = mkdir(path.c_str(), permissions); #endif if (result == -1) { switch (errno) { case EACCES: return Result::PERMISSION_DENIED; case EEXIST: return Result::ALREADY_EXISTS; case ENAMETOOLONG: return Result::PATH_TOO_LONG; default: return Result::UNKNOWN_ERROR; } } return Result::SUCCESS; } // Función auxiliar para crear carpetas padre recursivamente Result createParentFolders(const std::string& path, int permissions) { size_t pos = 0; while ((pos = path.find('/', pos + 1)) != std::string::npos) { std::string parent = path.substr(0, pos); if (!parent.empty() && !folderExists(parent)) { Result result = createSingleFolder(parent, permissions); if (result != Result::SUCCESS && result != Result::ALREADY_EXISTS) { return result; } } } return Result::SUCCESS; } Result createApplicationFolder(const std::string& app_name, std::string& out_path) { FolderConfig config; return createApplicationFolder(app_name, out_path, config); } Result createApplicationFolder(const std::string& app_name, std::string& out_path, const FolderConfig& config) { out_path = getApplicationDataPath(app_name); return createFolder(out_path, config); } Result createFolder(const std::string& path) { FolderConfig config; return createFolder(path, config); } Result createFolder(const std::string& path, const FolderConfig& config) { if (path.empty()) { return Result::INVALID_PATH; } // Verificar si ya existe y si eso es un error if (folderExists(path) && config.fail_if_exists) { return Result::ALREADY_EXISTS; } // Crear carpetas padre si es necesario if (config.create_parents) { Result parent_result = createParentFolders(path, config.permissions); if (parent_result != Result::SUCCESS) { return parent_result; } } // Crear la carpeta final return createSingleFolder(path, config.permissions); } std::string getApplicationDataPath(const std::string& app_name) { #ifdef _WIN32 char* appdata = getenv("APPDATA"); if (appdata) { return std::string(appdata) + "/" + app_name; } return "C:/Users/Default/AppData/Roaming/" + app_name; #elif __APPLE__ std::string home = getHomeDirectory(); return home + "/Library/Application Support/" + app_name; #elif __linux__ std::string home = getHomeDirectory(); return home + "/.config/" + app_name; #else // Fallback genérico std::string home = getHomeDirectory(); return home + "/." + app_name; #endif } bool folderExists(const std::string& path) { struct stat st = {0}; return (stat(path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)); } const char* resultToString(Result result) { switch (result) { case Result::SUCCESS: return "Operación exitosa"; case Result::PERMISSION_DENIED: return "Error: Permisos insuficientes"; case Result::PATH_TOO_LONG: return "Error: Ruta demasiado larga"; case Result::ALREADY_EXISTS: return "Error: La carpeta ya existe"; case Result::INVALID_PATH: return "Error: Ruta inválida"; case Result::UNKNOWN_ERROR: return "Error desconocido"; default: return "Error no identificado"; } } std::string getHomeDirectory() { #ifdef _WIN32 char* userprofile = getenv("USERPROFILE"); if (userprofile) { return std::string(userprofile); } return "C:/Users/Default"; #else struct passwd *pw = getpwuid(getuid()); if (pw && pw->pw_dir) { return std::string(pw->pw_dir); } // Fallback char* home = getenv("HOME"); if (home) { return std::string(home); } return "/tmp"; #endif } std::string getTempDirectory() { #ifdef _WIN32 char* temp = getenv("TEMP"); if (temp) { return std::string(temp); } return "C:/Windows/Temp"; #else return "/tmp"; #endif } } // namespace SystemUtils