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

Revision 4707, 9.4 KB (checked in by khali, 7 years ago)

Executing the set statements is an exclusive action.

  • 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 rrdNoAverage = 0;
43int syslogFacility = LOG_LOCAL4;
44int doScan = 0;
45int doSet = 0;
46int doCGI = 0;
47int doLoad = 0;
48int debug = 0;
49sensors_chip_name chipNames[MAX_CHIP_NAMES];
50int numChipNames = 0;
51
52static int
53parseTime
54(char *arg) {
55  char *end;
56  int value = strtoul (arg, &end, 10);
57  if ((end > arg) && (*end == 's')) {
58    ++ end;
59  } else if ((end > arg) && (*end == 'm')) {
60    value *= 60;
61    ++ end;
62  } else if ((end > arg) && (*end == 'h')) {
63    value *= 60 * 60;
64    ++ end;
65  }
66  if ((end == arg) || *end) {
67    fprintf (stderr, "Error parsing time value `%s'.\n", arg);
68    return -1;
69  }
70  return value;
71}
72
73static struct {
74  const char *name;
75  int id;
76} facilities[] = {
77  { "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 },
78  { "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 },
79  { "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 },
80  { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 },
81  { "daemon", LOG_DAEMON }, { "user", LOG_USER },
82  { NULL }
83};
84
85static int
86parseFacility
87(char *arg) {
88  int i = 0;
89  while (facilities[i].name && strcasecmp (arg, facilities[i].name))
90    ++ i;
91  if (!facilities[i].name) {
92    fprintf (stderr, "Error parsing facility value `%s'.\n", arg);
93    return -1;
94  }
95  return facilities[i].id;
96}
97
98static const char *daemonSyntax =
99  "  -i, --interval <time>     -- interval between scanning alarms (default 60s)\n"
100  "  -l, --log-interval <time> -- interval between logging sensors (default 30m)\n"
101  "  -t, --rrd-interval <time> -- interval between updating RRD file (default 5m)\n"
102  "  -T, --rrd-no-average      -- switch RRD in non-average mode\n"
103  "  -r, --rrd-file <file>     -- RRD file (default <none>)\n"
104  "  -c, --config-file <file>  -- configuration file (default sensors.conf)\n"
105  "  -p, --pid-file <file>     -- PID file (default /var/run/sensord.pid)\n"
106  "  -f, --syslog-facility <f> -- syslog facility to use (default local4)\n"
107  "  -g, --rrd-cgi <img-dir>   -- output an RRD CGI script and exit\n"
108  "  -a, --load-average        -- include load average in RRD file\n"
109  "  -d, --debug               -- display some debug information\n"
110  "  -v, --version             -- display version and exit\n"
111  "  -h, --help                -- display help and exit\n"
112  "\n"
113  "Specify a value of 0 for any interval to disable that operation;\n"
114  "for example, specify --log-interval 0 to only scan for alarms."
115  "\n"
116  "If no path is specified, a list of directories is examined for the config file;\n"
117  "specify the filename `-' to read the config file from stdin.\n"
118  "\n"
119  "If no chips are specified, all chip info will be printed.\n"
120  "\n"
121  "If unspecified, no RRD (round robin database) is used. If specified and the\n"
122  "file does not exist, it will be created. For RRD updates to be successful,\n"
123  "the RRD file configuration must EXACTLY match the sensors that are used. If\n"
124  "your configuration changes, delete the old RRD file and restart sensord.\n";
125
126static const char *appSyntax =
127  "  -a, --alarm-scan          -- only scan for alarms\n"
128  "  -s, --set                 -- execute set statements (root only)\n"
129  "  -r, --rrd-file <file>     -- only update RRD file\n"
130  "  -c, --config-file <file>  -- configuration file (default sensors.conf)\n"
131  "  -d, --debug               -- display some debug information\n"
132  "  -v, --version             -- display version and exit\n"
133  "  -h, --help                -- display help and exit\n"
134  "\n"
135  "If no path is specified, a list of directories is examined for the config file;\n"
136  "specify the filename `-' to read the config file from stdin.\n"
137  "\n"
138  "If no chips are specified, all chip info will be printed.\n";
139
140static const char *daemonShortOptions = "i:l:t:Tf:r:c:p:advhg:";
141
142static const struct option daemonLongOptions[] = {
143  { "interval", required_argument, NULL, 'i' },
144  { "log-interval", required_argument, NULL, 'l' },
145  { "rrd-interval", required_argument, NULL, 't' },
146  { "rrd-no-average", no_argument, NULL, 'T' },
147  { "syslog-facility", required_argument, NULL, 'f' },
148  { "rrd-file", required_argument, NULL, 'r' },
149  { "config-file", required_argument, NULL, 'c' },
150  { "pid-file", required_argument, NULL, 'p' },
151  { "rrd-cgi", required_argument, NULL, 'g' },
152  { "load-average", no_argument, NULL, 'a' },
153  { "debug", no_argument, NULL, 'd' },
154  { "version", no_argument, NULL, 'v' },
155  { "help", no_argument, NULL, 'h' },
156  { NULL, 0, NULL, 0 }
157};
158
159static const char *appShortOptions = "asr:c:dvh";
160
161static const struct option appLongOptions[] = {
162  { "alarm-scan", no_argument, NULL, 'a' },
163  { "set", no_argument, NULL, 's' },
164  { "rrd-file", required_argument, NULL, 'r' },
165  { "config-file", required_argument, NULL, 'c' },
166  { "debug", no_argument, NULL, 'd' },
167  { "version", no_argument, NULL, 'v' },
168  { "help", no_argument, NULL, 'h' },
169  { NULL, 0, NULL, 0 }
170};
171
172int
173parseArgs
174(int argc, char **argv) {
175  int c;
176  const char *shortOptions;
177  const struct option *longOptions;
178
179  isDaemon = (argv[0][strlen (argv[0]) - 1] == 'd');
180  shortOptions = isDaemon ? daemonShortOptions : appShortOptions;
181  longOptions = isDaemon ? daemonLongOptions : appLongOptions;
182
183  while ((c = getopt_long (argc, argv, shortOptions, longOptions, NULL)) != EOF) {
184    switch(c) {
185      case 'i':
186        if ((scanTime = parseTime (optarg)) < 0)
187          return -1;
188        break;
189      case 'l':
190        if ((logTime = parseTime (optarg)) < 0)
191          return -1;
192        break;
193      case 't':
194        if ((rrdTime = parseTime (optarg)) < 0)
195          return -1;
196        break;
197      case 'T':
198        rrdNoAverage = 1;
199        break;
200      case 'f':
201        if ((syslogFacility = parseFacility (optarg)) < 0)
202          return -1;
203        break;
204      case 'a':
205        if (isDaemon)
206          doLoad = 1;
207        else
208          doScan = 1;
209        break;
210      case 's':
211        doSet = 1;
212        break;
213      case 'c':
214        if ((sensorsCfgFile = strdup (optarg)) == NULL)
215          return -1;
216        break;
217      case 'p':
218        if ((pidFile = strdup (optarg)) == NULL)
219          return -1;
220        break;
221      case 'r':
222        if ((rrdFile = strdup (optarg)) == NULL)
223          return -1;
224        break;
225      case 'd':
226        debug = 1;
227        break;
228      case 'g':
229        doCGI = 1;
230        if ((cgiDir = strdup (optarg)) == NULL)
231          return -1;
232        break;
233      case 'v':
234        printf ("sensord version %s\n", version);
235        exit (EXIT_SUCCESS);
236        break;
237      case 'h':
238        printf ("Syntax: %s {options} {chips}\n%s", argv[0], isDaemon ? daemonSyntax : appSyntax);
239        exit (EXIT_SUCCESS);
240        break;
241      case ':':
242      case '?':
243        printf ("Try `%s --help' for more information.\n", argv[0]);
244        return -1;
245        break;
246      default:
247        fprintf (stderr, "Internal error while parsing options.\n");
248        return -1;
249        break;
250    }
251  }
252
253  if (doScan && doSet) {
254    fprintf (stderr, "Error: Incompatible --set and --alarm-scan.\n");
255    return -1;
256  }
257 
258  if (rrdFile && doSet) {
259    fprintf (stderr, "Error: Incompatible --set and --rrd-file.\n");
260    return -1;
261  }
262 
263  if (doScan && rrdFile) {
264    fprintf (stderr, "Error: Incompatible --rrd-file and --alarm-scan.\n");
265    return -1;
266  }
267
268  if (doCGI && !rrdFile) {
269    fprintf (stderr, "Error: Incompatible --rrd-cgi without --rrd-file.\n");
270    return -1;
271  }
272 
273  if (rrdFile && !rrdTime) {
274    fprintf (stderr, "Error: Incompatible --rrd-file without --rrd-interval.\n");
275    return -1;
276  }
277 
278  if (!logTime && !scanTime && !rrdFile) {
279    fprintf (stderr, "Error: No logging, alarm or RRD scanning.\n");
280    return -1;
281  }
282
283  return 0;
284}
285
286int
287parseChips
288(int argc, char **argv) {
289  if (optind == argc) {
290    chipNames[0].prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
291    chipNames[0].bus = SENSORS_CHIP_NAME_BUS_ANY;
292    chipNames[0].addr = SENSORS_CHIP_NAME_ADDR_ANY;
293    numChipNames = 1;
294  } else {
295    int i, n = argc - optind, err;
296    if (n > MAX_CHIP_NAMES) {
297      fprintf (stderr, "Too many chip names.\n");
298      return -1;
299    }
300    for (i = 0; i < n; ++ i) {
301      char *arg = argv[optind + i];
302      if ((err = sensors_parse_chip_name (arg, chipNames + i))) {
303        fprintf (stderr, "Invalid chip name `%s': %s\n", arg, sensors_strerror (err));
304        return -1;
305      }
306    }
307    numChipNames = n;
308  }
309  return 0;
310}
Note: See TracBrowser for help on using the browser.