diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-09-15 14:06:55 +0200 |
|---|---|---|
| committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-09-15 14:06:55 +0200 |
| commit | f855c5b5bbbc6d5436741fd8108be64825a3c76b (patch) | |
| tree | 0ee1242bc21dc75a12fae03a5bb211fe10c89625 | |
| parent | 8ef825d85fb4d09c32ca44c545d6eb8d995ddea4 (diff) | |
| download | monitoring-plugins-f855c5b5bbbc6d5436741fd8108be64825a3c76b.tar.gz | |
general refactorin in lib, more local variables, real booleans
| -rw-r--r-- | lib/extra_opts.c | 39 | ||||
| -rw-r--r-- | lib/maxfd.c | 1 | ||||
| -rw-r--r-- | lib/parse_ini.c | 141 | ||||
| -rw-r--r-- | lib/tests/test_cmd.c | 14 | ||||
| -rw-r--r-- | lib/tests/test_ini1.c | 3 | ||||
| -rw-r--r-- | lib/tests/test_opts1.c | 17 | ||||
| -rw-r--r-- | lib/tests/test_opts2.c | 17 | ||||
| -rw-r--r-- | lib/tests/test_tcp.c | 5 | ||||
| -rw-r--r-- | lib/utils_base.c | 2 | ||||
| -rw-r--r-- | lib/utils_base.h | 2 | ||||
| -rw-r--r-- | lib/utils_cmd.c | 107 | ||||
| -rw-r--r-- | lib/utils_cmd.h | 8 | ||||
| -rw-r--r-- | lib/utils_tcp.c | 20 |
13 files changed, 196 insertions, 180 deletions
diff --git a/lib/extra_opts.c b/lib/extra_opts.c index 857b34b4..3fe69014 100644 --- a/lib/extra_opts.c +++ b/lib/extra_opts.c | |||
| @@ -29,26 +29,30 @@ | |||
| 29 | bool is_option2(char *str) { | 29 | bool is_option2(char *str) { |
| 30 | if (!str) { | 30 | if (!str) { |
| 31 | return false; | 31 | return false; |
| 32 | } else if (strspn(str, "-") == 1 || strspn(str, "-") == 2) { | 32 | } |
| 33 | |||
| 34 | if (strspn(str, "-") == 1 || strspn(str, "-") == 2) { | ||
| 33 | return true; | 35 | return true; |
| 34 | } else { | ||
| 35 | return false; | ||
| 36 | } | 36 | } |
| 37 | |||
| 38 | return false; | ||
| 37 | } | 39 | } |
| 38 | 40 | ||
| 39 | /* this is the externally visible function used by plugins */ | 41 | /* this is the externally visible function used by plugins */ |
| 40 | char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | 42 | char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { |
| 41 | np_arg_list *extra_args = NULL, *ea1 = NULL, *ea_tmp = NULL; | ||
| 42 | char **argv_new = NULL; | ||
| 43 | char *argptr = NULL; | ||
| 44 | int i, j, optfound, argc_new, ea_num = *argc; | ||
| 45 | |||
| 46 | if (*argc < 2) { | 43 | if (*argc < 2) { |
| 47 | /* No arguments provided */ | 44 | /* No arguments provided */ |
| 48 | return argv; | 45 | return argv; |
| 49 | } | 46 | } |
| 50 | 47 | ||
| 51 | for (i = 1; i < *argc; i++) { | 48 | np_arg_list *extra_args = NULL; |
| 49 | np_arg_list *ea1 = NULL; | ||
| 50 | np_arg_list *ea_tmp = NULL; | ||
| 51 | char *argptr = NULL; | ||
| 52 | int optfound; | ||
| 53 | size_t ea_num = (size_t)*argc; | ||
| 54 | |||
| 55 | for (int i = 1; i < *argc; i++) { | ||
| 52 | argptr = NULL; | 56 | argptr = NULL; |
| 53 | optfound = 0; | 57 | optfound = 0; |
| 54 | 58 | ||
| @@ -57,9 +61,10 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | |||
| 57 | /* It is a single argument with value */ | 61 | /* It is a single argument with value */ |
| 58 | argptr = argv[i] + 13; | 62 | argptr = argv[i] + 13; |
| 59 | /* Delete the extra opts argument */ | 63 | /* Delete the extra opts argument */ |
| 60 | for (j = i; j < *argc; j++) { | 64 | for (int j = i; j < *argc; j++) { |
| 61 | argv[j] = argv[j + 1]; | 65 | argv[j] = argv[j + 1]; |
| 62 | } | 66 | } |
| 67 | |||
| 63 | i--; | 68 | i--; |
| 64 | *argc -= 1; | 69 | *argc -= 1; |
| 65 | } else if (strcmp(argv[i], "--extra-opts") == 0) { | 70 | } else if (strcmp(argv[i], "--extra-opts") == 0) { |
| @@ -67,9 +72,10 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | |||
| 67 | /* It is a argument with separate value */ | 72 | /* It is a argument with separate value */ |
| 68 | argptr = argv[i + 1]; | 73 | argptr = argv[i + 1]; |
| 69 | /* Delete the extra-opts argument/value */ | 74 | /* Delete the extra-opts argument/value */ |
| 70 | for (j = i; j < *argc - 1; j++) { | 75 | for (int j = i; j < *argc - 1; j++) { |
| 71 | argv[j] = argv[j + 2]; | 76 | argv[j] = argv[j + 2]; |
| 72 | } | 77 | } |
| 78 | |||
| 73 | i -= 2; | 79 | i -= 2; |
| 74 | *argc -= 2; | 80 | *argc -= 2; |
| 75 | ea_num--; | 81 | ea_num--; |
| @@ -77,9 +83,10 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | |||
| 77 | /* It has no value */ | 83 | /* It has no value */ |
| 78 | optfound = 1; | 84 | optfound = 1; |
| 79 | /* Delete the extra opts argument */ | 85 | /* Delete the extra opts argument */ |
| 80 | for (j = i; j < *argc; j++) { | 86 | for (int j = i; j < *argc; j++) { |
| 81 | argv[j] = argv[j + 1]; | 87 | argv[j] = argv[j + 1]; |
| 82 | } | 88 | } |
| 89 | |||
| 83 | i--; | 90 | i--; |
| 84 | *argc -= 1; | 91 | *argc -= 1; |
| 85 | } | 92 | } |
| @@ -115,20 +122,20 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | |||
| 115 | } | 122 | } |
| 116 | } /* lather, rince, repeat */ | 123 | } /* lather, rince, repeat */ |
| 117 | 124 | ||
| 118 | if (ea_num == *argc && extra_args == NULL) { | 125 | if (ea_num == (size_t)*argc && extra_args == NULL) { |
| 119 | /* No extra-opts */ | 126 | /* No extra-opts */ |
| 120 | return argv; | 127 | return argv; |
| 121 | } | 128 | } |
| 122 | 129 | ||
| 123 | /* done processing arguments. now create a new argv array... */ | 130 | /* done processing arguments. now create a new argv array... */ |
| 124 | argv_new = (char **)malloc((ea_num + 1) * sizeof(char **)); | 131 | char **argv_new = (char **)malloc((ea_num + 1) * sizeof(char **)); |
| 125 | if (argv_new == NULL) { | 132 | if (argv_new == NULL) { |
| 126 | die(STATE_UNKNOWN, _("malloc() failed!\n")); | 133 | die(STATE_UNKNOWN, _("malloc() failed!\n")); |
| 127 | } | 134 | } |
| 128 | 135 | ||
| 129 | /* starting with program name */ | 136 | /* starting with program name */ |
| 130 | argv_new[0] = argv[0]; | 137 | argv_new[0] = argv[0]; |
| 131 | argc_new = 1; | 138 | int argc_new = 1; |
| 132 | /* then parsed ini opts (frying them up in the same run) */ | 139 | /* then parsed ini opts (frying them up in the same run) */ |
| 133 | while (extra_args) { | 140 | while (extra_args) { |
| 134 | argv_new[argc_new++] = extra_args->arg; | 141 | argv_new[argc_new++] = extra_args->arg; |
| @@ -137,7 +144,7 @@ char **np_extra_opts(int *argc, char **argv, const char *plugin_name) { | |||
| 137 | free(ea1); | 144 | free(ea1); |
| 138 | } | 145 | } |
| 139 | /* finally the rest of the argv array */ | 146 | /* finally the rest of the argv array */ |
| 140 | for (i = 1; i < *argc; i++) { | 147 | for (int i = 1; i < *argc; i++) { |
| 141 | argv_new[argc_new++] = argv[i]; | 148 | argv_new[argc_new++] = argv[i]; |
| 142 | } | 149 | } |
| 143 | *argc = argc_new; | 150 | *argc = argc_new; |
diff --git a/lib/maxfd.c b/lib/maxfd.c index 9b58d8e3..a0f79949 100644 --- a/lib/maxfd.c +++ b/lib/maxfd.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | *****************************************************************************/ | 19 | *****************************************************************************/ |
| 20 | 20 | ||
| 21 | #include "./maxfd.h" | 21 | #include "./maxfd.h" |
| 22 | #include <errno.h> | ||
| 23 | 22 | ||
| 24 | long mp_open_max(void) { | 23 | long mp_open_max(void) { |
| 25 | long maxfd = 0L; | 24 | long maxfd = 0L; |
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[] = { | |||
| 59 | } while ((c) != EOF && (c) != (n)) | 59 | } while ((c) != EOF && (c) != (n)) |
| 60 | 60 | ||
| 61 | /* internal function that returns the constructed defaults options */ | 61 | /* internal function that returns the constructed defaults options */ |
| 62 | static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts); | 62 | static bool read_defaults(FILE *defaults_file, const char *stanza, np_arg_list **opts); |
| 63 | 63 | ||
| 64 | /* internal function that converts a single line into options format */ | 64 | /* internal function that converts a single line into options format */ |
| 65 | static int add_option(FILE *f, np_arg_list **optlst); | 65 | static int add_option(FILE *filePointer, np_arg_list **optlst); |
| 66 | 66 | ||
| 67 | /* internal functions to find default file */ | 67 | /* internal functions to find default file */ |
| 68 | static char *default_file(void); | 68 | static char *default_file(void); |
| @@ -74,7 +74,8 @@ static char *default_file_in_path(void); | |||
| 74 | * into its separate parts. | 74 | * into its separate parts. |
| 75 | */ | 75 | */ |
| 76 | static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i) { | 76 | static void parse_locator(const char *locator, const char *def_stanza, np_ini_info *i) { |
| 77 | size_t locator_len = 0, stanza_len = 0; | 77 | size_t locator_len = 0; |
| 78 | size_t stanza_len = 0; | ||
| 78 | 79 | ||
| 79 | /* if locator is NULL we'll use default values */ | 80 | /* if locator is NULL we'll use default values */ |
| 80 | if (locator != NULL) { | 81 | if (locator != NULL) { |
| @@ -112,33 +113,34 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in | |||
| 112 | * This is the externally visible function used by extra_opts. | 113 | * This is the externally visible function used by extra_opts. |
| 113 | */ | 114 | */ |
| 114 | np_arg_list *np_get_defaults(const char *locator, const char *default_section) { | 115 | np_arg_list *np_get_defaults(const char *locator, const char *default_section) { |
| 115 | FILE *inifile = NULL; | ||
| 116 | np_arg_list *defaults = NULL; | ||
| 117 | np_ini_info i; | ||
| 118 | int is_suid_plugin = mp_suid(); | 116 | int is_suid_plugin = mp_suid(); |
| 119 | 117 | ||
| 120 | if (is_suid_plugin && idpriv_temp_drop() == -1) { | 118 | if (is_suid_plugin && idpriv_temp_drop() == -1) { |
| 121 | die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"), strerror(errno)); | 119 | die(STATE_UNKNOWN, _("Cannot drop privileges: %s\n"), strerror(errno)); |
| 122 | } | 120 | } |
| 123 | 121 | ||
| 124 | parse_locator(locator, default_section, &i); | 122 | FILE *inifile = NULL; |
| 125 | inifile = strcmp(i.file, "-") == 0 ? stdin : fopen(i.file, "r"); | 123 | np_ini_info ini_info; |
| 124 | parse_locator(locator, default_section, &ini_info); | ||
| 125 | inifile = strcmp(ini_info.file, "-") == 0 ? stdin : fopen(ini_info.file, "r"); | ||
| 126 | 126 | ||
| 127 | if (inifile == NULL) { | 127 | if (inifile == NULL) { |
| 128 | die(STATE_UNKNOWN, _("Can't read config file: %s\n"), strerror(errno)); | 128 | die(STATE_UNKNOWN, _("Can't read config file: %s\n"), strerror(errno)); |
| 129 | } | 129 | } |
| 130 | if (!read_defaults(inifile, i.stanza, &defaults)) { | 130 | |
| 131 | die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), i.stanza, i.file); | 131 | np_arg_list *defaults = NULL; |
| 132 | if (!read_defaults(inifile, ini_info.stanza, &defaults)) { | ||
| 133 | die(STATE_UNKNOWN, _("Invalid section '%s' in config file '%s'\n"), ini_info.stanza, ini_info.file); | ||
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | if (i.file_string_on_heap) { | 136 | if (ini_info.file_string_on_heap) { |
| 135 | free(i.file); | 137 | free(ini_info.file); |
| 136 | } | 138 | } |
| 137 | 139 | ||
| 138 | if (inifile != stdin) { | 140 | if (inifile != stdin) { |
| 139 | fclose(inifile); | 141 | fclose(inifile); |
| 140 | } | 142 | } |
| 141 | free(i.stanza); | 143 | free(ini_info.stanza); |
| 142 | if (is_suid_plugin && idpriv_temp_restore() == -1) { | 144 | if (is_suid_plugin && idpriv_temp_restore() == -1) { |
| 143 | die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"), strerror(errno)); | 145 | die(STATE_UNKNOWN, _("Cannot restore privileges: %s\n"), strerror(errno)); |
| 144 | } | 146 | } |
| @@ -153,59 +155,58 @@ np_arg_list *np_get_defaults(const char *locator, const char *default_section) { | |||
| 153 | * be extra careful about user-supplied input (i.e. avoiding possible | 155 | * be extra careful about user-supplied input (i.e. avoiding possible |
| 154 | * format string vulnerabilities, etc). | 156 | * format string vulnerabilities, etc). |
| 155 | */ | 157 | */ |
| 156 | static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { | 158 | static bool read_defaults(FILE *defaults_file, const char *stanza, np_arg_list **opts) { |
| 157 | int c = 0; | ||
| 158 | bool status = false; | 159 | bool status = false; |
| 159 | size_t i, stanza_len; | ||
| 160 | enum { | 160 | enum { |
| 161 | NOSTANZA, | 161 | NOSTANZA, |
| 162 | WRONGSTANZA, | 162 | WRONGSTANZA, |
| 163 | RIGHTSTANZA | 163 | RIGHTSTANZA |
| 164 | } stanzastate = NOSTANZA; | 164 | } stanzastate = NOSTANZA; |
| 165 | 165 | ||
| 166 | stanza_len = strlen(stanza); | 166 | size_t stanza_len = strlen(stanza); |
| 167 | 167 | ||
| 168 | /* our little stanza-parsing state machine */ | 168 | /* our little stanza-parsing state machine */ |
| 169 | while ((c = fgetc(f)) != EOF) { | 169 | int current_char = 0; |
| 170 | while ((current_char = fgetc(defaults_file)) != EOF) { | ||
| 170 | /* gobble up leading whitespace */ | 171 | /* gobble up leading whitespace */ |
| 171 | if (isspace(c)) { | 172 | if (isspace(current_char)) { |
| 172 | continue; | 173 | continue; |
| 173 | } | 174 | } |
| 174 | switch (c) { | 175 | switch (current_char) { |
| 175 | /* globble up comment lines */ | 176 | /* globble up comment lines */ |
| 176 | case ';': | 177 | case ';': |
| 177 | case '#': | 178 | case '#': |
| 178 | GOBBLE_TO(f, c, '\n'); | 179 | GOBBLE_TO(defaults_file, current_char, '\n'); |
| 179 | break; | 180 | break; |
| 180 | /* start of a stanza, check to see if it matches */ | 181 | /* start of a stanza, check to see if it matches */ |
| 181 | case '[': | 182 | case '[': { |
| 182 | stanzastate = WRONGSTANZA; | 183 | stanzastate = WRONGSTANZA; |
| 184 | size_t i; | ||
| 183 | for (i = 0; i < stanza_len; i++) { | 185 | for (i = 0; i < stanza_len; i++) { |
| 184 | c = fgetc(f); | 186 | current_char = fgetc(defaults_file); |
| 185 | /* strip leading whitespace */ | 187 | /* strip leading whitespace */ |
| 186 | if (i == 0) { | 188 | if (i == 0) { |
| 187 | for (; isspace(c); c = fgetc(f)) { | 189 | for (; isspace(current_char); current_char = fgetc(defaults_file)) { |
| 188 | continue; | ||
| 189 | } | 190 | } |
| 190 | } | 191 | } |
| 191 | /* nope, read to the end of the line */ | 192 | /* nope, read to the end of the line */ |
| 192 | if (c != stanza[i]) { | 193 | if (current_char != stanza[i]) { |
| 193 | GOBBLE_TO(f, c, '\n'); | 194 | GOBBLE_TO(defaults_file, current_char, '\n'); |
| 194 | break; | 195 | break; |
| 195 | } | 196 | } |
| 196 | } | 197 | } |
| 198 | |||
| 197 | /* if it matched up to here and the next char is ']'... */ | 199 | /* if it matched up to here and the next char is ']'... */ |
| 198 | if (i == stanza_len) { | 200 | if (i == stanza_len) { |
| 199 | c = fgetc(f); | 201 | current_char = fgetc(defaults_file); |
| 200 | /* strip trailing whitespace */ | 202 | /* strip trailing whitespace */ |
| 201 | for (; isspace(c); c = fgetc(f)) { | 203 | for (; isspace(current_char); current_char = fgetc(defaults_file)) { |
| 202 | continue; | ||
| 203 | } | 204 | } |
| 204 | if (c == ']') { | 205 | if (current_char == ']') { |
| 205 | stanzastate = RIGHTSTANZA; | 206 | stanzastate = RIGHTSTANZA; |
| 206 | } | 207 | } |
| 207 | } | 208 | } |
| 208 | break; | 209 | } break; |
| 209 | /* otherwise, we're in the body of a stanza or a parse error */ | 210 | /* otherwise, we're in the body of a stanza or a parse error */ |
| 210 | default: | 211 | default: |
| 211 | switch (stanzastate) { | 212 | switch (stanzastate) { |
| @@ -216,12 +217,12 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { | |||
| 216 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); | 217 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); |
| 217 | /* we're in a stanza, but for a different plugin */ | 218 | /* we're in a stanza, but for a different plugin */ |
| 218 | case WRONGSTANZA: | 219 | case WRONGSTANZA: |
| 219 | GOBBLE_TO(f, c, '\n'); | 220 | GOBBLE_TO(defaults_file, current_char, '\n'); |
| 220 | break; | 221 | break; |
| 221 | /* okay, this is where we start taking the config */ | 222 | /* okay, this is where we start taking the config */ |
| 222 | case RIGHTSTANZA: | 223 | case RIGHTSTANZA: |
| 223 | ungetc(c, f); | 224 | ungetc(current_char, defaults_file); |
| 224 | if (add_option(f, opts)) { | 225 | if (add_option(defaults_file, opts)) { |
| 225 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); | 226 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); |
| 226 | } | 227 | } |
| 227 | status = true; | 228 | status = true; |
| @@ -240,13 +241,12 @@ static int read_defaults(FILE *f, const char *stanza, np_arg_list **opts) { | |||
| 240 | * --option[=value] | 241 | * --option[=value] |
| 241 | * appending it to the linked list optbuf. | 242 | * appending it to the linked list optbuf. |
| 242 | */ | 243 | */ |
| 243 | static int add_option(FILE *f, np_arg_list **optlst) { | 244 | static int add_option(FILE *filePointer, np_arg_list **optlst) { |
| 244 | np_arg_list *opttmp = *optlst, *optnew; | 245 | char *linebuf = NULL; |
| 245 | char *linebuf = NULL, *lineend = NULL, *optptr = NULL, *optend = NULL; | 246 | bool done_reading = false; |
| 246 | char *eqptr = NULL, *valptr = NULL, *valend = NULL; | 247 | const size_t read_sz = 8; |
| 247 | short done_reading = 0, equals = 0, value = 0; | 248 | size_t linebuf_sz = 0; |
| 248 | size_t cfg_len = 0, read_sz = 8, linebuf_sz = 0, read_pos = 0; | 249 | size_t read_pos = 0; |
| 249 | size_t opt_len = 0, val_len = 0; | ||
| 250 | 250 | ||
| 251 | /* read one line from the file */ | 251 | /* read one line from the file */ |
| 252 | while (!done_reading) { | 252 | while (!done_reading) { |
| @@ -258,24 +258,29 @@ static int add_option(FILE *f, np_arg_list **optlst) { | |||
| 258 | die(STATE_UNKNOWN, _("malloc() failed!\n")); | 258 | die(STATE_UNKNOWN, _("malloc() failed!\n")); |
| 259 | } | 259 | } |
| 260 | } | 260 | } |
| 261 | if (fgets(&linebuf[read_pos], (int)read_sz, f) == NULL) { | 261 | |
| 262 | done_reading = 1; | 262 | if (fgets(&linebuf[read_pos], (int)read_sz, filePointer) == NULL) { |
| 263 | done_reading = true; | ||
| 263 | } else { | 264 | } else { |
| 264 | read_pos = strlen(linebuf); | 265 | read_pos = strlen(linebuf); |
| 265 | if (linebuf[read_pos - 1] == '\n') { | 266 | if (linebuf[read_pos - 1] == '\n') { |
| 266 | linebuf[--read_pos] = '\0'; | 267 | linebuf[--read_pos] = '\0'; |
| 267 | done_reading = 1; | 268 | done_reading = true; |
| 268 | } | 269 | } |
| 269 | } | 270 | } |
| 270 | } | 271 | } |
| 271 | lineend = &linebuf[read_pos]; | 272 | |
| 273 | char *lineend = &linebuf[read_pos]; | ||
| 272 | /* all that to read one line, isn't C fun? :) now comes the parsing :/ */ | 274 | /* all that to read one line, isn't C fun? :) now comes the parsing :/ */ |
| 273 | 275 | ||
| 274 | /* skip leading whitespace */ | 276 | /* skip leading whitespace */ |
| 277 | char *optptr = NULL; | ||
| 275 | for (optptr = linebuf; optptr < lineend && isspace(*optptr); optptr++) { | 278 | for (optptr = linebuf; optptr < lineend && isspace(*optptr); optptr++) { |
| 276 | continue; | ||
| 277 | } | 279 | } |
| 280 | |||
| 278 | /* continue to '=' or EOL, watching for spaces that might precede it */ | 281 | /* continue to '=' or EOL, watching for spaces that might precede it */ |
| 282 | char *eqptr = NULL; | ||
| 283 | char *optend = NULL; | ||
| 279 | for (eqptr = optptr; eqptr < lineend && *eqptr != '='; eqptr++) { | 284 | for (eqptr = optptr; eqptr < lineend && *eqptr != '='; eqptr++) { |
| 280 | if (isspace(*eqptr) && optend == NULL) { | 285 | if (isspace(*eqptr) && optend == NULL) { |
| 281 | optend = eqptr; | 286 | optend = eqptr; |
| @@ -283,55 +288,67 @@ static int add_option(FILE *f, np_arg_list **optlst) { | |||
| 283 | optend = NULL; | 288 | optend = NULL; |
| 284 | } | 289 | } |
| 285 | } | 290 | } |
| 291 | |||
| 286 | if (optend == NULL) { | 292 | if (optend == NULL) { |
| 287 | optend = eqptr; | 293 | optend = eqptr; |
| 288 | } | 294 | } |
| 295 | |||
| 289 | --optend; | 296 | --optend; |
| 297 | |||
| 290 | /* ^[[:space:]]*=foo is a syntax error */ | 298 | /* ^[[:space:]]*=foo is a syntax error */ |
| 291 | if (optptr == eqptr) { | 299 | if (optptr == eqptr) { |
| 292 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); | 300 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); |
| 293 | } | 301 | } |
| 302 | |||
| 294 | /* continue from '=' to start of value or EOL */ | 303 | /* continue from '=' to start of value or EOL */ |
| 304 | char *valptr = NULL; | ||
| 295 | for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr); valptr++) { | 305 | for (valptr = eqptr + 1; valptr < lineend && isspace(*valptr); valptr++) { |
| 296 | continue; | ||
| 297 | } | 306 | } |
| 307 | |||
| 298 | /* continue to the end of value */ | 308 | /* continue to the end of value */ |
| 309 | char *valend = NULL; | ||
| 299 | for (valend = valptr; valend < lineend; valend++) { | 310 | for (valend = valptr; valend < lineend; valend++) { |
| 300 | continue; | ||
| 301 | } | 311 | } |
| 312 | |||
| 302 | --valend; | 313 | --valend; |
| 314 | |||
| 303 | /* finally trim off trailing spaces */ | 315 | /* finally trim off trailing spaces */ |
| 304 | for (; isspace(*valend); valend--) { | 316 | for (; isspace(*valend); valend--) { |
| 305 | continue; | ||
| 306 | } | 317 | } |
| 318 | |||
| 307 | /* calculate the length of "--foo" */ | 319 | /* calculate the length of "--foo" */ |
| 308 | opt_len = (size_t)(1 + optend - optptr); | 320 | size_t opt_len = (size_t)(1 + optend - optptr); |
| 309 | /* 1-character params needs only one dash */ | 321 | /* 1-character params needs only one dash */ |
| 322 | size_t cfg_len = 0; | ||
| 310 | if (opt_len == 1) { | 323 | if (opt_len == 1) { |
| 311 | cfg_len = 1 + (opt_len); | 324 | cfg_len = 1 + (opt_len); |
| 312 | } else { | 325 | } else { |
| 313 | cfg_len = 2 + (opt_len); | 326 | cfg_len = 2 + (opt_len); |
| 314 | } | 327 | } |
| 328 | |||
| 329 | size_t val_len = 0; | ||
| 330 | bool equals = false; | ||
| 331 | bool value = false; | ||
| 315 | /* if valptr<lineend then we have to also allocate space for "=bar" */ | 332 | /* if valptr<lineend then we have to also allocate space for "=bar" */ |
| 316 | if (valptr < lineend) { | 333 | if (valptr < lineend) { |
| 317 | equals = value = 1; | 334 | equals = value = true; |
| 318 | val_len = (size_t)(1 + valend - valptr); | 335 | val_len = (size_t)(1 + valend - valptr); |
| 319 | cfg_len += 1 + val_len; | 336 | cfg_len += 1 + val_len; |
| 320 | } | 337 | } else if (valptr == lineend) { |
| 321 | /* if valptr==valend then we have "=" but no "bar" */ | 338 | /* if valptr==valend then we have "=" but no "bar" */ |
| 322 | else if (valptr == lineend) { | 339 | equals = true; |
| 323 | equals = 1; | ||
| 324 | cfg_len += 1; | 340 | cfg_len += 1; |
| 325 | } | 341 | } |
| 342 | |||
| 326 | /* a line with no equal sign isn't valid */ | 343 | /* a line with no equal sign isn't valid */ |
| 327 | if (equals == 0) { | 344 | if (!equals) { |
| 328 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); | 345 | die(STATE_UNKNOWN, "%s\n", _("Config file error")); |
| 329 | } | 346 | } |
| 330 | 347 | ||
| 331 | /* okay, now we have all the info we need, so we create a new np_arg_list | 348 | /* okay, now we have all the info we need, so we create a new np_arg_list |
| 332 | * element and set the argument... | 349 | * element and set the argument... |
| 333 | */ | 350 | */ |
| 334 | optnew = malloc(sizeof(np_arg_list)); | 351 | np_arg_list *optnew = malloc(sizeof(np_arg_list)); |
| 335 | optnew->next = NULL; | 352 | optnew->next = NULL; |
| 336 | 353 | ||
| 337 | read_pos = 0; | 354 | read_pos = 0; |
| @@ -357,6 +374,7 @@ static int add_option(FILE *f, np_arg_list **optlst) { | |||
| 357 | if (*optlst == NULL) { | 374 | if (*optlst == NULL) { |
| 358 | *optlst = optnew; | 375 | *optlst = optnew; |
| 359 | } else { | 376 | } else { |
| 377 | np_arg_list *opttmp = *optlst; | ||
| 360 | while (opttmp->next != NULL) { | 378 | while (opttmp->next != NULL) { |
| 361 | opttmp = opttmp->next; | 379 | opttmp = opttmp->next; |
| 362 | } | 380 | } |
| @@ -384,8 +402,11 @@ static char *default_file(void) { | |||
| 384 | } | 402 | } |
| 385 | 403 | ||
| 386 | static char *default_file_in_path(void) { | 404 | static char *default_file_in_path(void) { |
| 387 | char *config_path, **file; | 405 | char *config_path; |
| 388 | char *dir, *ini_file, *tokens; | 406 | char **file; |
| 407 | char *dir; | ||
| 408 | char *ini_file; | ||
| 409 | char *tokens; | ||
| 389 | 410 | ||
| 390 | if ((config_path = getenv("NAGIOS_CONFIG_PATH")) == NULL) { | 411 | if ((config_path = getenv("NAGIOS_CONFIG_PATH")) == NULL) { |
| 391 | return NULL; | 412 | return NULL; |
diff --git a/lib/tests/test_cmd.c b/lib/tests/test_cmd.c index ade0da90..d51016cc 100644 --- a/lib/tests/test_cmd.c +++ b/lib/tests/test_cmd.c | |||
| @@ -38,31 +38,29 @@ char *get_command(char *const *line) { | |||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | int main(int argc, char **argv) { | 40 | int main(int argc, char **argv) { |
| 41 | char **command_line = malloc(sizeof(char *) * COMMAND_LINE); | ||
| 42 | char *command = NULL; | ||
| 43 | char *perl; | ||
| 44 | output chld_out, chld_err; | ||
| 45 | int c; | ||
| 46 | int result = UNSET; | ||
| 47 | |||
| 48 | plan_tests(51); | 41 | plan_tests(51); |
| 49 | 42 | ||
| 50 | diag("Running plain echo command, set one"); | 43 | diag("Running plain echo command, set one"); |
| 51 | 44 | ||
| 52 | /* ensure everything is empty before we begin */ | 45 | /* ensure everything is empty before we begin */ |
| 46 | |||
| 47 | output chld_out; | ||
| 53 | memset(&chld_out, 0, sizeof(output)); | 48 | memset(&chld_out, 0, sizeof(output)); |
| 49 | output chld_err; | ||
| 54 | memset(&chld_err, 0, sizeof(output)); | 50 | memset(&chld_err, 0, sizeof(output)); |
| 55 | ok(chld_out.lines == 0, "(initialised) Checking stdout is reset"); | 51 | ok(chld_out.lines == 0, "(initialised) Checking stdout is reset"); |
| 56 | ok(chld_err.lines == 0, "(initialised) Checking stderr is reset"); | 52 | ok(chld_err.lines == 0, "(initialised) Checking stderr is reset"); |
| 53 | int result = UNSET; | ||
| 57 | ok(result == UNSET, "(initialised) Checking exit code is reset"); | 54 | ok(result == UNSET, "(initialised) Checking exit code is reset"); |
| 58 | 55 | ||
| 56 | char **command_line = malloc(sizeof(char *) * COMMAND_LINE); | ||
| 59 | command_line[0] = strdup("/bin/echo"); | 57 | command_line[0] = strdup("/bin/echo"); |
| 60 | command_line[1] = strdup("this"); | 58 | command_line[1] = strdup("this"); |
| 61 | command_line[2] = strdup("is"); | 59 | command_line[2] = strdup("is"); |
| 62 | command_line[3] = strdup("test"); | 60 | command_line[3] = strdup("test"); |
| 63 | command_line[4] = strdup("one"); | 61 | command_line[4] = strdup("one"); |
| 64 | 62 | ||
| 65 | command = get_command(command_line); | 63 | char *command = get_command(command_line); |
| 66 | 64 | ||
| 67 | result = cmd_run_array(command_line, &chld_out, &chld_err, 0); | 65 | result = cmd_run_array(command_line, &chld_out, &chld_err, 0); |
| 68 | ok(chld_out.lines == 1, "(array) Check for expected number of stdout lines"); | 66 | ok(chld_out.lines == 1, "(array) Check for expected number of stdout lines"); |
diff --git a/lib/tests/test_ini1.c b/lib/tests/test_ini1.c index 3792d142..de983764 100644 --- a/lib/tests/test_ini1.c +++ b/lib/tests/test_ini1.c | |||
| @@ -50,11 +50,10 @@ char *list2str(np_arg_list *optlst) { | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | int main(int argc, char **argv) { | 52 | int main(int argc, char **argv) { |
| 53 | char *optstr = NULL; | ||
| 54 | 53 | ||
| 55 | plan_tests(12); | 54 | plan_tests(12); |
| 56 | 55 | ||
| 57 | optstr = list2str(np_get_defaults("section@./config-tiny.ini", "check_disk")); | 56 | char *optstr = list2str(np_get_defaults("section@./config-tiny.ini", "check_disk")); |
| 58 | ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), | 57 | ok(!strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank"), |
| 59 | "config-tiny.ini's section as expected"); | 58 | "config-tiny.ini's section as expected"); |
| 60 | my_free(optstr); | 59 | my_free(optstr); |
diff --git a/lib/tests/test_opts1.c b/lib/tests/test_opts1.c index 99da5596..fa95c4d4 100644 --- a/lib/tests/test_opts1.c +++ b/lib/tests/test_opts1.c | |||
| @@ -40,15 +40,16 @@ void my_free(int *argc, char **newargv, char **argv) { | |||
| 40 | #else | 40 | #else |
| 41 | void my_free(int *argc, char **newargv, char **argv) { | 41 | void my_free(int *argc, char **newargv, char **argv) { |
| 42 | /* Free stuff (and print while we're at it) */ | 42 | /* Free stuff (and print while we're at it) */ |
| 43 | int i, freeflag = 1; | 43 | bool freeflag = true; |
| 44 | printf(" Arg(%i): ", *argc + 1); | 44 | printf(" Arg(%i): ", *argc + 1); |
| 45 | printf("'%s' ", newargv[0]); | 45 | printf("'%s' ", newargv[0]); |
| 46 | for (i = 1; i < *argc; i++) { | 46 | |
| 47 | for (int i = 1; i < *argc; i++) { | ||
| 47 | printf("'%s' ", newargv[i]); | 48 | printf("'%s' ", newargv[i]); |
| 48 | /* Stop freeing when we get to the start of the original array */ | 49 | /* Stop freeing when we get to the start of the original array */ |
| 49 | if (freeflag) { | 50 | if (freeflag) { |
| 50 | if (newargv[i] == argv[1]) { | 51 | if (newargv[i] == argv[1]) { |
| 51 | freeflag = 0; | 52 | freeflag = false; |
| 52 | } else { | 53 | } else { |
| 53 | free(newargv[i]); | 54 | free(newargv[i]); |
| 54 | } | 55 | } |
| @@ -64,13 +65,12 @@ void my_free(int *argc, char **newargv, char **argv) { | |||
| 64 | #endif | 65 | #endif |
| 65 | 66 | ||
| 66 | int array_diff(int i1, char **a1, int i2, char **a2) { | 67 | int array_diff(int i1, char **a1, int i2, char **a2) { |
| 67 | int i; | ||
| 68 | |||
| 69 | if (i1 != i2) { | 68 | if (i1 != i2) { |
| 70 | printf(" Argument count doesn't match!\n"); | 69 | printf(" Argument count doesn't match!\n"); |
| 71 | return 0; | 70 | return 0; |
| 72 | } | 71 | } |
| 73 | for (i = 0; i <= i1; i++) { | 72 | |
| 73 | for (int i = 0; i <= i1; i++) { | ||
| 74 | if (a1[i] == NULL && a2[i] == NULL) { | 74 | if (a1[i] == NULL && a2[i] == NULL) { |
| 75 | continue; | 75 | continue; |
| 76 | } | 76 | } |
| @@ -87,11 +87,10 @@ int array_diff(int i1, char **a1, int i2, char **a2) { | |||
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | int main(int argc, char **argv) { | 89 | int main(int argc, char **argv) { |
| 90 | char **argv_new = NULL; | ||
| 91 | int i, argc_test; | ||
| 92 | |||
| 93 | plan_tests(5); | 90 | plan_tests(5); |
| 94 | 91 | ||
| 92 | char **argv_new = NULL; | ||
| 93 | int argc_test; | ||
| 95 | { | 94 | { |
| 96 | char *argv_test[] = {"prog_name", (char *)NULL}; | 95 | char *argv_test[] = {"prog_name", (char *)NULL}; |
| 97 | argc_test = 1; | 96 | argc_test = 1; |
diff --git a/lib/tests/test_opts2.c b/lib/tests/test_opts2.c index d1b0aca3..3dd1b039 100644 --- a/lib/tests/test_opts2.c +++ b/lib/tests/test_opts2.c | |||
| @@ -23,15 +23,16 @@ | |||
| 23 | 23 | ||
| 24 | void my_free(int *argc, char **newargv, char **argv) { | 24 | void my_free(int *argc, char **newargv, char **argv) { |
| 25 | /* Free stuff (and print while we're at it) */ | 25 | /* Free stuff (and print while we're at it) */ |
| 26 | int i, freeflag = 1; | 26 | bool freeflag = true; |
| 27 | |||
| 27 | printf(" Arg(%i): ", *argc + 1); | 28 | printf(" Arg(%i): ", *argc + 1); |
| 28 | printf("'%s' ", newargv[0]); | 29 | printf("'%s' ", newargv[0]); |
| 29 | for (i = 1; i < *argc; i++) { | 30 | for (int i = 1; i < *argc; i++) { |
| 30 | printf("'%s' ", newargv[i]); | 31 | printf("'%s' ", newargv[i]); |
| 31 | /* Stop freeing when we get to the start of the original array */ | 32 | /* Stop freeing when we get to the start of the original array */ |
| 32 | if (freeflag) { | 33 | if (freeflag) { |
| 33 | if (newargv[i] == argv[1]) { | 34 | if (newargv[i] == argv[1]) { |
| 34 | freeflag = 0; | 35 | freeflag = false; |
| 35 | } else { | 36 | } else { |
| 36 | free(newargv[i]); | 37 | free(newargv[i]); |
| 37 | } | 38 | } |
| @@ -46,13 +47,12 @@ void my_free(int *argc, char **newargv, char **argv) { | |||
| 46 | } | 47 | } |
| 47 | 48 | ||
| 48 | int array_diff(int i1, char **a1, int i2, char **a2) { | 49 | int array_diff(int i1, char **a1, int i2, char **a2) { |
| 49 | int i; | ||
| 50 | |||
| 51 | if (i1 != i2) { | 50 | if (i1 != i2) { |
| 52 | printf(" Argument count doesn't match!\n"); | 51 | printf(" Argument count doesn't match!\n"); |
| 53 | return 0; | 52 | return 0; |
| 54 | } | 53 | } |
| 55 | for (i = 0; i <= i1; i++) { | 54 | |
| 55 | for (int i = 0; i <= i1; i++) { | ||
| 56 | if (a1[i] == NULL && a2[i] == NULL) { | 56 | if (a1[i] == NULL && a2[i] == NULL) { |
| 57 | continue; | 57 | continue; |
| 58 | } | 58 | } |
| @@ -69,11 +69,10 @@ int array_diff(int i1, char **a1, int i2, char **a2) { | |||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | int main(int argc, char **argv) { | 71 | int main(int argc, char **argv) { |
| 72 | char **argv_new = NULL; | ||
| 73 | int i, argc_test; | ||
| 74 | |||
| 75 | plan_tests(5); | 72 | plan_tests(5); |
| 76 | 73 | ||
| 74 | char **argv_new = NULL; | ||
| 75 | int argc_test; | ||
| 77 | { | 76 | { |
| 78 | char *argv_test[] = {"prog_name", "arg1", "--extra-opts", "--arg3", "val2", (char *)NULL}; | 77 | char *argv_test[] = {"prog_name", "arg1", "--extra-opts", "--arg3", "val2", (char *)NULL}; |
| 79 | argc_test = 5; | 78 | argc_test = 5; |
diff --git a/lib/tests/test_tcp.c b/lib/tests/test_tcp.c index de3a2102..37c818c9 100644 --- a/lib/tests/test_tcp.c +++ b/lib/tests/test_tcp.c | |||
| @@ -21,11 +21,10 @@ | |||
| 21 | #include "tap.h" | 21 | #include "tap.h" |
| 22 | 22 | ||
| 23 | int main(void) { | 23 | int main(void) { |
| 24 | char **server_expect; | ||
| 25 | int server_expect_count = 3; | ||
| 26 | |||
| 27 | plan_tests(9); | 24 | plan_tests(9); |
| 28 | 25 | ||
| 26 | char **server_expect; | ||
| 27 | const int server_expect_count = 3; | ||
| 29 | server_expect = malloc(sizeof(char *) * server_expect_count); | 28 | server_expect = malloc(sizeof(char *) * server_expect_count); |
| 30 | 29 | ||
| 31 | server_expect[0] = strdup("AA"); | 30 | server_expect[0] = strdup("AA"); |
diff --git a/lib/utils_base.c b/lib/utils_base.c index 69024bc9..28e6dc47 100644 --- a/lib/utils_base.c +++ b/lib/utils_base.c | |||
| @@ -44,7 +44,7 @@ | |||
| 44 | 44 | ||
| 45 | monitoring_plugin *this_monitoring_plugin = NULL; | 45 | monitoring_plugin *this_monitoring_plugin = NULL; |
| 46 | 46 | ||
| 47 | int timeout_state = STATE_CRITICAL; | 47 | mp_state_enum timeout_state = STATE_CRITICAL; |
| 48 | unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT; | 48 | unsigned int timeout_interval = DEFAULT_SOCKET_TIMEOUT; |
| 49 | 49 | ||
| 50 | bool _np_state_read_file(FILE *state_file); | 50 | bool _np_state_read_file(FILE *state_file); |
diff --git a/lib/utils_base.h b/lib/utils_base.h index f31299c4..27884bf0 100644 --- a/lib/utils_base.h +++ b/lib/utils_base.h | |||
| @@ -41,7 +41,7 @@ bool mp_check_range(mp_perfdata_value, mp_range); | |||
| 41 | mp_state_enum get_status(double, thresholds *); | 41 | mp_state_enum get_status(double, thresholds *); |
| 42 | 42 | ||
| 43 | /* Handle timeouts */ | 43 | /* Handle timeouts */ |
| 44 | extern int timeout_state; | 44 | extern mp_state_enum timeout_state; |
| 45 | extern unsigned int timeout_interval; | 45 | extern unsigned int timeout_interval; |
| 46 | 46 | ||
| 47 | /* All possible characters in a threshold range */ | 47 | /* All possible characters in a threshold range */ |
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c index d1feaa33..35b83297 100644 --- a/lib/utils_cmd.c +++ b/lib/utils_cmd.c | |||
| @@ -40,7 +40,6 @@ | |||
| 40 | 40 | ||
| 41 | /** includes **/ | 41 | /** includes **/ |
| 42 | #include "common.h" | 42 | #include "common.h" |
| 43 | #include "utils.h" | ||
| 44 | #include "utils_cmd.h" | 43 | #include "utils_cmd.h" |
| 45 | /* This variable must be global, since there's no way the caller | 44 | /* This variable must be global, since there's no way the caller |
| 46 | * can forcibly slay a dead or ungainly running program otherwise. | 45 | * can forcibly slay a dead or ungainly running program otherwise. |
| @@ -62,9 +61,6 @@ static pid_t *_cmd_pids = NULL; | |||
| 62 | # include <sys/wait.h> | 61 | # include <sys/wait.h> |
| 63 | #endif | 62 | #endif |
| 64 | 63 | ||
| 65 | /* used in _cmd_open to pass the environment to commands */ | ||
| 66 | extern char **environ; | ||
| 67 | |||
| 68 | /** macros **/ | 64 | /** macros **/ |
| 69 | #ifndef WEXITSTATUS | 65 | #ifndef WEXITSTATUS |
| 70 | # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) | 66 | # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) |
| @@ -80,14 +76,12 @@ extern char **environ; | |||
| 80 | #endif | 76 | #endif |
| 81 | 77 | ||
| 82 | /** prototypes **/ | 78 | /** prototypes **/ |
| 83 | static int _cmd_open(char *const *, int *, int *) __attribute__((__nonnull__(1, 2, 3))); | 79 | static int _cmd_open(char *const *argv, int *pfd, int *pfderr) |
| 84 | 80 | __attribute__((__nonnull__(1, 2, 3))); | |
| 85 | static int _cmd_fetch_output(int, output *, int) __attribute__((__nonnull__(2))); | ||
| 86 | 81 | ||
| 87 | static int _cmd_close(int); | 82 | static int _cmd_fetch_output(int fileDescriptor, output *cmd_output, int flags) __attribute__((__nonnull__(2))); |
| 88 | 83 | ||
| 89 | /* prototype imported from utils.h */ | 84 | static int _cmd_close(int fileDescriptor); |
| 90 | extern void die(int, const char *, ...) __attribute__((__noreturn__, __format__(__printf__, 2, 3))); | ||
| 91 | 85 | ||
| 92 | /* this function is NOT async-safe. It is exported so multithreaded | 86 | /* this function is NOT async-safe. It is exported so multithreaded |
| 93 | * plugins (or other apps) can call it prior to running any commands | 87 | * plugins (or other apps) can call it prior to running any commands |
| @@ -110,7 +104,6 @@ void cmd_init(void) { | |||
| 110 | 104 | ||
| 111 | /* Start running a command, array style */ | 105 | /* Start running a command, array style */ |
| 112 | static int _cmd_open(char *const *argv, int *pfd, int *pfderr) { | 106 | static int _cmd_open(char *const *argv, int *pfd, int *pfderr) { |
| 113 | pid_t pid; | ||
| 114 | #ifdef RLIMIT_CORE | 107 | #ifdef RLIMIT_CORE |
| 115 | struct rlimit limit; | 108 | struct rlimit limit; |
| 116 | #endif | 109 | #endif |
| @@ -123,6 +116,7 @@ static int _cmd_open(char *const *argv, int *pfd, int *pfderr) { | |||
| 123 | 116 | ||
| 124 | setenv("LC_ALL", "C", 1); | 117 | setenv("LC_ALL", "C", 1); |
| 125 | 118 | ||
| 119 | pid_t pid; | ||
| 126 | if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) { | 120 | if (pipe(pfd) < 0 || pipe(pfderr) < 0 || (pid = fork()) < 0) { |
| 127 | return -1; /* errno set by the failing function */ | 121 | return -1; /* errno set by the failing function */ |
| 128 | } | 122 | } |
| @@ -171,22 +165,23 @@ static int _cmd_open(char *const *argv, int *pfd, int *pfderr) { | |||
| 171 | return pfd[0]; | 165 | return pfd[0]; |
| 172 | } | 166 | } |
| 173 | 167 | ||
| 174 | static int _cmd_close(int fd) { | 168 | static int _cmd_close(int fileDescriptor) { |
| 175 | int status; | ||
| 176 | pid_t pid; | 169 | pid_t pid; |
| 177 | 170 | ||
| 178 | /* make sure the provided fd was opened */ | 171 | /* make sure the provided fd was opened */ |
| 179 | long maxfd = mp_open_max(); | 172 | long maxfd = mp_open_max(); |
| 180 | if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0) { | 173 | if (fileDescriptor < 0 || fileDescriptor > maxfd || !_cmd_pids || |
| 174 | (pid = _cmd_pids[fileDescriptor]) == 0) { | ||
| 181 | return -1; | 175 | return -1; |
| 182 | } | 176 | } |
| 183 | 177 | ||
| 184 | _cmd_pids[fd] = 0; | 178 | _cmd_pids[fileDescriptor] = 0; |
| 185 | if (close(fd) == -1) { | 179 | if (close(fileDescriptor) == -1) { |
| 186 | return -1; | 180 | return -1; |
| 187 | } | 181 | } |
| 188 | 182 | ||
| 189 | /* EINTR is ok (sort of), everything else is bad */ | 183 | /* EINTR is ok (sort of), everything else is bad */ |
| 184 | int status; | ||
| 190 | while (waitpid(pid, &status, 0) < 0) { | 185 | while (waitpid(pid, &status, 0) < 0) { |
| 191 | if (errno != EINTR) { | 186 | if (errno != EINTR) { |
| 192 | return -1; | 187 | return -1; |
| @@ -197,68 +192,67 @@ static int _cmd_close(int fd) { | |||
| 197 | return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1; | 192 | return (WIFEXITED(status)) ? WEXITSTATUS(status) : -1; |
| 198 | } | 193 | } |
| 199 | 194 | ||
| 200 | static int _cmd_fetch_output(int fd, output *op, int flags) { | 195 | static int _cmd_fetch_output(int fileDescriptor, output *cmd_output, int flags) { |
| 201 | size_t len = 0, i = 0, lineno = 0; | ||
| 202 | size_t rsf = 6, ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */ | ||
| 203 | char *buf = NULL; | ||
| 204 | int ret; | ||
| 205 | char tmpbuf[4096]; | 196 | char tmpbuf[4096]; |
| 206 | 197 | cmd_output->buf = NULL; | |
| 207 | op->buf = NULL; | 198 | cmd_output->buflen = 0; |
| 208 | op->buflen = 0; | 199 | ssize_t ret; |
| 209 | while ((ret = read(fd, tmpbuf, sizeof(tmpbuf))) > 0) { | 200 | while ((ret = read(fileDescriptor, tmpbuf, sizeof(tmpbuf))) > 0) { |
| 210 | len = (size_t)ret; | 201 | size_t len = (size_t)ret; |
| 211 | op->buf = realloc(op->buf, op->buflen + len + 1); | 202 | cmd_output->buf = realloc(cmd_output->buf, cmd_output->buflen + len + 1); |
| 212 | memcpy(op->buf + op->buflen, tmpbuf, len); | 203 | memcpy(cmd_output->buf + cmd_output->buflen, tmpbuf, len); |
| 213 | op->buflen += len; | 204 | cmd_output->buflen += len; |
| 214 | i++; | ||
| 215 | } | 205 | } |
| 216 | 206 | ||
| 217 | if (ret < 0) { | 207 | if (ret < 0) { |
| 218 | printf("read() returned %d: %s\n", ret, strerror(errno)); | 208 | printf("read() returned %zd: %s\n", ret, strerror(errno)); |
| 219 | return ret; | 209 | return ret; |
| 220 | } | 210 | } |
| 221 | 211 | ||
| 222 | /* some plugins may want to keep output unbroken, and some commands | 212 | /* some plugins may want to keep output unbroken, and some commands |
| 223 | * will yield no output, so return here for those */ | 213 | * will yield no output, so return here for those */ |
| 224 | if (flags & CMD_NO_ARRAYS || !op->buf || !op->buflen) { | 214 | if (flags & CMD_NO_ARRAYS || !cmd_output->buf || !cmd_output->buflen) { |
| 225 | return op->buflen; | 215 | return cmd_output->buflen; |
| 226 | } | 216 | } |
| 227 | 217 | ||
| 228 | /* and some may want both */ | 218 | /* and some may want both */ |
| 219 | char *buf = NULL; | ||
| 229 | if (flags & CMD_NO_ASSOC) { | 220 | if (flags & CMD_NO_ASSOC) { |
| 230 | buf = malloc(op->buflen); | 221 | buf = malloc(cmd_output->buflen); |
| 231 | memcpy(buf, op->buf, op->buflen); | 222 | memcpy(buf, cmd_output->buf, cmd_output->buflen); |
| 232 | } else { | 223 | } else { |
| 233 | buf = op->buf; | 224 | buf = cmd_output->buf; |
| 234 | } | 225 | } |
| 235 | 226 | ||
| 236 | op->line = NULL; | 227 | cmd_output->line = NULL; |
| 237 | op->lens = NULL; | 228 | cmd_output->lens = NULL; |
| 238 | i = 0; | 229 | size_t i = 0; |
| 239 | while (i < op->buflen) { | 230 | size_t ary_size = 0; /* rsf = right shift factor, dec'ed uncond once */ |
| 231 | size_t rsf = 6; | ||
| 232 | size_t lineno = 0; | ||
| 233 | while (i < cmd_output->buflen) { | ||
| 240 | /* make sure we have enough memory */ | 234 | /* make sure we have enough memory */ |
| 241 | if (lineno >= ary_size) { | 235 | if (lineno >= ary_size) { |
| 242 | /* ary_size must never be zero */ | 236 | /* ary_size must never be zero */ |
| 243 | do { | 237 | do { |
| 244 | ary_size = op->buflen >> --rsf; | 238 | ary_size = cmd_output->buflen >> --rsf; |
| 245 | } while (!ary_size); | 239 | } while (!ary_size); |
| 246 | 240 | ||
| 247 | op->line = realloc(op->line, ary_size * sizeof(char *)); | 241 | cmd_output->line = realloc(cmd_output->line, ary_size * sizeof(char *)); |
| 248 | op->lens = realloc(op->lens, ary_size * sizeof(size_t)); | 242 | cmd_output->lens = realloc(cmd_output->lens, ary_size * sizeof(size_t)); |
| 249 | } | 243 | } |
| 250 | 244 | ||
| 251 | /* set the pointer to the string */ | 245 | /* set the pointer to the string */ |
| 252 | op->line[lineno] = &buf[i]; | 246 | cmd_output->line[lineno] = &buf[i]; |
| 253 | 247 | ||
| 254 | /* hop to next newline or end of buffer */ | 248 | /* hop to next newline or end of buffer */ |
| 255 | while (buf[i] != '\n' && i < op->buflen) { | 249 | while (buf[i] != '\n' && i < cmd_output->buflen) { |
| 256 | i++; | 250 | i++; |
| 257 | } | 251 | } |
| 258 | buf[i] = '\0'; | 252 | buf[i] = '\0'; |
| 259 | 253 | ||
| 260 | /* calculate the string length using pointer difference */ | 254 | /* calculate the string length using pointer difference */ |
| 261 | op->lens[lineno] = (size_t)&buf[i] - (size_t)op->line[lineno]; | 255 | cmd_output->lens[lineno] = (size_t)&buf[i] - (size_t)cmd_output->line[lineno]; |
| 262 | 256 | ||
| 263 | lineno++; | 257 | lineno++; |
| 264 | i++; | 258 | i++; |
| @@ -268,12 +262,6 @@ static int _cmd_fetch_output(int fd, output *op, int flags) { | |||
| 268 | } | 262 | } |
| 269 | 263 | ||
| 270 | int cmd_run(const char *cmdstring, output *out, output *err, int flags) { | 264 | int cmd_run(const char *cmdstring, output *out, output *err, int flags) { |
| 271 | int i = 0, argc; | ||
| 272 | size_t cmdlen; | ||
| 273 | char **argv = NULL; | ||
| 274 | char *cmd = NULL; | ||
| 275 | char *str = NULL; | ||
| 276 | |||
| 277 | if (cmdstring == NULL) { | 265 | if (cmdstring == NULL) { |
| 278 | return -1; | 266 | return -1; |
| 279 | } | 267 | } |
| @@ -288,7 +276,8 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) { | |||
| 288 | 276 | ||
| 289 | /* make copy of command string so strtok() doesn't silently modify it */ | 277 | /* make copy of command string so strtok() doesn't silently modify it */ |
| 290 | /* (the calling program may want to access it later) */ | 278 | /* (the calling program may want to access it later) */ |
| 291 | cmdlen = strlen(cmdstring); | 279 | size_t cmdlen = strlen(cmdstring); |
| 280 | char *cmd = NULL; | ||
| 292 | if ((cmd = malloc(cmdlen + 1)) == NULL) { | 281 | if ((cmd = malloc(cmdlen + 1)) == NULL) { |
| 293 | return -1; | 282 | return -1; |
| 294 | } | 283 | } |
| @@ -307,8 +296,8 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) { | |||
| 307 | 296 | ||
| 308 | /* each arg must be whitespace-separated, so args can be a maximum | 297 | /* each arg must be whitespace-separated, so args can be a maximum |
| 309 | * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */ | 298 | * of (len / 2) + 1. We add 1 extra to the mix for NULL termination */ |
| 310 | argc = (cmdlen >> 1) + 2; | 299 | int argc = (cmdlen >> 1) + 2; |
| 311 | argv = calloc((size_t)argc, sizeof(char *)); | 300 | char **argv = calloc((size_t)argc, sizeof(char *)); |
| 312 | 301 | ||
| 313 | if (argv == NULL) { | 302 | if (argv == NULL) { |
| 314 | printf("%s\n", _("Could not malloc argv array in popen()")); | 303 | printf("%s\n", _("Could not malloc argv array in popen()")); |
| @@ -316,8 +305,9 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) { | |||
| 316 | } | 305 | } |
| 317 | 306 | ||
| 318 | /* get command arguments (stupidly, but fairly quickly) */ | 307 | /* get command arguments (stupidly, but fairly quickly) */ |
| 308 | int i = 0; | ||
| 319 | while (cmd) { | 309 | while (cmd) { |
| 320 | str = cmd; | 310 | char *str = cmd; |
| 321 | str += strspn(str, " \t\r\n"); /* trim any leading whitespace */ | 311 | str += strspn(str, " \t\r\n"); /* trim any leading whitespace */ |
| 322 | 312 | ||
| 323 | if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ | 313 | if (strstr(str, "'") == str) { /* handle SIMPLE quoted strings */ |
| @@ -347,8 +337,6 @@ int cmd_run(const char *cmdstring, output *out, output *err, int flags) { | |||
| 347 | } | 337 | } |
| 348 | 338 | ||
| 349 | int cmd_run_array(char *const *argv, output *out, output *err, int flags) { | 339 | int cmd_run_array(char *const *argv, output *out, output *err, int flags) { |
| 350 | int fd, pfd_out[2], pfd_err[2]; | ||
| 351 | |||
| 352 | /* initialize the structs */ | 340 | /* initialize the structs */ |
| 353 | if (out) { | 341 | if (out) { |
| 354 | memset(out, 0, sizeof(output)); | 342 | memset(out, 0, sizeof(output)); |
| @@ -357,6 +345,9 @@ int cmd_run_array(char *const *argv, output *out, output *err, int flags) { | |||
| 357 | memset(err, 0, sizeof(output)); | 345 | memset(err, 0, sizeof(output)); |
| 358 | } | 346 | } |
| 359 | 347 | ||
| 348 | int fd; | ||
| 349 | int pfd_out[2]; | ||
| 350 | int pfd_err[2]; | ||
| 360 | if ((fd = _cmd_open(argv, pfd_out, pfd_err)) == -1) { | 351 | if ((fd = _cmd_open(argv, pfd_out, pfd_err)) == -1) { |
| 361 | die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), argv[0]); | 352 | die(STATE_UNKNOWN, _("Could not open pipe: %s\n"), argv[0]); |
| 362 | } | 353 | } |
diff --git a/lib/utils_cmd.h b/lib/utils_cmd.h index 728ece23..3672cdc9 100644 --- a/lib/utils_cmd.h +++ b/lib/utils_cmd.h | |||
| @@ -5,17 +5,17 @@ | |||
| 5 | * Header file for Monitoring Plugins utils_cmd.c | 5 | * Header file for Monitoring Plugins utils_cmd.c |
| 6 | * | 6 | * |
| 7 | */ | 7 | */ |
| 8 | #include "../config.h" | ||
| 9 | #include <stddef.h> | ||
| 8 | 10 | ||
| 9 | /** types **/ | 11 | /** types **/ |
| 10 | struct output { | 12 | typedef struct { |
| 11 | char *buf; /* output buffer */ | 13 | char *buf; /* output buffer */ |
| 12 | size_t buflen; /* output buffer content length */ | 14 | size_t buflen; /* output buffer content length */ |
| 13 | char **line; /* array of lines (points to buf) */ | 15 | char **line; /* array of lines (points to buf) */ |
| 14 | size_t *lens; /* string lengths */ | 16 | size_t *lens; /* string lengths */ |
| 15 | size_t lines; /* lines of output */ | 17 | size_t lines; /* lines of output */ |
| 16 | }; | 18 | } output; |
| 17 | |||
| 18 | typedef struct output output; | ||
| 19 | 19 | ||
| 20 | /** prototypes **/ | 20 | /** prototypes **/ |
| 21 | int cmd_run(const char *, output *, output *, int); | 21 | int cmd_run(const char *, output *, output *, int); |
diff --git a/lib/utils_tcp.c b/lib/utils_tcp.c index 1482458b..a82d5a3f 100644 --- a/lib/utils_tcp.c +++ b/lib/utils_tcp.c | |||
| @@ -26,8 +26,10 @@ | |||
| 26 | * | 26 | * |
| 27 | *****************************************************************************/ | 27 | *****************************************************************************/ |
| 28 | 28 | ||
| 29 | #include "common.h" | 29 | #include "../config.h" |
| 30 | #include "utils_tcp.h" | 30 | #include "utils_tcp.h" |
| 31 | #include <stdio.h> | ||
| 32 | #include <string.h> | ||
| 31 | 33 | ||
| 32 | #define VERBOSE(message) \ | 34 | #define VERBOSE(message) \ |
| 33 | do { \ | 35 | do { \ |
| @@ -37,9 +39,9 @@ | |||
| 37 | 39 | ||
| 38 | enum np_match_result np_expect_match(char *status, char **server_expect, int expect_count, | 40 | enum np_match_result np_expect_match(char *status, char **server_expect, int expect_count, |
| 39 | int flags) { | 41 | int flags) { |
| 40 | int i, match = 0, partial = 0; | 42 | int match = 0; |
| 41 | 43 | int partial = 0; | |
| 42 | for (i = 0; i < expect_count; i++) { | 44 | for (int i = 0; i < expect_count; i++) { |
| 43 | if (flags & NP_MATCH_VERBOSE) { | 45 | if (flags & NP_MATCH_VERBOSE) { |
| 44 | printf("looking for [%s] %s [%s]\n", server_expect[i], | 46 | printf("looking for [%s] %s [%s]\n", server_expect[i], |
| 45 | (flags & NP_MATCH_EXACT) ? "in beginning of" : "anywhere in", status); | 47 | (flags & NP_MATCH_EXACT) ? "in beginning of" : "anywhere in", status); |
| @@ -50,7 +52,9 @@ enum np_match_result np_expect_match(char *status, char **server_expect, int exp | |||
| 50 | VERBOSE("found it"); | 52 | VERBOSE("found it"); |
| 51 | match++; | 53 | match++; |
| 52 | continue; | 54 | continue; |
| 53 | } else if (strncmp(status, server_expect[i], strlen(status)) == 0) { | 55 | } |
| 56 | |||
| 57 | if (strncmp(status, server_expect[i], strlen(status)) == 0) { | ||
| 54 | VERBOSE("found a substring"); | 58 | VERBOSE("found a substring"); |
| 55 | partial++; | 59 | partial++; |
| 56 | continue; | 60 | continue; |
| @@ -66,9 +70,9 @@ enum np_match_result np_expect_match(char *status, char **server_expect, int exp | |||
| 66 | if ((flags & NP_MATCH_ALL && match == expect_count) || | 70 | if ((flags & NP_MATCH_ALL && match == expect_count) || |
| 67 | (!(flags & NP_MATCH_ALL) && match >= 1)) { | 71 | (!(flags & NP_MATCH_ALL) && match >= 1)) { |
| 68 | return NP_MATCH_SUCCESS; | 72 | return NP_MATCH_SUCCESS; |
| 69 | } else if (partial > 0 || !(flags & NP_MATCH_EXACT)) { | 73 | } |
| 74 | if (partial > 0 || !(flags & NP_MATCH_EXACT)) { | ||
| 70 | return NP_MATCH_RETRY; | 75 | return NP_MATCH_RETRY; |
| 71 | } else { | ||
| 72 | return NP_MATCH_FAILURE; | ||
| 73 | } | 76 | } |
| 77 | return NP_MATCH_FAILURE; | ||
| 74 | } | 78 | } |
