LCOV - code coverage report
Current view: top level - analyze - analyze-condition.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 0 50 0.0 %
Date: 2019-08-22 15:41:25 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <stdlib.h>
       4             : 
       5             : #include "analyze-condition.h"
       6             : #include "condition.h"
       7             : #include "conf-parser.h"
       8             : #include "load-fragment.h"
       9             : #include "service.h"
      10             : 
      11             : typedef struct condition_definition {
      12             :         const char *name;
      13             :         ConfigParserCallback parser;
      14             :         ConditionType type;
      15             : } condition_definition;
      16             : 
      17             : static const condition_definition condition_definitions[] = {
      18             :         { "ConditionPathExists",             config_parse_unit_condition_path,   CONDITION_PATH_EXISTS              },
      19             :         { "ConditionPathExistsGlob",         config_parse_unit_condition_path,   CONDITION_PATH_EXISTS_GLOB         },
      20             :         { "ConditionPathIsDirectory",        config_parse_unit_condition_path,   CONDITION_PATH_IS_DIRECTORY        },
      21             :         { "ConditionPathIsSymbolicLink",     config_parse_unit_condition_path,   CONDITION_PATH_IS_SYMBOLIC_LINK    },
      22             :         { "ConditionPathIsMountPoint",       config_parse_unit_condition_path,   CONDITION_PATH_IS_MOUNT_POINT      },
      23             :         { "ConditionPathIsReadWrite",        config_parse_unit_condition_path,   CONDITION_PATH_IS_READ_WRITE       },
      24             :         { "ConditionDirectoryNotEmpty",      config_parse_unit_condition_path,   CONDITION_DIRECTORY_NOT_EMPTY      },
      25             :         { "ConditionFileNotEmpty",           config_parse_unit_condition_path,   CONDITION_FILE_NOT_EMPTY           },
      26             :         { "ConditionFileIsExecutable",       config_parse_unit_condition_path,   CONDITION_FILE_IS_EXECUTABLE       },
      27             :         { "ConditionNeedsUpdate",            config_parse_unit_condition_path,   CONDITION_NEEDS_UPDATE             },
      28             :         { "ConditionFirstBoot",              config_parse_unit_condition_string, CONDITION_FIRST_BOOT               },
      29             :         { "ConditionKernelCommandLine",      config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE      },
      30             :         { "ConditionKernelVersion",          config_parse_unit_condition_string, CONDITION_KERNEL_VERSION           },
      31             :         { "ConditionArchitecture",           config_parse_unit_condition_string, CONDITION_ARCHITECTURE             },
      32             :         { "ConditionVirtualization",         config_parse_unit_condition_string, CONDITION_VIRTUALIZATION           },
      33             :         { "ConditionSecurity",               config_parse_unit_condition_string, CONDITION_SECURITY                 },
      34             :         { "ConditionCapability",             config_parse_unit_condition_string, CONDITION_CAPABILITY               },
      35             :         { "ConditionHost",                   config_parse_unit_condition_string, CONDITION_HOST                     },
      36             :         { "ConditionACPower",                config_parse_unit_condition_string, CONDITION_AC_POWER                 },
      37             :         { "ConditionUser",                   config_parse_unit_condition_string, CONDITION_USER                     },
      38             :         { "ConditionGroup",                  config_parse_unit_condition_string, CONDITION_GROUP                    },
      39             :         { "ConditionControlGroupController", config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER },
      40             : 
      41             :         { "AssertPathExists",                config_parse_unit_condition_path,   CONDITION_PATH_EXISTS              },
      42             :         { "AssertPathExistsGlob",            config_parse_unit_condition_path,   CONDITION_PATH_EXISTS_GLOB         },
      43             :         { "AssertPathIsDirectory",           config_parse_unit_condition_path,   CONDITION_PATH_IS_DIRECTORY        },
      44             :         { "AssertPathIsSymbolicLink",        config_parse_unit_condition_path,   CONDITION_PATH_IS_SYMBOLIC_LINK    },
      45             :         { "AssertPathIsMountPoint",          config_parse_unit_condition_path,   CONDITION_PATH_IS_MOUNT_POINT      },
      46             :         { "AssertPathIsReadWrite",           config_parse_unit_condition_path,   CONDITION_PATH_IS_READ_WRITE       },
      47             :         { "AssertDirectoryNotEmpty",         config_parse_unit_condition_path,   CONDITION_DIRECTORY_NOT_EMPTY      },
      48             :         { "AssertFileNotEmpty",              config_parse_unit_condition_path,   CONDITION_FILE_NOT_EMPTY           },
      49             :         { "AssertFileIsExecutable",          config_parse_unit_condition_path,   CONDITION_FILE_IS_EXECUTABLE       },
      50             :         { "AssertNeedsUpdate",               config_parse_unit_condition_path,   CONDITION_NEEDS_UPDATE             },
      51             :         { "AssertFirstBoot",                 config_parse_unit_condition_string, CONDITION_FIRST_BOOT               },
      52             :         { "AssertKernelCommandLine",         config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE      },
      53             :         { "AssertKernelVersion",             config_parse_unit_condition_string, CONDITION_KERNEL_VERSION           },
      54             :         { "AssertArchitecture",              config_parse_unit_condition_string, CONDITION_ARCHITECTURE             },
      55             :         { "AssertVirtualization",            config_parse_unit_condition_string, CONDITION_VIRTUALIZATION           },
      56             :         { "AssertSecurity",                  config_parse_unit_condition_string, CONDITION_SECURITY                 },
      57             :         { "AssertCapability",                config_parse_unit_condition_string, CONDITION_CAPABILITY               },
      58             :         { "AssertHost",                      config_parse_unit_condition_string, CONDITION_HOST                     },
      59             :         { "AssertACPower",                   config_parse_unit_condition_string, CONDITION_AC_POWER                 },
      60             :         { "AssertUser",                      config_parse_unit_condition_string, CONDITION_USER                     },
      61             :         { "AssertGroup",                     config_parse_unit_condition_string, CONDITION_GROUP                    },
      62             :         { "AssertControlGroupController",    config_parse_unit_condition_string, CONDITION_CONTROL_GROUP_CONTROLLER },
      63             : 
      64             :         /* deprecated, but we should still parse them */
      65             :         { "ConditionNull",                   config_parse_unit_condition_null,   0                                  },
      66             :         { "AssertNull",                      config_parse_unit_condition_null,   0                                  },
      67             : };
      68             : 
      69           0 : static int parse_condition(Unit *u, const char *line) {
      70             :         const char *p;
      71             :         Condition **target;
      72             : 
      73           0 :         if ((p = startswith(line, "Condition")))
      74           0 :                 target = &u->conditions;
      75           0 :         else if ((p = startswith(line, "Assert")))
      76           0 :                 target = &u->asserts;
      77             :         else
      78           0 :                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot parse \"%s\".", line);
      79             : 
      80           0 :         for (size_t i = 0; i < ELEMENTSOF(condition_definitions); i++) {
      81           0 :                 const condition_definition *c = &condition_definitions[i];
      82             : 
      83           0 :                 p = startswith(line, c->name);
      84           0 :                 if (!p)
      85           0 :                         continue;
      86           0 :                 p += strspn(p, WHITESPACE);
      87           0 :                 if (*p != '=')
      88           0 :                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Expected \"=\" in \"%s\".", line);
      89             : 
      90           0 :                 p += 1 + strspn(p + 1, WHITESPACE);
      91             : 
      92           0 :                 return c->parser(NULL, "(stdin)", 0, NULL, 0, c->name, c->type, p, target, u);
      93             :         }
      94             : 
      95           0 :         return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot parse \"%s\".", line);
      96             : }
      97             : 
      98             : _printf_(7, 8)
      99           0 : static int log_helper(void *userdata, int level, int error, const char *file, int line, const char *func, const char *format, ...) {
     100           0 :         Unit *u = userdata;
     101             :         va_list ap;
     102             :         int r;
     103             : 
     104           0 :         assert(u);
     105             : 
     106             :         /* "upgrade" debug messages */
     107           0 :         level = MIN(LOG_INFO, level);
     108             : 
     109           0 :         va_start(ap, format);
     110           0 :         r = log_object_internalv(level, error, file, line, func,
     111             :                                  NULL,
     112           0 :                                  u->id,
     113             :                                  NULL,
     114             :                                  NULL,
     115             :                                  format, ap);
     116           0 :         va_end(ap);
     117             : 
     118           0 :         return r;
     119             : }
     120             : 
     121           0 : int verify_conditions(char **lines, UnitFileScope scope) {
     122           0 :         _cleanup_(manager_freep) Manager *m = NULL;
     123             :         Unit *u;
     124             :         char **line;
     125           0 :         int r, q = 1;
     126             : 
     127           0 :         r = manager_new(scope, MANAGER_TEST_RUN_MINIMAL, &m);
     128           0 :         if (r < 0)
     129           0 :                 return log_error_errno(r, "Failed to initialize manager: %m");
     130             : 
     131           0 :         log_debug("Starting manager...");
     132           0 :         r = manager_startup(m, NULL, NULL);
     133           0 :         if (r < 0)
     134           0 :                 return r;
     135             : 
     136           0 :         r = unit_new_for_name(m, sizeof(Service), "test.service", &u);
     137           0 :         if (r < 0)
     138           0 :                 return log_error_errno(r, "Failed to create test.service: %m");
     139             : 
     140           0 :         STRV_FOREACH(line, lines) {
     141           0 :                 r = parse_condition(u, *line);
     142           0 :                 if (r < 0)
     143           0 :                         return r;
     144             :         }
     145             : 
     146           0 :         r = condition_test_list(u->asserts, assert_type_to_string, log_helper, u);
     147           0 :         if (u->asserts)
     148           0 :                 log_notice("Asserts %s.", r > 0 ? "succeeded" : "failed");
     149             : 
     150           0 :         q = condition_test_list(u->conditions, condition_type_to_string, log_helper, u);
     151           0 :         if (u->conditions)
     152           0 :                 log_notice("Conditions %s.", q > 0 ? "succeeded" : "failed");
     153             : 
     154           0 :         return r > 0 && q > 0 ? 0 : -EIO;
     155             : }

Generated by: LCOV version 1.14