~ubuntu-branches/ubuntu/oneiric/collectd/oneiric

« back to all changes in this revision

Viewing changes to src/utils_match.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Harl
  • Date: 2008-06-17 10:35:51 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080617103551-9d0ym3zejc7agtt3
Tags: 4.4.1-1
* New upstream release.
  - Fixed another issue of the sensors plugin affecting some chip types
    (Closes: #468143).
  - Fixed creation of "vserver" graphs in collection.cgi (Closes: #475120).
  - Fixed a segfault when using libperl 5.10.
  - collectd now ships libiptc itself.
  New plugins:
  - Ascent server statistics: ascent
  - IPMI sensors information: ipmi
  - PowerDNS name server statistics: powerdns
  - incremental parsing of logfiles: tail
  - TeamSpeak2 server statistics: teamspeak2
  - detailed virtual memory statistics: vmem
* Disable "tcpconns" plugin by default (Closes: #478759).
* Reenabled iptables plugin on all architectures (Closes: #473435).
  - Added the plugin to collectd.conf.
  - Added /usr/share/doc/collectd/examples/iptables/.
  - Added build dependency on linux-libc-dev (>= 2.6.25-4) - that version is
    required because of #479899.
* New debconf template translations:
  - gl.po, thanks to Jacobo Tarrio (Closes: #482667).
* Added a work around for #474087 (broken openipmi .pc files) by forcing the
  inclusion of the ipmi plugin and manually specifying the dependencies.
* Updated standards-version to 3.8.0 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * collectd - src/utils_match.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; either version 2 of the License, or (at your
 
8
 * option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful, but
 
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License along
 
16
 * with this program; if not, write to the Free Software Foundation, Inc.,
 
17
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
18
 *
 
19
 * Authors:
 
20
 *   Florian octo Forster <octo at verplant.org>
 
21
 **/
 
22
 
 
23
#include "collectd.h"
 
24
#include "common.h"
 
25
#include "plugin.h"
 
26
 
 
27
#include "utils_match.h"
 
28
 
 
29
#include <regex.h>
 
30
 
 
31
#define UTILS_MATCH_FLAGS_FREE_USER_DATA 0x01
 
32
 
 
33
struct cu_match_s
 
34
{
 
35
  regex_t regex;
 
36
  int flags;
 
37
 
 
38
  int (*callback) (const char *str, char * const *matches, size_t matches_num,
 
39
      void *user_data);
 
40
  void *user_data;
 
41
};
 
42
 
 
43
/*
 
44
 * Private functions
 
45
 */
 
46
static char *match_substr (const char *str, int begin, int end)
 
47
{
 
48
  char *ret;
 
49
  size_t ret_len;
 
50
 
 
51
  if ((begin < 0) || (end < 0) || (begin >= end))
 
52
    return (NULL);
 
53
  if (end > (strlen (str) + 1))
 
54
  {
 
55
    ERROR ("utils_match: match_substr: `end' points after end of string.");
 
56
    return (NULL);
 
57
  }
 
58
 
 
59
  ret_len = end - begin;
 
60
  ret = (char *) malloc (sizeof (char) * (ret_len + 1));
 
61
  if (ret == NULL)
 
62
  {
 
63
    ERROR ("utils_match: match_substr: malloc failed.");
 
64
    return (NULL);
 
65
  }
 
66
 
 
67
  sstrncpy (ret, str + begin, ret_len + 1);
 
68
  return (ret);
 
69
} /* char *match_substr */
 
70
 
 
71
static int default_callback (const char *str,
 
72
    char * const *matches, size_t matches_num, void *user_data)
 
73
{
 
74
  cu_match_value_t *data = (cu_match_value_t *) user_data;
 
75
 
 
76
  if (data->ds_type & UTILS_MATCH_DS_TYPE_GAUGE)
 
77
  {
 
78
    gauge_t value;
 
79
    char *endptr = NULL;
 
80
 
 
81
    if (matches_num < 2)
 
82
      return (-1);
 
83
 
 
84
    value = strtod (matches[1], &endptr);
 
85
    if (matches[1] == endptr)
 
86
      return (-1);
 
87
 
 
88
    if ((data->values_num == 0)
 
89
        || (data->ds_type & UTILS_MATCH_CF_GAUGE_LAST))
 
90
    {
 
91
      data->value.gauge = value;
 
92
    }
 
93
    else if (data->ds_type & UTILS_MATCH_CF_GAUGE_AVERAGE)
 
94
    {
 
95
      double f = ((double) data->values_num)
 
96
        / ((double) (data->values_num + 1));
 
97
      data->value.gauge = (data->value.gauge * f) + (value * (1.0 - f));
 
98
    }
 
99
    else if (data->ds_type & UTILS_MATCH_CF_GAUGE_MIN)
 
100
    {
 
101
      if (data->value.gauge > value)
 
102
        data->value.gauge = value;
 
103
    }
 
104
    else if (data->ds_type & UTILS_MATCH_CF_GAUGE_MAX)
 
105
    {
 
106
      if (data->value.gauge < value)
 
107
        data->value.gauge = value;
 
108
    }
 
109
    else
 
110
    {
 
111
      ERROR ("utils_match: default_callback: obj->ds_type is invalid!");
 
112
      return (-1);
 
113
    }
 
114
 
 
115
    data->values_num++;
 
116
  }
 
117
  else if (data->ds_type & UTILS_MATCH_DS_TYPE_COUNTER)
 
118
  {
 
119
    counter_t value;
 
120
    char *endptr = NULL;
 
121
 
 
122
    if (data->ds_type & UTILS_MATCH_CF_COUNTER_INC)
 
123
    {
 
124
      data->value.counter++;
 
125
      data->values_num++;
 
126
      return (0);
 
127
    }
 
128
 
 
129
    if (matches_num < 2)
 
130
      return (-1);
 
131
 
 
132
    value = strtoll (matches[1], &endptr, 0);
 
133
    if (matches[1] == endptr)
 
134
      return (-1);
 
135
 
 
136
    if (data->ds_type & UTILS_MATCH_CF_COUNTER_SET)
 
137
      data->value.counter = value;
 
138
    else if (data->ds_type & UTILS_MATCH_CF_COUNTER_ADD)
 
139
      data->value.counter += value;
 
140
    else
 
141
    {
 
142
      ERROR ("utils_match: default_callback: obj->ds_type is invalid!");
 
143
      return (-1);
 
144
    }
 
145
 
 
146
    data->values_num++;
 
147
  }
 
148
  else
 
149
  {
 
150
    ERROR ("utils_match: default_callback: obj->ds_type is invalid!");
 
151
    return (-1);
 
152
  }
 
153
 
 
154
  return (0);
 
155
} /* int default_callback */
 
156
 
 
157
/*
 
158
 * Public functions
 
159
 */
 
160
cu_match_t *match_create_callback (const char *regex,
 
161
                int (*callback) (const char *str,
 
162
                  char * const *matches, size_t matches_num, void *user_data),
 
163
                void *user_data)
 
164
{
 
165
  cu_match_t *obj;
 
166
  int status;
 
167
 
 
168
  DEBUG ("utils_match: match_create_callback: regex = %s", regex);
 
169
 
 
170
  obj = (cu_match_t *) malloc (sizeof (cu_match_t));
 
171
  if (obj == NULL)
 
172
    return (NULL);
 
173
  memset (obj, '\0', sizeof (cu_match_t));
 
174
 
 
175
  status = regcomp (&obj->regex, regex, REG_EXTENDED);
 
176
  if (status != 0)
 
177
  {
 
178
    ERROR ("Compiling the regular expression \"%s\" failed.", regex);
 
179
    sfree (obj);
 
180
    return (NULL);
 
181
  }
 
182
 
 
183
  obj->callback = callback;
 
184
  obj->user_data = user_data;
 
185
 
 
186
  return (obj);
 
187
} /* cu_match_t *match_create_callback */
 
188
 
 
189
cu_match_t *match_create_simple (const char *regex, int match_ds_type)
 
190
{
 
191
  cu_match_value_t *user_data;
 
192
  cu_match_t *obj;
 
193
 
 
194
  user_data = (cu_match_value_t *) malloc (sizeof (cu_match_value_t));
 
195
  if (user_data == NULL)
 
196
    return (NULL);
 
197
  memset (user_data, '\0', sizeof (cu_match_value_t));
 
198
  user_data->ds_type = match_ds_type;
 
199
 
 
200
  obj = match_create_callback (regex, default_callback, user_data);
 
201
  if (obj == NULL)
 
202
  {
 
203
    sfree (user_data);
 
204
    return (NULL);
 
205
  }
 
206
 
 
207
  obj->flags |= UTILS_MATCH_FLAGS_FREE_USER_DATA;
 
208
 
 
209
  return (obj);
 
210
} /* cu_match_t *match_create_simple */
 
211
 
 
212
void match_destroy (cu_match_t *obj)
 
213
{
 
214
  if (obj == NULL)
 
215
    return;
 
216
 
 
217
  if (obj->flags & UTILS_MATCH_FLAGS_FREE_USER_DATA)
 
218
  {
 
219
    sfree (obj->user_data);
 
220
  }
 
221
 
 
222
  sfree (obj);
 
223
} /* void match_destroy */
 
224
 
 
225
int match_apply (cu_match_t *obj, const char *str)
 
226
{
 
227
  int status;
 
228
  regmatch_t re_match[32];
 
229
  char *matches[32];
 
230
  size_t matches_num;
 
231
  int i;
 
232
 
 
233
  if ((obj == NULL) || (str == NULL))
 
234
    return (-1);
 
235
 
 
236
  status = regexec (&obj->regex, str,
 
237
      STATIC_ARRAY_SIZE (re_match), re_match,
 
238
      /* eflags = */ 0);
 
239
 
 
240
  /* Regex did not match */
 
241
  if (status != 0)
 
242
    return (0);
 
243
 
 
244
  memset (matches, '\0', sizeof (matches));
 
245
  for (matches_num = 0; matches_num < STATIC_ARRAY_SIZE (matches); matches_num++)
 
246
  {
 
247
    if ((re_match[matches_num].rm_so < 0)
 
248
        || (re_match[matches_num].rm_eo < 0))
 
249
      break;
 
250
 
 
251
    matches[matches_num] = match_substr (str,
 
252
        re_match[matches_num].rm_so, re_match[matches_num].rm_eo);
 
253
    if (matches[matches_num] == NULL)
 
254
    {
 
255
      status = -1;
 
256
      break;
 
257
    }
 
258
  }
 
259
 
 
260
  if (status != 0)
 
261
  {
 
262
    ERROR ("utils_match: match_apply: match_substr failed.");
 
263
  }
 
264
  else
 
265
  {
 
266
    status = obj->callback (str, matches, matches_num, obj->user_data);
 
267
    if (status != 0)
 
268
    {
 
269
      ERROR ("utils_match: match_apply: callback failed.");
 
270
    }
 
271
  }
 
272
 
 
273
  for (i = 0; i < matches_num; i++)
 
274
  {
 
275
    sfree (matches[i]);
 
276
  }
 
277
 
 
278
  return (status);
 
279
} /* int match_apply */
 
280
 
 
281
void *match_get_user_data (cu_match_t *obj)
 
282
{
 
283
  if (obj == NULL)
 
284
    return (NULL);
 
285
  return (obj->user_data);
 
286
} /* void *match_get_user_data */
 
287
 
 
288
/* vim: set sw=2 sts=2 ts=8 : */