2 * collection4 - filesystem.c
3 * Copyright (C) 2010 Florian octo Forster
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
21 * Florian octo Forster <ff at octo.it>
30 #include <sys/types.h>
34 #include "filesystem.h"
36 struct fs_scan_dir_data_s /* {{{ */
38 fs_ident_cb_t callback;
43 char *plugin_instance;
47 typedef struct fs_scan_dir_data_s fs_scan_dir_data_t;
49 typedef int (*callback_type_t) (const char *type, void *user_data);
50 typedef int (*callback_plugin_t) (const char *plugin, void *user_data);
51 typedef int (*callback_host_t) (const char *host, void *user_data);
54 * Directory and file walking functions
56 static int foreach_rrd_file (const char *dir, /* {{{ */
57 int (*callback) (const char *, void *),
71 while ((entry = readdir (dh)) != NULL)
74 char abspath[PATH_MAX + 1];
77 if (entry->d_name[0] == '.')
80 d_name_len = strlen (entry->d_name);
84 if (strcasecmp (".rrd", entry->d_name + (d_name_len - 4)) != 0)
87 snprintf (abspath, sizeof (abspath), "%s/%s", dir, entry->d_name);
88 abspath[sizeof (abspath) - 1] = 0;
90 memset (&statbuf, 0, sizeof (statbuf));
92 status = stat (abspath, &statbuf);
96 if (!S_ISREG (statbuf.st_mode))
99 entry->d_name[d_name_len - 4] = 0;
101 status = (*callback) (entry->d_name, user_data);
104 } /* while (readdir) */
108 } /* }}} int foreach_rrd_file */
110 static int foreach_dir (const char *dir, /* {{{ */
111 int (*callback) (const char *, void *),
115 struct dirent *entry;
118 if (callback == NULL)
125 while ((entry = readdir (dh)) != NULL)
128 char abspath[PATH_MAX + 1];
130 if (entry->d_name[0] == '.')
133 snprintf (abspath, sizeof (abspath), "%s/%s", dir, entry->d_name);
134 abspath[sizeof (abspath) - 1] = 0;
136 memset (&statbuf, 0, sizeof (statbuf));
138 status = stat (abspath, &statbuf);
142 if (!S_ISDIR (statbuf.st_mode))
145 status = (*callback) (entry->d_name, user_data);
148 } /* while (readdir) */
152 } /* }}} int foreach_dir */
154 static int foreach_type (const char *host, const char *plugin, /* {{{ */
155 callback_type_t callback, void *user_data)
157 char abspath[PATH_MAX + 1];
159 if ((host == NULL) || (plugin == NULL))
162 snprintf (abspath, sizeof (abspath), "%s/%s/%s", DATA_DIR, host, plugin);
163 abspath[sizeof (abspath) - 1] = 0;
165 return (foreach_rrd_file (abspath, callback, user_data));
166 } /* }}} int foreach_type */
168 static int foreach_plugin (const char *host, /* {{{ */
169 callback_plugin_t callback,
172 char abspath[PATH_MAX + 1];
177 snprintf (abspath, sizeof (abspath), "%s/%s", DATA_DIR, host);
178 abspath[sizeof (abspath) - 1] = 0;
180 return (foreach_dir (abspath, callback, user_data));
181 } /* }}} int foreach_plugin */
183 static int foreach_host (callback_host_t callback, /* {{{ */
186 return (foreach_dir (DATA_DIR, callback, user_data));
187 } /* }}} int foreach_host */
190 * Functions building "fs_scan_dir_data_t" and calling the user-supplied
191 * callback eventually.
193 static int scan_type (const char *type, void *user_data) /* {{{ */
195 fs_scan_dir_data_t *data = user_data;
196 graph_ident_t *ident;
199 if ((type == NULL) || (data == NULL))
202 if ((data->type != NULL) || (data->type_instance != NULL))
205 data->type = strdup (type);
206 if (data->type == NULL)
209 data->type_instance = strchr (data->type, '-');
210 if (data->type_instance != NULL)
212 *data->type_instance = 0;
213 data->type_instance++;
217 data->type_instance = data->type + strlen (data->type);
220 ident = ident_create (data->host,
221 data->plugin, data->plugin_instance,
222 data->type, data->type_instance);
229 status = (*data->callback) (ident, data->user_data);
230 ident_destroy (ident);
235 data->type_instance = NULL;
238 } /* }}} int scan_type */
240 static int scan_plugin (const char *plugin, void *user_data) /* {{{ */
242 fs_scan_dir_data_t *data = user_data;
245 if ((plugin == NULL) || (data == NULL))
248 if ((data->plugin != NULL) || (data->plugin_instance != NULL))
251 data->plugin = strdup (plugin);
252 if (data->plugin == NULL)
255 data->plugin_instance = strchr (data->plugin, '-');
256 if (data->plugin_instance != NULL)
258 *data->plugin_instance = 0;
259 data->plugin_instance++;
263 data->plugin_instance = data->plugin + strlen (data->plugin);
266 status = foreach_type (data->host, plugin, scan_type, data);
270 data->plugin_instance = NULL;
273 } /* }}} int scan_plugin */
275 static int scan_host (const char *host, void *user_data) /* {{{ */
277 fs_scan_dir_data_t *data = user_data;
280 if ((host == NULL) || (data == NULL))
283 if (data->host != NULL)
286 data->host = strdup (host);
287 if (data->host == NULL)
290 status = foreach_plugin (host, scan_plugin, data);
296 } /* }}} int scan_host */
301 int fs_scan (fs_ident_cb_t callback, void *user_data) /* {{{ */
303 fs_scan_dir_data_t data;
305 memset (&data, 0, sizeof (data));
306 data.callback = callback;
307 data.user_data = user_data;
311 data.plugin_instance = NULL;
313 data.type_instance = NULL;
315 foreach_host (scan_host, &data);
318 } /* }}} int fs_scan */
320 /* vim: set sw=2 sts=2 et fdm=marker : */