graph_list: Add basic configuration infrastructure.
[collection4.git] / common.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <unistd.h>
8 #include <dirent.h>
9
10 #include "common.h"
11
12 static int foreach_rrd_file (const char *dir, /* {{{ */
13     int (*callback) (const char *, void *),
14     void *user_data)
15 {
16   DIR *dh;
17   struct dirent *entry;
18   int status;
19
20   if (callback == NULL)
21     return (EINVAL);
22
23   dh = opendir (dir);
24   if (dh == NULL)
25     return (errno);
26
27   while ((entry = readdir (dh)) != NULL)
28   {
29     struct stat statbuf;
30     char abspath[PATH_MAX + 1];
31     size_t d_name_len;
32
33     if (entry->d_name[0] == '.')
34       continue;
35
36     d_name_len = strlen (entry->d_name);
37     if (d_name_len <= 4)
38       continue;
39
40     if (strcasecmp (".rrd", entry->d_name + (d_name_len - 4)) != 0)
41       continue;
42
43     snprintf (abspath, sizeof (abspath), "%s/%s", dir, entry->d_name);
44     abspath[sizeof (abspath) - 1] = 0;
45
46     memset (&statbuf, 0, sizeof (statbuf));
47
48     status = stat (abspath, &statbuf);
49     if (status != 0)
50       continue;
51
52     if (!S_ISREG (statbuf.st_mode))
53       continue;
54
55     entry->d_name[d_name_len - 4] = 0;
56
57     status = (*callback) (entry->d_name, user_data);
58     if (status != 0)
59       break;
60   } /* while (readdir) */
61
62   closedir (dh);
63   return (status);
64 } /* }}} int foreach_rrd_file */
65
66 static int foreach_dir (const char *dir, /* {{{ */
67     int (*callback) (const char *, void *),
68     void *user_data)
69 {
70   DIR *dh;
71   struct dirent *entry;
72   int status;
73
74   if (callback == NULL)
75     return (EINVAL);
76
77   dh = opendir (dir);
78   if (dh == NULL)
79     return (errno);
80
81   while ((entry = readdir (dh)) != NULL)
82   {
83     struct stat statbuf;
84     char abspath[PATH_MAX + 1];
85
86     if (entry->d_name[0] == '.')
87       continue;
88
89     snprintf (abspath, sizeof (abspath), "%s/%s", dir, entry->d_name);
90     abspath[sizeof (abspath) - 1] = 0;
91
92     memset (&statbuf, 0, sizeof (statbuf));
93
94     status = stat (abspath, &statbuf);
95     if (status != 0)
96       continue;
97
98     if (!S_ISDIR (statbuf.st_mode))
99       continue;
100
101     status = (*callback) (entry->d_name, user_data);
102     if (status != 0)
103       break;
104   } /* while (readdir) */
105
106   closedir (dh);
107   return (status);
108 } /* }}} int foreach_dir */
109
110 int foreach_type (const char *host, const char *plugin, /* {{{ */
111     callback_type_t callback, void *user_data)
112 {
113   char abspath[PATH_MAX + 1];
114
115   if ((host == NULL) || (plugin == NULL))
116     return (EINVAL);
117
118   snprintf (abspath, sizeof (abspath), "%s/%s/%s", DATA_DIR, host, plugin);
119   abspath[sizeof (abspath) - 1] = 0;
120
121   return (foreach_rrd_file (abspath, callback, user_data));
122 } /* }}} int foreach_type */
123
124 int foreach_plugin (const char *host, /* {{{ */
125     callback_plugin_t callback,
126     void *user_data)
127 {
128   char abspath[PATH_MAX + 1];
129
130   if (host == NULL)
131     return (EINVAL);
132
133   snprintf (abspath, sizeof (abspath), "%s/%s", DATA_DIR, host);
134   abspath[sizeof (abspath) - 1] = 0;
135
136   return (foreach_dir (abspath, callback, user_data));
137 } /* }}} int foreach_plugin */
138
139 int foreach_host (callback_host_t callback, /* {{{ */
140     void *user_data)
141 {
142   return (foreach_dir (DATA_DIR, callback, user_data));
143 } /* }}} int foreach_host */
144
145 /* vim: set sw=2 sts=2 et fdm=marker : */