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 2005 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 * listdgrp.c 32 * 33 * Contains 34 * listdgrp Writes on the standard output stream a list of devices 35 * that belong to the specified device group 36 */ 37 38 #include <sys/types.h> 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <errno.h> 43 #include <devmgmt.h> 44 #include <devtab.h> 45 #include <fmtmsg.h> 46 47 48 /* 49 * Local Definitions 50 * TRUE Boolean TRUE value (if not already defined) 51 * FALSE Boolean not-TRUE value (if not already defined) 52 */ 53 54 #ifndef TRUE 55 #define TRUE ('t') 56 #endif 57 58 #ifndef FALSE 59 #define FALSE (0) 60 #endif 61 62 /* 63 * Messages: 64 * M_USAGE Command usage error 65 * M_NODGRP Device group not found 66 * M_DGRPTAB Device-group table not found 67 * M_ERROR Internal error 68 */ 69 70 #define M_USAGE "usage: listdgrp dgroup" 71 #define M_NODGRP "Device group not found: %s" 72 #define M_DGRPTAB "Cannot open device-group table: %s" 73 #define M_ERROR "Internal error, errno=%d" 74 75 76 /* 77 * Exit codes 78 * EX_OK Exiting okay, no problem 79 * EX_ERROR Some problem with the command 80 * EX_NODGRPTAB Device group table could not be opened 81 * EX_NODGROUP Device group couldn't be found 82 */ 83 84 #define EX_OK 0 85 #define EX_ERROR 1 86 #define EX_NODGRPTAB 2 87 #define EX_NODGROUP 3 88 89 90 /* 91 * Macros 92 * stdmsg(r,l,s,t) Write a message in standard format 93 * r Recoverability flag 94 * l Label 95 * s Severity 96 * t Tag 97 */ 98 99 #define stdmsg(r,l,s,t) (void) fmtmsg(MM_PRINT|MM_UTIL|r,l,s,t,MM_NULLACT,MM_NULLTAG) 100 101 /* 102 * Global Variables 103 */ 104 105 106 /* 107 * Static Variables 108 * 109 * lbl Buffer for the message label 110 */ 111 112 static char lbl[MM_MXLABELLN+1]; 113 static char msg[MM_MXTXTLN+1]; 114 115 /* 116 * listdgrp <dgroup> 117 * 118 * List the devices that belong to the device group <dgroup>. 119 * It writes the list to the standard output file (stdout) 120 * in a new-line list. 121 * 122 * Returns: 123 * 0 Ok 124 * 1 Syntax or other error 125 * 2 Device table can't be opened 126 * 3 Device group doesn't exist 127 */ 128 129 int 130 main(int argc, char **argv) 131 { 132 133 /* 134 * Automatic data 135 */ 136 137 char **devices; /* List of devices in the group */ 138 char **pp; /* Running pointer to device names */ 139 char *cmdname; /* Simple command name */ 140 char *dgrptab; /* The device-group table name */ 141 char *dgroup; /* Device group to list */ 142 int exitcode; /* Value to return to the caller */ 143 int sev; /* Message severity */ 144 int optchar; /* Option char (from getopt()) */ 145 int usageerr; /* TRUE if syntax error on command */ 146 147 148 /* Build the message label from the (simple) command name */ 149 if ((cmdname = strrchr(argv[0], '/')) != (char *) NULL) cmdname++; 150 else cmdname = argv[0]; 151 (void) strlcat(strcpy(lbl, "UX:"), cmdname, sizeof(lbl)); 152 153 /* Only write the text component of a message (this goes away in SVR4.1) */ 154 (void) putenv("MSGVERB=text"); 155 156 /* 157 * Parse the command line: 158 * - Options 159 * - Device group to display 160 */ 161 162 /* 163 * Extract options from the command line 164 */ 165 166 /* Initializations */ 167 usageerr = FALSE; /* No errors on the command line (yet) */ 168 169 /* 170 * Loop until all of the command line options have been parced 171 * (and don't let getopt() write messages) 172 */ 173 174 opterr = FALSE; 175 while ((optchar = getopt(argc, argv, "")) != EOF) switch (optchar) { 176 177 /* Default case -- command usage error */ 178 case '?': 179 default: 180 usageerr = TRUE; 181 break; 182 } 183 184 /* Check the argument count and extract the device group name */ 185 if (usageerr || (optind != argc-1)) usageerr = TRUE; 186 else dgroup = argv[optind]; 187 188 /* If there is a usage error, write an appropriate message and exit */ 189 if (usageerr) { 190 stdmsg(MM_NRECOV, lbl, MM_ERROR, M_USAGE); 191 exit(EX_ERROR); 192 } 193 194 /* Open the device-group file (if there's one to be opened) */ 195 if (!_opendgrptab("r")) { 196 if (dgrptab = _dgrptabpath()) { 197 (void) snprintf(msg, sizeof(msg), M_DGRPTAB, dgrptab); 198 exitcode = EX_NODGRPTAB; 199 sev = MM_ERROR; 200 } else { 201 (void) sprintf(msg, M_ERROR, errno); 202 exitcode = EX_ERROR; 203 sev = MM_HALT; 204 } 205 stdmsg(MM_NRECOV, lbl, sev, msg); 206 exit(exitcode); 207 } 208 209 210 /* 211 * Get the list of devices associated with the device group. 212 * If we get one, write the list to the standard output. 213 * Otherwise, write an appropriate error message 214 */ 215 216 exitcode = EX_OK; 217 if (devices = listdgrp(dgroup)) { 218 for (pp = devices ; *pp ; pp++) (void) puts(*pp); 219 } 220 else { 221 if (errno == EINVAL) { 222 (void) snprintf(msg, sizeof(msg), M_NODGRP, dgroup); 223 stdmsg(MM_NRECOV, lbl, MM_ERROR, msg); 224 exitcode = EX_NODGROUP; 225 } 226 else { 227 (void) sprintf(msg, M_ERROR, errno); 228 stdmsg(MM_NRECOV, lbl, MM_HALT, msg); 229 exitcode = EX_ERROR; 230 } 231 } 232 233 /* Finished (now wasn't that special?) */ 234 return(exitcode); 235 } 236