From f855c5b5bbbc6d5436741fd8108be64825a3c76b Mon Sep 17 00:00:00 2001 From: Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> Date: Mon, 15 Sep 2025 14:06:55 +0200 Subject: general refactorin in lib, more local variables, real booleans --- lib/parse_ini.c | 141 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 81 insertions(+), 60 deletions(-) (limited to 'lib/parse_ini.c') diff --git a/lib/parse_ini.c b/lib/parse_ini.c index 4c3c1b93..db337622 100644 --- a/lib/parse_ini.c +++ b/lib/parse_ini.c @@ -59,10 +59,10 @@ static char *default_ini_path_names[] = { } while ((c) != EOF && (c) != (n)) /* internal function that returns the constructed defaults options */ -static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts); +static bool read_defaults(FILE *defaults_file, const char *stanza, np_arg_list **opts); /* internal function that converts a single line into options format */ -static int add_option(FILE *f, np_arg_list **optlst); +static int add_option(FILE *filePointer, np_arg_list **optlst); /* internal functions to find default file */ static char *default_file(void); @@ -74,7 +74,8 @@ static char *default_file_in_path(void); * into its separate parts. */ static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i) { - size_t locator_len = 0, stanza_len = 0; + size_t locator_len = 0; + size_t stanza_len = 0; /* if locator is NULL we'll use default values */ if (locator != NULL) { @@ -112,33 +113,34 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in * This is the externally visible function used by extra_opts. */ np_arg_list *np_get_defaults(const char *locator, const char *default_section) { - FILE *inifile = NULL; - np_arg_list *defaults = NULL; - np_ini_info i; int is_suid_plugin = mp_suid(); if (is_suid_plugin && idpriv_temp_drop() == -1) { die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"), strerror(errno)); } - parse_locator(locator, default_section, &i); - inifile = strcmp(i.file, "-") == 0 ? stdin : fopen(i.file, "r"); + FILE *inifile = NULL; + np_ini_info ini_info; + parse_locator(locator, default_section, &ini_info); + inifile = strcmp(ini_info.file, "-") == 0 ? stdin : fopen(ini_info.file, "r"); if (inifile == NULL) { die(STATE_UNKNOWN, _("Can't read config file: %s\n"), strerror(errno)); } - if (!read_defaults(inifile, i.stanza, &defaults)) { - die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), i.stanza, i.file); + + np_arg_list *defaults = NULL; + if (!read_defaults(inifile, ini_info.stanza, &defaults)) { + die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), ini_info.stanza, ini_info.file); } - if (i.file_string_on_heap) { - free(i.file); + if (ini_info.file_string_on_heap) { + free(ini_info.file); } if (inifile != stdin) { fclose(inifile); } - free(i.stanza); + free(ini_info.stanza); if (is_suid_plugin && idpriv_temp_restore() == -1) { die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"), strerror(errno)); } @@ -153,59 +155,58 @@ np_arg_list *np_get_defaults(const char *locator, const char *default_section) { * be extra careful about user-supplied input (i.e. avoiding possible * format string vulnerabilities, etc). */ -static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { - int c = 0; +static bool read_defaults(FILE *defaults_file, const char *stanza, np_arg_list **opts) { bool status = false; - size_t i, stanza_len; enum { NOSTANZA, WRONGSTANZA, RIGHTSTANZA } stanzastate = NOSTANZA; - stanza_len = strlen(stanza); + size_t stanza_len = strlen(stanza); /* our little stanza-parsing state machine */ - while ((c = fgetc(f)) != EOF) { + int current_char = 0; + while ((current_char = fgetc(defaults_file)) != EOF) { /* gobble up leading whitespace */ - if (isspace(c)) { + if (isspace(current_char)) { continue; } - switch (c) { + switch (current_char) { /* globble up comment lines */ case ';': case '#': - GOBBLE_TO(f, c, '\n'); + GOBBLE_TO(defaults_file, current_char, '\n'); break; /* start of a stanza, check to see if it matches */ - case '[': + case '[': { stanzastate = WRONGSTANZA; + size_t i; for (i = 0; i < stanza_len; i++) { - c = fgetc(f); + current_char = fgetc(defaults_file); /* strip leading whitespace */ if (i == 0) { - for (; isspace(c); c = fgetc(f)) { - continue; + for (; isspace(current_char); current_char = fgetc(defaults_file)) { } } /* nope, read to the end of the line */ - if (c != stanza[i]) { - GOBBLE_TO(f, c, '\n'); + if (current_char != stanza[i]) { + GOBBLE_TO(defaults_file, current_char, '\n'); break; } } + /* if it matched up to here and the next char is ']'... */ if (i == stanza_len) { - c = fgetc(f); + current_char = fgetc(defaults_file); /* strip trailing whitespace */ - for (; isspace(c); c = fgetc(f)) { - continue; + for (; isspace(current_char); current_char = fgetc(defaults_file)) { } - if (c == ']') { + if (current_char == ']') { stanzastate = RIGHTSTANZA; } } - break; + } break; /* otherwise, we're in the body of a stanza or a parse error */ default: switch (stanzastate) { @@ -216,12 +217,12 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { die(STATE_UNKNOWN, "%s\n", _("Config file error")); /* we're in a stanza, but for a different plugin */ case WRONGSTANZA: - GOBBLE_TO(f, c, '\n'); + GOBBLE_TO(defaults_file, current_char, '\n'); break; /* okay, this is where we start taking the config */ case RIGHTSTANZA: - ungetc(c, f); - if (add_option(f, opts)) { + ungetc(current_char, defaults_file); + if (add_option(defaults_file, opts)) { die(STATE_UNKNOWN, "%s\n", _("Config file error")); } status = true; @@ -240,13 +241,12 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { * --option[=value] * appending it to the linked list optbuf. */ -static int add_option(FILE *f, np_arg_list **optlst) { - np_arg_list *opttmp = *optlst, *optnew; - char *linebuf = NULL, *lineend = NULL, *optptr = NULL, *optend = NULL; - char *eqptr = NULL, *valptr = NULL, *valend = NULL; - short done_reading = 0, equals = 0, value = 0; - size_t cfg_len = 0, read_sz = 8, linebuf_sz = 0, read_pos = 0; - size_t opt_len = 0, val_len = 0; +static int add_option(FILE *filePointer, np_arg_list **optlst) { + char *linebuf = NULL; + bool done_reading = false; + const size_t read_sz = 8; + size_t linebuf_sz = 0; + size_t read_pos = 0; /* read one line from the file */ while (!done_reading) { @@ -258,24 +258,29 @@ static int add_option(FILE *f, np_arg_list **optlst) { die(STATE_UNKNOWN, _("malloc() failed!\n")); } } - if (fgets(&linebuf[read_pos], (int)read_sz, f) == NULL) { - done_reading = 1; + + if (fgets(&linebuf[read_pos], (int)read_sz, filePointer) == NULL) { + done_reading = true; } else { read_pos = strlen(linebuf); if (linebuf[read_pos - 1] == '\n') { linebuf[--read_pos] = '\0'; - done_reading = 1; + done_reading = true; } } } - lineend = &linebuf[read_pos]; + + char *lineend = &linebuf[read_pos]; /* all that to read one line, isn't C fun? :) now comes the parsing :/ */ /* skip leading whitespace */ + char *optptr = NULL; for (optptr = linebuf; optptr < lineend && isspace(*optptr); optptr++) { - continue; } + /* continue to '=' or EOL, watching for spaces that might precede it */ + char *eqptr = NULL; + char *optend = NULL; for (eqptr = optptr; eqptr < lineend && *eqptr != '='; eqptr++) { if (isspace(*eqptr) && optend == NULL) { optend = eqptr; @@ -283,55 +288,67 @@ static int add_option(FILE *f, np_arg_list **optlst) { optend = NULL; } } + if (optend == NULL) { optend = eqptr; } + --optend; + /* ^[[:space:]]*=foo is a syntax error */ if (optptr == eqptr) { die(STATE_UNKNOWN, "%s\n", _("Config file error")); } + /* continue from '=' to start of value or EOL */ + char *valptr = NULL; for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr); valptr++) { - continue; } + /* continue to the end of value */ + char *valend = NULL; for (valend = valptr; valend < lineend; valend++) { - continue; } + --valend; + /* finally trim off trailing spaces */ for (; isspace(*valend); valend--) { - continue; } + /* calculate the length of "--foo" */ - opt_len = (size_t)(1 + optend - optptr); + size_t opt_len = (size_t)(1 + optend - optptr); /* 1-character params needs only one dash */ + size_t cfg_len = 0; if (opt_len == 1) { cfg_len = 1 + (opt_len); } else { cfg_len = 2 + (opt_len); } + + size_t val_len = 0; + bool equals = false; + bool value = false; /* if valptrnext = NULL; read_pos = 0; @@ -357,6 +374,7 @@ static int add_option(FILE *f, np_arg_list **optlst) { if (*optlst == NULL) { *optlst = optnew; } else { + np_arg_list *opttmp = *optlst; while (opttmp->next != NULL) { opttmp = opttmp->next; } @@ -384,8 +402,11 @@ static char *default_file(void) { } static char *default_file_in_path(void) { - char *config_path, **file; - char *dir, *ini_file, *tokens; + char *config_path; + char **file; + char *dir; + char *ini_file; + char *tokens; if ((config_path = getenv("NAGIOS_CONFIG_PATH")) == NULL) { return NULL; -- cgit v1.2.3-74-g34f1