| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: envstat.c,v 1.92 2012/12/13 19:31:25 christos Exp $ */ | | 1 | /* $NetBSD: envstat.c,v 1.93 2012/12/13 20:06:42 christos Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2007, 2008 Juan Romero Pardines. | | 4 | * Copyright (c) 2007, 2008 Juan Romero Pardines. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,27 +17,27 @@ | | | @@ -17,27 +17,27 @@ |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | | 26 | */ |
27 | | | 27 | |
28 | #include <sys/cdefs.h> | | 28 | #include <sys/cdefs.h> |
29 | #ifndef lint | | 29 | #ifndef lint |
30 | __RCSID("$NetBSD: envstat.c,v 1.92 2012/12/13 19:31:25 christos Exp $"); | | 30 | __RCSID("$NetBSD: envstat.c,v 1.93 2012/12/13 20:06:42 christos Exp $"); |
31 | #endif /* not lint */ | | 31 | #endif /* not lint */ |
32 | | | 32 | |
33 | #include <stdio.h> | | 33 | #include <stdio.h> |
34 | #include <stdlib.h> | | 34 | #include <stdlib.h> |
35 | #include <stdbool.h> | | 35 | #include <stdbool.h> |
36 | #include <stdarg.h> | | 36 | #include <stdarg.h> |
37 | #include <stdint.h> | | 37 | #include <stdint.h> |
38 | #include <string.h> | | 38 | #include <string.h> |
39 | #include <unistd.h> | | 39 | #include <unistd.h> |
40 | #include <fcntl.h> | | 40 | #include <fcntl.h> |
41 | #include <err.h> | | 41 | #include <err.h> |
42 | #include <errno.h> | | 42 | #include <errno.h> |
43 | #include <paths.h> | | 43 | #include <paths.h> |
| @@ -102,57 +102,53 @@ static SIMPLEQ_HEAD(, envsys_sensor) sen | | | @@ -102,57 +102,53 @@ static SIMPLEQ_HEAD(, envsys_sensor) sen |
102 | /* A simple queue to manage statistics for all sensors */ | | 102 | /* A simple queue to manage statistics for all sensors */ |
103 | static SIMPLEQ_HEAD(, envsys_sensor_stats) sensor_stats_list = | | 103 | static SIMPLEQ_HEAD(, envsys_sensor_stats) sensor_stats_list = |
104 | SIMPLEQ_HEAD_INITIALIZER(sensor_stats_list); | | 104 | SIMPLEQ_HEAD_INITIALIZER(sensor_stats_list); |
105 | | | 105 | |
106 | static unsigned int interval, flags, width; | | 106 | static unsigned int interval, flags, width; |
107 | static char *mydevname, *sensors; | | 107 | static char *mydevname, *sensors; |
108 | static bool statistics; | | 108 | static bool statistics; |
109 | static u_int header_passes; | | 109 | static u_int header_passes; |
110 | | | 110 | |
111 | static int parse_dictionary(int); | | 111 | static int parse_dictionary(int); |
112 | static int send_dictionary(FILE *); | | 112 | static int send_dictionary(FILE *); |
113 | static int find_sensors(prop_array_t, const char *, dvprops_t); | | 113 | static int find_sensors(prop_array_t, const char *, dvprops_t); |
114 | static void print_sensors(void); | | 114 | static void print_sensors(void); |
115 | static int check_sensors(char *); | | 115 | static int check_sensors(const char *); |
116 | static int usage(void); | | 116 | static int usage(void); |
117 | | | 117 | |
118 | static int sysmonfd; /* fd of /dev/sysmon */ | | 118 | static int sysmonfd; /* fd of /dev/sysmon */ |
119 | | | 119 | |
120 | int main(int argc, char **argv) | | 120 | int main(int argc, char **argv) |
121 | { | | 121 | { |
122 | prop_dictionary_t dict; | | 122 | prop_dictionary_t dict; |
123 | int c, rval = 0; | | 123 | int c, rval = 0; |
124 | char *endptr, *configfile = NULL; | | 124 | char *endptr, *configfile = NULL; |
125 | FILE *cf; | | 125 | FILE *cf; |
126 | | | 126 | |
127 | if (prog_init && prog_init() == -1) | | 127 | if (prog_init && prog_init() == -1) |
128 | err(1, "init failed"); | | 128 | err(1, "init failed"); |
129 | | | 129 | |
130 | setprogname(argv[0]); | | 130 | setprogname(argv[0]); |
131 | | | 131 | |
132 | while ((c = getopt(argc, argv, "c:Dd:fIi:klrSs:Tw:Wx")) != -1) { | | 132 | while ((c = getopt(argc, argv, "c:Dd:fIi:klrSs:Tw:Wx")) != -1) { |
133 | switch (c) { | | 133 | switch (c) { |
134 | case 'c': /* configuration file */ | | 134 | case 'c': /* configuration file */ |
135 | configfile = strdup(optarg); | | 135 | configfile = optarg; |
136 | if (configfile == NULL) | | | |
137 | err(EXIT_FAILURE, "strdup"); | | | |
138 | break; | | 136 | break; |
139 | case 'D': /* list registered devices */ | | 137 | case 'D': /* list registered devices */ |
140 | flags |= ENVSYS_DFLAG; | | 138 | flags |= ENVSYS_DFLAG; |
141 | break; | | 139 | break; |
142 | case 'd': /* show sensors of a specific device */ | | 140 | case 'd': /* show sensors of a specific device */ |
143 | mydevname = strdup(optarg); | | 141 | mydevname = optarg; |
144 | if (mydevname == NULL) | | | |
145 | err(EXIT_FAILURE, "strdup"); | | | |
146 | break; | | 142 | break; |
147 | case 'f': /* display temperature in Farenheit */ | | 143 | case 'f': /* display temperature in Farenheit */ |
148 | flags |= ENVSYS_FFLAG; | | 144 | flags |= ENVSYS_FFLAG; |
149 | break; | | 145 | break; |
150 | case 'I': /* Skips invalid sensors */ | | 146 | case 'I': /* Skips invalid sensors */ |
151 | flags |= ENVSYS_IFLAG; | | 147 | flags |= ENVSYS_IFLAG; |
152 | break; | | 148 | break; |
153 | case 'i': /* wait time between intervals */ | | 149 | case 'i': /* wait time between intervals */ |
154 | interval = (unsigned int)strtoul(optarg, &endptr, 10); | | 150 | interval = (unsigned int)strtoul(optarg, &endptr, 10); |
155 | if (*endptr != '\0') | | 151 | if (*endptr != '\0') |
156 | errx(EXIT_FAILURE, "bad interval '%s'", optarg); | | 152 | errx(EXIT_FAILURE, "bad interval '%s'", optarg); |
157 | break; | | 153 | break; |
158 | case 'k': /* display temperature in Kelvin */ | | 154 | case 'k': /* display temperature in Kelvin */ |
| @@ -161,29 +157,27 @@ int main(int argc, char **argv) | | | @@ -161,29 +157,27 @@ int main(int argc, char **argv) |
161 | case 'l': /* list sensors */ | | 157 | case 'l': /* list sensors */ |
162 | flags |= ENVSYS_LFLAG; | | 158 | flags |= ENVSYS_LFLAG; |
163 | break; | | 159 | break; |
164 | case 'r': | | 160 | case 'r': |
165 | /* | | 161 | /* |
166 | * This flag is noop.. it's only here for | | 162 | * This flag is noop.. it's only here for |
167 | * compatibility with the old implementation. | | 163 | * compatibility with the old implementation. |
168 | */ | | 164 | */ |
169 | break; | | 165 | break; |
170 | case 'S': | | 166 | case 'S': |
171 | flags |= ENVSYS_SFLAG; | | 167 | flags |= ENVSYS_SFLAG; |
172 | break; | | 168 | break; |
173 | case 's': /* only show specified sensors */ | | 169 | case 's': /* only show specified sensors */ |
174 | sensors = strdup(optarg); | | 170 | sensors = optarg; |
175 | if (sensors == NULL) | | | |
176 | err(EXIT_FAILURE, "strdup"); | | | |
177 | break; | | 171 | break; |
178 | case 'T': /* make statistics */ | | 172 | case 'T': /* make statistics */ |
179 | flags |= ENVSYS_TFLAG; | | 173 | flags |= ENVSYS_TFLAG; |
180 | break; | | 174 | break; |
181 | case 'w': /* width value for the lines */ | | 175 | case 'w': /* width value for the lines */ |
182 | width = (unsigned int)strtoul(optarg, &endptr, 10); | | 176 | width = (unsigned int)strtoul(optarg, &endptr, 10); |
183 | if (*endptr != '\0') | | 177 | if (*endptr != '\0') |
184 | errx(EXIT_FAILURE, "bad width '%s'", optarg); | | 178 | errx(EXIT_FAILURE, "bad width '%s'", optarg); |
185 | break; | | 179 | break; |
186 | case 'x': /* print the dictionary in raw format */ | | 180 | case 'x': /* print the dictionary in raw format */ |
187 | flags |= ENVSYS_XFLAG; | | 181 | flags |= ENVSYS_XFLAG; |
188 | break; | | 182 | break; |
189 | case 'W': /* No longer used, retained for compatibility */ | | 183 | case 'W': /* No longer used, retained for compatibility */ |
| @@ -271,30 +265,26 @@ int main(int argc, char **argv) | | | @@ -271,30 +265,26 @@ int main(int argc, char **argv) |
271 | for (;;) { | | 265 | for (;;) { |
272 | rval = parse_dictionary(sysmonfd); | | 266 | rval = parse_dictionary(sysmonfd); |
273 | if (rval) | | 267 | if (rval) |
274 | break; | | 268 | break; |
275 | | | 269 | |
276 | (void)fflush(stdout); | | 270 | (void)fflush(stdout); |
277 | (void)sleep(interval); | | 271 | (void)sleep(interval); |
278 | } | | 272 | } |
279 | /* Show sensors without interval */ | | 273 | /* Show sensors without interval */ |
280 | } else { | | 274 | } else { |
281 | rval = parse_dictionary(sysmonfd); | | 275 | rval = parse_dictionary(sysmonfd); |
282 | } | | 276 | } |
283 | | | 277 | |
284 | if (sensors) | | | |
285 | free(sensors); | | | |
286 | if (mydevname) | | | |
287 | free(mydevname); | | | |
288 | (void)prog_close(sysmonfd); | | 278 | (void)prog_close(sysmonfd); |
289 | | | 279 | |
290 | return rval ? EXIT_FAILURE : EXIT_SUCCESS; | | 280 | return rval ? EXIT_FAILURE : EXIT_SUCCESS; |
291 | } | | 281 | } |
292 | | | 282 | |
293 | static int | | 283 | static int |
294 | send_dictionary(FILE *cf) | | 284 | send_dictionary(FILE *cf) |
295 | { | | 285 | { |
296 | prop_dictionary_t kdict, udict; | | 286 | prop_dictionary_t kdict, udict; |
297 | int error = 0; | | 287 | int error = 0; |
298 | | | 288 | |
299 | /* Retrieve dictionary from kernel */ | | 289 | /* Retrieve dictionary from kernel */ |
300 | error = prop_dictionary_recv_ioctl(sysmonfd, | | 290 | error = prop_dictionary_recv_ioctl(sysmonfd, |
| @@ -428,35 +418,28 @@ parse_dictionary(int fd) | | | @@ -428,35 +418,28 @@ parse_dictionary(int fd) |
428 | (void)printf("second)\n"); | | 418 | (void)printf("second)\n"); |
429 | else | | 419 | else |
430 | (void)printf("%d seconds)\n", | | 420 | (void)printf("%d seconds)\n", |
431 | (int)edp->refresh_timo); | | 421 | (int)edp->refresh_timo); |
432 | } | | 422 | } |
433 | | | 423 | |
434 | free(edp); | | 424 | free(edp); |
435 | edp = NULL; | | 425 | edp = NULL; |
436 | } | | 426 | } |
437 | prop_object_iterator_release(iter); | | 427 | prop_object_iterator_release(iter); |
438 | } | | 428 | } |
439 | | | 429 | |
440 | /* print sensors now */ | | 430 | /* print sensors now */ |
441 | if (sensors) { | | 431 | if (sensors) |
442 | char *str = strdup(sensors); | | 432 | rval = check_sensors(sensors); |
443 | if (!str) { | | | |
444 | rval = ENOMEM; | | | |
445 | goto out; | | | |
446 | } | | | |
447 | rval = check_sensors(str); | | | |
448 | free(str); | | | |
449 | } | | | |
450 | if ((flags & ENVSYS_LFLAG) == 0 && (flags & ENVSYS_DFLAG) == 0) | | 433 | if ((flags & ENVSYS_LFLAG) == 0 && (flags & ENVSYS_DFLAG) == 0) |
451 | print_sensors(); | | 434 | print_sensors(); |
452 | if (interval) | | 435 | if (interval) |
453 | (void)printf("\n"); | | 436 | (void)printf("\n"); |
454 | | | 437 | |
455 | out: | | 438 | out: |
456 | while ((sensor = SIMPLEQ_FIRST(&sensors_list))) { | | 439 | while ((sensor = SIMPLEQ_FIRST(&sensors_list))) { |
457 | SIMPLEQ_REMOVE_HEAD(&sensors_list, entries); | | 440 | SIMPLEQ_REMOVE_HEAD(&sensors_list, entries); |
458 | free(sensor); | | 441 | free(sensor); |
459 | } | | 442 | } |
460 | if (edp) | | 443 | if (edp) |
461 | free(edp); | | 444 | free(edp); |
462 | prop_object_release(dict); | | 445 | prop_object_release(dict); |
| @@ -649,76 +632,83 @@ find_sensors(prop_array_t array, const c | | | @@ -649,76 +632,83 @@ find_sensors(prop_array_t array, const c |
649 | | | 632 | |
650 | /* compute avg value */ | | 633 | /* compute avg value */ |
651 | stats->avg = | | 634 | stats->avg = |
652 | (sensor->cur_value + stats->max + stats->min) / 3; | | 635 | (sensor->cur_value + stats->max + stats->min) / 3; |
653 | } | | 636 | } |
654 | } | | 637 | } |
655 | | | 638 | |
656 | /* free memory */ | | 639 | /* free memory */ |
657 | prop_object_iterator_release(iter); | | 640 | prop_object_iterator_release(iter); |
658 | return 0; | | 641 | return 0; |
659 | } | | 642 | } |
660 | | | 643 | |
661 | static int | | 644 | static int |
662 | check_sensors(char *str) | | 645 | check_sensors(const char *str) |
663 | { | | 646 | { |
664 | sensor_t sensor = NULL; | | 647 | sensor_t sensor = NULL; |
665 | char *dvstring, *sstring, *p, *last; | | 648 | char *dvstring, *sstring, *p, *last, *s; |
666 | bool sensor_found = false; | | 649 | bool sensor_found = false; |
667 | | | 650 | |
| | | 651 | if ((s = strdup(str)) == NULL) |
| | | 652 | return errno; |
| | | 653 | |
668 | /* | | 654 | /* |
669 | * Parse device name and sensor description and find out | | 655 | * Parse device name and sensor description and find out |
670 | * if the sensor is valid. | | 656 | * if the sensor is valid. |
671 | */ | | 657 | */ |
672 | for ((p = strtok_r(str, ",", &last)); p; | | 658 | for ((p = strtok_r(s, ",", &last)); p; |
673 | (p = strtok_r(NULL, ",", &last))) { | | 659 | (p = strtok_r(NULL, ",", &last))) { |
674 | /* get device name */ | | 660 | /* get device name */ |
675 | dvstring = strtok(p, ":"); | | 661 | dvstring = strtok(p, ":"); |
676 | if (dvstring == NULL) { | | 662 | if (dvstring == NULL) { |
677 | warnx("missing device name"); | | 663 | warnx("missing device name"); |
678 | return EINVAL; | | 664 | goto out; |
679 | } | | 665 | } |
680 | | | 666 | |
681 | /* get sensor description */ | | 667 | /* get sensor description */ |
682 | sstring = strtok(NULL, ":"); | | 668 | sstring = strtok(NULL, ":"); |
683 | if (sstring == NULL) { | | 669 | if (sstring == NULL) { |
684 | warnx("missing sensor description"); | | 670 | warnx("missing sensor description"); |
685 | return EINVAL; | | 671 | goto out; |
686 | } | | 672 | } |
687 | | | 673 | |
688 | SIMPLEQ_FOREACH(sensor, &sensors_list, entries) { | | 674 | SIMPLEQ_FOREACH(sensor, &sensors_list, entries) { |
689 | /* skip until we match device */ | | 675 | /* skip until we match device */ |
690 | if (strcmp(dvstring, sensor->dvname)) | | 676 | if (strcmp(dvstring, sensor->dvname)) |
691 | continue; | | 677 | continue; |
692 | if (strcmp(sstring, sensor->desc) == 0) { | | 678 | if (strcmp(sstring, sensor->desc) == 0) { |
693 | sensor->visible = true; | | 679 | sensor->visible = true; |
694 | sensor_found = true; | | 680 | sensor_found = true; |
695 | break; | | 681 | break; |
696 | } | | 682 | } |
697 | } | | 683 | } |
698 | if (sensor_found == false) { | | 684 | if (sensor_found == false) { |
699 | warnx("unknown sensor `%s' for device `%s'", | | 685 | warnx("unknown sensor `%s' for device `%s'", |
700 | sstring, dvstring); | | 686 | sstring, dvstring); |
701 | return EINVAL; | | 687 | goto out; |
702 | } | | 688 | } |
703 | sensor_found = false; | | 689 | sensor_found = false; |
704 | } | | 690 | } |
705 | | | 691 | |
706 | /* check if all sensors were ok, and error out if not */ | | 692 | /* check if all sensors were ok, and error out if not */ |
707 | SIMPLEQ_FOREACH(sensor, &sensors_list, entries) | | 693 | SIMPLEQ_FOREACH(sensor, &sensors_list, entries) |
708 | if (sensor->visible) | | 694 | if (sensor->visible) { |
| | | 695 | free(s); |
709 | return 0; | | 696 | return 0; |
| | | 697 | } |
710 | | | 698 | |
711 | warnx("no sensors selected to display"); | | 699 | warnx("no sensors selected to display"); |
| | | 700 | out: |
| | | 701 | free(s); |
712 | return EINVAL; | | 702 | return EINVAL; |
713 | } | | 703 | } |
714 | | | 704 | |
715 | static void | | 705 | static void |
716 | print_sensors(void) | | 706 | print_sensors(void) |
717 | { | | 707 | { |
718 | sensor_t sensor; | | 708 | sensor_t sensor; |
719 | sensor_stats_t stats = NULL; | | 709 | sensor_stats_t stats = NULL; |
720 | size_t maxlen = 0, ilen; | | 710 | size_t maxlen = 0, ilen; |
721 | double temp = 0; | | 711 | double temp = 0; |
722 | const char *invalid = "N/A", *degrees, *tmpstr, *stype; | | 712 | const char *invalid = "N/A", *degrees, *tmpstr, *stype; |
723 | const char *a, *b, *c, *d, *e, *units; | | 713 | const char *a, *b, *c, *d, *e, *units; |
724 | | | 714 | |