00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdio.h>
00021 #include <unistd.h>
00022 #include <sys/time.h>
00023 #include <time.h>
00024 #include <string>
00025 #include <sys/stat.h>
00026 #include <sys/types.h>
00027 #include <dirent.h>
00028 #include <pwd.h>
00029 #include <errno.h>
00030 #include <iostream>
00031 #include <algorithm>
00032 #include "construo_error.hxx"
00033 #include "string_utils.hxx"
00034 #include "construo.hxx"
00035 #include "unix_system.hxx"
00036
00037 using namespace StringUtils;
00038
00039 UnixSystem::UnixSystem ()
00040 {
00041 timeval tv;
00042 gettimeofday(&tv, NULL);
00043 start_time = (long) tv.tv_sec*(long) 1000+(long) tv.tv_usec/(long) 1000;
00044
00045 char* home = getenv("HOME");
00046 if (home)
00047 {
00048 construo_rc_path = std::string(home) + std::string("/.construo/");
00049 }
00050 else
00051 {
00052 std::cout << "UnixSystem: FATAL ERROR: couldn't find env variable $HOME" << std::endl;
00053 throw ConstruoError ("UnixSystem: Couldn't find $HOME!");
00054 }
00055
00056
00057 struct stat buf;
00058
00059 if (stat(construo_rc_path.c_str(), &buf) != 0)
00060 {
00061 if (mkdir(construo_rc_path.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) != 0)
00062 {
00063 throw ConstruoError(std::string("UnixSystem: ") + construo_rc_path + ": "
00064 + strerror(errno));
00065 }
00066 }
00067 else
00068 {
00069 if (S_ISDIR(buf.st_rdev))
00070 {
00071 throw ConstruoError("Error: " + construo_rc_path + " is not a directory!");
00072 }
00073
00074 if (access(construo_rc_path.c_str (), R_OK | W_OK | X_OK) != 0)
00075 {
00076 throw ConstruoError("Error: " + construo_rc_path + " is not read or writeable!");
00077 }
00078 }
00079 }
00080
00081 UnixSystem::~UnixSystem ()
00082 {
00083 }
00084
00085 unsigned int
00086 UnixSystem::get_time ()
00087 {
00088 timeval tv;
00089 gettimeofday(&tv, NULL);
00090
00091 long tid = (long) tv.tv_sec*(long) 1000 + (long) tv.tv_usec/(long) 1000 - start_time;
00092
00093 return tid;
00094 }
00095
00096 void
00097 UnixSystem::sleep (unsigned long t)
00098 {
00099 usleep (t);
00100 }
00101
00102 std::string
00103 UnixSystem::get_construo_rc_path()
00104 {
00105 std::cout << "Returning: \n" << construo_rc_path << std::endl;
00106 return construo_rc_path;
00107 }
00108
00109 std::string
00110 UnixSystem::get_user_realname()
00111 {
00112 struct passwd* pw;
00113
00114 pw = getpwuid(getuid());
00115 if (pw)
00116 {
00117 return pw->pw_gecos;
00118 }
00119 else
00120 {
00121 return "";
00122 }
00123 }
00124
00125 std::string
00126 UnixSystem::get_user_email()
00127 {
00128 const char* s_email = getenv("EMAIL");
00129 if (s_email)
00130 {
00131 return s_email;
00132 }
00133 else
00134 return "";
00135 }
00136
00137 unsigned int
00138 UnixSystem::get_mtime (const std::string& filename)
00139 {
00140 std::string sys_name = translate_filename(filename);
00141
00142 struct stat buf;
00143 if (stat(sys_name.c_str(), &buf) != 0)
00144 {
00145 return 0;
00146 }
00147 else
00148 {
00149 return buf.st_mtime;
00150 }
00151 }
00152
00153 FileType
00154 UnixSystem::get_file_type(const std::string& filename)
00155 {
00156 if (filename == "/examples/"
00157 || filename == "/user/")
00158 return FT_DIRECTORY;
00159
00160 std::string sys_name = translate_filename(filename);
00161
00162 struct stat buf;
00163 if (stat(sys_name.c_str(), &buf) != 0)
00164 {
00165 std::cout << "UnixSystem: ERROR: Couldn't stat: '" << sys_name << "'" << std::endl;
00166 return FT_UNKNOWN_FILE;
00167 }
00168 else
00169 {
00170 if (S_ISDIR(buf.st_mode))
00171 {
00172 return FT_DIRECTORY;
00173 }
00174 else if (S_ISREG(buf.st_mode))
00175 {
00176 if (has_suffix(filename, ".construo") || has_suffix(filename, ".construo.gz"))
00177 return FT_CONSTRUO_FILE;
00178 else
00179 {
00180 return FT_UNKNOWN_FILE;
00181 }
00182 }
00183 else
00184 {
00185 return FT_UNKNOWN_FILE;
00186 }
00187 }
00188 }
00189
00190 std::string
00191 UnixSystem::translate_filename (const std::string& filename)
00192 {
00193 if (filename == "/")
00194 {
00195 assert("root directory is not translatable");
00196 return "";
00197 }
00198 else if (has_prefix(filename, "/user/"))
00199 {
00200 return "/home/ingo/.construo/" + filename.substr(6);
00201 }
00202 else if (has_prefix(filename, "/examples/"))
00203 {
00204 return "examples/" + filename.substr(10);
00205 }
00206 else
00207 return filename;
00208 }
00209
00210 FILE*
00211 UnixSystem::open_input_file(const std::string& filename)
00212 {
00213 std::cout << "UnixSystem: open_input_file: " << translate_filename (filename) << std::endl;
00214 return fopen(translate_filename (filename).c_str(), "r");
00215 }
00216
00217 FILE*
00218 UnixSystem::open_output_file(const std::string& filename)
00219 {
00220 std::cout << "UnixSystem: open_output_file: " << translate_filename (filename) << std::endl;
00221 return fopen(translate_filename (filename).c_str(), "w");
00222 }
00223
00224
00225 struct DirectorySorter
00226 {
00227 std::string pathname;
00228
00229 DirectorySorter(const std::string& p)
00230 : pathname(p)
00231 {
00232 }
00233
00234 bool operator()(const std::string& lhs, const std::string& rhs)
00235 {
00236 FileType lhs_type = system_context->get_file_type(pathname + "/" + lhs);
00237 FileType rhs_type = system_context->get_file_type(pathname + "/" + rhs);
00238
00239 if (lhs_type == rhs_type)
00240 return (lhs < rhs);
00241 else if (lhs_type == FT_DIRECTORY)
00242 {
00243 return true;
00244 }
00245 else if (rhs_type == FT_DIRECTORY)
00246 {
00247 return false;
00248 }
00249 else
00250 {
00251 return (lhs < rhs);
00252 }
00253 }
00254 };
00255
00256 std::vector<std::string>
00257 UnixSystem::read_directory(const std::string& arg_pathname)
00258 {
00259 if (arg_pathname == "/")
00260 {
00261 std::vector<std::string> ret;
00262 ret.push_back("examples/");
00263 ret.push_back("user/");
00264 return ret;
00265 }
00266 else
00267 {
00268 std::vector<std::string> dir_lst;
00269 std::string pathname = translate_filename (arg_pathname);
00270
00271 DIR* dir = ::opendir (pathname.c_str());
00272
00273 struct dirent* entry;
00274
00275 while ((entry = readdir(dir)) != 0)
00276 {
00277 if (strcmp(entry->d_name, ".") != 0
00278 && strcmp(entry->d_name, "..") != 0
00279 && strcmp(entry->d_name, "CVS") != 0)
00280 {
00281 dir_lst.push_back(entry->d_name);
00282 }
00283 }
00284
00285 closedir (dir);
00286
00287 std::sort(dir_lst.begin(), dir_lst.end(), DirectorySorter(pathname));
00288
00289 return dir_lst;
00290 }
00291 }
00292
00293