file_manip.cpp

Go to the documentation of this file.
00001 
00012 #include <unistd.h>
00013 #include <sys/stat.h>
00014 #include <fcntl.h>
00015 #include <utime.h>
00016 #include <limits.h>
00017 #include <stdlib.h>
00018 
00019 #include <cstdio>
00020 #include <cerrno>
00021 #include <iostream>
00022 #include <fstream>
00023 #include <vector>
00024 
00025 #include "op_file.h"
00026 
00027 #include "file_manip.h"
00028 #include "string_manip.h"
00029 
00030 using namespace std;
00031 
00032 
00033 bool copy_file(string const & source, string const & destination)
00034 {
00035     struct stat buf;
00036     if (stat(source.c_str(), &buf))
00037         return false;
00038 
00039     if (!op_file_readable(source))
00040         return false;
00041 
00042     ifstream in(source.c_str());
00043     if (!in)
00044         return false;
00045 
00046     mode_t mode = buf.st_mode & ~S_IFMT;
00047     if (!(mode & S_IWUSR))
00048         mode |= S_IWUSR;
00049 
00050     int fd = open(destination.c_str(), O_RDWR|O_CREAT, mode);
00051     if (fd < 0)
00052         return false;
00053     close(fd);
00054 
00055 
00056     // ignore error here: a simple user can copy a root.root 744 file
00057     // but can't chown the copied file to root.
00058 
00059     // a scope to ensure out is closed before changing is mtime/atime
00060     {
00061     ofstream out(destination.c_str(), ios::trunc);
00062     if (!out)
00063         return false;
00064     out << in.rdbuf();
00065     }
00066 
00067     struct utimbuf utim;
00068     utim.actime = buf.st_atime;
00069     utim.modtime = buf.st_mtime;
00070     if (utime(destination.c_str(), &utim))
00071         return false;
00072 
00073     return true;
00074 }
00075 
00076 
00077 bool is_directory(string const & dirname)
00078 {
00079     struct stat st;
00080     return !stat(dirname.c_str(), &st) && S_ISDIR(st.st_mode);
00081 }
00082 
00083 
00084 bool is_files_identical(string const & file1, string const & file2)
00085 {
00086     struct stat st1;
00087     struct stat st2;
00088 
00089     if (stat(file1.c_str(), &st1) == 0 && stat(file2.c_str(), &st2) == 0) {
00090         if (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino)
00091             return true;
00092     }
00093 
00094     return false;
00095 }
00096 
00097 
00098 string const op_realpath(string const & name)
00099 {
00100     static char tmp[PATH_MAX];
00101     if (!realpath(name.c_str(), tmp))
00102         return name;
00103     return string(tmp);
00104 }
00105 
00106 
00107 bool op_file_readable(string const & file)
00108 {
00109     return op_file_readable(file.c_str());
00110 }
00111 
00112 static void get_pathname(const char * pathname, void * name_list)
00113 {
00114     list<string> * file_list = (list<string> *)name_list;
00115     file_list->push_back(pathname);
00116 }
00117 
00118 bool create_file_list(list<string> & file_list, string const & base_dir,
00119               string const & filter, bool recursive)
00120 {
00121     return !get_matching_pathnames(&file_list, get_pathname,
00122                        base_dir.c_str(), filter.c_str(),
00123                        recursive ? MATCH_ANY_ENTRY_RECURSION :
00124                        NO_RECURSION) ? true : false;
00125  
00126 }
00127 
00128 
00134 static string erase_trailing_path_separator(string const & path_name)
00135 {
00136     string result(path_name);
00137 
00138     while (result.length() > 1) {
00139         if (result[result.length() - 1] != '/')
00140             break;
00141         result.erase(result.length() - 1, 1);
00142     }
00143 
00144     return result;
00145 }
00146 
00147 string op_dirname(string const & file_name)
00148 {
00149     string result = erase_trailing_path_separator(file_name);
00150     if (result.find_first_of('/') == string::npos)
00151         return ".";      
00152      
00153     // catch result == "/"   
00154     if (result.length() == 1)    
00155         return result;
00156 
00157     size_t pos = result.find_last_of('/');   
00158 
00159     // "/usr" must return "/"    
00160     if (pos == 0)    
00161         pos = 1;     
00162 
00163     result.erase(pos, result.length() - pos);    
00164 
00165     // "////usr" must return "/"
00166     return erase_trailing_path_separator(result);
00167 }
00168 
00169 
00170 string op_basename(string const & path_name)
00171 {
00172     string result = erase_trailing_path_separator(path_name);
00173 
00174     // catch result == "/"
00175     if (result.length() == 1)
00176         return result;
00177 
00178     return erase_to_last_of(result, '/');
00179 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1