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

Revision 4362, 13.0 KB (checked in by jwrdegoede, 6 years ago)

generic chip printing routine for sensors prog, by Bob Schlarmann and Luuk Kleiweg

  • 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
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <getopt.h>
23#include <string.h>
24#include <errno.h>
25#include <locale.h>
26#include <langinfo.h>
27
28#ifndef __UCLIBC__
29#include <iconv.h>
30#define HAVE_ICONV
31#endif
32
33#include "lib/sensors.h"
34#include "lib/error.h"
35#include "chips.h"
36#include "version.h"
37#include "chips_generic.h"
38
39#define PROGRAM "sensors"
40#define VERSION LM_VERSION
41#define DEFAULT_CONFIG_FILE_NAME "sensors.conf"
42
43FILE *config_file;
44extern const char *libsensors_version;
45
46extern int main(int argc, char *arv[]);
47static void print_short_help(void);
48static void print_long_help(void);
49static void print_version(void);
50static void do_a_print(sensors_chip_name name);
51static int do_a_set(sensors_chip_name name);
52static int do_the_real_work(int *error);
53static const char *sprintf_chip_name(sensors_chip_name name);
54
55#define CHIPS_MAX 20
56sensors_chip_name chips[CHIPS_MAX];
57int chips_count=0;
58int do_sets, do_unknown, fahrenheit, hide_adapter, hide_unknown, do_generic;
59
60char degstr[5]; /* store the correct string to print degrees */
61
62void print_short_help(void)
63{
64  printf("Try `%s -h' for more information\n",PROGRAM);
65}
66
67void print_long_help(void)
68{
69  printf("Usage: %s [OPTION]... [CHIP]...\n",PROGRAM);
70  printf("  -c, --config-file     Specify a config file (default: " ETCDIR "/" DEFAULT_CONFIG_FILE_NAME ")\n");
71  printf("  -h, --help            Display this help text\n");
72  printf("  -s, --set             Execute `set' statements too (root only)\n");
73  printf("  -f, --fahrenheit      Show temperatures in degrees fahrenheit\n");
74  printf("  -A, --no-adapter      Do not show adapter for each chip\n");
75  printf("  -U, --no-unknown      Do not show unknown chips\n");
76  printf("  -u, --unknown         Treat chips as unknown ones (testing only)\n");
77  printf("  -v, --version         Display the program version\n");
78  printf("  -g, --generic         Use generic printing routine for all chips (testing only)\n"); 
79  printf("\n");
80  printf("Use `-' after `-c' to read the config file from stdin.\n");
81  printf("If no chips are specified, all chip info will be printed.\n");
82  printf("Example chip names:\n");
83  printf("\tlm78-i2c-0-2d\t*-i2c-0-2d\n");
84  printf("\tlm78-i2c-0-*\t*-i2c-0-*\n");
85  printf("\tlm78-i2c-*-2d\t*-i2c-*-2d\n");
86  printf("\tlm78-i2c-*-*\t*-i2c-*-*\n");
87  printf("\tlm78-isa-0290\t*-isa-0290\n");
88  printf("\tlm78-isa-*\t*-isa-*\n");
89  printf("\tlm78-*\n");
90}
91
92void print_version(void)
93{
94  printf("%s version %s with libsensors version %s\n", PROGRAM, VERSION, libsensors_version);
95}
96
97/* This examines global var config_file, and leaves the name there too.
98   It also opens config_file. */
99void open_config_file(const char* config_file_name)
100{
101  if (!strcmp(config_file_name,"-")) {
102    config_file = stdin;
103    return;
104  }
105
106  config_file = fopen(config_file_name, "r");
107  if (!config_file) {
108    fprintf(stderr, "Could not open config file\n");
109    perror(config_file_name);
110    exit(1);
111  }
112}
113   
114void close_config_file(const char* config_file_name)
115{
116  if (fclose(config_file) == EOF) {
117    fprintf(stderr,"Could not close config file\n");
118    perror(config_file_name);
119  }
120}
121
122static void set_degstr(void)
123{
124  const char *deg_default_text[2] = {" C", " F"};
125
126#ifdef HAVE_ICONV
127  /* Size hardcoded for better performance.
128     Don't forget to count the trailing \0! */
129  size_t deg_latin1_size = 3;
130  char *deg_latin1_text[2] = {"\260C", "\260F"};
131  size_t nconv;
132  size_t degstr_size = sizeof(degstr);
133  char *degstr_ptr = degstr;
134
135  iconv_t cd = iconv_open(nl_langinfo(CODESET), "ISO-8859-1");
136  if (cd != (iconv_t) -1) {
137    nconv = iconv(cd, &(deg_latin1_text[fahrenheit]), &deg_latin1_size,
138                  &degstr_ptr, &degstr_size);
139    iconv_close(cd);
140   
141    if (nconv != (size_t) -1)
142      return;     
143  }
144#endif /* HAVE_ICONV */
145
146  /* There was an error during the conversion, use the default text */
147  strcpy(degstr, deg_default_text[fahrenheit]);
148}
149
150int main (int argc, char *argv[])
151{
152  int c,res,i,error;
153  const char *config_file_name = ETCDIR "/" DEFAULT_CONFIG_FILE_NAME;
154
155  struct option long_opts[] =  {
156    { "help", no_argument, NULL, 'h' },
157    { "set", no_argument, NULL, 's' },
158    { "version", no_argument, NULL, 'v'},
159    { "fahrenheit", no_argument, NULL, 'f' },
160    { "no-adapter", no_argument, NULL, 'A' },
161    { "no-unknown", no_argument, NULL, 'U' },
162    { "config-file", required_argument, NULL, 'c' },
163    { "unknown", no_argument, NULL, 'u' },
164    /* next option accepted for compatibility, but otherwise ignored */
165    { "algorithm", no_argument, NULL, 'a' },
166    { "generic", no_argument, NULL, 'g'},
167    { 0,0,0,0 }
168  };
169
170  setlocale(LC_CTYPE, "");
171
172  do_unknown = 0;
173  do_sets = 0;
174  hide_adapter = 0;
175  hide_unknown = 0;
176  do_generic = 0;
177  while (1) {
178    c = getopt_long(argc,argv,"hsvfaAUc:ug",long_opts,NULL);
179    if (c == EOF)
180      break;
181    switch(c) {
182    case ':':
183    case '?':
184      print_short_help();
185      exit(1);
186    case 'h':
187      print_long_help();
188      exit(0);
189    case 'v':
190      print_version();
191      exit(0);
192    case 'c':
193      config_file_name = optarg;
194      break;
195    case 's':
196      do_sets = 1;
197      break;
198    case 'f':
199      fahrenheit = 1;
200      break;
201    case 'A':
202      hide_adapter = 1;
203      break;
204    case 'U':
205      hide_unknown = 1;
206      break;
207    case 'u':
208      do_unknown = 1;
209      break;
210    case 'a':
211      /* Ignore for compatibility */
212      break;
213    case 'g':
214      do_generic = 1;
215      break;
216    default:
217      fprintf(stderr,"Internal error while parsing options!\n");
218      exit(1);
219    }
220  }
221
222  if (optind == argc) {
223    chips[0].prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
224    chips[0].bus = SENSORS_CHIP_NAME_BUS_ANY;
225    chips[0].addr = SENSORS_CHIP_NAME_ADDR_ANY;
226    chips_count = 1;
227  } else 
228    for(i = optind; i < argc; i++) 
229      if ((res = sensors_parse_chip_name(argv[i],chips+chips_count))) {
230        fprintf(stderr,"Parse error in chip name `%s'\n",argv[i]);
231        print_short_help();
232        exit(1);
233      } else if (++chips_count == CHIPS_MAX) {
234        fprintf(stderr,"Too many chips on command line!\n");
235        exit(1);
236      }
237
238  open_config_file(config_file_name);
239  if ((res = sensors_init(config_file))) {
240    fprintf(stderr,"%s\n",sensors_strerror(res));
241    if (res == -SENSORS_ERR_PROC)
242      fprintf(stderr,
243              "Kernel interface access error\n"
244              "For 2.6 kernels, make sure you have mounted sysfs and libsensors\n"
245              "was compiled with sysfs support!\n");
246    exit(1);
247  }
248  close_config_file(config_file_name);
249
250  /* build the degrees string */
251  set_degstr();
252
253  if(do_the_real_work(&error)) {
254    sensors_cleanup();
255    exit(error);
256  } else {
257    if(chips[0].prefix == SENSORS_CHIP_NAME_PREFIX_ANY)
258            fprintf(stderr,
259                    "No sensors found!\n"
260                    "Make sure you loaded all the kernel drivers you need.\n"
261                    "Try sensors-detect to find out which these are.\n");
262    else
263            fprintf(stderr,"Specified sensor(s) not found!\n");
264    sensors_cleanup();
265    exit(1);
266  }
267}
268
269/* returns number of chips found */
270int do_the_real_work(int *error)
271{
272  const sensors_chip_name *chip;
273  int chip_nr,i;
274  int cnt = 0;
275
276  *error = 0;
277  for (chip_nr = 0; (chip = sensors_get_detected_chips(&chip_nr));)
278    for(i = 0; i < chips_count; i++)
279      if (sensors_match_chip(*chip,chips[i])) {
280        if(do_sets) {
281          if (do_a_set(*chip))
282            *error = 1;
283        } else
284          do_a_print(*chip);
285        i = chips_count;
286        cnt++;
287      }
288   return(cnt);
289}
290
291/* returns 1 on error */
292int do_a_set(sensors_chip_name name)
293{
294  int res;
295
296  if ((res = sensors_do_chip_sets(name))) {
297    if (res == -SENSORS_ERR_PROC) {
298      fprintf(stderr,"%s: %s for writing;\n",sprintf_chip_name(name),
299              sensors_strerror(res));
300      fprintf(stderr,"Run as root?\n");
301      return 1;
302    } else if (res == -SENSORS_ERR_ACCESS_W) {
303      fprintf(stderr, "%s: At least one \"set\" statement failed\n",
304              sprintf_chip_name(name));
305    } else {
306      fprintf(stderr,"%s: %s\n",sprintf_chip_name(name),
307              sensors_strerror(res));
308    }
309  }
310  return 0;
311}
312
313const char *sprintf_chip_name(sensors_chip_name name)
314{
315  #define BUF_SIZE 200
316  static char buf[BUF_SIZE];
317
318  if (name.bus == SENSORS_CHIP_NAME_BUS_ISA)
319    snprintf(buf,BUF_SIZE,"%s-isa-%04x",name.prefix,name.addr);
320  else if (name.bus == SENSORS_CHIP_NAME_BUS_PCI)
321    snprintf(buf,BUF_SIZE,"%s-pci-%04x",name.prefix,name.addr);
322  else if (name.bus == SENSORS_CHIP_NAME_BUS_DUMMY)
323    snprintf(buf,BUF_SIZE,"%s-%s-%04x",name.prefix,name.busname,name.addr);
324  else
325    snprintf(buf,BUF_SIZE,"%s-i2c-%d-%02x",name.prefix,name.bus,name.addr);
326  return buf;
327}
328
329struct match {
330        const char * prefix;
331        void (*fn) (const sensors_chip_name *name);
332};
333
334struct match matches[] = {
335        { "ds1621", print_ds1621 },
336        { "lm75", print_lm75 },
337        { "adm1021", print_adm1021 },
338        { "max1617", print_adm1021 },
339        { "max1617a", print_adm1021 },
340        { "thmc10", print_adm1021 },
341        { "lm84", print_adm1021 },
342        { "gl523", print_adm1021 },
343        { "adm1023", print_adm1021 },
344        { "mc1066", print_adm1021 },
345        { "adm9240", print_adm9240 },
346        { "ds1780", print_adm9240 },
347        { "lm81", print_adm9240 },
348        { "lm78", print_lm78 },
349        { "lm78-j", print_lm78 },
350        { "lm79", print_lm78 },
351        { "mtp008", print_mtp008 },
352        { "sis5595", print_sis5595 },
353        { "via686a", print_via686a },
354        { "lm80", print_lm80 },
355        { "lm85", print_lm85 },
356        { "lm85b", print_lm85 },
357        { "lm85c", print_lm85 },
358        { "adm1027", print_lm85 },
359        { "adt7463", print_lm85 },
360        { "emc6d100", print_lm85 },
361        { "emc6d102", print_lm85 },
362        { "lm87", print_lm87 },
363        { "gl518sm", print_gl518 },
364        { "gl520sm", print_gl520 },
365        { "adm1025", print_adm1025 },
366        { "ne1619", print_adm1025 },
367        { "adm1024", print_adm1024 },
368        { "w83781d", print_w83781d },
369        { "w83782d", print_w83781d },
370        { "w83783d", print_w83781d },
371        { "w83627hf", print_w83781d },
372        { "w83627thf", print_w83781d },
373        { "w83637hf", print_w83781d },
374        { "w83697hf", print_w83781d },
375        { "w83687thf", print_w83781d },
376        { "w83627ehf", print_w83627ehf },
377        { "w83627dhg", print_w83627ehf },
378        { "w83791d", print_w83781d },
379        { "w83792d", print_w83792d },
380        { "w83793", print_w83793 },
381        { "w83l785ts", print_w83l785ts },
382        { "as99127f", print_w83781d },
383        { "maxilife", print_maxilife },
384        { "maxilife-cg", print_maxilife },
385        { "maxilife-co", print_maxilife },
386        { "maxilife-as", print_maxilife },
387        { "maxilife-nba", print_maxilife },
388        { "it87", print_it87 },
389        { "it8712", print_it87 },
390        { "it8716", print_it87 },
391        { "it8718", print_it87 },
392        { "fscpos", print_fscpos },
393        { "fscscy", print_fscscy },
394        { "fscher", print_fscher },
395        { "pcf8591", print_pcf8591 },
396        { "vt1211", print_vt1211 },
397        { "smsc47m192", print_smsc47m192 },
398        { "smsc47m1", print_smsc47m1 },
399        { "smsc47m2", print_smsc47m1 },
400        { "pc87360", print_pc87360 },
401        { "pc87363", print_pc87360 },
402        { "pc87364", print_pc87364 },
403        { "pc87365", print_pc87366 },
404        { "pc87366", print_pc87366 },
405        { "pc87427", print_pc87427 },
406        { "lm92", print_lm92 },
407        { "vt8231", print_vt8231 },
408        { "bmc", print_bmc },
409        { "adm1026", print_adm1026 },
410        { "lm83", print_lm83 },
411        { "lm90", print_lm90 },
412        { "adm1032", print_lm90 },
413        { "lm99", print_lm90 },
414        { "lm86", print_lm90 },
415        { "max6657", print_lm90 },
416        { "adt7461", print_lm90 },
417        { "lm63", print_lm63 },
418        { "xeontemp", print_xeontemp },
419        { "max6650", print_max6650 },
420        { "asb100", print_asb100 },
421        { "adm1029", print_adm1029 },
422        { "adm1030", print_adm1031 },
423        { "adm1031", print_adm1031 },
424        { "lm93", print_lm93 },
425        { "smsc47b397", print_smsc47b397 },
426        { "f71805f", print_f71805f },
427        { "f71872f", print_f71805f },
428        { "abituguru", print_abituguru },
429        { "k8temp", print_k8temp },
430        { "coretemp", print_coretemp },
431        { "dme1737", print_dme1737 },
432        { NULL, NULL }
433};
434
435void do_a_print(sensors_chip_name name)
436{
437  struct match *m;
438
439  /* do we know how to display it? */
440  for(m = matches; m->prefix != NULL; m++) {
441    if(!strcmp(name.prefix, m->prefix)) break;
442  }
443
444  if(m->prefix==NULL && hide_unknown)
445    return;
446
447  printf("%s\n",sprintf_chip_name(name));
448  if (!hide_adapter) {
449    const char *adap = sensors_get_adapter_name(name.bus);
450    if (adap)
451      printf("Adapter: %s\n", adap);
452    else
453      fprintf(stderr, "Can't get adapter name for bus %d\n", name.bus);
454  }
455  if (do_unknown)
456    print_unknown_chip(&name);
457  else if(do_generic)
458    print_generic_chip(&name);
459  else {
460    if(m->prefix == NULL)
461        print_generic_chip(&name);
462    else
463        m->fn(&name);
464  }
465  printf("\n");
466}
Note: See TracBrowser for help on using the browser.