diff options
-rw-r--r-- | hscript/disk.cc | 70 | ||||
-rw-r--r-- | hscript/disk.hh | 105 | ||||
-rw-r--r-- | hscript/disk_lvm.cc | 32 | ||||
-rw-r--r-- | hscript/key.cc | 6 | ||||
-rw-r--r-- | hscript/key.hh | 23 | ||||
-rw-r--r-- | hscript/meta.cc | 85 | ||||
-rw-r--r-- | hscript/meta.hh | 91 | ||||
-rw-r--r-- | hscript/network.cc | 44 | ||||
-rw-r--r-- | hscript/network.hh | 48 | ||||
-rw-r--r-- | hscript/script.cc | 7 | ||||
-rw-r--r-- | hscript/script_e.cc | 6 | ||||
-rw-r--r-- | hscript/script_v.cc | 70 | ||||
-rw-r--r-- | hscript/user.cc | 62 | ||||
-rw-r--r-- | hscript/user.hh | 69 |
14 files changed, 382 insertions, 336 deletions
diff --git a/hscript/disk.cc b/hscript/disk.cc index bef0b73..e1111f6 100644 --- a/hscript/disk.cc +++ b/hscript/disk.cc @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -62,7 +62,7 @@ bool is_block_device(const std::string &key, long line, Key *DiskId::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { std::string block, ident; std::string::size_type block_end = data.find_first_of(' '); if(block_end == std::string::npos) { @@ -75,13 +75,13 @@ Key *DiskId::parseFromData(const std::string &data, int lineno, int *errors, block = data.substr(0, block_end); ident = data.substr(block_end + 1); - return new DiskId(lineno, block, ident); + return new DiskId(script, lineno, block, ident); } -bool DiskId::validate(ScriptOptions options) const { +bool DiskId::validate() const { #ifdef HAS_INSTALL_ENV /* We only validate if running in an Installation Environment. */ - if(options.test(InstallEnvironment)) { + if(script->options().test(InstallEnvironment)) { /* Unlike 'mount', 'diskid' *does* require that the block device exist * before installation begins. This test is always valid. */ return is_block_device("diskid", this->lineno(), _block); @@ -91,14 +91,14 @@ bool DiskId::validate(ScriptOptions options) const { return true; } -bool DiskId::execute(ScriptOptions options) const { +bool DiskId::execute() const { bool match = false; output_info("installfile:" + std::to_string(line), "diskid: Checking " + _block + " for identification string " + _ident); - if(!options.test(InstallEnvironment)) return true; + if(!script->options().test(InstallEnvironment)) return true; #ifdef HAS_INSTALL_ENV struct udev *udev; @@ -156,7 +156,7 @@ bool DiskId::execute(ScriptOptions options) const { Key *DiskLabel::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { std::string block, label; std::string::size_type sep = data.find_first_of(' '); LabelType type; @@ -188,13 +188,13 @@ Key *DiskLabel::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; } - return new DiskLabel(lineno, block, type); + return new DiskLabel(script, lineno, block, type); } -bool DiskLabel::validate(ScriptOptions options) const { +bool DiskLabel::validate() const { #ifdef HAS_INSTALL_ENV /* REQ: Runner.Validate.disklabel.Block */ - if(options.test(InstallEnvironment)) { + if(script->options().test(InstallEnvironment)) { /* disklabels are created before any others, so we can check now */ return is_block_device("disklabel", this->lineno(), _block); } @@ -203,7 +203,7 @@ bool DiskLabel::validate(ScriptOptions options) const { return true; } -bool DiskLabel::execute(ScriptOptions options) const { +bool DiskLabel::execute() const { std::string type_str; switch(this->type()) { case APM: @@ -221,7 +221,7 @@ bool DiskLabel::execute(ScriptOptions options) const { "disklabel: creating new " + type_str + " disklabel on " + device()); - if(options.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "parted -ms " << this->device() << " mklabel " << type_str << std::endl; return true; @@ -262,7 +262,7 @@ bool DiskLabel::execute(ScriptOptions options) const { Key *Encrypt::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { std::string::size_type sep = data.find(' '); std::string dev, pass; @@ -280,14 +280,14 @@ Key *Encrypt::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; } - return new Encrypt(lineno, dev, pass); + return new Encrypt(script, lineno, dev, pass); } -bool Encrypt::validate(ScriptOptions) const { +bool Encrypt::validate() const { return true; } -bool Encrypt::execute(ScriptOptions) const { +bool Encrypt::execute() const { return false; } @@ -397,7 +397,7 @@ bool parse_size_string(const std::string &in_size, uint64_t *out_size, Key *Partition::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { std::string block, pno, size_str, typecode; std::string::size_type next_pos, last_pos; int part_no; @@ -471,12 +471,12 @@ Key *Partition::parseFromData(const std::string &data, int lineno, int *errors, } } - return new Partition(lineno, block, part_no, size_type, size, type); + return new Partition(script, lineno, block, part_no, size_type, size, type); } -bool Partition::validate(ScriptOptions opts) const { +bool Partition::validate() const { #ifdef HAS_INSTALL_ENV - if(opts.test(InstallEnvironment)) { + if(script->options().test(InstallEnvironment)) { /* REQ: Runner.Validate.partition.Block */ return is_block_device("partition", this->lineno(), this->device()); } @@ -484,12 +484,12 @@ bool Partition::validate(ScriptOptions opts) const { return true; } -bool Partition::execute(ScriptOptions opts) const { +bool Partition::execute() const { output_info("installfile:" + std::to_string(this->lineno()), "partition: creating partition #" + std::to_string(_partno) + " on " + _block); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { output_error("installfile:" + std::to_string(this->lineno()), "partition: Not supported in Simulation mode"); return true; @@ -610,7 +610,7 @@ const static std::set<std::string> valid_fses = { Key *Filesystem::parseFromData(const std::string &data, int lineno, - int *errors, int *) { + int *errors, int *, const Script *script) { if(std::count(data.begin(), data.end(), ' ') != 1) { if(errors) *errors += 1; output_error("installfile:" + std::to_string(lineno), @@ -659,15 +659,15 @@ Key *Filesystem::parseFromData(const std::string &data, int lineno, type = XFS; } - return new Filesystem(lineno, device, type); + return new Filesystem(script, lineno, device, type); } -bool Filesystem::validate(ScriptOptions) const { +bool Filesystem::validate() const { /* Validation is done during parsing. */ return true; } -bool Filesystem::execute(ScriptOptions opts) const { +bool Filesystem::execute() const { std::string cmd; std::vector<std::string> args; @@ -712,7 +712,7 @@ bool Filesystem::execute(ScriptOptions opts) const { args.push_back(_block); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << cmd; for(auto &&arg : args) { std::cout << " " << arg; @@ -733,7 +733,7 @@ bool Filesystem::execute(ScriptOptions opts) const { Key *Mount::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { std::string dev, where, opt; std::string::size_type where_pos, opt_pos; bool any_failure = false; @@ -775,14 +775,14 @@ Key *Mount::parseFromData(const std::string &data, int lineno, int *errors, if(any_failure) return nullptr; - return new Mount(lineno, dev, where, opt); + return new Mount(script, lineno, dev, where, opt); } -bool Mount::validate(ScriptOptions) const { +bool Mount::validate() const { return true; } -bool Mount::execute(ScriptOptions options) const { +bool Mount::execute() const { const std::string actual_mount = "/target" + this->mountpoint(); const char *fstype = nullptr; #ifdef HAS_INSTALL_ENV @@ -790,7 +790,7 @@ bool Mount::execute(ScriptOptions options) const { #endif /* We have to get the filesystem for the node. */ - if(options.test(Simulate)) { + if(script->options().test(Simulate)) { fstype = "auto"; } #ifdef HAS_INSTALL_ENV @@ -808,7 +808,7 @@ bool Mount::execute(ScriptOptions options) const { output_info("installfile:" + std::to_string(this->lineno()), "mount: mounting " + this->device() + " on " + this->mountpoint()); - if(options.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "mount "; if(!this->options().empty()) { std::cout << "-o " << this->options() << " "; @@ -851,7 +851,7 @@ bool Mount::execute(ScriptOptions options) const { char pass = (this->mountpoint() == "/" ? '1' : '0'); const std::string fstab_opts = (this->options().empty() ? "defaults" : this->options()); - if(options.test(Simulate)) { + if(script->options().test(Simulate)) { if(this->mountpoint() == "/") { std::cout << "mkdir -p /target/etc" << std::endl; } diff --git a/hscript/disk.hh b/hscript/disk.hh index 4adf8f5..e777c8f 100644 --- a/hscript/disk.hh +++ b/hscript/disk.hh @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -23,17 +23,19 @@ private: const std::string _block; const std::string _ident; - DiskId(int _line, const std::string &my_block, const std::string &my_i) : - Key(_line), _block(my_block), _ident(my_i) {} + DiskId(const Script *_s, int _line, const std::string &my_block, + const std::string &my_i) : + Key(_s, _line), _block(my_block), _ident(my_i) {} public: /*! Retrieve the block device that this key identifies. */ const std::string device() const { return this->_block; } /*! Retrieve the identification for the block device. */ const std::string ident() const { return this->_ident; } - static Key *parseFromData(const std::string &, int, int*, int*); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool validate() const override; + bool execute() const override; }; class DiskLabel : public Key { @@ -51,17 +53,19 @@ private: const std::string _block; const LabelType _type; - DiskLabel(int _line, const std::string &_b, const LabelType &_t) : - Key(_line), _block(_b), _type(_t) {} + DiskLabel(const Script *_s, int _line, const std::string &_b, + const LabelType &_t) : + Key(_s, _line), _block(_b), _type(_t) {} public: /*! Retrieve the block device that this key identifies. */ const std::string device() const { return this->_block; } /*! Retrieve the type of disklabel for the block device. */ LabelType type() const { return this->_type; } - static Key *parseFromData(const std::string &, int, int*, int*); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool validate() const override; + bool execute() const override; }; /*! The type of size a disk key has */ @@ -96,9 +100,9 @@ private: const uint64_t _size; const PartitionType _type; - Partition(int _line, const std::string &_b, const int _p, + Partition(const Script *_sc, int _line, const std::string &_b, const int _p, const SizeType _st, const uint64_t _s, const PartitionType _pt) : - Key(_line), _block(_b), _partno(_p), _size_type(_st), _size(_s), + Key(_sc, _line), _block(_b), _partno(_p), _size_type(_st), _size(_s), _type(_pt) {} public: /*! Retrieve the block device that this key identifies. */ @@ -112,9 +116,10 @@ public: /*! Retrieve the Type Code of this partition, if any. */ PartitionType type() const { return this->_type; } - static Key *parseFromData(const std::string &, int, int*, int*); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool validate() const override; + bool execute() const override; }; class Encrypt : public Key { @@ -122,25 +127,28 @@ private: const std::string _block; const std::string _pw; - Encrypt(int _line, const std::string &_b, const std::string &_p) : - Key(_line), _block(_b), _pw(_p) {} + Encrypt(const Script *_s, int _line, const std::string &_b, + const std::string &_p) : Key(_s, _line), _block(_b), _pw(_p) {} public: /*! Retrieve the block device that this key encrypts. */ const std::string device() const { return this->_block; } /*! Retrieve the passphrase used to encrypt the block device. */ const std::string passphrase() const { return this->_pw; } - static Key *parseFromData(const std::string &, int, int*, int*); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool validate() const override; + bool execute() const override; }; class LVMPhysical : public StringKey { private: - LVMPhysical(int _line, const std::string &_d) : StringKey(_line, _d) {} + LVMPhysical(const Script *_s, int _line, const std::string &_d) : + StringKey(_s, _line, _d) {} public: - static Key *parseFromData(const std::string &, int, int*, int*); - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool execute() const override; }; class LVMGroup : public Key { @@ -148,19 +156,21 @@ private: const std::string _pv; const std::string _vgname; - LVMGroup(int _line, const std::string &_p, const std::string &_v) : - Key(_line), _pv(_p), _vgname(_v) {} + LVMGroup(const Script *_s, int _line, const std::string &_p, + const std::string &_v) : + Key(_s, _line), _pv(_p), _vgname(_v) {} public: /*! Retrieve the physical volume where this volume group will reside. */ const std::string pv() const { return this->_pv; } /*! Retrieve the name of this volume group. */ const std::string name() const { return this->_vgname; } - static Key *parseFromData(const std::string &, int, int*, int*); - bool validate(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool validate() const override; /*! Determine if the PV passed is a real one. */ - bool test_pv(ScriptOptions) const; - bool execute(ScriptOptions) const override; + bool test_pv() const; + bool execute() const override; }; class LVMVolume : public Key { @@ -170,9 +180,9 @@ private: const SizeType _size_type; const uint64_t _size; - LVMVolume(int _line, const std::string &_v, const std::string &_n, - SizeType _t, uint64_t _s) : Key(_line), _vg(_v), _lvname(_n), - _size_type(_t), _size(_s) {} + LVMVolume(const Script *_sc, int _line, const std::string &_v, + const std::string &_n, SizeType _t, uint64_t _s) : + Key(_sc, _line), _vg(_v), _lvname(_n), _size_type(_t), _size(_s) {} public: /*! Retrieve the volume group to which this volume belongs. */ const std::string vg() const { return this->_vg; } @@ -183,9 +193,10 @@ public: /*! Retrieve the size of this volume. */ uint64_t size() const { return this->_size; } - static Key *parseFromData(const std::string &, int, int*, int*); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool validate() const override; + bool execute() const override; }; class Filesystem : public Key { @@ -203,17 +214,18 @@ private: const std::string _block; FilesystemType _type; - Filesystem(int _line, const std::string &_b, FilesystemType _t) : - Key(_line), _block(_b), _type(_t) {} + Filesystem(const Script *_s, int _line, const std::string &_b, + FilesystemType _t) : Key(_s, _line), _block(_b), _type(_t) {} public: /*! Retrieve the block device on which to create the filesystem. */ const std::string device() const { return this->_block; } /*! Retreive the type of filesystem to create. */ FilesystemType fstype() const { return this->_type; } - static Key *parseFromData(const std::string &, int, int*, int*); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool validate() const override; + bool execute() const override; }; class Mount : public Key { @@ -222,9 +234,9 @@ private: const std::string _mountpoint; const std::string _opts; - Mount(int _line, const std::string &my_block, + Mount(const Script *_s, int _line, const std::string &my_block, const std::string &my_mountpoint, const std::string &my_opts = "") : - Key(_line), _block(my_block), _mountpoint(my_mountpoint), + Key(_s, _line), _block(my_block), _mountpoint(my_mountpoint), _opts(my_opts) {} public: /*! Retrieve the block device to which this mount pertains. */ @@ -234,9 +246,10 @@ public: /*! Retrieve the mount options for this mount, if any. */ const std::string options() const { return this->_opts; } - static Key *parseFromData(const std::string &, int, int*, int*); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool validate() const override; + bool execute() const override; }; } diff --git a/hscript/disk_lvm.cc b/hscript/disk_lvm.cc index f558515..077d533 100644 --- a/hscript/disk_lvm.cc +++ b/hscript/disk_lvm.cc @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -26,7 +26,7 @@ using namespace Horizon::Keys; bool parse_size_string(const std::string &, uint64_t *, SizeType *); Key *LVMPhysical::parseFromData(const std::string &data, int lineno, - int *errors, int *) { + int *errors, int *, const Script *script) { if(data.size() < 6 || data.substr(0, 5) != "/dev/") { if(errors) *errors += 1; output_error("installfile:" + std::to_string(lineno), @@ -34,14 +34,14 @@ Key *LVMPhysical::parseFromData(const std::string &data, int lineno, return nullptr; } - return new LVMPhysical(lineno, data); + return new LVMPhysical(script, lineno, data); } -bool LVMPhysical::execute(ScriptOptions opts) const { +bool LVMPhysical::execute() const { output_info("installfile:" + std::to_string(line), "lvm_pv: creating physical volume on " + _value); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "pvcreate --force " << _value << std::endl; return true; } @@ -117,7 +117,7 @@ bool is_valid_lvm_lv_name(const std::string &name) { Key *LVMGroup::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { std::string::size_type space = data.find_first_of(' '); if(space == std::string::npos || data.size() == space + 1) { if(errors) *errors += 1; @@ -144,16 +144,16 @@ Key *LVMGroup::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; } - return new LVMGroup(lineno, pv, name); + return new LVMGroup(script, lineno, pv, name); } -bool LVMGroup::validate(ScriptOptions) const { +bool LVMGroup::validate() const { /* validation occurs during parsing */ return true; } /* LCOV_EXCL_START */ -bool LVMGroup::test_pv(ScriptOptions) const { +bool LVMGroup::test_pv() const { #ifdef HAS_INSTALL_ENV const char *fstype = blkid_get_tag_value(nullptr, "TYPE", this->pv().c_str()); @@ -214,11 +214,11 @@ bool does_vg_exist_on_pv(const std::string &vg, const std::string &pv, } #endif /* HAS_INSTALL_ENV */ -bool LVMGroup::execute(ScriptOptions opts) const { +bool LVMGroup::execute() const { output_info("installfile:" + std::to_string(line), "lvm_vg: creating volume group " + _vgname + " on " + _pv); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "vgcreate " << _vgname << " " << _pv << std::endl; return true; } @@ -244,7 +244,7 @@ bool LVMGroup::execute(ScriptOptions opts) const { Key *LVMVolume::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { std::string vg, name, size_str; std::string::size_type name_start, size_start; SizeType size_type; @@ -287,14 +287,14 @@ Key *LVMVolume::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; } - return new LVMVolume(lineno, vg, name, size_type, size); + return new LVMVolume(script, lineno, vg, name, size_type, size); } -bool LVMVolume::validate(ScriptOptions) const { +bool LVMVolume::validate() const { return true; } -bool LVMVolume::execute(ScriptOptions opts) const { +bool LVMVolume::execute() const { output_info("installfile:" + std::to_string(line), "lvm_lv: creating volume " + _lvname + " on " + _vg); std::string param, size; @@ -314,7 +314,7 @@ bool LVMVolume::execute(ScriptOptions opts) const { break; } - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "lvcreate " << param << " " << size << " -n " << _lvname << " " << _vg << std::endl; return true; diff --git a/hscript/key.cc b/hscript/key.cc index 6364886..a2d0342 100644 --- a/hscript/key.cc +++ b/hscript/key.cc @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -36,12 +36,12 @@ bool Horizon::Keys::BooleanKey::parse(const std::string &what, return true; } -bool Horizon::Keys::BooleanKey::validate(ScriptOptions) const { +bool Horizon::Keys::BooleanKey::validate() const { /* Key will fail init if it is not valid, so this is always a no-op. */ return true; } -bool Horizon::Keys::StringKey::validate(ScriptOptions) const { +bool Horizon::Keys::StringKey::validate() const { /* Key will fail init if it is not valid, so this is always a no-op. */ return true; } diff --git a/hscript/key.hh b/hscript/key.hh index 0a53124..20a461e 100644 --- a/hscript/key.hh +++ b/hscript/key.hh @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -25,9 +25,11 @@ namespace Keys { */ class Key { protected: + /*! The script that owns this Key. */ + const Script *script; /*! The line number where this Key appeared. */ long line; - Key(long _line) : line(_line) {} + Key(const Script *_s, long _line) : script(_s), line(_line) {} public: virtual ~Key(); @@ -42,19 +44,19 @@ public: /* LCOV_EXCL_START */ static Key *parseFromData(const std::string &data UNUSED, int lineno UNUSED, int *errors UNUSED, - int *warnings UNUSED) { + int *warnings UNUSED, const Script *s UNUSED) { return nullptr; } /* LCOV_EXCL_STOP */ #undef UNUSED /*! Determines if the data associated with the Key is valid. */ - virtual bool validate(ScriptOptions) const = 0; + virtual bool validate() const = 0; /*! Executes the action associated with this Key. * @note Will always return `false` if `validate` is `false`. */ - virtual bool execute(ScriptOptions) const = 0; + virtual bool execute() const = 0; long lineno() const { return this->line; } }; @@ -69,7 +71,8 @@ public: class BooleanKey : public Key { protected: const bool value; - BooleanKey(int _line, bool my_value) : Key(_line), value(my_value) {} + BooleanKey(const Script *_s, int _line, bool my_value) : Key(_s, _line), + value(my_value) {} /*! Parse a string into a boolean. * @param what The string to attempt parsing. @@ -87,7 +90,7 @@ public: bool test() const { return this->value; } /*! Key will fail to init if valid is invalid. */ - bool validate(ScriptOptions) const override; + bool validate() const override; }; @@ -95,8 +98,8 @@ public: class StringKey : public Key { protected: const std::string _value; - StringKey(int _line, const std::string &my_str) : - Key(_line), _value(my_str) {} + StringKey(const Script *_s, int _line, const std::string &my_str) : + Key(_s, _line), _value(my_str) {} public: /*! Retrieve the value of this key. */ @@ -105,7 +108,7 @@ public: /*! By default, key will be considered valid since it parsed. * This method should be overridden when further consideration is needed. */ - bool validate(ScriptOptions) const override; + bool validate() const override; }; } diff --git a/hscript/meta.cc b/hscript/meta.cc index f95e2ad..bfaabb3 100644 --- a/hscript/meta.cc +++ b/hscript/meta.cc @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -26,7 +26,7 @@ using namespace Horizon::Keys; Key *Hostname::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { std::string valid_chars("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_."); if(data.find_first_not_of(valid_chars) != std::string::npos) { if(errors) *errors += 1; @@ -35,10 +35,10 @@ Key *Hostname::parseFromData(const std::string &data, int lineno, int *errors, "'" + data + "' is not a valid hostname"); return nullptr; } - return new Hostname(lineno, data); + return new Hostname(script, lineno, data); } -bool Hostname::validate(ScriptOptions) const { +bool Hostname::validate() const { /* Validate that the name is a valid machine or DNS name */ bool any_failure = false; std::string::size_type last_dot = 0, next_dot = 0; @@ -73,7 +73,7 @@ bool Hostname::validate(ScriptOptions) const { return !any_failure; } -bool Hostname::execute(ScriptOptions opts) const { +bool Hostname::execute() const { /* Set the hostname of the target computer */ std::string actual; std::string::size_type dot = this->_value.find_first_of('.'); @@ -91,7 +91,7 @@ bool Hostname::execute(ScriptOptions opts) const { /* Runner.Execute.hostname. */ output_info("installfile:" + std::to_string(this->lineno()), "hostname: set hostname to '" + actual + "'"); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "hostname " << actual << std::endl; } #ifdef HAS_INSTALL_ENV @@ -108,7 +108,7 @@ bool Hostname::execute(ScriptOptions opts) const { /* Runner.Execute.hostname.Write. */ output_info("installfile:" + std::to_string(this->lineno()), "hostname: write '" + actual + "' to /etc/hostname"); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "printf '%s' " << actual << " > /target/etc/hostname" << std::endl; } @@ -130,7 +130,7 @@ bool Hostname::execute(ScriptOptions opts) const { const std::string domain(this->_value.substr(dot + 1)); output_info("installfile:" + std::to_string(this->lineno()), "hostname: set domain name '" + domain + "'"); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "mkdir -p /target/etc/conf.d" << std::endl; std::cout << "printf 'dns_domain_lo=\"" << domain << "\"\\" << "n' >> /target/etc/conf.d/net" << std::endl; @@ -174,7 +174,7 @@ static std::set<std::string> valid_arches = { Key *Arch::parseFromData(const std::string &data, int lineno, int *errors, - int *warnings) { + int *warnings, const Script *script) { if(data.find_first_not_of("abcdefghijklmnopqrstuvwyxz1234567890") != std::string::npos) { if(errors) *errors += 1; @@ -190,14 +190,14 @@ Key *Arch::parseFromData(const std::string &data, int lineno, int *errors, "arch: unknown CPU architecture '" + data + "'"); } - return new Arch(lineno, data); + return new Arch(script, lineno, data); } -bool Arch::execute(ScriptOptions opts) const { +bool Arch::execute() const { output_info("installfile:" + std::to_string(line), "arch: setting system CPU architecture to " + value()); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "printf '" << this->value() << "\\" << "n'" << " > /target/etc/apk/arch" << std::endl; return true; @@ -221,7 +221,8 @@ static std::regex valid_pkg("[0-9A-Za-z+_.-]*((>?<|[<>]?=|[~>])[0-9A-Za-z-_.]+)? Key *PkgInstall::parseFromData(const std::string &data, int lineno, - int *errors, int *warnings) { + int *errors, int *warnings, + const Script *script) { std::string next_pkg; std::istringstream stream(data); std::set<std::string> all_pkgs; @@ -243,18 +244,18 @@ Key *PkgInstall::parseFromData(const std::string &data, int lineno, } all_pkgs.insert(next_pkg); } - return new PkgInstall(lineno, all_pkgs); + return new PkgInstall(script, lineno, all_pkgs); } /* LCOV_EXCL_START */ -bool PkgInstall::validate(ScriptOptions) const { +bool PkgInstall::validate() const { /* Any validation errors would have occurred above. */ return true; } -bool PkgInstall::execute(ScriptOptions) const { +bool PkgInstall::execute() const { /* Package installation is handled in Script::execute. */ return true; } @@ -290,7 +291,7 @@ const std::set<std::string> valid_langs = { Key *Language::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { if(data.length() < 2 || valid_langs.find(data.substr(0, 2)) == valid_langs.end()) { if(errors) *errors += 1; @@ -323,15 +324,15 @@ Key *Language::parseFromData(const std::string &data, int lineno, int *errors, } } - return new Language(lineno, data); + return new Language(script, lineno, data); } -bool Language::execute(ScriptOptions opts) const { +bool Language::execute() const { output_info("installfile:" + std::to_string(this->lineno()), "language: setting default system language to " + this->value()); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "printf '#!/bin/sh\\" << "nexport LANG=\"%s\"\\" << "n' " << this->value() << " > /target/etc/profile.d/language.sh" << std::endl @@ -369,7 +370,7 @@ bool Language::execute(ScriptOptions opts) const { #include "util/keymaps.hh" Key *Keymap::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { if(valid_keymaps.find(data) == valid_keymaps.end()) { if(errors) *errors += 1; output_error("installfile:" + std::to_string(lineno), @@ -377,14 +378,14 @@ Key *Keymap::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; } - return new Keymap(lineno, data); + return new Keymap(script, lineno, data); } -bool Keymap::validate(ScriptOptions) const { +bool Keymap::validate() const { return true; } -bool Keymap::execute(ScriptOptions opts) const { +bool Keymap::execute() const { const std::string conf("# KEYBOARD CONFIGURATION FILE\n\ \n\ # Consult the keyboard(5) manual page.\n\ @@ -400,7 +401,7 @@ BACKSPACE=guess" output_info("installfile:" + std::to_string(line), "keymap: setting system keyboard map to " + _value); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "cat >/target/etc/default/keyboard <<-KEYCONF" << std::endl; std::cout << conf << std::endl; @@ -424,7 +425,7 @@ BACKSPACE=guess" Key *Firmware::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { bool value; if(!BooleanKey::parse(data, "installfile:" + std::to_string(lineno), "firmware", &value)) { @@ -448,11 +449,11 @@ Key *Firmware::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; #endif } - return new Firmware(lineno, value); + return new Firmware(script, lineno, value); } /* LCOV_EXCL_START */ -bool Firmware::execute(ScriptOptions) const { +bool Firmware::execute() const { /* By itself, this does nothing. */ return true; } @@ -460,7 +461,7 @@ bool Firmware::execute(ScriptOptions) const { Key *Timezone::parseFromData(const std::string &data, int lineno, int *errors, - int *warnings) { + int *warnings, const Script *script) { if(data.find_first_of(" .\\") != std::string::npos || data[0] == '/') { if(errors) *errors += 1; output_error("installfile:" + std::to_string(lineno), @@ -483,14 +484,14 @@ Key *Timezone::parseFromData(const std::string &data, int lineno, int *errors, } } - return new Timezone(lineno, data); + return new Timezone(script, lineno, data); } -bool Timezone::execute(ScriptOptions opts) const { +bool Timezone::execute() const { output_info("installfile:" + std::to_string(this->lineno()), "timezone: setting system timezone to " + this->value()); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { /* If the target doesn't have tzdata installed, copy the zoneinfo from * the Horizon environment. */ std::cout << "([ -f /target/usr/share/zoneinfo/" << this->value() @@ -532,27 +533,27 @@ bool Timezone::execute(ScriptOptions opts) const { Key *Repository::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { if(data.empty() || (data[0] != '/' && data.compare(0, 4, "http"))) { if(errors) *errors += 1; output_error("installfile:" + std::to_string(lineno), "repository: must be absolute path or HTTP(S) URL"); return nullptr; } - return new Repository(lineno, data); + return new Repository(script, lineno, data); } -bool Repository::validate(ScriptOptions) const { +bool Repository::validate() const { /* TODO XXX: Ensure URL is accessible if networking is available */ return true; } -bool Repository::execute(ScriptOptions opts) const { +bool Repository::execute() const { /* Runner.Execute.repository. */ output_info("installfile:" + std::to_string(this->lineno()), "repository: write '" + this->value() + "' to /etc/apk/repositories"); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "echo '" << this->value() << "' >> /target/etc/apk/repositories" << std::endl; return true; @@ -578,7 +579,7 @@ bool Repository::execute(ScriptOptions opts) const { Key *SigningKey::parseFromData(const std::string &data, int lineno, - int *errors, int *) { + int *errors, int *, const Script *script) { if(data.empty() || (data[0] != '/' && data.compare(0, 8, "https://"))) { if(errors) *errors += 1; output_error("installfile:" + std::to_string(lineno), @@ -586,14 +587,14 @@ Key *SigningKey::parseFromData(const std::string &data, int lineno, return nullptr; } - return new SigningKey(lineno, data); + return new SigningKey(script, lineno, data); } -bool SigningKey::validate(ScriptOptions) const { +bool SigningKey::validate() const { return true; } -bool SigningKey::execute(ScriptOptions opts) const { +bool SigningKey::execute() const { /* everything after the last / in the value is the filename */ const std::string name(_value.substr(_value.find_last_of('/') + 1)); @@ -602,7 +603,7 @@ bool SigningKey::execute(ScriptOptions opts) const { output_info("installfile:" + std::to_string(line), "signingkey: trusting " + name + " for repository signing"); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "mkdir -p /target/etc/apk/keys" << std::endl; if(_value[0] == '/') { std::cout << "cp " << _value << " " << target << std::endl; diff --git a/hscript/meta.hh b/hscript/meta.hh index 8740f96..060054b 100644 --- a/hscript/meta.hh +++ b/hscript/meta.hh @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -22,89 +22,100 @@ namespace Keys { class Hostname : public StringKey { private: - Hostname(int _line, const std::string my_name) : - StringKey(_line, my_name) {} + Hostname(const Script *_s, int _line, const std::string my_name) : + StringKey(_s, _line, my_name) {} public: - static Key *parseFromData(const std::string &, int, int *, int *); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int *, int *, + const Script *); + bool validate() const override; + bool execute() const override; }; class Arch : public StringKey { private: - Arch(int _line, const std::string &arch) : - StringKey(_line, arch) {} + Arch(const Script *_s, int _line, const std::string &arch) : + StringKey(_s, _line, arch) {} public: - static Key *parseFromData(const std::string &, int, int *, int *); - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int *, int *, + const Script *); + bool execute() const override; }; class PkgInstall : public Key { private: const std::set<std::string> _pkgs; - PkgInstall(int _line, const std::set<std::string> my_pkgs) : Key(_line), + PkgInstall(const Script *_s, int _line, + const std::set<std::string> my_pkgs) : Key(_s, _line), _pkgs(my_pkgs) {} public: - static Key *parseFromData(const std::string &, int, int *, int *); + static Key *parseFromData(const std::string &, int, int *, int *, + const Script *); const std::set<std::string> packages() const { return _pkgs; } - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + bool validate() const override; + bool execute() const override; }; class Language : public StringKey { private: - Language(int _line, const std::string &my_lang) : - StringKey(_line, my_lang) {} + Language(const Script *_s, int _line, const std::string &my_lang) : + StringKey(_s, _line, my_lang) {} public: - static Key *parseFromData(const std::string &, int, int *, int *); - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int *, int *, + const Script *); + bool execute() const override; }; class Keymap : public StringKey { private: - Keymap(int _line, const std::string &keymap) : - StringKey(_line, keymap) {} + Keymap(const Script *_s, int _line, const std::string &keymap) : + StringKey(_s, _line, keymap) {} public: - static Key *parseFromData(const std::string &, int, int *, int *); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int *, int *, + const Script *); + bool validate() const override; + bool execute() const override; }; class Firmware : public BooleanKey { private: - Firmware(int _line, bool _value) : BooleanKey(_line, _value) {} + Firmware(const Script *_s, int _line, bool _value) : + BooleanKey(_s, _line, _value) {} public: - static Key *parseFromData(const std::string &, int, int *, int *); - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int *, int *, + const Script *); + bool execute() const override; }; class Timezone : public StringKey { private: - Timezone(int _line, const std::string &my_zone) : - StringKey(_line, my_zone) {} + Timezone(const Script *_s, int _line, const std::string &my_zone) : + StringKey(_s, _line, my_zone) {} public: - static Key *parseFromData(const std::string &, int, int *, int *); - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int *, int *, + const Script *); + bool execute() const override; }; class Repository : public StringKey { private: - Repository(int _line, const std::string &my_url) : - StringKey(_line, my_url) {} + Repository(const Script *_s, int _line, const std::string &my_url) : + StringKey(_s, _line, my_url) {} public: - static Key *parseFromData(const std::string &, int, int *, int *); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int *, int *, + const Script *); + bool validate() const override; + bool execute() const override; }; class SigningKey : public StringKey { private: - SigningKey(int _line, const std::string &_path) : - StringKey(_line, _path) {} + SigningKey(const Script *_s, int _line, const std::string &_path) : + StringKey(_s, _line, _path) {} public: - static Key *parseFromData(const std::string &, int, int *, int *); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int *, int *, + const Script *); + bool validate() const override; + bool execute() const override; }; } diff --git a/hscript/network.cc b/hscript/network.cc index c8bc93e..3741b0c 100644 --- a/hscript/network.cc +++ b/hscript/network.cc @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -31,24 +31,24 @@ using namespace Horizon::Keys; Key *Network::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { bool value; if(!BooleanKey::parse(data, "installfile:" + std::to_string(lineno), "network", &value)) { if(errors) *errors += 1; return nullptr; } - return new Network(lineno, value); + return new Network(script, lineno, value); } -bool Network::execute(ScriptOptions) const { +bool Network::execute() const { /* The network key, by itself, does nothing. */ return true; } Key *NetAddress::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { long elements = std::count(data.cbegin(), data.cend(), ' ') + 1; std::string::size_type type_pos, addr_pos, prefix_pos, gw_pos, next_end; std::string iface, type, addr, prefix, gw; @@ -89,7 +89,8 @@ Key *NetAddress::parseFromData(const std::string &data, int lineno, int *errors, "accept further elements"); return nullptr; } - return new NetAddress(lineno, iface, AddressType::DHCP, "", 0, ""); + return new NetAddress(script, lineno, iface, AddressType::DHCP, "", 0, + ""); } else if(!type.compare("slaac")) { if(elements > 2) { if(errors) *errors += 1; @@ -98,7 +99,8 @@ Key *NetAddress::parseFromData(const std::string &data, int lineno, int *errors, "accept further elements"); return nullptr; } - return new NetAddress(lineno, iface, AddressType::SLAAC, "", 0, ""); + return new NetAddress(script, lineno, iface, AddressType::SLAAC, "", 0, + ""); } else if(type.compare("static")) { if(errors) *errors += 1; output_error("installfile:" + std::to_string(lineno), @@ -171,7 +173,7 @@ Key *NetAddress::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; } - return new NetAddress(lineno, iface, AddressType::Static, addr, + return new NetAddress(script, lineno, iface, AddressType::Static, addr, static_cast<uint8_t>(real_prefix), gw); } else if(addr.find('.') != std::string::npos) { /* IPv4 */ @@ -215,7 +217,7 @@ Key *NetAddress::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; } - return new NetAddress(lineno, iface, AddressType::Static, addr, + return new NetAddress(script, lineno, iface, AddressType::Static, addr, static_cast<uint8_t>(real_prefix), gw); } else { /* IPvBad */ @@ -227,8 +229,8 @@ Key *NetAddress::parseFromData(const std::string &data, int lineno, int *errors, } } -bool NetAddress::validate(ScriptOptions opts) const { - if(!opts.test(InstallEnvironment)) { +bool NetAddress::validate() const { + if(!script->options().test(InstallEnvironment)) { return true; } @@ -259,7 +261,7 @@ bool NetAddress::validate(ScriptOptions opts) const { return true; /* LCOV_EXCL_LINE */ } -bool NetAddress::execute(ScriptOptions) const { +bool NetAddress::execute() const { output_info("installfile:" + std::to_string(this->lineno()), "netaddress: adding configuration for " + _iface); @@ -302,7 +304,7 @@ bool NetAddress::execute(ScriptOptions) const { Key *Nameserver::parseFromData(const std::string &data, int lineno, - int *errors, int *) { + int *errors, int *, const Script *script) { char addr_buf[16]; static const std::string valid_chars("1234567890ABCDEFabcdef:."); @@ -339,11 +341,11 @@ Key *Nameserver::parseFromData(const std::string &data, int lineno, } } - return new Nameserver(lineno, data); + return new Nameserver(script, lineno, data); } -bool Nameserver::execute(ScriptOptions opts) const { - if(opts.test(Simulate)) { +bool Nameserver::execute() const { + if(script->options().test(Simulate)) { std::cout << "printf 'nameserver %s\\" << "n' " << _value << " >>/target/etc/resolv.conf" << std::endl; return true; @@ -363,7 +365,7 @@ bool Nameserver::execute(ScriptOptions opts) const { Key *NetSSID::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { std::string iface, ssid, secstr, passphrase; SecurityType type; std::string::size_type start, pos, next; @@ -443,12 +445,12 @@ Key *NetSSID::parseFromData(const std::string &data, int lineno, int *errors, } passphrase = data.substr(pos + 1); } - return new NetSSID(lineno, iface, ssid, type, passphrase); + return new NetSSID(script, lineno, iface, ssid, type, passphrase); } -bool NetSSID::validate(ScriptOptions options) const { +bool NetSSID::validate() const { /* REQ: Runner.Validate.network.netssid.Interface */ - if(!options.test(InstallEnvironment)) { + if(!script->options().test(InstallEnvironment)) { return true; } @@ -488,7 +490,7 @@ bool NetSSID::validate(ScriptOptions options) const { #endif } -bool NetSSID::execute(ScriptOptions) const { +bool NetSSID::execute() const { output_info("installfile:" + std::to_string(this->lineno()), "netssid: configuring SSID " + _ssid); diff --git a/hscript/network.hh b/hscript/network.hh index b556ab8..ec8d2cf 100644 --- a/hscript/network.hh +++ b/hscript/network.hh @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -21,11 +21,12 @@ namespace Keys { class Network : public BooleanKey { private: - Network(int _line, bool _value) : BooleanKey(_line, _value) {} + Network(const Script *_s, int _line, bool _value) : + BooleanKey(_s, _line, _value) {} public: - static Key *parseFromData(const std::string &data, int lineno, int *errors, - int *warnings); - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool execute() const override; }; class NetAddress : public Key { @@ -46,13 +47,14 @@ private: const uint8_t _prefix; const std::string _gw; - NetAddress(const int _line, const std::string &_i, const AddressType &_t, - const std::string &_a, const uint8_t _p, const std::string &_g) : - Key(_line), _iface(_i), _type(_t), _address(_a), _prefix(_p), _gw(_g) + NetAddress(const Script *_sc, const int _line, const std::string &_i, + const AddressType &_t, const std::string &_a, const uint8_t _p, + const std::string &_g) : Key(_sc, _line), _iface(_i), _type(_t), + _address(_a), _prefix(_p), _gw(_g) {} public: - static Key *parseFromData(const std::string &data, int lineno, int *errors, - int *warnings); + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); /*! Retrieve the interface to which this 'netaddress' key is associated. */ const std::string iface() const { return this->_iface; } @@ -65,16 +67,18 @@ public: /*! Retrieve the gateway, if any. */ const std::string gateway() const { return this->_gw; } - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + bool validate() const override; + bool execute() const override; }; class Nameserver : public StringKey { private: - Nameserver(int _line, const std::string &ns) : StringKey(_line, ns) {} + Nameserver(const Script *_s, int _line, const std::string &ns) : + StringKey(_s, _line, ns) {} public: - static Key *parseFromData(const std::string &, int, int *, int *); - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool execute() const override; }; class NetSSID : public Key { @@ -91,12 +95,12 @@ private: const SecurityType _sec; const std::string _pw; - NetSSID(int _line, const std::string &_if, const std::string &_s, - SecurityType _t, const std::string &_p) : Key(_line), _iface(_if), - _ssid(_s), _sec(_t), _pw(_p) {} + NetSSID(const Script *_sc, int _line, const std::string &_if, + const std::string &_s, SecurityType _t, const std::string &_p) : + Key(_sc, _line), _iface(_if), _ssid(_s), _sec(_t), _pw(_p) {} public: - static Key *parseFromData(const std::string &data, int lineno, int *errors, - int *warnings); + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); /*! Retrieve the interface to which this 'netssid' key is associated. */ const std::string iface() const { return this->_iface; } @@ -109,8 +113,8 @@ public: */ const std::string passphrase() const { return this->_pw; } - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + bool validate() const override; + bool execute() const override; }; } diff --git a/hscript/script.cc b/hscript/script.cc index 0bc6b8a..9073e04 100644 --- a/hscript/script.cc +++ b/hscript/script.cc @@ -30,7 +30,8 @@ #define SCRIPT_LINE_MAX 512 -typedef Horizon::Keys::Key *(*key_parse_fn)(const std::string &, int, int*, int*); +typedef Horizon::Keys::Key *(*key_parse_fn)(const std::string &, int, int*, + int*, const Horizon::Script *); using namespace Horizon::Keys; @@ -203,6 +204,7 @@ const Script *Script::load(std::istream &sstream, using namespace Horizon::Keys; Script *the_script = new Script; + the_script->opts = opts; int lineno = 0; char nextline[SCRIPT_LINE_MAX]; @@ -248,7 +250,7 @@ const Script *Script::load(std::istream &sstream, } Key *key_obj = valid_keys.at(key)(line.substr(value_begin), lineno, - &errors, &warnings); + &errors, &warnings, the_script); if(!key_obj) { PARSER_ERROR("value for key '" + key + "' was invalid") continue; @@ -309,7 +311,6 @@ const Script *Script::load(std::istream &sstream, delete the_script; return nullptr; } else { - the_script->opts = opts; return the_script; } diff --git a/hscript/script_e.cc b/hscript/script_e.cc index 402eb88..8360b28 100644 --- a/hscript/script_e.cc +++ b/hscript/script_e.cc @@ -87,7 +87,7 @@ bool Script::execute() const { output_error(phase, "The HorizonScript failed to execute",\ "Check the log file for more details.") #define EXECUTE_OR_FAIL(phase, obj) \ - if(!obj->execute(opts)) {\ + if(!obj->execute()) {\ EXECUTE_FAILURE(phase);\ return false;\ } @@ -212,7 +212,7 @@ bool Script::execute() const { } for(auto &ssid : internal->ssids) { - if(!ssid->execute(opts)) { + if(!ssid->execute()) { EXECUTE_FAILURE("ssid"); /* "Soft" error. Not fatal. */ } @@ -256,7 +256,7 @@ bool Script::execute() const { } for(auto &addr : internal->addresses) { - if(!addr->execute(opts)) { + if(!addr->execute()) { EXECUTE_FAILURE("netaddress"); /* "Soft" error. Not fatal. */ } else { diff --git a/hscript/script_v.cc b/hscript/script_v.cc index ad40f72..3622365 100644 --- a/hscript/script_v.cc +++ b/hscript/script_v.cc @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -45,18 +45,17 @@ namespace Horizon { * @param opts The ScriptOptions in use. * @returns A count of errors encountered, or 0 if the account is valid. */ -int validate_one_account(const std::string &name, UserDetail *detail, - ScriptOptions opts) { +int validate_one_account(const std::string &name, UserDetail *detail) { int failures = 0; /* REQ: Runner.Validate.username */ - if(!detail->name->validate(opts)) failures++; + if(!detail->name->validate()) failures++; /* REQ: Runner.Validate.useralias */ - if(detail->alias && !detail->alias->validate(opts)) failures++; + if(detail->alias && !detail->alias->validate()) failures++; /* REQ: Runner.Validate.userpw */ - if(detail->passphrase && !detail->passphrase->validate(opts)) failures++; + if(detail->passphrase && !detail->passphrase->validate()) failures++; /* REQ: Runner.Validate.userpw.None */ if(!detail->passphrase) { @@ -67,13 +66,13 @@ int validate_one_account(const std::string &name, UserDetail *detail, } /* REQ: Runner.Validate.usericon */ - if(detail->icon && !detail->icon->validate(opts)) failures++; + if(detail->icon && !detail->icon->validate()) failures++; if(detail->groups.size() > 0) { std::set<std::string> seen_groups; for(auto &group : detail->groups) { /* REQ: Runner.Validate.usergroups */ - if(!group->validate(opts)) failures++; + if(!group->validate()) failures++; /* REQ: Runner.Validate.usergroups.Unique */ const std::set<std::string> these = group->groups(); @@ -108,11 +107,11 @@ int validate_one_account(const std::string &name, UserDetail *detail, * Adélie Linux. Both system/ and user/ will be added. */ bool add_default_repos(std::vector<std::unique_ptr<Repository>> &repos, - bool firmware = false) { + const Script *s, bool firmware = false) { Repository *sys_key = dynamic_cast<Repository *>( Repository::parseFromData( "https://distfiles.adelielinux.org/adelie/stable/system", 0, - nullptr, nullptr + nullptr, nullptr, s ) ); if(!sys_key) { @@ -124,7 +123,7 @@ bool add_default_repos(std::vector<std::unique_ptr<Repository>> &repos, Repository *user_key = dynamic_cast<Repository *>( Repository::parseFromData( "https://distfiles.adelielinux.org/adelie/stable/user", 0, - nullptr, nullptr + nullptr, nullptr, s ) ); if(!user_key) { @@ -140,7 +139,7 @@ bool add_default_repos(std::vector<std::unique_ptr<Repository>> &repos, Repository *fw_key = dynamic_cast<Repository *>( Repository::parseFromData( "https://distfiles.apkfission.net/adelie-stable/nonfree", - 0, nullptr, nullptr + 0, nullptr, nullptr, s ) ); if(!fw_key) { @@ -162,10 +161,11 @@ bool add_default_repos(std::vector<std::unique_ptr<Repository>> &repos, * for Adélie Linux. */ bool add_default_repo_keys(std::vector<std::unique_ptr<SigningKey>> &keys, - bool firmware = false) { + const Script *s, bool firmware = false) { SigningKey *key = dynamic_cast<SigningKey *>( SigningKey::parseFromData( - "/etc/apk/keys/packages@adelielinux.org.pub", 0, nullptr, nullptr) + "/etc/apk/keys/packages@adelielinux.org.pub", 0, nullptr, nullptr, + s) ); if(!key) { output_error("internal", "failed to create default repository signing key"); @@ -179,7 +179,7 @@ bool add_default_repo_keys(std::vector<std::unique_ptr<SigningKey>> &keys, if(firmware) { SigningKey *fkey = dynamic_cast<SigningKey *>(SigningKey::parseFromData( "/etc/apk/keys/packages@pleroma.apkfission.net-5ac0b300.rsa.pub", - 0, nullptr, nullptr) + 0, nullptr, nullptr, s) ); if(!fkey) { output_error("internal", "failed to create firmware signing key"); @@ -189,7 +189,7 @@ bool add_default_repo_keys(std::vector<std::unique_ptr<SigningKey>> &keys, keys.push_back(std::move(fw_key)); fkey = dynamic_cast<SigningKey *>(SigningKey::parseFromData( "/etc/apk/keys/packages@pleroma.apkfission.net-5ac04808.rsa.pub", - 0, nullptr, nullptr)); + 0, nullptr, nullptr, s)); if(fkey) { std::unique_ptr<SigningKey> fw_key2(fkey); keys.push_back(std::move(fw_key2)); @@ -211,7 +211,7 @@ bool Horizon::Script::validate() const { #endif /* HAS_INSTALL_ENV */ /* REQ: Runner.Validate.network */ - if(!internal->network->validate(opts)) failures++; + if(!internal->network->validate()) failures++; /* REQ: Runner.Validate.network.netaddress */ if(internal->network->test() && internal->addresses.size() == 0) { @@ -221,7 +221,7 @@ bool Horizon::Script::validate() const { "networking."); } for(auto &address : internal->addresses) { - if(!address->validate(opts)) failures++; + if(!address->validate()) failures++; /* REQ: Runner.Validate.network.netaddress.Count */ if(seen_iface.find(address->iface()) == seen_iface.end()) { @@ -239,7 +239,7 @@ bool Horizon::Script::validate() const { /* REQ: Runner.Validate.nameserver */ for(auto &ns : internal->nses) { - if(!ns->validate(opts)) failures++; + if(!ns->validate()) failures++; } if(internal->nses.size() > MAXNS) { output_warning("installfile:" + @@ -250,33 +250,33 @@ bool Horizon::Script::validate() const { /* REQ: Runner.Validate.network.netssid */ for(auto &ssid : internal->ssids) { - if(!ssid->validate(opts)) failures++; + if(!ssid->validate()) failures++; } /* REQ: Runner.Validate.hostname */ - if(!internal->hostname->validate(opts)) failures++; + if(!internal->hostname->validate()) failures++; /* REQ: Runner.Validate.rootpw */ - if(!internal->rootpw->validate(opts)) failures++; + if(!internal->rootpw->validate()) failures++; /* REQ: Runner.Validate.arch */ - if(internal->arch && !internal->arch->validate(opts)) failures++; + if(internal->arch && !internal->arch->validate()) failures++; /* REQ: Runner.Validate.language */ - if(internal->lang && !internal->lang->validate(opts)) failures++; + if(internal->lang && !internal->lang->validate()) failures++; /* REQ: Runner.Validate.keymap */ - if(internal->keymap && !internal->keymap->validate(opts)) failures++; + if(internal->keymap && !internal->keymap->validate()) failures++; #ifdef NON_LIBRE_FIRMWARE /* REQ: Runner.Validate.firmware */ - if(internal->firmware && !internal->firmware->validate(opts)) failures++; + if(internal->firmware && !internal->firmware->validate()) failures++; #endif /* REQ: Runner.Execute.timezone */ if(!internal->tzone) { Timezone *utc = dynamic_cast<Timezone *> - (Timezone::parseFromData("UTC", 0, &failures, nullptr)); + (Timezone::parseFromData("UTC", 0, &failures, nullptr, this)); if(!utc) { output_error("internal", "failed to create default timezone"); return false; @@ -286,11 +286,11 @@ bool Horizon::Script::validate() const { } /* REQ: Runner.Validate.timezone */ - if(!internal->tzone->validate(opts)) failures++; + if(!internal->tzone->validate()) failures++; /* REQ: Script.repository */ if(internal->repos.size() == 0) { - if(!add_default_repos(internal->repos + if(!add_default_repos(internal->repos, this #ifdef NON_LIBRE_FIRMWARE , internal->firmware && internal->firmware->test() #endif @@ -301,7 +301,7 @@ bool Horizon::Script::validate() const { /* REQ: Runner.Validate.repository */ for(auto &repo : internal->repos) { - if(!repo->validate(opts)) failures++; + if(!repo->validate()) failures++; } if(internal->repos.size() > 10) { failures++; @@ -312,7 +312,7 @@ bool Horizon::Script::validate() const { /* REQ: Script.signingkey */ if(internal->repo_keys.size() == 0) { - if(!add_default_repo_keys(internal->repo_keys + if(!add_default_repo_keys(internal->repo_keys, this #ifdef NON_LIBRE_FIRMWARE , internal->firmware && internal->firmware->test() #endif @@ -323,7 +323,7 @@ bool Horizon::Script::validate() const { /* REQ: Runner.Validate.signingkey */ for(auto &key : internal->repo_keys) { - if(!key->validate(opts)) failures++; + if(!key->validate()) failures++; } if(internal->repo_keys.size() > 10) { failures++; @@ -335,11 +335,11 @@ bool Horizon::Script::validate() const { for(auto &acct : internal->accounts) { UserDetail *detail = acct.second.get(); - failures += validate_one_account(acct.first, detail, opts); + failures += validate_one_account(acct.first, detail); } #define VALIDATE_OR_SKIP(obj) \ - if(!obj->validate(opts)) {\ + if(!obj->validate()) {\ failures++;\ continue;\ } @@ -447,7 +447,7 @@ bool Horizon::Script::validate() const { /* Okay, let's see if a PV already exists there... */ if(opts.test(InstallEnvironment)) { #ifdef HAS_INSTALL_ENV - if(!vg->test_pv(opts)) { + if(!vg->test_pv()) { failures++; output_error("installfile:" + to_string(vg->lineno()), "lvm_vg: a physical volume does not exist on " diff --git a/hscript/user.cc b/hscript/user.cc index f7c5c7c..82d627c 100644 --- a/hscript/user.cc +++ b/hscript/user.cc @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -122,26 +122,26 @@ static bool string_is_crypt(const std::string &pw, const std::string &key, Key *RootPassphrase::parseFromData(const std::string &data, int lineno, - int *errors, int *) { + int *errors, int *, const Script *script) { if(!string_is_crypt(data, "rootpw", lineno)) { if(errors) *errors += 1; return nullptr; } - return new RootPassphrase(lineno, data); + return new RootPassphrase(script, lineno, data); } -bool RootPassphrase::validate(ScriptOptions) const { +bool RootPassphrase::validate() const { return true; } -bool RootPassphrase::execute(ScriptOptions options) const { +bool RootPassphrase::execute() const { const std::string root_line = "root:" + this->_value + ":" + std::to_string(time(nullptr) / 86400) + ":0:::::"; output_info("installfile:" + std::to_string(this->lineno()), "rootpw: setting root passphrase"); - if(options.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "(printf '" << root_line << "\\" << "n'; " << "cat /target/etc/shadow | sed '1d') > /tmp/shadow" << std::endl @@ -190,7 +190,7 @@ bool RootPassphrase::execute(ScriptOptions options) const { Key *Username::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { if(!is_valid_name(data.c_str())) { if(errors) *errors += 1; output_error("installfile:" + std::to_string(lineno), @@ -206,14 +206,14 @@ Key *Username::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; } - return new Username(lineno, data); + return new Username(script, lineno, data); } -bool Username::execute(ScriptOptions opts) const { +bool Username::execute() const { output_info("installfile:" + std::to_string(line), "username: creating account " + _value); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "useradd -c \"Adélie User\" -m -U " << _value << std::endl; return true; @@ -232,7 +232,7 @@ bool Username::execute(ScriptOptions opts) const { Key *UserAlias::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { /* REQ: Runner.Validate.useralias.Validity */ const std::string::size_type sep = data.find_first_of(' '); if(sep == std::string::npos || data.length() == sep + 1) { @@ -243,18 +243,19 @@ Key *UserAlias::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; } - return new UserAlias(lineno, data.substr(0, sep), data.substr(sep + 1)); + return new UserAlias(script, lineno, data.substr(0, sep), + data.substr(sep + 1)); } -bool UserAlias::validate(ScriptOptions) const { +bool UserAlias::validate() const { return true; } -bool UserAlias::execute(ScriptOptions opts) const { +bool UserAlias::execute() const { output_info("installfile:" + std::to_string(line), "useralias: setting GECOS name for " + _username); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "usermod -c \"" << _alias << "\" " << _username << std::endl; return true; @@ -272,7 +273,7 @@ bool UserAlias::execute(ScriptOptions opts) const { Key *UserPassphrase::parseFromData(const std::string &data, int lineno, - int *errors, int *) { + int *errors, int *, const Script *script) { /* REQ: Runner.Validate.userpw.Validity */ const std::string::size_type sep = data.find_first_of(' '); if(sep == std::string::npos || data.length() == sep + 1) { @@ -289,19 +290,20 @@ Key *UserPassphrase::parseFromData(const std::string &data, int lineno, return nullptr; } - return new UserPassphrase(lineno, data.substr(0, sep), data.substr(sep + 1)); + return new UserPassphrase(script, lineno, data.substr(0, sep), + data.substr(sep + 1)); } -bool UserPassphrase::validate(ScriptOptions) const { +bool UserPassphrase::validate() const { /* If it's parseable, it's valid. */ return true; } -bool UserPassphrase::execute(ScriptOptions opts) const { +bool UserPassphrase::execute() const { output_info("installfile:" + std::to_string(line), "userpw: setting passphrase for " + _username); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "usermod -p '" << _passphrase << "' " << _username << std::endl; return true; @@ -319,7 +321,7 @@ bool UserPassphrase::execute(ScriptOptions opts) const { Key *UserIcon::parseFromData(const std::string &data, int lineno, int *errors, - int *) { + int *, const Script *script) { /* REQ: Runner.Validate.usericon.Validity */ const std::string::size_type sep = data.find_first_of(' '); if(sep == std::string::npos || data.length() == sep + 1) { @@ -338,15 +340,15 @@ Key *UserIcon::parseFromData(const std::string &data, int lineno, int *errors, return nullptr; } - return new UserIcon(lineno, data.substr(0, sep), icon_path); + return new UserIcon(script, lineno, data.substr(0, sep), icon_path); } -bool UserIcon::validate(ScriptOptions) const { +bool UserIcon::validate() const { /* TODO XXX: ensure URL is accessible */ return true; } -bool UserIcon::execute(ScriptOptions opts) const { +bool UserIcon::execute() const { const std::string as_path("/target/var/lib/AccountsService/icons/" + _username); const std::string face_path("/target/home/" + _username + "/.face"); @@ -354,7 +356,7 @@ bool UserIcon::execute(ScriptOptions opts) const { output_info("installfile:" + std::to_string(line), "usericon: setting avatar for " + _username); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { if(_icon_path[0] == '/') { std::cout << "cp " << _icon_path << " " << as_path << std::endl; } else { @@ -403,7 +405,7 @@ bool UserIcon::execute(ScriptOptions opts) const { Key *UserGroups::parseFromData(const std::string &data, int lineno, - int *errors, int *) { + int *errors, int *, const Script *script) { /* REQ: Runner.Validate.usergroups.Validity */ const std::string::size_type sep = data.find_first_of(' '); if(sep == std::string::npos || data.length() == sep + 1) { @@ -438,15 +440,15 @@ Key *UserGroups::parseFromData(const std::string &data, int lineno, return nullptr; } - return new UserGroups(lineno, data.substr(0, sep), group_set); + return new UserGroups(script, lineno, data.substr(0, sep), group_set); } -bool UserGroups::validate(ScriptOptions) const { +bool UserGroups::validate() const { /* All validation is done in parsing stage */ return true; } -bool UserGroups::execute(ScriptOptions opts) const { +bool UserGroups::execute() const { output_info("installfile:" + std::to_string(line), "usergroups: setting group membership for " + _username); @@ -457,7 +459,7 @@ bool UserGroups::execute(ScriptOptions opts) const { /* remove the last comma. */ groups.pop_back(); - if(opts.test(Simulate)) { + if(script->options().test(Simulate)) { std::cout << "usermod -aG " << groups << " " << _username << std::endl; return true; } diff --git a/hscript/user.hh b/hscript/user.hh index d29944f..8a093fb 100644 --- a/hscript/user.hh +++ b/hscript/user.hh @@ -3,7 +3,7 @@ * libhscript, the HorizonScript library for * Project Horizon * - * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * Copyright (c) 2019-2020 Adélie Linux and contributors. All rights reserved. * This code is licensed under the AGPL 3.0 license, as noted in the * LICENSE-code file in the root directory of this repository. * @@ -22,21 +22,23 @@ namespace Keys { class RootPassphrase : public StringKey { private: - RootPassphrase(int _line, const std::string &my_pw) : - StringKey(_line, my_pw) {} + RootPassphrase(const Script *_s, int _line, const std::string &my_pw) : + StringKey(_s, _line, my_pw) {} public: - static Key *parseFromData(const std::string &, int, int*, int*); - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool validate() const override; + bool execute() const override; }; class Username : public StringKey { private: - Username(int _line, const std::string &name) : - StringKey(_line, name) {} + Username(const Script *_s, int _line, const std::string &name) : + StringKey(_s, _line, name) {} public: - static Key *parseFromData(const std::string &, int, int*, int*); - bool execute(ScriptOptions) const override; + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); + bool execute() const override; }; class UserAlias : public Key { @@ -44,18 +46,20 @@ private: const std::string _username; const std::string _alias; - UserAlias(int _line, const std::string &_n, const std::string &_a) : - Key(_line), _username(_n), _alias(_a) {} + UserAlias(const Script *_s, int _line, const std::string &_n, + const std::string &_a) : + Key(_s, _line), _username(_n), _alias(_a) {} public: - static Key *parseFromData(const std::string &, int, int*, int*); + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); /*! Retrieve the username for this alias. */ const std::string &username() const { return this->_username; } /*! Retrieve the alias for the account. */ const std::string &alias() const { return this->_alias; } - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + bool validate() const override; + bool execute() const override; }; class UserPassphrase : public Key { @@ -63,18 +67,20 @@ private: const std::string _username; const std::string _passphrase; - UserPassphrase(int _line, const std::string &_n, const std::string &_p) : - Key(_line), _username(_n), _passphrase(_p) {} + UserPassphrase(const Script *_s, int _line, const std::string &_n, + const std::string &_p) : + Key(_s, _line), _username(_n), _passphrase(_p) {} public: - static Key *parseFromData(const std::string &, int, int*, int*); + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); /*! Retrieve the username for this passphrase. */ const std::string &username() const { return this->_username; } /*! Retrieve the passphrase for the account. */ const std::string &passphrase() const { return this->_passphrase; } - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + bool validate() const override; + bool execute() const override; }; class UserIcon : public Key { @@ -82,18 +88,20 @@ private: const std::string _username; const std::string _icon_path; - UserIcon(int _line, const std::string &_n, const std::string &_i) : - Key(_line), _username(_n), _icon_path(_i) {} + UserIcon(const Script *_s, int _line, const std::string &_n, + const std::string &_i) : + Key(_s, _line), _username(_n), _icon_path(_i) {} public: - static Key *parseFromData(const std::string &, int, int*, int*); + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); /*! Retrieve the username for this icon. */ const std::string &username() const { return this->_username; } /*! Retrieve the icon path for the account. */ const std::string &icon() const { return this->_icon_path; } - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + bool validate() const override; + bool execute() const override; }; class UserGroups : public Key { @@ -101,19 +109,20 @@ private: const std::string _username; const std::set<std::string> _groups; - UserGroups(int _line, const std::string &_n, + UserGroups(const Script *_s, int _line, const std::string &_n, const std::set<std::string> &_g) : - Key(_line), _username(_n), _groups(_g) {} + Key(_s, _line), _username(_n), _groups(_g) {} public: - static Key *parseFromData(const std::string &, int, int*, int*); + static Key *parseFromData(const std::string &, int, int*, int*, + const Script *); /*! Retrieve the username for this group set. */ const std::string &username() const { return this->_username; } /*! Retrieve the groups for the account. */ const std::set<std::string> &groups() const { return this->_groups; } - bool validate(ScriptOptions) const override; - bool execute(ScriptOptions) const override; + bool validate() const override; + bool execute() const override; }; } |