directory.cpp

Go to the documentation of this file.
00001 
00006 // -*-C++-*- directory.cc
00007 // <!!----------------------------------------------------------------------> 
00008 // <!! Copyright (C) 1998 Dietmar Kuehl, Claas Solutions GmbH > 
00009 // <!!> 
00010 // <!! Permission to use, copy, modify, distribute and sell this > 
00011 // <!! software for any purpose is hereby granted without fee, provided > 
00012 // <!! that the above copyright notice appears in all copies and that > 
00013 // <!! both that copyright notice and this permission notice appear in > 
00014 // <!! supporting documentation. Dietmar Kuehl and Claas Solutions make no > 
00015 // <!! representations about the suitability of this software for any > 
00016 // <!! purpose. It is provided "as is" without express or implied warranty. > 
00017 // <!!----------------------------------------------------------------------> 
00018 
00019 // Author: Dietmar Kuehl dietmar.kuehl@claas-solutions.de 
00020 // Title:  Implementation of the directory iterator
00021 // Version: $Name:  $ $Id: directory.cpp,v 1.2 2006/01/30 13:23:59 wmayer Exp $
00022 
00023 // -------------------------------------------------------------------------- 
00024 
00025 #include "meta-iostreams.h"
00026 
00027 #include "directory.h"
00028 
00029 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
00030 #  define BOOST_UNIX 1
00031 #elif defined(_WINDOWS) || defined(__MINGW32__) || defined (_MSC_VER)
00032 #  define BOOST_WINNT 1
00033 #endif 
00034 
00035 // -------------------------------------------------------------------------- 
00036 // The POSIX version uses the functions opendir(), readdir(), and closdir()
00037 // to find directory entries. In addition, stat() is used to find out
00038 // about specific file attributes.
00039 
00040 #if defined(BOOST_UNIX)
00041 
00042 #ifndef __USE_BSD
00043 #define __USE_BSD
00044 #endif 
00045 #include <sys/stat.h>
00046 #include <dirent.h>
00047 #include <unistd.h>
00048 #include <pwd.h>
00049 #include <grp.h>
00050 
00051 struct boost::filesystem::dir_it::representation
00052 {
00053         representation():
00054                 m_handle(0),
00055                 m_refcount(1),
00056                 m_stat_p(false)
00057         {
00058         }
00059 
00060         representation(std::string const &dirname):
00061                 m_handle(opendir(dirname.c_str())),
00062                 m_refcount(1),
00063                 m_directory(dirname),
00064                 m_stat_p(false)
00065         {
00066                 if( m_directory.size() == 0 )
00067                         m_directory = "./" ;
00068                 if (m_directory[m_directory.size() - 1] != '/')
00069                         m_directory += '/';
00070                 operator++ ();
00071         }
00072 
00073         ~representation() { if ( m_handle )  closedir(m_handle); }
00074 
00075         representation *reference()
00076         {
00077                 ++m_refcount;
00078                 return this;
00079         }
00080         representation *release() { return --m_refcount? 0: this; }
00081 
00082         representation &operator++()
00083         {
00084                 if (m_handle)
00085                         {
00086                                 m_stat_p = false;
00087                                 dirent *rc = readdir(m_handle);
00088                                 if (rc != 0)
00089                                         m_current = rc->d_name;
00090                                 else
00091                                         {
00092                                                 m_current = "";
00093                                                 closedir(m_handle);
00094                                                 m_handle = 0;
00095                                         }
00096                         }
00097 
00098                 return *this;
00099         }
00100 
00101         bool operator== (representation const &rep) const
00102         {
00103                 return (m_handle == 0) == (rep.m_handle == 0);
00104         }
00105 
00106         std::string const &operator* () { return m_current; }
00107 
00108         struct stat &get_stat()
00109         {
00110                 if (!m_stat_p)
00111                         stat( (m_directory + m_current).c_str(), &m_stat);
00112                 return m_stat;
00113         }
00114 
00115         void set_mode(mode_t m, bool nv)
00116         {
00117                 if (((get_stat().st_mode & m) == 0) == nv)
00118                         chmod((m_directory + m_current).c_str(), get_stat().st_mode ^ m);
00119         }
00120         void change_owner(uid_t uid) { chown((m_directory + m_current).c_str(), uid, get_stat().st_gid); }
00121         void change_group(gid_t gid) { chown((m_directory + m_current).c_str(), get_stat().st_uid, gid); }
00122 
00123 private:
00124         DIR         *m_handle;
00125         int         m_refcount;
00126         std::string m_directory;
00127         std::string m_current;
00128         struct stat m_stat;
00129         bool        m_stat_p;
00130 };
00131 
00132 namespace boost
00133 {
00134         namespace filesystem
00135         {
00136 
00137                 template <> bool get<is_link>(dir_it const &it) { return S_ISLNK(it.rep->get_stat().st_mode); }
00138                 template <> bool get<is_regular>(dir_it const &it) { return S_ISREG(it.rep->get_stat().st_mode); }
00139                 template <> bool get<is_directory>(dir_it const &it) { return S_ISDIR(it.rep->get_stat().st_mode); }
00140                 template <> bool get<is_char_device>(dir_it const &it) { return S_ISCHR(it.rep->get_stat().st_mode); }
00141                 template <> bool get<is_block_device>(dir_it const &it) { return S_ISBLK(it.rep->get_stat().st_mode); }
00142                 template <> bool get<is_fifo>(dir_it const &it) { return S_ISFIFO(it.rep->get_stat().st_mode); }
00143                 template <> bool get<is_socket>(dir_it const &it) { return S_ISSOCK(it.rep->get_stat().st_mode); }
00144 
00145                 template <> bool get<user_read>(dir_it const &it) { return it.rep->get_stat().st_mode & S_IRUSR; }
00146                 template <> void set<user_read>(dir_it const &it, bool nv) { it.rep->set_mode(S_IRUSR, nv); }
00147                 template <> bool get<user_write>(dir_it const &it) { return it.rep->get_stat().st_mode & S_IWUSR; }
00148                 template <> void set<user_write>(dir_it const &it, bool nv) { it.rep->set_mode(S_IWUSR, nv); }
00149                 template <> bool get<user_execute>(dir_it const &it) { return it.rep->get_stat().st_mode & S_IXUSR; }
00150                 template <> void set<user_execute>(dir_it const &it, bool nv) { it.rep->set_mode(S_IXUSR, nv); }
00151                 template <> bool get<set_uid>(dir_it const &it) { return it.rep->get_stat().st_mode & S_ISUID; }
00152                 template <> void set<set_uid>(dir_it const &it, bool nv) { it.rep->set_mode(S_ISUID, nv); }
00153 
00154                 template <> bool get<group_read>(dir_it const &it) { return it.rep->get_stat().st_mode & S_IRGRP; }
00155                 template <> void set<group_read>(dir_it const &it, bool nv) { it.rep->set_mode(S_IRGRP, nv); }
00156                 template <> bool get<group_write>(dir_it const &it) { return it.rep->get_stat().st_mode & S_IWGRP; }
00157                 template <> void set<group_write>(dir_it const &it, bool nv) { it.rep->set_mode(S_IWGRP, nv); }
00158                 template <> bool get<group_execute>(dir_it const &it) { return it.rep->get_stat().st_mode & S_IXGRP; }
00159                 template <> void set<group_execute>(dir_it const &it, bool nv) { it.rep->set_mode(S_IXGRP, nv); }
00160                 template <> bool get<set_gid>(dir_it const &it) { return it.rep->get_stat().st_mode & S_ISGID; }
00161                 template <> void set<set_gid>(dir_it const &it, bool nv) { it.rep->set_mode(S_ISGID, nv); }
00162 
00163                 template <> bool get<other_read>(dir_it const &it) { return it.rep->get_stat().st_mode & S_IROTH; }
00164                 template <> void set<other_read>(dir_it const &it, bool nv) { it.rep->set_mode(S_IROTH, nv); }
00165                 template <> bool get<other_write>(dir_it const &it) { return it.rep->get_stat().st_mode & S_IWOTH; }
00166                 template <> void set<other_write>(dir_it const &it, bool nv) { it.rep->set_mode(S_IWOTH, nv); }
00167                 template <> bool get<other_execute>(dir_it const &it) { return it.rep->get_stat().st_mode & S_IXOTH; }
00168                 template <> void set<other_execute>(dir_it const &it, bool nv) { it.rep->set_mode(S_IXOTH, nv); }
00169                 template <> bool get<sticky>(dir_it const &it) { return it.rep->get_stat().st_mode & S_ISVTX; }
00170                 template <> void set<sticky>(dir_it const &it, bool nv) { it.rep->set_mode(S_ISVTX, nv); }
00171 
00172                 template <> nlink_t get<links>(dir_it const &it) { return it.rep->get_stat().st_nlink; }
00173                 template <> size_t get<size>(dir_it const &it) { return it.rep->get_stat().st_size; }
00174                 template <> unsigned long get<blocks>(dir_it const &it) { return it.rep->get_stat().st_blocks; }
00175                 template <> unsigned long get<blksize>(dir_it const &it) { return it.rep->get_stat().st_blksize; }
00176 
00177                 template <> mtime::value_type get<mtime>(dir_it const &it) { return &it.rep->get_stat().st_mtime; }
00178                 template <> atime::value_type get<atime>(dir_it const &it) { return &it.rep->get_stat().st_atime; }
00179                 template <> ctime::value_type get<ctime>(dir_it const &it) { return &it.rep->get_stat().st_ctime; }
00180 
00181                 template <> uid_t get<uid>(dir_it const &it) { return it.rep->get_stat().st_uid; }
00182                 template <> void set<uid>(dir_it const &it, uid_t uid) { it.rep->change_owner(uid); }
00183                 template <> std::string get<uname>(dir_it const &it)
00184                         {
00185                                 struct passwd *pw = getpwuid(it.rep->get_stat().st_uid);
00186                                 if (pw == 0)
00187                                         throw unknown_uid(it.rep->get_stat().st_uid);
00188                                 return pw->pw_name;
00189                         }
00190                 template <> void set<uname>(dir_it const &it, std::string name)
00191                         {
00192                                 struct passwd *pw = getpwnam(name.c_str());
00193                                 if (pw != 0)
00194                                         it.rep->change_owner(pw->pw_uid);
00195                                 else
00196                                         throw unknown_uname(name);
00197                         }
00198 
00199                 template <> gid_t get<gid>(dir_it const &it) { return it.rep->get_stat().st_gid; }
00200                 template <> void set<gid>(dir_it const &it, gid_t gid) { it.rep->change_group(gid); }
00201                 template <> std::string get<gname>(dir_it const &it)
00202                         {
00203                                 struct group *grp = getgrgid(it.rep->get_stat().st_gid);
00204                                 if (grp == 0)
00205                                         throw unknown_gid(it.rep->get_stat().st_gid);
00206                                 return grp->gr_name;
00207                         }
00208                 template <> void set<gname>(dir_it const &it, std::string name)
00209                         {
00210                                 struct group *grp = getgrnam(name.c_str());
00211                                 if (grp != 0)
00212                                         it.rep->change_group(grp->gr_gid);
00213                                 else
00214                                         throw unknown_gname(name);
00215                         }
00216 
00217 
00218                 template <> bool get<is_hidden>(dir_it const &it) { return (*it)[0] == '.'; }
00219         }
00220 }
00221 
00222 #elif defined(BOOST_WINNT)
00223 
00224 #include "io.h"
00225 #include "direct.h"
00226 
00227 struct boost::filesystem::dir_it::representation
00228 {
00229         representation():
00230                 m_handle(-1),
00231                 m_refcount(1)
00232         {
00233         }
00234 
00235         representation(std::string const &dirname):
00236                 m_handle(_findfirst((dirname + "\\*").c_str(), &m_data)),
00237                 m_refcount(1)
00238         {
00239         }
00240 
00241         ~representation() { if (m_handle != -1) _findclose(m_handle); }
00242 
00243         representation *reference()
00244         {
00245                 ++m_refcount;
00246                 return this;
00247         }
00248         representation *release() { return --m_refcount? 0: this; }
00249 
00250         representation &operator++()
00251         {
00252                 if (m_handle != -1)
00253                         {
00254                                 if (_findnext(m_handle, &m_data) == -1)
00255                                         {
00256                                                 _findclose(m_handle);
00257                                                 m_handle = -1;
00258                                         }
00259 
00260                         }
00261 
00262                 return *this;
00263         }
00264 
00265         bool operator== (representation const &rep) const
00266         {
00267                 return (m_handle == -1) == (rep.m_handle == -1);
00268         }
00269 
00270         std::string operator* () { return m_data.name; }
00271 
00272 
00273         struct _finddata_t const &get_data() const
00274         {
00275                 return m_data;
00276         }
00277 
00278 #if 0
00279         void set_mode(mode_t m, bool nv)
00280         {
00281                 if (((get_stat().st_mode & m) == 0) == nv)
00282                         chmod((m_directory + m_current).c_str(), get_stat().st_mode ^ m);
00283         }
00284         void change_owner(uid_t uid) { chown((m_directory + m_current).c_str(), uid, get_stat().st_gid); }
00285         void change_group(gid_t gid) { chown((m_directory + m_current).c_str(), get_stat().st_uid, gid); }
00286 #endif
00287 
00288 private:
00289         struct _finddata_t m_data;
00290         long               m_handle;
00291         int                m_refcount;
00292         std::string        m_directory;
00293 };
00294 
00295 namespace boost
00296 {
00297         namespace filesystem
00298         {
00299 #if defined(__MINGW32__)
00300                 template <> size_t get<size>(dir_it const &it)
00301                 {
00302                         return it.rep->get_data().size;
00303                 }
00304                 template <> mtime::value_type get<mtime>(dir_it const &it)
00305                 {
00306                         return &it.rep->get_data().time_write;
00307                 }
00308                 template <> bool get<is_directory>(dir_it const &it)
00309                 {
00310                         return (it.rep->get_data().attrib & _A_SUBDIR) != 0;
00311                 }
00312                 template <> bool get<is_regular>(dir_it const &it)
00313                 {
00314                         return (it.rep->get_data().attrib & _A_SUBDIR) == 0;
00315                 }
00316                 template <> bool get<is_hidden>(dir_it const &it)
00317                 {
00318                         return (it.rep->get_data().attrib & _A_HIDDEN) != 0;
00319                 }
00320                 template <> bool get<user_read>(dir_it const &it)
00321                 {
00322                         return true;
00323                 }
00324                 template <> bool get<user_write>(dir_it const &it)
00325                 {
00326                         return (it.rep->get_data().attrib & _A_RDONLY) == 0;
00327                 }
00328                 template <> bool get<user_execute>(dir_it const &it)
00329                 {
00330                         std::string name(*it);
00331                         std::string ext(name.substr(name.find_last_of('.')));
00332                         return ext == ".exe" || ext == ".bat";
00333                 }
00334 #else
00335                 get<size>::operator size::value_type() const
00336                 {
00337                         return m_it.rep->get_data().size;
00338                 }
00339                 get<mtime>::operator mtime::value_type() const
00340                 {
00341                         return &m_it.rep->get_data().time_write;
00342                 }
00343                 get<is_directory>::operator is_directory::value_type() const
00344                 {
00345                         return (m_it.rep->get_data().attrib & _A_SUBDIR) != 0;
00346                 }
00347                 get<is_regular>::operator is_regular::value_type() const
00348                 {
00349                         return (m_it.rep->get_data().attrib & _A_SUBDIR) == 0;
00350                 }
00351                 get<is_hidden>::operator is_hidden::value_type() const
00352                 {
00353                         return (m_it.rep->get_data().attrib & _A_HIDDEN) != 0;
00354                 }
00355                 get<user_read>::operator user_read::value_type() const
00356                 {
00357                         return true;
00358                 }
00359                 get<user_write>::operator user_write::value_type() const
00360                 {
00361                         return (m_it.rep->get_data().attrib & _A_RDONLY) == 0;
00362                 }
00363                 get<user_execute>::operator user_execute::value_type() const
00364                 {
00365                         std::string name(*m_it);
00366                         std::string ext(name.substr(name.find_last_of('.')));
00367                         return ext == ".exe" || ext == ".bat";
00368                 }
00369 #endif // __MINGW32__
00370         }
00371 }
00372 #endif
00373 
00374 // -------------------------------------------------------------------------- 
00375 
00376 boost::filesystem::dir_it::dir_it():
00377         rep(new representation())
00378 {
00379 }
00380 
00381 boost::filesystem::dir_it::dir_it(std::string const &dirname):
00382         rep(new representation(dirname))
00383 {
00384 }
00385 
00386 boost::filesystem::dir_it::dir_it(boost::filesystem::dir_it const &it):
00387         rep(it.rep->reference())
00388 {
00389 }
00390 
00391 boost::filesystem::dir_it::~dir_it()
00392 {
00393         delete rep->release();
00394 }
00395 
00396 boost::filesystem::dir_it &boost::filesystem::dir_it::operator= (boost::filesystem::dir_it const &it)
00397 {
00398         it.rep->reference();
00399         delete rep->release();
00400         rep = it.rep;
00401         return *this;
00402 }
00403 
00404 // -------------------------------------------------------------------------- 
00405 
00406 std::string boost::filesystem::dir_it::operator* () const
00407 {
00408         return *(*rep);
00409 }
00410 
00411 boost::filesystem::dir_it &boost::filesystem::dir_it::operator++ ()
00412 {
00413         ++(*rep);
00414         return *this;
00415 }
00416 
00417 boost::filesystem::dir_it::proxy boost::filesystem::dir_it::operator++ (int)
00418 {
00419         std::string rc(*(*rep));
00420         ++(*rep);
00421         return rc;
00422 }
00423 
00424 // -------------------------------------------------------------------------- 
00425 
00426 bool boost::filesystem::dir_it::operator== (boost::filesystem::dir_it const &it) const
00427 {
00428         return *rep == *(it.rep);
00429 }
00430 
00431 bool boost::filesystem::dir_it::operator!= (boost::filesystem::dir_it const &it) const
00432 {
00433         return !(*rep == *(it.rep));
00434 }

Generated on Wed Nov 23 19:00:05 2011 for FreeCAD by  doxygen 1.6.1