3 // SuperTux - A Jump'n Run
4 // Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <sys/types.h>
42 using namespace SuperTux;
45 #define mkdir(dir, mode) mkdir(dir)
48 /* Does the given file exist and is it accessible? */
49 bool FileSystem::faccessible(const std::string& filename)
52 if (stat(filename.c_str(), &filestat) == -1)
58 if(S_ISREG(filestat.st_mode))
65 /* Can we write to this location? */
66 bool FileSystem::fwriteable(const std::string& filename)
69 fi = fopen(filename.c_str(), "wa");
78 /* Makes sure a directory is created in either the SuperTux home directory or the SuperTux base directory.*/
79 bool FileSystem::fcreatedir(const std::string& relative_dir)
81 std::string path = user_dir + "/" + relative_dir + "/";
82 if(mkdir(path.c_str(),0755) != 0)
84 path = datadir + "/" + relative_dir + "/";
85 if(mkdir(path.c_str(),0755) != 0)
100 /* Get all names of sub-directories in a certain directory. */
101 /* Returns the number of sub-directories found. */
102 /* Note: The user has to free the allocated space. */
103 std::set<std::string> FileSystem::dsubdirs(const std::string &rel_path,const std::string& expected_file)
106 struct dirent *direntp;
107 std::set<std::string> sdirs;
108 std::string filename;
109 std::string path = user_dir + "/" + rel_path;
111 if((dirStructP = opendir(path.c_str())) != NULL)
113 while((direntp = readdir(dirStructP)) != NULL)
115 std::string absolute_filename;
118 absolute_filename = path + "/" + direntp->d_name;
120 if (stat(absolute_filename.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode))
122 if(!expected_file.empty())
124 filename = path + "/" + direntp->d_name + "/" + expected_file;
125 if(!faccessible(filename))
129 sdirs.insert(direntp->d_name);
132 closedir(dirStructP);
135 path = datadir + "/" + rel_path;
136 if((dirStructP = opendir(path.c_str())) != NULL)
138 while((direntp = readdir(dirStructP)) != NULL)
140 std::string absolute_filename;
143 absolute_filename = path + "/" + direntp->d_name;
145 if (stat(absolute_filename.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode))
147 if(!expected_file.empty())
149 filename = path + "/" + direntp->d_name + "/" + expected_file;
150 if(!faccessible(filename.c_str()))
156 filename = user_dir + "/" + rel_path + "/" + direntp->d_name + "/" + expected_file;
157 if(faccessible(filename.c_str()))
162 sdirs.insert(direntp->d_name);
165 closedir(dirStructP);
171 std::set<std::string> FileSystem::dfiles(const std::string& rel_path, const std::string& glob, const std::string& exception_str)
174 struct dirent *direntp;
175 std::set<std::string> sdirs;
176 std::string path = user_dir + "/" + rel_path;
178 if((dirStructP = opendir(path.c_str())) != NULL)
180 while((direntp = readdir(dirStructP)) != NULL)
182 std::string absolute_filename;
185 absolute_filename = path + "/" + direntp->d_name;
187 if (stat(absolute_filename.c_str(), &buf) == 0 && S_ISREG(buf.st_mode))
189 if(!exception_str.empty())
191 if(strstr(direntp->d_name,exception_str.c_str()) != NULL)
195 if(strstr(direntp->d_name,glob.c_str()) == NULL)
198 sdirs.insert(direntp->d_name);
201 closedir(dirStructP);
204 path = datadir + "/" + rel_path;
205 if((dirStructP = opendir(path.c_str())) != NULL)
207 while((direntp = readdir(dirStructP)) != NULL)
209 std::string absolute_filename;
212 absolute_filename = path + "/" + direntp->d_name;
214 if (stat(absolute_filename.c_str(), &buf) == 0 && S_ISREG(buf.st_mode))
216 if(!exception_str.empty())
218 if(strstr(direntp->d_name,exception_str.c_str()) != NULL)
222 if(strstr(direntp->d_name,glob.c_str()) == NULL)
225 sdirs.insert(direntp->d_name);
228 closedir(dirStructP);
234 std::string FileSystem::dirname(const std::string& filename)
236 std::string::size_type p = filename.find_last_of('/');
237 if(p == std::string::npos)
240 return filename.substr(0, p+1);
243 std::set<std::string> FileSystem::read_directory(const std::string& pathname)
245 std::set<std::string> dirnames;
247 DIR* dir = opendir(pathname.c_str());
250 struct dirent *direntp;
252 while((direntp = readdir(dir)))
254 dirnames.insert(direntp->d_name);