1287473Sbapt/*- 2287473Sbapt * Copyright (c) 2015 Baptiste Daroussin <bapt@FreeBSD.org> 3293865Sallanjude * Copyright (c) 2015 Allan Jude <allanjude@FreeBSD.org> 4293865Sallanjude * 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: stable/10/usr.sbin/sesutil/sesutil.c 306797 2016-10-07 01:33:03Z mav $"); 31287473Sbapt 32287473Sbapt#include <sys/param.h> 33287473Sbapt#include <sys/ioctl.h> 34293865Sallanjude#include <sys/types.h> 35293865Sallanjude#include <sys/sbuf.h> 36287473Sbapt 37287473Sbapt#include <err.h> 38287473Sbapt#include <errno.h> 39287473Sbapt#include <fcntl.h> 40293865Sallanjude#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_all.h> 51287473Sbapt#include <cam/scsi/scsi_enc.h> 52287473Sbapt 53293865Sallanjude#include "eltsub.h" 54293865Sallanjude 55293865Sallanjudestatic int encstatus(int argc, char **argv); 56293865Sallanjudestatic int fault(int argc, char **argv); 57287473Sbaptstatic int locate(int argc, char **argv); 58293865Sallanjudestatic int objmap(int argc, char **argv); 59293865Sallanjudestatic int sesled(int argc, char **argv, bool fault); 60287473Sbapt 61287473Sbaptstatic struct command { 62287473Sbapt const char *name; 63293865Sallanjude const char *param; 64287473Sbapt const char *desc; 65287473Sbapt int (*exec)(int argc, char **argv); 66287473Sbapt} cmds[] = { 67293865Sallanjude { "fault", 68293865Sallanjude "(<disk>|<sesid>|all) (on|off)", 69293865Sallanjude "Change the state of the fault LED associated with a disk", 70293865Sallanjude fault }, 71293865Sallanjude { "locate", 72293865Sallanjude "(<disk>|<sesid>|all) (on|off)", 73293865Sallanjude "Change the state of the locate LED associated with a disk", 74293865Sallanjude locate }, 75293865Sallanjude { "map", "", 76293865Sallanjude "Print a map of the devices managed by the enclosure", objmap } , 77293865Sallanjude { "status", "", "Print the status of the enclosure", 78293865Sallanjude encstatus }, 79287473Sbapt}; 80287473Sbapt 81287473Sbaptstatic const int nbcmds = nitems(cmds); 82293865Sallanjudestatic const char *uflag; 83287473Sbapt 84287473Sbaptstatic void 85293865Sallanjudeusage(FILE *out, const char *subcmd) 86287473Sbapt{ 87293865Sallanjude int i; 88293865Sallanjude 89293865Sallanjude if (subcmd == NULL) { 90293865Sallanjude fprintf(out, "Usage: %s [-u /dev/ses<N>] <command> [options]\n", 91293865Sallanjude getprogname()); 92293865Sallanjude fprintf(out, "Commands supported:\n"); 93293865Sallanjude } 94293865Sallanjude for (i = 0; i < nbcmds; i++) { 95293865Sallanjude if (subcmd != NULL) { 96293865Sallanjude if (strcmp(subcmd, cmds[i].name) == 0) { 97293865Sallanjude fprintf(out, "Usage: %s %s [-u /dev/ses<N>] " 98293865Sallanjude "%s\n\t%s\n", getprogname(), subcmd, 99293865Sallanjude cmds[i].param, cmds[i].desc); 100293865Sallanjude break; 101293865Sallanjude } 102293865Sallanjude continue; 103293865Sallanjude } 104293865Sallanjude fprintf(out, " %-12s%s\n\t\t%s\n\n", cmds[i].name, 105293865Sallanjude cmds[i].param, cmds[i].desc); 106293865Sallanjude } 107293865Sallanjude 108293865Sallanjude exit(EXIT_FAILURE); 109293865Sallanjude} 110293865Sallanjude 111293865Sallanjudestatic void 112293865Sallanjudedo_led(int fd, unsigned int idx, bool onoff, bool setfault) 113293865Sallanjude{ 114287473Sbapt encioc_elm_status_t o; 115287473Sbapt 116287473Sbapt o.elm_idx = idx; 117287473Sbapt if (ioctl(fd, ENCIOC_GETELMSTAT, (caddr_t) &o) < 0) { 118287473Sbapt close(fd); 119287473Sbapt err(EXIT_FAILURE, "ENCIOC_GETELMSTAT"); 120287473Sbapt } 121287473Sbapt o.cstat[0] |= 0x80; 122306797Smav if (setfault) { 123306797Smav if (onoff) 124306797Smav o.cstat[3] |= 0x20; 125306797Smav else 126306797Smav o.cstat[3] &= 0xdf; 127293865Sallanjude } else { 128306797Smav if (onoff) 129306797Smav o.cstat[2] |= 0x02; 130306797Smav else 131306797Smav o.cstat[2] &= 0xfd; 132293865Sallanjude } 133287473Sbapt 134287473Sbapt if (ioctl(fd, ENCIOC_SETELMSTAT, (caddr_t) &o) < 0) { 135287473Sbapt close(fd); 136287473Sbapt err(EXIT_FAILURE, "ENCIOC_SETELMSTAT"); 137287473Sbapt } 138287473Sbapt} 139287473Sbapt 140287473Sbaptstatic bool 141287473Sbaptdisk_match(const char *devnames, const char *disk, size_t len) 142287473Sbapt{ 143288710Sbapt const char *dname; 144287473Sbapt 145288710Sbapt dname = devnames; 146288710Sbapt while ((dname = strstr(dname, disk)) != NULL) { 147293865Sallanjude if (dname[len] == '\0' || dname[len] == ',') { 148287473Sbapt return (true); 149293865Sallanjude } 150288710Sbapt dname++; 151287473Sbapt } 152293865Sallanjude 153287473Sbapt return (false); 154287473Sbapt} 155287473Sbapt 156287473Sbaptstatic int 157293865Sallanjudesesled(int argc, char **argv, bool setfault) 158287473Sbapt{ 159287473Sbapt encioc_elm_devnames_t objdn; 160287473Sbapt encioc_element_t *objp; 161287473Sbapt glob_t g; 162293865Sallanjude char *disk, *endptr; 163293865Sallanjude size_t len, i, ndisks; 164293865Sallanjude int fd; 165293865Sallanjude unsigned int nobj, j, sesid; 166293865Sallanjude bool all, isses, onoff; 167287473Sbapt 168293865Sallanjude isses = false; 169293865Sallanjude all = false; 170293865Sallanjude onoff = false; 171293865Sallanjude 172293865Sallanjude if (argc != 3) { 173293865Sallanjude usage(stderr, (setfault ? "fault" : "locate")); 174287473Sbapt } 175287473Sbapt 176293865Sallanjude disk = argv[1]; 177287473Sbapt 178293865Sallanjude sesid = strtoul(disk, &endptr, 10); 179293865Sallanjude if (*endptr == '\0') { 180293865Sallanjude endptr = strrchr(uflag, '*'); 181293865Sallanjude if (endptr != NULL && *endptr == '*') { 182293865Sallanjude warnx("Must specifying a SES device (-u) to use a SES " 183293865Sallanjude "id# to identify a disk"); 184293865Sallanjude usage(stderr, (setfault ? "fault" : "locate")); 185293865Sallanjude } 186293865Sallanjude isses = true; 187293865Sallanjude } 188293865Sallanjude 189293865Sallanjude if (strcmp(argv[2], "on") == 0) { 190288710Sbapt onoff = true; 191293865Sallanjude } else if (strcmp(argv[2], "off") == 0) { 192288710Sbapt onoff = false; 193287473Sbapt } else { 194293865Sallanjude usage(stderr, (setfault ? "fault" : "locate")); 195287473Sbapt } 196287473Sbapt 197287473Sbapt if (strcmp(disk, "all") == 0) { 198287473Sbapt all = true; 199287473Sbapt } 200287473Sbapt len = strlen(disk); 201287473Sbapt 202287473Sbapt /* Get the list of ses devices */ 203293865Sallanjude if (glob((uflag != NULL ? uflag : "/dev/ses[0-9]*"), 0, NULL, &g) == 204293865Sallanjude GLOB_NOMATCH) { 205287473Sbapt globfree(&g); 206287473Sbapt errx(EXIT_FAILURE, "No SES devices found"); 207287473Sbapt } 208293865Sallanjude 209293865Sallanjude ndisks = 0; 210287473Sbapt for (i = 0; i < g.gl_pathc; i++) { 211287473Sbapt /* ensure we only got numbers after ses */ 212287473Sbapt if (strspn(g.gl_pathv[i] + 8, "0123456789") != 213293865Sallanjude strlen(g.gl_pathv[i] + 8)) { 214287473Sbapt continue; 215293865Sallanjude } 216287473Sbapt if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) { 217293865Sallanjude /* 218293865Sallanjude * Don't treat non-access errors as critical if we are 219293865Sallanjude * accessing all devices 220293865Sallanjude */ 221293865Sallanjude if (errno == EACCES && g.gl_pathc > 1) { 222293865Sallanjude err(EXIT_FAILURE, "unable to access SES device"); 223293865Sallanjude } 224293865Sallanjude warn("unable to access SES device: %s", g.gl_pathv[i]); 225293865Sallanjude continue; 226287473Sbapt } 227287473Sbapt 228293865Sallanjude if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) { 229293865Sallanjude close(fd); 230287473Sbapt err(EXIT_FAILURE, "ENCIOC_GETNELM"); 231293865Sallanjude } 232287473Sbapt 233287473Sbapt objp = calloc(nobj, sizeof(encioc_element_t)); 234293865Sallanjude if (objp == NULL) { 235293865Sallanjude close(fd); 236287473Sbapt err(EXIT_FAILURE, "calloc()"); 237293865Sallanjude } 238287473Sbapt 239293865Sallanjude if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0) { 240293865Sallanjude close(fd); 241287473Sbapt err(EXIT_FAILURE, "ENCIOC_GETELMMAP"); 242293865Sallanjude } 243287473Sbapt 244293865Sallanjude if (isses) { 245293865Sallanjude if (sesid > nobj) { 246293865Sallanjude close(fd); 247293865Sallanjude errx(EXIT_FAILURE, 248293865Sallanjude "Requested SES ID does not exist"); 249293865Sallanjude } 250293865Sallanjude do_led(fd, sesid, onoff, setfault); 251293865Sallanjude ndisks++; 252293865Sallanjude close(fd); 253293865Sallanjude break; 254293865Sallanjude } 255287473Sbapt for (j = 0; j < nobj; j++) { 256287473Sbapt memset(&objdn, 0, sizeof(objdn)); 257287473Sbapt objdn.elm_idx = objp[j].elm_idx; 258287473Sbapt objdn.elm_names_size = 128; 259287473Sbapt objdn.elm_devnames = calloc(128, sizeof(char)); 260293865Sallanjude if (objdn.elm_devnames == NULL) { 261293865Sallanjude close(fd); 262287473Sbapt err(EXIT_FAILURE, "calloc()"); 263293865Sallanjude } 264287473Sbapt if (ioctl(fd, ENCIOC_GETELMDEVNAMES, 265293865Sallanjude (caddr_t) &objdn) <0) { 266287473Sbapt continue; 267293865Sallanjude } 268287473Sbapt if (objdn.elm_names_len > 0) { 269287473Sbapt if (all) { 270293865Sallanjude do_led(fd, objdn.elm_idx, 271293865Sallanjude onoff, setfault); 272287473Sbapt continue; 273287473Sbapt } 274287473Sbapt if (disk_match(objdn.elm_devnames, disk, len)) { 275293865Sallanjude do_led(fd, objdn.elm_idx, 276293865Sallanjude onoff, setfault); 277293865Sallanjude ndisks++; 278287473Sbapt break; 279287473Sbapt } 280287473Sbapt } 281293865Sallanjude } 282287473Sbapt close(fd); 283287473Sbapt } 284287473Sbapt globfree(&g); 285293865Sallanjude if (ndisks == 0 && all == false) { 286293865Sallanjude errx(EXIT_FAILURE, "Count not find the SES id of device '%s'", 287293865Sallanjude disk); 288293865Sallanjude } 289287473Sbapt 290287473Sbapt return (EXIT_SUCCESS); 291287473Sbapt} 292287473Sbapt 293293865Sallanjudestatic int 294293865Sallanjudelocate(int argc, char **argv) 295287473Sbapt{ 296287473Sbapt 297293865Sallanjude return (sesled(argc, argv, false)); 298287473Sbapt} 299287473Sbapt 300293865Sallanjudestatic int 301293865Sallanjudefault(int argc, char **argv) 302293865Sallanjude{ 303293865Sallanjude 304293865Sallanjude return (sesled(argc, argv, true)); 305293865Sallanjude} 306293865Sallanjude 307293865Sallanjudestatic int 308293865Sallanjudeobjmap(int argc, char **argv __unused) 309293865Sallanjude{ 310293865Sallanjude struct sbuf *extra; 311293865Sallanjude encioc_string_t stri; 312293865Sallanjude encioc_elm_devnames_t e_devname; 313293865Sallanjude encioc_elm_status_t e_status; 314293865Sallanjude encioc_elm_desc_t e_desc; 315293865Sallanjude encioc_element_t *e_ptr; 316293865Sallanjude glob_t g; 317293865Sallanjude int fd; 318293865Sallanjude unsigned int j, nobj; 319293865Sallanjude size_t i; 320293865Sallanjude char str[32]; 321293865Sallanjude 322293865Sallanjude if (argc != 1) { 323293865Sallanjude usage(stderr, "map"); 324293865Sallanjude } 325293865Sallanjude 326293865Sallanjude /* Get the list of ses devices */ 327293865Sallanjude if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) { 328293865Sallanjude globfree(&g); 329293865Sallanjude errx(EXIT_FAILURE, "No SES devices found"); 330293865Sallanjude } 331293865Sallanjude for (i = 0; i < g.gl_pathc; i++) { 332293865Sallanjude /* ensure we only got numbers after ses */ 333293865Sallanjude if (strspn(g.gl_pathv[i] + 8, "0123456789") != 334293865Sallanjude strlen(g.gl_pathv[i] + 8)) { 335293865Sallanjude continue; 336293865Sallanjude } 337293865Sallanjude if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) { 338293865Sallanjude /* 339293865Sallanjude * Don't treat non-access errors as critical if we are 340293865Sallanjude * accessing all devices 341293865Sallanjude */ 342293865Sallanjude if (errno == EACCES && g.gl_pathc > 1) { 343293865Sallanjude err(EXIT_FAILURE, "unable to access SES device"); 344293865Sallanjude } 345293865Sallanjude warn("unable to access SES device: %s", g.gl_pathv[i]); 346293865Sallanjude continue; 347293865Sallanjude } 348293865Sallanjude 349293865Sallanjude if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) { 350293865Sallanjude close(fd); 351293865Sallanjude err(EXIT_FAILURE, "ENCIOC_GETNELM"); 352293865Sallanjude } 353293865Sallanjude 354293865Sallanjude e_ptr = calloc(nobj, sizeof(encioc_element_t)); 355293865Sallanjude if (e_ptr == NULL) { 356293865Sallanjude close(fd); 357293865Sallanjude err(EXIT_FAILURE, "calloc()"); 358293865Sallanjude } 359293865Sallanjude 360293865Sallanjude if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) e_ptr) < 0) { 361293865Sallanjude close(fd); 362293865Sallanjude err(EXIT_FAILURE, "ENCIOC_GETELMMAP"); 363293865Sallanjude } 364293865Sallanjude 365293865Sallanjude printf("%s:\n", g.gl_pathv[i] + 5); 366293865Sallanjude stri.bufsiz = sizeof(str); 367293865Sallanjude stri.buf = &str[0]; 368293865Sallanjude if (ioctl(fd, ENCIOC_GETENCNAME, (caddr_t) &stri) == 0) 369293865Sallanjude printf("\tEnclosure Name: %s\n", stri.buf); 370293865Sallanjude stri.bufsiz = sizeof(str); 371293865Sallanjude stri.buf = &str[0]; 372293865Sallanjude if (ioctl(fd, ENCIOC_GETENCID, (caddr_t) &stri) == 0) 373293865Sallanjude printf("\tEnclosure ID: %s\n", stri.buf); 374293865Sallanjude 375293865Sallanjude for (j = 0; j < nobj; j++) { 376293865Sallanjude /* Get the status of the element */ 377293865Sallanjude memset(&e_status, 0, sizeof(e_status)); 378293865Sallanjude e_status.elm_idx = e_ptr[j].elm_idx; 379293865Sallanjude if (ioctl(fd, ENCIOC_GETELMSTAT, 380293865Sallanjude (caddr_t) &e_status) < 0) { 381293865Sallanjude close(fd); 382293865Sallanjude err(EXIT_FAILURE, "ENCIOC_GETELMSTAT"); 383293865Sallanjude } 384293865Sallanjude /* Get the description of the element */ 385293865Sallanjude memset(&e_desc, 0, sizeof(e_desc)); 386293865Sallanjude e_desc.elm_idx = e_ptr[j].elm_idx; 387293865Sallanjude e_desc.elm_desc_len = UINT16_MAX; 388293865Sallanjude e_desc.elm_desc_str = calloc(UINT16_MAX, sizeof(char)); 389293865Sallanjude if (e_desc.elm_desc_str == NULL) { 390293865Sallanjude close(fd); 391293865Sallanjude err(EXIT_FAILURE, "calloc()"); 392293865Sallanjude } 393293865Sallanjude if (ioctl(fd, ENCIOC_GETELMDESC, 394293865Sallanjude (caddr_t) &e_desc) < 0) { 395293865Sallanjude close(fd); 396293865Sallanjude err(EXIT_FAILURE, "ENCIOC_GETELMDESC"); 397293865Sallanjude } 398293865Sallanjude /* Get the device name(s) of the element */ 399293865Sallanjude memset(&e_devname, 0, sizeof(e_devname)); 400293865Sallanjude e_devname.elm_idx = e_ptr[j].elm_idx; 401293865Sallanjude e_devname.elm_names_size = 128; 402293865Sallanjude e_devname.elm_devnames = calloc(128, sizeof(char)); 403293865Sallanjude if (e_devname.elm_devnames == NULL) { 404293865Sallanjude close(fd); 405293865Sallanjude err(EXIT_FAILURE, "calloc()"); 406293865Sallanjude } 407293865Sallanjude if (ioctl(fd, ENCIOC_GETELMDEVNAMES, 408293865Sallanjude (caddr_t) &e_devname) <0) { 409293865Sallanjude /* We don't care if this fails */ 410293865Sallanjude e_devname.elm_devnames[0] = '\0'; 411293865Sallanjude } 412293865Sallanjude printf("\tElement %u, Type: %s\n", e_ptr[j].elm_idx, 413293865Sallanjude geteltnm(e_ptr[j].elm_type)); 414293865Sallanjude printf("\t\tStatus: %s (0x%02x 0x%02x 0x%02x 0x%02x)\n", 415293865Sallanjude scode2ascii(e_status.cstat[0]), e_status.cstat[0], 416293865Sallanjude e_status.cstat[1], e_status.cstat[2], 417293865Sallanjude e_status.cstat[3]); 418293865Sallanjude if (e_desc.elm_desc_len > 0) { 419293865Sallanjude printf("\t\tDescription: %s\n", 420293865Sallanjude e_desc.elm_desc_str); 421293865Sallanjude } 422293865Sallanjude if (e_devname.elm_names_len > 0) { 423293865Sallanjude printf("\t\tDevice Names: %s\n", 424293865Sallanjude e_devname.elm_devnames); 425293865Sallanjude } 426293865Sallanjude extra = stat2sbuf(e_ptr[j].elm_type, e_status.cstat); 427293865Sallanjude if (sbuf_len(extra) > 0) { 428293865Sallanjude printf("\t\tExtra status:\n%s", 429293865Sallanjude sbuf_data(extra)); 430293865Sallanjude } 431293865Sallanjude sbuf_delete(extra); 432293865Sallanjude free(e_devname.elm_devnames); 433293865Sallanjude } 434293865Sallanjude close(fd); 435293865Sallanjude } 436293865Sallanjude globfree(&g); 437293865Sallanjude 438293865Sallanjude return (EXIT_SUCCESS); 439293865Sallanjude} 440293865Sallanjude 441293865Sallanjudestatic int 442293865Sallanjudeencstatus(int argc, char **argv __unused) 443293865Sallanjude{ 444293865Sallanjude glob_t g; 445293865Sallanjude int fd, status; 446293865Sallanjude size_t i, e; 447293865Sallanjude u_char estat; 448293865Sallanjude 449293865Sallanjude status = 0; 450293865Sallanjude if (argc != 1) { 451293865Sallanjude usage(stderr, "status"); 452293865Sallanjude } 453293865Sallanjude 454293865Sallanjude /* Get the list of ses devices */ 455293865Sallanjude if (glob(uflag, 0, NULL, &g) == GLOB_NOMATCH) { 456293865Sallanjude globfree(&g); 457293865Sallanjude errx(EXIT_FAILURE, "No SES devices found"); 458293865Sallanjude } 459293865Sallanjude for (i = 0; i < g.gl_pathc; i++) { 460293865Sallanjude /* ensure we only got numbers after ses */ 461293865Sallanjude if (strspn(g.gl_pathv[i] + 8, "0123456789") != 462293865Sallanjude strlen(g.gl_pathv[i] + 8)) { 463293865Sallanjude continue; 464293865Sallanjude } 465293865Sallanjude if ((fd = open(g.gl_pathv[i], O_RDWR)) < 0) { 466293865Sallanjude /* 467293865Sallanjude * Don't treat non-access errors as critical if we are 468293865Sallanjude * accessing all devices 469293865Sallanjude */ 470293865Sallanjude if (errno == EACCES && g.gl_pathc > 1) { 471293865Sallanjude err(EXIT_FAILURE, "unable to access SES device"); 472293865Sallanjude } 473293865Sallanjude warn("unable to access SES device: %s", g.gl_pathv[i]); 474293865Sallanjude continue; 475293865Sallanjude } 476293865Sallanjude 477293865Sallanjude if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &estat) < 0) { 478293865Sallanjude close(fd); 479293865Sallanjude err(EXIT_FAILURE, "ENCIOC_GETENCSTAT"); 480293865Sallanjude } 481293865Sallanjude 482293865Sallanjude printf("%s: ", g.gl_pathv[i] + 5); 483293865Sallanjude e = 0; 484293865Sallanjude if (estat == 0) { 485293865Sallanjude if (status == 0) { 486293865Sallanjude status = 1; 487293865Sallanjude } 488293865Sallanjude printf("OK"); 489293865Sallanjude } else { 490293865Sallanjude if (estat & SES_ENCSTAT_INFO) { 491293865Sallanjude printf("INFO"); 492293865Sallanjude e++; 493293865Sallanjude } 494293865Sallanjude if (estat & SES_ENCSTAT_NONCRITICAL) { 495293865Sallanjude if (e) 496293865Sallanjude printf(","); 497293865Sallanjude printf("NONCRITICAL"); 498293865Sallanjude e++; 499293865Sallanjude } 500293865Sallanjude if (estat & SES_ENCSTAT_CRITICAL) { 501293865Sallanjude if (e) 502293865Sallanjude printf(","); 503293865Sallanjude printf("CRITICAL"); 504293865Sallanjude e++; 505293865Sallanjude status = -1; 506293865Sallanjude } 507293865Sallanjude if (estat & SES_ENCSTAT_UNRECOV) { 508293865Sallanjude if (e) 509293865Sallanjude printf(","); 510293865Sallanjude printf("UNRECOV"); 511293865Sallanjude e++; 512293865Sallanjude status = -1; 513293865Sallanjude } 514293865Sallanjude } 515293865Sallanjude printf("\n"); 516293865Sallanjude 517293865Sallanjude close(fd); 518293865Sallanjude } 519293865Sallanjude globfree(&g); 520293865Sallanjude 521293865Sallanjude if (status == 1) { 522293865Sallanjude return (EXIT_SUCCESS); 523293865Sallanjude } else { 524293865Sallanjude return (EXIT_FAILURE); 525293865Sallanjude } 526293865Sallanjude} 527293865Sallanjude 528287473Sbaptint 529287473Sbaptmain(int argc, char **argv) 530287473Sbapt{ 531293865Sallanjude int i, ch; 532287473Sbapt struct command *cmd = NULL; 533287473Sbapt 534293865Sallanjude uflag = "/dev/ses[0-9]*"; 535293865Sallanjude while ((ch = getopt_long(argc, argv, "u:", NULL, NULL)) != -1) { 536293865Sallanjude switch (ch) { 537293865Sallanjude case 'u': 538293865Sallanjude uflag = optarg; 539293865Sallanjude break; 540293865Sallanjude case '?': 541293865Sallanjude default: 542293865Sallanjude usage(stderr, NULL); 543293865Sallanjude } 544293865Sallanjude } 545293865Sallanjude argc -= optind; 546293865Sallanjude argv += optind; 547293865Sallanjude 548293865Sallanjude if (argc < 1) { 549287473Sbapt warnx("Missing command"); 550293865Sallanjude usage(stderr, NULL); 551287473Sbapt } 552287473Sbapt 553287473Sbapt for (i = 0; i < nbcmds; i++) { 554293865Sallanjude if (strcmp(argv[0], cmds[i].name) == 0) { 555287473Sbapt cmd = &cmds[i]; 556287473Sbapt break; 557287473Sbapt } 558287473Sbapt } 559287473Sbapt 560287473Sbapt if (cmd == NULL) { 561293865Sallanjude warnx("unknown command %s", argv[0]); 562293865Sallanjude usage(stderr, NULL); 563287473Sbapt } 564287473Sbapt 565287473Sbapt return (cmd->exec(argc, argv)); 566287473Sbapt} 567