Stefan Schuermans commited on 2020-09-19 12:44:39
Showing 16 changed files, with 303 additions and 32 deletions.
| ... | ... |
@@ -93,12 +93,18 @@ The configuration file lists directory trees and the ownerships and permissions |
| 93 | 93 |
to set for them. If some of the specified trees are nested within each other, |
| 94 | 94 |
the nested tree(s) is/are excluded from the containing tree(s). |
| 95 | 95 |
|
| 96 |
-The syntax of the config file is line-based. Each line defines a directory tree |
|
| 97 |
-and the ownerships and permissions. |
|
| 96 |
+The syntax of the config file is line-based. Each line defines a setting or a |
|
| 97 |
+directory tree and the ownerships and permissions for it. |
|
| 98 | 98 |
|
| 99 | 99 |
Syntax: |
| 100 | 100 |
|
| 101 |
-* Each line: `tree <user> <group> <permissions> <directory>` |
|
| 101 |
+ * process nice-ness (only for `permissionerd`, ignored by `permissonerc`) |
|
| 102 |
+ `nice [<niceness value>] [idle] |
|
| 103 |
+ * `<niceness value>`: Linux niceness value for daemon process, |
|
| 104 |
+ `19` for nicest (lowest CPU priority) |
|
| 105 |
+ * `idle`: set I/O priority class to idle |
|
| 106 |
+ * owership and permission configuration: |
|
| 107 |
+ `tree <user> <group> <permissions> <directory>` |
|
| 102 | 108 |
* `<user>`: User name to set as user/owner, `-` to not change the user/owner. |
| 103 | 109 |
* `<group>`: Group name to set as group, `-` to not change the group. |
| 104 | 110 |
* `<permissions>`: Comma-separated list of permission settings. |
| ... | ... |
@@ -3,12 +3,14 @@ add_library( |
| 3 | 3 |
STATIC |
| 4 | 4 |
include/permissioner/Config.h |
| 5 | 5 |
include/permissioner/Group.h |
| 6 |
+ include/permissioner/Nice.h |
|
| 6 | 7 |
include/permissioner/Permissions.h |
| 7 | 8 |
include/permissioner/StringUtils.h |
| 8 | 9 |
include/permissioner/Tree.h |
| 9 | 10 |
include/permissioner/User.h |
| 10 | 11 |
src/Config.cpp |
| 11 | 12 |
src/Group.cpp |
| 13 |
+ src/Nice.cpp |
|
| 12 | 14 |
src/Permissions.cpp |
| 13 | 15 |
src/StringUtils.cpp |
| 14 | 16 |
src/Tree.cpp |
| ... | ... |
@@ -7,6 +7,7 @@ |
| 7 | 7 |
#ifndef CONFIG_H |
| 8 | 8 |
#define CONFIG_H |
| 9 | 9 |
|
| 10 |
+#include <permissioner/Nice.h> |
|
| 10 | 11 |
#include <permissioner/Tree.h> |
| 11 | 12 |
|
| 12 | 13 |
#include <boost/filesystem.hpp> |
| ... | ... |
@@ -23,6 +24,9 @@ public: |
| 23 | 24 |
*/ |
| 24 | 25 |
void parseFile(std::string const &configFileName); |
| 25 | 26 |
|
| 27 |
+ /// return nice settings |
|
| 28 |
+ Nice const & getNice() const; |
|
| 29 |
+ |
|
| 26 | 30 |
/// return trees |
| 27 | 31 |
TreeMap const & getTrees() const; |
| 28 | 32 |
|
| ... | ... |
@@ -32,6 +36,7 @@ public: |
| 32 | 36 |
void setPermissions() const; |
| 33 | 37 |
|
| 34 | 38 |
protected: |
| 39 |
+ Nice nice; |
|
| 35 | 40 |
TreeMap trees; |
| 36 | 41 |
}; |
| 37 | 42 |
|
| ... | ... |
@@ -0,0 +1,41 @@ |
| 1 |
+/** |
|
| 2 |
+ * Permissioner: set file ownerships and permissions |
|
| 3 |
+ * Copyright 2020: Stefan Schuermans, Aachen, Germany <stefan@schuermans.info> |
|
| 4 |
+ * Copyleft: GNU GENERAL PUBLIC LICENSE version 3 (see LICENSE) |
|
| 5 |
+ */ |
|
| 6 |
+ |
|
| 7 |
+#ifndef NICE_H |
|
| 8 |
+#define NICE_H |
|
| 9 |
+ |
|
| 10 |
+#include <boost/optional.hpp> |
|
| 11 |
+#include <string> |
|
| 12 |
+ |
|
| 13 |
+/// nice (CPU and I/O) priority settings |
|
| 14 |
+class Nice {
|
|
| 15 |
+public: |
|
| 16 |
+ Nice(); |
|
| 17 |
+ |
|
| 18 |
+ /** |
|
| 19 |
+ * @brief parse nice parameters |
|
| 20 |
+ * @param[in] parmStr parameter string |
|
| 21 |
+ * @throws std::exception if something goes wrong |
|
| 22 |
+ */ |
|
| 23 |
+ void parseParams(std::string const ¶mStr); |
|
| 24 |
+ |
|
| 25 |
+ /// return niceness level |
|
| 26 |
+ boost::optional<int> getNice() const; |
|
| 27 |
+ |
|
| 28 |
+ /// return whether using I/O idle class |
|
| 29 |
+ bool getIoIdle() const; |
|
| 30 |
+ |
|
| 31 |
+ /** |
|
| 32 |
+ * @brief set CPU and I/O priority of process |
|
| 33 |
+ */ |
|
| 34 |
+ void apply() const; |
|
| 35 |
+ |
|
| 36 |
+protected: |
|
| 37 |
+ boost::optional<int> nice; |
|
| 38 |
+ bool ioIdle; |
|
| 39 |
+}; |
|
| 40 |
+ |
|
| 41 |
+#endif // #ifndef NICE_H |
| ... | ... |
@@ -21,6 +21,27 @@ public: |
| 21 | 21 |
*/ |
| 22 | 22 |
static void getNextField(std::string const &str, std::string::size_type &pos, |
| 23 | 23 |
std::string &field, std::string const &name); |
| 24 |
+ |
|
| 25 |
+ /** |
|
| 26 |
+ * @brief convert a string to a long integer |
|
| 27 |
+ * @param[in] str string on which to operate |
|
| 28 |
+ * @param[in] name filed name for exception |
|
| 29 |
+ * @return integer value |
|
| 30 |
+ * @throws std::exception if something goes wrong |
|
| 31 |
+ */ |
|
| 32 |
+ static long str2long(std::string const &str, std::string const &name); |
|
| 33 |
+ |
|
| 34 |
+ /** |
|
| 35 |
+ * @brief convert a string to an integer and check range |
|
| 36 |
+ * @param[in] str string on which to operate |
|
| 37 |
+ * @param[in] minVal minium value |
|
| 38 |
+ * @param[in] maxVal maxium value |
|
| 39 |
+ * @param[in] name filed name for exception |
|
| 40 |
+ * @return integer value |
|
| 41 |
+ * @throws std::exception if something goes wrong |
|
| 42 |
+ */ |
|
| 43 |
+ static int str2intRange(std::string const &str, int minVal, int maxVal, |
|
| 44 |
+ std::string const &name); |
|
| 24 | 45 |
}; |
| 25 | 46 |
|
| 26 | 47 |
#endif // #ifndef STRING_UTILS_H |
| ... | ... |
@@ -36,6 +36,10 @@ void Config::parseFile(std::string const &configFileName) {
|
| 36 | 36 |
continue; // comment line -> ignore |
| 37 | 37 |
} |
| 38 | 38 |
// actual configuration lines |
| 39 |
+ if (typeStr == "nice") {
|
|
| 40 |
+ nice.parseParams(line.substr(pos)); |
|
| 41 |
+ continue; |
|
| 42 |
+ } |
|
| 39 | 43 |
if (typeStr == "tree") {
|
| 40 | 44 |
Tree tree; |
| 41 | 45 |
tree.parseParams(line.substr(pos)); |
| ... | ... |
@@ -49,6 +53,10 @@ void Config::parseFile(std::string const &configFileName) {
|
| 49 | 53 |
} |
| 50 | 54 |
} |
| 51 | 55 |
|
| 56 |
+Nice const & Config::getNice() const {
|
|
| 57 |
+ return nice; |
|
| 58 |
+} |
|
| 59 |
+ |
|
| 52 | 60 |
TreeMap const & Config::getTrees() const {
|
| 53 | 61 |
return trees; |
| 54 | 62 |
} |
| ... | ... |
@@ -0,0 +1,64 @@ |
| 1 |
+/** |
|
| 2 |
+ * Permissioner: set file ownerships and permissions |
|
| 3 |
+ * Copyright 2020: Stefan Schuermans, Aachen, Germany <stefan@schuermans.info> |
|
| 4 |
+ * Copyleft: GNU GENERAL PUBLIC LICENSE version 3 (see LICENSE) |
|
| 5 |
+ */ |
|
| 6 |
+ |
|
| 7 |
+#include <permissioner/Nice.h> |
|
| 8 |
+ |
|
| 9 |
+#include <permissioner/StringUtils.h> |
|
| 10 |
+ |
|
| 11 |
+#include <boost/optional.hpp> |
|
| 12 |
+#include <string> |
|
| 13 |
+#include <sys/time.h> |
|
| 14 |
+#include <sys/resource.h> |
|
| 15 |
+#include <sys/syscall.h> |
|
| 16 |
+ |
|
| 17 |
+#define IOPRIO_CLASS_SHIFT (13) |
|
| 18 |
+#define IOPRIO_PRIO_VALUE(class_, data) (((class_) << IOPRIO_CLASS_SHIFT) | data) |
|
| 19 |
+enum {
|
|
| 20 |
+ IOPRIO_WHO_PROCESS = 1, |
|
| 21 |
+ IOPRIO_WHO_PGRP, |
|
| 22 |
+ IOPRIO_WHO_USER, |
|
| 23 |
+}; |
|
| 24 |
+enum {
|
|
| 25 |
+ IOPRIO_CLASS_NONE, |
|
| 26 |
+ IOPRIO_CLASS_RT, |
|
| 27 |
+ IOPRIO_CLASS_BE, |
|
| 28 |
+ IOPRIO_CLASS_IDLE, |
|
| 29 |
+}; |
|
| 30 |
+ |
|
| 31 |
+Nice::Nice() : ioIdle(false) {}
|
|
| 32 |
+ |
|
| 33 |
+void Nice::parseParams(std::string const ¶mStr) {
|
|
| 34 |
+ // format of paramStr is: <nice prm 1> [" " <nice prm 2>] |
|
| 35 |
+ // <nice prm> may be <nice value: int> or "idle" |
|
| 36 |
+ std::string niceStr; |
|
| 37 |
+ |
|
| 38 |
+ std::string::size_type pos = 0; |
|
| 39 |
+ while (pos < paramStr.length()) {
|
|
| 40 |
+ StringUtils::getNextField(paramStr, pos, niceStr, "nice prm"); |
|
| 41 |
+ if (niceStr == "idle") {
|
|
| 42 |
+ ioIdle = true; |
|
| 43 |
+ continue; |
|
| 44 |
+ } |
|
| 45 |
+ nice = StringUtils::str2intRange(niceStr, -20, 19, "nice value"); |
|
| 46 |
+ } |
|
| 47 |
+} |
|
| 48 |
+ |
|
| 49 |
+boost::optional<int> Nice::getNice() const { return nice; }
|
|
| 50 |
+ |
|
| 51 |
+bool Nice::getIoIdle() const { return ioIdle; }
|
|
| 52 |
+ |
|
| 53 |
+void Nice::apply() const {
|
|
| 54 |
+ // set CPU priority |
|
| 55 |
+ if (nice.is_initialized()) {
|
|
| 56 |
+ setpriority(PRIO_PROCESS, 0, nice.get()); |
|
| 57 |
+ } |
|
| 58 |
+ |
|
| 59 |
+ // set idle I/O priority |
|
| 60 |
+ if (ioIdle) {
|
|
| 61 |
+ syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, 0, |
|
| 62 |
+ IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0)); |
|
| 63 |
+ } |
|
| 64 |
+} |
| ... | ... |
@@ -6,8 +6,9 @@ |
| 6 | 6 |
|
| 7 | 7 |
#include <permissioner/StringUtils.h> |
| 8 | 8 |
|
| 9 |
-#include <stdexcept> |
|
| 9 |
+#include <cstdlib> |
|
| 10 | 10 |
#include <sstream> |
| 11 |
+#include <stdexcept> |
|
| 11 | 12 |
#include <string> |
| 12 | 13 |
|
| 13 | 14 |
void StringUtils::getNextField(std::string const &str, |
| ... | ... |
@@ -33,3 +34,27 @@ void StringUtils::getNextField(std::string const &str, |
| 33 | 34 |
pos = str.length(); |
| 34 | 35 |
} |
| 35 | 36 |
} |
| 37 |
+ |
|
| 38 |
+long StringUtils::str2long(std::string const &str, std::string const &name) {
|
|
| 39 |
+ char const *c_str = str.c_str(); |
|
| 40 |
+ char *end; |
|
| 41 |
+ long val = strtol(c_str, &end, 0); |
|
| 42 |
+ if (end == c_str || *end != 0) {
|
|
| 43 |
+ std::stringstream msg; |
|
| 44 |
+ msg << "invalid integer value \"" << str << "\" for <" << name << "> field"; |
|
| 45 |
+ throw std::runtime_error(msg.str()); |
|
| 46 |
+ } |
|
| 47 |
+ return val; |
|
| 48 |
+} |
|
| 49 |
+ |
|
| 50 |
+int StringUtils::str2intRange(std::string const &str, int minVal, int maxVal, |
|
| 51 |
+ std::string const &name) {
|
|
| 52 |
+ long val = str2long(str, name); |
|
| 53 |
+ if (val < minVal || val > maxVal) {
|
|
| 54 |
+ std::stringstream msg; |
|
| 55 |
+ msg << "value " << val << "of <" << name << "> field out of range " |
|
| 56 |
+ << minVal << " - " << maxVal; |
|
| 57 |
+ throw std::runtime_error(msg.str()); |
|
| 58 |
+ } |
|
| 59 |
+ return val; |
|
| 60 |
+} |
| ... | ... |
@@ -45,6 +45,9 @@ int main(int argc, char const **argv) {
|
| 45 | 45 |
std::cout << "permissionerd (" << configFileName << ") starting"
|
| 46 | 46 |
<< std::endl; |
| 47 | 47 |
|
| 48 |
+ // set nicecess of process |
|
| 49 |
+ config.getNice().apply(); |
|
| 50 |
+ |
|
| 48 | 51 |
// continuously set ownership and permissions |
| 49 | 52 |
int ret = EXIT_SUCCESS; |
| 50 | 53 |
while (go_on) {
|
| ... | ... |
@@ -0,0 +1 @@ |
| 1 |
+# comment |
| ... | ... |
@@ -0,0 +1 @@ |
| 1 |
+nice idle |
| ... | ... |
@@ -0,0 +1 @@ |
| 1 |
+nice 19 |
| ... | ... |
@@ -0,0 +1 @@ |
| 1 |
+nice 19 idle |
| ... | ... |
@@ -7,8 +7,8 @@ |
| 7 | 7 |
#include <permissioner/Config.h> |
| 8 | 8 |
#include <permissioner/Group.h> |
| 9 | 9 |
#include <permissioner/Permissions.h> |
| 10 |
-#include <permissioner/User.h> |
|
| 11 | 10 |
#include <permissioner/Tree.h> |
| 11 |
+#include <permissioner/User.h> |
|
| 12 | 12 |
|
| 13 | 13 |
#include <boost/filesystem.hpp> |
| 14 | 14 |
#include <boost/optional.hpp> |
| ... | ... |
@@ -18,11 +18,95 @@ |
| 18 | 18 |
#include <iostream> |
| 19 | 19 |
#include <string> |
| 20 | 20 |
|
| 21 |
-bool check(TreeMap const &treeMap, std::string const &rel_path, |
|
| 21 |
+int testEmpty() {
|
|
| 22 |
+ Config config; |
|
| 23 |
+ config.parseFile("empty.cfg");
|
|
| 24 |
+ |
|
| 25 |
+ int ret = EXIT_SUCCESS; |
|
| 26 |
+ |
|
| 27 |
+ Nice const &nice = config.getNice(); |
|
| 28 |
+ if (nice.getNice().is_initialized()) {
|
|
| 29 |
+ std::cerr << "unexpected nice value: " << nice.getNice().get() << std::endl; |
|
| 30 |
+ ret = EXIT_FAILURE; |
|
| 31 |
+ } |
|
| 32 |
+ if (nice.getIoIdle()) {
|
|
| 33 |
+ std::cerr << "unexpected I/O idle" << std::endl; |
|
| 34 |
+ ret = EXIT_FAILURE; |
|
| 35 |
+ } |
|
| 36 |
+ |
|
| 37 |
+ TreeMap const &treeMap = config.getTrees(); |
|
| 38 |
+ if (treeMap.size() != 0) {
|
|
| 39 |
+ std::cerr << "unexpected trees: " << treeMap.size() << std::endl; |
|
| 40 |
+ ret = EXIT_FAILURE; |
|
| 41 |
+ } |
|
| 42 |
+ |
|
| 43 |
+ return ret; |
|
| 44 |
+} |
|
| 45 |
+ |
|
| 46 |
+int testNice() {
|
|
| 47 |
+ int ret = EXIT_SUCCESS; |
|
| 48 |
+ |
|
| 49 |
+ {
|
|
| 50 |
+ Config config; |
|
| 51 |
+ config.parseFile("nice.cfg");
|
|
| 52 |
+ |
|
| 53 |
+ Nice const &nice = config.getNice(); |
|
| 54 |
+ if (!nice.getNice().is_initialized()) {
|
|
| 55 |
+ std::cerr << "expected nice value, but got none" << std::endl; |
|
| 56 |
+ ret = EXIT_FAILURE; |
|
| 57 |
+ } else {
|
|
| 58 |
+ if (nice.getNice().get() != 19) {
|
|
| 59 |
+ std::cerr << "unexpected nice value: " << nice.getNice().get() |
|
| 60 |
+ << ", expected 19" << std::endl; |
|
| 61 |
+ ret = EXIT_FAILURE; |
|
| 62 |
+ } |
|
| 63 |
+ } |
|
| 64 |
+ if (nice.getIoIdle()) {
|
|
| 65 |
+ std::cerr << "unexpected I/O idle" << std::endl; |
|
| 66 |
+ ret = EXIT_FAILURE; |
|
| 67 |
+ } |
|
| 68 |
+ } |
|
| 69 |
+ |
|
| 70 |
+ {
|
|
| 71 |
+ Config config; |
|
| 72 |
+ config.parseFile("idle.cfg");
|
|
| 73 |
+ |
|
| 74 |
+ Nice const &nice = config.getNice(); |
|
| 75 |
+ if (nice.getNice().is_initialized()) {
|
|
| 76 |
+ std::cerr << "unexpected nice value: " << nice.getNice().get() |
|
| 77 |
+ << std::endl; |
|
| 78 |
+ ret = EXIT_FAILURE; |
|
| 79 |
+ } |
|
| 80 |
+ if (!nice.getIoIdle()) {
|
|
| 81 |
+ std::cerr << "expected I/O idle, but did not get it" << std::endl; |
|
| 82 |
+ ret = EXIT_FAILURE; |
|
| 83 |
+ } |
|
| 84 |
+ } |
|
| 85 |
+ |
|
| 86 |
+ {
|
|
| 87 |
+ Config config; |
|
| 88 |
+ config.parseFile("nice_idle.cfg");
|
|
| 89 |
+ |
|
| 90 |
+ Nice const &nice = config.getNice(); |
|
| 91 |
+ if (!nice.getNice().is_initialized()) {
|
|
| 92 |
+ std::cerr << "expected nice value, but got none" << std::endl; |
|
| 93 |
+ ret = EXIT_FAILURE; |
|
| 94 |
+ } else {
|
|
| 95 |
+ if (nice.getNice().get() != 19) {
|
|
| 96 |
+ std::cerr << "unexpected nice value: " << nice.getNice().get() |
|
| 97 |
+ << ", expected 19" << std::endl; |
|
| 98 |
+ ret = EXIT_FAILURE; |
|
| 99 |
+ } |
|
| 100 |
+ } |
|
| 101 |
+ } |
|
| 102 |
+ |
|
| 103 |
+ return ret; |
|
| 104 |
+} |
|
| 105 |
+ |
|
| 106 |
+bool checkTrees(TreeMap const &treeMap, std::string const &rel_path, |
|
| 22 | 107 |
boost::optional<std::string> user, |
| 23 |
- boost::optional<std::string> group, |
|
| 24 |
- mode_t setMode, mode_t setCondMode, |
|
| 25 |
- mode_t clearMode, mode_t clearCondMode) {
|
|
| 108 |
+ boost::optional<std::string> group, mode_t setMode, |
|
| 109 |
+ mode_t setCondMode, mode_t clearMode, mode_t clearCondMode) {
|
|
| 26 | 110 |
std::string path = boost::filesystem::canonical(rel_path).string(); |
| 27 | 111 |
TreeMap::const_iterator itTree = treeMap.find(path); |
| 28 | 112 |
if (itTree == treeMap.end()) {
|
| ... | ... |
@@ -50,41 +134,37 @@ bool check(TreeMap const &treeMap, std::string const &rel_path, |
| 50 | 134 |
} |
| 51 | 135 |
Permissions const &perms = tree.getPermissions(); |
| 52 | 136 |
if (perms.getSet() != setMode) {
|
| 53 |
- std::cerr << "tree map entry \"" << path |
|
| 54 |
- << "\": unexpected set mode " |
|
| 55 |
- << std::oct << perms.getSet() << " != " << setMode |
|
| 56 |
- << std::dec << std::endl; |
|
| 137 |
+ std::cerr << "tree map entry \"" << path << "\": unexpected set mode " |
|
| 138 |
+ << std::oct << perms.getSet() << " != " << setMode << std::dec |
|
| 139 |
+ << std::endl; |
|
| 57 | 140 |
ret = false; |
| 58 | 141 |
} |
| 59 | 142 |
if (perms.getSetCond() != setCondMode) {
|
| 60 |
- std::cerr << "tree map entry \"" << path |
|
| 61 |
- << "\": unexpected set cond mode " |
|
| 143 |
+ std::cerr << "tree map entry \"" << path << "\": unexpected set cond mode " |
|
| 62 | 144 |
<< std::oct << perms.getSetCond() << " != " << setCondMode |
| 63 | 145 |
<< std::dec << std::endl; |
| 64 | 146 |
ret = false; |
| 65 | 147 |
} |
| 66 | 148 |
if (perms.getClear() != clearMode) {
|
| 67 |
- std::cerr << "tree map entry \"" << path |
|
| 68 |
- << "\": unexpected clear mode " |
|
| 69 |
- << std::oct << perms.getClear() << " != " << clearMode |
|
| 70 |
- << std::dec << std::endl; |
|
| 149 |
+ std::cerr << "tree map entry \"" << path << "\": unexpected clear mode " |
|
| 150 |
+ << std::oct << perms.getClear() << " != " << clearMode << std::dec |
|
| 151 |
+ << std::endl; |
|
| 71 | 152 |
ret = false; |
| 72 | 153 |
} |
| 73 | 154 |
if (perms.getClearCond() != clearCondMode) {
|
| 74 | 155 |
std::cerr << "tree map entry \"" << path |
| 75 |
- << "\": unexpected clear cond mode " |
|
| 76 |
- << std::oct << perms.getClearCond() << " != " << clearCondMode |
|
| 77 |
- << std::dec << std::endl; |
|
| 156 |
+ << "\": unexpected clear cond mode " << std::oct |
|
| 157 |
+ << perms.getClearCond() << " != " << clearCondMode << std::dec |
|
| 158 |
+ << std::endl; |
|
| 78 | 159 |
ret = false; |
| 79 | 160 |
} |
| 80 | 161 |
|
| 81 | 162 |
return ret; |
| 82 | 163 |
} |
| 83 | 164 |
|
| 84 |
-int main(int argc, char const **argv) {
|
|
| 85 |
- (void)argc; |
|
| 165 |
+int testTrees() {
|
|
| 86 | 166 |
Config config; |
| 87 |
- config.parseFile(argv[1]); |
|
| 167 |
+ config.parseFile("trees.cfg");
|
|
| 88 | 168 |
|
| 89 | 169 |
int ret = EXIT_SUCCESS; |
| 90 | 170 |
|
| ... | ... |
@@ -93,16 +173,28 @@ int main(int argc, char const **argv) {
|
| 93 | 173 |
std::cerr << "unexpected number of trees: " << treeMap.size() << std::endl; |
| 94 | 174 |
ret = EXIT_FAILURE; |
| 95 | 175 |
} |
| 96 |
- if (! check(treeMap, "some/dir", std::string("nobody"),
|
|
| 97 |
- std::string("nogroup"),
|
|
| 98 |
- 0011, 0044, 0022, 000)) {
|
|
| 176 |
+ if (!checkTrees(treeMap, "some/dir", std::string("nobody"),
|
|
| 177 |
+ std::string("nogroup"), 0011, 0044, 0022, 000)) {
|
|
| 99 | 178 |
ret = EXIT_FAILURE; |
| 100 | 179 |
} |
| 101 |
- if (! check(treeMap, "some/other/dir", boost::none, |
|
| 102 |
- boost::none, |
|
| 103 |
- 0777, 0000, 0000, 0000)) {
|
|
| 180 |
+ if (!checkTrees(treeMap, "some/other/dir", boost::none, boost::none, 0777, |
|
| 181 |
+ 0000, 0000, 0000)) {
|
|
| 104 | 182 |
ret = EXIT_FAILURE; |
| 105 | 183 |
} |
| 106 | 184 |
|
| 107 | 185 |
return ret; |
| 108 | 186 |
} |
| 187 |
+ |
|
| 188 |
+void merge_ret(int &ret, int ret2) {
|
|
| 189 |
+ if (ret == EXIT_SUCCESS && ret2 != EXIT_SUCCESS) {
|
|
| 190 |
+ ret = ret2; |
|
| 191 |
+ } |
|
| 192 |
+} |
|
| 193 |
+ |
|
| 194 |
+int main() {
|
|
| 195 |
+ int ret = EXIT_SUCCESS; |
|
| 196 |
+ merge_ret(ret, testEmpty()); |
|
| 197 |
+ merge_ret(ret, testNice()); |
|
| 198 |
+ merge_ret(ret, testTrees()); |
|
| 199 |
+ return ret; |
|
| 200 |
+} |