From f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 4 Jan 2006 10:32:16 -0500 Subject: [PATCH] Add syntax error reporting to the profile library E2fsck will now report syntax errors in /etc/e2fsck.conf intead of simply ignoring the config file when there are errors. Signed-off-by: "Theodore Ts'o" --- e2fsck/ChangeLog | 9 +++++ e2fsck/profile.c | 117 +++++++++++++++++++------------------------------------ e2fsck/profile.h | 5 +++ e2fsck/unix.c | 9 +++++ 4 files changed, 62 insertions(+), 78 deletions(-) diff --git a/e2fsck/ChangeLog b/e2fsck/ChangeLog index 562bbd4..ce3f4d1 100644 --- a/e2fsck/ChangeLog +++ b/e2fsck/ChangeLog @@ -1,3 +1,12 @@ +2006-01-04 Theodore Ts'o + + * profile.c (profile_parse_file, profile_set_syntax_err_cb): Add + support for a syntax error callback to allow better error + reporting to the user. + + * e2fsck(PRS): Set a profile syntax error callback so we can + report errors in /etc/e2fsck.conf. + 2006-01-02 Theodore Ts'o * profile.c, profile_helpers.c, profile_helpers.h: Boil down and diff --git a/e2fsck/profile.c b/e2fsck/profile.c index d8324e7..7582c2a 100644 --- a/e2fsck/profile.c +++ b/e2fsck/profile.c @@ -167,7 +167,7 @@ struct profile_node { /* profile_parse.c */ static errcode_t profile_parse_file - (FILE *f, struct profile_node **root); + (FILE *f, prf_data_t data); #ifdef DEBUG_PROGRAM static errcode_t profile_write_tree_file @@ -452,7 +452,7 @@ errcode_t profile_update_file_data(prf_data_t data) return retval; } data->upd_serial++; - retval = profile_parse_file(f, &data->root); + retval = profile_parse_file(f, data); fclose(f); if (retval) { return retval; @@ -480,15 +480,27 @@ void profile_free_file(prf_file_t prf) /* Begin prof_parse.c */ +static profile_syntax_err_cb_t syntax_err_cb; + +profile_syntax_err_cb_t profile_set_syntax_err_cb(profile_syntax_err_cb_t hook) +{ + profile_syntax_err_cb_t old; + + old = syntax_err_cb; + syntax_err_cb = hook; + return(old); +} + #define SECTION_SEP_CHAR '/' -#define STATE_INIT_COMMENT 1 -#define STATE_STD_LINE 2 -#define STATE_GET_OBRACE 3 +#define STATE_INIT_COMMENT 0 +#define STATE_STD_LINE 1 +#define STATE_GET_OBRACE 2 struct parse_state { int state; int group_level; + int line_num; struct profile_node *root_section; struct profile_node *current_section; }; @@ -537,14 +549,6 @@ static void parse_quoted_string(char *str) } -static errcode_t parse_init_state(struct parse_state *state) -{ - state->state = STATE_INIT_COMMENT; - state->group_level = 0; - - return profile_create_node("(root)", 0, &state->root_section); -} - static errcode_t parse_std_line(char *line, struct parse_state *state) { char *cp, ch, *tag, *value; @@ -672,6 +676,7 @@ static errcode_t parse_line(char *line, struct parse_state *state) { char *cp; + state->line_num++; switch (state->state) { case STATE_INIT_COMMENT: if (line[0] != '[') @@ -688,87 +693,35 @@ static errcode_t parse_line(char *line, struct parse_state *state) return 0; } -errcode_t profile_parse_file(FILE *f, struct profile_node **root) +errcode_t profile_parse_file(FILE *f, prf_data_t data) { -#define BUF_SIZE 2048 - char *bptr; + char buf[2048]; errcode_t retval; struct parse_state state; - bptr = malloc (BUF_SIZE); - if (!bptr) - return ENOMEM; + memset(&state, 0, sizeof(struct parse_state)); - retval = parse_init_state(&state); - if (retval) { - free (bptr); + retval = profile_create_node("(root)", 0, &state.root_section); + if (retval) return retval; - } + while (!feof(f)) { - if (fgets(bptr, BUF_SIZE, f) == NULL) + if (fgets(buf, sizeof(buf), f) == NULL) break; -#ifndef PROFILE_SUPPORTS_FOREIGN_NEWLINES - retval = parse_line(bptr, &state); + retval = parse_line(buf, &state); if (retval) { - free (bptr); + if (syntax_err_cb) + (syntax_err_cb)(data->filespec, retval, + state.line_num); return retval; } -#else - { - char *p, *end; - - if (strlen(bptr) >= BUF_SIZE - 1) { - /* The string may have foreign newlines and - gotten chopped off on a non-newline - boundary. Seek backwards to the last known - newline. */ - long offset; - char *c = bptr + strlen (bptr); - for (offset = 0; offset > -BUF_SIZE; offset--) { - if (*c == '\r' || *c == '\n') { - *c = '\0'; - fseek (f, offset, SEEK_CUR); - break; - } - c--; - } - } - - /* First change all newlines to \n */ - for (p = bptr; *p != '\0'; p++) { - if (*p == '\r') - *p = '\n'; - } - /* Then parse all lines */ - p = bptr; - end = bptr + strlen (bptr); - while (p < end) { - char* newline; - char* newp; - - newline = strchr (p, '\n'); - if (newline != NULL) - *newline = '\0'; - - /* parse_line modifies contents of p */ - newp = p + strlen (p) + 1; - retval = parse_line (p, &state); - if (retval) { - free (bptr); - return retval; - } - - p = newp; - } - } -#endif } - *root = state.root_section; + data->root = state.root_section; - free (bptr); return 0; } + #ifdef DEBUG_PROGRAM /* * Return TRUE if the string begins or ends with whitespace @@ -1720,6 +1673,12 @@ static void do_batchmode(profile_t profile) } +void syntax_err_report(const char *filename, long err, int line_num) +{ + fprintf(stderr, "Syntax error in %s, line number %d: %s\n", + filename, line_num, error_message(err)); + exit(1); +} int main(int argc, char **argv) { @@ -1733,6 +1692,8 @@ int main(int argc, char **argv) } initialize_prof_error_table(); + + profile_set_syntax_err_cb(syntax_err_report); retval = profile_init_path(argv[1], &profile); if (retval) { diff --git a/e2fsck/profile.h b/e2fsck/profile.h index ce6be03..1a175fc 100644 --- a/e2fsck/profile.h +++ b/e2fsck/profile.h @@ -41,6 +41,9 @@ typedef struct _profile_t *profile_t; +typedef void (*profile_syntax_err_cb_t)(const char *file, long err, + int line_num); + /* * Used by the profile iterator in prof_get.c */ @@ -82,6 +85,8 @@ void profile_iterator_free long profile_iterator (void **iter_p, char **ret_name, char **ret_value); +profile_syntax_err_cb_t profile_set_syntax_err_cb(profile_syntax_err_cb_t hook); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 708c255..c6c088f 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -548,6 +548,14 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts) } } +static void syntax_err_report(const char *filename, long err, int line_num) +{ + fprintf(stderr, + _("Syntax error in e2fsck config file (%s, line #%d)\n\t%s\n"), + filename, line_num, error_message(err)); + exit(FSCK_ERROR); +} + static const char *config_fn[] = { "/etc/e2fsck.conf", 0 }; static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) @@ -737,6 +745,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) if ((cp = getenv("E2FSCK_CONFIG")) != NULL) config_fn[0] = cp; + profile_set_syntax_err_cb(syntax_err_report); profile_init(config_fn, &ctx->profile); if (flush) { -- 1.8.3.1