summaryrefslogtreecommitdiff
path: root/hscript
diff options
context:
space:
mode:
Diffstat (limited to 'hscript')
-rw-r--r--hscript/meta.cc36
-rw-r--r--hscript/meta.hh11
-rw-r--r--hscript/script.cc3
-rw-r--r--hscript/script_e.cc12
-rw-r--r--hscript/script_i.hh13
5 files changed, 73 insertions, 2 deletions
diff --git a/hscript/meta.cc b/hscript/meta.cc
index ee34372..8079b1a 100644
--- a/hscript/meta.cc
+++ b/hscript/meta.cc
@@ -708,6 +708,42 @@ bool Version::execute() const {
/* LCOV_EXCL_STOP */
+Key* RootShell::parseFromData(const std::string &data,
+ const ScriptLocation &pos, int *errors, int *,
+ const Script *script) {
+ if(data.at(0) != '/') {
+ if(errors) *errors += 1;
+ output_error(pos, "rootshell: invalid shell specified", data);
+ return nullptr;
+ }
+
+ return new RootShell(script, pos, data);
+}
+
+bool RootShell::execute() const {
+ auto target = script->targetDirectory();
+
+ if(script->options().test(Simulate)) {
+ std::cout << "[ -x " << target << _value << "] && "
+ << "sed -i 's#/root:/bin/sh$#/root:" << _value << "#' "
+ << target << "/etc/passwd" << std::endl;
+ }
+#ifdef HAS_INSTALL_ENV
+ else {
+ if(fs::exists(target + _value)) {
+ run_command("sed", {"-i", "s#/root:/bin/sh$#/root:" + _value + "#",
+ script->targetDirectory() + "/etc/passwd"});
+ } else {
+ output_warning(pos, "shell " + _value +
+ " not found; leaving root shell as /bin/sh");
+ }
+ }
+#endif /* HAS_INSTALL_ENV */
+
+ return true;
+}
+
+
const std::string my_arch(const Horizon::Script *script) {
const Key *arch_key = script->getOneValue("arch");
if(arch_key != nullptr) {
diff --git a/hscript/meta.hh b/hscript/meta.hh
index 32f8eb7..3d1382e 100644
--- a/hscript/meta.hh
+++ b/hscript/meta.hh
@@ -146,6 +146,17 @@ public:
bool execute() const override;
};
+class RootShell : public StringKey {
+private:
+ RootShell(const Script *_s, const ScriptLocation &_p,
+ const std::string &_v) :
+ StringKey(_s, _p, _v) {}
+public:
+ static Key *parseFromData(const std::string &, const ScriptLocation &,
+ int *, int *, const Script *);
+ bool execute() const override;
+};
+
class Bootloader : public Key {
private:
const std::string _device;
diff --git a/hscript/script.cc b/hscript/script.cc
index d86216d..0126a99 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -52,6 +52,7 @@ const std::map<std::string, key_parse_fn> valid_keys = {
{"signingkey", &SigningKey::parseFromData},
{"svcenable", &SvcEnable::parseFromData},
{"version", &Version::parseFromData},
+ {"rootshell", &RootShell::parseFromData},
{"bootloader", &Bootloader::parseFromData},
{"netconfigtype", &NetConfigType::parseFromData},
@@ -129,6 +130,8 @@ bool Script::ScriptPrivate::store_key(const std::string &key_name, Key *obj,
return store_svcenable(obj, pos, errors, warnings, opts);
} else if(key_name == "version") {
return store_version(obj, pos, errors, warnings, opts);
+ } else if(key_name == "rootshell") {
+ return store_rootshell(obj, pos, errors, warnings, opts);
} else if(key_name == "bootloader") {
return store_bootloader(obj, pos, errors, warnings, opts);
} else if(key_name == "username") {
diff --git a/hscript/script_e.cc b/hscript/script_e.cc
index 50f92e1..738bfed 100644
--- a/hscript/script_e.cc
+++ b/hscript/script_e.cc
@@ -647,8 +647,12 @@ bool Script::execute() const {
if(internal->keymap) {
EXECUTE_OR_FAIL("keymap", internal->keymap)
- fs::create_symlink("/etc/init.d/keymaps",
- targ_etc + "/runlevels/default/keymaps", ec);
+#ifdef HAS_INSTALL_ENV
+ if(!opts.test(Simulate)) {
+ fs::create_symlink("/etc/init.d/keymaps",
+ targ_etc + "/runlevels/default/keymaps", ec);
+ }
+#endif /* HAS_INSTALL_ENV */
}
for(auto &acct : internal->accounts) {
@@ -697,6 +701,10 @@ bool Script::execute() const {
}
#endif
+ if(internal->root_shell) {
+ EXECUTE_OR_FAIL("rootshell", internal->root_shell)
+ }
+
if(internal->boot) {
EXECUTE_OR_FAIL("bootloader", internal->boot)
}
diff --git a/hscript/script_i.hh b/hscript/script_i.hh
index 12ec133..641c749 100644
--- a/hscript/script_i.hh
+++ b/hscript/script_i.hh
@@ -65,6 +65,8 @@ struct Script::ScriptPrivate {
std::unique_ptr<Version> version;
/*! The desired bootloader configuration. */
std::unique_ptr<Bootloader> boot;
+ /*! The desired root shell. */
+ std::unique_ptr<RootShell> root_shell;
/*! Network addressing configuration */
std::vector< std::unique_ptr<NetAddress> > addresses;
@@ -297,6 +299,17 @@ struct Script::ScriptPrivate {
return true;
}
+ bool store_rootshell(Key *obj, const ScriptLocation &pos, int *errors,
+ int *, const ScriptOptions &) {
+ if(root_shell) {
+ DUPLICATE_ERROR(root_shell, "rootshell", root_shell->value())
+ return false;
+ }
+ std::unique_ptr<RootShell> r(dynamic_cast<RootShell *>(obj));
+ root_shell = std::move(r);
+ return true;
+ }
+
bool store_bootloader(Key *obj, const ScriptLocation &pos, int *errors,
int *, const ScriptOptions &) {
if(boot) {