sesutil.c revision 298382
1287473Sbapt/*- 2287473Sbapt * Copyright (c) 2015 Baptiste Daroussin <bapt@FreeBSD.org> 3287988Sallanjude * Copyright (c) 2015 Allan Jude <allanjude@FreeBSD.org> 4287988Sallanjude * Copyright (c) 2000 by Matthew Jacob 5287473Sbapt * All rights reserved. 6287473Sbapt * 7287473Sbapt * Redistribution and use in source and binary forms, with or without 8287473Sbapt * modification, are permitted provided that the following conditions 9287473Sbapt * are met: 10287473Sbapt * 1. Redistributions of source code must retain the above copyright 11287473Sbapt * notice, this list of conditions and the following disclaimer 12287473Sbapt * in this position and unchanged. 13287473Sbapt * 2. Redistributions in binary form must reproduce the above copyright 14287473Sbapt * notice, this list of conditions and the following disclaimer in the 15287473Sbapt * documentation and/or other materials provided with the distribution. 16287473Sbapt * 17287473Sbapt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 18287473Sbapt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19287473Sbapt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20287473Sbapt * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 21287473Sbapt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22287473Sbapt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23287473Sbapt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24287473Sbapt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25287473Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26287473Sbapt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27287473Sbapt */ 28287473Sbapt 29287473Sbapt#include <sys/cdefs.h> 30287473Sbapt__FBSDID("$FreeBSD: head/usr.sbin/sesutil/sesutil.c 298382 2016-04-20 21:37:32Z bapt $"); 31287473Sbapt 32287473Sbapt#include <sys/param.h> 33287473Sbapt#include <sys/ioctl.h> 34292121Sbapt#include <sys/types.h> 35292121Sbapt#include <sys/sbuf.h> 36287473Sbapt 37287473Sbapt#include <err.h> 38287473Sbapt#include <errno.h> 39287473Sbapt#include <fcntl.h> 40287988Sallanjude#include <getopt.h> 41287473Sbapt#include <glob.h> 42287473Sbapt#include <stdbool.h> 43287473Sbapt#include <stddef.h> 44287473Sbapt#include <stdint.h> 45287473Sbapt#include <stdio.h> 46287473Sbapt#include <stdlib.h> 47287473Sbapt#include <string.h> 48287473Sbapt#include <unistd.h> 49287473Sbapt 50287473Sbapt#include <cam/scsi/scsi_enc.h> 51287473Sbapt 52287988Sallanjude#include "eltsub.h" 53287988Sallanjude 54287988Sallanjudestatic int encstatus(int argc, char **argv); 55287988Sallanjudestatic int fault(int argc, char **argv); 56287473Sbaptstatic int locate(int argc, char **argv); 57287988Sallanjudestatic int objmap(int argc, char **argv); 58287988Sallanjudestatic int sesled(int argc, char **argv, bool fault); 59287473Sbapt 60287473Sbaptstatic struct command { 61287473Sbapt const char *name; 62287988Sallanjude const char *param; 63287473Sbapt const char *desc; 64287473Sbapt int (*exec)(int argc, char **argv); 65287473Sbapt} cmds[] = { 66287988Sallanjude { "fault", 67287988Sallanjude "(<disk>|<sesid>|all) (on|off)", 68287988Sallanjude "Change the state of the fault LED associated with a disk", 69287988Sallanjude fault }, 70287988Sallanjude { "locate", 71287988Sallanjude "(<disk>|<sesid>|all) (on|off)", 72287988Sallanjude "Change the state of the locate LED associated with a disk", 73287988Sallanjude locate }, 74287988Sallanjude { "map", "", 75287988Sallanjude "Print a map of the devices managed by the enclosure", objmap } , 76287988Sallanjude { "status", "", "Print the status of the enclosure", 77287988Sallanjude encstatus }, 78287473Sbapt}; 79287473Sbapt 80287473Sbaptstatic const int nbcmds = nitems(cmds); 81287988Sallanjudestatic const char *uflag; 82287473Sbapt 83287473Sbaptstatic void 84287988Sallanjudeusage(FILE *out, const char *subcmd) 85287473Sbapt{ 86287988Sallanjude int i; 87287988Sallanjude 88287988Sallanjude if (subcmd == NULL) { 89287988Sallanjude fprintf(out, "Usage: %s [-u /dev/ses<N>] <command> [options]\n", 90287988Sallanjude getprogname()); 91287988Sallanjude fprintf(out, "Commands supported:\n"); 92287988Sallanjude } 93287988Sallanjude for (i = 0; i < nbcmds; i++) { 94287988Sallanjude if (subcmd != NULL) { 95287988Sallanjude if (strcmp(subcmd, cmds[i].name) == 0) { 96287988Sallanjude fprintf(out, "Usage: %s %s [-u /dev/ses<N>] " 97287988Sallanjude "%s\n\t%s\n", getprogname(), subcmd, 98287988Sallanjude cmds[i].param, cmds[i].desc); 99287988Sallanjude break; 100287988Sallanjude } 101287988Sallanjude continue; 102287988Sallanjude } 103287988Sallanjude fprintf(out, " %-12s%s\n\t\t%s\n\n", cmds[i].name, 104287988Sallanjude cmds[i].param, cmds[i].desc); 105287988Sallanjude } 106287988Sallanjude 107287988Sallanjude exit(EXIT_FAILURE); 108287988Sallanjude} 109287988Sallanjude 110287988Sallanjudestatic void 111287992Sallanjudedo_led(int fd, unsigned int idx, bool onoff, bool setfault) 112287988Sallanjude{ 113287473Sbapt encioc_elm_status_t o; 114287473Sbapt 115287473Sbapt o.elm_idx = idx; 116287473Sbapt if (ioctl(fd, ENCIOC_GETELMSTAT, (caddr_t) &o) < 0) { 117287473Sbapt close(fd); 118287473Sbapt err(EXIT_FAILURE, "ENCIOC_GETELMSTAT"); 119287473Sbapt } 120287473Sbapt o.cstat[0] |= 0x80; 121287988Sallanjude if (onoff) { 122287992Sallanjude o.cstat[2] |= (setfault ? 0x20 : 0x02); 123287988Sallanjude } else { 124287992Sallanjude o.cstat[2] &= (setfault ? 0xdf : 0xfd); 125287988Sallanjude } 126287473Sbapt 127287473Sbapt if (ioctl(fd, ENCIOC_SETELMSTAT, (caddr_t) &o) < 0) { 128287473Sbapt close(fd); 129287473Sbapt err(EXIT_FAILURE, "ENCIOC_SETELMSTAT"); 130287473Sbapt } 131287473Sbapt} 132287473Sbapt 133287473Sbaptstatic bool 134287473Sbaptdisk_match(const char *devnames, const char *disk, size_t len) 135287473Sbapt{ 136287494Sbapt const char *dname; 137287473Sbapt 138287494Sbapt dname = devnames; 139287494Sbapt while ((dname = strstr(dname, disk)) != NULL) { 140287988Sallanjude if (dname[len] == '\0' || dname[len] == ',') { 141287473Sbapt return (true); 142287988Sallanjude } 143287494Sbapt dname++; 144287473Sbapt } 145287988Sallanjude 146287473Sbapt return (false); 147287473Sbapt} 148287473Sbapt 149287473Sbaptstatic int 150287992Sallanjudesesled(int argc, char **argv, bool setfault) 151287473Sbapt{ 152287473Sbapt encioc_elm_devnames_t objdn; 153287473Sbapt encioc_element_t *objp; 154287473Sbapt glob_t g; 155287988Sallanjude char *disk, *endptr; 156287988Sallanjude size_t len, i, ndisks; 157287988Sallanjude int fd; 158287988Sallanjude unsigned int nobj, j, sesid; 159287988Sallanjude bool all, isses, onoff; 160287473Sbapt 161287988Sallanjude isses = false; 162287988Sallanjude all = false; 163287988Sallanjude onoff = false; 164287988Sallanjude 165287988Sallanjude if (argc != 3) { 166287992Sallanjude usage(stderr, (setfault ? "fault" : "locate")); 167287473Sbapt } 168287473Sbapt 169287988Sallanjude disk = argv[1]; 170287473Sbapt 171287988Sallanjude sesid = strtoul(disk, &endptr, 10); 172287988Sallanjude if (*endptr == '\0') { 173287988Sallanjude endptr = strrchr(uflag, '*'); 174292122Sbapt if (endptr != NULL && *endptr == '*') { 175287988Sallanjude warnx("Must specifying a SES device (-u) to use a SES " 176287988Sallanjude "id# to identify a disk"); 177287992Sallanjude usage(stderr, (setfault ? "fault" : "locate")); 178287988Sallanjude } 179287988Sallanjude isses = true; 180287988Sallanjude } 181287988Sallanjude 182287988Sallanjude if (strcmp(argv[2], "on") == 0) { 183287485Sbapt onoff = true; 184287988Sallanjude } else if (strcmp(argv[2], "off") == 0) { 185287485Sbapt onoff = false; 186287473Sbapt } else { 187287992Sallanjude usage(stderr, (setfault ? "fault" : "locate")); 188287473Sbapt } 189287473Sbapt 190287473Sbapt if (strcmp(disk, "all") == 0) { 191287473Sbapt all = true; 192287473Sbapt } 193287473Sbapt len = strlen(disk); 194287473Sbapt 195287473Sbapt /* Get the list of ses devices */ 196287988Sallanjude if (glob((uflag != NULL ? uflag : "/dev/ses[0-9]*"), 0, NULL, &g) == 197287988Sallanjude GLOB_NOMATCH) { 198287473Sbapt globfree(&g); 199287473Sbapt errx(EXIT_FAILURE, "No SES devices found"); 200287473Sbapt } 201287988Sallanjude 202287988Sallanjude ndisks = 0; 203287473Sbapt for (i = 0; i < g.gl_pathc; i++) { 204287473Sbapt /* ensure we only got numbers after ses */ 205287473Sbapt if (strspn(g.gl_pathv[i] + 8, "0123456789") != 206287988Sallanjude strlen(g.gl_pathv[i] + 8)) { 207287473Sbapt continue; 208287988Sallanjude } 209287473Sbapt if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) { 210287988Sallanjude /* 211287988Sallanjude * Don't treat non-access errors as critical if we are 212287988Sallanjude * accessing all devices 213287988Sallanjude */ 214287988Sallanjude if (errno == EACCES && g.gl_pathc > 1) { 215287988Sallanjude err(EXIT_FAILURE, "unable to access SES device"); 216287988Sallanjude } 217287988Sallanjude warn("unable to access SES device: %s", g.gl_pathv[i]); 218287988Sallanjude continue; 219287473Sbapt } 220287473Sbapt 221287988Sallanjude if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) { 222287988Sallanjude close(fd); 223287473Sbapt err(EXIT_FAILURE, "ENCIOC_GETNELM"); 224287988Sallanjude } 225287473Sbapt 226287473Sbapt objp = calloc(nobj, sizeof(encioc_element_t)); 227287988Sallanjude if (objp == NULL) { 228287988Sallanjude close(fd); 229287473Sbapt err(EXIT_FAILURE, "calloc()"); 230287988Sallanjude } 231287473Sbapt 232287988Sallanjude if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0) { 233287988Sallanjude close(fd); 234287473Sbapt err(EXIT_FAILURE, "ENCIOC_GETELMMAP"); 235287988Sallanjude } 236287473Sbapt 237287988Sallanjude if (isses) { 238287988Sallanjude if (sesid > nobj) { 239287988Sallanjude close(fd); 240287988Sallanjude errx(EXIT_FAILURE, 241287988Sallanjude "Requested SES ID does not exist"); 242287988Sallanjude } 243287992Sallanjude do_led(fd, sesid, onoff, setfault); 244287988Sallanjude ndisks++; 245287988Sallanjude close(fd); 246287988Sallanjude break; 247287988Sallanjude } 248287473Sbapt for (j = 0; j < nobj; j++) { 249287473Sbapt memset(&objdn, 0, sizeof(objdn)); 250287473Sbapt objdn.elm_idx = objp[j].elm_idx; 251287473Sbapt objdn.elm_names_size = 128; 252287473Sbapt objdn.elm_devnames = calloc(128, sizeof(char)); 253287988Sallanjude if (objdn.elm_devnames == NULL) { 254287988Sallanjude close(fd); 255287473Sbapt err(EXIT_FAILURE, "calloc()"); 256287988Sallanjude } 257287473Sbapt if (ioctl(fd, ENCIOC_GETELMDEVNAMES, 258287988Sallanjude (caddr_t) &objdn) <0) { 259287473Sbapt continue; 260287988Sallanjude } 261287473Sbapt if (objdn.elm_names_len > 0) { 262287473Sbapt if (all) { 263287988Sallanjude do_led(fd, objdn.elm_idx, 264287992Sallanjude onoff, setfault); 265287473Sbapt continue; 266287473Sbapt } 267287473Sbapt if (disk_match(objdn.elm_devnames, disk, len)) { 268287988Sallanjude do_led(fd, objdn.elm_idx, 269287992Sallanjude onoff, setfault); 270287988Sallanjude ndisks++; 271287473Sbapt break; 272287473Sbapt } 273287473Sbapt } 274287988Sallanjude } 275298382Sbapt free(objp); 276287473Sbapt close(fd); 277287473Sbapt } 278287473Sbapt globfree(&g); 279287988Sallanjude if (ndisks == 0 && all == false) { 280287988Sallanjude errx(EXIT_FAILURE, "Count not find the SES id of device '%s'", 281287988Sallanjude disk); 282287988Sallanjude } 283287473Sbapt 284287473Sbapt return (EXIT_SUCCESS); 285287473Sbapt} 286287473Sbapt 287287988Sallanjudestatic int 288287988Sallanjudelocate(int argc, char **argv) 289287473Sbapt{ 290287473Sbapt 291287988Sallanjude return (sesled(argc, argv, false)); 292287473Sbapt} 293287473Sbapt 294287988Sallanjudestatic int 295287988Sallanjudefault(int argc, char **argv) 296287988Sallanjude{ 297287988Sallanjude 298287988Sallanjude return (sesled(argc, argv, true)); 299287988Sallanjude} 300287988Sallanjude 301287988Sallanjudestatic int 302287988Sallanjudeobjmap(int argc, char **argv __unused) 303287988Sallanjude{ 304292121Sbapt struct sbuf *extra; 305292262Sbapt encioc_string_t stri; 306287988Sallanjude encioc_elm_devnames_t e_devname; 307287988Sallanjude encioc_elm_status_t e_status; 308287988Sallanjude encioc_elm_desc_t e_desc; 309287988Sallanjude encioc_element_t *e_ptr; 310287988Sallanjude glob_t g; 311287988Sallanjude int fd; 312287988Sallanjude unsigned int j, nobj; 313287988Sallanjude size_t i; 314292262Sbapt char str[32]; 315287988Sallanjude 316287988Sallanjude if (argc != 1) { 317287988Sallanjude usage(stderr, "map"); 318287988Sallanjude } 319287988Sallanjude 320287988Sallanjude /* Get the list of ses devices */ 321287988Sallanjude if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) { 322287988Sallanjude globfree(&g); 323287988Sallanjude errx(EXIT_FAILURE, "No SES devices found"); 324287988Sallanjude } 325287988Sallanjude for (i = 0; i < g.gl_pathc; i++) { 326287988Sallanjude /* ensure we only got numbers after ses */ 327287988Sallanjude if (strspn(g.gl_pathv[i] + 8, "0123456789") != 328287988Sallanjude strlen(g.gl_pathv[i] + 8)) { 329287988Sallanjude continue; 330287988Sallanjude } 331287988Sallanjude if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) { 332287988Sallanjude /* 333287988Sallanjude * Don't treat non-access errors as critical if we are 334287988Sallanjude * accessing all devices 335287988Sallanjude */ 336287988Sallanjude if (errno == EACCES && g.gl_pathc > 1) { 337287988Sallanjude err(EXIT_FAILURE, "unable to access SES device"); 338287988Sallanjude } 339287988Sallanjude warn("unable to access SES device: %s", g.gl_pathv[i]); 340287988Sallanjude continue; 341287988Sallanjude } 342287988Sallanjude 343287988Sallanjude if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) { 344287988Sallanjude close(fd); 345287988Sallanjude err(EXIT_FAILURE, "ENCIOC_GETNELM"); 346287988Sallanjude } 347287988Sallanjude 348287988Sallanjude e_ptr = calloc(nobj, sizeof(encioc_element_t)); 349287988Sallanjude if (e_ptr == NULL) { 350287988Sallanjude close(fd); 351287988Sallanjude err(EXIT_FAILURE, "calloc()"); 352287988Sallanjude } 353287988Sallanjude 354287988Sallanjude if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) e_ptr) < 0) { 355287988Sallanjude close(fd); 356287988Sallanjude err(EXIT_FAILURE, "ENCIOC_GETELMMAP"); 357287988Sallanjude } 358287988Sallanjude 359287988Sallanjude printf("%s:\n", g.gl_pathv[i] + 5); 360292262Sbapt stri.bufsiz = sizeof(str); 361292262Sbapt stri.buf = &str[0]; 362292262Sbapt if (ioctl(fd, ENCIOC_GETENCNAME, (caddr_t) &stri) == 0) 363292262Sbapt printf("\tEnclosure Name: %s\n", stri.buf); 364292262Sbapt stri.bufsiz = sizeof(str); 365292262Sbapt stri.buf = &str[0]; 366292262Sbapt if (ioctl(fd, ENCIOC_GETENCID, (caddr_t) &stri) == 0) 367292262Sbapt printf("\tEnclosure ID: %s\n", stri.buf); 368292262Sbapt 369287988Sallanjude for (j = 0; j < nobj; j++) { 370287988Sallanjude /* Get the status of the element */ 371287988Sallanjude memset(&e_status, 0, sizeof(e_status)); 372287988Sallanjude e_status.elm_idx = e_ptr[j].elm_idx; 373287988Sallanjude if (ioctl(fd, ENCIOC_GETELMSTAT, 374287988Sallanjude (caddr_t) &e_status) < 0) { 375287988Sallanjude close(fd); 376287988Sallanjude err(EXIT_FAILURE, "ENCIOC_GETELMSTAT"); 377287988Sallanjude } 378287988Sallanjude /* Get the description of the element */ 379287988Sallanjude memset(&e_desc, 0, sizeof(e_desc)); 380287988Sallanjude e_desc.elm_idx = e_ptr[j].elm_idx; 381287988Sallanjude e_desc.elm_desc_len = UINT16_MAX; 382287988Sallanjude e_desc.elm_desc_str = calloc(UINT16_MAX, sizeof(char)); 383287988Sallanjude if (e_desc.elm_desc_str == NULL) { 384287988Sallanjude close(fd); 385287988Sallanjude err(EXIT_FAILURE, "calloc()"); 386287988Sallanjude } 387287988Sallanjude if (ioctl(fd, ENCIOC_GETELMDESC, 388287988Sallanjude (caddr_t) &e_desc) < 0) { 389287988Sallanjude close(fd); 390287988Sallanjude err(EXIT_FAILURE, "ENCIOC_GETELMDESC"); 391287988Sallanjude } 392287988Sallanjude /* Get the device name(s) of the element */ 393287988Sallanjude memset(&e_devname, 0, sizeof(e_devname)); 394287988Sallanjude e_devname.elm_idx = e_ptr[j].elm_idx; 395287988Sallanjude e_devname.elm_names_size = 128; 396287988Sallanjude e_devname.elm_devnames = calloc(128, sizeof(char)); 397287988Sallanjude if (e_devname.elm_devnames == NULL) { 398287988Sallanjude close(fd); 399287988Sallanjude err(EXIT_FAILURE, "calloc()"); 400287988Sallanjude } 401287988Sallanjude if (ioctl(fd, ENCIOC_GETELMDEVNAMES, 402287988Sallanjude (caddr_t) &e_devname) <0) { 403287988Sallanjude /* We don't care if this fails */ 404287988Sallanjude e_devname.elm_devnames[0] = '\0'; 405287988Sallanjude } 406287988Sallanjude printf("\tElement %u, Type: %s\n", e_ptr[j].elm_idx, 407287988Sallanjude geteltnm(e_ptr[j].elm_type)); 408292121Sbapt printf("\t\tStatus: %s (0x%02x 0x%02x 0x%02x 0x%02x)\n", 409292121Sbapt scode2ascii(e_status.cstat[0]), e_status.cstat[0], 410292121Sbapt e_status.cstat[1], e_status.cstat[2], 411292121Sbapt e_status.cstat[3]); 412287988Sallanjude if (e_desc.elm_desc_len > 0) { 413287988Sallanjude printf("\t\tDescription: %s\n", 414287988Sallanjude e_desc.elm_desc_str); 415287988Sallanjude } 416287988Sallanjude if (e_devname.elm_names_len > 0) { 417287988Sallanjude printf("\t\tDevice Names: %s\n", 418287988Sallanjude e_devname.elm_devnames); 419287988Sallanjude } 420292121Sbapt extra = stat2sbuf(e_ptr[j].elm_type, e_status.cstat); 421292121Sbapt if (sbuf_len(extra) > 0) { 422292121Sbapt printf("\t\tExtra status:\n%s", 423292121Sbapt sbuf_data(extra)); 424292121Sbapt } 425292121Sbapt sbuf_delete(extra); 426287988Sallanjude free(e_devname.elm_devnames); 427287988Sallanjude } 428298382Sbapt free(e_ptr); 429287988Sallanjude close(fd); 430287988Sallanjude } 431287988Sallanjude globfree(&g); 432287988Sallanjude 433287988Sallanjude return (EXIT_SUCCESS); 434287988Sallanjude} 435287988Sallanjude 436287988Sallanjudestatic int 437287988Sallanjudeencstatus(int argc, char **argv __unused) 438287988Sallanjude{ 439287988Sallanjude glob_t g; 440287988Sallanjude int fd, status; 441287988Sallanjude size_t i, e; 442287988Sallanjude u_char estat; 443287988Sallanjude 444287988Sallanjude status = 0; 445287988Sallanjude if (argc != 1) { 446287988Sallanjude usage(stderr, "status"); 447287988Sallanjude } 448287988Sallanjude 449287988Sallanjude /* Get the list of ses devices */ 450287988Sallanjude if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) { 451287988Sallanjude globfree(&g); 452287988Sallanjude errx(EXIT_FAILURE, "No SES devices found"); 453287988Sallanjude } 454287988Sallanjude for (i = 0; i < g.gl_pathc; i++) { 455287988Sallanjude /* ensure we only got numbers after ses */ 456287988Sallanjude if (strspn(g.gl_pathv[i] + 8, "0123456789") != 457287988Sallanjude strlen(g.gl_pathv[i] + 8)) { 458287988Sallanjude continue; 459287988Sallanjude } 460287988Sallanjude if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) { 461287988Sallanjude /* 462287988Sallanjude * Don't treat non-access errors as critical if we are 463287988Sallanjude * accessing all devices 464287988Sallanjude */ 465287988Sallanjude if (errno == EACCES && g.gl_pathc > 1) { 466287988Sallanjude err(EXIT_FAILURE, "unable to access SES device"); 467287988Sallanjude } 468287988Sallanjude warn("unable to access SES device: %s", g.gl_pathv[i]); 469287988Sallanjude continue; 470287988Sallanjude } 471287988Sallanjude 472287988Sallanjude if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &estat) < 0) { 473287988Sallanjude close(fd); 474287988Sallanjude err(EXIT_FAILURE, "ENCIOC_GETENCSTAT"); 475287988Sallanjude } 476287988Sallanjude 477287988Sallanjude printf("%s: ", g.gl_pathv[i] + 5); 478287988Sallanjude e = 0; 479287988Sallanjude if (estat == 0) { 480287988Sallanjude if (status == 0) { 481287988Sallanjude status = 1; 482287988Sallanjude } 483287988Sallanjude printf("OK"); 484287988Sallanjude } else { 485287988Sallanjude if (estat & SES_ENCSTAT_INFO) { 486287988Sallanjude printf("INFO"); 487287988Sallanjude e++; 488287988Sallanjude } 489287988Sallanjude if (estat & SES_ENCSTAT_NONCRITICAL) { 490287988Sallanjude if (e) 491287988Sallanjude printf(","); 492287988Sallanjude printf("NONCRITICAL"); 493287988Sallanjude e++; 494287988Sallanjude } 495287988Sallanjude if (estat & SES_ENCSTAT_CRITICAL) { 496287988Sallanjude if (e) 497287988Sallanjude printf(","); 498287988Sallanjude printf("CRITICAL"); 499287988Sallanjude e++; 500287988Sallanjude status = -1; 501287988Sallanjude } 502287988Sallanjude if (estat & SES_ENCSTAT_UNRECOV) { 503287988Sallanjude if (e) 504287988Sallanjude printf(","); 505287988Sallanjude printf("UNRECOV"); 506287988Sallanjude e++; 507287988Sallanjude status = -1; 508287988Sallanjude } 509287988Sallanjude } 510287988Sallanjude printf("\n"); 511287988Sallanjude 512287988Sallanjude close(fd); 513287988Sallanjude } 514287988Sallanjude globfree(&g); 515287988Sallanjude 516287988Sallanjude if (status == 1) { 517287988Sallanjude return (EXIT_SUCCESS); 518287988Sallanjude } else { 519287988Sallanjude return (EXIT_FAILURE); 520287988Sallanjude } 521287988Sallanjude} 522287988Sallanjude 523287473Sbaptint 524287473Sbaptmain(int argc, char **argv) 525287473Sbapt{ 526287988Sallanjude int i, ch; 527287473Sbapt struct command *cmd = NULL; 528287473Sbapt 529287988Sallanjude uflag = "/dev/ses[0-9]*"; 530287988Sallanjude while ((ch = getopt_long(argc, argv, "u:", NULL, NULL)) != -1) { 531287988Sallanjude switch (ch) { 532287988Sallanjude case 'u': 533287988Sallanjude uflag = optarg; 534287988Sallanjude break; 535287988Sallanjude case '?': 536287988Sallanjude default: 537287988Sallanjude usage(stderr, NULL); 538287988Sallanjude } 539287988Sallanjude } 540287988Sallanjude argc -= optind; 541287988Sallanjude argv += optind; 542287988Sallanjude 543287988Sallanjude if (argc < 1) { 544287473Sbapt warnx("Missing command"); 545287988Sallanjude usage(stderr, NULL); 546287473Sbapt } 547287473Sbapt 548287473Sbapt for (i = 0; i < nbcmds; i++) { 549287988Sallanjude if (strcmp(argv[0], cmds[i].name) == 0) { 550287473Sbapt cmd = &cmds[i]; 551287473Sbapt break; 552287473Sbapt } 553287473Sbapt } 554287473Sbapt 555287473Sbapt if (cmd == NULL) { 556287988Sallanjude warnx("unknown command %s", argv[0]); 557287988Sallanjude usage(stderr, NULL); 558287473Sbapt } 559287473Sbapt 560287473Sbapt return (cmd->exec(argc, argv)); 561287473Sbapt} 562