root/lm-sensors/branches/lm-sensors-3.0.0/prog/sensors/main.c @ 5163

Revision 5163, 8.3 KB (checked in by khali, 7 years ago)

Patch from Aurelien Jarno:

I have just noticed that the FSF address is the old one in all files
except COPYING. Please find a patch below to fix that.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    main.c - Part of sensors, a user-space program for hardware monitoring
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 <stdio.h>
23#include <stdlib.h>
24#include <getopt.h>
25#include <string.h>
26#include <errno.h>
27#include <locale.h>
28#include <langinfo.h>
29
30#ifndef __UCLIBC__
31#include <iconv.h>
32#define HAVE_ICONV
33#endif
34
35#include "lib/sensors.h"
36#include "lib/error.h"
37#include "main.h"
38#include "chips.h"
39#include "version.h"
40
41#define PROGRAM                 "sensors"
42#define VERSION                 LM_VERSION
43
44static int do_sets, do_raw, hide_adapter;
45
46int fahrenheit;
47char degstr[5]; /* store the correct string to print degrees */
48
49static void print_short_help(void)
50{
51        printf("Try `%s -h' for more information\n", PROGRAM);
52}
53
54static void print_long_help(void)
55{
56        printf("Usage: %s [OPTION]... [CHIP]...\n", PROGRAM);
57        puts("  -c, --config-file     Specify a config file\n"
58             "  -h, --help            Display this help text\n"
59             "  -s, --set             Execute `set' statements (root only)\n"
60             "  -f, --fahrenheit      Show temperatures in degrees fahrenheit\n"
61             "  -A, --no-adapter      Do not show adapter for each chip\n"
62             "      --bus-list        Generate bus statements for sensors.conf\n"
63             "  -u                    Raw output (debugging only)\n"
64             "  -v, --version         Display the program version\n"
65             "\n"
66             "Use `-' after `-c' to read the config file from stdin.\n"
67             "If no chips are specified, all chip info will be printed.\n"
68             "Example chip names:\n"
69             "\tlm78-i2c-0-2d\t*-i2c-0-2d\n"
70             "\tlm78-i2c-0-*\t*-i2c-0-*\n"
71             "\tlm78-i2c-*-2d\t*-i2c-*-2d\n"
72             "\tlm78-i2c-*-*\t*-i2c-*-*\n"
73             "\tlm78-isa-0290\t*-isa-0290\n"
74             "\tlm78-isa-*\t*-isa-*\n"
75             "\tlm78-*");
76}
77
78static void print_version(void)
79{
80        printf("%s version %s with libsensors version %s\n", PROGRAM, VERSION,
81               libsensors_version);
82}
83
84/* Return 0 on success, and an exit error code otherwise */
85static int read_config_file(const char *config_file_name)
86{
87        FILE *config_file;
88        int err;
89
90        if (config_file_name) {
91                if (!strcmp(config_file_name, "-"))
92                        config_file = stdin;
93                else
94                        config_file = fopen(config_file_name, "r");
95
96                if (!config_file) {
97                        fprintf(stderr, "Could not open config file\n");
98                        perror(config_file_name);
99                        return 1;
100                }
101        } else {
102                /* Use libsensors default */
103                config_file = NULL;
104        }
105
106        err = sensors_init(config_file);
107        if (err) {
108                fprintf(stderr, "sensors_init: %s\n", sensors_strerror(err));
109                if (config_file)
110                        fclose(config_file);
111                return 1;
112        }
113
114        if (config_file && fclose(config_file) == EOF)
115                perror(config_file_name);
116
117        return 0;
118}
119
120static void set_degstr(void)
121{
122        const char *deg_default_text[2] = { " C", " F" };
123
124#ifdef HAVE_ICONV
125        /* Size hardcoded for better performance.
126           Don't forget to count the trailing \0! */
127        size_t deg_latin1_size = 3;
128        char *deg_latin1_text[2] = { "\260C", "\260F" };
129        size_t nconv;
130        size_t degstr_size = sizeof(degstr);
131        char *degstr_ptr = degstr;
132
133        iconv_t cd = iconv_open(nl_langinfo(CODESET), "ISO-8859-1");
134        if (cd != (iconv_t) -1) {
135                nconv = iconv(cd, &(deg_latin1_text[fahrenheit]),
136                              &deg_latin1_size, &degstr_ptr, &degstr_size);
137                iconv_close(cd);
138
139                if (nconv != (size_t) -1)
140                        return;
141        }
142#endif /* HAVE_ICONV */
143
144        /* There was an error during the conversion, use the default text */
145        strcpy(degstr, deg_default_text[fahrenheit]);
146}
147
148static const char *sprintf_chip_name(const sensors_chip_name *name)
149{
150#define BUF_SIZE 200
151        static char buf[BUF_SIZE];
152
153        if (sensors_snprintf_chip_name(buf, BUF_SIZE, name) < 0)
154                return NULL;
155        return buf;
156}
157
158static void do_a_print(const sensors_chip_name *name)
159{
160        printf("%s\n", sprintf_chip_name(name));
161        if (!hide_adapter) {
162                const char *adap = sensors_get_adapter_name(&name->bus);
163                if (adap)
164                        printf("Adapter: %s\n", adap);
165                else
166                        fprintf(stderr, "Can't get adapter name\n");
167        }
168        if (do_raw)
169                print_chip_raw(name);
170        else
171                print_chip(name);
172        printf("\n");
173}
174
175/* returns 1 on error */
176static int do_a_set(const sensors_chip_name *name)
177{
178        int res;
179
180        if ((res = sensors_do_chip_sets(name))) {
181                if (res == -SENSORS_ERR_KERNEL) {
182                        fprintf(stderr, "%s: %s;\n",
183                                sprintf_chip_name(name),
184                                sensors_strerror(res));
185                        fprintf(stderr, "Run as root?\n");
186                        return 1;
187                } else if (res == -SENSORS_ERR_ACCESS_W) {
188                        fprintf(stderr,
189                                "%s: At least one \"set\" statement failed\n",
190                                sprintf_chip_name(name));
191                } else {
192                        fprintf(stderr, "%s: %s\n", sprintf_chip_name(name),
193                                sensors_strerror(res));
194                }
195        }
196        return 0;
197}
198
199/* returns number of chips found */
200static int do_the_real_work(const sensors_chip_name *match, int *error)
201{
202        const sensors_chip_name *chip;
203        int chip_nr;
204        int cnt = 0;
205
206        chip_nr = 0;
207        while ((chip = sensors_get_detected_chips(match, &chip_nr))) {
208                if (do_sets) {
209                        if (do_a_set(chip))
210                                *error = 1;
211                } else
212                        do_a_print(chip);
213                cnt++;
214        }
215        return cnt;
216}
217
218/* List the buses in a format suitable for sensors.conf. We only list
219   bus types for which bus statements are actually useful and supported.
220   Known bug: i2c buses with number >= 32 or 64 could be listed several
221   times. Very unlikely to ever happen, though. */
222static void print_bus_list(void)
223{
224        const sensors_chip_name *chip;
225        int chip_nr;
226        unsigned long seen_i2c = 0;
227
228        chip_nr = 0;
229        while ((chip = sensors_get_detected_chips(NULL, &chip_nr))) {
230                switch (chip->bus.type) {
231                case SENSORS_BUS_TYPE_I2C:
232                        if (chip->bus.nr < (int)sizeof(unsigned long) * 8) {
233                                if (seen_i2c & (1 << chip->bus.nr))
234                                        break;
235                                seen_i2c |= 1 << chip->bus.nr;
236                        }
237                        printf("bus \"i2c-%d\" \"%s\"\n", chip->bus.nr,
238                               sensors_get_adapter_name(&chip->bus));
239                        break;
240                }
241        }
242}
243
244int main(int argc, char *argv[])
245{
246        int c, res, i, error, do_bus_list;
247        const char *config_file_name = NULL;
248
249        struct option long_opts[] =  {
250                { "help", no_argument, NULL, 'h' },
251                { "set", no_argument, NULL, 's' },
252                { "version", no_argument, NULL, 'v'},
253                { "fahrenheit", no_argument, NULL, 'f' },
254                { "no-adapter", no_argument, NULL, 'A' },
255                { "config-file", required_argument, NULL, 'c' },
256                { "bus-list", no_argument, NULL, 'B' },
257                { 0, 0, 0, 0 }
258        };
259
260        setlocale(LC_CTYPE, "");
261
262        do_raw = 0;
263        do_sets = 0;
264        do_bus_list = 0;
265        hide_adapter = 0;
266        while (1) {
267                c = getopt_long(argc, argv, "hsvfAc:u", long_opts, NULL);
268                if (c == EOF)
269                        break;
270                switch(c) {
271                case ':':
272                case '?':
273                        print_short_help();
274                        exit(1);
275                case 'h':
276                        print_long_help();
277                        exit(0);
278                case 'v':
279                        print_version();
280                        exit(0);
281                case 'c':
282                        config_file_name = optarg;
283                        break;
284                case 's':
285                        do_sets = 1;
286                        break;
287                case 'f':
288                        fahrenheit = 1;
289                        break;
290                case 'A':
291                        hide_adapter = 1;
292                        break;
293                case 'u':
294                        do_raw = 1;
295                        break;
296                case 'B':
297                        do_bus_list = 1;
298                        break;
299                default:
300                        fprintf(stderr,
301                                "Internal error while parsing options!\n");
302                        exit(1);
303                }
304        }
305
306        res = read_config_file(config_file_name);
307        if (res)
308                exit(res);
309
310        /* build the degrees string */
311        set_degstr();
312
313        if (do_bus_list) {
314                print_bus_list();
315        } else if (optind == argc) { /* No chip name on command line */
316                if (!do_the_real_work(NULL, &error)) {
317                        fprintf(stderr,
318                                "No sensors found!\n"
319                                "Make sure you loaded all the kernel drivers you need.\n"
320                                "Try sensors-detect to find out which these are.\n");
321                        error = 1;
322                }
323        } else {
324                int cnt = 0;
325                sensors_chip_name chip;
326
327                for (i = optind; i < argc; i++) {
328                        if (sensors_parse_chip_name(argv[i], &chip)) {
329                                fprintf(stderr,
330                                        "Parse error in chip name `%s'\n",
331                                        argv[i]);
332                                print_short_help();
333                                error = 1;
334                                goto exit;
335                        }
336                        cnt += do_the_real_work(&chip, &error);
337                }
338
339                if (!cnt) {
340                        fprintf(stderr, "Specified sensor(s) not found!\n");
341                        error = 1;
342                }
343        }
344
345exit:
346        sensors_cleanup();
347        exit(res);
348}
Note: See TracBrowser for help on using the browser.