Service description loading: improve error messages
authorDavin McCall <davmac@davmac.org>
Tue, 19 Nov 2019 18:10:27 +0000 (18:10 +0000)
committerDavin McCall <davmac@davmac.org>
Tue, 19 Nov 2019 18:10:27 +0000 (18:10 +0000)
Include parameter name and improve consistency in error messages when
parsing service descriptions.

src/dinitcheck.cc
src/includes/load-service.h
src/load-service.cc

index 37507dd866427c06516211cafc76051be2124cec..302e9ae817d96d763505955c4139b9599f83cbc8 100644 (file)
@@ -126,7 +126,7 @@ int main(int argc, char **argv)
 
 static void report_unknown_setting_error(const std::string &service_name, const char *setting_name)
 {
-    std::cerr << "Service '" << service_name << "', unknown setting: " << setting_name << "\n";
+    std::cerr << "Service '" << service_name << "', unknown setting: '" << setting_name << "'.\n";
 }
 
 static void report_error(dinit_load::setting_exception &exc, const std::string &service_name, const char *setting_name)
@@ -134,6 +134,11 @@ static void report_error(dinit_load::setting_exception &exc, const std::string &
     std::cerr << "Service '" << service_name << "', " << setting_name << ": " << exc.get_info() << "\n";
 }
 
