LCOV - code coverage report
Current view: top level - shared - conf-parser.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 290 468 62.0 %
Date: 2019-08-23 13:36:53 Functions: 23 38 60.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 234 628 37.3 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <limits.h>
       5                 :            : #include <stdint.h>
       6                 :            : #include <stdio.h>
       7                 :            : #include <stdlib.h>
       8                 :            : #include <string.h>
       9                 :            : #include <sys/types.h>
      10                 :            : 
      11                 :            : #include "alloc-util.h"
      12                 :            : #include "conf-files.h"
      13                 :            : #include "conf-parser.h"
      14                 :            : #include "def.h"
      15                 :            : #include "extract-word.h"
      16                 :            : #include "fd-util.h"
      17                 :            : #include "fileio.h"
      18                 :            : #include "fs-util.h"
      19                 :            : #include "log.h"
      20                 :            : #include "macro.h"
      21                 :            : #include "missing.h"
      22                 :            : #include "nulstr-util.h"
      23                 :            : #include "parse-util.h"
      24                 :            : #include "path-util.h"
      25                 :            : #include "process-util.h"
      26                 :            : #include "rlimit-util.h"
      27                 :            : #include "signal-util.h"
      28                 :            : #include "socket-util.h"
      29                 :            : #include "string-util.h"
      30                 :            : #include "strv.h"
      31                 :            : #include "syslog-util.h"
      32                 :            : #include "time-util.h"
      33                 :            : #include "utf8.h"
      34                 :            : 
      35                 :      20904 : int config_item_table_lookup(
      36                 :            :                 const void *table,
      37                 :            :                 const char *section,
      38                 :            :                 const char *lvalue,
      39                 :            :                 ConfigParserCallback *func,
      40                 :            :                 int *ltype,
      41                 :            :                 void **data,
      42                 :            :                 void *userdata) {
      43                 :            : 
      44                 :            :         const ConfigTableItem *t;
      45                 :            : 
      46         [ -  + ]:      20904 :         assert(table);
      47         [ -  + ]:      20904 :         assert(lvalue);
      48         [ -  + ]:      20904 :         assert(func);
      49         [ -  + ]:      20904 :         assert(ltype);
      50         [ -  + ]:      20904 :         assert(data);
      51                 :            : 
      52         [ +  + ]:     116808 :         for (t = table; t->lvalue; t++) {
      53                 :            : 
      54         [ +  + ]:      98300 :                 if (!streq(lvalue, t->lvalue))
      55                 :      95904 :                         continue;
      56                 :            : 
      57         [ -  + ]:       2396 :                 if (!streq_ptr(section, t->section))
      58                 :          0 :                         continue;
      59                 :            : 
      60                 :       2396 :                 *func = t->parse;
      61                 :       2396 :                 *ltype = t->ltype;
      62                 :       2396 :                 *data = t->data;
      63                 :       2396 :                 return 1;
      64                 :            :         }
      65                 :            : 
      66                 :      18508 :         return 0;
      67                 :            : }
      68                 :            : 
      69                 :       1516 : int config_item_perf_lookup(
      70                 :            :                 const void *table,
      71                 :            :                 const char *section,
      72                 :            :                 const char *lvalue,
      73                 :            :                 ConfigParserCallback *func,
      74                 :            :                 int *ltype,
      75                 :            :                 void **data,
      76                 :            :                 void *userdata) {
      77                 :            : 
      78                 :       1516 :         ConfigPerfItemLookup lookup = (ConfigPerfItemLookup) table;
      79                 :            :         const ConfigPerfItem *p;
      80                 :            : 
      81         [ -  + ]:       1516 :         assert(table);
      82         [ -  + ]:       1516 :         assert(lvalue);
      83         [ -  + ]:       1516 :         assert(func);
      84         [ -  + ]:       1516 :         assert(ltype);
      85         [ -  + ]:       1516 :         assert(data);
      86                 :            : 
      87         [ +  - ]:       1516 :         if (section) {
      88                 :            :                 const char *key;
      89                 :            : 
      90   [ +  +  +  -  :      10612 :                 key = strjoina(section, ".", lvalue);
          -  +  -  +  +  
                +  +  - ]
      91                 :       1516 :                 p = lookup(key, strlen(key));
      92                 :            :         } else
      93                 :          0 :                 p = lookup(lvalue, strlen(lvalue));
      94         [ -  + ]:       1516 :         if (!p)
      95                 :          0 :                 return 0;
      96                 :            : 
      97                 :       1516 :         *func = p->parse;
      98                 :       1516 :         *ltype = p->ltype;
      99                 :       1516 :         *data = (uint8_t*) userdata + p->offset;
     100                 :       1516 :         return 1;
     101                 :            : }
     102                 :            : 
     103                 :            : /* Run the user supplied parser for an assignment */
     104                 :      22420 : static int next_assignment(
     105                 :            :                 const char *unit,
     106                 :            :                 const char *filename,
     107                 :            :                 unsigned line,
     108                 :            :                 ConfigItemLookup lookup,
     109                 :            :                 const void *table,
     110                 :            :                 const char *section,
     111                 :            :                 unsigned section_line,
     112                 :            :                 const char *lvalue,
     113                 :            :                 const char *rvalue,
     114                 :            :                 ConfigParseFlags flags,
     115                 :            :                 void *userdata) {
     116                 :            : 
     117                 :      22420 :         ConfigParserCallback func = NULL;
     118                 :      22420 :         int ltype = 0;
     119                 :      22420 :         void *data = NULL;
     120                 :            :         int r;
     121                 :            : 
     122         [ -  + ]:      22420 :         assert(filename);
     123         [ -  + ]:      22420 :         assert(line > 0);
     124         [ -  + ]:      22420 :         assert(lookup);
     125         [ -  + ]:      22420 :         assert(lvalue);
     126         [ -  + ]:      22420 :         assert(rvalue);
     127                 :            : 
     128                 :      22420 :         r = lookup(table, section, lvalue, &func, &ltype, &data, userdata);
     129         [ -  + ]:      22420 :         if (r < 0)
     130                 :          0 :                 return r;
     131         [ +  + ]:      22420 :         if (r > 0) {
     132         [ +  + ]:       3912 :                 if (func)
     133                 :       3884 :                         return func(unit, filename, line, section, section_line,
     134                 :            :                                     lvalue, ltype, rvalue, data, userdata);
     135                 :            : 
     136                 :         28 :                 return 0;
     137                 :            :         }
     138                 :            : 
     139                 :            :         /* Warn about unknown non-extension fields. */
     140   [ -  +  #  # ]:      18508 :         if (!(flags & CONFIG_PARSE_RELAXED) && !startswith(lvalue, "X-"))
     141         [ #  # ]:          0 :                 log_syntax(unit, LOG_WARNING, filename, line, 0,
     142                 :            :                            "Unknown key name '%s' in section '%s', ignoring.", lvalue, section);
     143                 :            : 
     144                 :      18508 :         return 0;
     145                 :            : }
     146                 :            : 
     147                 :            : /* Parse a single logical line */
     148                 :      33604 : static int parse_line(
     149                 :            :                 const char* unit,
     150                 :            :                 const char *filename,
     151                 :            :                 unsigned line,
     152                 :            :                 const char *sections,
     153                 :            :                 ConfigItemLookup lookup,
     154                 :            :                 const void *table,
     155                 :            :                 ConfigParseFlags flags,
     156                 :            :                 char **section,
     157                 :            :                 unsigned *section_line,
     158                 :            :                 bool *section_ignored,
     159                 :            :                 char *l,
     160                 :            :                 void *userdata) {
     161                 :            : 
     162                 :            :         char *e, *include;
     163                 :            : 
     164         [ -  + ]:      33604 :         assert(filename);
     165         [ -  + ]:      33604 :         assert(line > 0);
     166         [ -  + ]:      33604 :         assert(lookup);
     167         [ -  + ]:      33604 :         assert(l);
     168                 :            : 
     169                 :      33604 :         l = strstrip(l);
     170         [ +  + ]:      33604 :         if (!*l)
     171                 :       4892 :                 return 0;
     172                 :            : 
     173         [ -  + ]:      28712 :         if (*l == '\n')
     174                 :          0 :                 return 0;
     175                 :            : 
     176                 :      28712 :         include = first_word(l, ".include");
     177         [ -  + ]:      28712 :         if (include) {
     178                 :          0 :                 _cleanup_free_ char *fn = NULL;
     179                 :            : 
     180                 :            :                 /* .includes are a bad idea, we only support them here
     181                 :            :                  * for historical reasons. They create cyclic include
     182                 :            :                  * problems and make it difficult to detect
     183                 :            :                  * configuration file changes with an easy
     184                 :            :                  * stat(). Better approaches, such as .d/ drop-in
     185                 :            :                  * snippets exist.
     186                 :            :                  *
     187                 :            :                  * Support for them should be eventually removed. */
     188                 :            : 
     189         [ #  # ]:          0 :                 if (!(flags & CONFIG_PARSE_ALLOW_INCLUDE)) {
     190         [ #  # ]:          0 :                         log_syntax(unit, LOG_ERR, filename, line, 0, ".include not allowed here. Ignoring.");
     191                 :          0 :                         return 0;
     192                 :            :                 }
     193                 :            : 
     194         [ #  # ]:          0 :                 log_syntax(unit, LOG_WARNING, filename, line, 0,
     195                 :            :                            ".include directives are deprecated, and support for them will be removed in a future version of systemd. "
     196                 :            :                            "Please use drop-in files instead.");
     197                 :            : 
     198                 :          0 :                 fn = file_in_same_dir(filename, strstrip(include));
     199         [ #  # ]:          0 :                 if (!fn)
     200                 :          0 :                         return -ENOMEM;
     201                 :            : 
     202                 :          0 :                 return config_parse(unit, fn, NULL, sections, lookup, table, flags, userdata);
     203                 :            :         }
     204                 :            : 
     205         [ -  + ]:      28712 :         if (!utf8_is_valid(l))
     206         [ #  # ]:          0 :                 return log_syntax_invalid_utf8(unit, LOG_WARNING, filename, line, l);
     207                 :            : 
     208         [ +  + ]:      28712 :         if (*l == '[') {
     209                 :            :                 size_t k;
     210                 :            :                 char *n;
     211                 :            : 
     212                 :       6292 :                 k = strlen(l);
     213         [ -  + ]:       6292 :                 assert(k > 0);
     214                 :            : 
     215         [ -  + ]:       6292 :                 if (l[k-1] != ']') {
     216         [ #  # ]:          0 :                         log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid section header '%s'", l);
     217                 :          0 :                         return -EBADMSG;
     218                 :            :                 }
     219                 :            : 
     220                 :       6292 :                 n = strndup(l+1, k-2);
     221         [ -  + ]:       6292 :                 if (!n)
     222                 :          0 :                         return -ENOMEM;
     223                 :            : 
     224   [ +  +  -  + ]:       6292 :                 if (sections && !nulstr_contains(sections, n)) {
     225                 :            : 
     226   [ #  #  #  # ]:          0 :                         if (!(flags & CONFIG_PARSE_RELAXED) && !startswith(n, "X-"))
     227         [ #  # ]:          0 :                                 log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown section '%s'. Ignoring.", n);
     228                 :            : 
     229                 :          0 :                         free(n);
     230                 :          0 :                         *section = mfree(*section);
     231                 :          0 :                         *section_line = 0;
     232                 :          0 :                         *section_ignored = true;
     233                 :            :                 } else {
     234                 :       6292 :                         free_and_replace(*section, n);
     235                 :       6292 :                         *section_line = line;
     236                 :       6292 :                         *section_ignored = false;
     237                 :            :                 }
     238                 :            : 
     239                 :       6292 :                 return 0;
     240                 :            :         }
     241                 :            : 
     242   [ +  +  -  + ]:      22420 :         if (sections && !*section) {
     243   [ #  #  #  # ]:          0 :                 if (!(flags & CONFIG_PARSE_RELAXED) && !*section_ignored)
     244         [ #  # ]:          0 :                         log_syntax(unit, LOG_WARNING, filename, line, 0, "Assignment outside of section. Ignoring.");
     245                 :            : 
     246                 :          0 :                 return 0;
     247                 :            :         }
     248                 :            : 
     249                 :      22420 :         e = strchr(l, '=');
     250         [ -  + ]:      22420 :         if (!e)
     251         [ #  # ]:          0 :                 return log_syntax(unit, LOG_WARNING, filename, line, 0,
     252                 :            :                                   "Missing '=', ignoring line.");
     253         [ -  + ]:      22420 :         if (e == l)
     254         [ #  # ]:          0 :                 return log_syntax(unit, LOG_WARNING, filename, line, 0,
     255                 :            :                                   "Missing key name before '=', ignoring line.");
     256                 :            : 
     257                 :      22420 :         *e = 0;
     258                 :      22420 :         e++;
     259                 :            : 
     260                 :      22420 :         return next_assignment(unit,
     261                 :            :                                filename,
     262                 :            :                                line,
     263                 :            :                                lookup,
     264                 :            :                                table,
     265                 :            :                                *section,
     266                 :            :                                *section_line,
     267                 :      22420 :                                strstrip(l),
     268                 :      22420 :                                strstrip(e),
     269                 :            :                                flags,
     270                 :            :                                userdata);
     271                 :            : }
     272                 :            : 
     273                 :            : /* Go through the file and parse each line */
     274                 :       3448 : int config_parse(const char *unit,
     275                 :            :                  const char *filename,
     276                 :            :                  FILE *f,
     277                 :            :                  const char *sections,
     278                 :            :                  ConfigItemLookup lookup,
     279                 :            :                  const void *table,
     280                 :            :                  ConfigParseFlags flags,
     281                 :            :                  void *userdata) {
     282                 :            : 
     283                 :       3448 :         _cleanup_free_ char *section = NULL, *continuation = NULL;
     284                 :       3448 :         _cleanup_fclose_ FILE *ours = NULL;
     285                 :       3448 :         unsigned line = 0, section_line = 0;
     286                 :       3448 :         bool section_ignored = false;
     287                 :            :         int r;
     288                 :            : 
     289         [ -  + ]:       3448 :         assert(filename);
     290         [ -  + ]:       3448 :         assert(lookup);
     291                 :            : 
     292         [ +  + ]:       3448 :         if (!f) {
     293                 :         76 :                 f = ours = fopen(filename, "re");
     294         [ +  + ]:         76 :                 if (!f) {
     295                 :            :                         /* Only log on request, except for ENOENT,
     296                 :            :                          * since we return 0 to the caller. */
     297   [ -  +  #  # ]:         52 :                         if ((flags & CONFIG_PARSE_WARN) || errno == ENOENT)
     298   [ +  -  +  + ]:         52 :                                 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
     299                 :            :                                                "Failed to open configuration file '%s': %m", filename);
     300         [ -  + ]:         52 :                         return errno == ENOENT ? 0 : -errno;
     301                 :            :                 }
     302                 :            :         }
     303                 :            : 
     304                 :       3396 :         fd_warn_permissions(filename, fileno(f));
     305                 :            : 
     306                 :      48180 :         for (;;) {
     307   [ +  +  +  + ]:      51576 :                 _cleanup_free_ char *buf = NULL;
     308                 :      51576 :                 bool escaped = false;
     309                 :            :                 char *l, *p, *e;
     310                 :            : 
     311                 :      51576 :                 r = read_line(f, LONG_LINE_MAX, &buf);
     312         [ +  + ]:      51576 :                 if (r == 0)
     313                 :       3388 :                         break;
     314         [ +  + ]:      48188 :                 if (r == -ENOBUFS) {
     315         [ +  - ]:          4 :                         if (flags & CONFIG_PARSE_WARN)
     316         [ +  - ]:          4 :                                 log_error_errno(r, "%s:%u: Line too long", filename, line);
     317                 :            : 
     318                 :          4 :                         return r;
     319                 :            :                 }
     320         [ -  + ]:      48184 :                 if (r < 0) {
     321                 :            :                         if (CONFIG_PARSE_WARN)
     322         [ #  # ]:          0 :                                 log_error_errno(r, "%s:%u: Error while reading configuration file: %m", filename, line);
     323                 :            : 
     324                 :          0 :                         return r;
     325                 :            :                 }
     326                 :            : 
     327                 :      48184 :                 l = skip_leading_chars(buf, WHITESPACE);
     328   [ +  +  +  + ]:      48184 :                 if (*l != '\0' && strchr(COMMENTS, *l))
     329                 :      10416 :                         continue;
     330                 :            : 
     331                 :      37768 :                 l = buf;
     332         [ +  - ]:      37768 :                 if (!(flags & CONFIG_PARSE_REFUSE_BOM)) {
     333                 :            :                         char *q;
     334                 :            : 
     335                 :      37768 :                         q = startswith(buf, UTF8_BYTE_ORDER_MARK);
     336         [ -  + ]:      37768 :                         if (q) {
     337                 :          0 :                                 l = q;
     338                 :          0 :                                 flags |= CONFIG_PARSE_REFUSE_BOM;
     339                 :            :                         }
     340                 :            :                 }
     341                 :            : 
     342         [ +  + ]:      37768 :                 if (continuation) {
     343         [ +  + ]:       4160 :                         if (strlen(continuation) + strlen(l) > LONG_LINE_MAX) {
     344         [ +  - ]:          4 :                                 if (flags & CONFIG_PARSE_WARN)
     345         [ +  - ]:          4 :                                         log_error("%s:%u: Continuation line too long", filename, line);
     346                 :          4 :                                 return -ENOBUFS;
     347                 :            :                         }
     348                 :            : 
     349         [ -  + ]:       4156 :                         if (!strextend(&continuation, l, NULL)) {
     350         [ #  # ]:          0 :                                 if (flags & CONFIG_PARSE_WARN)
     351                 :          0 :                                         log_oom();
     352                 :          0 :                                 return -ENOMEM;
     353                 :            :                         }
     354                 :            : 
     355                 :       4156 :                         p = continuation;
     356                 :            :                 } else
     357                 :      33608 :                         p = l;
     358                 :            : 
     359         [ +  + ]: 2092448592 :                 for (e = p; *e; e++) {
     360         [ +  + ]: 2092410828 :                         if (escaped)
     361                 :        164 :                                 escaped = false;
     362         [ +  + ]: 2092410664 :                         else if (*e == '\\')
     363                 :       4332 :                                 escaped = true;
     364                 :            :                 }
     365                 :            : 
     366         [ +  + ]:      37764 :                 if (escaped) {
     367                 :       4168 :                         *(e-1) = ' ';
     368                 :            : 
     369         [ +  + ]:       4168 :                         if (!continuation) {
     370                 :         60 :                                 continuation = strdup(l);
     371         [ -  + ]:         60 :                                 if (!continuation) {
     372         [ #  # ]:          0 :                                         if (flags & CONFIG_PARSE_WARN)
     373                 :          0 :                                                 log_oom();
     374                 :          0 :                                         return -ENOMEM;
     375                 :            :                                 }
     376                 :            :                         }
     377                 :            : 
     378                 :       4168 :                         continue;
     379                 :            :                 }
     380                 :            : 
     381                 :      33596 :                 r = parse_line(unit,
     382                 :            :                                filename,
     383                 :            :                                ++line,
     384                 :            :                                sections,
     385                 :            :                                lookup,
     386                 :            :                                table,
     387                 :            :                                flags,
     388                 :            :                                &section,
     389                 :            :                                &section_line,
     390                 :            :                                &section_ignored,
     391                 :            :                                p,
     392                 :            :                                userdata);
     393         [ -  + ]:      33596 :                 if (r < 0) {
     394         [ #  # ]:          0 :                         if (flags & CONFIG_PARSE_WARN)
     395         [ #  # ]:          0 :                                 log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
     396                 :          0 :                         return r;
     397                 :            :                 }
     398                 :            : 
     399                 :      33596 :                 continuation = mfree(continuation);
     400                 :            :         }
     401                 :            : 
     402         [ +  + ]:       3388 :         if (continuation) {
     403                 :          8 :                 r = parse_line(unit,
     404                 :            :                                filename,
     405                 :            :                                ++line,
     406                 :            :                                sections,
     407                 :            :                                lookup,
     408                 :            :                                table,
     409                 :            :                                flags,
     410                 :            :                                &section,
     411                 :            :                                &section_line,
     412                 :            :                                &section_ignored,
     413                 :            :                                continuation,
     414                 :            :                                userdata);
     415         [ -  + ]:          8 :                 if (r < 0) {
     416         [ #  # ]:          0 :                         if (flags & CONFIG_PARSE_WARN)
     417         [ #  # ]:          0 :                                 log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
     418                 :          0 :                         return r;
     419                 :            :                 }
     420                 :            :         }
     421                 :            : 
     422                 :       3388 :         return 0;
     423                 :            : }
     424                 :            : 
     425                 :         64 : static int config_parse_many_files(
     426                 :            :                 const char *conf_file,
     427                 :            :                 char **files,
     428                 :            :                 const char *sections,
     429                 :            :                 ConfigItemLookup lookup,
     430                 :            :                 const void *table,
     431                 :            :                 ConfigParseFlags flags,
     432                 :            :                 void *userdata) {
     433                 :            : 
     434                 :            :         char **fn;
     435                 :            :         int r;
     436                 :            : 
     437         [ +  - ]:         64 :         if (conf_file) {
     438                 :         64 :                 r = config_parse(NULL, conf_file, NULL, sections, lookup, table, flags, userdata);
     439         [ -  + ]:         64 :                 if (r < 0)
     440                 :          0 :                         return r;
     441                 :            :         }
     442                 :            : 
     443   [ +  -  -  + ]:         64 :         STRV_FOREACH(fn, files) {
     444                 :          0 :                 r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata);
     445         [ #  # ]:          0 :                 if (r < 0)
     446                 :          0 :                         return r;
     447                 :            :         }
     448                 :            : 
     449                 :         64 :         return 0;
     450                 :            : }
     451                 :            : 
     452                 :            : /* Parse each config file in the directories specified as nulstr. */
     453                 :         52 : int config_parse_many_nulstr(
     454                 :            :                 const char *conf_file,
     455                 :            :                 const char *conf_file_dirs,
     456                 :            :                 const char *sections,
     457                 :            :                 ConfigItemLookup lookup,
     458                 :            :                 const void *table,
     459                 :            :                 ConfigParseFlags flags,
     460                 :            :                 void *userdata) {
     461                 :            : 
     462                 :         52 :         _cleanup_strv_free_ char **files = NULL;
     463                 :            :         int r;
     464                 :            : 
     465                 :         52 :         r = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs);
     466         [ -  + ]:         52 :         if (r < 0)
     467                 :          0 :                 return r;
     468                 :            : 
     469                 :         52 :         return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata);
     470                 :            : }
     471                 :            : 
     472                 :            : /* Parse each config file in the directories specified as strv. */
     473                 :         12 : int config_parse_many(
     474                 :            :                 const char *conf_file,
     475                 :            :                 const char* const* conf_file_dirs,
     476                 :            :                 const char *dropin_dirname,
     477                 :            :                 const char *sections,
     478                 :            :                 ConfigItemLookup lookup,
     479                 :            :                 const void *table,
     480                 :            :                 ConfigParseFlags flags,
     481                 :            :                 void *userdata) {
     482                 :            : 
     483                 :         12 :         _cleanup_strv_free_ char **dropin_dirs = NULL;
     484                 :         12 :         _cleanup_strv_free_ char **files = NULL;
     485                 :            :         const char *suffix;
     486                 :            :         int r;
     487                 :            : 
     488   [ +  +  +  -  :         60 :         suffix = strjoina("/", dropin_dirname);
          -  +  -  +  +  
                +  +  - ]
     489                 :         12 :         r = strv_extend_strv_concat(&dropin_dirs, (char**) conf_file_dirs, suffix);
     490         [ -  + ]:         12 :         if (r < 0)
     491                 :          0 :                 return r;
     492                 :            : 
     493                 :         12 :         r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char* const*) dropin_dirs);
     494         [ -  + ]:         12 :         if (r < 0)
     495                 :          0 :                 return r;
     496                 :            : 
     497                 :         12 :         return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata);
     498                 :            : }
     499                 :            : 
     500                 :            : #define DEFINE_PARSER(type, vartype, conv_func)                         \
     501                 :            :         DEFINE_CONFIG_PARSE_PTR(config_parse_##type, conv_func, vartype, "Failed to parse " #type " value")
     502                 :            : 
     503   [ -  +  -  +  :         28 : DEFINE_PARSER(int, int, safe_atoi);
          -  +  -  +  +  
                +  +  - ]
     504   [ #  #  #  #  :          0 : DEFINE_PARSER(long, long, safe_atoli);
          #  #  #  #  #  
                #  #  # ]
     505   [ #  #  #  #  :          0 : DEFINE_PARSER(uint8, uint8_t, safe_atou8);
          #  #  #  #  #  
                #  #  # ]
     506   [ #  #  #  #  :          0 : DEFINE_PARSER(uint16, uint16_t, safe_atou16);
          #  #  #  #  #  
                #  #  # ]
     507   [ #  #  #  #  :          0 : DEFINE_PARSER(uint32, uint32_t, safe_atou32);
          #  #  #  #  #  
                #  #  # ]
     508   [ #  #  #  #  :          0 : DEFINE_PARSER(uint64, uint64_t, safe_atou64);
          #  #  #  #  #  
                #  #  # ]
     509   [ -  +  -  +  :         28 : DEFINE_PARSER(unsigned, unsigned, safe_atou);
          -  +  -  +  +  
                +  +  - ]
     510   [ #  #  #  #  :          0 : DEFINE_PARSER(double, double, safe_atod);
          #  #  #  #  #  
                #  #  # ]
     511   [ -  +  -  +  :         28 : DEFINE_PARSER(nsec, nsec_t, parse_nsec);
          -  +  -  +  +  
                +  +  - ]
     512   [ -  +  -  +  :         28 : DEFINE_PARSER(sec, usec_t, parse_sec);
          -  +  -  +  +  
                +  +  - ]
     513   [ #  #  #  #  :          0 : DEFINE_PARSER(sec_def_infinity, usec_t, parse_sec_def_infinity);
          #  #  #  #  #  
                #  #  # ]
     514   [ -  +  -  +  :         32 : DEFINE_PARSER(mode, mode_t, parse_mode);
          -  +  -  +  +  
                +  +  - ]
     515                 :            : 
     516                 :         36 : int config_parse_iec_size(const char* unit,
     517                 :            :                             const char *filename,
     518                 :            :                             unsigned line,
     519                 :            :                             const char *section,
     520                 :            :                             unsigned section_line,
     521                 :            :                             const char *lvalue,
     522                 :            :                             int ltype,
     523                 :            :                             const char *rvalue,
     524                 :            :                             void *data,
     525                 :            :                             void *userdata) {
     526                 :            : 
     527                 :         36 :         size_t *sz = data;
     528                 :            :         uint64_t v;
     529                 :            :         int r;
     530                 :            : 
     531         [ -  + ]:         36 :         assert(filename);
     532         [ -  + ]:         36 :         assert(lvalue);
     533         [ -  + ]:         36 :         assert(rvalue);
     534         [ -  + ]:         36 :         assert(data);
     535                 :            : 
     536                 :         36 :         r = parse_size(rvalue, 1024, &v);
     537                 :            :         if (r >= 0 && (uint64_t) (size_t) v != v)
     538                 :            :                 r = -ERANGE;
     539         [ +  + ]:         36 :         if (r < 0) {
     540         [ +  - ]:         12 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value '%s', ignoring: %m", rvalue);
     541                 :         12 :                 return 0;
     542                 :            :         }
     543                 :            : 
     544                 :         24 :         *sz = (size_t) v;
     545                 :         24 :         return 0;
     546                 :            : }
     547                 :            : 
     548                 :         36 : int config_parse_si_size(
     549                 :            :                 const char* unit,
     550                 :            :                 const char *filename,
     551                 :            :                 unsigned line,
     552                 :            :                 const char *section,
     553                 :            :                 unsigned section_line,
     554                 :            :                 const char *lvalue,
     555                 :            :                 int ltype,
     556                 :            :                 const char *rvalue,
     557                 :            :                 void *data,
     558                 :            :                 void *userdata) {
     559                 :            : 
     560                 :         36 :         size_t *sz = data;
     561                 :            :         uint64_t v;
     562                 :            :         int r;
     563                 :            : 
     564         [ -  + ]:         36 :         assert(filename);
     565         [ -  + ]:         36 :         assert(lvalue);
     566         [ -  + ]:         36 :         assert(rvalue);
     567         [ -  + ]:         36 :         assert(data);
     568                 :            : 
     569                 :         36 :         r = parse_size(rvalue, 1000, &v);
     570                 :            :         if (r >= 0 && (uint64_t) (size_t) v != v)
     571                 :            :                 r = -ERANGE;
     572         [ +  + ]:         36 :         if (r < 0) {
     573         [ +  - ]:         12 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value '%s', ignoring: %m", rvalue);
     574                 :         12 :                 return 0;
     575                 :            :         }
     576                 :            : 
     577                 :         24 :         *sz = (size_t) v;
     578                 :         24 :         return 0;
     579                 :            : }
     580                 :            : 
     581                 :          8 : int config_parse_iec_uint64(
     582                 :            :                 const char* unit,
     583                 :            :                 const char *filename,
     584                 :            :                 unsigned line,
     585                 :            :                 const char *section,
     586                 :            :                 unsigned section_line,
     587                 :            :                 const char *lvalue,
     588                 :            :                 int ltype,
     589                 :            :                 const char *rvalue,
     590                 :            :                 void *data,
     591                 :            :                 void *userdata) {
     592                 :            : 
     593                 :          8 :         uint64_t *bytes = data;
     594                 :            :         int r;
     595                 :            : 
     596         [ -  + ]:          8 :         assert(filename);
     597         [ -  + ]:          8 :         assert(lvalue);
     598         [ -  + ]:          8 :         assert(rvalue);
     599         [ -  + ]:          8 :         assert(data);
     600                 :            : 
     601                 :          8 :         r = parse_size(rvalue, 1024, bytes);
     602         [ -  + ]:          8 :         if (r < 0)
     603         [ #  # ]:          0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue);
     604                 :            : 
     605                 :          8 :         return 0;
     606                 :            : }
     607                 :            : 
     608                 :         80 : int config_parse_bool(const char* unit,
     609                 :            :                       const char *filename,
     610                 :            :                       unsigned line,
     611                 :            :                       const char *section,
     612                 :            :                       unsigned section_line,
     613                 :            :                       const char *lvalue,
     614                 :            :                       int ltype,
     615                 :            :                       const char *rvalue,
     616                 :            :                       void *data,
     617                 :            :                       void *userdata) {
     618                 :            : 
     619                 :            :         int k;
     620                 :         80 :         bool *b = data;
     621                 :         80 :         bool fatal = ltype;
     622                 :            : 
     623         [ -  + ]:         80 :         assert(filename);
     624         [ -  + ]:         80 :         assert(lvalue);
     625         [ -  + ]:         80 :         assert(rvalue);
     626         [ -  + ]:         80 :         assert(data);
     627                 :            : 
     628                 :         80 :         k = parse_boolean(rvalue);
     629         [ -  + ]:         80 :         if (k < 0) {
     630   [ #  #  #  # ]:          0 :                 log_syntax(unit, LOG_ERR, filename, line, k,
     631                 :            :                            "Failed to parse boolean value%s: %s",
     632                 :            :                            fatal ? "" : ", ignoring", rvalue);
     633         [ #  # ]:          0 :                 return fatal ? -ENOEXEC : 0;
     634                 :            :         }
     635                 :            : 
     636                 :         80 :         *b = k;
     637                 :         80 :         return 0;
     638                 :            : }
     639                 :            : 
     640                 :          0 : int config_parse_tristate(
     641                 :            :                 const char* unit,
     642                 :            :                 const char *filename,
     643                 :            :                 unsigned line,
     644                 :            :                 const char *section,
     645                 :            :                 unsigned section_line,
     646                 :            :                 const char *lvalue,
     647                 :            :                 int ltype,
     648                 :            :                 const char *rvalue,
     649                 :            :                 void *data,
     650                 :            :                 void *userdata) {
     651                 :            : 
     652                 :          0 :         int k, *t = data;
     653                 :            : 
     654         [ #  # ]:          0 :         assert(filename);
     655         [ #  # ]:          0 :         assert(lvalue);
     656         [ #  # ]:          0 :         assert(rvalue);
     657         [ #  # ]:          0 :         assert(data);
     658                 :            : 
     659                 :            :         /* A tristate is pretty much a boolean, except that it can
     660                 :            :          * also take the special value -1, indicating "uninitialized",
     661                 :            :          * much like NULL is for a pointer type. */
     662                 :            : 
     663                 :          0 :         k = parse_boolean(rvalue);
     664         [ #  # ]:          0 :         if (k < 0) {
     665         [ #  # ]:          0 :                 log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse boolean value, ignoring: %s", rvalue);
     666                 :          0 :                 return 0;
     667                 :            :         }
     668                 :            : 
     669                 :          0 :         *t = !!k;
     670                 :          0 :         return 0;
     671                 :            : }
     672                 :            : 
     673                 :        432 : int config_parse_string(
     674                 :            :                 const char *unit,
     675                 :            :                 const char *filename,
     676                 :            :                 unsigned line,
     677                 :            :                 const char *section,
     678                 :            :                 unsigned section_line,
     679                 :            :                 const char *lvalue,
     680                 :            :                 int ltype,
     681                 :            :                 const char *rvalue,
     682                 :            :                 void *data,
     683                 :            :                 void *userdata) {
     684                 :            : 
     685                 :        432 :         char **s = data;
     686                 :            : 
     687         [ -  + ]:        432 :         assert(filename);
     688         [ -  + ]:        432 :         assert(lvalue);
     689         [ -  + ]:        432 :         assert(rvalue);
     690         [ -  + ]:        432 :         assert(data);
     691                 :            : 
     692         [ -  + ]:        432 :         if (free_and_strdup(s, empty_to_null(rvalue)) < 0)
     693                 :          0 :                 return log_oom();
     694                 :            : 
     695                 :        432 :         return 0;
     696                 :            : }
     697                 :            : 
     698                 :         28 : int config_parse_path(
     699                 :            :                 const char *unit,
     700                 :            :                 const char *filename,
     701                 :            :                 unsigned line,
     702                 :            :                 const char *section,
     703                 :            :                 unsigned section_line,
     704                 :            :                 const char *lvalue,
     705                 :            :                 int ltype,
     706                 :            :                 const char *rvalue,
     707                 :            :                 void *data,
     708                 :            :                 void *userdata) {
     709                 :            : 
     710                 :         28 :         _cleanup_free_ char *n = NULL;
     711                 :         28 :         bool fatal = ltype;
     712                 :         28 :         char **s = data;
     713                 :            :         int r;
     714                 :            : 
     715         [ -  + ]:         28 :         assert(filename);
     716         [ -  + ]:         28 :         assert(lvalue);
     717         [ -  + ]:         28 :         assert(rvalue);
     718         [ -  + ]:         28 :         assert(data);
     719                 :            : 
     720         [ -  + ]:         28 :         if (isempty(rvalue))
     721                 :          0 :                 goto finalize;
     722                 :            : 
     723                 :         28 :         n = strdup(rvalue);
     724         [ -  + ]:         28 :         if (!n)
     725                 :          0 :                 return log_oom();
     726                 :            : 
     727         [ -  + ]:         28 :         r = path_simplify_and_warn(n, PATH_CHECK_ABSOLUTE | (fatal ? PATH_CHECK_FATAL : 0), unit, filename, line, lvalue);
     728         [ +  + ]:         28 :         if (r < 0)
     729         [ -  + ]:          8 :                 return fatal ? -ENOEXEC : 0;
     730                 :            : 
     731                 :         20 : finalize:
     732                 :         20 :         return free_and_replace(*s, n);
     733                 :            : }
     734                 :            : 
     735                 :       2040 : int config_parse_strv(
     736                 :            :                 const char *unit,
     737                 :            :                 const char *filename,
     738                 :            :                 unsigned line,
     739                 :            :                 const char *section,
     740                 :            :                 unsigned section_line,
     741                 :            :                 const char *lvalue,
     742                 :            :                 int ltype,
     743                 :            :                 const char *rvalue,
     744                 :            :                 void *data,
     745                 :            :                 void *userdata) {
     746                 :            : 
     747                 :       2040 :         char ***sv = data;
     748                 :            :         int r;
     749                 :            : 
     750         [ -  + ]:       2040 :         assert(filename);
     751         [ -  + ]:       2040 :         assert(lvalue);
     752         [ -  + ]:       2040 :         assert(rvalue);
     753         [ -  + ]:       2040 :         assert(data);
     754                 :            : 
     755         [ +  + ]:       2040 :         if (isempty(rvalue)) {
     756                 :          4 :                 *sv = strv_free(*sv);
     757                 :          4 :                 return 0;
     758                 :            :         }
     759                 :            : 
     760                 :       2076 :         for (;;) {
     761                 :       4112 :                 char *word = NULL;
     762                 :            : 
     763                 :       4112 :                 r = extract_first_word(&rvalue, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
     764         [ +  + ]:       4112 :                 if (r == 0)
     765                 :       2036 :                         break;
     766         [ -  + ]:       2076 :                 if (r == -ENOMEM)
     767                 :          0 :                         return log_oom();
     768         [ -  + ]:       2076 :                 if (r < 0) {
     769         [ #  # ]:          0 :                         log_syntax(unit, LOG_ERR, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
     770                 :          0 :                         break;
     771                 :            :                 }
     772                 :            : 
     773                 :       2076 :                 r = strv_consume(sv, word);
     774         [ -  + ]:       2076 :                 if (r < 0)
     775                 :          0 :                         return log_oom();
     776                 :            :         }
     777                 :            : 
     778                 :       2036 :         return 0;
     779                 :            : }
     780                 :            : 
     781                 :          0 : int config_parse_warn_compat(
     782                 :            :                 const char *unit,
     783                 :            :                 const char *filename,
     784                 :            :                 unsigned line,
     785                 :            :                 const char *section,
     786                 :            :                 unsigned section_line,
     787                 :            :                 const char *lvalue,
     788                 :            :                 int ltype,
     789                 :            :                 const char *rvalue,
     790                 :            :                 void *data,
     791                 :            :                 void *userdata) {
     792                 :            : 
     793                 :          0 :         Disabled reason = ltype;
     794                 :            : 
     795   [ #  #  #  # ]:          0 :         switch(reason) {
     796                 :            : 
     797                 :          0 :         case DISABLED_CONFIGURATION:
     798         [ #  # ]:          0 :                 log_syntax(unit, LOG_DEBUG, filename, line, 0,
     799                 :            :                            "Support for option %s= has been disabled at compile time and it is ignored", lvalue);
     800                 :          0 :                 break;
     801                 :            : 
     802                 :          0 :         case DISABLED_LEGACY:
     803         [ #  # ]:          0 :                 log_syntax(unit, LOG_INFO, filename, line, 0,
     804                 :            :                            "Support for option %s= has been removed and it is ignored", lvalue);
     805                 :          0 :                 break;
     806                 :            : 
     807                 :          0 :         case DISABLED_EXPERIMENTAL:
     808         [ #  # ]:          0 :                 log_syntax(unit, LOG_INFO, filename, line, 0,
     809                 :            :                            "Support for option %s= has not yet been enabled and it is ignored", lvalue);
     810                 :          0 :                 break;
     811                 :            :         }
     812                 :            : 
     813                 :          0 :         return 0;
     814                 :            : }
     815                 :            : 
     816                 :         12 : int config_parse_log_facility(
     817                 :            :                 const char *unit,
     818                 :            :                 const char *filename,
     819                 :            :                 unsigned line,
     820                 :            :                 const char *section,
     821                 :            :                 unsigned section_line,
     822                 :            :                 const char *lvalue,
     823                 :            :                 int ltype,
     824                 :            :                 const char *rvalue,
     825                 :            :                 void *data,
     826                 :            :                 void *userdata) {
     827                 :            : 
     828                 :         12 :         int *o = data, x;
     829                 :            : 
     830         [ -  + ]:         12 :         assert(filename);
     831         [ -  + ]:         12 :         assert(lvalue);
     832         [ -  + ]:         12 :         assert(rvalue);
     833         [ -  + ]:         12 :         assert(data);
     834                 :            : 
     835                 :         12 :         x = log_facility_unshifted_from_string(rvalue);
     836         [ +  + ]:         12 :         if (x < 0) {
     837         [ +  - ]:          4 :                 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse log facility, ignoring: %s", rvalue);
     838                 :          4 :                 return 0;
     839                 :            :         }
     840                 :            : 
     841                 :          8 :         *o = (x << 3) | LOG_PRI(*o);
     842                 :            : 
     843                 :          8 :         return 0;
     844                 :            : }
     845                 :            : 
     846                 :         12 : int config_parse_log_level(
     847                 :            :                 const char *unit,
     848                 :            :                 const char *filename,
     849                 :            :                 unsigned line,
     850                 :            :                 const char *section,
     851                 :            :                 unsigned section_line,
     852                 :            :                 const char *lvalue,
     853                 :            :                 int ltype,
     854                 :            :                 const char *rvalue,
     855                 :            :                 void *data,
     856                 :            :                 void *userdata) {
     857                 :            : 
     858                 :         12 :         int *o = data, x;
     859                 :            : 
     860         [ -  + ]:         12 :         assert(filename);
     861         [ -  + ]:         12 :         assert(lvalue);
     862         [ -  + ]:         12 :         assert(rvalue);
     863         [ -  + ]:         12 :         assert(data);
     864                 :            : 
     865                 :         12 :         x = log_level_from_string(rvalue);
     866         [ +  + ]:         12 :         if (x < 0) {
     867         [ +  - ]:          4 :                 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse log level, ignoring: %s", rvalue);
     868                 :          4 :                 return 0;
     869                 :            :         }
     870                 :            : 
     871         [ -  + ]:          8 :         if (*o < 0) /* if it wasn't initialized so far, assume zero facility */
     872                 :          0 :                 *o = x;
     873                 :            :         else
     874                 :          8 :                 *o = (*o & LOG_FACMASK) | x;
     875                 :            : 
     876                 :          8 :         return 0;
     877                 :            : }
     878                 :            : 
     879                 :          0 : int config_parse_signal(
     880                 :            :                 const char *unit,
     881                 :            :                 const char *filename,
     882                 :            :                 unsigned line,
     883                 :            :                 const char *section,
     884                 :            :                 unsigned section_line,
     885                 :            :                 const char *lvalue,
     886                 :            :                 int ltype,
     887                 :            :                 const char *rvalue,
     888                 :            :                 void *data,
     889                 :            :                 void *userdata) {
     890                 :            : 
     891                 :          0 :         int *sig = data, r;
     892                 :            : 
     893         [ #  # ]:          0 :         assert(filename);
     894         [ #  # ]:          0 :         assert(lvalue);
     895         [ #  # ]:          0 :         assert(rvalue);
     896         [ #  # ]:          0 :         assert(sig);
     897                 :            : 
     898                 :          0 :         r = signal_from_string(rvalue);
     899         [ #  # ]:          0 :         if (r <= 0) {
     900         [ #  # ]:          0 :                 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse signal name, ignoring: %s", rvalue);
     901                 :          0 :                 return 0;
     902                 :            :         }
     903                 :            : 
     904                 :          0 :         *sig = r;
     905                 :          0 :         return 0;
     906                 :            : }
     907                 :            : 
     908                 :          0 : int config_parse_personality(
     909                 :            :                 const char *unit,
     910                 :            :                 const char *filename,
     911                 :            :                 unsigned line,
     912                 :            :                 const char *section,
     913                 :            :                 unsigned section_line,
     914                 :            :                 const char *lvalue,
     915                 :            :                 int ltype,
     916                 :            :                 const char *rvalue,
     917                 :            :                 void *data,
     918                 :            :                 void *userdata) {
     919                 :            : 
     920                 :          0 :         unsigned long *personality = data, p;
     921                 :            : 
     922         [ #  # ]:          0 :         assert(filename);
     923         [ #  # ]:          0 :         assert(lvalue);
     924         [ #  # ]:          0 :         assert(rvalue);
     925         [ #  # ]:          0 :         assert(personality);
     926                 :            : 
     927         [ #  # ]:          0 :         if (isempty(rvalue))
     928                 :          0 :                 p = PERSONALITY_INVALID;
     929                 :            :         else {
     930                 :          0 :                 p = personality_from_string(rvalue);
     931         [ #  # ]:          0 :                 if (p == PERSONALITY_INVALID) {
     932         [ #  # ]:          0 :                         log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse personality, ignoring: %s", rvalue);
     933                 :          0 :                         return 0;
     934                 :            :                 }
     935                 :            :         }
     936                 :            : 
     937                 :          0 :         *personality = p;
     938                 :          0 :         return 0;
     939                 :            : }
     940                 :            : 
     941                 :          0 : int config_parse_ifname(
     942                 :            :                 const char *unit,
     943                 :            :                 const char *filename,
     944                 :            :                 unsigned line,
     945                 :            :                 const char *section,
     946                 :            :                 unsigned section_line,
     947                 :            :                 const char *lvalue,
     948                 :            :                 int ltype,
     949                 :            :                 const char *rvalue,
     950                 :            :                 void *data,
     951                 :            :                 void *userdata) {
     952                 :            : 
     953                 :          0 :         char **s = data;
     954                 :            :         int r;
     955                 :            : 
     956         [ #  # ]:          0 :         assert(filename);
     957         [ #  # ]:          0 :         assert(lvalue);
     958         [ #  # ]:          0 :         assert(rvalue);
     959         [ #  # ]:          0 :         assert(data);
     960                 :            : 
     961         [ #  # ]:          0 :         if (isempty(rvalue)) {
     962                 :          0 :                 *s = mfree(*s);
     963                 :          0 :                 return 0;
     964                 :            :         }
     965                 :            : 
     966         [ #  # ]:          0 :         if (!ifname_valid(rvalue)) {
     967         [ #  # ]:          0 :                 log_syntax(unit, LOG_ERR, filename, line, 0, "Interface name is not valid or too long, ignoring assignment: %s", rvalue);
     968                 :          0 :                 return 0;
     969                 :            :         }
     970                 :            : 
     971                 :          0 :         r = free_and_strdup(s, rvalue);
     972         [ #  # ]:          0 :         if (r < 0)
     973                 :          0 :                 return log_oom();
     974                 :            : 
     975                 :          0 :         return 0;
     976                 :            : }
     977                 :            : 
     978                 :          0 : int config_parse_ip_port(
     979                 :            :                 const char *unit,
     980                 :            :                 const char *filename,
     981                 :            :                 unsigned line,
     982                 :            :                 const char *section,
     983                 :            :                 unsigned section_line,
     984                 :            :                 const char *lvalue,
     985                 :            :                 int ltype,
     986                 :            :                 const char *rvalue,
     987                 :            :                 void *data,
     988                 :            :                 void *userdata) {
     989                 :            : 
     990                 :          0 :         uint16_t *s = data;
     991                 :            :         uint16_t port;
     992                 :            :         int r;
     993                 :            : 
     994         [ #  # ]:          0 :         assert(filename);
     995         [ #  # ]:          0 :         assert(lvalue);
     996         [ #  # ]:          0 :         assert(rvalue);
     997         [ #  # ]:          0 :         assert(data);
     998                 :            : 
     999         [ #  # ]:          0 :         if (isempty(rvalue)) {
    1000                 :          0 :                 *s = 0;
    1001                 :          0 :                 return 0;
    1002                 :            :         }
    1003                 :            : 
    1004                 :          0 :         r = parse_ip_port(rvalue, &port);
    1005         [ #  # ]:          0 :         if (r < 0) {
    1006         [ #  # ]:          0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse port '%s'.", rvalue);
    1007                 :          0 :                 return 0;
    1008                 :            :         }
    1009                 :            : 
    1010                 :          0 :         *s = port;
    1011                 :            : 
    1012                 :          0 :         return 0;
    1013                 :            : }
    1014                 :            : 
    1015                 :          0 : int config_parse_mtu(
    1016                 :            :                 const char *unit,
    1017                 :            :                 const char *filename,
    1018                 :            :                 unsigned line,
    1019                 :            :                 const char *section,
    1020                 :            :                 unsigned section_line,
    1021                 :            :                 const char *lvalue,
    1022                 :            :                 int ltype,
    1023                 :            :                 const char *rvalue,
    1024                 :            :                 void *data,
    1025                 :            :                 void *userdata) {
    1026                 :            : 
    1027                 :          0 :         uint32_t *mtu = data;
    1028                 :            :         int r;
    1029                 :            : 
    1030         [ #  # ]:          0 :         assert(rvalue);
    1031         [ #  # ]:          0 :         assert(mtu);
    1032                 :            : 
    1033                 :          0 :         r = parse_mtu(ltype, rvalue, mtu);
    1034         [ #  # ]:          0 :         if (r == -ERANGE) {
    1035   [ #  #  #  # ]:          0 :                 log_syntax(unit, LOG_ERR, filename, line, r,
    1036                 :            :                            "Maximum transfer unit (MTU) value out of range. Permitted range is %" PRIu32 "…%" PRIu32 ", ignoring: %s",
    1037                 :            :                            (uint32_t) (ltype == AF_INET6 ? IPV6_MIN_MTU : IPV4_MIN_MTU), (uint32_t) UINT32_MAX,
    1038                 :            :                            rvalue);
    1039                 :          0 :                 return 0;
    1040                 :            :         }
    1041         [ #  # ]:          0 :         if (r < 0) {
    1042         [ #  # ]:          0 :                 log_syntax(unit, LOG_ERR, filename, line, r,
    1043                 :            :                            "Failed to parse MTU value '%s', ignoring: %m", rvalue);
    1044                 :          0 :                 return 0;
    1045                 :            :         }
    1046                 :            : 
    1047                 :          0 :         return 0;
    1048                 :            : }
    1049                 :            : 
    1050                 :         80 : int config_parse_rlimit(
    1051                 :            :                 const char *unit,
    1052                 :            :                 const char *filename,
    1053                 :            :                 unsigned line,
    1054                 :            :                 const char *section,
    1055                 :            :                 unsigned section_line,
    1056                 :            :                 const char *lvalue,
    1057                 :            :                 int ltype,
    1058                 :            :                 const char *rvalue,
    1059                 :            :                 void *data,
    1060                 :            :                 void *userdata) {
    1061                 :            : 
    1062                 :         80 :         struct rlimit **rl = data, d = {};
    1063                 :            :         int r;
    1064                 :            : 
    1065         [ -  + ]:         80 :         assert(rvalue);
    1066         [ -  + ]:         80 :         assert(rl);
    1067                 :            : 
    1068                 :         80 :         r = rlimit_parse(ltype, rvalue, &d);
    1069         [ +  + ]:         80 :         if (r == -EILSEQ) {
    1070         [ +  - ]:          4 :                 log_syntax(unit, LOG_WARNING, filename, line, r, "Soft resource limit chosen higher than hard limit, ignoring: %s", rvalue);
    1071                 :          4 :                 return 0;
    1072                 :            :         }
    1073         [ +  + ]:         76 :         if (r < 0) {
    1074         [ +  - ]:         12 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue);
    1075                 :         12 :                 return 0;
    1076                 :            :         }
    1077                 :            : 
    1078         [ +  + ]:         64 :         if (rl[ltype])
    1079                 :         52 :                 *rl[ltype] = d;
    1080                 :            :         else {
    1081                 :         12 :                 rl[ltype] = newdup(struct rlimit, &d, 1);
    1082         [ -  + ]:         12 :                 if (!rl[ltype])
    1083                 :          0 :                         return log_oom();
    1084                 :            :         }
    1085                 :            : 
    1086                 :         64 :         return 0;
    1087                 :            : }
    1088                 :            : 
    1089                 :          0 : int config_parse_permille(const char* unit,
    1090                 :            :                           const char *filename,
    1091                 :            :                           unsigned line,
    1092                 :            :                           const char *section,
    1093                 :            :                           unsigned section_line,
    1094                 :            :                           const char *lvalue,
    1095                 :            :                           int ltype,
    1096                 :            :                           const char *rvalue,
    1097                 :            :                           void *data,
    1098                 :            :                           void *userdata) {
    1099                 :            : 
    1100                 :          0 :         unsigned *permille = data;
    1101                 :            :         int r;
    1102                 :            : 
    1103         [ #  # ]:          0 :         assert(filename);
    1104         [ #  # ]:          0 :         assert(lvalue);
    1105         [ #  # ]:          0 :         assert(rvalue);
    1106         [ #  # ]:          0 :         assert(permille);
    1107                 :            : 
    1108                 :          0 :         r = parse_permille(rvalue);
    1109         [ #  # ]:          0 :         if (r < 0) {
    1110         [ #  # ]:          0 :                 log_syntax(unit, LOG_ERR, filename, line, r,
    1111                 :            :                            "Failed to parse permille value, ignoring: %s", rvalue);
    1112                 :          0 :                 return 0;
    1113                 :            :         }
    1114                 :            : 
    1115                 :          0 :         *permille = (unsigned) r;
    1116                 :            : 
    1117                 :          0 :         return 0;
    1118                 :            : }

Generated by: LCOV version 1.14