root/lm-sensors/trunk/prog/sensors/main.c @ 2925

Revision 2925, 12.2 KB (checked in by mds, 10 years ago)

w83792d driver and userspace support patch from Winbond.

by Chunhao Huang <huang0@…>
submitted by <DZShen@…>

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