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);
#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)
goto err;
return tb;
err:
+ fprintf(stderr, "%s: parsing failed\n", file);
mnt_free_tab(tb);
return NULL;
}
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);
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;
}
{
char buf[BUFSIZ];
char *s;
- int rc;
assert(tb);
assert(f);
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;
}
/**
* 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;