root/lm-sensors/branches/lm-sensors-3.0.0/lib/init.c @ 5169

Revision 5169, 5.3 KB (checked in by khali, 7 years ago)

The configuration file is currently parsed in the locale set by the main
program using the library. This means that if the decimal separator
(defined in LC_NUMERIC) is not '.' the values in the compute lines are
truncated. This happens for example with sensors-applet and a French
locale.

 http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=469333

Parsing the configuration file in C locale fixes the problem.
Original patch from Aurelien Jarno.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    init.c - Part of libsensors, a Linux library for reading sensor data.
3    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
4    Copyright (C) 2007        Jean Delvare <khali@linux-fr.org>
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19    MA 02110-1301 USA.
20*/
21
22#include <locale.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include <errno.h>
27#include "sensors.h"
28#include "data.h"
29#include "error.h"
30#include "access.h"
31#include "conf.h"
32#include "sysfs.h"
33#include "scanner.h"
34#include "init.h"
35
36#define DEFAULT_CONFIG_FILE     ETCDIR "/sensors3.conf"
37#define ALT_CONFIG_FILE         ETCDIR "/sensors.conf"
38
39/* Wrapper around sensors_yyparse(), which clears the locale so that
40   the decimal numbers are always parsed properly. */
41static int sensors_parse(void)
42{
43        int res;
44        char *locale;
45
46        /* Remember the current locale and clear it */
47        locale = setlocale(LC_ALL, NULL);
48        if (locale) {
49                locale = strdup(locale);
50                setlocale(LC_ALL, "C");
51        }
52
53        res = sensors_yyparse();
54
55        /* Restore the old locale */
56        if (locale) {
57                setlocale(LC_ALL, locale);
58                free(locale);
59        }
60
61        return res;
62}
63
64int sensors_init(FILE *input)
65{
66        int res;
67
68        if (!sensors_init_sysfs())
69                return -SENSORS_ERR_KERNEL;
70        if ((res = sensors_read_sysfs_bus()) ||
71            (res = sensors_read_sysfs_chips()))
72                goto exit_cleanup;
73
74        res = -SENSORS_ERR_PARSE;
75        if (input) {
76                if (sensors_scanner_init(input) ||
77                    sensors_parse())
78                        goto exit_cleanup;
79        } else {
80                /* No configuration provided, use default */
81                input = fopen(DEFAULT_CONFIG_FILE, "r");
82                if (!input && errno == ENOENT)
83                        input = fopen(ALT_CONFIG_FILE, "r");
84                if (input) {
85                        if (sensors_scanner_init(input) ||
86                            sensors_parse()) {
87                                fclose(input);
88                                goto exit_cleanup;
89                        }
90                        fclose(input);
91                }
92        }
93
94        if ((res = sensors_substitute_busses()))
95                goto exit_cleanup;
96        return 0;
97
98exit_cleanup:
99        sensors_cleanup();
100        return res;
101}
102
103static void free_chip_name(sensors_chip_name *name)
104{
105        free(name->prefix);
106        free(name->path);
107}
108
109static void free_chip_features(sensors_chip_features *features)
110{
111        int i;
112
113        for (i = 0; i < features->subfeature_count; i++)
114                free(features->subfeature[i].name);
115        free(features->subfeature);
116        for (i = 0; i < features->feature_count; i++)
117                free(features->feature[i].name);
118        free(features->feature);
119}
120
121static void free_bus(sensors_bus *bus)
122{
123        free(bus->adapter);
124}
125
126static void free_label(sensors_label *label)
127{
128        free(label->name);
129        free(label->value);
130}
131
132void free_expr(sensors_expr *expr)
133{
134        if (expr->kind == sensors_kind_var)
135                free(expr->data.var);
136        else if (expr->kind == sensors_kind_sub) {
137                if (expr->data.subexpr.sub1)
138                        free_expr(expr->data.subexpr.sub1);
139                if (expr->data.subexpr.sub2)
140                        free_expr(expr->data.subexpr.sub2);
141        }
142        free(expr);
143}
144
145static void free_set(sensors_set *set)
146{
147        free(set->name);
148        free_expr(set->value);
149}
150
151static void free_compute(sensors_compute *compute)
152{
153        free(compute->name);
154        free_expr(compute->from_proc);
155        free_expr(compute->to_proc);
156}
157
158static void free_ignore(sensors_ignore *ignore)
159{
160        free(ignore->name);
161}
162
163static void free_chip(sensors_chip *chip)
164{
165        int i;
166
167        for (i = 0; i < chip->chips.fits_count; i++)
168                free_chip_name(&chip->chips.fits[i]);
169        free(chip->chips.fits);
170        chip->chips.fits_count = chip->chips.fits_max = 0;
171
172        for (i = 0; i < chip->labels_count; i++)
173                free_label(&chip->labels[i]);
174        free(chip->labels);
175        chip->labels_count = chip->labels_max = 0;
176
177        for (i = 0; i < chip->sets_count; i++)
178                free_set(&chip->sets[i]);
179        free(chip->sets);
180        chip->sets_count = chip->sets_max = 0;
181
182        for (i = 0; i < chip->computes_count; i++)
183                free_compute(&chip->computes[i]);
184        free(chip->computes);
185        chip->computes_count = chip->computes_max = 0;
186
187        for (i = 0; i < chip->ignores_count; i++)
188                free_ignore(&chip->ignores[i]);
189        free(chip->ignores);
190        chip->ignores_count = chip->ignores_max = 0;
191}
192
193void sensors_cleanup(void)
194{
195        int i;
196
197        sensors_scanner_exit();
198
199        for (i = 0; i < sensors_proc_chips_count; i++) {
200                free_chip_name(&sensors_proc_chips[i].chip);
201                free_chip_features(&sensors_proc_chips[i]);
202        }
203        free(sensors_proc_chips);
204        sensors_proc_chips = NULL;
205        sensors_proc_chips_count = sensors_proc_chips_max = 0;
206
207        for (i = 0; i < sensors_config_busses_count; i++)
208                free_bus(&sensors_config_busses[i]);
209        free(sensors_config_busses);
210        sensors_config_busses = NULL;
211        sensors_config_busses_count = sensors_config_busses_max = 0;
212
213        for (i = 0; i < sensors_config_chips_count; i++)
214                free_chip(&sensors_config_chips[i]);
215        free(sensors_config_chips);
216        sensors_config_chips = NULL;
217        sensors_config_chips_count = sensors_config_chips_max = 0;
218
219        for (i = 0; i < sensors_proc_bus_count; i++)
220                free_bus(&sensors_proc_bus[i]);
221        free(sensors_proc_bus);
222        sensors_proc_bus = NULL;
223        sensors_proc_bus_count = sensors_proc_bus_max = 0;
224}
Note: See TracBrowser for help on using the browser.