LCOV - code coverage report
Current view: top level - shared - fstab-util.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 69 95 72.6 %
Date: 2015-07-29 18:47:03 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : /***
       4             :   This file is part of systemd.
       5             : 
       6             :   Copyright 2015 Zbigniew Jędrzejewski-Szmek
       7             : 
       8             :   systemd is free software; you can redistribute it and/or modify it
       9             :   under the terms of the GNU Lesser General Public License as published by
      10             :   the Free Software Foundation; either version 2.1 of the License, or
      11             :   (at your option) any later version.
      12             : 
      13             :   systemd is distributed in the hope that it will be useful, but
      14             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      16             :   Lesser General Public License for more details.
      17             : 
      18             :   You should have received a copy of the GNU Lesser General Public License
      19             :   along with systemd; If not, see <http://www.gnu.org/licenses/>.
      20             : ***/
      21             : 
      22             : #include "fstab-util.h"
      23             : #include "strv.h"
      24             : #include "util.h"
      25             : 
      26         159 : int fstab_filter_options(const char *opts, const char *names,
      27             :                          const char **namefound, char **value, char **filtered) {
      28         159 :         const char *name, *n = NULL, *x;
      29         318 :         _cleanup_strv_free_ char **stor = NULL;
      30         318 :         _cleanup_free_ char *v = NULL, **strv = NULL;
      31             : 
      32         159 :         assert(names && *names);
      33             : 
      34         159 :         if (!opts)
      35           2 :                 goto answer;
      36             : 
      37             :         /* If !value and !filtered, this function is not allowed to fail. */
      38             : 
      39         157 :         if (!filtered) {
      40             :                 const char *word, *state;
      41             :                 size_t l;
      42             : 
      43         481 :                 FOREACH_WORD_SEPARATOR(word, l, opts, ",", state)
      44        1060 :                         NULSTR_FOREACH(name, names) {
      45         702 :                                 if (l < strlen(name))
      46         201 :                                         continue;
      47         501 :                                 if (!strneq(word, name, strlen(name)))
      48         448 :                                         continue;
      49             : 
      50             :                                 /* we know that the string is NUL
      51             :                                  * terminated, so *x is valid */
      52          53 :                                 x = word + strlen(name);
      53          53 :                                 if (IN_SET(*x, '\0', '=', ',')) {
      54          47 :                                         n = name;
      55          47 :                                         if (value) {
      56           5 :                                                 free(v);
      57           5 :                                                 if (IN_SET(*x, '\0', ','))
      58           1 :                                                         v = NULL;
      59             :                                                 else {
      60           4 :                                                         assert(*x == '=');
      61           4 :                                                         x++;
      62           4 :                                                         v = strndup(x, l - strlen(name) - 1);
      63           4 :                                                         if (!v)
      64           0 :                                                                 return -ENOMEM;
      65             :                                                 }
      66             :                                         }
      67             :                                 }
      68             :                         }
      69             :         } else {
      70             :                 char **t, **s;
      71             : 
      72          34 :                 stor = strv_split(opts, ",");
      73          34 :                 if (!stor)
      74           0 :                         return -ENOMEM;
      75          34 :                 strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
      76          34 :                 if (!strv)
      77           0 :                         return -ENOMEM;
      78             : 
      79          98 :                 for (s = t = strv; *s; s++) {
      80         144 :                         NULSTR_FOREACH(name, names) {
      81         110 :                                 x = startswith(*s, name);
      82         110 :                                 if (x && IN_SET(*x, '\0', '='))
      83          30 :                                         goto found;
      84             :                         }
      85             : 
      86          34 :                         *t = *s;
      87          34 :                         t++;
      88          34 :                         continue;
      89             :                 found:
      90             :                         /* Keep the last occurence found */
      91          30 :                         n = name;
      92          30 :                         if (value) {
      93          30 :                                 free(v);
      94          30 :                                 if (*x == '\0')
      95          11 :                                         v = NULL;
      96             :                                 else {
      97          19 :                                         assert(*x == '=');
      98          19 :                                         x++;
      99          19 :                                         v = strdup(x);
     100          19 :                                         if (!v)
     101           0 :                                                 return -ENOMEM;
     102             :                                 }
     103             :                         }
     104             :                 }
     105          34 :                 *t = NULL;
     106             :         }
     107             : 
     108             : answer:
     109         159 :         if (namefound)
     110          75 :                 *namefound = n;
     111         159 :         if (filtered) {
     112             :                 char *f;
     113             : 
     114          35 :                 f = strv_join(strv, ",");
     115          35 :                 if (!f)
     116           0 :                         return -ENOMEM;
     117             : 
     118          35 :                 *filtered = f;
     119             :         }
     120         159 :         if (value) {
     121          39 :                 *value = v;
     122          39 :                 v = NULL;
     123             :         }
     124             : 
     125         159 :         return !!n;
     126             : }
     127             : 
     128           0 : int fstab_extract_values(const char *opts, const char *name, char ***values) {
     129           0 :         _cleanup_strv_free_ char **optsv = NULL, **res = NULL;
     130             :         char **s;
     131             : 
     132           0 :         assert(opts);
     133           0 :         assert(name);
     134           0 :         assert(values);
     135             : 
     136           0 :         optsv = strv_split(opts, ",");
     137           0 :         if (!optsv)
     138           0 :                 return -ENOMEM;
     139             : 
     140           0 :         STRV_FOREACH(s, optsv) {
     141             :                 char *arg;
     142             :                 int r;
     143             : 
     144           0 :                 arg = startswith(*s, name);
     145           0 :                 if (!arg || *arg != '=')
     146           0 :                         continue;
     147           0 :                 r = strv_extend(&res, arg + 1);
     148           0 :                 if (r < 0)
     149           0 :                         return r;
     150             :         }
     151             : 
     152           0 :         *values = res;
     153           0 :         res = NULL;
     154             : 
     155           0 :         return !!*values;
     156             : }
     157             : 
     158           4 : int fstab_find_pri(const char *options, int *ret) {
     159           8 :         _cleanup_free_ char *opt = NULL;
     160             :         int r;
     161             :         unsigned pri;
     162             : 
     163           4 :         assert(ret);
     164             : 
     165           4 :         r = fstab_filter_options(options, "pri\0", NULL, &opt, NULL);
     166           4 :         if (r < 0)
     167           0 :                 return r;
     168           4 :         if (r == 0 || !opt)
     169           1 :                 return 0;
     170             : 
     171           3 :         r = safe_atou(opt, &pri);
     172           3 :         if (r < 0)
     173           0 :                 return r;
     174             : 
     175           3 :         if ((int) pri < 0)
     176           0 :                 return -ERANGE;
     177             : 
     178           3 :         *ret = (int) pri;
     179           3 :         return 1;
     180             : }

Generated by: LCOV version 1.11