148 lines
3.6 KiB
C++
148 lines
3.6 KiB
C++
#include "fs.h"
|
|
#include "files.h"
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <dirent.h>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <host/CopyFile.h>
|
|
|
|
using namespace std;
|
|
|
|
static bool
|
|
is_dir(const string& path)
|
|
{
|
|
int err;
|
|
struct stat st;
|
|
err = stat(path.c_str(), &st);
|
|
return err != 0 || S_ISDIR(st.st_mode);
|
|
}
|
|
|
|
static int
|
|
remove_file(const string& path)
|
|
{
|
|
int err = unlink(path.c_str());
|
|
if (err != 0) {
|
|
fprintf(stderr, "error deleting file %s (%s)\n", path.c_str(),
|
|
strerror(errno));
|
|
return errno;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
remove_recursively(const string& path)
|
|
{
|
|
int err;
|
|
|
|
if (is_dir(path)) {
|
|
DIR *d = opendir(path.c_str());
|
|
if (d == NULL) {
|
|
fprintf(stderr, "error getting directory contents %s (%s)\n",
|
|
path.c_str(), strerror(errno));
|
|
return errno;
|
|
}
|
|
|
|
vector<string> files;
|
|
vector<string> dirs;
|
|
|
|
struct dirent *ent;
|
|
while (NULL != (ent = readdir(d))) {
|
|
if (0 == strcmp(".", ent->d_name)
|
|
|| 0 == strcmp("..", ent->d_name)) {
|
|
continue;
|
|
}
|
|
string full = path;
|
|
full += '/';
|
|
full += ent->d_name;
|
|
#ifdef HAVE_DIRENT_D_TYPE
|
|
bool is_directory = (ent->d_type == DT_DIR);
|
|
#else
|
|
// If dirent.d_type is missing, then use stat instead
|
|
struct stat stat_buf;
|
|
stat(full.c_str(), &stat_buf);
|
|
bool is_directory = S_ISDIR(stat_buf.st_mode);
|
|
#endif
|
|
if (is_directory) {
|
|
dirs.push_back(full);
|
|
} else {
|
|
files.push_back(full);
|
|
}
|
|
}
|
|
closedir(d);
|
|
|
|
for (vector<string>::iterator it=files.begin(); it!=files.end(); it++) {
|
|
err = remove_file(*it);
|
|
if (err != 0) {
|
|
return err;
|
|
}
|
|
}
|
|
|
|
for (vector<string>::iterator it=dirs.begin(); it!=dirs.end(); it++) {
|
|
err = remove_recursively(*it);
|
|
if (err != 0) {
|
|
return err;
|
|
}
|
|
}
|
|
|
|
err = rmdir(path.c_str());
|
|
if (err != 0) {
|
|
fprintf(stderr, "error deleting directory %s (%s)\n", path.c_str(),
|
|
strerror(errno));
|
|
return errno;
|
|
}
|
|
return 0;
|
|
} else {
|
|
return remove_file(path);
|
|
}
|
|
}
|
|
|
|
int
|
|
mkdir_recursively(const string& path)
|
|
{
|
|
int err;
|
|
size_t pos = 0;
|
|
// For absolute pathnames, that starts with leading '/'
|
|
// use appropriate initial value.
|
|
if (path.length() != 0 and path[0] == '/') pos++;
|
|
|
|
while (true) {
|
|
pos = path.find('/', pos);
|
|
string p = path.substr(0, pos);
|
|
struct stat st;
|
|
err = stat(p.c_str(), &st);
|
|
if (err != 0) {
|
|
err = mkdir(p.c_str(), 0770);
|
|
if (err != 0) {
|
|
fprintf(stderr, "can't create directory %s (%s)\n",
|
|
path.c_str(), strerror(errno));
|
|
return errno;
|
|
}
|
|
}
|
|
else if (!S_ISDIR(st.st_mode)) {
|
|
fprintf(stderr, "can't create directory %s because %s is a file.\n",
|
|
path.c_str(), p.c_str());
|
|
return 1;
|
|
}
|
|
pos++;
|
|
if (p == path) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
int
|
|
copy_file(const string& src, const string& dst)
|
|
{
|
|
int err;
|
|
|
|
err = copyFile(src.c_str(), dst.c_str(),
|
|
COPY_NO_DEREFERENCE | COPY_FORCE | COPY_PERMISSIONS);
|
|
return err;
|
|
}
|