summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Guyot-Sionnest <dermoth@users.sourceforge.net>2008-03-15 04:51:45 (GMT)
committerThomas Guyot-Sionnest <dermoth@users.sourceforge.net>2008-03-15 04:51:45 (GMT)
commit6004d95868fcd9badbc0f026980a4a3597eb22db (patch)
treebe1a47aeb9e08632f74bc7bd155504b0221367e2
parent118e57b78972c4fbbcd4f45d84af546d7346141d (diff)
downloadmonitoring-plugins-6004d95868fcd9badbc0f026980a4a3597eb22db.tar.gz
This commit consist of two changes:
1. Make np_get_defaults return a linked list instead of a string. It will then be easy to convert the linked list back to an argument array. 2. Fix tests 3-4 of test_ini.c. A test_ini.t was added too. parse_ini and test_ini aren't included yet in the build makefiles. git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@1945 f882894a-f735-0410-b71e-b25c423dba1c
-rw-r--r--lib/parse_ini.c76
-rw-r--r--lib/parse_ini.h9
-rw-r--r--lib/tests/test_ini.c25
-rwxr-xr-xlib/tests/test_ini.t6
4 files changed, 74 insertions, 42 deletions
diff --git a/lib/parse_ini.c b/lib/parse_ini.c
index ef56be9..c915d79 100644
--- a/lib/parse_ini.c
+++ b/lib/parse_ini.c
@@ -42,9 +42,9 @@ typedef struct {
42#define GOBBLE_TO(f, c, n) do { (c)=fgetc((f)); } while((c)!=EOF && (c)!=(n)) 42#define GOBBLE_TO(f, c, n) do { (c)=fgetc((f)); } while((c)!=EOF && (c)!=(n))
43 43
44/* internal function that returns the constructed defaults options */ 44/* internal function that returns the constructed defaults options */
45static char* read_defaults(FILE *f, const char *stanza); 45static np_arg_list* read_defaults(FILE *f, const char *stanza);
46/* internal function that converts a single line into options format */ 46/* internal function that converts a single line into options format */
47static int add_option(FILE *f, char **optbuf, size_t *bufsize); 47static int add_option(FILE *f, np_arg_list **optlst);
48 48
49/* parse_locator decomposes a string of the form 49/* parse_locator decomposes a string of the form
50 * [stanza][@filename] 50 * [stanza][@filename]
@@ -76,9 +76,9 @@ static void parse_locator(const char *locator, const char *def_stanza, np_ini_in
76} 76}
77 77
78/* this is the externally visible function used by plugins */ 78/* this is the externally visible function used by plugins */
79char* np_get_defaults(const char *locator, const char *default_section){ 79np_arg_list* np_get_defaults(const char *locator, const char *default_section){
80 FILE *inifile=NULL; 80 FILE *inifile=NULL;
81 char *defaults=NULL; 81 np_arg_list *defaults=NULL;
82 np_ini_info i; 82 np_ini_info i;
83 83
84 parse_locator(locator, default_section, &i); 84 parse_locator(locator, default_section, &i);
@@ -104,10 +104,10 @@ char* np_get_defaults(const char *locator, const char *default_section){
104 * be extra careful about user-supplied input (i.e. avoiding possible 104 * be extra careful about user-supplied input (i.e. avoiding possible
105 * format string vulnerabilities, etc) 105 * format string vulnerabilities, etc)
106 */ 106 */
107static char* read_defaults(FILE *f, const char *stanza){ 107static np_arg_list* read_defaults(FILE *f, const char *stanza){
108 int c; 108 int c;
109 char *opts=NULL; 109 np_arg_list *opts=NULL;
110 size_t i, stanza_len, opts_buf_size=0; 110 size_t i, stanza_len;
111 enum { NOSTANZA, WRONGSTANZA, RIGHTSTANZA } stanzastate=NOSTANZA; 111 enum { NOSTANZA, WRONGSTANZA, RIGHTSTANZA } stanzastate=NOSTANZA;
112 112
113 stanza_len=strlen(stanza); 113 stanza_len=strlen(stanza);
@@ -154,7 +154,7 @@ static char* read_defaults(FILE *f, const char *stanza){
154 /* okay, this is where we start taking the config */ 154 /* okay, this is where we start taking the config */
155 case RIGHTSTANZA: 155 case RIGHTSTANZA:
156 ungetc(c, f); 156 ungetc(c, f);
157 if(add_option(f, &opts, &opts_buf_size)){ 157 if(add_option(f, &opts)){
158 die(STATE_UNKNOWN, _("Config file error")); 158 die(STATE_UNKNOWN, _("Config file error"));
159 } 159 }
160 break; 160 break;
@@ -170,15 +170,14 @@ static char* read_defaults(FILE *f, const char *stanza){
170 * ^option[[:space:]]*(=[[:space:]]*value)? 170 * ^option[[:space:]]*(=[[:space:]]*value)?
171 * and creates it as a cmdline argument 171 * and creates it as a cmdline argument
172 * --option[=value] 172 * --option[=value]
173 * appending it to the string pointed to by optbuf (which will 173 * appending it to the linked list optbuf.
174 * be dynamically grown if needed)
175 */ 174 */
176static int add_option(FILE *f, char **optbuf, size_t *bufsize){ 175static int add_option(FILE *f, np_arg_list **optlst){
177 char *newbuf=*optbuf; 176 np_arg_list *opttmp=*optlst, *optnew;
178 char *linebuf=NULL, *lineend=NULL, *optptr=NULL, *optend=NULL; 177 char *linebuf=NULL, *lineend=NULL, *optptr=NULL, *optend=NULL;
179 char *eqptr=NULL, *valptr=NULL, *spaceptr=NULL, *valend=NULL; 178 char *eqptr=NULL, *valptr=NULL, *spaceptr=NULL, *valend=NULL;
180 short done_reading=0, equals=0, value=0; 179 short done_reading=0, equals=0, value=0;
181 size_t cfg_len=0, read_sz=8, linebuf_sz=0, read_pos=0, bs=*bufsize; 180 size_t cfg_len=0, read_sz=8, linebuf_sz=0, read_pos=0;
182 size_t opt_len=0, val_len=0; 181 size_t opt_len=0, val_len=0;
183 182
184 /* read one line from the file */ 183 /* read one line from the file */
@@ -214,14 +213,13 @@ static int add_option(FILE *f, char **optbuf, size_t *bufsize){
214 if(optptr==eqptr) die(STATE_UNKNOWN, _("Config file error\n")); 213 if(optptr==eqptr) die(STATE_UNKNOWN, _("Config file error\n"));
215 /* continue from '=' to start of value or EOL */ 214 /* continue from '=' to start of value or EOL */
216 for(valptr=eqptr+1; valptr<lineend && isspace(*valptr); valptr++); 215 for(valptr=eqptr+1; valptr<lineend && isspace(*valptr); valptr++);
217 /* continue to the end of value, watching for trailing space/comments */ 216 /* continue to the end of value (FIXME: watching for trailing comments) */
218 for(valend=valptr; valend<lineend; valend++){ 217 for(valend=valptr; valend<lineend; valend++)
219 if(isspace(*valend) && spaceptr==NULL) spaceptr=valend; 218 /* FIXME: N::P doesn't allow comments. Remove next line and parse_ini won't either */
220 else if(*valend=='#') break; 219 if(*valend=='#') break;
221 else spaceptr=NULL;
222 }
223 if(spaceptr!=NULL) valend=spaceptr;
224 --valend; 220 --valend;
221 /* Finally trim off trailing spaces */
222 for(valend; isspace(*valend); valend--);
225 /* calculate the length of "--foo" */ 223 /* calculate the length of "--foo" */
226 opt_len=1+optend-optptr; 224 opt_len=1+optend-optptr;
227 cfg_len=2+(opt_len); 225 cfg_len=2+(opt_len);
@@ -237,27 +235,31 @@ static int add_option(FILE *f, char **optbuf, size_t *bufsize){
237 cfg_len+=1; 235 cfg_len+=1;
238 } 236 }
239 237
240 /* okay, now we have all the info we need, so we grow the default opts 238 /* okay, now we have all the info we need, so we create a new np_arg_list
241 * buffer if it's necessary, and put everything together. 239 * element and set the argument...
242 * (+2 is for a potential space and a null byte)
243 */ 240 */
244 read_pos=(newbuf==NULL)?0:strlen(newbuf); 241 optnew=(np_arg_list *)malloc(sizeof(np_arg_list));
245 if(newbuf==NULL || read_pos+cfg_len+2 >= bs){ 242 optnew->next=NULL;
246 bs=(bs>0)?(bs+cfg_len+2)<<1:cfg_len+1; 243
247 newbuf=realloc(newbuf, bs); 244 read_pos=0;
248 if(newbuf==NULL) die(STATE_UNKNOWN, _("malloc() failed!\n")); 245 optnew->arg=(char *)malloc(cfg_len+1);
249 } 246 strncpy(&optnew->arg[read_pos], "--", 2); read_pos+=2;
250 if(read_pos>0) newbuf[read_pos++]=' '; 247 strncpy(&optnew->arg[read_pos], optptr, opt_len); read_pos+=opt_len;
251 strncpy(&newbuf[read_pos], "--", 2); read_pos+=2; 248 if(equals) optnew->arg[read_pos++]='=';
252 strncpy(&newbuf[read_pos], optptr, opt_len); read_pos+=opt_len;
253 if(equals) newbuf[read_pos++]='=';
254 if(value) { 249 if(value) {
255 strncpy(&newbuf[read_pos], valptr, val_len); read_pos+=val_len; 250 strncpy(&optnew->arg[read_pos], valptr, val_len); read_pos+=val_len;
256 } 251 }
257 newbuf[read_pos]='\0'; 252 optnew->arg[read_pos]='\0';
258 253
259 *optbuf=newbuf; 254 /* ...and put that to the end of the list */
260 *bufsize=bs; 255 if (*optlst==NULL) {
256 *optlst=optnew;
257 } else {
258 while (opttmp->next!=NULL) {
259 opttmp=opttmp->next;
260 }
261 opttmp->next = optnew;
262 }
261 263
262 free(linebuf); 264 free(linebuf);
263 return 0; 265 return 0;
diff --git a/lib/parse_ini.h b/lib/parse_ini.h
index 1c28c7d..fea745c 100644
--- a/lib/parse_ini.h
+++ b/lib/parse_ini.h
@@ -6,6 +6,13 @@
6 * configuration files. 6 * configuration files.
7 */ 7 */
8 8
9/* np_arg_list is a linked list of arguments passed between the ini
10 * parser and the argument parser to construct the final array */
11typedef struct np_arg_el {
12 char *arg;
13 struct np_arg_el *next;
14} np_arg_list;
15
9/* NP_DEFAULT_INI_PATH: compile-time default location for ini file */ 16/* NP_DEFAULT_INI_PATH: compile-time default location for ini file */
10#ifndef NP_DEFAULT_INI_PATH 17#ifndef NP_DEFAULT_INI_PATH
11# define NP_DEFAULT_INI_PATH "/etc/nagios-plugins/plugins.ini" 18# define NP_DEFAULT_INI_PATH "/etc/nagios-plugins/plugins.ini"
@@ -14,6 +21,6 @@
14/* np_load_defaults: load the default configuration (if present) for 21/* np_load_defaults: load the default configuration (if present) for
15 * a plugin from the ini file 22 * a plugin from the ini file
16 */ 23 */
17char* np_get_defaults(const char *locator, const char *default_section); 24np_arg_list* np_get_defaults(const char *locator, const char *default_section);
18 25
19#endif /* _PARSE_INI_H_ */ 26#endif /* _PARSE_INI_H_ */
diff --git a/lib/tests/test_ini.c b/lib/tests/test_ini.c
index 302a2e5..b02d145 100644
--- a/lib/tests/test_ini.c
+++ b/lib/tests/test_ini.c
@@ -19,6 +19,7 @@
19 19
20#include "common.h" 20#include "common.h"
21#include "parse_ini.h" 21#include "parse_ini.h"
22#include "utils_base.h"
22 23
23#include "tap.h" 24#include "tap.h"
24 25
@@ -29,6 +30,22 @@ void my_free(char *string) {
29 } 30 }
30} 31}
31 32
33char*
34list2str(np_arg_list *optlst)
35{
36 char *optstr=NULL;
37
38 /* Put everything as a space-separated string */
39 while (optlst) {
40 asprintf(&optstr, "%s%s ", optstr?optstr:"", optlst->arg);
41 optlst=optlst->next;
42 }
43 /* Strip last whitespace */
44 optstr[strlen(optstr)-1]='\0';
45
46 return optstr;
47}
48
32int 49int
33main (int argc, char **argv) 50main (int argc, char **argv)
34{ 51{
@@ -36,11 +53,11 @@ main (int argc, char **argv)
36 53
37 plan_tests(4); 54 plan_tests(4);
38 55
39 optstr=np_get_defaults("section@./config-tiny.ini", "check_disk"); 56 optstr=list2str(np_get_defaults("section@./config-tiny.ini", "check_disk"));
40 ok( !strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank="), "config-tiny.ini's section as expected"); 57 ok( !strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank="), "config-tiny.ini's section as expected");
41 my_free(optstr); 58 my_free(optstr);
42 59
43 optstr=np_get_defaults("@./config-tiny.ini", "section"); 60 optstr=list2str(np_get_defaults("@./config-tiny.ini", "section"));
44 ok( !strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank="), "Used default section name, without specific"); 61 ok( !strcmp(optstr, "--one=two --Foo=Bar --this=Your Mother! --blank="), "Used default section name, without specific");
45 my_free(optstr); 62 my_free(optstr);
46 63
@@ -51,7 +68,7 @@ main (int argc, char **argv)
51 my_free(optstr); 68 my_free(optstr);
52 */ 69 */
53 70
54 optstr=np_get_defaults("Section Two@./config-tiny.ini", "check_disk"); 71 optstr=list2str(np_get_defaults("Section Two@./config-tiny.ini", "check_disk"));
55 ok( !strcmp(optstr, "--something else=blah --remove=whitespace"), "config-tiny.ini's Section Two as expected"); 72 ok( !strcmp(optstr, "--something else=blah --remove=whitespace"), "config-tiny.ini's Section Two as expected");
56 my_free(optstr); 73 my_free(optstr);
57 74
@@ -70,7 +87,7 @@ main (int argc, char **argv)
70 my_free(optstr); 87 my_free(optstr);
71 */ 88 */
72 89
73 optstr=np_get_defaults("check_mysql@./plugin.ini", "check_disk"); 90 optstr=list2str(np_get_defaults("check_mysql@./plugin.ini", "check_disk"));
74 ok( !strcmp(optstr, "--username=operator --password=secret"), "plugin.ini's check_mysql as expected"); 91 ok( !strcmp(optstr, "--username=operator --password=secret"), "plugin.ini's check_mysql as expected");
75 my_free(optstr); 92 my_free(optstr);
76 93
diff --git a/lib/tests/test_ini.t b/lib/tests/test_ini.t
new file mode 100755
index 0000000..b130a01
--- /dev/null
+++ b/lib/tests/test_ini.t
@@ -0,0 +1,6 @@
1#!/usr/bin/perl
2use Test::More;
3if (! -e "./test_ini") {
4 plan skip_all => "./test_ini not compiled - please install tap library to test";
5}
6exec "./test_ini";