diff options
author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2025-09-15 16:09:40 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-15 16:09:40 +0200 |
commit | 601a48a63e745817cf2a4c7f3ca526e393dd3fb8 (patch) | |
tree | ed011d8f2bfcde8750bca64c0f69407df4bd6444 | |
parent | 8ef825d85fb4d09c32ca44c545d6eb8d995ddea4 (diff) | |
parent | 15ecdb73ce5cda54f824e5a63ee8e801bf16a996 (diff) | |
download | monitoring-plugins-601a48a6.tar.gz |
Merge pull request #2150 from RincewindsHat/refactor/lib
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 | ||||
-rw-r--r-- | plugins-root/check_icmp.d/check_icmp_helpers.c | 4 | ||||
-rw-r--r-- | plugins/check_apt.c | 8 | ||||
-rw-r--r-- | plugins/check_load.c | 4 | ||||
-rw-r--r-- | plugins/netutils.c | 224 | ||||
-rw-r--r-- | plugins/netutils.h | 32 |
18 files changed, 339 insertions, 309 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 | } |
diff --git a/plugins-root/check_icmp.d/check_icmp_helpers.c b/plugins-root/check_icmp.d/check_icmp_helpers.c index d56fbd8b..1b96a392 100644 --- a/plugins-root/check_icmp.d/check_icmp_helpers.c +++ b/plugins-root/check_icmp.d/check_icmp_helpers.c | |||
@@ -76,7 +76,7 @@ check_icmp_state check_icmp_state_init() { | |||
76 | 76 | ||
77 | ping_target_create_wrapper ping_target_create(struct sockaddr_storage address) { | 77 | ping_target_create_wrapper ping_target_create(struct sockaddr_storage address) { |
78 | ping_target_create_wrapper result = { | 78 | ping_target_create_wrapper result = { |
79 | .errorcode = OK, | 79 | .errorcode = 0, |
80 | }; | 80 | }; |
81 | 81 | ||
82 | struct sockaddr_storage *tmp_addr = &address; | 82 | struct sockaddr_storage *tmp_addr = &address; |
@@ -88,7 +88,7 @@ ping_target_create_wrapper ping_target_create(struct sockaddr_storage address) { | |||
88 | ((struct sockaddr_in *)tmp_addr)->sin_addr.s_addr == INADDR_ANY))) || | 88 | ((struct sockaddr_in *)tmp_addr)->sin_addr.s_addr == INADDR_ANY))) || |
89 | (tmp_addr->ss_family == AF_INET6 && | 89 | (tmp_addr->ss_family == AF_INET6 && |
90 | (((struct sockaddr_in6 *)tmp_addr)->sin6_addr.s6_addr == in6addr_any.s6_addr))) { | 90 | (((struct sockaddr_in6 *)tmp_addr)->sin6_addr.s6_addr == in6addr_any.s6_addr))) { |
91 | result.errorcode = ERROR; | 91 | result.errorcode = 1; |
92 | return result; | 92 | return result; |
93 | } | 93 | } |
94 | 94 | ||
diff --git a/plugins/check_apt.c b/plugins/check_apt.c index e840184b..ab66a8d2 100644 --- a/plugins/check_apt.c +++ b/plugins/check_apt.c | |||
@@ -310,8 +310,8 @@ run_upgrade_result run_upgrade(const upgrade_type upgrade, const char *do_includ | |||
310 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); | 310 | die(STATE_UNKNOWN, _("%s: Error compiling regexp: %s"), progname, rerrbuf); |
311 | } | 311 | } |
312 | 312 | ||
313 | struct output chld_out; | 313 | output chld_out; |
314 | struct output chld_err; | 314 | output chld_err; |
315 | char *cmdline = NULL; | 315 | char *cmdline = NULL; |
316 | cmdline = construct_cmdline(upgrade, upgrade_opts); | 316 | cmdline = construct_cmdline(upgrade, upgrade_opts); |
317 | if (input_filename != NULL) { | 317 | if (input_filename != NULL) { |
@@ -410,8 +410,8 @@ int run_update(char *update_opts) { | |||
410 | /* run the update */ | 410 | /* run the update */ |
411 | cmdline = construct_cmdline(NO_UPGRADE, update_opts); | 411 | cmdline = construct_cmdline(NO_UPGRADE, update_opts); |
412 | 412 | ||
413 | struct output chld_out; | 413 | output chld_out; |
414 | struct output chld_err; | 414 | output chld_err; |
415 | result = np_runcmd(cmdline, &chld_out, &chld_err, 0); | 415 | result = np_runcmd(cmdline, &chld_out, &chld_err, 0); |
416 | /* apt-get update changes exit status if it can't fetch packages. | 416 | /* apt-get update changes exit status if it can't fetch packages. |
417 | * since we were explicitly asked to do so, this is treated as | 417 | * since we were explicitly asked to do so, this is treated as |
diff --git a/plugins/check_load.c b/plugins/check_load.c index f7a6f7fd..644cd604 100644 --- a/plugins/check_load.c +++ b/plugins/check_load.c | |||
@@ -452,8 +452,8 @@ static top_processes_result print_top_consuming_processes(unsigned long n_procs_ | |||
452 | top_processes_result result = { | 452 | top_processes_result result = { |
453 | .errorcode = OK, | 453 | .errorcode = OK, |
454 | }; | 454 | }; |
455 | struct output chld_out; | 455 | output chld_out; |
456 | struct output chld_err; | 456 | output chld_err; |
457 | if (np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0) != 0) { | 457 | if (np_runcmd(PS_COMMAND, &chld_out, &chld_err, 0) != 0) { |
458 | fprintf(stderr, _("'%s' exited with non-zero status.\n"), PS_COMMAND); | 458 | fprintf(stderr, _("'%s' exited with non-zero status.\n"), PS_COMMAND); |
459 | result.errorcode = ERROR; | 459 | result.errorcode = ERROR; |
diff --git a/plugins/netutils.c b/plugins/netutils.c index 92c53e4c..b4c6ff0a 100644 --- a/plugins/netutils.c +++ b/plugins/netutils.c | |||
@@ -30,13 +30,14 @@ | |||
30 | #include "common.h" | 30 | #include "common.h" |
31 | #include "output.h" | 31 | #include "output.h" |
32 | #include "states.h" | 32 | #include "states.h" |
33 | #include <sys/types.h> | ||
33 | #include "netutils.h" | 34 | #include "netutils.h" |
34 | 35 | ||
35 | unsigned int socket_timeout = DEFAULT_SOCKET_TIMEOUT; | 36 | unsigned int socket_timeout = DEFAULT_SOCKET_TIMEOUT; |
36 | unsigned int socket_timeout_state = STATE_CRITICAL; | 37 | mp_state_enum socket_timeout_state = STATE_CRITICAL; |
37 | 38 | mp_state_enum econn_refuse_state = STATE_CRITICAL; | |
38 | int econn_refuse_state = STATE_CRITICAL; | ||
39 | bool was_refused = false; | 39 | bool was_refused = false; |
40 | |||
40 | #if USE_IPV6 | 41 | #if USE_IPV6 |
41 | int address_family = AF_UNSPEC; | 42 | int address_family = AF_UNSPEC; |
42 | #else | 43 | #else |
@@ -63,39 +64,40 @@ void socket_timeout_alarm_handler(int sig) { | |||
63 | /* connects to a host on a specified tcp port, sends a string, and gets a | 64 | /* connects to a host on a specified tcp port, sends a string, and gets a |
64 | response. loops on select-recv until timeout or eof to get all of a | 65 | response. loops on select-recv until timeout or eof to get all of a |
65 | multi-packet answer */ | 66 | multi-packet answer */ |
66 | int process_tcp_request2(const char *server_address, int server_port, const char *send_buffer, | 67 | mp_state_enum process_tcp_request2(const char *server_address, const int server_port, |
67 | char *recv_buffer, int recv_size) { | 68 | const char *send_buffer, char *recv_buffer, |
69 | const int recv_size) { | ||
68 | 70 | ||
69 | int result; | 71 | int socket; |
70 | int send_result; | ||
71 | int recv_result; | ||
72 | int sd; | ||
73 | struct timeval tv; | ||
74 | fd_set readfds; | ||
75 | int recv_length = 0; | ||
76 | 72 | ||
77 | result = np_net_connect(server_address, server_port, &sd, IPPROTO_TCP); | 73 | mp_state_enum connect_result = |
78 | if (result != STATE_OK) { | 74 | np_net_connect(server_address, server_port, &socket, IPPROTO_TCP); |
75 | if (connect_result != STATE_OK) { | ||
79 | return STATE_CRITICAL; | 76 | return STATE_CRITICAL; |
80 | } | 77 | } |
81 | 78 | ||
82 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); | 79 | mp_state_enum result; |
80 | ssize_t send_result = send(socket, send_buffer, strlen(send_buffer), 0); | ||
83 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { | 81 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { |
84 | // printf("%s\n", _("Send failed")); | 82 | // printf("%s\n", _("Send failed")); |
85 | result = STATE_WARNING; | 83 | result = STATE_WARNING; |
86 | } | 84 | } |
87 | 85 | ||
88 | while (1) { | 86 | fd_set readfds; |
87 | ssize_t recv_length = 0; | ||
88 | while (true) { | ||
89 | /* wait up to the number of seconds for socket timeout | 89 | /* wait up to the number of seconds for socket timeout |
90 | minus one for data from the host */ | 90 | minus one for data from the host */ |
91 | tv.tv_sec = socket_timeout - 1; | 91 | struct timeval timeout = { |
92 | tv.tv_usec = 0; | 92 | .tv_sec = socket_timeout - 1, |
93 | .tv_usec = 0, | ||
94 | }; | ||
93 | FD_ZERO(&readfds); | 95 | FD_ZERO(&readfds); |
94 | FD_SET(sd, &readfds); | 96 | FD_SET(socket, &readfds); |
95 | select(sd + 1, &readfds, NULL, NULL, &tv); | 97 | select(socket + 1, &readfds, NULL, NULL, &timeout); |
96 | 98 | ||
97 | /* make sure some data has arrived */ | 99 | /* make sure some data has arrived */ |
98 | if (!FD_ISSET(sd, &readfds)) { /* it hasn't */ | 100 | if (!FD_ISSET(socket, &readfds)) { /* it hasn't */ |
99 | if (!recv_length) { | 101 | if (!recv_length) { |
100 | strcpy(recv_buffer, ""); | 102 | strcpy(recv_buffer, ""); |
101 | // printf("%s\n", _("No data was received from host!")); | 103 | // printf("%s\n", _("No data was received from host!")); |
@@ -104,72 +106,69 @@ int process_tcp_request2(const char *server_address, int server_port, const char | |||
104 | recv_buffer[recv_length] = 0; | 106 | recv_buffer[recv_length] = 0; |
105 | } | 107 | } |
106 | break; | 108 | break; |
107 | } else { /* it has */ | 109 | } /* it has */ |
108 | recv_result = | 110 | |
109 | recv(sd, recv_buffer + recv_length, (size_t)recv_size - recv_length - 1, 0); | 111 | ssize_t recv_result = |
110 | if (recv_result == -1) { | 112 | recv(socket, recv_buffer + recv_length, (size_t)(recv_size - recv_length - 1), 0); |
111 | /* recv failed, bail out */ | 113 | if (recv_result == -1) { |
112 | strcpy(recv_buffer + recv_length, ""); | 114 | /* recv failed, bail out */ |
113 | result = STATE_WARNING; | 115 | strcpy(recv_buffer + recv_length, ""); |
114 | break; | 116 | result = STATE_WARNING; |
115 | } else if (recv_result == 0) { | 117 | break; |
116 | /* end of file ? */ | 118 | } |
117 | recv_buffer[recv_length] = 0; | 119 | |
118 | break; | 120 | if (recv_result == 0) { |
119 | } else { /* we got data! */ | 121 | /* end of file ? */ |
120 | recv_length += recv_result; | 122 | recv_buffer[recv_length] = 0; |
121 | if (recv_length >= recv_size - 1) { | 123 | break; |
122 | /* buffer full, we're done */ | 124 | } |
123 | recv_buffer[recv_size - 1] = 0; | 125 | |
124 | break; | 126 | /* we got data! */ |
125 | } | 127 | recv_length += recv_result; |
126 | } | 128 | if (recv_length >= recv_size - 1) { |
129 | /* buffer full, we're done */ | ||
130 | recv_buffer[recv_size - 1] = 0; | ||
131 | break; | ||
127 | } | 132 | } |
128 | /* end if(!FD_ISSET(sd,&readfds)) */ | 133 | /* end if(!FD_ISSET(sd,&readfds)) */ |
129 | } | 134 | } |
130 | /* end while(1) */ | ||
131 | 135 | ||
132 | close(sd); | 136 | close(socket); |
133 | return result; | 137 | return result; |
134 | } | 138 | } |
135 | 139 | ||
136 | /* connects to a host on a specified port, sends a string, and gets a | 140 | /* connects to a host on a specified port, sends a string, and gets a |
137 | response */ | 141 | response */ |
138 | int process_request(const char *server_address, int server_port, int proto, const char *send_buffer, | 142 | mp_state_enum process_request(const char *server_address, const int server_port, const int proto, |
139 | char *recv_buffer, int recv_size) { | 143 | const char *send_buffer, char *recv_buffer, const int recv_size) { |
140 | int result; | ||
141 | int sd; | ||
142 | 144 | ||
143 | result = STATE_OK; | 145 | mp_state_enum result = STATE_OK; |
144 | 146 | int socket; | |
145 | result = np_net_connect(server_address, server_port, &sd, proto); | 147 | result = np_net_connect(server_address, server_port, &socket, proto); |
146 | if (result != STATE_OK) { | 148 | if (result != STATE_OK) { |
147 | return STATE_CRITICAL; | 149 | return STATE_CRITICAL; |
148 | } | 150 | } |
149 | 151 | ||
150 | result = send_request(sd, proto, send_buffer, recv_buffer, recv_size); | 152 | result = send_request(socket, proto, send_buffer, recv_buffer, recv_size); |
151 | 153 | ||
152 | close(sd); | 154 | close(socket); |
153 | 155 | ||
154 | return result; | 156 | return result; |
155 | } | 157 | } |
156 | 158 | ||
157 | /* opens a tcp or udp connection to a remote host or local socket */ | 159 | /* opens a tcp or udp connection to a remote host or local socket */ |
158 | int np_net_connect(const char *host_name, int port, int *sd, int proto) { | 160 | mp_state_enum np_net_connect(const char *host_name, int port, int *socketDescriptor, |
161 | const int proto) { | ||
159 | /* send back STATE_UNKOWN if there's an error | 162 | /* send back STATE_UNKOWN if there's an error |
160 | send back STATE_OK if we connect | 163 | send back STATE_OK if we connect |
161 | send back STATE_CRITICAL if we can't connect. | 164 | send back STATE_CRITICAL if we can't connect. |
162 | Let upstream figure out what to send to the user. */ | 165 | Let upstream figure out what to send to the user. */ |
163 | struct addrinfo hints; | 166 | bool is_socket = (host_name[0] == '/'); |
164 | struct addrinfo *r, *res; | 167 | int socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; |
165 | struct sockaddr_un su; | ||
166 | char port_str[6], host[MAX_HOST_ADDRESS_LENGTH]; | ||
167 | size_t len; | ||
168 | int socktype, result; | ||
169 | short is_socket = (host_name[0] == '/'); | ||
170 | |||
171 | socktype = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM; | ||
172 | 168 | ||
169 | struct addrinfo hints = {}; | ||
170 | struct addrinfo *res = NULL; | ||
171 | int result; | ||
173 | /* as long as it doesn't start with a '/', it's assumed a host or ip */ | 172 | /* as long as it doesn't start with a '/', it's assumed a host or ip */ |
174 | if (!is_socket) { | 173 | if (!is_socket) { |
175 | memset(&hints, 0, sizeof(hints)); | 174 | memset(&hints, 0, sizeof(hints)); |
@@ -177,38 +176,46 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
177 | hints.ai_protocol = proto; | 176 | hints.ai_protocol = proto; |
178 | hints.ai_socktype = socktype; | 177 | hints.ai_socktype = socktype; |
179 | 178 | ||
180 | len = strlen(host_name); | 179 | size_t len = strlen(host_name); |
181 | /* check for an [IPv6] address (and strip the brackets) */ | 180 | /* check for an [IPv6] address (and strip the brackets) */ |
182 | if (len >= 2 && host_name[0] == '[' && host_name[len - 1] == ']') { | 181 | if (len >= 2 && host_name[0] == '[' && host_name[len - 1] == ']') { |
183 | host_name++; | 182 | host_name++; |
184 | len -= 2; | 183 | len -= 2; |
185 | } | 184 | } |
185 | |||
186 | char host[MAX_HOST_ADDRESS_LENGTH]; | ||
187 | |||
186 | if (len >= sizeof(host)) { | 188 | if (len >= sizeof(host)) { |
187 | return STATE_UNKNOWN; | 189 | return STATE_UNKNOWN; |
188 | } | 190 | } |
191 | |||
189 | memcpy(host, host_name, len); | 192 | memcpy(host, host_name, len); |
190 | host[len] = '\0'; | 193 | host[len] = '\0'; |
194 | |||
195 | char port_str[6]; | ||
191 | snprintf(port_str, sizeof(port_str), "%d", port); | 196 | snprintf(port_str, sizeof(port_str), "%d", port); |
192 | result = getaddrinfo(host, port_str, &hints, &res); | 197 | int getaddrinfo_err = getaddrinfo(host, port_str, &hints, &res); |
193 | 198 | ||
194 | if (result != 0) { | 199 | if (getaddrinfo_err != 0) { |
195 | // printf("%s\n", gai_strerror(result)); | 200 | // printf("%s\n", gai_strerror(result)); |
196 | return STATE_UNKNOWN; | 201 | return STATE_UNKNOWN; |
197 | } | 202 | } |
198 | 203 | ||
199 | r = res; | 204 | struct addrinfo *addressPointer = res; |
200 | while (r) { | 205 | while (addressPointer) { |
201 | /* attempt to create a socket */ | 206 | /* attempt to create a socket */ |
202 | *sd = socket(r->ai_family, socktype, r->ai_protocol); | 207 | *socketDescriptor = |
208 | socket(addressPointer->ai_family, socktype, addressPointer->ai_protocol); | ||
203 | 209 | ||
204 | if (*sd < 0) { | 210 | if (*socketDescriptor < 0) { |
205 | // printf("%s\n", _("Socket creation failed")); | 211 | // printf("%s\n", _("Socket creation failed")); |
206 | freeaddrinfo(r); | 212 | freeaddrinfo(addressPointer); |
207 | return STATE_UNKNOWN; | 213 | return STATE_UNKNOWN; |
208 | } | 214 | } |
209 | 215 | ||
210 | /* attempt to open a connection */ | 216 | /* attempt to open a connection */ |
211 | result = connect(*sd, r->ai_addr, r->ai_addrlen); | 217 | result = |
218 | connect(*socketDescriptor, addressPointer->ai_addr, addressPointer->ai_addrlen); | ||
212 | 219 | ||
213 | if (result == 0) { | 220 | if (result == 0) { |
214 | was_refused = false; | 221 | was_refused = false; |
@@ -223,24 +230,28 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
223 | } | 230 | } |
224 | } | 231 | } |
225 | 232 | ||
226 | close(*sd); | 233 | close(*socketDescriptor); |
227 | r = r->ai_next; | 234 | addressPointer = addressPointer->ai_next; |
228 | } | 235 | } |
236 | |||
229 | freeaddrinfo(res); | 237 | freeaddrinfo(res); |
230 | } | 238 | |
231 | /* else the hostname is interpreted as a path to a unix socket */ | 239 | } else { |
232 | else { | 240 | /* else the hostname is interpreted as a path to a unix socket */ |
233 | if (strlen(host_name) >= UNIX_PATH_MAX) { | 241 | if (strlen(host_name) >= UNIX_PATH_MAX) { |
234 | die(STATE_UNKNOWN, _("Supplied path too long unix domain socket")); | 242 | die(STATE_UNKNOWN, _("Supplied path too long unix domain socket")); |
235 | } | 243 | } |
236 | memset(&su, 0, sizeof(su)); | 244 | |
245 | struct sockaddr_un su = {}; | ||
237 | su.sun_family = AF_UNIX; | 246 | su.sun_family = AF_UNIX; |
238 | strncpy(su.sun_path, host_name, UNIX_PATH_MAX); | 247 | strncpy(su.sun_path, host_name, UNIX_PATH_MAX); |
239 | *sd = socket(PF_UNIX, SOCK_STREAM, 0); | 248 | *socketDescriptor = socket(PF_UNIX, SOCK_STREAM, 0); |
240 | if (*sd < 0) { | 249 | |
250 | if (*socketDescriptor < 0) { | ||
241 | die(STATE_UNKNOWN, _("Socket creation failed")); | 251 | die(STATE_UNKNOWN, _("Socket creation failed")); |
242 | } | 252 | } |
243 | result = connect(*sd, (struct sockaddr *)&su, sizeof(su)); | 253 | |
254 | result = connect(*socketDescriptor, (struct sockaddr *)&su, sizeof(su)); | ||
244 | if (result < 0 && errno == ECONNREFUSED) { | 255 | if (result < 0 && errno == ECONNREFUSED) { |
245 | was_refused = true; | 256 | was_refused = true; |
246 | } | 257 | } |
@@ -248,7 +259,9 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
248 | 259 | ||
249 | if (result == 0) { | 260 | if (result == 0) { |
250 | return STATE_OK; | 261 | return STATE_OK; |
251 | } else if (was_refused) { | 262 | } |
263 | |||
264 | if (was_refused) { | ||
252 | switch (econn_refuse_state) { /* a user-defined expected outcome */ | 265 | switch (econn_refuse_state) { /* a user-defined expected outcome */ |
253 | case STATE_OK: | 266 | case STATE_OK: |
254 | case STATE_WARNING: /* user wants WARN or OK on refusal, or... */ | 267 | case STATE_WARNING: /* user wants WARN or OK on refusal, or... */ |
@@ -275,14 +288,11 @@ int np_net_connect(const char *host_name, int port, int *sd, int proto) { | |||
275 | } | 288 | } |
276 | } | 289 | } |
277 | 290 | ||
278 | int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, int recv_size) { | 291 | mp_state_enum send_request(const int socket, const int proto, const char *send_buffer, |
279 | int result = STATE_OK; | 292 | char *recv_buffer, const int recv_size) { |
280 | int send_result; | 293 | mp_state_enum result = STATE_OK; |
281 | int recv_result; | ||
282 | struct timeval tv; | ||
283 | fd_set readfds; | ||
284 | 294 | ||
285 | send_result = send(sd, send_buffer, strlen(send_buffer), 0); | 295 | ssize_t send_result = send(socket, send_buffer, strlen(send_buffer), 0); |
286 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { | 296 | if (send_result < 0 || (size_t)send_result != strlen(send_buffer)) { |
287 | // printf("%s\n", _("Send failed")); | 297 | // printf("%s\n", _("Send failed")); |
288 | result = STATE_WARNING; | 298 | result = STATE_WARNING; |
@@ -290,21 +300,22 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, | |||
290 | 300 | ||
291 | /* wait up to the number of seconds for socket timeout minus one | 301 | /* wait up to the number of seconds for socket timeout minus one |
292 | for data from the host */ | 302 | for data from the host */ |
293 | tv.tv_sec = socket_timeout - 1; | 303 | struct timeval timestamp = { |
294 | tv.tv_usec = 0; | 304 | .tv_sec = socket_timeout - 1, |
305 | .tv_usec = 0, | ||
306 | }; | ||
307 | fd_set readfds; | ||
295 | FD_ZERO(&readfds); | 308 | FD_ZERO(&readfds); |
296 | FD_SET(sd, &readfds); | 309 | FD_SET(socket, &readfds); |
297 | select(sd + 1, &readfds, NULL, NULL, &tv); | 310 | select(socket + 1, &readfds, NULL, NULL, ×tamp); |
298 | 311 | ||
299 | /* make sure some data has arrived */ | 312 | /* make sure some data has arrived */ |
300 | if (!FD_ISSET(sd, &readfds)) { | 313 | if (!FD_ISSET(socket, &readfds)) { |
301 | strcpy(recv_buffer, ""); | 314 | strcpy(recv_buffer, ""); |
302 | // printf("%s\n", _("No data was received from host!")); | 315 | // printf("%s\n", _("No data was received from host!")); |
303 | result = STATE_WARNING; | 316 | result = STATE_WARNING; |
304 | } | 317 | } else { |
305 | 318 | ssize_t recv_result = recv(socket, recv_buffer, (size_t)(recv_size - 1), 0); | |
306 | else { | ||
307 | recv_result = recv(sd, recv_buffer, (size_t)recv_size - 1, 0); | ||
308 | if (recv_result == -1) { | 319 | if (recv_result == -1) { |
309 | strcpy(recv_buffer, ""); | 320 | strcpy(recv_buffer, ""); |
310 | if (proto != IPPROTO_TCP) { | 321 | if (proto != IPPROTO_TCP) { |
@@ -318,6 +329,7 @@ int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, | |||
318 | /* die returned string */ | 329 | /* die returned string */ |
319 | recv_buffer[recv_size - 1] = 0; | 330 | recv_buffer[recv_size - 1] = 0; |
320 | } | 331 | } |
332 | |||
321 | return result; | 333 | return result; |
322 | } | 334 | } |
323 | 335 | ||
@@ -339,27 +351,27 @@ bool is_addr(const char *address) { | |||
339 | #ifdef USE_IPV6 | 351 | #ifdef USE_IPV6 |
340 | if (address_family == AF_INET && is_inet_addr(address)) { | 352 | if (address_family == AF_INET && is_inet_addr(address)) { |
341 | return true; | 353 | return true; |
342 | } else if (address_family == AF_INET6 && is_inet6_addr(address)) { | 354 | } |
355 | |||
356 | if (address_family == AF_INET6 && is_inet6_addr(address)) { | ||
343 | return true; | 357 | return true; |
344 | } | 358 | } |
345 | #else | 359 | #else |
346 | if (is_inet_addr(address)) { | 360 | if (is_inet_addr(address)) { |
347 | return (true); | 361 | return true; |
348 | } | 362 | } |
349 | #endif | 363 | #endif |
350 | 364 | ||
351 | return (false); | 365 | return false; |
352 | } | 366 | } |
353 | 367 | ||
354 | int dns_lookup(const char *in, struct sockaddr_storage *ss, int family) { | 368 | bool dns_lookup(const char *node_string, struct sockaddr_storage *ss, const int family) { |
355 | struct addrinfo hints; | 369 | struct addrinfo hints; |
356 | struct addrinfo *res; | ||
357 | int retval; | ||
358 | |||
359 | memset(&hints, 0, sizeof(struct addrinfo)); | 370 | memset(&hints, 0, sizeof(struct addrinfo)); |
360 | hints.ai_family = family; | 371 | hints.ai_family = family; |
361 | 372 | ||
362 | retval = getaddrinfo(in, NULL, &hints, &res); | 373 | struct addrinfo *res; |
374 | int retval = getaddrinfo(node_string, NULL, &hints, &res); | ||
363 | if (retval != 0) { | 375 | if (retval != 0) { |
364 | return false; | 376 | return false; |
365 | } | 377 | } |
@@ -367,6 +379,8 @@ int dns_lookup(const char *in, struct sockaddr_storage *ss, int family) { | |||
367 | if (ss != NULL) { | 379 | if (ss != NULL) { |
368 | memcpy(ss, res->ai_addr, res->ai_addrlen); | 380 | memcpy(ss, res->ai_addr, res->ai_addrlen); |
369 | } | 381 | } |
382 | |||
370 | freeaddrinfo(res); | 383 | freeaddrinfo(res); |
384 | |||
371 | return true; | 385 | return true; |
372 | } | 386 | } |
diff --git a/plugins/netutils.h b/plugins/netutils.h index 6adb8e01..c4461113 100644 --- a/plugins/netutils.h +++ b/plugins/netutils.h | |||
@@ -31,7 +31,6 @@ | |||
31 | #ifndef _NETUTILS_H_ | 31 | #ifndef _NETUTILS_H_ |
32 | #define _NETUTILS_H_ | 32 | #define _NETUTILS_H_ |
33 | 33 | ||
34 | #include "common.h" | ||
35 | #include "output.h" | 34 | #include "output.h" |
36 | #include "states.h" | 35 | #include "states.h" |
37 | #include "utils.h" | 36 | #include "utils.h" |
@@ -56,25 +55,26 @@ | |||
56 | process_request(addr, port, IPPROTO_TCP, sbuf, rbuf, rsize) | 55 | process_request(addr, port, IPPROTO_TCP, sbuf, rbuf, rsize) |
57 | #define process_udp_request(addr, port, sbuf, rbuf, rsize) \ | 56 | #define process_udp_request(addr, port, sbuf, rbuf, rsize) \ |
58 | process_request(addr, port, IPPROTO_UDP, sbuf, rbuf, rsize) | 57 | process_request(addr, port, IPPROTO_UDP, sbuf, rbuf, rsize) |
59 | int process_tcp_request2(const char *address, int port, const char *sbuffer, char *rbuffer, | 58 | mp_state_enum process_tcp_request2(const char *server_address, int server_port, |
60 | int rsize); | 59 | const char *send_buffer, char *recv_buffer, int recv_size); |
61 | int process_request(const char *address, int port, int proto, const char *sbuffer, char *rbuffer, | 60 | mp_state_enum process_request(const char *server_address, int server_port, int proto, |
62 | int rsize); | 61 | const char *send_buffer, char *recv_buffer, int recv_size); |
63 | 62 | ||
64 | /* my_connect and wrapper macros */ | 63 | /* my_connect and wrapper macros */ |
65 | #define my_tcp_connect(addr, port, s) np_net_connect(addr, port, s, IPPROTO_TCP) | 64 | #define my_tcp_connect(addr, port, s) np_net_connect(addr, port, s, IPPROTO_TCP) |
66 | #define my_udp_connect(addr, port, s) np_net_connect(addr, port, s, IPPROTO_UDP) | 65 | #define my_udp_connect(addr, port, s) np_net_connect(addr, port, s, IPPROTO_UDP) |
67 | int np_net_connect(const char *address, int port, int *sd, int proto); | 66 | mp_state_enum np_net_connect(const char *host_name, int port, int *socketDescriptor, int proto); |
68 | 67 | ||
69 | /* send_request and wrapper macros */ | 68 | /* send_request and wrapper macros */ |
70 | #define send_tcp_request(s, sbuf, rbuf, rsize) send_request(s, IPPROTO_TCP, sbuf, rbuf, rsize) | 69 | #define send_tcp_request(s, sbuf, rbuf, rsize) send_request(s, IPPROTO_TCP, sbuf, rbuf, rsize) |
71 | #define send_udp_request(s, sbuf, rbuf, rsize) send_request(s, IPPROTO_UDP, sbuf, rbuf, rsize) | 70 | #define send_udp_request(s, sbuf, rbuf, rsize) send_request(s, IPPROTO_UDP, sbuf, rbuf, rsize) |
72 | int send_request(int sd, int proto, const char *send_buffer, char *recv_buffer, int recv_size); | 71 | mp_state_enum send_request(int socket, int proto, const char *send_buffer, char *recv_buffer, |
72 | int recv_size); | ||
73 | 73 | ||
74 | /* "is_*" wrapper macros and functions */ | 74 | /* "is_*" wrapper macros and functions */ |
75 | bool is_host(const char *); | 75 | bool is_host(const char *); |
76 | bool is_addr(const char *); | 76 | bool is_addr(const char *); |
77 | int dns_lookup(const char *, struct sockaddr_storage *, int); | 77 | bool dns_lookup(const char *, struct sockaddr_storage *, int); |
78 | void host_or_die(const char *str); | 78 | void host_or_die(const char *str); |
79 | #define resolve_host_or_addr(addr, family) dns_lookup(addr, NULL, family) | 79 | #define resolve_host_or_addr(addr, family) dns_lookup(addr, NULL, family) |
80 | #define is_inet_addr(addr) resolve_host_or_addr(addr, AF_INET) | 80 | #define is_inet_addr(addr) resolve_host_or_addr(addr, AF_INET) |
@@ -86,8 +86,8 @@ void host_or_die(const char *str); | |||
86 | #endif | 86 | #endif |
87 | 87 | ||
88 | extern unsigned int socket_timeout; | 88 | extern unsigned int socket_timeout; |
89 | extern unsigned int socket_timeout_state; | 89 | extern mp_state_enum socket_timeout_state; |
90 | extern int econn_refuse_state; | 90 | extern mp_state_enum econn_refuse_state; |
91 | extern bool was_refused; | 91 | extern bool was_refused; |
92 | extern int address_family; | 92 | extern int address_family; |
93 | 93 | ||
@@ -106,12 +106,12 @@ void socket_timeout_alarm_handler(int) __attribute__((noreturn)); | |||
106 | # define MP_TLSv1_1_OR_NEWER 9 | 106 | # define MP_TLSv1_1_OR_NEWER 9 |
107 | # define MP_TLSv1_2_OR_NEWER 10 | 107 | # define MP_TLSv1_2_OR_NEWER 10 |
108 | /* maybe this could be merged with the above np_net_connect, via some flags */ | 108 | /* maybe this could be merged with the above np_net_connect, via some flags */ |
109 | int np_net_ssl_init(int sd); | 109 | int np_net_ssl_init(int socket); |
110 | int np_net_ssl_init_with_hostname(int sd, char *host_name); | 110 | int np_net_ssl_init_with_hostname(int socket, char *host_name); |
111 | int np_net_ssl_init_with_hostname_and_version(int sd, char *host_name, int version); | 111 | int np_net_ssl_init_with_hostname_and_version(int socket, char *host_name, int version); |
112 | int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, | 112 | int np_net_ssl_init_with_hostname_version_and_cert(int socket, char *host_name, int version, |
113 | char *privkey); | 113 | char *cert, char *privkey); |
114 | void np_net_ssl_cleanup(); | 114 | void np_net_ssl_cleanup(void); |
115 | int np_net_ssl_write(const void *buf, int num); | 115 | int np_net_ssl_write(const void *buf, int num); |
116 | int np_net_ssl_read(void *buf, int num); | 116 | int np_net_ssl_read(void *buf, int num); |
117 | mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit); | 117 | mp_state_enum np_net_ssl_check_cert(int days_till_exp_warn, int days_till_exp_crit); |