This machine mirrors various open-source projects.
20 Gbit/s uplink.
If there are any issues or you want another project mirrored, please contact
mirror-service -=AT=- netcologne DOT de !
00001 // $Id: unix_system.cxx,v 1.11 2003/01/12 19:06:08 grumbel Exp $ 00002 // 00003 // Construo - A wire-frame construction game 00004 // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de> 00005 // 00006 // This program is free software; you can redistribute it and/or 00007 // modify it under the terms of the GNU General Public License 00008 // as published by the Free Software Foundation; either version 2 00009 // of the License, or (at your option) any later version. 00010 // 00011 // This program is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU General Public License 00017 // along with this program; if not, write to the Free Software 00018 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 { // riped out of ClanLib-0.7 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 // create $HOME directory if not already there 00057 struct stat buf; 00058 00059 if (stat(construo_rc_path.c_str(), &buf) != 0) // Couldn't find directory, create it 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)) // Is not a directory 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) // not readable/writeable 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 { // riped out of ClanLib-0.7 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 // FIXME: Error checking here 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 { // We ignore unusefull directories 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 /* EOF */