Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00028 #include <config.h>
00029 #include <dirent.h>
00030 #include <drizzled/definitions.h>
00031
00032 #include <boost/foreach.hpp>
00033 #include <sys/types.h>
00034 #include <sys/stat.h>
00035 #include <unistd.h>
00036
00037 #include <strings.h>
00038 #include <limits.h>
00039
00040 #include <drizzled/cached_directory.h>
00041 #include <drizzled/util/find_ptr.h>
00042 #include <drizzled/error_t.h>
00043 #include <drizzled/error.h>
00044 #include <drizzled/errmsg_print.h>
00045
00046 using namespace std;
00047 using namespace drizzled;
00048
00049 namespace drizzled {
00050
00051 CachedDirectory::CachedDirectory() :
00052 error(0)
00053 {
00054 }
00055
00056
00057 CachedDirectory::CachedDirectory(const string &in_path) :
00058 error(0),
00059 use_full_path(false)
00060 {
00061
00062 (void) open(in_path);
00063 }
00064
00065
00066 CachedDirectory::CachedDirectory(const string& in_path, set<string>& allowed_exts) :
00067 error(0),
00068 use_full_path(false)
00069 {
00070
00071 (void) open(in_path, allowed_exts);
00072 }
00073
00074 CachedDirectory::CachedDirectory(const string& in_path, enum CachedDirectory::FILTER filter, bool use_full_path_arg) :
00075 error(0),
00076 use_full_path(use_full_path_arg)
00077 {
00078 set<string> empty;
00079
00080 (void) open(in_path, empty, filter);
00081 }
00082
00083
00084 CachedDirectory::~CachedDirectory()
00085 {
00086 BOOST_FOREACH(Entries::reference iter, entries)
00087 delete iter;
00088 }
00089
00090 bool CachedDirectory::open(const string &in_path)
00091 {
00092 set<string> empty;
00093 return open(in_path, empty);
00094 }
00095
00096 bool CachedDirectory::open(const string &in_path, set<string> &allowed_exts)
00097 {
00098 return open(in_path, allowed_exts, CachedDirectory::NONE);
00099 }
00100
00101 bool CachedDirectory::open(const string &in_path, set<string> &allowed_exts, enum CachedDirectory::FILTER filter)
00102 {
00103 DIR *dirp= opendir(in_path.c_str());
00104
00105 if (dirp == NULL)
00106 {
00107 error= errno;
00108 return false;
00109 }
00110
00111 path= in_path;
00112
00113 union {
00114 dirent entry;
00115 #ifdef __sun
00116
00117
00118
00119
00120
00121
00122
00123 char space[sizeof(dirent) + PATH_MAX + 1];
00124 #endif
00125 } buffer;
00126
00127 int retcode;
00128 dirent *result;
00129
00130 while ((retcode= readdir_r(dirp, &buffer.entry, &result)) == 0 &&
00131 result != NULL)
00132 {
00133 std::string buffered_fullpath;
00134 if (not allowed_exts.empty())
00135 {
00136 char *ptr= rindex(result->d_name, '.');
00137 if (ptr && allowed_exts.count(ptr))
00138 {
00139 entries.push_back(new Entry(result->d_name));
00140 }
00141 }
00142 else
00143 {
00144 switch (filter)
00145 {
00146 case DIRECTORY:
00147 {
00148 struct stat entrystat;
00149
00150 if (result->d_name[0] == '.')
00151 continue;
00152
00153 if (use_full_path)
00154 {
00155 buffered_fullpath.append(in_path);
00156 if (buffered_fullpath[buffered_fullpath.length()] != '/')
00157 buffered_fullpath.append(1, FN_LIBCHAR);
00158 }
00159
00160 buffered_fullpath.append(result->d_name);
00161
00162 int err= stat(buffered_fullpath.c_str(), &entrystat);
00163
00164 if (err != 0)
00165 {
00166 errmsg_printf(error::WARN, ER(ER_CANT_GET_STAT),
00167 buffered_fullpath.c_str(),
00168 errno);
00169 }
00170
00171 if (err == 0 && S_ISDIR(entrystat.st_mode))
00172 {
00173 entries.push_back(new Entry(result->d_name));
00174 }
00175 }
00176 break;
00177 case FILE:
00178 {
00179 struct stat entrystat;
00180
00181 buffered_fullpath.append(in_path);
00182 if (buffered_fullpath[buffered_fullpath.length() - 1] != '/')
00183 buffered_fullpath.append(1, FN_LIBCHAR);
00184
00185 buffered_fullpath= result->d_name;
00186
00187 stat(buffered_fullpath.c_str(), &entrystat);
00188
00189 if (S_ISREG(entrystat.st_mode))
00190 {
00191 entries.push_back(new Entry(result->d_name));
00192 }
00193 }
00194 break;
00195 case NONE:
00196 case MAX:
00197 entries.push_back(new Entry(result->d_name));
00198 break;
00199 }
00200 }
00201 }
00202
00203 closedir(dirp);
00204 error= retcode;
00205
00206 return error == 0;
00207 }
00208
00209 std::ostream& operator<<(std::ostream& output, const CachedDirectory &directory)
00210 {
00211 output << "CachedDirectory:(Path: " << directory.getPath() << ")\n";
00212 BOOST_FOREACH(const CachedDirectory::Entry* iter, directory.getEntries())
00213 output << "\t(" << iter->filename << ")\n";
00214 return output;
00215 }
00216
00217 }