>From 67244412e1ae8fcc955bd412dad3b578e75cb426 Mon Sep 17 00:00:00 2001
From: Daniel Hilst <danielhilst@gmail.com>
Date: Sat, 10 Mar 2012 12:24:52 +0000
Subject: [PATCH] processes.c: Added support to invert match, a grep -v like option

---
 src/processes.c |   41 ++++++++++++++++++++++++++---------------
 1 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/src/processes.c b/src/processes.c
index 8f4eb88..b2d02c2 100644
--- a/src/processes.c
+++ b/src/processes.c
@@ -183,6 +183,7 @@ typedef struct procstat
 
 	struct procstat   *next;
 	struct procstat_entry_s *instances;
+        int invert;
 } procstat_t;
 
 static procstat_t *list_head_g = NULL;
@@ -218,7 +219,7 @@ int getargs (struct procentry64 *processBuffer, int bufferLen, char *argsBuffer,
 /* put name of process from config to list_head_g tree
    list_head_g is a list of 'procstat_t' structs with
    processes names we want to watch */
-static void ps_list_register (const char *name, const char *regexp)
+static void ps_list_register (const char *name, const char *regexp, int invert)
 {
 	procstat_t *new;
 	procstat_t *ptr;
@@ -232,7 +233,7 @@ static void ps_list_register (const char *name, const char *regexp)
 	}
 	memset (new, 0, sizeof (procstat_t));
 	sstrncpy (new->name, name, sizeof (new->name));
-
+        new->invert = invert;
 #if HAVE_REGEX_H
 	if (regexp != NULL)
 	{
@@ -309,7 +310,7 @@ static int ps_list_match (const char *name, const char *cmdline, procstat_t *ps)
 				/* nmatch = */ 0,
 				/* pmatch = */ NULL,
 				/* eflags = */ 0);
-		if (status == 0)
+		if (ps->invert ? status : status == 0)
 			return (1);
 	}
 	else
@@ -331,8 +332,13 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
 
 	for (ps = list_head_g; ps != NULL; ps = ps->next)
 	{
-		if ((ps_list_match (name, cmdline, ps)) == 0)
+		if ((ps_list_match (name, cmdline, ps)) == 0) {
 			continue;
+                } else {
+                        DEBUG ("process plugin: ProcessMatch \"%s\" \"%s\" Inverted=%s", 
+                               ps->name, cmdline, (ps->invert ? "yes" : "no"));
+                }
+
 
 		for (pse = ps->instances; pse != NULL; pse = pse->next)
 			if ((pse->id == entry->id) || (pse->next == NULL))
@@ -516,6 +522,7 @@ static void ps_list_reset (void)
 static int ps_config (oconfig_item_t *ci)
 {
 	int i;
+        int invert;
 
 	for (i = 0; i < ci->children_num; ++i) {
 		oconfig_item_t *c = ci->children + i;
@@ -537,19 +544,19 @@ static int ps_config (oconfig_item_t *ci)
 						c->children_num, c->values[0].value.string);
 			}
 
-			ps_list_register (c->values[0].value.string, NULL);
+			ps_list_register (c->values[0].value.string, NULL, 0);
 		}
 		else if (strcasecmp (c->key, "ProcessMatch") == 0)
 		{
-			if ((c->values_num != 2)
-					|| (OCONFIG_TYPE_STRING != c->values[0].type)
-					|| (OCONFIG_TYPE_STRING != c->values[1].type))
-			{
-				ERROR ("processes plugin: `ProcessMatch' needs exactly "
-						"two string arguments (got %i).",
-						c->values_num);
-				continue;
-			}
+			/* if (c->values_num != 2) */
+			/* 		|| (OCONFIG_TYPE_STRING != c->values[0].type) */
+			/* 		|| (OCONFIG_TYPE_STRING != c->values[1].type)) */
+			/* { */
+			/* 	ERROR ("processes plugin: `ProcessMatch' needs exactly " */
+			/* 			"two string arguments (got %i).", */
+			/* 			c->values_num); */
+			/* 	continue; */
+			/* } */
 
 			if (c->children_num != 0) {
 				WARNING ("processes plugin: the `ProcessMatch' config option "
@@ -559,8 +566,12 @@ static int ps_config (oconfig_item_t *ci)
 						c->values[1].value.string);
 			}
 
+                        invert = 0;
+                        if (c->values_num == 3 && !strcasecmp("Invert", c->values[2].value.string)) 
+                                invert = 1;
+
 			ps_list_register (c->values[0].value.string,
-					c->values[1].value.string);
+                                          c->values[1].value.string, invert);
 		}
 		else
 		{
-- 
1.7.3.4

