diff options
| author | groo <groo@NetBSD.org> | 2000-03-10 05:51:56 +0000 |
|---|---|---|
| committer | groo <groo@NetBSD.org> | 2000-03-10 05:51:56 +0000 |
| commit | 38cfdfd8fc82fe3e90cea77f719de8fd7b005755 (patch) | |
| tree | 416c05a24b8896adbc3bc984657cc44a598d06b5 /usr.sbin/envstat | |
| parent | cf32e2713c5a19d6b82c2c3e11f612352ecddb2f (diff) | |
Add envstat(8) for displaying sensor readings from any envsys(4)
compatible device.
Diffstat (limited to 'usr.sbin/envstat')
| -rw-r--r-- | usr.sbin/envstat/Makefile | 7 | ||||
| -rw-r--r-- | usr.sbin/envstat/envstat.8 | 101 | ||||
| -rw-r--r-- | usr.sbin/envstat/envstat.c | 462 |
3 files changed, 570 insertions, 0 deletions
diff --git a/usr.sbin/envstat/Makefile b/usr.sbin/envstat/Makefile new file mode 100644 index 00000000000..7bba8ba5498 --- /dev/null +++ b/usr.sbin/envstat/Makefile @@ -0,0 +1,7 @@ +# $NetBSD: Makefile,v 1.1 2000/03/10 05:51:57 groo Exp $ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= envstat +MAN= envstat.8 + +.include <bsd.prog.mk> diff --git a/usr.sbin/envstat/envstat.8 b/usr.sbin/envstat/envstat.8 new file mode 100644 index 00000000000..e076bacf227 --- /dev/null +++ b/usr.sbin/envstat/envstat.8 @@ -0,0 +1,101 @@ +.\" $NetBSD: envstat.8,v 1.1 2000/03/10 05:51:58 groo Exp $ +.\" +.\" Copyright (c) 2000 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Bill Squier. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the NetBSD +.\" Foundation, Inc. and its contributors. +.\" 4. Neither the name of The NetBSD Foundation nor the names of its +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd March 8, 2000 +.Dt ENVSTAT 8 +.Os +.Sh NAME +.Nm envstat +.Nd display environmental sensor readings +.Sh SYNOPSIS +.Nm +.Op Fl fl +.Op Fl i Ar interval +.Op Fl n Ar headrep +.Op Fl s Ar sensor1,sensor2,... +.Op Fl w Ar width +.Ar device +.Sh DESCRIPTION +.Nm +displays sensor readings from any device which supports the +.Xr envsys 4 +API. Readings are displayed in columns, one column per sensor. Column +widths as well as displayed sensors are fully customizable. The column +headers display the name (stored in the device driver) as well as +the units of each sensor. +.Pp +The options are as follows: +.Bl -tag -width flag +.It Fl f +Display any temperature values in degrees Fahrenheit. The default is to +display temperature values in degrees Celsius. +.It Fl l +List the names of all supported sensors, one per line. Use of this +flag causes +.Nm +to ignore all other option flags. +.It Fl i +Repeat the display every +.Ar interval +seconds. Note that some devices do not provide fresh values on demand. +See the individual device's manual page for meaningful values for +.Ar interval . +If not specified, or specified as 0, +.Nm +produces one line of values and exits. +.It Fl n +Display a new header every +.Ar headrep +lines. An argument of 0 disables header line printing completely. +The default is every 22 lines. +.It Fl s +Restrict the display to the named sensors. The sensor names must be +supplied as a comma separated list. Sensor names are case sensitive. +.It Fl w +Use +.Ar width +as the column width for the output. Each column is additionally separated +by a single space. The default is either the length of the longest sensor +name or spread evenly to fill 80 columns, whichever is greater. +.El +.Sh SEE ALSO +.Xr envsys 4 , +.Xr lm 4 +.Sh HISTORY +.Nm +appeared in +.Nx 1.5 . + diff --git a/usr.sbin/envstat/envstat.c b/usr.sbin/envstat/envstat.c new file mode 100644 index 00000000000..9805ae997b8 --- /dev/null +++ b/usr.sbin/envstat/envstat.c @@ -0,0 +1,462 @@ +/* $NetBSD: envstat.c,v 1.1 2000/03/10 05:51:58 groo Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Bill Squier. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +#ifndef lint +__RCSID("$NetBSD: envstat.c,v 1.1 2000/03/10 05:51:58 groo Exp $"); +#endif + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/envsys.h> +#include <sys/ioctl.h> + +extern char *__progname; +const char E_CANTENUM[] = "envsys: cannot enumerate sensors\n"; + +int main __P((int, char **)); +void listsensors __P((envsys_basic_info_t *, int)); +int numsensors __P((int)); +int fillsensors __P((int, envsys_tre_data_t *, envsys_basic_info_t *, int)); +int longestname __P((envsys_basic_info_t *, int)); +int marksensors __P((envsys_basic_info_t *, int *, char *, int)); +int strtosnum __P((envsys_basic_info_t *, const char *, int)); +void header __P((unsigned, int, envsys_basic_info_t *, const int * const, + int)); +void values __P((unsigned, int, envsys_tre_data_t *, const int * const, int)); +void usage __P((void)); + + +int +main(argc, argv) + int argc; + char **argv; +{ + extern int optind; + extern char *optarg; + int c, fd, ns, ls, celsius; + unsigned int interval, width, headrep, headcnt; + envsys_tre_data_t *etds; + envsys_basic_info_t *ebis; + int *cetds; + char *sensors; + + fd = -1; + ls = 0; + celsius = 1; + interval = 0; + width = 0; + sensors = NULL; + headrep = 22; + + while ((c = getopt(argc, argv, "cfi:ln:s:w:")) != -1) { + switch(c) { + case 'i': /* wait time between displays */ + interval = atoi(optarg); + break; + case 'w': /* minimum column width */ + width = atoi(optarg); + break; + case 'l': /* list sensor names */ + ls = 1; + break; + case 'n': /* repeat header every headrep lines */ + headrep = atoi(optarg); + break; + case 's': /* restrict display to named sensors */ + sensors = (char *)malloc(strlen(optarg) + 1); + if (sensors == NULL) + exit(1); + strcpy(sensors, optarg); + break; + case 'f': /* display temp in degF */ + celsius = 0; + break; + case '?': + default: + usage(); + /* NOTREACHED */ + } + } + + if (optind < argc) { + if ((fd = open(argv[optind], O_RDONLY)) == -1) { + perror("envstat"); + exit(1); + } + } else { + fprintf(stderr, "envstat: no device specified\n"); + usage(); + } + + + /* + * Determine number of sensors, allocate and fill arrays with + * initial information. Determine column width + */ + if ((ns = numsensors(fd)) <= 0) { + fprintf(stderr, E_CANTENUM); + exit(1); + } + + cetds = (int *)malloc(ns * sizeof(int)); + etds = (envsys_tre_data_t *)malloc(ns * sizeof(envsys_tre_data_t)); + ebis = (envsys_basic_info_t *)malloc(ns * sizeof(envsys_basic_info_t)); + + if ((cetds == NULL) || (etds == NULL) || (ebis == NULL)) { + fprintf(stderr, "envstat: cannot allocate memory\n"); + exit(1); + } + + if (fillsensors(fd, etds, ebis, ns) == -1) { + fprintf(stderr, E_CANTENUM); + exit(1); + } + + + if (ls) { + listsensors(ebis, ns); + exit(0); + } + + +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + if (!width) { + width = longestname(ebis, ns); + width = MAX(((79 - ns) / ns), width); + } + + /* Mark which sensor numbers are to be displayed */ + if (marksensors(ebis, cetds, sensors, ns) == -1) + exit(1); + + /* If we didn't specify an interval value, print the sensors once */ + if (!interval) { + if (headrep) + header(width, celsius, ebis, cetds, ns); + values(width, celsius, etds, cetds, ns); + + exit (0); + } + + headcnt = 0; + if (headrep) + header(width, celsius, ebis, cetds, ns); + + for (;;) { + values(width, celsius, etds, cetds, ns); + if (headrep && (++headcnt == headrep)) { + headcnt = 0; + header(width, celsius, ebis, cetds, ns); + } + + sleep(interval); + + if (fillsensors(fd, etds, ebis, ns) == -1) { + fprintf(stderr, E_CANTENUM); + exit(1); + } + } + + /* NOTREACHED */ + return (0); +} + + +static const char *unit_str[] = {"degC", "RPM", "VAC", "Vcc", "Ohms", "Watts", + "Amps", "Ukn"}; + +/* + * pre: cetds[i] != 0 iff sensor i should appear in the output + * post: a column header line is displayed on stdout + */ +void +header(width, celsius, ebis, cetds, ns) + unsigned width; + int celsius; + envsys_basic_info_t *ebis; + const int * const cetds; + int ns; +{ + int i; + const char *s; + + /* sensor names */ + for (i = 0; i < ns; ++i) + if (cetds[i]) + printf(" %*.*s", (int)width, (int)width, ebis[i].desc); + + printf("\n"); + + /* units */ + for (i = 0; i < ns; ++i) + if (cetds[i]) { + if ((ebis[i].units == ENVSYS_STEMP) && + !celsius) + s = "degF"; + else if (ebis[i].units > 6) + s = unit_str[7]; + else + s = unit_str[ebis[i].units]; + + printf(" %*.*s", (int)width, (int)width, s); + } + printf("\n"); +} + +void +values(width, celsius, etds, cetds, ns) + unsigned width; + int celsius; + envsys_tre_data_t *etds; + const int * const cetds; + int ns; +{ + int i; + double temp; + + for (i = 0; i < ns; ++i) + if (cetds[i]) { + + /* * sensors without valid data */ + if ((etds[i].validflags & ENVSYS_FCURVALID) == 0) { + printf(" %*.*s", (int)width, (int)width, "*"); + continue; + } + + switch(etds[i].units) { + case ENVSYS_STEMP: + temp = (etds[i].cur.data_us / 1000000.0) - + 273.15; + if (!celsius) + temp = (9.0 / 5.0) * temp + 32.0; + printf(" %*.2f", width, temp); + break; + case ENVSYS_SFANRPM: + printf(" %*u", width, etds[i].cur.data_us); + break; + default: + printf(" %*.2f", width, etds[i].cur.data_s / + 1000000.0); + break; + } + } + printf("\n"); +} + + +/* + * post: displays usage on stderr + */ +void +usage() +{ + fprintf(stderr, "usage: %s [-c] [-s s1,s2,...]", __progname); + fprintf(stderr, " [-i interval] [-n headrep] [-w width] device\n"); + fprintf(stderr, " envstat -l device\n"); + exit(1); +} + + +/* + * post: a list of sensor names supported by the device is displayed on stdout + */ +void +listsensors(ebis, ns) + envsys_basic_info_t *ebis; + int ns; +{ + int i; + + for (i = 0; i < ns; ++i) + if (ebis[i].validflags & ENVSYS_FVALID) + printf("%s\n", ebis[i].desc); +} + + +/* + * pre: fd contains a valid file descriptor of an envsys(4) supporting device + * post: returns the number of valid sensors provided by the device + * or -1 on error + */ +int +numsensors(fd) + int fd; +{ + int count = 0, valid = 1; + envsys_tre_data_t etd; + etd.sensor = 0; + + while (valid) { + if (ioctl(fd, ENVSYS_GTREDATA, &etd) == -1) { + fprintf(stderr, E_CANTENUM); + exit(1); + } + + valid = etd.validflags & ENVSYS_FVALID; + if (valid) + ++count; + + ++etd.sensor; + } + + return count; +} + +/* + * pre: fd contains a valid file descriptor of an envsys(4) supporting device + * && ns is the number of sensors + * && etds and ebis are arrays of sufficient size + * post: returns 0 and etds and ebis arrays are filled with sensor info + * or returns -1 on failure + */ +int +fillsensors(fd, etds, ebis, ns) + int fd; + envsys_tre_data_t *etds; + envsys_basic_info_t *ebis; + int ns; +{ + int i; + + for (i = 0; i < ns; ++i) { + ebis[i].sensor = i; + if (ioctl(fd, ENVSYS_GTREINFO, &ebis[i]) == -1) + return -1; + + etds[i].sensor = i; + if (ioctl(fd, ENVSYS_GTREDATA, &etds[i]) == -1) + return -1; + } + + return 0; +} + + +/* + * post: returns the strlen() of the longest sensor name + */ +int +longestname(ebis, ns) + envsys_basic_info_t *ebis; + int ns; +{ + int i, maxlen, cur; + + maxlen = 0; + + for (i = 0; i < ns; ++i) { + cur = strlen(ebis[i].desc); + if (cur > maxlen) + maxlen = cur; + } + + return maxlen; +} + +/* + * post: returns 0 and cetds[i] != 0 iff sensor i should appear in the output + * or returns -1 + */ +int +marksensors(ebis, cetds, sensors, ns) + envsys_basic_info_t *ebis; + int *cetds; + char *sensors; + int ns; +{ + int i; + char *s; + + if (sensors == NULL) { + /* No sensors specified, include them all */ + for (i = 0; i < ns; ++i) + cetds[i] = 1; + + return 0; + } + + /* Assume no sensors in display */ + memset(cetds, 0, ns * sizeof(int)); + + s = strtok(sensors, ","); + while (s != NULL) { + if ((i = strtosnum(ebis, s, ns)) != -1) + cetds[i] = 1; + else { + fprintf(stderr, "envstat: unknown sensor %s\n", s); + return (-1); + } + + s = strtok(NULL, ","); + } + + /* Check if we have at least one sensor selected for output */ + for (i = 0; i < ns; ++i) + if (cetds[i] == 1) + return (0); + + fprintf(stderr, "envstat: no sensors selected for display\n"); + return (-1); +} + + +/* + * returns -1 if s is not a valid sensor name for the device + * or the sensor number of a sensor which has that name + */ +int +strtosnum(ebis, s, ns) + envsys_basic_info_t *ebis; + const char *s; + int ns; +{ + int i; + + for (i = 0; i < ns; ++i) { + if((ebis[i].validflags & ENVSYS_FVALID) && + !strcmp(s, ebis[i].desc)) + return ebis[i].sensor; + } + + return -1; +} |
