Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

vul_file.cxx

Go to the documentation of this file.
00001 // This is core/vul/vul_file.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 //
00008 // \author Andrew W. Fitzgibbon, Oxford RRG
00009 // \date   02 Nov 98
00010 //
00011 //-----------------------------------------------------------------------------
00012 
00013 #include "vul_file.h"
00014 
00015 #include <sys/stat.h>
00016 #include <vcl_cstring.h>
00017 #include <vcl_cstdlib.h>
00018 
00019 #if defined(VCL_WIN32) && !defined(__CYGWIN__)
00020 #include <direct.h> // for getcwd, mkdir
00021 #else
00022 #include <unistd.h>
00023 #endif
00024 
00025 #if defined(como4301) && defined(__linux__)
00026 # ifndef S_IFMT
00027 #  define S_IFMT 0170000
00028 # endif
00029 # ifndef S_IFDIR
00030 #  define S_IFDIR 0040000
00031 # endif
00032 #endif
00033 
00034 #include <vul/vul_user_info.h>
00035 
00036 vcl_string vul_file::get_cwd()
00037 {
00038   const int BIG = 65536;
00039   char buf[BIG];
00040   getcwd(buf,BIG-1);
00041   return buf;
00042 }
00043 
00044 bool vul_file::change_directory(char const* dirname)
00045 {
00046   return 0 == chdir(dirname);
00047 }
00048 
00049 bool vul_file::make_directory(char const* name)
00050 {
00051 #if defined(VCL_WIN32) && !defined(__CYGWIN__)
00052   return -1 != mkdir(name);
00053 #else
00054   return -1 != mkdir(name, 0755);
00055 #endif
00056 }
00057 
00058 bool vul_file::is_directory(char const* fn)
00059 {
00060   struct stat fs;
00061   return stat(fn, &fs) == 0 && (fs.st_mode & S_IFMT) == S_IFDIR;
00062 }
00063 
00064 //: Make a writable directory, including any necessary parents.
00065 // Returns true if successful, or if the directory alredy exists.
00066 bool vul_file::make_directory_path(char const* filename)
00067 {
00068   if (is_directory(filename)) return true;
00069   if (!make_directory_path(dirname(filename))) return false;
00070   return make_directory(filename);
00071 }
00072 
00073 
00074 unsigned long vul_file::size(char const* fn)
00075 {
00076   struct stat fs;
00077   if (stat(fn, &fs) == 0)
00078     return fs.st_size;
00079   else
00080     return 0L;
00081 }
00082 
00083 bool vul_file::exists(char const* fn)
00084 {
00085   struct stat fs;
00086   return stat(fn, &fs) == 0;
00087 }
00088 
00089 vcl_string vul_file::dirname(char const* fn)
00090 {
00091   vcl_string self(fn);
00092 
00093 #if defined(VCL_WIN32) && !defined(__CYGWIN__)
00094   vcl_string::size_type slash_index = self.find_last_of("\\/");
00095 #else
00096   vcl_string::size_type slash_index = self.rfind('/');
00097 #endif
00098   if (slash_index == vcl_string::npos)
00099     return ".";
00100 
00101 
00102   return self.substr(0, slash_index);
00103 }
00104 
00105 vcl_string vul_file::extension(char const* fn)
00106 {
00107   vcl_string self(fn);
00108 
00109   vcl_string::size_type dot_index = self.rfind('.');
00110   if (dot_index != vcl_string::npos)
00111     return self.substr(dot_index, vcl_string::npos);
00112   else
00113     return vcl_string();
00114 }
00115 
00116 vcl_string vul_file::strip_directory(char const* fn)
00117 {
00118    vcl_string self(fn);
00119 
00120 #if defined(VCL_WIN32) && !defined(__CYGWIN__)
00121    vcl_string::size_type slash_index = self.find_last_of("\\/");
00122 #else
00123    vcl_string::size_type slash_index = self.rfind('/');
00124 #endif
00125    if (slash_index != vcl_string::npos)
00126      self.erase(0, slash_index+1);
00127 
00128    return self;
00129 }
00130 
00131 vcl_string vul_file::strip_extension(char const* fn)
00132 {
00133   vcl_string self(fn);
00134 
00135   vcl_string::size_type dot_index = self.rfind('.');
00136   if (dot_index != vcl_string::npos)
00137     self.erase(dot_index, vcl_string::npos);
00138 
00139   return self;
00140 }
00141 
00142 vcl_string vul_file::basename(char const* fn, char const * suffix)
00143 {
00144   // First strip dir
00145   vcl_string self(fn);
00146 
00147 #if defined(VCL_WIN32) && !defined(__CYGWIN__)
00148   vcl_string::size_type slash_index = self.find_last_of("\\/");
00149 #else
00150   vcl_string::size_type slash_index = self.rfind('/');
00151 #endif
00152 
00153   if (slash_index != vcl_string::npos)
00154     self.erase(0, slash_index+1);
00155 
00156   // Now strip suffix if any
00157   if (suffix) {
00158     int start = self.size() - vcl_strlen(suffix);
00159     if (start >= 0)
00160       // egcs, 2.95, 2.96 have no method which can do
00161       //   self.compare(start, vcl_string::npos, suffix) == 0
00162       if (vcl_string(self.begin()+start, self.end()) == suffix)
00163         self.erase(start, vcl_string::npos);
00164   }
00165   return self;
00166 }
00167 
00168 
00169 #if defined(VCL_WIN32) && !defined(__CYGWIN__)
00170 //: replace instances of 'from' in 's' with 'to'
00171 static unsigned replace(char from, char to, vcl_string &s)
00172 {
00173   unsigned c = 0;
00174   for (unsigned i=0; i<s.size(); ++i)
00175     if (s[i] == from)
00176     {
00177       c++;
00178       s[i] = to;
00179     }
00180     return c;
00181 }
00182 #endif
00183 
00184 //: Delete 1 or more files using the Local OS preferred globbing.
00185 // E.g. \c delete_file_glob("*"); will delete all the files in the
00186 // current directory on most operating systems.
00187 // Takes Posix path separators i.e. '/'
00188 bool vul_file::delete_file_glob(char const* file_glob)
00189 {
00190   vcl_string command = file_glob;
00191 #if defined(VCL_WIN32) && !defined(__CYGWIN__)
00192   replace('/', '\\', command);
00193   command = "del " + command;
00194 #else
00195   command = "rm " + command;
00196 #endif
00197   return vcl_system(command.c_str())==0;
00198 }
00199 
00200 
00201 vcl_string vul_file::expand_tilde(char const* vul_filename)
00202 {
00203   if (!vul_filename || (vcl_strlen(vul_filename) == 0))
00204     return "";
00205 
00206 #if defined(VCL_WIN32) && !defined(__CYGWIN__)
00207   // ~ meaningless on win32
00208   return vcl_string(vul_filename);
00209 #else
00210 
00211   if (vul_filename[0] != '~')
00212     return vcl_string(vul_filename);
00213 
00214   //// ** Have a tilde, go for it
00215 
00216   // 1. Strip to directory only, and remove the tilde itself
00217   vcl_string fn(vul_filename);
00218   vcl_string dir;
00219   vcl_string::size_type first_slash =  fn.find('/');
00220   if (first_slash != vcl_string::npos) {
00221     dir = fn.substr(1, first_slash-1);
00222     fn = fn.substr(first_slash, vcl_string::npos);
00223   } else {
00224     dir = fn.substr(1, vcl_string::npos);
00225     fn = "";
00226   }
00227   // Now, from original to  (dir, vul_filename) is one of
00228   //  ~            ""     ""
00229   //  ~fre         "fre"  ""
00230   //  ~/fred       ""     "/fred"
00231   //  ~user/fred   "user" "/fred"
00232 
00233   if (dir.size() == 0) {
00234     // Was just ~, use getenv(HOME)
00235     char const * home_directory = getenv("HOME");
00236     if (!home_directory) home_directory = "";
00237     return vcl_string(home_directory) + fn;
00238   }
00239 
00240   // Was ~user, Check password list for match
00241   vul_user_info user(dir);
00242   if (!user.ok)
00243     return vcl_string(vul_filename);
00244 
00245   // Got user info
00246   return user.home_directory + fn;
00247 #endif
00248 }

Generated on Thu Jan 10 14:41:00 2008 for core/vul by  doxygen 1.4.4