Thu Dec 13 20:06:42 2012 UTC ()
- no point in allocating memory to hold command line arguments.
- allocate memory inside the function used.


(christos)
diff -r1.92 -r1.93 src/usr.sbin/envstat/envstat.c

cvs diff -r1.92 -r1.93 src/usr.sbin/envstat/envstat.c (expand / switch to unified diff)

--- src/usr.sbin/envstat/envstat.c 2012/12/13 19:31:25 1.92
+++ src/usr.sbin/envstat/envstat.c 2012/12/13 20:06:42 1.93
@@ -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 */
103static SIMPLEQ_HEAD(, envsys_sensor_stats) sensor_stats_list = 103static SIMPLEQ_HEAD(, envsys_sensor_stats) sensor_stats_list =
104 SIMPLEQ_HEAD_INITIALIZER(sensor_stats_list); 104 SIMPLEQ_HEAD_INITIALIZER(sensor_stats_list);
105 105
106static unsigned int interval, flags, width; 106static unsigned int interval, flags, width;
107static char *mydevname, *sensors; 107static char *mydevname, *sensors;
108static bool statistics; 108static bool statistics;
109static u_int header_passes; 109static u_int header_passes;
110 110
111static int parse_dictionary(int); 111static int parse_dictionary(int);
112static int send_dictionary(FILE *); 112static int send_dictionary(FILE *);
113static int find_sensors(prop_array_t, const char *, dvprops_t); 113static int find_sensors(prop_array_t, const char *, dvprops_t);
114static void print_sensors(void); 114static void print_sensors(void);
115static int check_sensors(char *); 115static int check_sensors(const char *);
116static int usage(void); 116static int usage(void);
117 117
118static int sysmonfd; /* fd of /dev/sysmon */ 118static int sysmonfd; /* fd of /dev/sysmon */
119 119
120int main(int argc, char **argv) 120int 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
293static int 283static int
294send_dictionary(FILE *cf) 284send_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
455out: 438out:
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
661static int 644static int
662check_sensors(char *str) 645check_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");
 700out:
 701 free(s);
712 return EINVAL; 702 return EINVAL;
713} 703}
714 704
715static void 705static void
716print_sensors(void) 706print_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