LCOV - code coverage report
Current view: top level - shared - fstab-util.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 96 148 64.9 %
Date: 2019-08-23 13:36:53 Functions: 5 8 62.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 74 138 53.6 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <mntent.h>
       5                 :            : #include <stdio.h>
       6                 :            : #include <stdlib.h>
       7                 :            : #include <string.h>
       8                 :            : 
       9                 :            : #include "alloc-util.h"
      10                 :            : #include "device-nodes.h"
      11                 :            : #include "fstab-util.h"
      12                 :            : #include "macro.h"
      13                 :            : #include "mount-util.h"
      14                 :            : #include "nulstr-util.h"
      15                 :            : #include "parse-util.h"
      16                 :            : #include "path-util.h"
      17                 :            : #include "string-util.h"
      18                 :            : #include "strv.h"
      19                 :            : 
      20                 :          0 : int fstab_has_fstype(const char *fstype) {
      21                 :          0 :         _cleanup_endmntent_ FILE *f = NULL;
      22                 :            :         struct mntent *m;
      23                 :            : 
      24                 :          0 :         f = setmntent("/etc/fstab", "re");
      25         [ #  # ]:          0 :         if (!f)
      26         [ #  # ]:          0 :                 return errno == ENOENT ? false : -errno;
      27                 :            : 
      28                 :            :         for (;;) {
      29                 :          0 :                 errno = 0;
      30                 :          0 :                 m = getmntent(f);
      31         [ #  # ]:          0 :                 if (!m)
      32         [ #  # ]:          0 :                         return errno != 0 ? -errno : false;
      33                 :            : 
      34         [ #  # ]:          0 :                 if (streq(m->mnt_type, fstype))
      35                 :          0 :                         return true;
      36                 :            :         }
      37                 :            :         return false;
      38                 :            : }
      39                 :            : 
      40                 :          0 : int fstab_is_mount_point(const char *mount) {
      41                 :          0 :         _cleanup_endmntent_ FILE *f = NULL;
      42                 :            :         struct mntent *m;
      43                 :            : 
      44                 :          0 :         f = setmntent("/etc/fstab", "re");
      45         [ #  # ]:          0 :         if (!f)
      46         [ #  # ]:          0 :                 return errno == ENOENT ? false : -errno;
      47                 :            : 
      48                 :            :         for (;;) {
      49                 :          0 :                 errno = 0;
      50                 :          0 :                 m = getmntent(f);
      51         [ #  # ]:          0 :                 if (!m)
      52         [ #  # ]:          0 :                         return errno != 0 ? -errno : false;
      53                 :            : 
      54         [ #  # ]:          0 :                 if (path_equal(m->mnt_dir, mount))
      55                 :          0 :                         return true;
      56                 :            :         }
      57                 :            :         return false;
      58                 :            : }
      59                 :            : 
      60                 :       1216 : int fstab_filter_options(const char *opts, const char *names,
      61                 :            :                          const char **namefound, char **value, char **filtered) {
      62                 :       1216 :         const char *name, *n = NULL, *x;
      63                 :       1216 :         _cleanup_strv_free_ char **stor = NULL;
      64                 :       1216 :         _cleanup_free_ char *v = NULL, **strv = NULL;
      65                 :            : 
      66   [ +  -  -  + ]:       1216 :         assert(names && *names);
      67                 :            : 
      68         [ +  + ]:       1216 :         if (!opts)
      69                 :          8 :                 goto answer;
      70                 :            : 
      71                 :            :         /* If !value and !filtered, this function is not allowed to fail. */
      72                 :            : 
      73         [ +  + ]:       1208 :         if (!filtered) {
      74                 :            :                 const char *word, *state;
      75                 :            :                 size_t l;
      76                 :            : 
      77         [ +  + ]:       4848 :                 FOREACH_WORD_SEPARATOR(word, l, opts, ",", state)
      78   [ +  -  +  + ]:      10744 :                         NULSTR_FOREACH(name, names) {
      79         [ +  + ]:       6968 :                                 if (l < strlen(name))
      80                 :       2020 :                                         continue;
      81         [ +  + ]:       4948 :                                 if (!strneq(word, name, strlen(name)))
      82                 :       4608 :                                         continue;
      83                 :            : 
      84                 :            :                                 /* we know that the string is NUL
      85                 :            :                                  * terminated, so *x is valid */
      86                 :        340 :                                 x = word + strlen(name);
      87   [ +  +  +  + ]:        340 :                                 if (IN_SET(*x, '\0', '=', ',')) {
      88                 :        316 :                                         n = name;
      89         [ +  + ]:        316 :                                         if (value) {
      90                 :         20 :                                                 free(v);
      91   [ +  +  +  + ]:         20 :                                                 if (IN_SET(*x, '\0', ','))
      92                 :          4 :                                                         v = NULL;
      93                 :            :                                                 else {
      94         [ -  + ]:         16 :                                                         assert(*x == '=');
      95                 :         16 :                                                         x++;
      96                 :         16 :                                                         v = strndup(x, l - strlen(name) - 1);
      97         [ -  + ]:         16 :                                                         if (!v)
      98                 :          0 :                                                                 return -ENOMEM;
      99                 :            :                                                 }
     100                 :            :                                         }
     101                 :            :                                 }
     102                 :            :                         }
     103                 :            :         } else {
     104                 :            :                 char **t, **s;
     105                 :            : 
     106                 :        136 :                 stor = strv_split(opts, ",");
     107         [ -  + ]:        136 :                 if (!stor)
     108                 :          0 :                         return -ENOMEM;
     109                 :        136 :                 strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
     110         [ -  + ]:        136 :                 if (!strv)
     111                 :          0 :                         return -ENOMEM;
     112                 :            : 
     113         [ +  + ]:        392 :                 for (s = t = strv; *s; s++) {
     114   [ +  -  +  + ]:        576 :                         NULSTR_FOREACH(name, names) {
     115                 :        440 :                                 x = startswith(*s, name);
     116   [ +  +  +  +  :        440 :                                 if (x && IN_SET(*x, '\0', '='))
                   +  + ]
     117                 :        120 :                                         goto found;
     118                 :            :                         }
     119                 :            : 
     120                 :        136 :                         *t = *s;
     121                 :        136 :                         t++;
     122                 :        136 :                         continue;
     123                 :        120 :                 found:
     124                 :            :                         /* Keep the last occurrence found */
     125                 :        120 :                         n = name;
     126         [ +  - ]:        120 :                         if (value) {
     127                 :        120 :                                 free(v);
     128         [ +  + ]:        120 :                                 if (*x == '\0')
     129                 :         44 :                                         v = NULL;
     130                 :            :                                 else {
     131         [ -  + ]:         76 :                                         assert(*x == '=');
     132                 :         76 :                                         x++;
     133                 :         76 :                                         v = strdup(x);
     134         [ -  + ]:         76 :                                         if (!v)
     135                 :          0 :                                                 return -ENOMEM;
     136                 :            :                                 }
     137                 :            :                         }
     138                 :            :                 }
     139                 :        136 :                 *t = NULL;
     140                 :            :         }
     141                 :            : 
     142                 :       1216 : answer:
     143         [ +  + ]:       1216 :         if (namefound)
     144                 :        364 :                 *namefound = n;
     145         [ +  + ]:       1216 :         if (filtered) {
     146                 :            :                 char *f;
     147                 :            : 
     148                 :        140 :                 f = strv_join(strv, ",");
     149         [ -  + ]:        140 :                 if (!f)
     150                 :          0 :                         return -ENOMEM;
     151                 :            : 
     152                 :        140 :                 *filtered = f;
     153                 :            :         }
     154         [ +  + ]:       1216 :         if (value)
     155                 :        156 :                 *value = TAKE_PTR(v);
     156                 :            : 
     157                 :       1216 :         return !!n;
     158                 :            : }
     159                 :            : 
     160                 :          0 : int fstab_extract_values(const char *opts, const char *name, char ***values) {
     161                 :          0 :         _cleanup_strv_free_ char **optsv = NULL, **res = NULL;
     162                 :            :         char **s;
     163                 :            : 
     164         [ #  # ]:          0 :         assert(opts);
     165         [ #  # ]:          0 :         assert(name);
     166         [ #  # ]:          0 :         assert(values);
     167                 :            : 
     168                 :          0 :         optsv = strv_split(opts, ",");
     169         [ #  # ]:          0 :         if (!optsv)
     170                 :          0 :                 return -ENOMEM;
     171                 :            : 
     172   [ #  #  #  # ]:          0 :         STRV_FOREACH(s, optsv) {
     173                 :            :                 char *arg;
     174                 :            :                 int r;
     175                 :            : 
     176                 :          0 :                 arg = startswith(*s, name);
     177   [ #  #  #  # ]:          0 :                 if (!arg || *arg != '=')
     178                 :          0 :                         continue;
     179                 :          0 :                 r = strv_extend(&res, arg + 1);
     180         [ #  # ]:          0 :                 if (r < 0)
     181                 :          0 :                         return r;
     182                 :            :         }
     183                 :            : 
     184                 :          0 :         *values = TAKE_PTR(res);
     185                 :            : 
     186                 :          0 :         return !!*values;
     187                 :            : }
     188                 :            : 
     189                 :         16 : int fstab_find_pri(const char *options, int *ret) {
     190                 :         16 :         _cleanup_free_ char *opt = NULL;
     191                 :            :         int r;
     192                 :            :         unsigned pri;
     193                 :            : 
     194         [ -  + ]:         16 :         assert(ret);
     195                 :            : 
     196                 :         16 :         r = fstab_filter_options(options, "pri\0", NULL, &opt, NULL);
     197         [ -  + ]:         16 :         if (r < 0)
     198                 :          0 :                 return r;
     199   [ +  -  +  + ]:         16 :         if (r == 0 || !opt)
     200                 :          4 :                 return 0;
     201                 :            : 
     202                 :         12 :         r = safe_atou(opt, &pri);
     203         [ -  + ]:         12 :         if (r < 0)
     204                 :          0 :                 return r;
     205                 :            : 
     206         [ -  + ]:         12 :         if ((int) pri < 0)
     207                 :          0 :                 return -ERANGE;
     208                 :            : 
     209                 :         12 :         *ret = (int) pri;
     210                 :         12 :         return 1;
     211                 :            : }
     212                 :            : 
     213                 :         16 : static char *unquote(const char *s, const char* quotes) {
     214                 :            :         size_t l;
     215         [ -  + ]:         16 :         assert(s);
     216                 :            : 
     217                 :            :         /* This is rather stupid, simply removes the heading and
     218                 :            :          * trailing quotes if there is one. Doesn't care about
     219                 :            :          * escaping or anything.
     220                 :            :          *
     221                 :            :          * DON'T USE THIS FOR NEW CODE ANYMORE! */
     222                 :            : 
     223                 :         16 :         l = strlen(s);
     224         [ -  + ]:         16 :         if (l < 2)
     225                 :          0 :                 return strdup(s);
     226                 :            : 
     227   [ -  +  #  # ]:         16 :         if (strchr(quotes, s[0]) && s[l-1] == s[0])
     228                 :          0 :                 return strndup(s+1, l-2);
     229                 :            : 
     230                 :         16 :         return strdup(s);
     231                 :            : }
     232                 :            : 
     233                 :         16 : static char *tag_to_udev_node(const char *tagvalue, const char *by) {
     234                 :         16 :         _cleanup_free_ char *t = NULL, *u = NULL;
     235                 :            :         size_t enc_len;
     236                 :            : 
     237                 :         16 :         u = unquote(tagvalue, QUOTES);
     238         [ -  + ]:         16 :         if (!u)
     239                 :          0 :                 return NULL;
     240                 :            : 
     241                 :         16 :         enc_len = strlen(u) * 4 + 1;
     242                 :         16 :         t = new(char, enc_len);
     243         [ -  + ]:         16 :         if (!t)
     244                 :          0 :                 return NULL;
     245                 :            : 
     246         [ -  + ]:         16 :         if (encode_devnode_name(u, t, enc_len) < 0)
     247                 :          0 :                 return NULL;
     248                 :            : 
     249                 :         16 :         return strjoin("/dev/disk/by-", by, "/", t);
     250                 :            : }
     251                 :            : 
     252                 :         24 : char *fstab_node_to_udev_node(const char *p) {
     253         [ -  + ]:         24 :         assert(p);
     254                 :            : 
     255         [ +  + ]:         24 :         if (startswith(p, "LABEL="))
     256                 :          4 :                 return tag_to_udev_node(p+6, "label");
     257                 :            : 
     258         [ +  + ]:         20 :         if (startswith(p, "UUID="))
     259                 :          4 :                 return tag_to_udev_node(p+5, "uuid");
     260                 :            : 
     261         [ +  + ]:         16 :         if (startswith(p, "PARTUUID="))
     262                 :          4 :                 return tag_to_udev_node(p+9, "partuuid");
     263                 :            : 
     264         [ +  + ]:         12 :         if (startswith(p, "PARTLABEL="))
     265                 :          4 :                 return tag_to_udev_node(p+10, "partlabel");
     266                 :            : 
     267                 :          8 :         return strdup(p);
     268                 :            : }

Generated by: LCOV version 1.14