1 /*
2 * ppui/osinterface/posix/PPPath_POSIX.cpp
3 *
4 * Copyright 2009 Peter Barth
5 *
6 * This file is part of Milkytracker.
7 *
8 * Milkytracker is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Milkytracker is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Milkytracker. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 /*
24 * PPPath_POSIX.cpp
25 * MilkyTracker
26 *
27 * Created by Peter Barth on 10.03.06.
28 *
29 */
30
31 #include "PPPath_POSIX.h"
32 #include <sys/stat.h>
33 #include <limits.h>
34
35 #ifdef __PSP__
36 // Needed for PATH_MAX
37 #include <sys/syslimits.h>
38 #endif
39
40 #ifdef PATH_MAX
41 #define PPMAX_DIR_PATH PATH_MAX
42 #else
43 #define PPMAX_DIR_PATH 1024
44 #endif
45
create(const PPSystemString & path,const PPSystemString & name)46 void PPPathEntry_POSIX::create(const PPSystemString& path, const PPSystemString& name)
47 {
48 this->name = name;
49 PPSystemString fullPath = path;
50
51 fullPath.append(name);
52
53 struct stat file_status;
54
55 if (::stat(fullPath, &file_status) == 0)
56 {
57 size = file_status.st_size;
58
59 if (S_ISDIR(file_status.st_mode))
60 type = Directory;
61 //if (S_ISLNK(file_status.st_mode))
62 // printf("foo.txt is a symbolic link\n");
63 if (S_ISCHR(file_status.st_mode))
64 type = Hidden;
65 if (S_ISBLK(file_status.st_mode))
66 type = Hidden;
67 if (S_ISFIFO(file_status.st_mode))
68 type = Hidden;
69 if (S_ISSOCK(file_status.st_mode))
70 type = Hidden;
71 if (S_ISREG(file_status.st_mode))
72 type = File;
73 }
74 else
75 { /* stat() call failed and returned '-1'. */
76 type = Nonexistent;
77 }
78 }
79
isHidden() const80 bool PPPathEntry_POSIX::isHidden() const
81 {
82 return PPPathEntry::isHidden() || (name.startsWith(".") && name.compareTo("..") != 0);
83 }
84
updatePath()85 bool PPPath_POSIX::updatePath()
86 {
87 return chdir(current) == 0;
88 }
89
PPPath_POSIX()90 PPPath_POSIX::PPPath_POSIX()
91 {
92 current = getCurrent();
93 updatePath();
94 }
95
PPPath_POSIX(const PPSystemString & path)96 PPPath_POSIX::PPPath_POSIX(const PPSystemString& path) :
97 current(path)
98 {
99 updatePath();
100 }
101
getCurrent()102 const PPSystemString PPPath_POSIX::getCurrent()
103 {
104 char cwd[PPMAX_DIR_PATH+1];
105 memset(cwd, 0, sizeof(cwd));
106
107 getcwd(cwd, PPMAX_DIR_PATH+1);
108
109 PPSystemString path(cwd);
110
111 path.ensureTrailingCharacter(getPathSeparatorAsASCII());
112 return path;
113 }
114
change(const PPSystemString & path)115 bool PPPath_POSIX::change(const PPSystemString& path)
116 {
117 PPSystemString old = current;
118 current = path;
119 current.ensureTrailingCharacter(getPathSeparatorAsASCII());
120 bool res = updatePath();
121 if (res)
122 return true;
123 current = old;
124 return false;
125 }
126
stepInto(const PPSystemString & directory)127 bool PPPath_POSIX::stepInto(const PPSystemString& directory)
128 {
129 PPSystemString old = current;
130 current.append(directory);
131 current.append(getPathSeparator());
132 bool res = updatePath();
133 if (res)
134 return true;
135 current = old;
136 return false;
137 }
138
getFirstEntry()139 const PPPathEntry* PPPath_POSIX::getFirstEntry()
140 {
141 dir = ::opendir(current);
142 if (!dir)
143 {
144 return NULL;
145 }
146
147 return getNextEntry();
148 }
149
getNextEntry()150 const PPPathEntry* PPPath_POSIX::getNextEntry()
151 {
152 struct dirent* entry;
153 if ((entry = ::readdir(dir)) != NULL)
154 {
155 PPSystemString file(entry->d_name);
156 this->entry.create(current, file);
157
158 return &this->entry;
159 }
160
161 ::closedir(dir);
162 return NULL;
163 }
164
canGotoHome() const165 bool PPPath_POSIX::canGotoHome() const
166 {
167 return getenv("HOME") ? true : false;
168 }
169
gotoHome()170 void PPPath_POSIX::gotoHome()
171 {
172 char* home = getenv("HOME");
173 if (home)
174 {
175 change(home);
176 updatePath();
177 }
178 }
179
canGotoRoot() const180 bool PPPath_POSIX::canGotoRoot() const
181 {
182 return true;
183 }
184
gotoRoot()185 void PPPath_POSIX::gotoRoot()
186 {
187 change("/");
188 updatePath();
189 }
190
canGotoParent() const191 bool PPPath_POSIX::canGotoParent() const
192 {
193 return true;
194 }
195
gotoParent()196 void PPPath_POSIX::gotoParent()
197 {
198 stepInto("..");
199 }
200
getPathSeparatorAsASCII() const201 char PPPath_POSIX::getPathSeparatorAsASCII() const
202 {
203 return '/';
204 }
205
getPathSeparator() const206 const PPSystemString PPPath_POSIX::getPathSeparator() const
207 {
208 return PPSystemString(getPathSeparatorAsASCII());
209 }
210
fileExists(const PPSystemString & fileName) const211 bool PPPath_POSIX::fileExists(const PPSystemString& fileName) const
212 {
213 struct stat file_status;
214
215 if (::stat(fileName, &file_status) == 0)
216 {
217 return (S_ISREG(file_status.st_mode)) != 0;
218 }
219
220 return false;
221 }
222
223
224