/* $Id$ */ /* Copyright (C) 2003 by David White Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. See the COPYING file for more details. */ //include files for opendir(3), readdir(3), etc. These files may vary //from platform to platform, since these functions are NOT ANSI-conforming //functions. They may have to be altered to port to new platforms #include #include //for mkdir #include #include #ifdef _WIN32 #include #include #define mkdir(a,b) (_mkdir(a)) #define mode_t int #endif //for getenv #include #include #include #include "filesystem.hpp" namespace { const mode_t AccessMode = 00770; } #ifdef _WIN32 #define DIR_INVALID(d) (d == -1) #else #define DIR_INVALID(d) (d == NULL) #endif void get_files_in_dir(const std::string& directory, std::vector* files, std::vector* dirs, FILE_NAME_MODE mode) { //if we have a path to find directories in, then convert relative //pathnames to be rooted on the wesnoth path #ifdef WESNOTH_PATH if(!directory.empty() && directory[0] != '/' && WESNOTH_PATH[0] == '/') { const std::string& dir = WESNOTH_PATH + std::string("/") + directory; if(is_directory(dir)) { get_files_in_dir(dir,files,dirs,mode); return; } } #endif #ifdef _WIN32 _finddata_t fileinfo; long dir = _findfirst((directory + "/*.*").c_str(),&fileinfo); #else DIR* dir = opendir(directory.c_str()); #endif if(DIR_INVALID(dir)) { //try to make the directory const int res = mkdir(directory.c_str(),AccessMode); if(res == 0) { #ifdef _WIN32 dir = _findfirst((directory + "/*.*").c_str(),&fileinfo); #else dir = opendir(directory.c_str()); #endif } if(DIR_INVALID(dir)) return; } #ifdef _WIN32 int res = dir; do { if(fileinfo.name[0] != '.') { const std::string path = (mode == ENTIRE_FILE_PATH ? directory + "/" : std::string("")) + fileinfo.name; if(fileinfo.attrib&_A_SUBDIR) { if(dirs != NULL) dirs->push_back(path); } else { if(files != NULL) files->push_back(path); } } res = _findnext(dir,&fileinfo); } while(!DIR_INVALID(res)); _findclose(dir); #else struct dirent* entry; while((entry = readdir(dir)) != NULL) { if(entry->d_name[0] == '.') continue; const std::string name((directory + "/") + entry->d_name); //try to open it as a directory to test if it is a directory DIR* const temp_dir = opendir(name.c_str()); if(temp_dir != NULL) { closedir(temp_dir); if(dirs != NULL) { if(mode == ENTIRE_FILE_PATH) dirs->push_back(name); else dirs->push_back(entry->d_name); } } else if(files != NULL) { if(mode == ENTIRE_FILE_PATH) files->push_back(name); else files->push_back(entry->d_name); } } closedir(dir); #endif if(files != NULL) std::sort(files->begin(),files->end()); if(dirs != NULL) std::sort(dirs->begin(),dirs->end()); } std::string get_prefs_file() { return get_user_data_dir() + "/preferences"; } std::string get_saves_dir() { const std::string dir_path = get_user_data_dir() + "/saves"; #ifdef _WIN32 _mkdir(dir_path.c_str()); #else DIR* dir = opendir(dir_path.c_str()); if(dir == NULL) { const int res = mkdir(dir_path.c_str(),AccessMode); if(res == 0) { dir = opendir(dir_path.c_str()); } else { std::cerr << "Could not open or create directory: '" << dir_path << "'\n"; } } if(dir == NULL) return ""; #endif return dir_path; } std::string get_user_data_dir() { static const char* const current_dir = "."; #ifdef _WIN32 _mkdir("userdata"); return "userdata"; #else const char* home_str = getenv("HOME"); if(home_str == NULL) home_str = current_dir; const std::string home(home_str); const std::string dir_path = home + "/.wesnoth"; DIR* dir = opendir(dir_path.c_str()); if(dir == NULL) { const int res = mkdir(dir_path.c_str(),AccessMode); if(res == 0) { dir = opendir(dir_path.c_str()); } else { std::cerr << "Could not open or create directory: '" << dir_path << "'\n"; } } if(dir == NULL) return ""; closedir(dir); return dir_path; #endif } bool is_directory(const std::string& fname) { #ifdef WESNOTH_PATH if(!fname.empty() && fname[0] != '/' && WESNOTH_PATH[0] == '/') { if(is_directory(WESNOTH_PATH + std::string("/") + fname)) return true; } #endif #ifdef _WIN32 _finddata_t info; const long handle = _findfirst((fname + "/*").c_str(),&info); if(handle >= 0) { _findclose(handle); return true; } else { return false; } #else DIR* const dir = opendir(fname.c_str()); if(dir != NULL) { closedir(dir); return true; } else { return false; } #endif }