Merge branch 'collectd-4.2' into collectd-4.3
[collectd.git] / src / utils_cmd_putnotif.c
1 /**
2  * collectd - src/utils_cms_putnotif.c
3  * Copyright (C) 2008  Florian octo Forster
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; only version 2 of the License is applicable.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  *
18  * Author:
19  *   Florian octo Forster <octo at verplant.org>
20  **/
21
22 #include "collectd.h"
23 #include "common.h"
24 #include "plugin.h"
25
26 static int parse_option_severity (notification_t *n, char *value)
27 {
28   if (strcasecmp (value, "Failure") == 0)
29     n->severity = NOTIF_FAILURE;
30   else if (strcasecmp (value, "Warning") == 0)
31     n->severity = NOTIF_WARNING;
32   else if (strcasecmp (value, "Okay") == 0)
33     n->severity = NOTIF_OKAY;
34   else
35     return (-1);
36
37   return (0);
38 } /* int parse_option_severity */
39
40 static int parse_option_time (notification_t *n, char *value)
41 {
42   time_t tmp;
43   
44   tmp = (time_t) atoi (value);
45   if (tmp <= 0)
46     return (-1);
47
48   n->time = tmp;
49
50   return (0);
51 } /* int parse_option_time */
52
53 static int parse_option (notification_t *n, char *buffer)
54 {
55   char *option = buffer;
56   char *value;
57
58   if ((n == NULL) || (option == NULL))
59     return (-1);
60
61   value = strchr (option, '=');
62   if (value == NULL)
63     return (-1);
64   *value = '\0'; value++;
65
66   if (strcasecmp ("severity", option) == 0)
67     return (parse_option_severity (n, value));
68   else if (strcasecmp ("time", option) == 0)
69     return (parse_option_time (n, value));
70   else if (strcasecmp ("host", option) == 0)
71     sstrncpy (n->host, value, sizeof (n->host));
72   else if (strcasecmp ("plugin", option) == 0)
73     sstrncpy (n->plugin, value, sizeof (n->plugin));
74   else if (strcasecmp ("plugin_instance", option) == 0)
75     sstrncpy (n->plugin_instance, value, sizeof (n->plugin_instance));
76   else if (strcasecmp ("type", option) == 0)
77     sstrncpy (n->type, value, sizeof (n->type));
78   else if (strcasecmp ("type_instance", option) == 0)
79     sstrncpy (n->type_instance, value, sizeof (n->type_instance));
80   else
81     return (1);
82
83   return (0);
84 } /* int parse_option */
85
86 static int parse_message (notification_t *n, char **fields, int fields_num)
87 {
88   int status;
89
90   /* Strip off the leading `message=' */
91   fields[0] += strlen ("message=");
92
93   status = strjoin (n->message, sizeof (n->message), fields, fields_num, " ");
94   if (status < 0)
95     return (-1);
96
97   return (0);
98 } /* int parse_message */
99
100 int handle_putnotif (FILE *fh, char **fields, int fields_num)
101 {
102   notification_t n;
103   int status;
104   int i;
105
106   /* Required fields: `PUTNOTIF', severity, time, message */
107   if (fields_num < 4)
108   {
109     DEBUG ("cmd putnotif: Wrong number of fields: %i", fields_num);
110     fprintf (fh, "-1 Wrong number of fields: Got %i, expected at least 4.\n",
111         fields_num);
112     fflush (fh);
113     return (-1);
114   }
115
116   memset (&n, '\0', sizeof (n));
117
118   status = 0;
119   for (i = 1; i < fields_num; i++)
120   {
121     if (strncasecmp (fields[i], "message=", strlen ("message=")) == 0)
122     {
123       status = parse_message (&n, fields + i, fields_num - i);
124       if (status != 0)
125       {
126         fprintf (fh, "-1 Error parsing the message. Have you hit the "
127             "limit of %u bytes?\n", (unsigned int) sizeof (n.message));
128       }
129       break;
130     }
131     else
132     {
133       status = parse_option (&n, fields[i]);
134       if (status != 0)
135       {
136         fprintf (fh, "-1 Error parsing option `%s'", fields[i]);
137         break;
138       }
139     }
140   } /* for (i) */
141
142   /* Check for required fields and complain if anything is missing. */
143   if ((status == 0) && (n.severity == 0))
144   {
145     fprintf (fh, "-1 Option `severity' missing.\n");
146     status = -1;
147   }
148   if ((status == 0) && (n.time == 0))
149   {
150     fprintf (fh, "-1 Option `time' missing.\n");
151     status = -1;
152   }
153   if ((status == 0) && (strlen (n.message) == 0))
154   {
155     fprintf (fh, "-1 No message or message of length 0 given.\n");
156     status = -1;
157   }
158
159   /* If status is still zero the notification is fine and we can finally
160    * dispatch it. */
161   if (status == 0)
162   {
163     plugin_dispatch_notification (&n);
164     fprintf (fh, "0 Success\n");
165   }
166   fflush (fh);
167
168   return (0);
169 } /* int handle_putnotif */
170
171 /* vim: set shiftwidth=2 softtabstop=2 tabstop=8 : */