blob: 31371c16cc666fae3f17f3671c4f2db9eff78ecd [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "spec_utils.h"
#include <dirent.h>
#include <errno.h>
#include <glog/logging.h>
#include <limits.h>
#include <string>
#include <sys/stat.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
int DeleteDir(std::string dirname) {
DLOG(INFO) << "Deleting: " << dirname;
DIR* dir = opendir(dirname.c_str());
if (dir == NULL) {
return errno;
}
struct dirent* de;
struct stat stat_buf;
while ((de = readdir(dir)) != NULL) {
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
continue;
}
std::string name = dirname + "/" + de->d_name;
if (stat(name.c_str(), &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode)) {
if (DeleteDir(name) != 0) {
return errno;
}
} else {
if (unlink(name.c_str()) != 0) {
return errno;
}
}
}
if (closedir(dir) != 0) {
return errno;
}
if (rmdir(dirname.c_str()) != 0) {
return errno;
}
return 0;
}
int CopyDir(std::string dest_dirname, std::string src_dirname) {
DIR* dir = opendir(src_dirname.c_str());
if (dir == NULL) {
return errno;
}
DLOG(INFO) << "Copy " << src_dirname << " to " << dest_dirname;
struct dirent* de;
struct stat stat_buf;
while ((de = readdir(dir)) != NULL) {
std::string name = src_dirname + "/" + de->d_name;
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
continue;
}
if (stat(name.c_str(), &stat_buf) != 0) {
return errno;
}
if (S_ISDIR(stat_buf.st_mode)) {
std::string sub_dir = dest_dirname + "/" + de->d_name;
if (mkdir(sub_dir.c_str(), 0600) != 0) {
return errno;
}
if (CopyDir(sub_dir, name) != 0) {
return errno;
}
} else if (S_ISREG(stat_buf.st_mode)) {
if (CopyFile(dest_dirname + "/" + de->d_name, name) != 0) {
return errno;
}
}
}
if (closedir(dir) != 0) {
return errno;
}
return 0;
}
int CopyFile(std::string dest, std::string src) {
int page_size = getpagesize();
char buf[page_size];
size_t size;
DLOG(INFO) << "Copy " << src << " to " << dest;
FILE* srcfile = fopen(src.c_str(), "rb");
if (srcfile == NULL) {
return errno;
}
FILE* destfile = fopen(dest.c_str(), "wb");
if (destfile == NULL) {
return errno;
}
while ((size = fread(buf, 1, page_size, srcfile))) {
if (fwrite(buf, 1, size, destfile) != size) {
return errno;
}
}
if (fclose(srcfile) != 0) {
return errno;
}
if (fflush(destfile) != 0) {
return errno;
}
if (fclose(destfile) != 0) {
return errno;
}
return 0;
}