license stuff
[oweals/minetest.git] / src / filesys.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "filesys.h"
21 #include <iostream>
22
23 namespace fs
24 {
25
26 #ifdef _WIN32
27
28 #define _WIN32_WINNT 0x0501
29 #include <Windows.h>
30 #include <stdio.h>
31 #include <malloc.h>
32 #include <tchar.h> 
33 #include <wchar.h> 
34 #include <stdio.h>
35
36 #define BUFSIZE MAX_PATH
37
38 std::vector<DirListNode> GetDirListing(std::string pathstring)
39 {
40         std::vector<DirListNode> listing;
41
42         WIN32_FIND_DATA FindFileData;
43         HANDLE hFind = INVALID_HANDLE_VALUE;
44         DWORD dwError;
45         LPTSTR DirSpec;
46         INT retval;
47
48         DirSpec = (LPTSTR) malloc (BUFSIZE);
49
50         if( DirSpec == NULL )
51         {
52           printf( "Insufficient memory available\n" );
53           retval = 1;
54           goto Cleanup;
55         }
56
57         // Check that the input is not larger than allowed.
58         if (pathstring.size() > (BUFSIZE - 2))
59         {
60           _tprintf(TEXT("Input directory is too large.\n"));
61           retval = 3;
62           goto Cleanup;
63         }
64
65         //_tprintf (TEXT("Target directory is %s.\n"), pathstring.c_str());
66
67         sprintf(DirSpec, "%s", (pathstring + "\\*").c_str());
68
69         // Find the first file in the directory.
70         hFind = FindFirstFile(DirSpec, &FindFileData);
71
72         if (hFind == INVALID_HANDLE_VALUE) 
73         {
74           _tprintf (TEXT("Invalid file handle. Error is %u.\n"), 
75                                 GetLastError());
76           retval = (-1);
77         } 
78         else 
79         {
80                 DirListNode node;
81                 node.name = FindFileData.cFileName;
82                 node.dir = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
83                 listing.push_back(node);
84
85                 // List all the other files in the directory.
86                 while (FindNextFile(hFind, &FindFileData) != 0) 
87                 {
88                         DirListNode node;
89                         node.name = FindFileData.cFileName;
90                         node.dir = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
91                         listing.push_back(node);
92                 }
93
94                 dwError = GetLastError();
95                 FindClose(hFind);
96                 if (dwError != ERROR_NO_MORE_FILES) 
97                 {
98                  _tprintf (TEXT("FindNextFile error. Error is %u.\n"), 
99                                    dwError);
100                 retval = (-1);
101                 goto Cleanup;
102                 }
103         }
104         retval  = 0;
105
106 Cleanup:
107         free(DirSpec);
108
109         if(retval != 0) listing.clear();
110
111         //for(unsigned int i=0; i<listing.size(); i++){
112         //      std::cout<<listing[i].name<<(listing[i].dir?" (dir)":" (file)")<<std::endl;
113         //}
114         
115         return listing;
116 }
117
118 bool CreateDir(std::string path)
119 {
120         bool r = CreateDirectory(path.c_str(), NULL);
121         if(r == true)
122                 return true;
123         if(GetLastError() == ERROR_ALREADY_EXISTS)
124                 return true;
125         return false;
126 }
127
128 bool PathExists(std::string path)
129 {
130         return (GetFileAttributes(path.c_str()) != INVALID_FILE_ATTRIBUTES);
131 }
132
133 #else
134
135 #ifdef linux
136
137 #include <sys/types.h>
138 #include <dirent.h>
139 #include <errno.h>
140 #include <sys/stat.h>
141
142 std::vector<DirListNode> GetDirListing(std::string pathstring)
143 {
144         std::vector<DirListNode> listing;
145
146     DIR *dp;
147     struct dirent *dirp;
148     if((dp  = opendir(pathstring.c_str())) == NULL) {
149                 //std::cout<<"Error("<<errno<<") opening "<<pathstring<<std::endl;
150         return listing;
151     }
152
153     while ((dirp = readdir(dp)) != NULL) {
154                 if(dirp->d_name[0]!='.'){
155                         DirListNode node;
156                         node.name = dirp->d_name;
157                         if(dirp->d_type == DT_DIR) node.dir = true;
158                         else node.dir = false;
159                         listing.push_back(node);
160                 }
161     }
162     closedir(dp);
163
164         return listing;
165 }
166
167 bool CreateDir(std::string path)
168 {
169         int r = mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
170         if(r == 0)
171         {
172                 return true;
173         }
174         else
175         {
176                 // If already exists, return true
177                 if(errno == EEXIST)
178                         return true;
179                 return false;
180         }
181 }
182
183 bool PathExists(std::string path)
184 {
185         struct stat st;
186         return (stat(path.c_str(),&st) == 0);
187 }
188
189 #else
190
191 #include "boost/filesystem/operations.hpp"
192 namespace bfsys = boost::filesystem;
193
194 std::vector<DirListNode> GetDirListing(std::string pathstring)
195 {
196         std::vector<DirListNode> listing;
197
198         bfsys::path path(pathstring);
199
200         if( !exists( path ) ) return listing;
201
202         bfsys::directory_iterator end_itr; // default construction yields past-the-end
203         for( bfsys::directory_iterator itr( path ); itr != end_itr; ++itr ){
204                 DirListNode node;
205                 node.name = itr->leaf();
206                 node.dir = is_directory(*itr);
207                 listing.push_back(node);
208         }
209
210         return listing;
211 }
212
213 bool CreateDir(std::string path)
214 {
215         std::cout<<"CreateDir not implemented in boost"<<std::endl;
216         return false;
217 }
218
219 #endif
220
221 #endif
222
223 }
224