Root/
1 | /*************************************************************************** |
2 | * Copyright (C) 2006 by Massimiliano Torromeo * |
3 | * massimiliano.torromeo@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 * |
16 | * along with this program; if not, write to the * |
17 | * Free Software Foundation, Inc., * |
18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
19 | ***************************************************************************/ |
20 | |
21 | #include "filelister.h" |
22 | |
23 | #include "debug.h" |
24 | #include "utilities.h" |
25 | |
26 | //for browsing the filesystem |
27 | #include <sys/stat.h> |
28 | #include <sys/types.h> |
29 | #include <dirent.h> |
30 | #include <errno.h> |
31 | #include <iostream> |
32 | #include <algorithm> |
33 | #include <cstring> |
34 | |
35 | using namespace std; |
36 | |
37 | FileLister::FileLister(const string &startPath, bool showDirectories, |
38 | bool showFiles) : showDirectories(showDirectories), showFiles(showFiles) |
39 | { |
40 | setPath(startPath, false); |
41 | } |
42 | |
43 | const string &FileLister::getPath() |
44 | { |
45 | return path; |
46 | } |
47 | |
48 | void FileLister::setPath(const string &path, bool doBrowse) |
49 | { |
50 | this->path = path; |
51 | |
52 | if (this->path[path.length() - 1]!='/') |
53 | this->path += "/"; |
54 | |
55 | if (doBrowse) |
56 | browse(); |
57 | } |
58 | |
59 | const string &FileLister::getFilter() |
60 | { |
61 | return filter; |
62 | } |
63 | |
64 | void FileLister::setFilter(const string &filter) |
65 | { |
66 | this->filter = filter; |
67 | } |
68 | |
69 | void FileLister::browse(bool clean) |
70 | { |
71 | if (clean) { |
72 | directories.clear(); |
73 | files.clear(); |
74 | } |
75 | |
76 | if (showDirectories || showFiles) { |
77 | DIR *dirp; |
78 | if ((dirp = opendir(path.c_str())) == NULL) { |
79 | ERROR("Unable to open directory: %s\n", path.c_str()); |
80 | return; |
81 | } |
82 | |
83 | string filepath, file; |
84 | struct stat st; |
85 | struct dirent *dptr; |
86 | |
87 | while ((dptr = readdir(dirp))) { |
88 | file = dptr->d_name; |
89 | |
90 | if (file[0] == '.' && file != "..") |
91 | continue; |
92 | |
93 | filepath = path + file; |
94 | int statRet = stat(filepath.c_str(), &st); |
95 | if (statRet == -1) { |
96 | ERROR("Stat failed on '%s' with error '%s'\n", filepath.c_str(), strerror(errno)); |
97 | continue; |
98 | } |
99 | if (find(excludes.begin(), excludes.end(), file) != excludes.end()) |
100 | continue; |
101 | |
102 | if (S_ISDIR(st.st_mode)) { |
103 | if (!showDirectories) |
104 | continue; |
105 | |
106 | if (std::find(directories.begin(), directories.end(), file) != directories.end()) |
107 | continue; |
108 | |
109 | directories.push_back(file); |
110 | } else { |
111 | if (!showFiles) |
112 | continue; |
113 | |
114 | if (std::find(files.begin(), files.end(), file) != files.end()) |
115 | continue; |
116 | |
117 | if (filter.compare("*") == 0) { |
118 | files.push_back(file); |
119 | continue; |
120 | } |
121 | |
122 | vector<string> vfilter; |
123 | split(vfilter, filter, ","); |
124 | for (vector<string>::iterator it = vfilter.begin(); it != vfilter.end(); ++it) { |
125 | if (file.find('.') == string::npos) { |
126 | if (!it->empty()) |
127 | continue; |
128 | |
129 | files.push_back(file); |
130 | break; |
131 | } |
132 | |
133 | if (it->length() < file.length()) { |
134 | if (file[file.length() - it->length() - 1] != '.') |
135 | continue; |
136 | |
137 | string file_lowercase = |
138 | file.substr(file.length() - it->length()); |
139 | |
140 | /* XXX: This won't accept UTF-8 codes. |
141 | * Thanksfully file extensions shouldn't contain any. */ |
142 | transform(file_lowercase.begin(), file_lowercase.end(), |
143 | file_lowercase.begin(), ::tolower); |
144 | |
145 | if (file_lowercase.compare(0, it->length(), *it) == 0) { |
146 | files.push_back(file); |
147 | break; |
148 | } |
149 | } |
150 | } |
151 | } |
152 | } |
153 | |
154 | closedir(dirp); |
155 | sort(files.begin(), files.end(), case_less()); |
156 | sort(directories.begin(), directories.end(), case_less()); |
157 | } |
158 | } |
159 | |
160 | unsigned int FileLister::size() |
161 | { |
162 | return files.size() + directories.size(); |
163 | } |
164 | |
165 | unsigned int FileLister::dirCount() |
166 | { |
167 | return directories.size(); |
168 | } |
169 | |
170 | unsigned int FileLister::fileCount() |
171 | { |
172 | return files.size(); |
173 | } |
174 | |
175 | string FileLister::operator[](uint x) |
176 | { |
177 | return at(x); |
178 | } |
179 | |
180 | string FileLister::at(uint x) |
181 | { |
182 | if (x < directories.size()) |
183 | return directories[x]; |
184 | else |
185 | return files[x-directories.size()]; |
186 | } |
187 | |
188 | bool FileLister::isFile(unsigned int x) |
189 | { |
190 | return x >= directories.size() && x < size(); |
191 | } |
192 | |
193 | bool FileLister::isDirectory(unsigned int x) |
194 | { |
195 | return x < directories.size(); |
196 | } |
197 | |
198 | void FileLister::insertFile(const string &file) { |
199 | files.insert(files.begin(), file); |
200 | } |
201 | |
202 | void FileLister::addExclude(const string &exclude) { |
203 | excludes.push_back(exclude); |
204 | } |
205 |
Branches:
install_locations
master
opkrun
packages