+static void report_service_description_exc(service_description_exc &exc)
+{
+    std::cerr << "Service '" << exc.service_name << "': " << exc.exc_description << "\n";
+}
+
 static void report_error(std::system_error &exc, const std::string &service_name)
 {
     std::cerr << "Service '" << service_name << "', error reading service description: " << exc.what() << "\n";
@@ -290,11 +295,11 @@ service_record *load_service(service_set_t &services, const std::string &name,
                 }
                 else if (setting == "socket-uid") {
                     string sock_uid_s = read_setting_value(i, end, nullptr);
-                    socket_uid = parse_uid_param(sock_uid_s, name, &socket_gid);
+                    socket_uid = parse_uid_param(sock_uid_s, name, "socket-uid", &socket_gid);
                 }
                 else if (setting == "socket-gid") {
                     string sock_gid_s = read_setting_value(i, end, nullptr);
-                    socket_gid = parse_gid_param(sock_gid_s, name);
+                    socket_gid = parse_gid_param(sock_gid_s, "socket-gid", name);
                 }
                 else if (setting == "stop-command") {
                     stop_command = read_setting_value(i, end, &stop_command_offsets);
@@ -448,7 +453,7 @@ service_record *load_service(service_set_t &services, const std::string &name,
                 }
                 else if (setting == "run-as") {
                     string run_as_str = read_setting_value(i, end, nullptr);
-                    run_as_uid = parse_uid_param(run_as_str, name, &run_as_gid);
+                    run_as_uid = parse_uid_param(run_as_str, name, "run-as", &run_as_gid);
                 }
                 else if (setting == "chain-to") {
                     chain_to_name = read_setting_value(i, end, nullptr);
@@ -515,6 +520,9 @@ service_record *load_service(service_set_t &services, const std::string &name,
                     report_unknown_setting_error(name, setting.c_str());
                 }
             }
+            catch (service_description_exc &exc) {
+                report_service_description_exc(exc);
+            }
             catch (setting_exception &exc) {
                 report_error(exc, name, setting.c_str());
             }
index cff1cfe32c1cdffccf97edb40938bf0c8ab5a6c2..d19bac16ebdcbf4f3afa1dabf28cd9cdb319a98b 100644 (file)
@@ -273,7 +273,7 @@ inline string read_setting_value(string_iterator & i, string_iterator end,
 // userid is looked up via the system user database (getpwnam() function). In this case,
 // the associated group is stored in the location specified by the group_p parameter iff
 // it is not null and iff it contains the value -1.
-inline uid_t parse_uid_param(const std::string &param, const std::string &service_name, gid_t *group_p)
+inline uid_t parse_uid_param(const std::string &param, const std::string &service_name, const char *setting_name, gid_t *group_p)
 {
     const char * uid_err_msg = "Specified user id contains invalid numeric characters "
             "or is outside allowed range.";
@@ -291,7 +291,7 @@ inline uid_t parse_uid_param(const std::string &param, const std::string &servic
         unsigned long long v = std::stoull(param, &ind, 0);
         if (v > static_cast<unsigned long long>(std::numeric_limits<uid_t>::max())
                 || ind != param.length()) {
-            throw service_description_exc(service_name, uid_err_msg);
+            throw service_description_exc(service_name, std::string(setting_name) + ": " + uid_err_msg);
         }
         return v;
     }
@@ -307,7 +307,7 @@ inline uid_t parse_uid_param(const std::string &param, const std::string &servic
     if (pwent == nullptr) {
         // Maybe an error, maybe just no entry.
         if (errno == 0) {
-            throw service_description_exc(service_name, "Specified user \"" + param
+            throw service_description_exc(service_name, std::string(setting_name) + ": Specified user \"" + param
                     + "\" does not exist in system database.");
         }
         else {
@@ -323,7 +323,7 @@ inline uid_t parse_uid_param(const std::string &param, const std::string &servic
     return pwent->pw_uid;
 }
 
-inline gid_t parse_gid_param(const std::string &param, const std::string &service_name)
+inline gid_t parse_gid_param(const std::string &param, const char *setting_name, const std::string &service_name)
 {
     const char * gid_err_msg = "Specified group id contains invalid numeric characters or is "
             "outside allowed range.";
@@ -341,12 +341,12 @@ inline gid_t parse_gid_param(const std::string &param, const std::string &servic
         unsigned long long v = std::stoull(param, &ind, 0);
         if (v > static_cast<unsigned long long>(std::numeric_limits<gid_t>::max())
                 || ind != param.length()) {
-            throw service_description_exc(service_name, gid_err_msg);
+            throw service_description_exc(service_name, std::string(setting_name) + ": " + gid_err_msg);
         }
         return v;
     }
     catch (std::out_of_range &exc) {
-        throw service_description_exc(service_name, gid_err_msg);
+        throw service_description_exc(service_name, std::string(setting_name) + ": " + gid_err_msg);
     }
     catch (std::invalid_argument &exc) {
         // Ok, so it doesn't look like a number: proceed...
@@ -357,7 +357,7 @@ inline gid_t parse_gid_param(const std::string &param, const std::string &servic
     if (grent == nullptr) {
         // Maybe an error, maybe just no entry.
         if (errno == 0) {
-            throw service_description_exc(service_name, "Specified group \"" + param
+            throw service_description_exc(service_name, std::string(setting_name) + ": Specified group \"" + param
                     + "\" does not exist in system database.");
         }
         else {
@@ -455,7 +455,7 @@ inline void parse_rlimit(const std::string &line, const std::string &service_nam
     // 4     soft and hard limit set to same limit
 
     if (line.empty()) {
-        throw service_description_exc(service_name, std::string("Bad value for ") + param_name);
+        throw service_description_exc(service_name, std::string(param_name) + ": Bad value.");
     }
 
     const char *cline = line.c_str();
@@ -486,7 +486,7 @@ inline void parse_rlimit(const std::string &line, const std::string &service_nam
             }
 
             if (*index != ':') {
-                throw service_description_exc(service_name, std::string("Bad value for ") + param_name);
+                throw service_description_exc(service_name, std::string(param_name) + ": Bad value.");
             }
         }
 
@@ -496,7 +496,7 @@ inline void parse_rlimit(const std::string &line, const std::string &service_nam
         if (*index == '-') {
             rlimit.limits.rlim_max = RLIM_INFINITY;
             if (index[1] != 0) {
-                throw service_description_exc(service_name, std::string("Bad value for ") + param_name);
+                throw service_description_exc(service_name, std::string(param_name) + ": Bad value.");
             }
         }
         else {
@@ -510,10 +510,10 @@ inline void parse_rlimit(const std::string &line, const std::string &service_nam
         }
     }
     catch (std::invalid_argument &exc) {
-        throw service_description_exc(service_name, std::string("Bad value for ") + param_name);
+        throw service_description_exc(service_name, std::string(param_name) + ": Bad value.");
     }
     catch (std::out_of_range &exc) {
-        throw service_description_exc(service_name, std::string("Too-large value for ") + param_name);
+        throw service_description_exc(service_name, std::string(param_name) + ": Too-large value.");
     }
 }
 
index 612c54e51de6b4d8640cf2d2b8352c5b82496080..791f05b23c0624240da87102b6a4101bce24d4e7 100644 (file)
@@ -245,11 +245,11 @@ service_record * dirload_service_set::load_service(const char * name)
             }
             else if (setting == "socket-uid") {
                 string sock_uid_s = read_setting_value(i, end, nullptr);
-                socket_uid = parse_uid_param(sock_uid_s, name, &socket_gid);
+                socket_uid = parse_uid_param(sock_uid_s, name, "socket-uid", &socket_gid);
             }
             else if (setting == "socket-gid") {
                 string sock_gid_s = read_setting_value(i, end, nullptr);
-                socket_gid = parse_gid_param(sock_gid_s, name);
+                socket_gid = parse_gid_param(sock_gid_s, "socket-gid", name);
             }
             else if (setting == "stop-command") {
                 stop_command = read_setting_value(i, end, &stop_command_offsets);
@@ -403,7 +403,7 @@ service_record * dirload_service_set::load_service(const char * name)
             }
             else if (setting == "run-as") {
                 string run_as_str = read_setting_value(i, end, nullptr);
-                run_as_uid = parse_uid_param(run_as_str, name, &run_as_gid);
+                run_as_uid = parse_uid_param(run_as_str, name, "run-as", &run_as_gid);
             }
             else if (setting == "chain-to") {
                 chain_to_name = read_setting_value(i, end, nullptr);