ucommon  7.0.0
About: GNU uCommon C++ is a portable and optimized class framework for writing C++ applications that need to use threads and support concurrent synchronization, and that use sockets, XML parsing, object serialization, thread-optimized string and data structure classes, etc..
  Fossies Dox: ucommon-7.0.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

Loading...
Searching...
No Matches
dir.cpp
Go to the documentation of this file.
1// Copyright (C) 1999-2005 Open Source Telecom Corporation.
2// Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
3// Copyright (C) 2015 Cherokees of Idaho.
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 Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18//
19// As a special exception, you may use this file as part of a free software
20// library without restriction. Specifically, if other files instantiate
21// templates or use macros or inline functions from this file, or you compile
22// this file and link it with other files to produce an executable, this
23// file does not by itself cause the resulting executable to be covered by
24// the GNU General Public License. This exception does not however
25// invalidate any other reasons why the executable file might be covered by
26// the GNU General Public License.
27//
28// This exception applies only to the code released under the name GNU
29// Common C++. If you copy code from other releases into a copy of GNU
30// Common C++, as the General Public License permits, the exception does
31// not apply to the code that you add in this way. To avoid misleading
32// anyone as to the status of such modified files, you must delete
33// this exception notice from them.
34//
35// If you write modifications of your own for GNU Common C++, it is your choice
36// whether to permit this exception to apply to your modifications.
37// If you do not wish that, delete this exception notice.
38//
39
40#ifndef _MSC_VER
41#include <sys/stat.h>
42#endif
43
44// needed for GNU/LINUX glibc otherwise pread/pwrite wont work
45
46#ifndef _XOPEN_SOURCE
47#define _XOPEN_SOURCE 600
48#endif
49
50/*
51 * on old glibc's, this has to be
52 * defined explicitly
53 */
54#ifndef _XOPEN_SOURCE_EXTENDED
55#define _XOPEN_SOURCE_EXTENDED
56#endif
57
58#include <ucommon-config.h>
59
60#include <commoncpp/config.h>
61#include <commoncpp/export.h>
62#include <commoncpp/exception.h>
63#include <commoncpp/thread.h>
64#include <commoncpp/process.h>
65#include <commoncpp/file.h>
66
67#ifdef _MSWINDOWS_
68#include <sys/stat.h>
69#include <malloc.h>
70#endif
71
72namespace ost {
73using namespace std;
74
75Dir::Dir(const char *fname) :
76#ifdef _MSWINDOWS_
77hDir(INVALID_HANDLE_VALUE), name(NULL)
78#else
79dir(NULL)
80#endif
81{
82#ifdef HAVE_READDIR_R
83 save = reinterpret_cast<struct dirent*>(save_space);
84#endif
85 if(fname)
86 open(fname);
87}
88
89bool Dir::create(const char *path, Attr attr)
90{
91 bool rtn = true;
92#ifdef _MSWINDOWS_
93
94 // fixme: make it form a security attributes structure
95
96 if(!CreateDirectory(path, NULL))
97 rtn = false;
98#else
99 long xmask = 0;
100
101 switch(attr)
102 {
103 case attrPublic:
104 xmask |= S_IXOTH;
105 case attrGroup:
106 xmask |= S_IXGRP;
107 case attrPrivate:
108 xmask |= S_IXUSR;
109 break;
110 default:
111 return false;
112 }
113 if(mkdir(path, (long)attr | xmask))
114 rtn = false;
115#endif
116 return rtn;
117}
118
119bool Dir::remove(const char *path)
120{
121 bool rtn = true;
122#ifdef _MSWINDOWS_
123 if(!RemoveDirectory(path))
124 rtn = false;
125#else
126 if(rmdir(path))
127 rtn = false;
128#endif
129 return rtn;
130}
131
132bool Dir::setPrefix(const char *prefix)
133{
134 bool rtn = true;
135
136#ifdef _MSWINDOWS_
137 if(!SetCurrentDirectory(prefix))
138 rtn = false;
139#else
140 if(chdir(prefix))
141 rtn = false;
142#endif
143 return rtn;
144}
145
146bool Dir::getPrefix(char *prefix, size_t size)
147{
148 bool rtn = true;
149
150#ifdef _MSWINDOWS_
151 if(!GetCurrentDirectory((DWORD)size, prefix))
152 rtn = false;
153#else
154 if(getcwd(prefix, size) == NULL)
155 rtn = false;
156#endif
157 return rtn;
158}
159
160void Dir::open(const char *fname)
161{
162#ifdef _MSWINDOWS_
163 size_t len = strlen(fname) + 4;
164 char *path;
165#endif
166
167 close();
168#ifdef _MSWINDOWS_
169 DWORD attr = GetFileAttributes(fname);
170 if( (attr == (DWORD)~0l) || !(attr & FILE_ATTRIBUTE_DIRECTORY) )
171 {
172#ifdef CCXX_EXCEPTIONS
174 throw(this);
175#ifdef COMMON_STD_EXCEPTION
177 throw(DirException(String(fname) + ": failed"));
178#endif
179#endif
180 }
181
182 path = (char *)_malloca(len + 1);
183 if(path)
184 snprintf(path, len + 1, "%s", fname);
185#ifdef CCXX_EXCEPTIONS
187 throw(this);
188#ifdef COMMON_STD_EXCEPTION
189 else if(!path && Thread::getException() == Thread::throwException)
190 throw(DirException(String(fname) + ": failed"));
191#endif
192#endif
193 if (!path || !path[0])
194 return;
195 addString(path, len, "\\*");
196 hDir = FindFirstFile(path, &fdata);
197 if(hDir != INVALID_HANDLE_VALUE)
198 name = fdata.cFileName;
199 memcpy(&data, &fdata, sizeof(fdata));
200
201#else // WIN32
202 entry = NULL;
203 dir = opendir(fname);
204#ifdef CCXX_EXCEPTIONS
206 throw(this);
207#ifdef COMMON_STD_EXCEPTION
209 throw(DirException(String(fname) + ": failed"));
210#endif
211#endif
212#endif // WIN32
213}
214
216{
217 close();
218}
219
220void Dir::close(void)
221{
222#ifdef _MSWINDOWS_
223 if(hDir != INVALID_HANDLE_VALUE)
224 FindClose(hDir);
226#else
227 if(dir)
228 closedir(dir);
229 dir = NULL;
230 entry = NULL;
231#endif
232}
233
234bool Dir::rewind(void)
235{
236 bool rtn = true;
237#ifdef _MSWINDOWS_
238 memcpy(&data, &fdata, sizeof(data));
239 name = fdata.cFileName;
240#else
241 if(!dir)
242 rtn = false;
243 else
244 rewinddir(dir);
245#endif
246 return rtn;
247}
248
249bool Dir::isValid(void) const
250{
251#ifdef _MSWINDOWS_
252 if(hDir == INVALID_HANDLE_VALUE)
253#else
254 if(!dir)
255#endif
256 return false;
257
258 return true;
259}
260
261const char *Dir::operator*()
262{
263#ifdef _MSWINDOWS_
264 return name;
265#else
266 if(!dir)
267 return NULL;
268
269 if(!entry)
270 return getName();
271
272 return entry->d_name;
273#endif
274}
275
276const char *Dir::getName(void)
277{
278#ifdef _MSWINDOWS_
279 char *retname = name;
280
281 if(hDir == INVALID_HANDLE_VALUE)
282 return NULL;
283
284 if(retname)
285 {
286 name = NULL;
287 if(FindNextFile(hDir, &data))
288 name = data.cFileName;
289 }
290 return retname;
291
292#else
293 if(!dir)
294 return NULL;
295
296#ifdef HAVE_READDIR_R
297 readdir_r(dir, save, &entry);
298#else
299 entry = readdir(dir);
300#endif
301 if(!entry)
302 return NULL;
303
304 return entry->d_name;
305#endif // WIN32
306}
307
308DirTree::DirTree(const char *prefix, unsigned depth)
309{
310 max = ++depth;
311 dir = new Dir[depth];
312 current = 0;
313
314 open(prefix);
315}
316
317DirTree::DirTree(unsigned depth)
318{
319 max = ++depth;
320 dir = new Dir[depth];
321 current = 0;
322}
323
324void DirTree::open(const char *prefix)
325{
326 char *cp;
327
328 close();
329
330 if(!isDir(prefix))
331 return;
332
333 snprintf(path, sizeof(path), "%s/", prefix);
334 prefixpos = (unsigned)strlen(path) - 1;
335
336 while(NULL != (cp = strchr(path, '\\')))
337 *cp = '/';
338
339 while(prefixpos && path[prefixpos - 1] == '/')
340 path[prefixpos--] = 0;
341
342 dir[current++].open(prefix);
343}
344
346{
347 close();
348
349 if(dir)
350 delete[] dir;
351
352 dir = NULL;
353}
354
355unsigned DirTree::perform(const char *prefix)
356{
357 unsigned count = 0;
358
359 open(prefix);
360 while(NULL != (getPath()))
361 ++count;
362 close();
363 return count;
364}
365
367{
368 while(current--)
369 dir[current].close();
370
371 current = 0;
372}
373
374
375bool DirTree::filter(const char *fpath, struct stat *ino)
376{
377 fpath = strrchr(path, '/');
378
379 if(fpath)
380 ++fpath;
381 else
382 return false;
383
384 if(!strcmp(fpath, "."))
385 return false;
386
387 if(!strcmp(fpath, ".."))
388 return false;
389
390 if(!ino)
391 return false;
392
393 return true;
394}
395
397{
398 char *cp;
399 const char *name;
400 struct stat ino;
401 bool flag;
402
403 while(current)
404 {
405 cp = strrchr(path, '/');
406 name = dir[current - 1].getName();
407 if(!name)
408 {
409 *cp = 0;
410 dir[--current].close();
411 continue;
412 }
413 snprintf(cp + 1, sizeof(path) - strlen(path) - 2, "%s", name);
414
415 if(::stat(path, &ino))
416 {
417 ino.st_mode = 0;
418 flag = filter(path, NULL);
419 }
420 else
421 flag = filter(path, &ino);
422
423 if(!flag)
424 continue;
425
426 if((ino.st_mode & S_IFMT) == S_IFDIR)
427 {
428 if(!canAccess(path))
429 break;
430
431 if(current < max)
432 dir[current++].open(path);
433
434 snprintf(path + strlen(path), sizeof(path) - strlen(path), "/");
435 }
436 break;
437 }
438 if(!current)
439 return NULL;
440
441 return path;
442}
443
444} // end namespace
static char prefix[80]
Definition: args.cpp:33
virtual bool filter(const char *file, struct stat *ino)
Virtual method to filter results.
Definition: dir.cpp:375
char * getPath(void)
Extract the next full pathname from the directory walk.
Definition: dir.cpp:396
unsigned max
Definition: file.h:314
char path[256+1]
Definition: file.h:312
DirTree(const char *prefix, unsigned maxdepth)
Construct a directory tree walk starting at the specified prefix.
Definition: dir.cpp:308
Dir * dir
Definition: file.h:313
unsigned current
Definition: file.h:314
unsigned prefixpos
Definition: file.h:314
virtual ~DirTree()
Definition: dir.cpp:345
void close(void)
Close the directory path.
Definition: dir.cpp:366
unsigned perform(const char *prefix)
This is used to step through the filter virtual for an entire subtree, and is used for cases where a ...
Definition: dir.cpp:355
void open(const char *prefix)
Open a directory tree path.
Definition: dir.cpp:324
A low level portable directory class.
Definition: file.h:242
Dir(const char *name=NULL)
Definition: dir.cpp:75
const char * getName(void)
Definition: dir.cpp:276
virtual ~Dir()
Definition: dir.cpp:215
static bool create(const char *path, Attr attr=attrGroup)
Definition: dir.cpp:89
const char * operator*()
Definition: dir.cpp:261
static bool getPrefix(char *path, size_t size=256)
Definition: dir.cpp:146
void open(const char *name)
Definition: dir.cpp:160
void close(void)
Definition: dir.cpp:220
bool rewind(void)
Definition: dir.cpp:234
struct dirent * entry
Definition: file.h:248
char save_space[sizeof(struct dirent)+256+1]
Definition: file.h:247
bool isValid(void) const
Definition: dir.cpp:249
static bool remove(const char *path)
Definition: dir.cpp:119
static bool setPrefix(const char *path)
Definition: dir.cpp:132
struct dirent * save
Definition: file.h:246
@ attrPublic
Definition: file.h:186
@ attrGroup
Definition: file.h:185
@ attrPrivate
Definition: file.h:184
static Throw getException(void)
Get exception mode of the current thread.
Definition: thread.cpp:287
@ throwException
throw an object relative to error
Definition: thread.h:415
@ throwObject
throw object that cause error (throw this)
Definition: thread.h:414
A copy-on-write string class that operates by reference count.
Definition: string.h:79
Convenience class for directories.
Definition: fsys.h:744
void open(const char *path)
Open a directory path for reading.
Definition: fsys.cpp:909
void close(void)
Close and release directory object.
Definition: fsys.cpp:808
Export interfaces for library interfaces.
Common C++ thread class and sychronization objects.
GNU Common C++ exception model base classes.
Files and dynamic loader services.
Definition: address.cpp:63
bool canAccess(const char *path)
Definition: file.cpp:1259
char * addString(char *target, size_t size, const char *str)
Definition: string.h:67
bool isDir(const char *path)
Definition: file.cpp:1193
STL namespace.
#define INVALID_HANDLE_VALUE
Definition: platform.h:417
Process services.