00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <unistd.h>
00021 #include <errno.h>
00022 #include <string.h>
00023 #include <sys/types.h>
00024 #include <sys/stat.h>
00025 #include <dirent.h>
00026
00027 #include <string>
00028
00029 #include <archon/util/file.H>
00030
00031 using namespace std;
00032
00033 static size_t maxBufferSize = 32767-1024;
00034
00035 namespace Archon
00036 {
00037 namespace Utilities
00038 {
00039 namespace File
00040 {
00041 string getCWD()
00042 {
00043 size_t bufferSize = 1024;
00044 char *buffer;
00045 for(;;)
00046 {
00047 buffer = new char[bufferSize];
00048 if(getcwd(buffer, bufferSize)) break;
00049 if(errno != ERANGE)
00050 {
00051 delete[] buffer;
00052 ARCHON_THROW1(ResourceException,
00053 string("Utilities::File::getCWD: 'getcwd' failed: ") +
00054 strerror(errno));
00055 }
00056
00057 delete[] buffer;
00058 bufferSize += 1024;
00059 if(bufferSize > maxBufferSize)
00060 ARCHON_THROW1(ResourceException,
00061 "System::File::getCWD: Path is too long");
00062 }
00063 const string result = buffer;
00064 delete[] buffer;
00065 return result;
00066 }
00067
00068 string getHomeDir()
00069 {
00070 char *s = getenv("HOME");
00071 if(!s) ARCHON_THROW1(ResourceException,
00072 "Could not determine home directory of "
00073 "the logged in user");
00074 return s;
00075 }
00076
00077 void makeDir(string path)
00078 {
00079 int error = mkdir(path.c_str(), S_IRWXU|S_IRWXG|S_IRWXO);
00080 if(error < 0)
00081 ARCHON_THROW1(ArgumentException,
00082 "'mkdir " + path + "' failed: " + strerror(errno));
00083 }
00084
00085 vector<string> getDirNames(string dirPath)
00086 {
00087 DIR *dir = opendir(dirPath.c_str());
00088 if(!dir)
00089 ARCHON_THROW1(ArgumentException,
00090 "Utilities::File::getDirNames: 'opendir " +
00091 dirPath + "' failed: " + strerror(errno));
00092
00093 vector<string> v;
00094
00095 for(;;)
00096 {
00097 dirent *e = readdir(dir);
00098 if(!e) break;
00099 v.push_back(e->d_name);
00100 }
00101
00102 closedir(dir);
00103
00104 return v;
00105 }
00106
00107 Stat::Stat(string path)
00108 {
00109 struct stat s;
00110 if(stat(path.c_str(), &s))
00111 ARCHON_THROW1(ArgumentException,
00112 "Utilities::File::Stat::Stat: 'stat " + path +
00113 "' failed: " + strerror(errno));
00114
00115 type =
00116 S_ISREG(s.st_mode) ? type_regular :
00117 S_ISDIR(s.st_mode) ? type_directory :
00118 S_ISCHR(s.st_mode) ? type_characterDevice :
00119 S_ISBLK(s.st_mode) ? type_blockDevice :
00120 S_ISFIFO(s.st_mode) ? type_fifo :
00121 S_ISLNK(s.st_mode) ? type_symbolicLink :
00122 S_ISSOCK(s.st_mode) ? type_socket : type_other;
00123 }
00124
00125 bool isRegular(string p)
00126 {
00127 try
00128 {
00129 Stat s(p);
00130 return s.getType() == Stat::type_regular;
00131 }
00132 catch(ArgumentException &)
00133 {
00134 return false;
00135 }
00136 }
00137
00138 bool isDir(string p)
00139 {
00140 try
00141 {
00142 Stat s(p);
00143 return s.getType() == Stat::type_directory;
00144 }
00145 catch(ArgumentException &)
00146 {
00147 return false;
00148 }
00149 }
00150
00151 bool isSymbolicLink(string p)
00152 {
00153 try
00154 {
00155 Stat s(p);
00156 return s.getType() == Stat::type_symbolicLink;
00157 }
00158 catch(ArgumentException &)
00159 {
00160 return false;
00161 }
00162 }
00163
00164 string nameOf(string filePath)
00165 {
00166 const string::size_type p = filePath.rfind('/');
00167 return p == string::npos ? filePath : string(filePath, p+1);
00168 }
00169
00170 string suffixOf(string filePath)
00171 {
00172 const string name = nameOf(filePath);
00173 const string::size_type p = name.rfind('.');
00174 return p == string::npos ? "" : string(name, p+1);
00175 }
00176 }
00177 }
00178 }