1/* $NetBSD: getencstat.c,v 1.4 2018/01/23 21:06:26 sevan Exp $ */
2/* $FreeBSD: $ */
3/* $OpenBSD: $ */
4/*
5 * Copyright (c) 2000 by Matthew Jacob
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions, and the following disclaimer,
13 *    without modification, immediately at the beginning of the file.
14 * 2. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * Alternatively, this software may be distributed under the terms of the
18 * the GNU Public License ("GPL").
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * Matthew Jacob
33 * Feral Software
34 * mjacob@feral.com
35 */
36
37#include <unistd.h>
38#include <string.h>
39#include <stdlib.h>
40#include <stdio.h>
41#include <sys/ioctl.h>
42#include <fcntl.h>
43#include SESINC
44
45extern char *geteltnm(int);
46extern char *stat2ascii(int, u_char *);
47
48int
49main(int a, char *v[])
50{
51	ses_object *objp;
52	ses_objstat ob;
53	int fd, nobj, f, i, verbose, quiet, errors;
54	u_char estat;
55
56	if (a < 2) {
57		fprintf(stderr, "usage: %s [ -v ] device [ device ... ]\n", *v);
58		return (1);
59	}
60	errors = quiet = verbose = 0;
61	if (strcmp(v[1], "-V") == 0) {
62		verbose = 2;
63		v++;
64	} else if (strcmp(v[1], "-v") == 0) {
65		verbose = 1;
66		v++;
67	} else if (strcmp(v[1], "-q") == 0) {
68		quiet = 1;
69		verbose = 0;
70		v++;
71	}
72	while (*++v) {
73
74		fd = open(*v, O_RDONLY);
75		if (fd < 0) {
76			perror(*v);
77			continue;
78		}
79		if (ioctl(fd, SESIOC_GETNOBJ, (caddr_t) &nobj) < 0) {
80			perror("SESIOC_GETNOBJ");
81			(void) close(fd);
82			continue;
83		}
84		if (ioctl(fd, SESIOC_GETENCSTAT, (caddr_t) &estat) < 0) {
85			perror("SESIOC_GETENCSTAT");
86			(void) close(fd);
87			continue;
88		}
89		if ((verbose == 0 || quiet == 1) && estat == 0) {
90			if (quiet == 0)
91				fprintf(stdout, "%s: Enclosure OK\n", *v);
92			(void) close(fd);
93			continue;
94		}
95		fprintf(stdout, "%s: Enclosure Status ", *v);
96		if (estat == 0) {
97			fprintf(stdout, "<OK");
98		} else {
99			errors++;
100			f = '<';
101			if (estat & SES_ENCSTAT_INFO) {
102				fprintf(stdout, "%cINFO", f);
103				f = ',';
104			}
105			if (estat & SES_ENCSTAT_NONCRITICAL) {
106				fprintf(stdout, "%cNONCRITICAL", f);
107				f = ',';
108			}
109			if (estat & SES_ENCSTAT_CRITICAL) {
110				fprintf(stdout, "%cCRITICAL", f);
111				f = ',';
112			}
113			if (estat & SES_ENCSTAT_UNRECOV) {
114				fprintf(stdout, "%cUNRECOV", f);
115				f = ',';
116			}
117		}
118		fprintf(stdout, ">\n");
119		objp = calloc(nobj, sizeof (ses_object));
120		if (objp == NULL) {
121			perror("calloc");
122			(void) close(fd);
123			continue;
124		}
125                if (ioctl(fd, SESIOC_GETOBJMAP, (caddr_t) objp) < 0) {
126                        perror("SESIOC_GETOBJMAP");
127                        (void) close(fd);
128                        continue;
129                }
130		for (i = 0; i < nobj; i++) {
131			ob.obj_id = objp[i].obj_id;
132			if (ioctl(fd, SESIOC_GETOBJSTAT, (caddr_t) &ob) < 0) {
133				perror("SESIOC_GETOBJSTAT");
134				(void) close(fd);
135				break;
136			}
137			if ((ob.cstat[0] & 0xf) == SES_OBJSTAT_OK) {
138				if (verbose) {
139					fprintf(stdout,
140					    "Element 0x%x: %s OK (%s)\n",
141					    ob.obj_id,
142					    geteltnm(objp[i].object_type),
143					    stat2ascii(objp[i].object_type,
144					    ob.cstat));
145				}
146				continue;
147			}
148			fprintf(stdout, "Element 0x%x: %s, %s\n",
149			    ob.obj_id, geteltnm(objp[i].object_type),
150			    stat2ascii(objp[i].object_type, ob.cstat));
151		}
152		free(objp);
153		(void) close(fd);
154	}
155	return (errors);
156}
157