]> err.no Git - util-linux/commitdiff
libmount: cleanup fstab parser, improve mnt_tab errcb usage
authorKarel Zak <kzak@redhat.com>
Mon, 18 Oct 2010 12:19:21 +0000 (14:19 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 3 Jan 2011 11:28:45 +0000 (12:28 +0100)
Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/mount/src/mount.h.in
shlibs/mount/src/mountP.h
shlibs/mount/src/tab.c
shlibs/mount/src/tab_parse.c

index f4b4e6ad4c85ff5cd64e75d74c43eb3d623ffb42..a1143ee273c92bcc3b9b3d84a77a2b16fc69d472 100644 (file)
@@ -254,7 +254,7 @@ extern int mnt_tab_parse_file(mnt_tab *tb, const char *filename);
 extern int mnt_tab_parse_fstab(mnt_tab *tb);
 extern int mnt_tab_parse_mtab(mnt_tab *tb);
 extern int mnt_tab_set_parser_errcb(mnt_tab *tb,
-                int (*cb)(mnt_tab *tb, const char *filename, int line, int flag));
+                int (*cb)(mnt_tab *tb, const char *filename, int line));
 
 /* tab.c */
 extern mnt_tab *mnt_new_tab(void);
index 7d66f0ba9407944a2549229f3b3a7fa6d48b63e1..2a418758361b96399dc6698f23623b73987ce912 100644 (file)
@@ -195,8 +195,7 @@ struct _mnt_tab {
 
        mnt_cache       *cache;         /* canonicalized paths/tags cache */
 
-        int            (*errcb)(mnt_tab *tb, const char *filename,
-                                               int line, int flag);
+        int            (*errcb)(mnt_tab *tb, const char *filename, int line);
 
        struct list_head        ents;   /* list of entries (mentry) */
 };
index 2b680270851d7342b0400723675423586aa3bdd0..97e4d16617674a222c581d3e3c27c4b919ff18cb 100644 (file)
@@ -691,10 +691,11 @@ mnt_fs *mnt_tab_find_pair(mnt_tab *tb, const char *source,
 
 #ifdef TEST_PROGRAM
 
-static int parser_errcb(mnt_tab *tb, const char *filename, int line, int flag)
+static int parser_errcb(mnt_tab *tb, const char *filename, int line)
 {
        fprintf(stderr, "%s:%d: parse error\n", filename, line);
-       return 0;
+
+       return 1;       /* all errors are recoverable -- this is default */
 }
 
 mnt_tab *create_tab(const char *file)
@@ -713,6 +714,7 @@ mnt_tab *create_tab(const char *file)
                goto err;
        return tb;
 err:
+       fprintf(stderr, "%s: parsing failed\n", file);
        mnt_free_tab(tb);
        return NULL;
 }
index 603908f203314ea3fb794b80c17918c602effe0e..ae390e86e8b5c27a007ccb869e7cb0bb5444bc06 100644 (file)
@@ -29,29 +29,48 @@ static inline char *skip_spaces(char *s)
        return s;
 }
 
+static int next_number(char **s, int *num)
+{
+       char *end = NULL;
+
+       assert(num);
+       assert(s);
+
+       *s = skip_spaces(*s);
+       if (!**s)
+               return -1;
+       *num = strtol(*s, &end, 10);
+       if (end == NULL || *s == end)
+              return -1;
+
+       *s = end;
+
+       /* valid end of number is space or terminator */
+       if (*end == ' ' || *end == '\t' || *end == '\0')
+               return 0;
+       return -1;
+}
+
 /*
  * Parses one line from {fs,m}tab
  */
 static int mnt_tab_parse_file_line(mnt_fs *fs, char *s)
 {
-       int rc;
+       int rc, n = 0;
        char *src, *fstype, *optstr;
 
        rc = sscanf(s,  "%ms "  /* (1) source */
                        "%ms "  /* (2) target */
                        "%ms "  /* (3) FS type */
                        "%ms "  /* (4) options */
-                       "%u "   /* (5) freq */
-                       "%u ",  /* (6) passno */
-
+                       "%n",   /* byte count */
                        &src,
                        &fs->target,
                        &fstype,
                        &optstr,
-                       &fs->freq,
-                       &fs->passno);
+                       &n);
 
-       if (rc >= 4 && rc <= 6) {
+       if (rc == 4) {
                unmangle_string(src);
                unmangle_string(fs->target);
                unmangle_string(fstype);
@@ -63,10 +82,23 @@ static int mnt_tab_parse_file_line(mnt_fs *fs, char *s)
                if (!rc)
                        rc = __mnt_fs_set_optstr_ptr(fs, optstr, TRUE);
        } else {
-               DBG(TAB, mnt_debug( "parse error: [field=%d]: '%s'", rc, s));
+               DBG(TAB, mnt_debug( "parse error: [sscanf rc=%d]: '%s'", rc, s));
                rc = -EINVAL;
        }
 
+       if (rc)
+               return rc;      /* error */
+
+       fs->passno = fs->freq = 0;
+       s = skip_spaces(s + n);
+       if (*s) {
+               if (next_number(&s, &fs->freq) != 0) {
+                       if (*s)
+                               rc = -EINVAL;
+               } else if (next_number(&s, &fs->passno) != 0 && *s)
+                       rc = -EINVAL;
+       }
+
        return rc;
 }
 
@@ -205,7 +237,6 @@ static int mnt_tab_parse_next(mnt_tab *tb, FILE *f, mnt_fs *fs,
 {
        char buf[BUFSIZ];
        char *s;
-       int rc;
 
        assert(tb);
        assert(f);
@@ -268,11 +299,10 @@ static int mnt_tab_parse_next(mnt_tab *tb, FILE *f, mnt_fs *fs,
 err:
        DBG(TAB, mnt_debug_h(tb, "%s:%d: parse error", filename, *nlines));
 
-       rc = 1;         /* recoverable error */
-
-       if (tb->errcb)
-               rc = tb->errcb(tb, filename, *nlines, 0);
-       return rc;
+       /* by default all errors are recoverable, otherwise behavior depends on
+        * errcb() function. See mnt_tab_set_parser_errcb().
+        */
+       return tb->errcb ? tb->errcb(tb, filename, *nlines) : 1;
 }
 
 /**
@@ -397,7 +427,7 @@ mnt_tab *mnt_new_tab_from_file(const char *filename)
  * Returns: 0 on success or negative number in case of error.
  */
 int mnt_tab_set_parser_errcb(mnt_tab *tb,
-               int (*cb)(mnt_tab *tb, const char *filename, int line, int flag))
+               int (*cb)(mnt_tab *tb, const char *filename, int line))
 {
        assert(tb);
        tb->errcb = cb;