157580Smjacob/* $FreeBSD$ */
257580Smjacob/*
357580Smjacob * Copyright (c) 2000 by Matthew Jacob
457580Smjacob * All rights reserved.
557580Smjacob *
657580Smjacob * Redistribution and use in source and binary forms, with or without
757580Smjacob * modification, are permitted provided that the following conditions
857580Smjacob * are met:
957580Smjacob * 1. Redistributions of source code must retain the above copyright
1057580Smjacob *    notice, this list of conditions, and the following disclaimer,
1157580Smjacob *    without modification, immediately at the beginning of the file.
1257580Smjacob * 2. The name of the author may not be used to endorse or promote products
1357580Smjacob *    derived from this software without specific prior written permission.
1457580Smjacob *
1557580Smjacob * Alternatively, this software may be distributed under the terms of the
1657580Smjacob * the GNU Public License ("GPL").
1757580Smjacob *
1857580Smjacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1957580Smjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2057580Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2157580Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2257580Smjacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2357580Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2457580Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2557580Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2657580Smjacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2757580Smjacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2857580Smjacob * SUCH DAMAGE.
2957580Smjacob *
3057580Smjacob * Matthew Jacob
3157580Smjacob * Feral Software
3257580Smjacob * mjacob@feral.com
3357580Smjacob */
3457580Smjacob
3557580Smjacob#include <unistd.h>
36246437Smav#include <stddef.h>
37246437Smav#include <stdint.h>
3857580Smjacob#include <stdlib.h>
3957580Smjacob#include <stdio.h>
40198929Sdelphij#include <string.h>
4157580Smjacob#include <sys/ioctl.h>
4257580Smjacob#include <fcntl.h>
43246437Smav#include <cam/scsi/scsi_all.h>
44246437Smav#include <cam/scsi/scsi_enc.h>
4557580Smjacob
46198934Sdelphij#include "eltsub.h"
4757580Smjacob
4857580Smjacobint
49198934Sdelphijmain(int a, char **v)
5057580Smjacob{
51246437Smav	encioc_element_t *objp;
52246437Smav	encioc_elm_status_t ob;
53246437Smav	encioc_elm_desc_t objd;
54246437Smav	encioc_elm_devnames_t objdn;
5557580Smjacob	int fd, nobj, f, i, verbose, quiet, errors;
5657580Smjacob	u_char estat;
5757580Smjacob
5857580Smjacob	if (a < 2) {
5957580Smjacob		fprintf(stderr, "usage: %s [ -v ] device [ device ... ]\n", *v);
6057580Smjacob		return (1);
6157580Smjacob	}
6257580Smjacob	errors = quiet = verbose = 0;
6357580Smjacob	if (strcmp(v[1], "-V") == 0) {
6457580Smjacob		verbose = 2;
6557580Smjacob		v++;
6657580Smjacob	} else if (strcmp(v[1], "-v") == 0) {
6757580Smjacob		verbose = 1;
6857580Smjacob		v++;
6957580Smjacob	} else if (strcmp(v[1], "-q") == 0) {
7057580Smjacob		quiet = 1;
7157580Smjacob		verbose = 0;
7257580Smjacob		v++;
7357580Smjacob	}
7457580Smjacob	while (*++v) {
7557580Smjacob
7657580Smjacob		fd = open(*v, O_RDONLY);
7757580Smjacob		if (fd < 0) {
7857580Smjacob			perror(*v);
7957580Smjacob			continue;
8057580Smjacob		}
81246437Smav		if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) {
82246437Smav			perror("ENCIOC_GETNELM");
8357580Smjacob			(void) close(fd);
8457580Smjacob			continue;
8557580Smjacob		}
86246437Smav		if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &estat) < 0) {
87246437Smav			perror("ENCIOC_GETENCSTAT");
8857580Smjacob			(void) close(fd);
8957580Smjacob			continue;
9057580Smjacob		}
9157580Smjacob		if ((verbose == 0 || quiet == 1) && estat == 0) {
9257580Smjacob			if (quiet == 0)
9357580Smjacob				fprintf(stdout, "%s: Enclosure OK\n", *v);
9457580Smjacob			(void) close(fd);
9557580Smjacob			continue;
9657580Smjacob		}
9757580Smjacob		fprintf(stdout, "%s: Enclosure Status ", *v);
9857580Smjacob		if (estat == 0) {
9957580Smjacob			fprintf(stdout, "<OK");
10057580Smjacob		} else {
10157580Smjacob			errors++;
10257580Smjacob			f = '<';
10357580Smjacob			if (estat & SES_ENCSTAT_INFO) {
10457580Smjacob				fprintf(stdout, "%cINFO", f);
10557580Smjacob				f = ',';
10657580Smjacob			}
10757580Smjacob			if (estat & SES_ENCSTAT_NONCRITICAL) {
10857580Smjacob				fprintf(stdout, "%cNONCRITICAL", f);
10957580Smjacob				f = ',';
11057580Smjacob			}
11157580Smjacob			if (estat & SES_ENCSTAT_CRITICAL) {
11257580Smjacob				fprintf(stdout, "%cCRITICAL", f);
11357580Smjacob				f = ',';
11457580Smjacob			}
11557580Smjacob			if (estat & SES_ENCSTAT_UNRECOV) {
11657580Smjacob				fprintf(stdout, "%cUNRECOV", f);
11757580Smjacob				f = ',';
11857580Smjacob			}
11957580Smjacob		}
12057580Smjacob		fprintf(stdout, ">\n");
121246437Smav		objp = calloc(nobj, sizeof (encioc_element_t));
12257580Smjacob		if (objp == NULL) {
12357580Smjacob			perror("calloc");
12457580Smjacob			(void) close(fd);
12557580Smjacob			continue;
12657580Smjacob		}
127246437Smav                if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0) {
128246437Smav                        perror("ENCIOC_GETELMMAP");
12957580Smjacob                        (void) close(fd);
13057580Smjacob                        continue;
13157580Smjacob                }
13257580Smjacob		for (i = 0; i < nobj; i++) {
133246437Smav			ob.elm_idx = objp[i].elm_idx;
134246437Smav			if (ioctl(fd, ENCIOC_GETELMSTAT, (caddr_t) &ob) < 0) {
135246437Smav				perror("ENCIOC_GETELMSTAT");
13657580Smjacob				(void) close(fd);
13757580Smjacob				break;
13857580Smjacob			}
139246437Smav			bzero(&objd, sizeof(objd));
140246437Smav			objd.elm_idx = objp[i].elm_idx;
141246437Smav			objd.elm_desc_len = UINT16_MAX;
142246437Smav			objd.elm_desc_str = calloc(UINT16_MAX, sizeof(char));
143246437Smav			if (objd.elm_desc_str == NULL) {
144246437Smav				perror("calloc");
145246437Smav				(void) close(fd);
14657580Smjacob				continue;
14757580Smjacob			}
148246437Smav			if (ioctl(fd, ENCIOC_GETELMDESC, (caddr_t)&objd) < 0) {
149246437Smav				perror("ENCIOC_GETELMDESC");
150246437Smav				(void) close(fd);
151246437Smav				break;
152246437Smav			}
153246437Smav			bzero(&objdn, sizeof(objdn));
154246437Smav			objdn.elm_idx = objp[i].elm_idx;
155246437Smav			objdn.elm_names_size = 128;
156246437Smav			objdn.elm_devnames = calloc(128, sizeof(char));
157246437Smav			if (objdn.elm_devnames == NULL) {
158246437Smav				perror("calloc");
159246437Smav				(void) close(fd);
160246437Smav				break;
161246437Smav			}
162246437Smav			/*
163246437Smav			 * This ioctl isn't critical and has a good chance
164246437Smav			 * of returning -1.
165246437Smav			 */
166246437Smav			(void)ioctl(fd, ENCIOC_GETELMDEVNAMES, (caddr_t)&objdn);
167246437Smav			fprintf(stdout, "Element 0x%x: %s", ob.elm_idx,
168246437Smav			    geteltnm(objp[i].elm_type));
169246437Smav			fprintf(stdout, ", %s",
170246437Smav			    stat2ascii(objp[i].elm_type, ob.cstat));
171246437Smav			if (objd.elm_desc_len > 0)
172246437Smav				fprintf(stdout, ", descriptor: '%s'",
173246437Smav				    objd.elm_desc_str);
174246437Smav			if (objdn.elm_names_len > 0)
175246437Smav				fprintf(stdout, ", dev: '%s'",
176246437Smav				    objdn.elm_devnames);
177246437Smav			fprintf(stdout, "\n");
178246437Smav			free(objdn.elm_devnames);
17957580Smjacob		}
18057580Smjacob		free(objp);
18157580Smjacob		(void) close(fd);
18257580Smjacob	}
18357580Smjacob	return (errors);
18457580Smjacob}
185