Convert coding style in prog/sensord/ from gnu to kernel style.

git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@5678 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Andre Prendel committed 2009-03-09 15:32:03 +00:00
1 parent 531a6416f2
commit e065e827e9
7 files changed
+1327 -1250

No files matched your search

+234 -220
View File
@@ -51,257 +51,271 @@ int debug = 0;
sensors_chip_name chipNames[MAX_CHIP_NAMES];
int numChipNames = 0;
static int
parseTime
(char *arg) {
char *end;
int value = strtoul (arg, &end, 10);
if ((end > arg) && (*end == 's')) {
++ end;
} else if ((end > arg) && (*end == 'm')) {
value *= 60;
++ end;
} else if ((end > arg) && (*end == 'h')) {
value *= 60 * 60;
++ end;
}
if ((end == arg) || *end) {
fprintf (stderr, "Error parsing time value `%s'.\n", arg);
return -1;
}
return value;
static int parseTime(char *arg)
{
char *end;
int value = strtoul(arg, &end, 10);
if ((end > arg) && (*end == 's')) {
++ end;
} else if ((end > arg) && (*end == 'm')) {
value *= 60;
++ end;
} else if ((end > arg) && (*end == 'h')) {
value *= 60 * 60;
++ end;
}
if ((end == arg) || *end) {
fprintf(stderr, "Error parsing time value `%s'.\n", arg);
return -1;
}
return value;
}
static struct {
const char *name;
int id;
const char *name;
int id;
} facilities[] = {
{ "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 },
{ "daemon", LOG_DAEMON }, { "user", LOG_USER },
{ NULL, 0 }
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ "daemon", LOG_DAEMON },
{ "user", LOG_USER },
{ NULL, 0 }
};
static int
parseFacility
(char *arg) {
int i = 0;
while (facilities[i].name && strcasecmp (arg, facilities[i].name))
++ i;
if (!facilities[i].name) {
fprintf (stderr, "Error parsing facility value `%s'.\n", arg);
return -1;
}
return facilities[i].id;
static int parseFacility(char *arg)
{
int i = 0;
while (facilities[i].name && strcasecmp(arg, facilities[i].name))
++ i;
if (!facilities[i].name) {
fprintf(stderr, "Error parsing facility value `%s'.\n", arg);
return -1;
}
return facilities[i].id;
}
static const char *daemonSyntax =
" -i, --interval <time> -- interval between scanning alarms (default 60s)\n"
" -l, --log-interval <time> -- interval between logging sensors (default 30m)\n"
" -t, --rrd-interval <time> -- interval between updating RRD file (default 5m)\n"
" -T, --rrd-no-average -- switch RRD in non-average mode\n"
" -r, --rrd-file <file> -- RRD file (default <none>)\n"
" -c, --config-file <file> -- configuration file\n"
" -p, --pid-file <file> -- PID file (default /var/run/sensord.pid)\n"
" -f, --syslog-facility <f> -- syslog facility to use (default local4)\n"
" -g, --rrd-cgi <img-dir> -- output an RRD CGI script and exit\n"
" -a, --load-average -- include load average in RRD file\n"
" -d, --debug -- display some debug information\n"
" -v, --version -- display version and exit\n"
" -h, --help -- display help and exit\n"
"\n"
"Specify a value of 0 for any interval to disable that operation;\n"
"for example, specify --log-interval 0 to only scan for alarms."
"\n"
"Specify the filename `-' to read the config file from stdin.\n"
"\n"
"If no chips are specified, all chip info will be printed.\n"
"\n"
"If unspecified, no RRD (round robin database) is used. If specified and the\n"
"file does not exist, it will be created. For RRD updates to be successful,\n"
"the RRD file configuration must EXACTLY match the sensors that are used. If\n"
"your configuration changes, delete the old RRD file and restart sensord.\n";
" -i, --interval <time> -- interval between scanning alarms (default 60s)\n"
" -l, --log-interval <time> -- interval between logging sensors (default 30m)\n"
" -t, --rrd-interval <time> -- interval between updating RRD file (default 5m)\n"
" -T, --rrd-no-average -- switch RRD in non-average mode\n"
" -r, --rrd-file <file> -- RRD file (default <none>)\n"
" -c, --config-file <file> -- configuration file\n"
" -p, --pid-file <file> -- PID file (default /var/run/sensord.pid)\n"
" -f, --syslog-facility <f> -- syslog facility to use (default local4)\n"
" -g, --rrd-cgi <img-dir> -- output an RRD CGI script and exit\n"
" -a, --load-average -- include load average in RRD file\n"
" -d, --debug -- display some debug information\n"
" -v, --version -- display version and exit\n"
" -h, --help -- display help and exit\n"
"\n"
"Specify a value of 0 for any interval to disable that operation;\n"
"for example, specify --log-interval 0 to only scan for alarms."
"\n"
"Specify the filename `-' to read the config file from stdin.\n"
"\n"
"If no chips are specified, all chip info will be printed.\n"
"\n"
"If unspecified, no RRD (round robin database) is used. If specified and the\n"
"file does not exist, it will be created. For RRD updates to be successful,\n"
"the RRD file configuration must EXACTLY match the sensors that are used. If\n"
"your configuration changes, delete the old RRD file and restart sensord.\n";
static const char *appSyntax =
" -a, --alarm-scan -- only scan for alarms\n"
" -s, --set -- execute set statements (root only)\n"
" -r, --rrd-file <file> -- only update RRD file\n"
" -c, --config-file <file> -- configuration file\n"
" -d, --debug -- display some debug information\n"
" -v, --version -- display version and exit\n"
" -h, --help -- display help and exit\n"
"\n"
"Specify the filename `-' to read the config file from stdin.\n"
"\n"
"If no chips are specified, all chip info will be printed.\n";
" -a, --alarm-scan -- only scan for alarms\n"
" -s, --set -- execute set statements (root only)\n"
" -r, --rrd-file <file> -- only update RRD file\n"
" -c, --config-file <file> -- configuration file\n"
" -d, --debug -- display some debug information\n"
" -v, --version -- display version and exit\n"
" -h, --help -- display help and exit\n"
"\n"
"Specify the filename `-' to read the config file from stdin.\n"
"\n"
"If no chips are specified, all chip info will be printed.\n";
static const char *daemonShortOptions = "i:l:t:Tf:r:c:p:advhg:";
static const struct option daemonLongOptions[] = {
{ "interval", required_argument, NULL, 'i' },
{ "log-interval", required_argument, NULL, 'l' },
{ "rrd-interval", required_argument, NULL, 't' },
{ "rrd-no-average", no_argument, NULL, 'T' },
{ "syslog-facility", required_argument, NULL, 'f' },
{ "rrd-file", required_argument, NULL, 'r' },
{ "config-file", required_argument, NULL, 'c' },
{ "pid-file", required_argument, NULL, 'p' },
{ "rrd-cgi", required_argument, NULL, 'g' },
{ "load-average", no_argument, NULL, 'a' },
{ "debug", no_argument, NULL, 'd' },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 }
{ "interval", required_argument, NULL, 'i' },
{ "log-interval", required_argument, NULL, 'l' },
{ "rrd-interval", required_argument, NULL, 't' },
{ "rrd-no-average", no_argument, NULL, 'T' },
{ "syslog-facility", required_argument, NULL, 'f' },
{ "rrd-file", required_argument, NULL, 'r' },
{ "config-file", required_argument, NULL, 'c' },
{ "pid-file", required_argument, NULL, 'p' },
{ "rrd-cgi", required_argument, NULL, 'g' },
{ "load-average", no_argument, NULL, 'a' },
{ "debug", no_argument, NULL, 'd' },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 }
};
static const char *appShortOptions = "asr:c:dvh";
static const struct option appLongOptions[] = {
{ "alarm-scan", no_argument, NULL, 'a' },
{ "set", no_argument, NULL, 's' },
{ "rrd-file", required_argument, NULL, 'r' },
{ "config-file", required_argument, NULL, 'c' },
{ "debug", no_argument, NULL, 'd' },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 }
{ "alarm-scan", no_argument, NULL, 'a' },
{ "set", no_argument, NULL, 's' },
{ "rrd-file", required_argument, NULL, 'r' },
{ "config-file", required_argument, NULL, 'c' },
{ "debug", no_argument, NULL, 'd' },
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 }
};
int
parseArgs
(int argc, char **argv) {
int c;
const char *shortOptions;
const struct option *longOptions;
int parseArgs(int argc, char **argv)
{
int c;
const char *shortOptions;
const struct option *longOptions;
isDaemon = (argv[0][strlen (argv[0]) - 1] == 'd');
shortOptions = isDaemon ? daemonShortOptions : appShortOptions;
longOptions = isDaemon ? daemonLongOptions : appLongOptions;
isDaemon = (argv[0][strlen (argv[0]) - 1] == 'd');
shortOptions = isDaemon ? daemonShortOptions : appShortOptions;
longOptions = isDaemon ? daemonLongOptions : appLongOptions;
while ((c = getopt_long (argc, argv, shortOptions, longOptions, NULL)) != EOF) {
switch(c) {
case 'i':
if ((scanTime = parseTime (optarg)) < 0)
return -1;
break;
case 'l':
if ((logTime = parseTime (optarg)) < 0)
return -1;
break;
case 't':
if ((rrdTime = parseTime (optarg)) < 0)
return -1;
break;
case 'T':
rrdNoAverage = 1;
break;
case 'f':
if ((syslogFacility = parseFacility (optarg)) < 0)
return -1;
break;
case 'a':
if (isDaemon)
doLoad = 1;
else
doScan = 1;
break;
case 's':
doSet = 1;
break;
case 'c':
sensorsCfgFile = optarg;
break;
case 'p':
pidFile = optarg;
break;
case 'r':
rrdFile = optarg;
break;
case 'd':
debug = 1;
break;
case 'g':
doCGI = 1;
cgiDir = optarg;
break;
case 'v':
printf ("sensord version %s\n", LM_VERSION);
exit (EXIT_SUCCESS);
break;
case 'h':
printf ("Syntax: %s {options} {chips}\n%s", argv[0], isDaemon ? daemonSyntax : appSyntax);
exit (EXIT_SUCCESS);
break;
case ':':
case '?':
printf ("Try `%s --help' for more information.\n", argv[0]);
return -1;
break;
default:
fprintf (stderr, "Internal error while parsing options.\n");
return -1;
break;
}
}
while ((c = getopt_long(argc, argv, shortOptions, longOptions, NULL))
!= EOF) {
switch(c) {
case 'i':
if ((scanTime = parseTime(optarg)) < 0)
return -1;
break;
case 'l':
if ((logTime = parseTime(optarg)) < 0)
return -1;
break;
case 't':
if ((rrdTime = parseTime(optarg)) < 0)
return -1;
break;
case 'T':
rrdNoAverage = 1;
break;
case 'f':
if ((syslogFacility = parseFacility(optarg)) < 0)
return -1;
break;
case 'a':
if (isDaemon)
doLoad = 1;
else
doScan = 1;
break;
case 's':
doSet = 1;
break;
case 'c':
sensorsCfgFile = optarg;
break;
case 'p':
pidFile = optarg;
break;
case 'r':
rrdFile = optarg;
break;
case 'd':
debug = 1;
break;
case 'g':
doCGI = 1;
cgiDir = optarg;
break;
case 'v':
printf("sensord version %s\n", LM_VERSION);
exit(EXIT_SUCCESS);
break;
case 'h':
printf("Syntax: %s {options} {chips}\n%s", argv[0],
isDaemon ? daemonSyntax : appSyntax);
exit(EXIT_SUCCESS);
break;
case ':':
case '?':
printf("Try `%s --help' for more information.\n",
argv[0]);
return -1;
break;
default:
fprintf(stderr,
"Internal error while parsing options.\n");
return -1;
break;
}
}
if (doScan && doSet) {
fprintf (stderr, "Error: Incompatible --set and --alarm-scan.\n");
return -1;
}
if (doScan && doSet) {
fprintf(stderr,
"Error: Incompatible --set and --alarm-scan.\n");
return -1;
}
if (rrdFile && doSet) {
fprintf (stderr, "Error: Incompatible --set and --rrd-file.\n");
return -1;
}
if (rrdFile && doSet) {
fprintf(stderr,
"Error: Incompatible --set and --rrd-file.\n");
return -1;
}
if (doScan && rrdFile) {
fprintf (stderr, "Error: Incompatible --rrd-file and --alarm-scan.\n");
return -1;
}
if (doScan && rrdFile) {
fprintf(stderr,
"Error: Incompatible --rrd-file and --alarm-scan.\n");
return -1;
}
if (doCGI && !rrdFile) {
fprintf (stderr, "Error: Incompatible --rrd-cgi without --rrd-file.\n");
return -1;
}
if (doCGI && !rrdFile) {
fprintf(stderr,
"Error: Incompatible --rrd-cgi without --rrd-file.\n");
return -1;
}
if (rrdFile && !rrdTime) {
fprintf (stderr, "Error: Incompatible --rrd-file without --rrd-interval.\n");
return -1;
}
if (rrdFile && !rrdTime) {
fprintf(stderr,
"Error: Incompatible --rrd-file without --rrd-interval.\n");
return -1;
}
if (!logTime && !scanTime && !rrdFile) {
fprintf (stderr, "Error: No logging, alarm or RRD scanning.\n");
return -1;
}
if (!logTime && !scanTime && !rrdFile) {
fprintf(stderr,
"Error: No logging, alarm or RRD scanning.\n");
return -1;
}
return 0;
return 0;
}
int
parseChips
(int argc, char **argv) {
if (optind == argc) {
chipNames[0].prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
chipNames[0].bus.type = SENSORS_BUS_TYPE_ANY;
chipNames[0].bus.nr = SENSORS_BUS_NR_ANY;
chipNames[0].addr = SENSORS_CHIP_NAME_ADDR_ANY;
numChipNames = 1;
} else {
int i, n = argc - optind, err;
if (n > MAX_CHIP_NAMES) {
fprintf (stderr, "Too many chip names.\n");
return -1;
}
for (i = 0; i < n; ++ i) {
char *arg = argv[optind + i];
if ((err = sensors_parse_chip_name (arg, chipNames + i))) {
fprintf (stderr, "Invalid chip name `%s': %s\n", arg, sensors_strerror (err));
return -1;
}
}
numChipNames = n;
}
return 0;
int parseChips(int argc, char **argv)
{
if (optind == argc) {
chipNames[0].prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
chipNames[0].bus.type = SENSORS_BUS_TYPE_ANY;
chipNames[0].bus.nr = SENSORS_BUS_NR_ANY;
chipNames[0].addr = SENSORS_CHIP_NAME_ADDR_ANY;
numChipNames = 1;
} else {
int i, n = argc - optind, err;
if (n > MAX_CHIP_NAMES) {
fprintf(stderr, "Too many chip names.\n");
return -1;
}
for (i = 0; i < n; ++ i) {
char *arg = argv[optind + i];
if ((err = sensors_parse_chip_name(arg,
chipNames + i))) {
fprintf(stderr,
"Invalid chip name `%s': %s\n", arg,
sensors_strerror(err));
return -1;
}
}
numChipNames = n;
}
return 0;
}
+285 -276
View File
@@ -33,291 +33,300 @@
static char buff[4096];
static const char *
fmtExtra
(int alarm, int beep) {
if (alarm)
sprintf (buff + strlen (buff), " [ALARM]");
if (beep)
sprintf (buff + strlen (buff), " (beep)");
return buff;
}
static const char *
fmtTemps_1
(const double values[], int alarm, int beep) {
sprintf (buff, "%.1f C (limit = %.1f C, hysteresis = %.1f C)", values[0], values[1], values[2]);
return fmtExtra (alarm, beep);
}
static const char *
fmtTemps_minmax_1
(const double values[], int alarm, int beep) {
sprintf (buff, "%.1f C (min = %.1f C, max = %.1f C)", values[0], values[1], values[2]);
return fmtExtra (alarm, beep);
}
static const char *
fmtTemp_only
(const double values[], int alarm, int beep) {
sprintf (buff, "%.1f C", values[0]);
return fmtExtra (alarm, beep);
}
static const char *
fmtVolt_2
(const double values[], int alarm, int beep) {
sprintf (buff, "%+.2f V", values[0]);
return fmtExtra (alarm, beep);
}
static const char *
fmtVolt_3
(const double values[], int alarm, int beep) {
sprintf (buff, "%+.3f V", values[0]);
return fmtExtra (alarm, beep);
}
static const char *
fmtVolts_2
(const double values[], int alarm, int beep) {
sprintf (buff, "%+.2f V (min = %+.2f V, max = %+.2f V)", values[0], values[1], values[2]);
return fmtExtra (alarm, beep);
}
static const char *
fmtFans_0
(const double values[], int alarm, int beep) {
sprintf (buff, "%.0f RPM (min = %.0f RPM, div = %.0f)", values[0], values[1], values[2]);
return fmtExtra (alarm, beep);
}
static const char *
fmtFans_nodiv_0
(const double values[], int alarm, int beep) {
sprintf (buff, "%.0f RPM (min = %.0f RPM)", values[0], values[1]);
return fmtExtra (alarm, beep);
}
static const char *
fmtFan_only
(const double values[], int alarm, int beep) {
sprintf (buff, "%.0f RPM", values[0]);
return fmtExtra (alarm, beep);
}
static const char *
fmtSoundAlarm
(const double values[], int alarm, int beep) {
sprintf (buff, "Sound alarm %s", (values[0] < 0.5) ? "disabled" : "enabled");
return fmtExtra (alarm, beep);
}
static const char *
rrdF0
(const double values[]) {
sprintf (buff, "%.0f", values[0]);
return buff;
}
static const char *
rrdF1
(const double values[]) {
sprintf (buff, "%.1f", values[0]);
return buff;
}
static const char *
rrdF2
(const double values[]) {
sprintf (buff, "%.2f", values[0]);
return buff;
}
static const char *
rrdF3
(const double values[]) {
sprintf (buff, "%.3f", values[0]);
return buff;
}
static void fillChipVoltage (FeatureDescriptor *voltage,
const sensors_chip_name *name,
const sensors_feature *feature)
static const char *fmtExtra(int alarm, int beep)
{
const sensors_subfeature *sf, *sfmin, *sfmax;
int pos = 0;
if (alarm)
sprintf(buff + strlen(buff), " [ALARM]");
if (beep)
sprintf(buff + strlen(buff), " (beep)");
return buff;
}
voltage->rrd = rrdF2;
voltage->type = DataType_voltage;
static const char *fmtTemps_1(const double values[], int alarm, int beep)
{
sprintf(buff, "%.1f C (limit = %.1f C, hysteresis = %.1f C)",
values[0], values[1], values[2]);
return fmtExtra(alarm, beep);
}
sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_INPUT);
if (sf)
voltage->dataNumbers[pos++] = sf->number;
static const char *fmtTemps_minmax_1(const double values[], int alarm,
int beep) {
sprintf(buff, "%.1f C (min = %.1f C, max = %.1f C)", values[0],
values[1], values[2]);
return fmtExtra(alarm, beep);
}
sfmin = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MIN);
sfmax = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MAX);
if (sfmin && sfmax) {
voltage->format = fmtVolts_2;
voltage->dataNumbers[pos++] = sfmin->number;
voltage->dataNumbers[pos++] = sfmax->number;
} else {
voltage->format = fmtVolt_2;
}
static const char *fmtTemp_only(const double values[], int alarm, int beep)
{
sprintf(buff, "%.1f C", values[0]);
return fmtExtra(alarm, beep);
}
static const char *fmtVolt_2(const double values[], int alarm, int beep)
{
sprintf(buff, "%+.2f V", values[0]);
return fmtExtra(alarm, beep);
}
static const char *fmtVolt_3(const double values[], int alarm, int beep)
{
sprintf(buff, "%+.3f V", values[0]);
return fmtExtra(alarm, beep);
}
static const char *fmtVolts_2(const double values[], int alarm, int beep)
{
sprintf(buff, "%+.2f V (min = %+.2f V, max = %+.2f V)", values[0],
values[1], values[2]);
return fmtExtra(alarm, beep);
}
static const char *fmtFans_0(const double values[], int alarm, int beep)
{
sprintf(buff, "%.0f RPM (min = %.0f RPM, div = %.0f)", values[0],
values[1], values[2]);
return fmtExtra(alarm, beep);
}
static const char *fmtFans_nodiv_0(const double values[], int alarm, int beep)
{
sprintf(buff, "%.0f RPM (min = %.0f RPM)", values[0], values[1]);
return fmtExtra(alarm, beep);
}
static const char *fmtFan_only(const double values[], int alarm, int beep)
{
sprintf(buff, "%.0f RPM", values[0]);
return fmtExtra(alarm, beep);
}
static const char *fmtSoundAlarm(const double values[], int alarm, int beep)
{
sprintf(buff, "Sound alarm %s",
(values[0] < 0.5) ? "disabled" : "enabled");
return fmtExtra(alarm, beep);
}
static const char *rrdF0(const double values[])
{
sprintf(buff, "%.0f", values[0]);
return buff;
}
static const char *rrdF1(const double values[])
{
sprintf(buff, "%.1f", values[0]);
return buff;
}
static const char *rrdF2(const double values[])
{
sprintf(buff, "%.2f", values[0]);
return buff;
}
static const char *rrdF3(const double values[])
{
sprintf(buff, "%.3f", values[0]);
return buff;
}
static void fillChipVoltage(FeatureDescriptor *voltage,
const sensors_chip_name *name,
const sensors_feature *feature)
{
const sensors_subfeature *sf, *sfmin, *sfmax;
int pos = 0;
voltage->rrd = rrdF2;
voltage->type = DataType_voltage;
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_INPUT);
if (sf)
voltage->dataNumbers[pos++] = sf->number;
sfmin = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_MIN);
sfmax = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_MAX);
if (sfmin && sfmax) {
voltage->format = fmtVolts_2;
voltage->dataNumbers[pos++] = sfmin->number;
voltage->dataNumbers[pos++] = sfmax->number;
} else {
voltage->format = fmtVolt_2;
}
/* terminate the list */
voltage->dataNumbers[pos] = -1;
/* terminate the list */
voltage->dataNumbers[pos] = -1;
/* alarm if applicable */
if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_ALARM)) ||
(sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MIN_ALARM)) ||
(sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_MAX_ALARM))) {
voltage->alarmNumber = sf->number;
} else {
voltage->alarmNumber = -1;
}
/* beep if applicable */
if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_IN_BEEP))) {
voltage->beepNumber = sf->number;
} else {
voltage->beepNumber = -1;
}
/* alarm if applicable */
if ((sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_ALARM)) ||
(sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_MIN_ALARM)) ||
(sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_MAX_ALARM))) {
voltage->alarmNumber = sf->number;
} else {
voltage->alarmNumber = -1;
}
/* beep if applicable */
if ((sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_IN_BEEP))) {
voltage->beepNumber = sf->number;
} else {
voltage->beepNumber = -1;
}
}
static void fillChipTemperature (FeatureDescriptor *temperature,
const sensors_chip_name *name,
const sensors_feature *feature)
static void fillChipTemperature(FeatureDescriptor *temperature,
const sensors_chip_name *name,
const sensors_feature *feature)
{
const sensors_subfeature *sf, *sfmin, *sfmax, *sfhyst;
int pos = 0;
const sensors_subfeature *sf, *sfmin, *sfmax, *sfhyst;
int pos = 0;
temperature->rrd = rrdF1;
temperature->type = DataType_temperature;
temperature->rrd = rrdF1;
temperature->type = DataType_temperature;
sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_INPUT);
if (sf)
temperature->dataNumbers[pos++] = sf->number;
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_INPUT);
if (sf)
temperature->dataNumbers[pos++] = sf->number;
sfmin = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MIN);
sfmax = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MAX);
sfhyst = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MAX_HYST);
if (sfmin && sfmax) {
temperature->format = fmtTemps_minmax_1;
temperature->dataNumbers[pos++] = sfmin->number;
temperature->dataNumbers[pos++] = sfmax->number;
} else if (sfmax && sfhyst) {
temperature->format = fmtTemps_1;
temperature->dataNumbers[pos++] = sfmax->number;
temperature->dataNumbers[pos++] = sfhyst->number;
} else {
temperature->format = fmtTemp_only;
}
sfmin = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_MIN);
sfmax = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_MAX);
sfhyst = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_MAX_HYST);
if (sfmin && sfmax) {
temperature->format = fmtTemps_minmax_1;
temperature->dataNumbers[pos++] = sfmin->number;
temperature->dataNumbers[pos++] = sfmax->number;
} else if (sfmax && sfhyst) {
temperature->format = fmtTemps_1;
temperature->dataNumbers[pos++] = sfmax->number;
temperature->dataNumbers[pos++] = sfhyst->number;
} else {
temperature->format = fmtTemp_only;
}
/* terminate the list */
temperature->dataNumbers[pos] = -1;
/* terminate the list */
temperature->dataNumbers[pos] = -1;
/* alarm if applicable */
if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_ALARM)) ||
(sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_MAX_ALARM))) {
temperature->alarmNumber = sf->number;
} else {
temperature->alarmNumber = -1;
}
/* beep if applicable */
if ((sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_TEMP_BEEP))) {
temperature->beepNumber = sf->number;
} else {
temperature->beepNumber = -1;
}
/* alarm if applicable */
if ((sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_ALARM)) ||
(sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_MAX_ALARM))) {
temperature->alarmNumber = sf->number;
} else {
temperature->alarmNumber = -1;
}
/* beep if applicable */
if ((sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_TEMP_BEEP))) {
temperature->beepNumber = sf->number;
} else {
temperature->beepNumber = -1;
}
}
static void fillChipFan (FeatureDescriptor *fan,
const sensors_chip_name *name,
const sensors_feature *feature)
static void fillChipFan(FeatureDescriptor *fan,
const sensors_chip_name *name,
const sensors_feature *feature)
{
const sensors_subfeature *sf, *sfmin, *sfdiv;
int pos = 0;
const sensors_subfeature *sf, *sfmin, *sfdiv;
int pos = 0;
fan->rrd = rrdF0;
fan->type = DataType_rpm;
fan->rrd = rrdF0;
fan->type = DataType_rpm;
sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_INPUT);
if (sf)
fan->dataNumbers[pos++] = sf->number;
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_FAN_INPUT);
if (sf)
fan->dataNumbers[pos++] = sf->number;
sfmin = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_MIN);
if (sfmin) {
fan->dataNumbers[pos++] = sfmin->number;
sfdiv = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_DIV);
if (sfdiv) {
fan->format = fmtFans_0;
fan->dataNumbers[pos++] = sfdiv->number;
} else {
fan->format = fmtFans_nodiv_0;
}
} else {
fan->format = fmtFan_only;
}
sfmin = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_FAN_MIN);
if (sfmin) {
fan->dataNumbers[pos++] = sfmin->number;
sfdiv = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_FAN_DIV);
if (sfdiv) {
fan->format = fmtFans_0;
fan->dataNumbers[pos++] = sfdiv->number;
} else {
fan->format = fmtFans_nodiv_0;
}
} else {
fan->format = fmtFan_only;
}
/* terminate the list */
fan->dataNumbers[pos] = -1;
/* terminate the list */
fan->dataNumbers[pos] = -1;
/* alarm if applicable */
sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_ALARM);
if (sf) {
fan->alarmNumber = sf->number;
} else {
fan->alarmNumber = -1;
}
/* beep if applicable */
sf = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_FAN_BEEP);
if (sf) {
fan->beepNumber = sf->number;
} else {
fan->beepNumber = -1;
}
/* alarm if applicable */
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_FAN_ALARM);
if (sf) {
fan->alarmNumber = sf->number;
} else {
fan->alarmNumber = -1;
}
/* beep if applicable */
sf = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_FAN_BEEP);
if (sf) {
fan->beepNumber = sf->number;
} else {
fan->beepNumber = -1;
}
}
static void fillChipVid (FeatureDescriptor *vid,
const sensors_chip_name *name,
const sensors_feature *feature)
static void fillChipVid(FeatureDescriptor *vid,
const sensors_chip_name *name,
const sensors_feature *feature)
{
const sensors_subfeature *sub;
const sensors_subfeature *sub;
sub = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_VID);
if (!sub)
return;
sub = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_VID);
if (!sub)
return;
vid->format = fmtVolt_3;
vid->rrd = rrdF3;
vid->type = DataType_voltage;
vid->alarmNumber = -1;
vid->beepNumber = -1;
vid->dataNumbers[0] = sub->number;
vid->dataNumbers[1] = -1;
vid->format = fmtVolt_3;
vid->rrd = rrdF3;
vid->type = DataType_voltage;
vid->alarmNumber = -1;
vid->beepNumber = -1;
vid->dataNumbers[0] = sub->number;
vid->dataNumbers[1] = -1;
}
static void fillChipBeepEnable (FeatureDescriptor *beepen,
const sensors_chip_name *name,
const sensors_feature *feature)
static void fillChipBeepEnable(FeatureDescriptor *beepen,
const sensors_chip_name *name,
const sensors_feature *feature)
{
const sensors_subfeature *sub;
const sensors_subfeature *sub;
sub = sensors_get_subfeature(name, feature, SENSORS_SUBFEATURE_BEEP_ENABLE);
if (!sub)
return;
sub = sensors_get_subfeature(name, feature,
SENSORS_SUBFEATURE_BEEP_ENABLE);
if (!sub)
return;
beepen->format = fmtSoundAlarm;
beepen->rrd = rrdF0;
beepen->type = DataType_other;
beepen->alarmNumber = -1;
beepen->beepNumber = -1;
beepen->dataNumbers[0] = sub->number;
beepen->dataNumbers[1] = -1;
beepen->format = fmtSoundAlarm;
beepen->rrd = rrdF0;
beepen->type = DataType_other;
beepen->alarmNumber = -1;
beepen->beepNumber = -1;
beepen->dataNumbers[0] = sub->number;
beepen->dataNumbers[1] = -1;
}
static
FeatureDescriptor * generateChipFeatures (const sensors_chip_name *chip)
static FeatureDescriptor * generateChipFeatures(const sensors_chip_name *chip)
{
int nr, count = 1;
const sensors_feature *sensor;
@@ -366,38 +375,38 @@ FeatureDescriptor * generateChipFeatures (const sensors_chip_name *chip)
ChipDescriptor * knownChips;
int initKnownChips (void)
int initKnownChips(void)
{
int nr, count = 1;
const sensors_chip_name *name;
int nr, count = 1;
const sensors_chip_name *name;
/* How many chips do we have? */
nr = 0;
while ((name = sensors_get_detected_chips(NULL, &nr)))
count++;
/* How many chips do we have? */
nr = 0;
while ((name = sensors_get_detected_chips(NULL, &nr)))
count++;
/* Allocate the memory we need */
knownChips = calloc(count, sizeof(ChipDescriptor));
if (!knownChips)
return 1;
/* Allocate the memory we need */
knownChips = calloc(count, sizeof(ChipDescriptor));
if (!knownChips)
return 1;
/* Fill in the data structures */
count = 0;
nr = 0;
while ((name = sensors_get_detected_chips(NULL, &nr))) {
knownChips[count].name = name;
if ((knownChips[count].features = generateChipFeatures(name)))
count++;
}
/* Fill in the data structures */
count = 0;
nr = 0;
while ((name = sensors_get_detected_chips(NULL, &nr))) {
knownChips[count].name = name;
if ((knownChips[count].features = generateChipFeatures(name)))
count++;
}
return 0;
return 0;
}
void freeKnownChips (void)
void freeKnownChips(void)
{
int index0;
int index0;
for (index0 = 0; knownChips[index0].features; index0++)
free (knownChips[index0].features);
free (knownChips);
for (index0 = 0; knownChips[index0].features; index0++)
free(knownChips[index0].features);
free(knownChips);
}
+60 -57
View File
@@ -32,69 +32,72 @@
#include "sensord.h"
#include "lib/error.h"
static int
loadConfig
(const char *cfgPath, int reload) {
struct stat stats;
FILE *cfg = NULL;
int ret = 0;
static int loadConfig(const char *cfgPath, int reload)
{
struct stat stats;
FILE *cfg = NULL;
int ret = 0;
if (cfgPath && !strcmp (cfgPath, "-")) {
if (!reload) {
if ((ret = sensors_init (stdin))) {
sensorLog (LOG_ERR, "Error loading sensors configuration file <stdin>: %s",
sensors_strerror (ret));
ret = 12;
}
}
} else if (cfgPath && stat (cfgPath, &stats) < 0) {
sensorLog (LOG_ERR, "Error stating sensors configuration file: %s", cfgPath);
ret = 10;
} else {
if (reload) {
sensorLog (LOG_INFO, "configuration reloading");
sensors_cleanup ();
}
if (cfgPath && !(cfg = fopen (cfgPath, "r"))) {
sensorLog (LOG_ERR, "Error opening sensors configuration file: %s", cfgPath);
ret = 11;
} else if ((ret = sensors_init (cfg))) {
sensorLog (LOG_ERR, "Error loading sensors configuration file %s: %s",
cfgPath ? cfgPath : "(default)", sensors_strerror (ret));
ret = 11;
}
if (cfg)
fclose (cfg);
}
if (cfgPath && !strcmp(cfgPath, "-")) {
if (!reload) {
if ((ret = sensors_init(stdin))) {
sensorLog(LOG_ERR,
"Error loading sensors configuration file <stdin>: %s",
sensors_strerror(ret));
ret = 12;
}
}
} else if (cfgPath && stat(cfgPath, &stats) < 0) {
sensorLog(LOG_ERR,
"Error stating sensors configuration file: %s",
cfgPath);
ret = 10;
} else {
if (reload) {
sensorLog(LOG_INFO, "configuration reloading");
sensors_cleanup();
}
if (cfgPath && !(cfg = fopen(cfgPath, "r"))) {
sensorLog(LOG_ERR,
"Error opening sensors configuration file: %s",
cfgPath);
ret = 11;
} else if ((ret = sensors_init(cfg))) {
sensorLog(LOG_ERR,
"Error loading sensors configuration file %s: %s",
cfgPath ? cfgPath : "(default)",
sensors_strerror(ret));
ret = 11;
}
if (cfg)
fclose(cfg);
}
return ret;
return ret;
}
int
loadLib
(const char *cfgPath) {
int ret;
ret = loadConfig (cfgPath, 0);
if (!ret)
ret = initKnownChips ();
return ret;
int loadLib(const char *cfgPath)
{
int ret;
ret = loadConfig(cfgPath, 0);
if (!ret)
ret = initKnownChips();
return ret;
}
int
reloadLib
(const char *cfgPath) {
int ret;
freeKnownChips ();
ret = loadConfig (cfgPath, 1);
if (!ret)
ret = initKnownChips ();
return ret;
int reloadLib(const char *cfgPath)
{
int ret;
freeKnownChips();
ret = loadConfig(cfgPath, 1);
if (!ret)
ret = initKnownChips();
return ret;
}
int
unloadLib
(void) {
freeKnownChips ();
sensors_cleanup ();
return 0;
int unloadLib(void)
{
freeKnownChips();
sensors_cleanup();
return 0;
}
+368 -335
View File
@@ -67,386 +67,419 @@ static char rrdLabels[MAX_RRD_SENSORS][RAW_LABEL_LENGTH + 1];
#define LOADAVG "loadavg"
#define LOAD_AVERAGE "Load Average"
typedef int (*FeatureFN) (void *data, const char *rawLabel, const char *label, const FeatureDescriptor *feature);
typedef int (*FeatureFN) (void *data, const char *rawLabel, const char *label,
const FeatureDescriptor *feature);
static char
rrdNextChar
(char c) {
if (c == '9') {
return 'A';
} else if (c == 'Z') {
return 'a';
} else if (c == 'z') {
return 0;
} else {
return c + 1;
}
static char rrdNextChar(char c)
{
if (c == '9') {
return 'A';
} else if (c == 'Z') {
return 'a';
} else if (c == 'z') {
return 0;
} else {
return c + 1;
}
}
static void
rrdCheckLabel
(const char *rawLabel, int index0) {
char *buffer = rrdLabels[index0];
int i, j, okay;
static void rrdCheckLabel(const char *rawLabel, int index0)
{
char *buffer = rrdLabels[index0];
int i, j, okay;
i = 0;
while ((i < RAW_LABEL_LENGTH) && rawLabel[i]) { /* contrain raw label to [A-Za-z0-9_] */
char c = rawLabel[i];
if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')) || (c == '_')) {
buffer[i] = c;
} else {
buffer[i] = '_';
}
++ i;
}
buffer[i] = '\0';
i = 0;
/* contrain raw label to [A-Za-z0-9_] */
while ((i < RAW_LABEL_LENGTH) && rawLabel[i]) {
char c = rawLabel[i];
if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))
|| ((c >= '0') && (c <= '9')) || (c == '_')) {
buffer[i] = c;
} else {
buffer[i] = '_';
}
++ i;
}
buffer[i] = '\0';
j = 0;
okay = (i > 0);
while (okay && (j < index0)) /* locate duplicates */
okay = strcmp (rrdLabels[j ++], buffer);
j = 0;
okay = (i > 0);
while (!okay) { /* uniquify duplicate labels with _? or _?? */
if (!buffer[i]) {
if (i > RAW_LABEL_LENGTH - 3)
i = RAW_LABEL_LENGTH - 3;
buffer[i] = '_';
buffer[i + 1] = '0';
buffer[i + 2] = '\0';
} else if (!buffer[i + 2]) {
if (!(buffer[i + 1] = rrdNextChar (buffer[i + 1]))) {
buffer[i + 1] = '0';
buffer[i + 2] = '0';
buffer[i + 3] = '\0';
}
} else {
if (!(buffer[i + 2] = rrdNextChar (buffer[i + 2]))) {
buffer[i + 1] = rrdNextChar (buffer[i + 1]);
buffer[i + 2] = '0';
}
}
j = 0;
okay = 1;
while (okay && (j < index0))
okay = strcmp (rrdLabels[j ++], buffer);
}
/* locate duplicates */
while (okay && (j < index0))
okay = strcmp(rrdLabels[j ++], buffer);
/* uniquify duplicate labels with _? or _?? */
while (!okay) {
if (!buffer[i]) {
if (i > RAW_LABEL_LENGTH - 3)
i = RAW_LABEL_LENGTH - 3;
buffer[i] = '_';
buffer[i + 1] = '0';
buffer[i + 2] = '\0';
} else if (!buffer[i + 2]) {
if (!(buffer[i + 1] = rrdNextChar(buffer[i + 1]))) {
buffer[i + 1] = '0';
buffer[i + 2] = '0';
buffer[i + 3] = '\0';
}
} else {
if (!(buffer[i + 2] = rrdNextChar(buffer[i + 2]))) {
buffer[i + 1] = rrdNextChar(buffer[i + 1]);
buffer[i + 2] = '0';
}
}
j = 0;
okay = 1;
while (okay && (j < index0))
okay = strcmp(rrdLabels[j ++], buffer);
}
}
static int
applyToFeatures
(FeatureFN fn, void *data) {
const sensors_chip_name *chip;
int i, j, ret = 0, num = 0;
static int applyToFeatures(FeatureFN fn, void *data)
{
const sensors_chip_name *chip;
int i, j, ret = 0, num = 0;
for (j = 0; (ret == 0) && (j < numChipNames); ++ j) {
i = 0;
while ((ret == 0) && ((chip = sensors_get_detected_chips (&chipNames[j], &i)) != NULL)) {
int index0, chipindex = -1;
for (index0 = 0; knownChips[index0].features; ++ index0)
/* Trick: we compare addresses here. We know it works because both
pointers were returned by sensors_get_detected_chips(), so they
refer to libsensors internal structures, which do not move. */
if (knownChips[index0].name == chip) {
chipindex = index0;
break;
}
if (chipindex >= 0) {
const ChipDescriptor *descriptor = &knownChips[chipindex];
const FeatureDescriptor *features = descriptor->features;
for (j = 0; (ret == 0) && (j < numChipNames); ++ j) {
i = 0;
while ((ret == 0) && ((chip = sensors_get_detected_chips(&chipNames[j], &i)) != NULL)) {
int index0, chipindex = -1;
for (index0 = 0; (ret == 0) && (num < MAX_RRD_SENSORS) && features[index0].format; ++ index0) {
const FeatureDescriptor *feature = features + index0;
const char *rawLabel = feature->feature->name;
char *label = NULL;
/* Trick: we compare addresses here. We know it works
* because both pointers were returned by
* sensors_get_detected_chips(), so they refer to
* libsensors internal structures, which do not move.
*/
for (index0 = 0; knownChips[index0].features; ++index0)
if (knownChips[index0].name == chip) {
chipindex = index0;
break;
}
if (chipindex >= 0) {
const ChipDescriptor *descriptor = &knownChips[chipindex];
const FeatureDescriptor *features = descriptor->features;
if (!(label = sensors_get_label (chip, feature->feature))) {
sensorLog (LOG_ERR, "Error getting sensor label: %s/%s", chip->prefix, rawLabel);
ret = -1;
} else {
rrdCheckLabel (rawLabel, num);
ret = fn (data, rrdLabels[num], label, feature);
++ num;
}
if (label)
free (label);
}
}
}
}
for (index0 = 0; (ret == 0) && (num < MAX_RRD_SENSORS) && features[index0].format; ++index0) {
const FeatureDescriptor *feature = features + index0;
const char *rawLabel = feature->feature->name;
char *label = NULL;
return ret;
if (!(label = sensors_get_label(chip, feature->feature))) {
sensorLog(LOG_ERR, "Error getting sensor label: %s/%s", chip->prefix, rawLabel);
ret = -1;
} else {
rrdCheckLabel(rawLabel, num);
ret = fn(data,
rrdLabels[num],
label, feature);
++ num;
}
if (label)
free(label);
}
}
}
}
return ret;
}
struct ds {
int num;
const char **argv;
int num;
const char **argv;
};
static int
rrdGetSensors_DS
(void *_data, const char *rawLabel, const char *label, const FeatureDescriptor *feature) {
(void) label; /* no warning */
if (!feature || feature->rrd) {
struct ds *data = (struct ds *) _data;
char *ptr = rrdBuff + data->num * RRD_BUFF;
const char *min, *max;
data->argv[data->num ++] = ptr;
switch (feature ? feature->type : DataType_other) { /* arbitrary sanity limits */
case DataType_voltage:
min="-25";
max="25";
break;
case DataType_rpm:
min = "0";
max = "12000";
break;
case DataType_temperature:
min = "-100";
max = "250";
break;
default:
min = max = "U";
break;
}
sprintf (ptr, "DS:%s:GAUGE:%d:%s:%s", rawLabel, /* number of seconds downtime during which average be used instead of unknown */ 5 * rrdTime, min, max);
}
return 0;
static int rrdGetSensors_DS(void *_data, const char *rawLabel,
const char *label,
const FeatureDescriptor *feature)
{
(void) label; /* no warning */
if (!feature || feature->rrd) {
struct ds *data = (struct ds *) _data;
char *ptr = rrdBuff + data->num * RRD_BUFF;
const char *min, *max;
data->argv[data->num ++] = ptr;
/* arbitrary sanity limits */
switch (feature ? feature->type : DataType_other) {
case DataType_voltage:
min="-25";
max="25";
break;
case DataType_rpm:
min = "0";
max = "12000";
break;
case DataType_temperature:
min = "-100";
max = "250";
break;
default:
min = max = "U";
break;
}
/*
* number of seconds downtime during which average be used
* instead of unknown
*/
sprintf(ptr, "DS:%s:GAUGE:%d:%s:%s", rawLabel, 5 * rrdTime,
min, max);
}
return 0;
}
static int
rrdGetSensors
(const char **argv) {
int ret = 0;
struct ds data = { 0, argv};
ret = applyToFeatures (rrdGetSensors_DS, &data);
if (!ret && doLoad)
ret = rrdGetSensors_DS (&data, LOADAVG, LOAD_AVERAGE, NULL);
return ret ? -1 : data.num;
static int rrdGetSensors(const char **argv)
{
int ret = 0;
struct ds data = { 0, argv};
ret = applyToFeatures(rrdGetSensors_DS, &data);
if (!ret && doLoad)
ret = rrdGetSensors_DS(&data, LOADAVG, LOAD_AVERAGE, NULL);
return ret ? -1 : data.num;
}
int
rrdInit
(void) {
int ret = 0;
struct stat tmp;
int rrdInit(void)
{
int ret = 0;
struct stat tmp;
sensorLog (LOG_DEBUG, "sensor RRD init");
if (stat (rrdFile, &tmp)) {
if (errno == ENOENT) {
char stepBuff[STEP_BUFF], rraBuff[RRA_BUFF];
int argc = 4, num;
const char *argv[6 + MAX_RRD_SENSORS] = {
"sensord", rrdFile, "-s", stepBuff
};
sensorLog(LOG_DEBUG, "sensor RRD init");
if (stat(rrdFile, &tmp)) {
if (errno == ENOENT) {
char stepBuff[STEP_BUFF], rraBuff[RRA_BUFF];
int argc = 4, num;
const char *argv[6 + MAX_RRD_SENSORS] = {
"sensord", rrdFile, "-s", stepBuff
};
sensorLog (LOG_INFO, "creating round robin database");
num = rrdGetSensors (argv + argc);
if (num == 0) {
sensorLog (LOG_ERR, "Error creating RRD: %s: %s", rrdFile, "No sensors detected");
ret = 2;
} else if (num < 0) {
ret = -num;
} else {
sprintf (stepBuff, "%d", rrdTime);
sprintf (rraBuff, "RRA:%s:%f:%d:%d", rrdNoAverage?"LAST":"AVERAGE", 0.5 /* fraction of non-unknown samples needed per entry */, 1 /* samples per entry */, 7 * 24 * 60 * 60 / rrdTime /* 1 week */);
argc += num;
argv[argc ++] = rraBuff;
argv[argc] = NULL;
if ((ret = rrd_create (argc, (char **) /* WEAK */ argv))) {
sensorLog (LOG_ERR, "Error creating RRD file: %s: %s", rrdFile, rrd_get_error ());
}
}
} else {
sensorLog (LOG_ERR, "Error stat()ing RRD: %s: %s", rrdFile, strerror (errno));
ret = 1;
}
}
sensorLog (LOG_DEBUG, "sensor RRD inited");
sensorLog(LOG_INFO, "creating round robin database");
num = rrdGetSensors(argv + argc);
if (num == 0) {
sensorLog(LOG_ERR,
"Error creating RRD: %s: %s",
rrdFile, "No sensors detected");
ret = 2;
} else if (num < 0) {
ret = -num;
} else {
sprintf(stepBuff, "%d", rrdTime);
sprintf(rraBuff, "RRA:%s:%f:%d:%d",
rrdNoAverage?"LAST":"AVERAGE",
0.5 /* fraction of non-unknown samples needed per entry */,
1 /* samples per entry */,
7 * 24 * 60 * 60 / rrdTime /* 1 week */);
argc += num;
argv[argc ++] = rraBuff;
argv[argc] = NULL;
if ((ret = rrd_create(argc,
(char **) /* WEAK */ argv))) {
sensorLog(LOG_ERR,
"Error creating RRD file: %s: %s",
rrdFile, rrd_get_error());
}
}
} else {
sensorLog(LOG_ERR, "Error stat()ing RRD: %s: %s",
rrdFile, strerror(errno));
ret = 1;
}
}
sensorLog(LOG_DEBUG, "sensor RRD inited");
return ret;
return ret;
}
#define RRDCGI "/usr/bin/rrdcgi"
#define WWWDIR "/sensord"
struct gr {
DataType type;
const char *h2;
const char *image;
const char *title;
const char *axisTitle;
const char *axisDefn;
const char *options;
int loadAvg;
DataType type;
const char *h2;
const char *image;
const char *title;
const char *axisTitle;
const char *axisDefn;
const char *options;
int loadAvg;
};
static int
rrdCGI_DEF
(void *_data, const char *rawLabel, const char *label, const FeatureDescriptor *feature) {
struct gr *data = (struct gr *) _data;
(void) label; /* no warning */
if (!feature || (feature->rrd && (feature->type == data->type)))
printf ("\n\tDEF:%s=%s:%s:AVERAGE", rawLabel, rrdFile, rawLabel);
return 0;
static int rrdCGI_DEF(void *_data, const char *rawLabel, const char *label,
const FeatureDescriptor *feature)
{
struct gr *data = (struct gr *) _data;
(void) label; /* no warning */
if (!feature || (feature->rrd && (feature->type == data->type)))
printf("\n\tDEF:%s=%s:%s:AVERAGE", rawLabel, rrdFile,
rawLabel);
return 0;
}
/* Compute an arbitrary color based on the sensor label. This is preferred
over a random value because this guarantees that daily and weekly charts
will use the same colors. */
static int
rrdCGI_color
(const char *label) {
unsigned long color = 0, brightness;
const char *c;
/*
* Compute an arbitrary color based on the sensor label. This is preferred
* over a random value because this guarantees that daily and weekly charts
* will use the same colors.
*/
static int rrdCGI_color(const char *label)
{
unsigned long color = 0, brightness;
const char *c;
for (c = label; *c; c++) {
color = (color << 6) + (color >> (*c & 7));
color ^= (*c) * 0x401;
}
color &= 0xffffff;
/* Adjust very light colors */
brightness = (color & 0xff) + ((color >> 8) & 0xff) + (color >> 16);
if (brightness > 672)
color &= 0x7f7f7f;
/* Adjust very dark colors */
else if (brightness < 96)
color |= 0x808080;
return color;
for (c = label; *c; c++) {
color = (color << 6) + (color >> (*c & 7));
color ^= (*c) * 0x401;
}
color &= 0xffffff;
/* Adjust very light colors */
brightness = (color & 0xff) + ((color >> 8) & 0xff) + (color >> 16);
if (brightness > 672)
color &= 0x7f7f7f;
/* Adjust very dark colors */
else if (brightness < 96)
color |= 0x808080;
return color;
}
static int
rrdCGI_LINE
(void *_data, const char *rawLabel, const char *label, const FeatureDescriptor *feature) {
struct gr *data = (struct gr *) _data;
if (!feature || (feature->rrd && (feature->type == data->type)))
printf ("\n\tLINE2:%s#%.6x:\"%s\"", rawLabel, rrdCGI_color(label), label);
return 0;
static int rrdCGI_LINE(void *_data, const char *rawLabel, const char *label,
const FeatureDescriptor *feature)
{
struct gr *data = (struct gr *) _data;
if (!feature || (feature->rrd && (feature->type == data->type)))
printf("\n\tLINE2:%s#%.6x:\"%s\"", rawLabel,
rrdCGI_color(label), label);
return 0;
}
static struct gr graphs[] = {
{
DataType_temperature,
"Daily Temperature Summary",
"daily-temperature",
"Temperature",
"Temperature (C)",
"HOUR:1:HOUR:3:HOUR:3:0:%b %d %H:00",
"-s -1d -l 0",
1
}, {
DataType_rpm,
"Daily Fan Speed Summary",
"daily-rpm",
"Fan Speed",
"Speed (RPM)",
"HOUR:1:HOUR:3:HOUR:3:0:%b %d %H:00",
"-s -1d -l 0",
0
}, {
DataType_voltage,
"Daily Voltage Summary",
"daily-voltage",
"Power Supply",
"Voltage (V)",
"HOUR:1:HOUR:3:HOUR:3:0:%b %d %H:00",
"-s -1d --alt-autoscale",
0
}, {
DataType_temperature,
"Weekly Temperature Summary",
"weekly-temperature",
"Temperature",
"Temperature (C)",
"HOUR:6:DAY:1:DAY:1:86400:%a %b %d",
"-s -1w -l 0",
1
}, {
DataType_rpm,
"Weekly Fan Speed Summary",
"weekly-rpm",
"Fan Speed",
"Speed (RPM)",
"HOUR:6:DAY:1:DAY:1:86400:%a %b %d",
"-s -1w -l 0",
0
}, {
DataType_voltage,
"Weekly Voltage Summary",
"weekly-voltage",
"Power Supply",
"Voltage (V)",
"HOUR:6:DAY:1:DAY:1:86400:%a %b %d",
"-s -1w --alt-autoscale",
0
}, {
DataType_other,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
0
}
{
DataType_temperature,
"Daily Temperature Summary",
"daily-temperature",
"Temperature",
"Temperature (C)",
"HOUR:1:HOUR:3:HOUR:3:0:%b %d %H:00",
"-s -1d -l 0",
1
}, {
DataType_rpm,
"Daily Fan Speed Summary",
"daily-rpm",
"Fan Speed",
"Speed (RPM)",
"HOUR:1:HOUR:3:HOUR:3:0:%b %d %H:00",
"-s -1d -l 0",
0
}, {
DataType_voltage,
"Daily Voltage Summary",
"daily-voltage",
"Power Supply",
"Voltage (V)",
"HOUR:1:HOUR:3:HOUR:3:0:%b %d %H:00",
"-s -1d --alt-autoscale",
0
}, {
DataType_temperature,
"Weekly Temperature Summary",
"weekly-temperature",
"Temperature",
"Temperature (C)",
"HOUR:6:DAY:1:DAY:1:86400:%a %b %d",
"-s -1w -l 0",
1
}, {
DataType_rpm,
"Weekly Fan Speed Summary",
"weekly-rpm",
"Fan Speed",
"Speed (RPM)",
"HOUR:6:DAY:1:DAY:1:86400:%a %b %d",
"-s -1w -l 0",
0
}, {
DataType_voltage,
"Weekly Voltage Summary",
"weekly-voltage",
"Power Supply",
"Voltage (V)",
"HOUR:6:DAY:1:DAY:1:86400:%a %b %d",
"-s -1w --alt-autoscale",
0
}, {
DataType_other,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
0
}
};
int
rrdUpdate
(void) {
int ret = rrdChips ();
if (!ret && doLoad) {
FILE *loadavg;
if (!(loadavg = fopen ("/proc/loadavg", "r"))) {
sensorLog (LOG_ERR, "Error opening `/proc/loadavg': %s", strerror (errno));
ret = 1;
} else {
float value;
if (fscanf (loadavg, "%f", &value) != 1) {
sensorLog (LOG_ERR, "Error reading load average");
ret = 2;
} else {
sprintf (rrdBuff + strlen (rrdBuff), ":%f", value);
}
fclose (loadavg);
}
}
if (!ret) {
const char *argv[] = {
"sensord", rrdFile, rrdBuff, NULL
};
if ((ret = rrd_update (3, (char **) /* WEAK */ argv))) {
sensorLog (LOG_ERR, "Error updating RRD file: %s: %s", rrdFile, rrd_get_error ());
}
}
sensorLog (LOG_DEBUG, "sensor rrd updated");
int rrdUpdate(void)
{
int ret = rrdChips ();
if (!ret && doLoad) {
FILE *loadavg;
if (!(loadavg = fopen("/proc/loadavg", "r"))) {
sensorLog(LOG_ERR,
"Error opening `/proc/loadavg': %s",
strerror(errno));
ret = 1;
} else {
float value;
if (fscanf(loadavg, "%f", &value) != 1) {
sensorLog(LOG_ERR,
"Error reading load average");
ret = 2;
} else {
sprintf(rrdBuff + strlen(rrdBuff), ":%f",
value);
}
fclose(loadavg);
}
}
if (!ret) {
const char *argv[] = {
"sensord", rrdFile, rrdBuff, NULL
};
if ((ret = rrd_update(3, (char **) /* WEAK */ argv))) {
sensorLog(LOG_ERR, "Error updating RRD file: %s: %s",
rrdFile, rrd_get_error());
}
}
sensorLog(LOG_DEBUG, "sensor rrd updated");
return ret;
return ret;
}
int
rrdCGI
(void) {
int ret = 0;
struct gr *graph = graphs;
int rrdCGI(void)
{
int ret = 0;
struct gr *graph = graphs;
printf ("#!" RRDCGI "\n\n<HTML>\n<HEAD>\n<TITLE>sensord</TITLE>\n</HEAD>\n<BODY>\n<H1>sensord</H1>\n");
while (graph->type != DataType_other) {
printf ("<H2>%s</H2>\n", graph->h2);
printf ("<P>\n<RRD::GRAPH %s/%s.png\n\t--imginfo '<IMG SRC=" WWWDIR "/%%s WIDTH=%%lu HEIGHT=%%lu>'\n\t-a PNG\n\t-h 200 -w 800\n", cgiDir, graph->image);
printf ("\t--lazy\n\t-v '%s'\n\t-t '%s'\n\t-x '%s'\n\t%s", graph->axisTitle, graph->title, graph->axisDefn, graph->options);
if (!ret)
ret = applyToFeatures (rrdCGI_DEF, graph);
if (!ret && doLoad && graph->loadAvg)
ret = rrdCGI_DEF (graph, LOADAVG, LOAD_AVERAGE, NULL);
if (!ret)
ret = applyToFeatures (rrdCGI_LINE, graph);
if (!ret && doLoad && graph->loadAvg)
ret = rrdCGI_LINE (graph, LOADAVG, LOAD_AVERAGE, NULL);
printf (">\n</P>\n");
++ graph;
}
printf ("<p>\n<small><b>sensord</b> by <a href=\"mailto:merlin@merlin.org\">Merlin Hughes</a>, all credit to the <a href=\"http://www.lm-sensors.org/\">lm_sensors</a> crew.</small>\n</p>\n");
printf ("</BODY>\n</HTML>\n");
printf("#!" RRDCGI "\n\n<HTML>\n<HEAD>\n<TITLE>sensord</TITLE>\n</HEAD>\n<BODY>\n<H1>sensord</H1>\n");
while (graph->type != DataType_other) {
printf("<H2>%s</H2>\n", graph->h2);
printf("<P>\n<RRD::GRAPH %s/%s.png\n\t--imginfo '<IMG SRC=" WWWDIR "/%%s WIDTH=%%lu HEIGHT=%%lu>'\n\t-a PNG\n\t-h 200 -w 800\n",
cgiDir, graph->image);
printf("\t--lazy\n\t-v '%s'\n\t-t '%s'\n\t-x '%s'\n\t%s",
graph->axisTitle, graph->title, graph->axisDefn,
graph->options);
if (!ret)
ret = applyToFeatures(rrdCGI_DEF, graph);
if (!ret && doLoad && graph->loadAvg)
ret = rrdCGI_DEF(graph, LOADAVG, LOAD_AVERAGE, NULL);
if (!ret)
ret = applyToFeatures(rrdCGI_LINE, graph);
if (!ret && doLoad && graph->loadAvg)
ret = rrdCGI_LINE(graph, LOADAVG, LOAD_AVERAGE, NULL);
printf (">\n</P>\n");
++ graph;
}
printf("<p>\n<small><b>sensord</b> by <a href=\"mailto:merlin@merlin.org\">Merlin Hughes</a>, all credit to the <a href=\"http://www.lm-sensors.org/\">lm_sensors</a> crew.</small>\n</p>\n");
printf("</BODY>\n</HTML>\n");
return ret;
return ret;
}
+176 -161
View File
@@ -34,202 +34,217 @@
#define DO_SET 2
#define DO_RRD 3
static const char *
chipName
(const sensors_chip_name *chip) {
static char buffer[256];
if (sensors_snprintf_chip_name(buffer, 256, chip) < 0)
return NULL;
return buffer;
static const char *chipName(const sensors_chip_name *chip)
{
static char buffer[256];
if (sensors_snprintf_chip_name(buffer, 256, chip) < 0)
return NULL;
return buffer;
}
static int
idChip
(const sensors_chip_name *chip) {
const char *adapter;
static int idChip(const sensors_chip_name *chip)
{
const char *adapter;
sensorLog (LOG_INFO, "Chip: %s", chipName (chip));
adapter = sensors_get_adapter_name (&chip->bus);
if (adapter)
sensorLog (LOG_INFO, "Adapter: %s", adapter);
return 0;
sensorLog(LOG_INFO, "Chip: %s", chipName (chip));
adapter = sensors_get_adapter_name(&chip->bus);
if (adapter)
sensorLog(LOG_INFO, "Adapter: %s", adapter);
return 0;
}
static int
doKnownChip
(const sensors_chip_name *chip, const ChipDescriptor *descriptor, int action) {
const FeatureDescriptor *features = descriptor->features;
int index0, subindex;
int ret = 0;
double tmp;
static int doKnownChip(const sensors_chip_name *chip,
const ChipDescriptor *descriptor, int action)
{
const FeatureDescriptor *features = descriptor->features;
int index0, subindex;
int ret = 0;
double tmp;
if (action == DO_READ)
ret = idChip (chip);
for (index0 = 0; (ret == 0) && features[index0].format; ++ index0) {
const FeatureDescriptor *feature = features + index0;
int alarm, beep;
char *label = NULL;
if (action == DO_READ)
ret = idChip(chip);
for (index0 = 0; (ret == 0) && features[index0].format; ++ index0) {
const FeatureDescriptor *feature = features + index0;
int alarm, beep;
char *label = NULL;
if (!(label = sensors_get_label (chip, feature->feature))) {
sensorLog (LOG_ERR, "Error getting sensor label: %s/%s", chip->prefix, feature->feature->name);
ret = 22;
} else {
double values[MAX_DATA];
if (!(label = sensors_get_label(chip, feature->feature))) {
sensorLog(LOG_ERR,
"Error getting sensor label: %s/%s",
chip->prefix, feature->feature->name);
ret = 22;
} else {
double values[MAX_DATA];
alarm = 0;
if (!ret && feature->alarmNumber != -1) {
if ((ret = sensors_get_value (chip, feature->alarmNumber, &tmp))) {
sensorLog (LOG_ERR, "Error getting sensor data: %s/#%d: %s", chip->prefix, feature->alarmNumber, sensors_strerror (ret));
ret = 20;
} else {
alarm = (int) (tmp + 0.5);
}
}
if ((action == DO_SCAN) && !alarm)
continue;
alarm = 0;
if (!ret && feature->alarmNumber != -1) {
if ((ret = sensors_get_value(chip,
feature->alarmNumber,
&tmp))) {
sensorLog(LOG_ERR,
"Error getting sensor data: %s/#%d: %s",
chip->prefix,
feature->alarmNumber,
sensors_strerror(ret));
ret = 20;
} else {
alarm = (int) (tmp + 0.5);
}
}
if ((action == DO_SCAN) && !alarm)
continue;
beep = 0;
if (!ret && feature->beepNumber != -1) {
if ((ret = sensors_get_value (chip, feature->beepNumber, &tmp))) {
sensorLog (LOG_ERR, "Error getting sensor data: %s/#%d: %s", chip->prefix, feature->beepNumber, sensors_strerror (ret));
ret = 21;
} else {
beep = (int) (tmp + 0.5);
}
}
beep = 0;
if (!ret && feature->beepNumber != -1) {
if ((ret = sensors_get_value(chip,
feature->beepNumber,
&tmp))) {
sensorLog(LOG_ERR,
"Error getting sensor data: %s/#%d: %s",
chip->prefix,
feature->beepNumber,
sensors_strerror(ret));
ret = 21;
} else {
beep = (int) (tmp + 0.5);
}
}
for (subindex = 0; !ret && (feature->dataNumbers[subindex] >= 0); ++ subindex) {
if ((ret = sensors_get_value (chip, feature->dataNumbers[subindex], values + subindex))) {
sensorLog (LOG_ERR, "Error getting sensor data: %s/#%d: %s", chip->prefix, feature->dataNumbers[subindex], sensors_strerror (ret));
ret = 23;
}
}
if (ret == 0) {
if (action == DO_RRD) { // arse = "N:"
if (feature->rrd) {
const char *rrded = feature->rrd (values);
strcat (strcat (rrdBuff, ":"), rrded ? rrded : "U");
}
} else {
const char *formatted = feature->format (values, alarm, beep);
if (formatted) {
if (action == DO_READ) {
sensorLog (LOG_INFO, " %s: %s", label, formatted);
} else {
sensorLog (LOG_ALERT, "Sensor alarm: Chip %s: %s: %s", chipName (chip), label, formatted);
}
}
}
}
}
if (label)
free (label);
}
return ret;
for (subindex = 0; !ret &&
(feature->dataNumbers[subindex] >= 0); ++ subindex) {
if ((ret = sensors_get_value(chip, feature->dataNumbers[subindex], values + subindex))) {
sensorLog(LOG_ERR, "Error getting sensor data: %s/#%d: %s", chip->prefix, feature->dataNumbers[subindex], sensors_strerror(ret));
ret = 23;
}
}
if (ret == 0) {
if (action == DO_RRD) { // arse = "N:"
if (feature->rrd) {
const char *rrded = feature->rrd (values);
strcat(strcat (rrdBuff, ":"),
rrded ? rrded : "U");
}
} else {
const char *formatted = feature->format (values, alarm, beep);
if (formatted) {
if (action == DO_READ) {
sensorLog(LOG_INFO, " %s: %s", label, formatted);
} else {
sensorLog(LOG_ALERT, "Sensor alarm: Chip %s: %s: %s", chipName(chip), label, formatted);
}
}
}
}
}
if (label)
free(label);
}
return ret;
}
static int
setChip
(const sensors_chip_name *chip) {
int ret = 0;
if ((ret = idChip (chip))) {
sensorLog (LOG_ERR, "Error identifying chip: %s", chip->prefix);
} else if ((ret = sensors_do_chip_sets (chip))) {
sensorLog (LOG_ERR, "Error performing chip sets: %s: %s", chip->prefix, sensors_strerror (ret));
ret = 50;
} else {
sensorLog (LOG_INFO, "Set.");
}
return ret;
static int setChip(const sensors_chip_name *chip)
{
int ret = 0;
if ((ret = idChip(chip))) {
sensorLog(LOG_ERR, "Error identifying chip: %s",
chip->prefix);
} else if ((ret = sensors_do_chip_sets(chip))) {
sensorLog(LOG_ERR, "Error performing chip sets: %s: %s",
chip->prefix, sensors_strerror(ret));
ret = 50;
} else {
sensorLog(LOG_INFO, "Set.");
}
return ret;
}
static int
doChip
(const sensors_chip_name *chip, int action) {
int ret = 0;
if (action == DO_SET) {
ret = setChip (chip);
} else {
int index0, chipindex = -1;
for (index0 = 0; knownChips[index0].features; ++ index0)
/* Trick: we compare addresses here. We know it works because both
pointers were returned by sensors_get_detected_chips(), so they
refer to libsensors internal structures, which do not move. */
if (knownChips[index0].name == chip) {
chipindex = index0;
break;
}
if (chipindex >= 0)
ret = doKnownChip (chip, &knownChips[chipindex], action);
}
return ret;
static int doChip(const sensors_chip_name *chip, int action)
{
int ret = 0;
if (action == DO_SET) {
ret = setChip(chip);
} else {
int index0, chipindex = -1;
for (index0 = 0; knownChips[index0].features; ++ index0)
/*
* Trick: we compare addresses here. We know it works
* because both pointers were returned by
* sensors_get_detected_chips(), so they refer to
* libsensors internal structures, which do not move.
*/
if (knownChips[index0].name == chip) {
chipindex = index0;
break;
}
if (chipindex >= 0)
ret = doKnownChip(chip, &knownChips[chipindex],
action);
}
return ret;
}
static int
doChips
(int action) {
const sensors_chip_name *chip;
int i, j, ret = 0;
static int doChips(int action)
{
const sensors_chip_name *chip;
int i, j, ret = 0;
for (j = 0; (ret == 0) && (j < numChipNames); ++ j) {
i = 0;
while ((ret == 0) && ((chip = sensors_get_detected_chips (&chipNames[j], &i)) != NULL)) {
ret = doChip (chip, action);
}
}
for (j = 0; (ret == 0) && (j < numChipNames); ++ j) {
i = 0;
while ((ret == 0) &&
((chip = sensors_get_detected_chips(&chipNames[j], &i))
!= NULL)) {
ret = doChip(chip, action);
}
}
return ret;
return ret;
}
int
readChips
(void) {
int ret = 0;
int readChips(void)
{
int ret = 0;
sensorLog (LOG_DEBUG, "sensor read started");
ret = doChips (DO_READ);
sensorLog (LOG_DEBUG, "sensor read finished");
sensorLog(LOG_DEBUG, "sensor read started");
ret = doChips(DO_READ);
sensorLog(LOG_DEBUG, "sensor read finished");
return ret;
return ret;
}
int
scanChips
(void) {
int ret = 0;
int scanChips(void)
{
int ret = 0;
sensorLog (LOG_DEBUG, "sensor sweep started"); /* only logged in debug mode */
ret = doChips (DO_SCAN);
sensorLog (LOG_DEBUG, "sensor sweep finished");
sensorLog(LOG_DEBUG, "sensor sweep started");
ret = doChips(DO_SCAN);
sensorLog(LOG_DEBUG, "sensor sweep finished");
return ret;
return ret;
}
int
setChips
(void) {
int ret = 0;
int setChips(void)
{
int ret = 0;
sensorLog (LOG_DEBUG, "sensor set started");
ret = doChips (DO_SET);
sensorLog (LOG_DEBUG, "sensor set finished");
sensorLog(LOG_DEBUG, "sensor set started");
ret = doChips(DO_SET);
sensorLog(LOG_DEBUG, "sensor set finished");
return ret;
return ret;
}
/* TODO: loadavg entry */
int
rrdChips
(void) {
int ret = 0;
int rrdChips(void)
{
int ret = 0;
strcpy (rrdBuff, "N");
strcpy(rrdBuff, "N");
sensorLog (LOG_DEBUG, "sensor rrd started");
ret = doChips (DO_RRD);
sensorLog (LOG_DEBUG, "sensor rrd finished");
sensorLog(LOG_DEBUG, "sensor rrd started");
ret = doChips(DO_RRD);
sensorLog(LOG_DEBUG, "sensor rrd finished");
return ret;
return ret;
}
+173 -171
View File
@@ -44,197 +44,199 @@ static volatile sig_atomic_t reload = 0;
#include <stdarg.h>
void
sensorLog
(int priority, const char *fmt, ...) {
static char buffer[1 + LOG_BUFFER];
va_list ap;
va_start (ap, fmt);
vsnprintf (buffer, LOG_BUFFER, fmt, ap);
buffer[LOG_BUFFER] = '\0';
va_end (ap);
if (debug || (priority < LOG_DEBUG)) {
if (logOpened) {
syslog (priority, "%s", buffer);
} else {
fprintf (stderr, "%s\n", buffer);
fflush (stderr);
}
}
void sensorLog(int priority, const char *fmt, ...)
{
static char buffer[1 + LOG_BUFFER];
va_list ap;
va_start(ap, fmt);
vsnprintf(buffer, LOG_BUFFER, fmt, ap);
buffer[LOG_BUFFER] = '\0';
va_end(ap);
if (debug || (priority < LOG_DEBUG)) {
if (logOpened) {
syslog(priority, "%s", buffer);
} else {
fprintf(stderr, "%s\n", buffer);
fflush(stderr);
}
}
}
static void
signalHandler
(int sig) {
signal (sig, signalHandler);
switch (sig) {
case SIGTERM:
done = 1;
break;
case SIGHUP:
reload = 1;
break;
}
static void signalHandler(int sig)
{
signal(sig, signalHandler);
switch (sig) {
case SIGTERM:
done = 1;
break;
case SIGHUP:
reload = 1;
break;
}
}
static int
sensord
(void) {
int ret = 0;
int scanValue = 0, logValue = 0;
/*
* First RRD update at next RRD timeslot to prevent failures due
* one timeslot updated twice on restart for example.
*/
int rrdValue = rrdTime - time(NULL) % rrdTime;
static int sensord(void)
{
int ret = 0;
int scanValue = 0, logValue = 0;
/*
* First RRD update at next RRD timeslot to prevent failures due
* one timeslot updated twice on restart for example.
*/
int rrdValue = rrdTime - time(NULL) % rrdTime;
sensorLog (LOG_INFO, "sensord started");
sensorLog(LOG_INFO, "sensord started");
while (!done) {
if (reload) {
ret = reloadLib (sensorsCfgFile);
if (ret)
sensorLog (LOG_NOTICE, "config reload error (%d)", ret);
reload = 0;
}
if (scanTime && (scanValue <= 0)) {
if ((ret = scanChips ()))
sensorLog (LOG_NOTICE, "sensor scan error (%d)", ret);
scanValue += scanTime;
}
if (logTime && (logValue <= 0)) {
if ((ret = readChips ()))
sensorLog (LOG_NOTICE, "sensor read error (%d)", ret);
logValue += logTime;
}
if (rrdTime && rrdFile && (rrdValue <= 0)) {
if ((ret = rrdUpdate ()))
sensorLog (LOG_NOTICE, "rrd update error (%d)", ret);
/*
* The amount of time to wait is computed using the same method as
* in RRD instead of simply adding the interval.
*/
rrdValue = rrdTime - time(NULL) % rrdTime;
}
if (!done) {
int a = logTime ? logValue : INT_MAX;
int b = scanTime ? scanValue : INT_MAX;
int c = (rrdTime && rrdFile) ? rrdValue : INT_MAX;
int sleepTime = (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c);
sleep (sleepTime);
scanValue -= sleepTime;
logValue -= sleepTime;
rrdValue -= sleepTime;
}
}
while (!done) {
if (reload) {
ret = reloadLib(sensorsCfgFile);
if (ret)
sensorLog(LOG_NOTICE,
"config reload error (%d)", ret);
reload = 0;
}
if (scanTime && (scanValue <= 0)) {
if ((ret = scanChips()))
sensorLog(LOG_NOTICE,
"sensor scan error (%d)", ret);
scanValue += scanTime;
}
if (logTime && (logValue <= 0)) {
if ((ret = readChips()))
sensorLog(LOG_NOTICE,
"sensor read error (%d)", ret);
logValue += logTime;
}
if (rrdTime && rrdFile && (rrdValue <= 0)) {
if ((ret = rrdUpdate()))
sensorLog(LOG_NOTICE,
"rrd update error (%d)", ret);
/*
* The amount of time to wait is computed using the
* same method as in RRD instead of simply adding the
* interval.
*/
rrdValue = rrdTime - time(NULL) % rrdTime;
}
if (!done) {
int a = logTime ? logValue : INT_MAX;
int b = scanTime ? scanValue : INT_MAX;
int c = (rrdTime && rrdFile) ? rrdValue : INT_MAX;
int sleepTime = (a < b) ? ((a < c) ? a : c) :
((b < c) ? b : c);
sleep(sleepTime);
scanValue -= sleepTime;
logValue -= sleepTime;
rrdValue -= sleepTime;
}
}
sensorLog (LOG_INFO, "sensord stopped");
sensorLog(LOG_INFO, "sensord stopped");
return ret;
return ret;
}
static void
openLog
(void) {
openlog ("sensord", 0, syslogFacility);
logOpened = 1;
static void openLog(void)
{
openlog("sensord", 0, syslogFacility);
logOpened = 1;
}
static void
daemonize
(void) {
int pid;
struct stat fileStat;
FILE *file;
static void daemonize(void)
{
int pid;
struct stat fileStat;
FILE *file;
if (chdir ("/") < 0) {
perror ("chdir()");
exit (EXIT_FAILURE);
}
if (chdir("/") < 0) {
perror("chdir()");
exit(EXIT_FAILURE);
}
if (!(stat (pidFile, &fileStat)) &&
((!S_ISREG (fileStat.st_mode)) || (fileStat.st_size > 11))) {
fprintf (stderr, "Error: PID file `%s' already exists and looks suspicious.\n", pidFile);
exit (EXIT_FAILURE);
}
if (!(file = fopen (pidFile, "w"))) {
fprintf (stderr, "fopen(\"%s\"): %s\n", pidFile, strerror (errno));
exit (EXIT_FAILURE);
}
/* I should use sigaction but... */
if (signal (SIGTERM, signalHandler) == SIG_ERR ||
signal (SIGHUP, signalHandler) == SIG_ERR) {
perror ("signal");
exit (EXIT_FAILURE);
}
if (!(stat(pidFile, &fileStat)) &&
((!S_ISREG(fileStat.st_mode)) || (fileStat.st_size > 11))) {
fprintf(stderr,
"Error: PID file `%s' already exists and looks suspicious.\n",
pidFile);
exit(EXIT_FAILURE);
}
if ((pid = fork ()) == -1) {
perror ("fork()");
exit (EXIT_FAILURE);
} else if (pid != 0) {
fprintf (file, "%d\n", pid);
fclose (file);
unloadLib ();
exit (EXIT_SUCCESS);
}
if (!(file = fopen(pidFile, "w"))) {
fprintf(stderr, "fopen(\"%s\"): %s\n", pidFile,
strerror(errno));
exit(EXIT_FAILURE);
}
if (setsid () < 0) {
perror ("setsid()");
exit (EXIT_FAILURE);
}
/* I should use sigaction but... */
if (signal(SIGTERM, signalHandler) == SIG_ERR ||
signal (SIGHUP, signalHandler) == SIG_ERR) {
perror("signal");
exit(EXIT_FAILURE);
}
fclose (file);
close (STDIN_FILENO);
close (STDOUT_FILENO);
close (STDERR_FILENO);
if ((pid = fork()) == -1) {
perror("fork()");
exit(EXIT_FAILURE);
} else if (pid != 0) {
fprintf(file, "%d\n", pid);
fclose(file);
unloadLib();
exit(EXIT_SUCCESS);
}
if (setsid() < 0) {
perror("setsid()");
exit(EXIT_FAILURE);
}
fclose(file);
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
}
static void
undaemonize
(void) {
unlink (pidFile);
closelog ();
static void undaemonize(void)
{
unlink(pidFile);
closelog();
}
int
main
(int argc, char **argv) {
int ret = 0;
if (parseArgs (argc, argv) ||
parseChips (argc, argv))
exit (EXIT_FAILURE);
if (loadLib (sensorsCfgFile))
exit (EXIT_FAILURE);
int main(int argc, char **argv)
{
int ret = 0;
if (isDaemon)
openLog ();
if (rrdFile)
ret = rrdInit ();
if (ret) {
} else if (doCGI) {
ret = rrdCGI ();
} else if (isDaemon) {
daemonize ();
ret = sensord ();
undaemonize ();
} else {
if (doSet)
ret = setChips ();
else if (doScan)
ret = scanChips ();
else if (rrdFile)
ret = rrdUpdate ();
else
ret = readChips ();
}
if (unloadLib ())
exit (EXIT_FAILURE);
return ret;
if (parseArgs(argc, argv) ||
parseChips(argc, argv))
exit(EXIT_FAILURE);
if (loadLib(sensorsCfgFile))
exit(EXIT_FAILURE);
if (isDaemon)
openLog();
if (rrdFile)
ret = rrdInit();
if (ret) {
} else if (doCGI) {
ret = rrdCGI();
} else if (isDaemon) {
daemonize();
ret = sensord();
undaemonize();
} else {
if (doSet)
ret = setChips();
else if (doScan)
ret = scanChips();
else if (rrdFile)
ret = rrdUpdate();
else
ret = readChips();
}
if (unloadLib())
exit(EXIT_FAILURE);
return ret;
}
+31 -30
View File
@@ -23,7 +23,7 @@
#include "lib/sensors.h"
extern void sensorLog (int priority, const char *fmt, ...);
extern void sensorLog(int priority, const char *fmt, ...);
/* from args.c */
@@ -45,59 +45,60 @@ extern int debug;
extern sensors_chip_name chipNames[];
extern int numChipNames;
extern int parseArgs (int argc, char **argv);
extern int parseChips (int argc, char **argv);
extern int parseArgs(int argc, char **argv);
extern int parseChips(int argc, char **argv);
/* from lib.c */
extern int loadLib (const char *cfgPath);
extern int reloadLib (const char *cfgPath);
extern int unloadLib (void);
extern int loadLib(const char *cfgPath);
extern int reloadLib(const char *cfgPath);
extern int unloadLib(void);
/* from sense.c */
extern int readChips (void);
extern int scanChips (void);
extern int setChips (void);
extern int rrdChips (void);
extern int readChips(void);
extern int scanChips(void);
extern int setChips(void);
extern int rrdChips(void);
/* from rrd.c */
extern char rrdBuff[];
extern int rrdInit (void);
extern int rrdUpdate (void);
extern int rrdCGI (void);
extern int rrdInit(void);
extern int rrdUpdate(void);
extern int rrdCGI(void);
/* from chips.c */
#define MAX_DATA 5
typedef const char * (*FormatterFN) (const double values[], int alarm, int beep);
typedef const char *(*FormatterFN) (const double values[], int alarm,
int beep);
typedef const char * (*RRDFN) (const double values[]);
typedef const char *(*RRDFN) (const double values[]);
typedef enum {
DataType_voltage = 0,
DataType_rpm,
DataType_temperature,
DataType_other = -1
DataType_voltage = 0,
DataType_rpm,
DataType_temperature,
DataType_other = -1
} DataType;
typedef struct {
FormatterFN format;
RRDFN rrd;
DataType type;
int alarmNumber;
int beepNumber;
const sensors_feature *feature;
int dataNumbers[MAX_DATA + 1];
FormatterFN format;
RRDFN rrd;
DataType type;
int alarmNumber;
int beepNumber;
const sensors_feature *feature;
int dataNumbers[MAX_DATA + 1];
} FeatureDescriptor;
typedef struct {
const sensors_chip_name *name;
FeatureDescriptor *features;
const sensors_chip_name *name;
FeatureDescriptor *features;
} ChipDescriptor;
extern ChipDescriptor * knownChips;
extern int initKnownChips (void);
extern void freeKnownChips (void);
extern int initKnownChips(void);
extern void freeKnownChips(void);