diff options
Diffstat (limited to 'hscript')
-rw-r--r-- | hscript/meta.cc | 36 | ||||
-rw-r--r-- | hscript/meta.hh | 11 | ||||
-rw-r--r-- | hscript/script.cc | 3 | ||||
-rw-r--r-- | hscript/script_e.cc | 12 | ||||
-rw-r--r-- | hscript/script_i.hh | 13 |
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) { |