Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

unix_system.cxx

Go to the documentation of this file.
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 <[email protected]>
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 */

Generated on Thu Jul 24 10:24:31 2003 for Construo by doxygen1.3-rc3