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

Revision 2252, 12.6 KB (checked in by khali, 9 years ago)

Move degrees string construction into a single, common place.

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