• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
is_dir(const string & path)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
remove_file(const string & path)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
remove_recursively(const string & path)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
mkdir_recursively(const string & path)107 mkdir_recursively(const string& path)
108 {
109     int err;
110     size_t pos = 0;
111     while (true) {
112         pos = path.find('/', pos);
113         string p = path.substr(0, pos);
114         struct stat st;
115         err = stat(p.c_str(), &st);
116         if (err != 0) {
117             err = mkdir(p.c_str(), 0770);
118             if (err != 0) {
119                 fprintf(stderr, "can't create directory %s (%s)\n",
120                         path.c_str(), strerror(errno));
121                 return errno;
122             }
123         }
124         else if (!S_ISDIR(st.st_mode)) {
125             fprintf(stderr, "can't create directory %s because %s is a file.\n",
126                         path.c_str(), p.c_str());
127             return 1;
128         }
129         pos++;
130         if (p == path) {
131             return 0;
132         }
133     }
134 }
135 
136 int
copy_file(const string & src,const string & dst)137 copy_file(const string& src, const string& dst)
138 {
139     int err;
140 
141     err = copyFile(src.c_str(), dst.c_str(),
142                     COPY_NO_DEREFERENCE | COPY_FORCE | COPY_PERMISSIONS);
143     return err;
144 }
145