2 * collectd - src/config_list.c
3 * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
5 * This program is free software; you can redistribute it and/
6 * or modify it under the terms of the GNU General Public Li-
7 * cence as published by the Free Software Foundation; either
8 * version 2 of the Licence, or any later version.
10 * This program is distributed in the hope that it will be use-
11 * ful, but WITHOUT ANY WARRANTY; without even the implied war-
12 * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public Licence for more details.
15 * You should have received a copy of the GNU General Public
16 * Licence along with this program; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
21 * Lubos Stanek <lubek at users.sourceforge.net>
24 * ignorelist handles plugin's list of configured collectable
25 * entries with global ignore action
30 * Define plugin's global pointer variable of type ignorelist_t:
31 * ignorelist_t *myconfig_ignore;
32 * If you know the state of the global ignore (IgnoreSelected),
33 * allocate the variable with:
34 * myconfig_ignore = ignorelist_create (YourKnownIgnore);
35 * If you do not know the state of the global ignore,
36 * initialize the global variable and set the ignore flag later:
37 * myconfig_ignore = ignorelist_init ();
38 * Append single entries in your cf_register'ed callback function:
39 * ignorelist_add (myconfig_ignore, newentry);
40 * When you hit the IgnoreSelected config option,
41 * offer it to the list:
42 * ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore);
43 * That is all for the ignorelist initialization.
44 * Later during read and write (plugin's registered functions) get
45 * the information whether this entry would be collected or not:
46 * if (ignorelist_ignored (myconfig_ignore, thisentry))
51 #include "utils_debug.h"
52 #include "utils_ignorelist.h"
57 struct ignorelist_item_s
60 regex_t *rmatch; /* regular expression entry identification */
62 char *smatch; /* string entry identification */
63 struct ignorelist_item_s *next;
65 typedef struct ignorelist_item_s ignorelist_item_t;
69 int ignore; /* ignore entries */
70 int num; /* number of entries */
71 ignorelist_item_t *next; /* pointer to the first entry */
74 /* *** *** *** ********************************************* *** *** *** */
75 /* *** *** *** *** *** *** private functions *** *** *** *** *** *** */
76 /* *** *** *** ********************************************* *** *** *** */
79 static int ignorelist_regappend(ignorelist_t *conflist, const char *entry)
85 ignorelist_item_t *new;
88 if ((regtemp = malloc(sizeof(regex_t))) == NULL)
90 syslog (LOG_ERR, "cannot allocate new config entry");
93 memset (regtemp, '\0', sizeof(regex_t));
96 if ((rcompile = regcomp (regtemp, entry, REG_EXTENDED)) != 0)
98 /* prepare message buffer */
99 errsize = regerror(rcompile, regtemp, NULL, 0);
101 regerr = smalloc(errsize);
102 /* get error message */
103 if (regerror(rcompile, regtemp, regerr, errsize))
104 syslog (LOG_ERR, "cannot compile regex %s: %i/%s",
105 entry, rcompile, regerr);
107 syslog (LOG_ERR, "cannot compile regex %s: %i",
114 DBG("regex compiled: %s - %i", entry, rcompile);
116 /* create new entry */
117 if ((new = malloc(sizeof(ignorelist_item_t))) == NULL)
119 syslog (LOG_ERR, "cannot allocate new config entry");
123 memset (new, '\0', sizeof(ignorelist_item_t));
124 new->rmatch = regtemp;
126 /* append new entry */
127 if (conflist->next == NULL)
133 new->next=conflist->next;
138 } /* int ignorelist_regappend(ignorelist_t *conflist, const char *entry) */
141 static int ignorelist_strappend(ignorelist_t *conflist, const char *entry)
143 ignorelist_item_t *new;
145 /* create new entry */
146 if ((new = malloc(sizeof(ignorelist_item_t))) == NULL )
148 syslog (LOG_ERR, "cannot allocate new entry");
151 memset (new, '\0', sizeof(ignorelist_item_t));
152 new->smatch = sstrdup(entry);
154 /* append new entry */
155 if (conflist->next == NULL)
161 new->next=conflist->next;
166 } /* int ignorelist_strappend(ignorelist_t *conflist, const char *entry) */
170 * check list for entry regex match
173 static int ignorelist_item_rmatch (ignorelist_item_t *confentry, const char *entry)
175 if (confentry == NULL)
178 if (strlen (entry) == 0)
181 if (confentry->rmatch == NULL)
185 if (regexec (confentry->rmatch, entry, 0, NULL, 0) == 0)
189 } /* int ignorelist_item_rmatch (ignorelist_item_t *confentry, const char *entry) */
193 * check list for entry string match
196 static int ignorelist_item_smatch (ignorelist_item_t *confentry, const char *entry)
198 if (confentry == NULL)
201 if (strlen (entry) == 0)
204 if ((confentry->smatch != NULL && strcmp (entry, confentry->smatch) == 0))
208 } /* int ignorelist_item_smatch (ignorelist_item_t *confentry, const char *entry) */
211 /* *** *** *** ******************************************** *** *** *** */
212 /* *** *** *** *** *** *** public functions *** *** *** *** *** *** */
213 /* *** *** *** ******************************************** *** *** *** */
216 * create the ignorelist_t with known ignore state
217 * return pointer to ignorelist_t
219 ignorelist_t *ignorelist_create (int ignore)
221 ignorelist_t *conflist;
223 if ((conflist = smalloc (sizeof (ignorelist_t))) == NULL)
225 syslog(LOG_ERR, "not enough memory to allocate ignorelist");
228 DBG("ignorelist created 0x%p, ignore %i", (void *) conflist, ignore);
229 memset (conflist, '\0', sizeof (ignorelist_t));
232 conflist->ignore = ignore;
235 } /* ignorelist_t *ignorelist_create (int ignore) */
238 * create ignorelist_t and initialize the ignore state to 0
239 * return pointer to ignorelist_t
241 ignorelist_t *ignorelist_init (void)
243 return (ignorelist_create (0));
244 } /* ignorelist_t *ignorelist_init (void) */
248 * free memory used by ignorelist_t
250 void ignorelist_free (ignorelist_t *conflist)
252 ignorelist_item_t *this;
253 ignorelist_item_t *next;
255 DBG ("(conflist = 0x%p)", (void *) conflist);
257 if (conflist == NULL)
260 for (this = conflist->next; this != NULL; this = next)
262 DBG ("free - confentry = 0x%p, numlist %i", (void *) this, conflist->num);
266 if (this->rmatch != NULL)
268 regfree (this->rmatch);
272 if (this->smatch != NULL)
274 sfree (this->smatch);
280 if (conflist->num != 0)
281 DBG ("after free numlist: %i", conflist->num);
286 } /* void ignorelist_destroy (ignorelist_t *conflist) */
289 * set ignore state of the ignorelist_t
291 void ignorelist_ignore (ignorelist_t *conflist, int ignore)
293 if (conflist == NULL)
295 DBG("ignore call with ignorelist_t == NULL");
299 conflist->ignore = ignore;
300 } /* void ignorelist_ignore (ignorelist_t *conflist, int ignore) */
303 * get number of entries in the ignorelist_t
306 int ignorelist_num (ignorelist_t *conflist)
308 if (conflist == NULL)
310 DBG("get num called with ignorelist_t == NULL");
314 return (conflist->num);
315 } /* int ignorelist_num (ignorelist_t *conflist) */
318 * append entry into ignorelist_t
319 * return 1 for success
321 int ignorelist_add (ignorelist_t *conflist, const char *entry)
328 if (conflist == NULL)
330 DBG("add called with ignorelist_t == NULL");
334 /* append nothing, report success */
335 if (strlen(entry) == 0)
337 DBG("not appending: empty entry");
342 /* regex string is enclosed in "/.../" */
343 if (entry[0] == '/' && strlen(entry) > 2 && entry[strlen(entry) - 1] == '/')
345 entrytemp = smalloc(strlen(entry) - 2);
346 sstrncpy(entrytemp, &entry[1], strlen(entry) - 1);
347 DBG("to add regex entry: %s", entrytemp);
348 restemp = ignorelist_regappend(conflist, entrytemp);
354 DBG("to add entry: %s", entry);
355 restemp = ignorelist_strappend(conflist, entry);
358 } /* int ignorelist_add (ignorelist_t *conflist, const char *entry) */
361 * check list for entry
362 * return 1 for ignored entry
364 int ignorelist_ignored (ignorelist_t *conflist, const char *entry)
366 ignorelist_item_t *traverse;
368 /* if no entries, collect all */
369 if (ignorelist_num(conflist) == 0)
372 /* traverse list and check entries */
373 traverse = conflist->next;
374 while (traverse != NULL)
377 if (traverse->rmatch != NULL)
379 if (ignorelist_item_rmatch (traverse, entry))
380 return (conflist->ignore);
385 if (ignorelist_item_smatch (traverse, entry))
386 return (conflist->ignore);
388 traverse = traverse->next;
391 return (1 - conflist->ignore);
392 } /* int ignorelist_ignored (ignorelist_t *conflist, const char *entry) */