1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #if defined(__WII__)
24
25 #define FORBIDDEN_SYMBOL_EXCEPTION_time_h
26 #define FORBIDDEN_SYMBOL_EXCEPTION_unistd_h
27
28 #define FORBIDDEN_SYMBOL_EXCEPTION_mkdir
29
30 #include "backends/fs/wii/wii-fs.h"
31 #include "backends/fs/wii/wii-fs-factory.h"
32 #include "backends/fs/stdiostream.h"
33
34 #include <sys/iosupport.h>
35 #include <sys/dir.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <errno.h>
39 #include <unistd.h>
40
41 #include <gctypes.h>
42
43 // gets all registered devoptab devices
getDevopChildren(AbstractFSList & list,ListMode mode,bool hidden) const44 bool WiiFilesystemNode::getDevopChildren(AbstractFSList &list, ListMode mode, bool hidden) const {
45 u8 i;
46 const devoptab_t* dt;
47
48 if (mode == Common::FSNode::kListFilesOnly)
49 return true;
50
51 // skip in, out and err
52 for (i = 3; i < STD_MAX; ++i) {
53 dt = devoptab_list[i];
54
55 if (!dt || !dt->name || !dt->open_r || !dt->diropen_r)
56 continue;
57
58 list.push_back(new WiiFilesystemNode(Common::String(dt->name) + ":/"));
59 }
60
61 return true;
62 }
63
initRootNode()64 void WiiFilesystemNode::initRootNode() {
65 _path.clear();
66 _displayName = "<devices>";
67
68 _exists = true;
69 _isDirectory = true;
70 _isReadable = false;
71 _isWritable = false;
72 }
73
clearFlags()74 void WiiFilesystemNode::clearFlags() {
75 _exists = false;
76 _isDirectory = false;
77 _isReadable = false;
78 _isWritable = false;
79 }
80
setFlags(const struct stat * st)81 void WiiFilesystemNode::setFlags(const struct stat *st) {
82 _exists = true;
83 _isDirectory = ( (st->st_mode & S_IFDIR) != 0 );
84 _isReadable = ( (st->st_mode & S_IRUSR) != 0 );
85 _isWritable = ( (st->st_mode & S_IWUSR) != 0 );
86 }
87
WiiFilesystemNode()88 WiiFilesystemNode::WiiFilesystemNode() {
89 initRootNode();
90 }
91
WiiFilesystemNode(const Common::String & p)92 WiiFilesystemNode::WiiFilesystemNode(const Common::String &p) {
93 if (p.empty()) {
94 initRootNode();
95 return;
96 }
97
98 _path = Common::normalizePath(p, '/');
99
100 WiiFilesystemFactory::instance().mountByPath(_path);
101
102 // "sd:" is not a valid directory, but "sd:/" is
103 if (_path.lastChar() == ':')
104 _path += '/';
105
106 _displayName = lastPathComponent(_path, '/');
107
108 struct stat st;
109 if(stat(_path.c_str(), &st) != -1)
110 setFlags(&st);
111 else
112 clearFlags();
113 }
114
WiiFilesystemNode(const Common::String & p,const struct stat * st)115 WiiFilesystemNode::WiiFilesystemNode(const Common::String &p, const struct stat *st) {
116 if (p.empty()) {
117 initRootNode();
118 return;
119 }
120
121 _path = Common::normalizePath(p, '/');
122
123 // "sd:" is not a valid directory, but "sd:/" is
124 if (_path.lastChar() == ':')
125 _path += '/';
126
127 _displayName = lastPathComponent(_path, '/');
128
129 setFlags(st);
130 }
131
exists() const132 bool WiiFilesystemNode::exists() const {
133 return _exists;
134 }
135
getChild(const Common::String & n) const136 AbstractFSNode *WiiFilesystemNode::getChild(const Common::String &n) const {
137 assert(_isDirectory);
138
139 assert(!n.contains('/'));
140
141 Common::String newPath(_path);
142 if (newPath.lastChar() != '/')
143 newPath += '/';
144 newPath += n;
145
146 return new WiiFilesystemNode(newPath);
147 }
148
getChildren(AbstractFSList & list,ListMode mode,bool hidden) const149 bool WiiFilesystemNode::getChildren(AbstractFSList &list, ListMode mode, bool hidden) const {
150 assert(_isDirectory);
151
152 if (_path.empty())
153 return getDevopChildren(list, mode, hidden);
154
155 DIR* dp = opendir (_path.c_str());
156 DIR* tmpdir;
157
158 if (dp == NULL)
159 return false;
160
161 struct dirent *pent;
162
163 while ((pent = readdir(dp)) != NULL) {
164 if (strcmp(pent->d_name, ".") == 0 || strcmp(pent->d_name, "..") == 0)
165 continue;
166
167 Common::String newPath(_path);
168 if (newPath.lastChar() != '/')
169 newPath += '/';
170 newPath += pent->d_name;
171
172 bool isDir = false;
173 tmpdir = opendir(newPath.c_str());
174 if(tmpdir)
175 {
176 isDir = true;
177 closedir(tmpdir);
178 }
179
180 if ((mode == Common::FSNode::kListFilesOnly && isDir) ||
181 (mode == Common::FSNode::kListDirectoriesOnly && !isDir))
182 continue;
183
184 struct stat st;
185 st.st_mode = 0;
186 st.st_mode |= ( isDir ? S_IFDIR : 0 );
187 st.st_mode |= S_IRUSR;
188 st.st_mode |= S_IWUSR;
189
190 list.push_back(new WiiFilesystemNode(newPath, &st));
191 }
192
193 closedir(dp);
194
195 return true;
196 }
197
getParent() const198 AbstractFSNode *WiiFilesystemNode::getParent() const {
199 if (_path.empty())
200 return NULL;
201
202 const char *start = _path.c_str();
203 const char *end = lastPathComponent(_path, '/');
204
205 return new WiiFilesystemNode(Common::String(start, end - start));
206 }
207
createReadStream()208 Common::SeekableReadStream *WiiFilesystemNode::createReadStream() {
209 return StdioStream::makeFromPath(getPath(), false);
210 }
211
createWriteStream()212 Common::WriteStream *WiiFilesystemNode::createWriteStream() {
213 return StdioStream::makeFromPath(getPath(), true);
214 }
215
createDirectory()216 bool WiiFilesystemNode::createDirectory() {
217 warning("WiiFilesystemNode::createDirectory(): Not supported");
218 return _exists && _isDirectory;
219 }
220
221 #endif //#if defined(__WII__)
222