root/lm-sensors/trunk/prog/sensord/args.c @ 1474

Revision 1474, 9.2 KB (checked in by merlin, 11 years ago)

Update to support logging of the load average to the round-robin
database.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * sensord
3 *
4 * A daemon that periodically logs sensor information to syslog.
5 *
6 * Copyright (c) 1999-2002 Merlin Hughes <merlin@merlin.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <getopt.h>
27#include <syslog.h>
28
29#include "sensord.h"
30#include "lib/error.h"
31
32#define MAX_CHIP_NAMES 32
33
34int isDaemon = 0;
35const char *sensorsCfgFile = "sensors.conf";
36const char *pidFile = "/var/run/sensord.pid";
37const char *rrdFile = NULL;
38const char *cgiDir = NULL;
39int scanTime = 60;
40int logTime = 30 * 60;
41int rrdTime = 5 * 60;
42int syslogFacility = LOG_LOCAL4;
43int doScan = 0;
44int doSet = 0;
45int doCGI = 0;
46int doLoad = 0;
47int debug = 0;
48sensors_chip_name chipNames[MAX_CHIP_NAMES];
49int numChipNames = 0;
50
51static int
52parseTime
53(char *arg) {
54  char *end;
55  int value = strtoul (arg, &end, 10);
56  if ((end > arg) && (*end == 's')) {
57    ++ end;
58  } else if ((end > arg) && (*end == 'm')) {
59    value *= 60;
60    ++ end;
61  } else if ((end > arg) && (*end == 'h')) {
62    value *= 60 * 60;
63    ++ end;
64  }
65  if ((end == arg) || *end) {
66    fprintf (stderr, "Error parsing time value `%s'.\n", arg);
67    return -1;
68  }
69  return value;
70}
71
72static struct {
73  const char *name;
74  int id;
75} facilities[] = {
76  { "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 },
77  { "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 },
78  { "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 },
79  { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 },
80  { "daemon", LOG_DAEMON }, { "user", LOG_USER },
81  { NULL }
82};
83
84static int
85parseFacility
86(char *arg) {
87  int i = 0;
88  while (facilities[i].name && strcasecmp (arg, facilities[i].name))
89    ++ i;
90  if (!facilities[i].name) {
91    fprintf (stderr, "Error parsing facility value `%s'.\n", arg);
92    return -1;
93  }
94  return facilities[i].id;
95}
96
97static const char *daemonSyntax =
98  "  -i, --interval <time>     -- interval between scanning alarms (default 60s)\n"
99  "  -l, --log-interval <time> -- interval between logging sensors (default 30m)\n"
100  "  -t, --rrd-interval <time> -- interval between updating RRD file (default 5m)\n"
101  "  -r, --rrd-file <file>     -- RRD file (default <none>)\n"
102  "  -c, --config-file <file>  -- configuration file (default sensors.conf)\n"
103  "  -p, --pid-file <file>     -- PID file (default /var/run/sensord.pid)\n"
104  "  -f, --syslog-facility <f> -- syslog facility to use (default local4)\n"
105  "  -g, --rrd-cgi <img-dir>   -- output an RRD CGI script and exit\n"
106  "  -a, --load-average        -- include load average in RRD file\n"
107  "  -d, --debug               -- display some debug information\n"
108  "  -v, --version             -- display version and exit\n"
109  "  -h, --help                -- display help and exit\n"
110  "\n"
111  "Specify a value of 0 for any interval to disable that operation;\n"
112  "for example, specify --log-interval 0 to only scan for alarms."
113  "\n"
114  "If no path is specified, a list of directories is examined for the config file;\n"
115  "specify the filename `-' to read the config file from stdin.\n"
116  "\n"
117  "If no chips are specified, all chip info will be printed.\n"
118  "\n"
119  "If unspecified, no RRD (round robin database) is used. If specified and the\n"
120  "file does not exist, it will be created. For RRD updates to be successful,\n"
121  "the RRD file configuration must EXACTLY match the sensors that are used. If\n"
122  "your configuration changes, delete the old RRD file and restart sensord.\n";
123
124static const char *appSyntax =
125  "  -a, --alarm-scan          -- only scan for alarms\n"
126  "  -s, --set                 -- execute set statements too (root only)\n"
127  "  -r, --rrd-file <file>     -- only update RRD file\n"
128  "  -c, --config-file <file>  -- configuration file (default sensors.conf)\n"
129  "  -d, --debug               -- display some debug information\n"
130  "  -v, --version             -- display version and exit\n"
131  "  -h, --help                -- display help and exit\n"
132  "\n"
133  "If no path is specified, a list of directories is examined for the config file;\n"
134  "specify the filename `-' to read the config file from stdin.\n"
135  "\n"
136  "If no chips are specified, all chip info will be printed.\n";
137
138static const char *daemonShortOptions = "i:l:t:f:r:c:p:advhg:";
139
140static const struct option daemonLongOptions[] = {
141  { "interval", required_argument, NULL, 'i' },
142  { "log-interval", required_argument, NULL, 'l' },
143  { "rrd-interval", required_argument, NULL, 't' },
144  { "syslog-facility", required_argument, NULL, 'f' },
145  { "rrd-file", required_argument, NULL, 'r' },
146  { "config-file", required_argument, NULL, 'c' },
147  { "pid-file", required_argument, NULL, 'p' },
148  { "rrd-cgi", required_argument, NULL, 'g' },
149  { "load-average", no_argument, NULL, 'a' },
150  { "debug", no_argument, NULL, 'd' },
151  { "version", no_argument, NULL, 'v' },
152  { "help", no_argument, NULL, 'h' },
153  { NULL, 0, NULL, 0 }
154};
155
156static const char *appShortOptions = "asr:c:dvh";
157
158static const struct option appLongOptions[] = {
159  { "alarm-scan", no_argument, NULL, 'a' },
160  { "set", no_argument, NULL, 's' },
161  { "rrd-file", required_argument, NULL, 'r' },
162  { "config-file", required_argument, NULL, 'c' },
163  { "debug", no_argument, NULL, 'd' },
164  { "version", no_argument, NULL, 'v' },
165  { "help", no_argument, NULL, 'h' },
166  { NULL, 0, NULL, 0 }
167};
168
169int
170parseArgs
171(int argc, char **argv) {
172  int c;
173  const char *shortOptions;
174  const struct option *longOptions;
175
176  isDaemon = (argv[0][strlen (argv[0]) - 1] == 'd');
177  shortOptions = isDaemon ? daemonShortOptions : appShortOptions;
178  longOptions = isDaemon ? daemonLongOptions : appLongOptions;
179
180  while ((c = getopt_long (argc, argv, shortOptions, longOptions, NULL)) != EOF) {
181    switch(c) {
182      case 'i':
183        if ((scanTime = parseTime (optarg)) < 0)
184          return -1;
185        break;
186      case 'l':
187        if ((logTime = parseTime (optarg)) < 0)
188          return -1;
189        break;
190      case 't':
191        if ((rrdTime = parseTime (optarg)) < 0)
192          return -1;
193        break;
194      case 'f':
195        if ((syslogFacility = parseFacility (optarg)) < 0)
196          return -1;
197        break;
198      case 'a':
199        if (isDaemon)
200          doLoad = 1;
201        else
202          doScan = 1;
203        break;
204      case 's':
205        doSet = 1;
206        break;
207      case 'c':
208        if ((sensorsCfgFile = strdup (optarg)) == NULL)
209          return -1;
210        break;
211      case 'p':
212        if ((pidFile = strdup (optarg)) == NULL)
213          return -1;
214        break;
215      case 'r':
216        if ((rrdFile = strdup (optarg)) == NULL)
217          return -1;
218        break;
219      case 'd':
220        debug = 1;
221        break;
222      case 'g':
223        doCGI = 1;
224        if ((cgiDir = strdup (optarg)) == NULL)
225          return -1;
226        break;
227      case 'v':
228        printf ("sensord version %s\n", version);
229        exit (EXIT_SUCCESS);
230        break;
231      case 'h':
232        printf ("Syntax: %s {options} {chips}\n%s", argv[0], isDaemon ? daemonSyntax : appSyntax);
233        exit (EXIT_SUCCESS);
234        break;
235      case ':':
236      case '?':
237        printf ("Try `%s --help' for more information.\n", argv[0]);
238        return -1;
239        break;
240      default:
241        fprintf (stderr, "Internal error while parsing options.\n");
242        return -1;
243        break;
244    }
245  }
246
247  if (doScan && doSet) {
248    fprintf (stderr, "Error: Incompatible --set and --alarm-scan.\n");
249    return -1;
250  }
251 
252  if (rrdFile && doSet) {
253    fprintf (stderr, "Error: Incompatible --set and --rrd-file.\n");
254    return -1;
255  }
256 
257  if (doScan && rrdFile) {
258    fprintf (stderr, "Error: Incompatible --rrd-file and --alarm-scan.\n");
259    return -1;
260  }
261
262  if (doCGI && !rrdFile) {
263    fprintf (stderr, "Error: Incompatible --rrd-cgi without --rrd-file.\n");
264    return -1;
265  }
266 
267  if (rrdFile && !rrdTime) {
268    fprintf (stderr, "Error: Incompatible --rrd-file without --rrd-interval.\n");
269    return -1;
270  }
271 
272  if (!logTime && !scanTime && !rrdFile) {
273    fprintf (stderr, "Error: No logging, alarm or RRD scanning.\n");
274    return -1;
275  }
276
277  return 0;
278}
279
280int
281parseChips
282(int argc, char **argv) {
283  if (optind == argc) {
284    chipNames[0].prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
285    chipNames[0].bus = SENSORS_CHIP_NAME_BUS_ANY;
286    chipNames[0].addr = SENSORS_CHIP_NAME_ADDR_ANY;
287    numChipNames = 1;
288  } else {
289    int i, n = argc - optind, err;
290    if (n > MAX_CHIP_NAMES) {
291      fprintf (stderr, "Too many chip names.\n");
292      return -1;
293    }
294    for (i = 0; i < n; ++ i) {
295      char *arg = argv[optind + i];
296      if ((err = sensors_parse_chip_name (arg, chipNames + i))) {
297        fprintf (stderr, "Invalid chip name `%s': %s\n", arg, sensors_strerror (err));
298        return -1;
299      }
300    }
301    numChipNames = n;
302  }
303  return 0;
304}
Note: See TracBrowser for help on using the browser.