summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2019-10-27 08:04:43 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2019-10-27 08:04:43 -0500
commitad413ebf14fb097ebe663676003854accdcc9958 (patch)
treeaf48fbf418ff264bf2475046159edaaea8d826bc
parent1fdc18eb819b85cf54d80418892ac3dc1ad5a05c (diff)
downloadhorizon-ad413ebf14fb097ebe663676003854accdcc9958.tar.gz
horizon-ad413ebf14fb097ebe663676003854accdcc9958.tar.bz2
horizon-ad413ebf14fb097ebe663676003854accdcc9958.tar.xz
horizon-ad413ebf14fb097ebe663676003854accdcc9958.zip
hscript: Use boost::filesystem everywhere convenient
-rw-r--r--hscript/disk.cc46
-rw-r--r--hscript/meta.cc49
2 files changed, 60 insertions, 35 deletions
diff --git a/hscript/disk.cc b/hscript/disk.cc
index c02d4c8..784db24 100644
--- a/hscript/disk.cc
+++ b/hscript/disk.cc
@@ -17,10 +17,11 @@
#ifdef HAS_INSTALL_ENV
# include <assert.h> /* assert */
# include <blkid/blkid.h> /* blkid_get_tag_value */
+# include <boost/filesystem.hpp>
# include <libudev.h> /* udev_* */
# include <parted/parted.h> /* ped_* */
# include <sys/mount.h> /* mount */
-# include <sys/stat.h> /* mkdir, stat */
+# include <sys/stat.h> /* stat */
# include <sys/types.h> /* S_* */
# include <unistd.h> /* access */
#endif /* HAS_INSTALL_ENV */
@@ -29,6 +30,9 @@
using namespace Horizon::Keys;
+namespace fs = boost::filesystem;
+using boost::system::error_code;
+
#ifdef HAS_INSTALL_ENV
/*! Determine if _block is a valid block device.
@@ -424,7 +428,7 @@ bool Partition::execute(ScriptOptions) const {
Key *LVMPhysical::parseFromData(const std::string &data, int lineno,
- int *errors, int *warnings) {
+ int *errors, int *) {
if(data.size() < 6 || data.substr(0, 5) != "/dev/") {
if(errors) *errors += 1;
output_error("installfile:" + std::to_string(lineno),
@@ -432,12 +436,6 @@ Key *LVMPhysical::parseFromData(const std::string &data, int lineno,
return nullptr;
}
- /*if(access(data.c_str(), F_OK) != 0) {
- if(warnings) *warnings += 1;
- output_warning("installfile:" + std::to_string(lineno),
- "lvm_pv: device may not exist");
- }*/
-
return new LVMPhysical(lineno, data);
}
@@ -508,6 +506,9 @@ bool Mount::validate(ScriptOptions options) const {
bool Mount::execute(ScriptOptions options) const {
const std::string actual_mount = "/target" + this->mountpoint();
const char *fstype = nullptr;
+#ifdef HAS_INSTALL_ENV
+ error_code ec;
+#endif
/* We have to get the filesystem for the node. */
if(options.test(Simulate)) {
@@ -538,6 +539,15 @@ bool Mount::execute(ScriptOptions options) const {
#ifdef HAS_INSTALL_ENV
else {
/* mount */
+ if(!fs::exists(actual_mount, ec)) {
+ fs::create_directory(actual_mount, ec);
+ if(ec.failed()) {
+ output_error("installfile:" + std::to_string(this->lineno()),
+ "mount: failed to create target directory for "
+ + this->mountpoint(), ec.message());
+ return false;
+ }
+ }
if(mount(this->device().c_str(), actual_mount.c_str(), fstype, 0,
this->options().c_str()) != 0) {
output_warning("installfile:" + std::to_string(this->lineno()),
@@ -574,9 +584,23 @@ bool Mount::execute(ScriptOptions options) const {
#ifdef HAS_INSTALL_ENV
else {
if(this->mountpoint() == "/") {
- /* failure of mkdir will be handled in the !fstab_f case */
- mkdir("/target/etc",
- S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+ fs::create_directory("/target/etc", ec);
+ if(ec.failed()) {
+ output_error("installfile:" + std::to_string(this->lineno()),
+ "mount: failed to create /etc for target",
+ ec.message());
+ return false;
+ }
+ fs::permissions("/target/etc",
+ fs::perms::owner_all |
+ fs::perms::group_read | fs::perms::group_exe |
+ fs::perms::others_read | fs::perms::others_exe,
+ ec);
+ if(ec.failed()) {
+ output_warning("installfile:" + std::to_string(this->lineno()),
+ "mount: failed to set permissions for target /etc",
+ ec.message());
+ }
}
std::ofstream fstab_f("/target/etc/fstab");
if(!fstab_f) {
diff --git a/hscript/meta.cc b/hscript/meta.cc
index 66e96f2..304b9c1 100644
--- a/hscript/meta.cc
+++ b/hscript/meta.cc
@@ -16,9 +16,7 @@
#include <set>
#include <sstream>
#ifdef HAS_INSTALL_ENV
-# include <cstring> /* strerror */
-# include <errno.h> /* errno */
-# include <sys/stat.h> /* chmod */
+# include <boost/filesystem.hpp>
#endif /* HAS_INSTALL_ENV */
#include <unistd.h> /* access - used by tz code even in RT env */
#include "meta.hh"
@@ -26,6 +24,9 @@
using namespace Horizon::Keys;
+namespace fs = boost::filesystem;
+using boost::system::error_code;
+
Key *Hostname::parseFromData(const std::string &data, int lineno, int *errors,
int *) {
std::regex valid_re("[A-Za-z0-9-_.]*");
@@ -115,7 +116,7 @@ bool Hostname::execute(ScriptOptions opts) const {
}
#ifdef HAS_INSTALL_ENV
else {
- std::ofstream hostname_f("/target/etc/hostname");
+ std::ofstream hostname_f("/target/etc/hostname", std::ios_base::trunc);
if(!hostname_f) {
output_error("installfile:" + std::to_string(this->lineno()),
"hostname: could not open /etc/hostname for writing");
@@ -137,7 +138,8 @@ bool Hostname::execute(ScriptOptions opts) const {
}
#ifdef HAS_INSTALL_ENV
else {
- std::ofstream net_conf_f("/target/etc/conf.d/net");
+ std::ofstream net_conf_f("/target/etc/conf.d/net",
+ std::ios_base::app);
if(!net_conf_f) {
output_error("installfile:" + std::to_string(this->lineno()),
"hostname: could not open /etc/conf.d/net for "
@@ -226,7 +228,7 @@ const std::set<std::string> valid_langs = {
Key *Language::parseFromData(const std::string &data, int lineno, int *errors,
- int *warnings) {
+ int *) {
if(data.length() < 2 ||
valid_langs.find(data.substr(0, 2)) == valid_langs.end()) {
if(errors) *errors += 1;
@@ -279,7 +281,8 @@ bool Language::execute(ScriptOptions opts) const {
#ifdef HAS_INSTALL_ENV
const char *lang_path = "/target/etc/profile.d/language.sh";
- std::ofstream lang_f(lang_path);
+ std::ofstream lang_f(lang_path, std::ios_base::trunc);
+ error_code ec;
if(!lang_f) {
output_error("installfile:" + std::to_string(this->lineno()),
"language: could not open /etc/profile.d/language.sh "
@@ -290,11 +293,14 @@ bool Language::execute(ScriptOptions opts) const {
<< this->value() << "\"" << std::endl;
lang_f.close();
- if(chmod(lang_path,
- S_IRUSR | S_IWUSR | S_IXUSR | S_IXGRP | S_IXOTH) != 0) {
+ fs::permissions(lang_path,
+ fs::perms::owner_all |
+ fs::perms::group_read | fs::perms::group_exe |
+ fs::perms::others_read | fs::perms::others_exe, ec);
+ if(ec.failed()) {
output_error("installfile:" + std::to_string(this->lineno()),
"language: could not set /etc/profile.d/language.sh "
- "as executable", strerror(errno));
+ "as executable", ec.message());
return false;
}
#endif /* HAS_INSTALL_ENV */
@@ -380,31 +386,26 @@ bool Timezone::execute(ScriptOptions opts) const {
#ifdef HAS_INSTALL_ENV
std::string zi_path = "/usr/share/zoneinfo/" + this->value();
std::string target_zi = "/target" + zi_path;
- if(access(target_zi.c_str(), F_OK) == 0) {
- if(symlink(zi_path.c_str(), "/target/etc/localtime") != 0) {
+ error_code ec;
+ if(fs::exists(target_zi, ec)) {
+ fs::create_symlink(zi_path, "/target/etc/localtime", ec);
+ if(ec.failed()) {
output_error("installfile:" + std::to_string(this->lineno()),
"timezone: failed to create symbolic link",
- strerror(errno));
+ ec.message());
return false;
}
return true;
} else {
/* The target doesn't have tzdata installed. We copy the zoneinfo
* file from the Horizon environment to the target. */
- std::ifstream zoneinfo(zi_path, std::ios::binary);
- if(!zoneinfo) {
+ fs::copy_file(zi_path, "/target/etc/localtime", ec);
+ if(ec.failed()) {
output_error("installfile:" + std::to_string(this->lineno()),
- "timezone: failed to open zoneinfo file");
+ "timezone: failed to prepare target environment",
+ ec.message());
return false;
}
- std::ofstream output("/target/etc/localtime");
- if(!output) {
- output_error("installfile:" + std::to_string(this->lineno()),
- "timezone: failed to prepare target environment");
- return false;
- }
-
- output << zoneinfo.rdbuf();
return true;
}
#else