Merge tag 'v3.10.54' into linux-linaro-lsk
[firefly-linux-kernel-4.4.55.git] / tools / gator / daemon / libsensors / init.c
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, 2009  Jean Delvare <khali@linux-fr.org>
5
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Lesser General Public
8     License as published by the Free Software Foundation; either
9     version 2.1 of the License, or (at your option) any later version.
10
11     This library 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 Lesser 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 /*** This file modified by ARM on Jan 23, 2013 to cast alphasort to supress a warning as it's prototype is different on android. ***/
23
24 /* Needed for scandir() and alphasort() */
25 #define _BSD_SOURCE
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <locale.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <dirent.h>
35 #include <unistd.h>
36 #include "sensors.h"
37 #include "data.h"
38 #include "error.h"
39 #include "access.h"
40 #include "conf.h"
41 #include "sysfs.h"
42 #include "scanner.h"
43 #include "init.h"
44
45 #define DEFAULT_CONFIG_FILE     ETCDIR "/sensors3.conf"
46 #define ALT_CONFIG_FILE         ETCDIR "/sensors.conf"
47 #define DEFAULT_CONFIG_DIR      ETCDIR "/sensors.d"
48
49 /* Wrapper around sensors_yyparse(), which clears the locale so that
50    the decimal numbers are always parsed properly. */
51 static int sensors_parse(void)
52 {
53         int res;
54         char *locale;
55
56         /* Remember the current locale and clear it */
57         locale = setlocale(LC_ALL, NULL);
58         if (locale) {
59                 locale = strdup(locale);
60                 if (!locale)
61                         sensors_fatal_error(__func__, "Out of memory");
62
63                 setlocale(LC_ALL, "C");
64         }
65
66         res = sensors_yyparse();
67
68         /* Restore the old locale */
69         if (locale) {
70                 setlocale(LC_ALL, locale);
71                 free(locale);
72         }
73
74         return res;
75 }
76
77 static void free_bus(sensors_bus *bus)
78 {
79         free(bus->adapter);
80 }
81
82 static void free_config_busses(void)
83 {
84         int i;
85
86         for (i = 0; i < sensors_config_busses_count; i++)
87                 free_bus(&sensors_config_busses[i]);
88         free(sensors_config_busses);
89         sensors_config_busses = NULL;
90         sensors_config_busses_count = sensors_config_busses_max = 0;
91 }
92
93 static int parse_config(FILE *input, const char *name)
94 {
95         int err;
96         char *name_copy;
97
98         if (name) {
99                 /* Record configuration file name for error reporting */
100                 name_copy = strdup(name);
101                 if (!name_copy)
102                         sensors_fatal_error(__func__, "Out of memory");
103                 sensors_add_config_files(&name_copy);
104         } else
105                 name_copy = NULL;
106
107         if (sensors_scanner_init(input, name_copy)) {
108                 err = -SENSORS_ERR_PARSE;
109                 goto exit_cleanup;
110         }
111         err = sensors_parse();
112         sensors_scanner_exit();
113         if (err) {
114                 err = -SENSORS_ERR_PARSE;
115                 goto exit_cleanup;
116         }
117
118         err = sensors_substitute_busses();
119
120 exit_cleanup:
121         free_config_busses();
122         return err;
123 }
124
125 static int config_file_filter(const struct dirent *entry)
126 {
127         return entry->d_name[0] != '.';         /* Skip hidden files */
128 }
129
130 static int add_config_from_dir(const char *dir)
131 {
132         int count, res, i;
133         struct dirent **namelist;
134
135         count = scandir(dir, &namelist, config_file_filter, (int (*)(const struct dirent **, const struct dirent **))alphasort);
136         if (count < 0) {
137                 /* Do not return an error if directory does not exist */
138                 if (errno == ENOENT)
139                         return 0;
140                 
141                 sensors_parse_error_wfn(strerror(errno), NULL, 0);
142                 return -SENSORS_ERR_PARSE;
143         }
144
145         for (res = 0, i = 0; !res && i < count; i++) {
146                 int len;
147                 char path[PATH_MAX];
148                 FILE *input;
149                 struct stat st;
150
151                 len = snprintf(path, sizeof(path), "%s/%s", dir,
152                                namelist[i]->d_name);
153                 if (len < 0 || len >= (int)sizeof(path)) {
154                         res = -SENSORS_ERR_PARSE;
155                         continue;
156                 }
157
158                 /* Only accept regular files */
159                 if (stat(path, &st) < 0 || !S_ISREG(st.st_mode))
160                         continue;
161
162                 input = fopen(path, "r");
163                 if (input) {
164                         res = parse_config(input, path);
165                         fclose(input);
166                 } else {
167                         res = -SENSORS_ERR_PARSE;
168                         sensors_parse_error_wfn(strerror(errno), path, 0);
169                 }
170         }
171
172         /* Free memory allocated by scandir() */
173         for (i = 0; i < count; i++)
174                 free(namelist[i]);
175         free(namelist);
176
177         return res;
178 }
179
180 int sensors_init(FILE *input)
181 {
182         int res;
183
184         if (!sensors_init_sysfs())
185                 return -SENSORS_ERR_KERNEL;
186         if ((res = sensors_read_sysfs_bus()) ||
187             (res = sensors_read_sysfs_chips()))
188                 goto exit_cleanup;
189
190         if (input) {
191                 res = parse_config(input, NULL);
192                 if (res)
193                         goto exit_cleanup;
194         } else {
195                 const char* name;
196
197                 /* No configuration provided, use default */
198                 input = fopen(name = DEFAULT_CONFIG_FILE, "r");
199                 if (!input && errno == ENOENT)
200                         input = fopen(name = ALT_CONFIG_FILE, "r");
201                 if (input) {
202                         res = parse_config(input, name);
203                         fclose(input);
204                         if (res)
205                                 goto exit_cleanup;
206
207                 } else if (errno != ENOENT) {
208                         sensors_parse_error_wfn(strerror(errno), name, 0);
209                         res = -SENSORS_ERR_PARSE;
210                         goto exit_cleanup;
211                 }
212
213                 /* Also check for files in default directory */
214                 res = add_config_from_dir(DEFAULT_CONFIG_DIR);
215                 if (res)
216                         goto exit_cleanup;
217         }
218
219         return 0;
220
221 exit_cleanup:
222         sensors_cleanup();
223         return res;
224 }
225
226 static void free_chip_name(sensors_chip_name *name)
227 {
228         free(name->prefix);
229         free(name->path);
230 }
231
232 static void free_chip_features(sensors_chip_features *features)
233 {
234         int i;
235
236         for (i = 0; i < features->subfeature_count; i++)
237                 free(features->subfeature[i].name);
238         free(features->subfeature);
239         for (i = 0; i < features->feature_count; i++)
240                 free(features->feature[i].name);
241         free(features->feature);
242 }
243
244 static void free_label(sensors_label *label)
245 {
246         free(label->name);
247         free(label->value);
248 }
249
250 void sensors_free_expr(sensors_expr *expr)
251 {
252         if (expr->kind == sensors_kind_var)
253                 free(expr->data.var);
254         else if (expr->kind == sensors_kind_sub) {
255                 if (expr->data.subexpr.sub1)
256                         sensors_free_expr(expr->data.subexpr.sub1);
257                 if (expr->data.subexpr.sub2)
258                         sensors_free_expr(expr->data.subexpr.sub2);
259         }
260         free(expr);
261 }
262
263 static void free_set(sensors_set *set)
264 {
265         free(set->name);
266         sensors_free_expr(set->value);
267 }
268
269 static void free_compute(sensors_compute *compute)
270 {
271         free(compute->name);
272         sensors_free_expr(compute->from_proc);
273         sensors_free_expr(compute->to_proc);
274 }
275
276 static void free_ignore(sensors_ignore *ignore)
277 {
278         free(ignore->name);
279 }
280
281 static void free_chip(sensors_chip *chip)
282 {
283         int i;
284
285         for (i = 0; i < chip->chips.fits_count; i++)
286                 free_chip_name(&chip->chips.fits[i]);
287         free(chip->chips.fits);
288         chip->chips.fits_count = chip->chips.fits_max = 0;
289
290         for (i = 0; i < chip->labels_count; i++)
291                 free_label(&chip->labels[i]);
292         free(chip->labels);
293         chip->labels_count = chip->labels_max = 0;
294
295         for (i = 0; i < chip->sets_count; i++)
296                 free_set(&chip->sets[i]);
297         free(chip->sets);
298         chip->sets_count = chip->sets_max = 0;
299
300         for (i = 0; i < chip->computes_count; i++)
301                 free_compute(&chip->computes[i]);
302         free(chip->computes);
303         chip->computes_count = chip->computes_max = 0;
304
305         for (i = 0; i < chip->ignores_count; i++)
306                 free_ignore(&chip->ignores[i]);
307         free(chip->ignores);
308         chip->ignores_count = chip->ignores_max = 0;
309 }
310
311 void sensors_cleanup(void)
312 {
313         int i;
314
315         for (i = 0; i < sensors_proc_chips_count; i++) {
316                 free_chip_name(&sensors_proc_chips[i].chip);
317                 free_chip_features(&sensors_proc_chips[i]);
318         }
319         free(sensors_proc_chips);
320         sensors_proc_chips = NULL;
321         sensors_proc_chips_count = sensors_proc_chips_max = 0;
322
323         for (i = 0; i < sensors_config_chips_count; i++)
324                 free_chip(&sensors_config_chips[i]);
325         free(sensors_config_chips);
326         sensors_config_chips = NULL;
327         sensors_config_chips_count = sensors_config_chips_max = 0;
328         sensors_config_chips_subst = 0;
329
330         for (i = 0; i < sensors_proc_bus_count; i++)
331                 free_bus(&sensors_proc_bus[i]);
332         free(sensors_proc_bus);
333         sensors_proc_bus = NULL;
334         sensors_proc_bus_count = sensors_proc_bus_max = 0;
335
336         for (i = 0; i < sensors_config_files_count; i++)
337                 free(sensors_config_files[i]);
338         free(sensors_config_files);
339         sensors_config_files = NULL;
340         sensors_config_files_count = sensors_config_files_max = 0;
341 }