1 /* 2 * Copyright (c) 2000 by Matthew Jacob 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions, and the following disclaimer, 10 * without modification, immediately at the beginning of the file. 11 * 2. The name of the author may not be used to endorse or promote products 12 * derived from this software without specific prior written permission. 13 * 14 * Alternatively, this software may be distributed under the terms of the 15 * the GNU Public License ("GPL"). 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * Matthew Jacob 30 * Feral Software 31 * mjacob@feral.com 32 */ 33 34 #include <unistd.h> 35 #include <stddef.h> 36 #include <stdint.h> 37 #include <stdlib.h> 38 #include <stdio.h> 39 #include <string.h> 40 #include <sys/ioctl.h> 41 #include <fcntl.h> 42 #include <cam/scsi/scsi_all.h> 43 #include <cam/scsi/scsi_enc.h> 44 45 #include "eltsub.h" 46 47 int 48 main(int a, char **v) 49 { 50 encioc_string_t stri; 51 encioc_element_t *objp; 52 encioc_elm_status_t ob; 53 encioc_elm_desc_t objd; 54 encioc_elm_devnames_t objdn; 55 int fd, nobj, f, i, verbose, quiet, errors; 56 u_char estat; 57 char str[32]; 58 59 if (a < 2) { 60 fprintf(stderr, "usage: %s [ -v ] device [ device ... ]\n", *v); 61 return (1); 62 } 63 errors = quiet = verbose = 0; 64 if (strcmp(v[1], "-V") == 0) { 65 verbose = 2; 66 v++; 67 } else if (strcmp(v[1], "-v") == 0) { 68 verbose = 1; 69 v++; 70 } else if (strcmp(v[1], "-q") == 0) { 71 quiet = 1; 72 verbose = 0; 73 v++; 74 } 75 while (*++v) { 76 77 fd = open(*v, O_RDONLY); 78 if (fd < 0) { 79 perror(*v); 80 continue; 81 } 82 if (verbose > 1) { 83 stri.bufsiz = sizeof(str); 84 stri.buf = &str[0]; 85 if (ioctl(fd, ENCIOC_GETENCNAME, (caddr_t) &stri) == 0) 86 printf("%s: Enclosure Name: %s\n", *v, stri.buf); 87 stri.bufsiz = sizeof(str); 88 stri.buf = &str[0]; 89 if (ioctl(fd, ENCIOC_GETENCID, (caddr_t) &stri) == 0) 90 printf("%s: Enclosure ID: %s\n", *v, stri.buf); 91 } 92 if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) { 93 perror("ENCIOC_GETNELM"); 94 (void) close(fd); 95 continue; 96 } 97 if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &estat) < 0) { 98 perror("ENCIOC_GETENCSTAT"); 99 (void) close(fd); 100 continue; 101 } 102 if ((verbose == 0 || quiet == 1) && estat == 0) { 103 if (quiet == 0) 104 fprintf(stdout, "%s: Enclosure OK\n", *v); 105 (void) close(fd); 106 continue; 107 } 108 fprintf(stdout, "%s: Enclosure Status ", *v); 109 if (estat == 0) { 110 fprintf(stdout, "<OK"); 111 } else { 112 errors++; 113 f = '<'; 114 if (estat & SES_ENCSTAT_INFO) { 115 fprintf(stdout, "%cINFO", f); 116 f = ','; 117 } 118 if (estat & SES_ENCSTAT_NONCRITICAL) { 119 fprintf(stdout, "%cNONCRITICAL", f); 120 f = ','; 121 } 122 if (estat & SES_ENCSTAT_CRITICAL) { 123 fprintf(stdout, "%cCRITICAL", f); 124 f = ','; 125 } 126 if (estat & SES_ENCSTAT_UNRECOV) { 127 fprintf(stdout, "%cUNRECOV", f); 128 f = ','; 129 } 130 } 131 fprintf(stdout, ">\n"); 132 objp = calloc(nobj, sizeof (encioc_element_t)); 133 if (objp == NULL) { 134 perror("calloc"); 135 (void) close(fd); 136 continue; 137 } 138 if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0) { 139 perror("ENCIOC_GETELMMAP"); 140 (void) close(fd); 141 continue; 142 } 143 for (i = 0; i < nobj; i++) { 144 ob.elm_idx = objp[i].elm_idx; 145 if (ioctl(fd, ENCIOC_GETELMSTAT, (caddr_t) &ob) < 0) { 146 perror("ENCIOC_GETELMSTAT"); 147 (void) close(fd); 148 break; 149 } 150 bzero(&objd, sizeof(objd)); 151 objd.elm_idx = objp[i].elm_idx; 152 objd.elm_desc_len = UINT16_MAX; 153 objd.elm_desc_str = calloc(UINT16_MAX, sizeof(char)); 154 if (objd.elm_desc_str == NULL) { 155 perror("calloc"); 156 (void) close(fd); 157 continue; 158 } 159 if (ioctl(fd, ENCIOC_GETELMDESC, (caddr_t)&objd) < 0) { 160 perror("ENCIOC_GETELMDESC"); 161 (void) close(fd); 162 break; 163 } 164 bzero(&objdn, sizeof(objdn)); 165 objdn.elm_idx = objp[i].elm_idx; 166 objdn.elm_names_size = 128; 167 objdn.elm_devnames = calloc(128, sizeof(char)); 168 if (objdn.elm_devnames == NULL) { 169 perror("calloc"); 170 (void) close(fd); 171 break; 172 } 173 /* 174 * This ioctl isn't critical and has a good chance 175 * of returning -1. 176 */ 177 (void)ioctl(fd, ENCIOC_GETELMDEVNAMES, (caddr_t)&objdn); 178 fprintf(stdout, "Element 0x%x: %s", ob.elm_idx, 179 geteltnm(objp[i].elm_type)); 180 fprintf(stdout, ", %s", 181 stat2ascii(objp[i].elm_type, ob.cstat)); 182 if (objd.elm_desc_len > 0) 183 fprintf(stdout, ", descriptor: '%s'", 184 objd.elm_desc_str); 185 if (objdn.elm_names_len > 0) 186 fprintf(stdout, ", dev: '%s'", 187 objdn.elm_devnames); 188 fprintf(stdout, "\n"); 189 free(objdn.elm_devnames); 190 } 191 free(objp); 192 (void) close(fd); 193 } 194 return (errors); 195 } 196