Home | History | Annotate | Download | only in atree
      1 #include "fs.h"
      2 #include "files.h"
      3 #include <unistd.h>
      4 #include <sys/types.h>
      5 #include <dirent.h>
      6 #include <string>
      7 #include <vector>
      8 #include <stdio.h>
      9 #include <string.h>
     10 #include <errno.h>
     11 #include <sys/stat.h>
     12 #include <unistd.h>
     13 #include <string.h>
     14 #include <host/CopyFile.h>
     15 
     16 using namespace std;
     17 
     18 static bool
     19 is_dir(const string& path)
     20 {
     21     int err;
     22     struct stat st;
     23     err = stat(path.c_str(), &st);
     24     return err != 0 || S_ISDIR(st.st_mode);
     25 }
     26 
     27 static int
     28 remove_file(const string& path)
     29 {
     30     int err = unlink(path.c_str());
     31     if (err != 0) {
     32         fprintf(stderr, "error deleting file %s (%s)\n", path.c_str(),
     33                 strerror(errno));
     34         return errno;
     35     }
     36     return 0;
     37 }
     38 
     39 int
     40 remove_recursively(const string& path)
     41 {
     42     int err;
     43 
     44     if (is_dir(path)) {
     45         DIR *d = opendir(path.c_str());
     46         if (d == NULL) {
     47             fprintf(stderr, "error getting directory contents %s (%s)\n",
     48                     path.c_str(), strerror(errno));
     49             return errno;
     50         }
     51 
     52         vector<string> files;
     53         vector<string> dirs;
     54 
     55         struct dirent *ent;
     56         while (NULL != (ent = readdir(d))) {
     57             if (0 == strcmp(".", ent->d_name)
     58                     || 0 == strcmp("..", ent->d_name)) {
     59                 continue;
     60             }
     61             string full = path;
     62             full += '/';
     63             full += ent->d_name;
     64 #ifdef HAVE_DIRENT_D_TYPE
     65             bool is_directory = (ent->d_type == DT_DIR);
     66 #else
     67 	    	// If dirent.d_type is missing, then use stat instead
     68 			struct stat stat_buf;
     69 			stat(full.c_str(), &stat_buf);
     70 			bool is_directory = S_ISDIR(stat_buf.st_mode);
     71 #endif
     72             if (is_directory) {
     73                 dirs.push_back(full);
     74             } else {
     75                 files.push_back(full);
     76             }
     77         }
     78         closedir(d);
     79 
     80         for (vector<string>::iterator it=files.begin(); it!=files.end(); it++) {
     81             err = remove_file(*it);
     82             if (err != 0) {
     83                 return err;
     84             }
     85         }
     86 
     87         for (vector<string>::iterator it=dirs.begin(); it!=dirs.end(); it++) {
     88             err = remove_recursively(*it);
     89             if (err != 0) {
     90                 return err;
     91             }
     92         }
     93 
     94         err = rmdir(path.c_str());
     95         if (err != 0) {
     96             fprintf(stderr, "error deleting directory %s (%s)\n", path.c_str(),
     97                     strerror(errno));
     98             return errno;
     99         }
    100         return 0;
    101     } else {
    102         return remove_file(path);
    103     }
    104 }
    105 
    106 int
    107 mkdir_recursively(const string& path)
    108 {
    109     int err;
    110     size_t pos = 0;
    111     // For absolute pathnames, that starts with leading '/'
    112     // use appropriate initial value.
    113     if (path.length() != 0 and path[0] == '/') pos++;
    114 
    115     while (true) {
    116         pos = path.find('/', pos);
    117         string p = path.substr(0, pos);
    118         struct stat st;
    119         err = stat(p.c_str(), &st);
    120         if (err != 0) {
    121             err = mkdir(p.c_str(), 0770);
    122             if (err != 0) {
    123                 fprintf(stderr, "can't create directory %s (%s)\n",
    124                         path.c_str(), strerror(errno));
    125                 return errno;
    126             }
    127         }
    128         else if (!S_ISDIR(st.st_mode)) {
    129             fprintf(stderr, "can't create directory %s because %s is a file.\n",
    130                         path.c_str(), p.c_str());
    131             return 1;
    132         }
    133         pos++;
    134         if (p == path) {
    135             return 0;
    136         }
    137     }
    138 }
    139 
    140 int
    141 copy_file(const string& src, const string& dst)
    142 {
    143     int err;
    144 
    145     err = copyFile(src.c_str(), dst.c_str(),
    146                     COPY_NO_DEREFERENCE | COPY_FORCE | COPY_PERMISSIONS);
    147     return err;
    148 }
    149