1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * listdgrp.c 35 * 36 * Contains 37 * listdgrp Writes on the standard output stream a list of devices 38 * that belong to the specified device group 39 */ 40 41 #include <sys/types.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <errno.h> 46 #include <devmgmt.h> 47 #include <devtab.h> 48 #include <fmtmsg.h> 49 50 51 /* 52 * Local Definitions 53 * TRUE Boolean TRUE value (if not already defined) 54 * FALSE Boolean not-TRUE value (if not already defined) 55 */ 56 57 #ifndef TRUE 58 #define TRUE ('t') 59 #endif 60 61 #ifndef FALSE 62 #define FALSE (0) 63 #endif 64 65 /* 66 * Messages: 67 * M_USAGE Command usage error 68 * M_NODGRP Device group not found 69 * M_DGRPTAB Device-group table not found 70 * M_ERROR Internal error 71 */ 72 73 #define M_USAGE "usage: listdgrp dgroup" 74 #define M_NODGRP "Device group not found: %s" 75 #define M_DGRPTAB "Cannot open device-group table: %s" 76 #define M_ERROR "Internal error, errno=%d" 77 78 79 /* 80 * Exit codes 81 * EX_OK Exiting okay, no problem 82 * EX_ERROR Some problem with the command 83 * EX_NODGRPTAB Device group table could not be opened 84 * EX_NODGROUP Device group couldn't be found 85 */ 86 87 #define EX_OK 0 88 #define EX_ERROR 1 89 #define EX_NODGRPTAB 2 90 #define EX_NODGROUP 3 91 92 93 /* 94 * Macros 95 * stdmsg(r,l,s,t) Write a message in standard format 96 * r Recoverability flag 97 * l Label 98 * s Severity 99 * t Tag 100 */ 101 102 #define stdmsg(r,l,s,t) (void) fmtmsg(MM_PRINT|MM_UTIL|r,l,s,t,MM_NULLACT,MM_NULLTAG) 103 104 /* 105 * Global Variables 106 */ 107 108 109 /* 110 * Static Variables 111 * 112 * lbl Buffer for the message label 113 */ 114 115 static char lbl[MM_MXLABELLN+1]; 116 static char msg[MM_MXTXTLN+1]; 117 118 /* 119 * listdgrp <dgroup> 120 * 121 * List the devices that belong to the device group <dgroup>. 122 * It writes the list to the standard output file (stdout) 123 * in a new-line list. 124 * 125 * Returns: 126 * 0 Ok 127 * 1 Syntax or other error 128 * 2 Device table can't be opened 129 * 3 Device group doesn't exist 130 */ 131 132 main(argc, argv) 133 int argc; /* Number of items in command */ 134 char **argv; /* List of pointers to the arguments */ 135 { 136 137 /* 138 * Automatic data 139 */ 140 141 char **devices; /* List of devices in the group */ 142 char **pp; /* Running pointer to device names */ 143 char *cmdname; /* Simple command name */ 144 char *dgrptab; /* The device-group table name */ 145 char *dgroup; /* Device group to list */ 146 int exitcode; /* Value to return to the caller */ 147 int sev; /* Message severity */ 148 int optchar; /* Option char (from getopt()) */ 149 int usageerr; /* TRUE if syntax error on command */ 150 151 152 /* Build the message label from the (simple) command name */ 153 if ((cmdname = strrchr(argv[0], '/')) != (char *) NULL) cmdname++; 154 else cmdname = argv[0]; 155 (void) strlcat(strcpy(lbl, "UX:"), cmdname, sizeof(lbl)); 156 157 /* Only write the text component of a message (this goes away in SVR4.1) */ 158 (void) putenv("MSGVERB=text"); 159 160 /* 161 * Parse the command line: 162 * - Options 163 * - Device group to display 164 */ 165 166 /* 167 * Extract options from the command line 168 */ 169 170 /* Initializations */ 171 usageerr = FALSE; /* No errors on the command line (yet) */ 172 173 /* 174 * Loop until all of the command line options have been parced 175 * (and don't let getopt() write messages) 176 */ 177 178 opterr = FALSE; 179 while ((optchar = getopt(argc, argv, "")) != EOF) switch (optchar) { 180 181 /* Default case -- command usage error */ 182 case '?': 183 default: 184 usageerr = TRUE; 185 break; 186 } 187 188 /* Check the argument count and extract the device group name */ 189 if (usageerr || (optind != argc-1)) usageerr = TRUE; 190 else dgroup = argv[optind]; 191 192 /* If there is a usage error, write an appropriate message and exit */ 193 if (usageerr) { 194 stdmsg(MM_NRECOV, lbl, MM_ERROR, M_USAGE); 195 exit(EX_ERROR); 196 } 197 198 /* Open the device-group file (if there's one to be opened) */ 199 if (!_opendgrptab("r")) { 200 if (dgrptab = _dgrptabpath()) { 201 (void) snprintf(msg, sizeof(msg), M_DGRPTAB, dgrptab); 202 exitcode = EX_NODGRPTAB; 203 sev = MM_ERROR; 204 } else { 205 (void) sprintf(msg, M_ERROR, errno); 206 exitcode = EX_ERROR; 207 sev = MM_HALT; 208 } 209 stdmsg(MM_NRECOV, lbl, sev, msg); 210 exit(exitcode); 211 } 212 213 214 /* 215 * Get the list of devices associated with the device group. 216 * If we get one, write the list to the standard output. 217 * Otherwise, write an appropriate error message 218 */ 219 220 exitcode = EX_OK; 221 if (devices = listdgrp(dgroup)) { 222 for (pp = devices ; *pp ; pp++) (void) puts(*pp); 223 } 224 else { 225 if (errno == EINVAL) { 226 (void) snprintf(msg, sizeof(msg), M_NODGRP, dgroup); 227 stdmsg(MM_NRECOV, lbl, MM_ERROR, msg); 228 exitcode = EX_NODGROUP; 229 } 230 else { 231 (void) sprintf(msg, M_ERROR, errno); 232 stdmsg(MM_NRECOV, lbl, MM_HALT, msg); 233 exitcode = EX_ERROR; 234 } 235 } 236 237 /* Finished (now wasn't that special?) */ 238 return(exitcode); 239 } 240