1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate /* 35*7c478bd9Sstevel@tonic-gate * fmtmsg.c 36*7c478bd9Sstevel@tonic-gate * 37*7c478bd9Sstevel@tonic-gate * Contains: 38*7c478bd9Sstevel@tonic-gate * fmtmsg Command that writes a message in the standard 39*7c478bd9Sstevel@tonic-gate * message format. May in future make these 40*7c478bd9Sstevel@tonic-gate * messages available for logging. 41*7c478bd9Sstevel@tonic-gate */ 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * Header files used: 46*7c478bd9Sstevel@tonic-gate * <stdio.h> C Standard I/O function definitions 47*7c478bd9Sstevel@tonic-gate * <string.h> C string-handling definitions 48*7c478bd9Sstevel@tonic-gate * <errno.h> UNIX error-code "errno" definitions 49*7c478bd9Sstevel@tonic-gate * <fmtmsg.h> Standard Message definitions 50*7c478bd9Sstevel@tonic-gate */ 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #include <stdio.h> 53*7c478bd9Sstevel@tonic-gate #include <string.h> 54*7c478bd9Sstevel@tonic-gate #include <errno.h> 55*7c478bd9Sstevel@tonic-gate #include <fmtmsg.h> 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate /* 59*7c478bd9Sstevel@tonic-gate * Externals referenced: 60*7c478bd9Sstevel@tonic-gate * strtol Function that converts char strings to "long" 61*7c478bd9Sstevel@tonic-gate * fmtmsg Function that writes a message in standard format 62*7c478bd9Sstevel@tonic-gate * getenv Function that extracts an environment variable's 63*7c478bd9Sstevel@tonic-gate * value 64*7c478bd9Sstevel@tonic-gate * malloc Allocate memory from the memory pool 65*7c478bd9Sstevel@tonic-gate * free Frees allocated memory 66*7c478bd9Sstevel@tonic-gate * getopt Function that extracts arguments from the command- 67*7c478bd9Sstevel@tonic-gate * optarg Points to option's argument (from getopt()) 68*7c478bd9Sstevel@tonic-gate * optind Option's argument index (from getopt()) 69*7c478bd9Sstevel@tonic-gate * opterr FLAG, write error if invalid option (for getopt()) 70*7c478bd9Sstevel@tonic-gate * line. 71*7c478bd9Sstevel@tonic-gate * exit Exits the command 72*7c478bd9Sstevel@tonic-gate */ 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate extern long strtol(); 75*7c478bd9Sstevel@tonic-gate extern int fmtmsg(); 76*7c478bd9Sstevel@tonic-gate extern char *getenv(); 77*7c478bd9Sstevel@tonic-gate extern void *malloc(); 78*7c478bd9Sstevel@tonic-gate extern void free(); 79*7c478bd9Sstevel@tonic-gate extern int getopt(); 80*7c478bd9Sstevel@tonic-gate extern char *optarg; 81*7c478bd9Sstevel@tonic-gate extern int optind; 82*7c478bd9Sstevel@tonic-gate extern int opterr; 83*7c478bd9Sstevel@tonic-gate extern void exit(); 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate /* 86*7c478bd9Sstevel@tonic-gate * Local definitions 87*7c478bd9Sstevel@tonic-gate */ 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate /* 90*7c478bd9Sstevel@tonic-gate * Local constants 91*7c478bd9Sstevel@tonic-gate */ 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate /* 95*7c478bd9Sstevel@tonic-gate * Boolean constants 96*7c478bd9Sstevel@tonic-gate * TRUE Boolean value for "true" (any bits on) 97*7c478bd9Sstevel@tonic-gate * FALSE Boolean value for "false" (all bits off) 98*7c478bd9Sstevel@tonic-gate */ 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate #ifndef FALSE 101*7c478bd9Sstevel@tonic-gate #define FALSE (0) 102*7c478bd9Sstevel@tonic-gate #endif 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate #ifndef TRUE 105*7c478bd9Sstevel@tonic-gate #define TRUE (1) 106*7c478bd9Sstevel@tonic-gate #endif 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate #define CLASS (MM_PRINT|MM_SOFT|MM_NRECOV|MM_UTIL) 110*7c478bd9Sstevel@tonic-gate #define BIGUSAGE "fmtmsg [-a action] [-c class] [-l label] [-s severity] [-t tag]\n [-u subclass[,subclass[,...]]] [text]\n" 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate /* 114*7c478bd9Sstevel@tonic-gate * Local data-type definitions 115*7c478bd9Sstevel@tonic-gate */ 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate /* 118*7c478bd9Sstevel@tonic-gate * Structure used for tables containing keywords and integer values 119*7c478bd9Sstevel@tonic-gate */ 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate struct sev_info { 122*7c478bd9Sstevel@tonic-gate char *keyword; 123*7c478bd9Sstevel@tonic-gate int value; 124*7c478bd9Sstevel@tonic-gate }; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate /* 128*7c478bd9Sstevel@tonic-gate * Structure used for tables containing keywords, long values 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate struct class_info { 132*7c478bd9Sstevel@tonic-gate char *keyword; 133*7c478bd9Sstevel@tonic-gate long value; 134*7c478bd9Sstevel@tonic-gate long conflict; 135*7c478bd9Sstevel@tonic-gate }; 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* 139*7c478bd9Sstevel@tonic-gate * Severity string structure 140*7c478bd9Sstevel@tonic-gate * 141*7c478bd9Sstevel@tonic-gate * struct sevstr 142*7c478bd9Sstevel@tonic-gate * sevvalue Value of the severity-level being defined 143*7c478bd9Sstevel@tonic-gate * sevkywd Keyword identifying the severity 144*7c478bd9Sstevel@tonic-gate * sevprptr Pointer to the string associated with the value 145*7c478bd9Sstevel@tonic-gate * sevnext Pointer to the next value in the list. 146*7c478bd9Sstevel@tonic-gate */ 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate struct sevstr { 149*7c478bd9Sstevel@tonic-gate int sevvalue; 150*7c478bd9Sstevel@tonic-gate char *sevkywd; 151*7c478bd9Sstevel@tonic-gate char *sevprstr; 152*7c478bd9Sstevel@tonic-gate struct sevstr *sevnext; 153*7c478bd9Sstevel@tonic-gate }; 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate /* 157*7c478bd9Sstevel@tonic-gate * Local static data 158*7c478bd9Sstevel@tonic-gate */ 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate /* 162*7c478bd9Sstevel@tonic-gate * Table contains the keywords for the classes of a message 163*7c478bd9Sstevel@tonic-gate */ 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate static struct class_info classes[] = { 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate {"hard", MM_HARD, MM_SOFT|MM_FIRM}, /* hardware */ 168*7c478bd9Sstevel@tonic-gate {"soft", MM_SOFT, MM_HARD|MM_FIRM}, /* software */ 169*7c478bd9Sstevel@tonic-gate {"firm", MM_FIRM, MM_SOFT|MM_FIRM}, /* firmware */ 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate {(char *) NULL, 0L, 0L} /* end of list */ 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate }; 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate /* 177*7c478bd9Sstevel@tonic-gate * Table contains the keywords for the subclasses for a message 178*7c478bd9Sstevel@tonic-gate */ 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate static struct class_info subclasses[] = { 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate {"appl", MM_APPL, MM_UTIL|MM_OPSYS}, /* Application */ 183*7c478bd9Sstevel@tonic-gate {"util", MM_UTIL, MM_APPL|MM_OPSYS}, /* Utility */ 184*7c478bd9Sstevel@tonic-gate {"opsys", MM_OPSYS, MM_APPL|MM_UTIL}, /* Operating System */ 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate {"recov", MM_RECOVER, MM_NRECOV}, /* Recoverable */ 187*7c478bd9Sstevel@tonic-gate {"nrecov", MM_NRECOV, MM_RECOVER}, /* Non-recoverable */ 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate {"print", MM_PRINT, 0L}, /* Write message to stderr */ 190*7c478bd9Sstevel@tonic-gate {"console", MM_CONSOLE, 0L}, /* Write message on /dev/console */ 191*7c478bd9Sstevel@tonic-gate {(char *) NULL, 0L, 0L} /* End of list */ 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate }; 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate /* 197*7c478bd9Sstevel@tonic-gate * Table contains the keywords for the standard severities of a message. 198*7c478bd9Sstevel@tonic-gate * User may supply more through the SEV_LEVEL environment variable. 199*7c478bd9Sstevel@tonic-gate */ 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate static struct sev_info severities[] = { 202*7c478bd9Sstevel@tonic-gate {"halt", MM_HALT}, /* halt */ 203*7c478bd9Sstevel@tonic-gate {"error", MM_ERROR}, /* error */ 204*7c478bd9Sstevel@tonic-gate {"warn", MM_WARNING}, /* warn */ 205*7c478bd9Sstevel@tonic-gate {"info", MM_INFO}, /* info */ 206*7c478bd9Sstevel@tonic-gate {(char *) NULL, 0} /* end of list */ 207*7c478bd9Sstevel@tonic-gate }; 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate /* 211*7c478bd9Sstevel@tonic-gate * Buffers used by the command 212*7c478bd9Sstevel@tonic-gate */ 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate static char labelbuf[128]; /* Buf for message label */ 215*7c478bd9Sstevel@tonic-gate static char msgbuf[256]; /* Buf for messages */ 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate /* 218*7c478bd9Sstevel@tonic-gate * static char *exttok(str, delims) 219*7c478bd9Sstevel@tonic-gate * char *str 220*7c478bd9Sstevel@tonic-gate * char *delims 221*7c478bd9Sstevel@tonic-gate * 222*7c478bd9Sstevel@tonic-gate * This function examines the string pointed to by "str", looking 223*7c478bd9Sstevel@tonic-gate * for the first occurrence of any of the characters in the string 224*7c478bd9Sstevel@tonic-gate * whose address is "delims". It returns the address of that 225*7c478bd9Sstevel@tonic-gate * character or (char *) NULL if there was nothing to search. 226*7c478bd9Sstevel@tonic-gate * 227*7c478bd9Sstevel@tonic-gate * Arguments: 228*7c478bd9Sstevel@tonic-gate * str Address of the string to search 229*7c478bd9Sstevel@tonic-gate * delims Address of the string containing delimiters 230*7c478bd9Sstevel@tonic-gate * 231*7c478bd9Sstevel@tonic-gate * Returns: char * 232*7c478bd9Sstevel@tonic-gate * Returns the address of the first occurrence of any of the characters 233*7c478bd9Sstevel@tonic-gate * in "delim" in the string "str" (incl '\0'). If there was nothing 234*7c478bd9Sstevel@tonic-gate * to search, the function returns (char *) NULL. 235*7c478bd9Sstevel@tonic-gate * 236*7c478bd9Sstevel@tonic-gate * Notes: 237*7c478bd9Sstevel@tonic-gate * - This function is needed because strtok() can't be used inside a 238*7c478bd9Sstevel@tonic-gate * function. Besides, strtok() is destructive in the string, which 239*7c478bd9Sstevel@tonic-gate * is undesirable in many circumstances. 240*7c478bd9Sstevel@tonic-gate * - This function understands escaped delimiters as non-delimiters. 241*7c478bd9Sstevel@tonic-gate * Delimiters are escaped by preceding them with '\' characters. 242*7c478bd9Sstevel@tonic-gate * The '\' character also must be escaped. 243*7c478bd9Sstevel@tonic-gate */ 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate static char * 246*7c478bd9Sstevel@tonic-gate exttok(tok, delims) 247*7c478bd9Sstevel@tonic-gate char *tok; /* Ptr to the token we're parsing */ 248*7c478bd9Sstevel@tonic-gate char *delims; /* Ptr to string with delimiters */ 249*7c478bd9Sstevel@tonic-gate { 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate /* Automatic Data */ 252*7c478bd9Sstevel@tonic-gate char *tokend; /* Ptr to the end of the token */ 253*7c478bd9Sstevel@tonic-gate char *p, *q; /* Temp pointers */ 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate /* Algorithm: 257*7c478bd9Sstevel@tonic-gate * 1. Get the starting address (new string or where we 258*7c478bd9Sstevel@tonic-gate * left off). If nothing to search, return (char *) NULL 259*7c478bd9Sstevel@tonic-gate * 2. Find the end of the string 260*7c478bd9Sstevel@tonic-gate * 3. Look for the first unescaped delimiter closest to the 261*7c478bd9Sstevel@tonic-gate * beginning of the string 262*7c478bd9Sstevel@tonic-gate * 4. Remember where we left off 263*7c478bd9Sstevel@tonic-gate * 5. Return a pointer to the delimiter we found 264*7c478bd9Sstevel@tonic-gate */ 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate /* Begin at the beginning, if any */ 267*7c478bd9Sstevel@tonic-gate if (tok == (char *) NULL) { 268*7c478bd9Sstevel@tonic-gate return ((char *) NULL); 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate /* Find end of the token string */ 272*7c478bd9Sstevel@tonic-gate tokend = tok + strlen(tok); 273*7c478bd9Sstevel@tonic-gate 274*7c478bd9Sstevel@tonic-gate /* Look for the 1st occurrence of any delimiter */ 275*7c478bd9Sstevel@tonic-gate for (p = delims ; *p != '\0' ; p++) { 276*7c478bd9Sstevel@tonic-gate for (q = strchr(tok, *p) ; q && (q != tok) && (*(q-1) == '\\') ; q = strchr(q+1, *p)) ; 277*7c478bd9Sstevel@tonic-gate if (q && (q < tokend)) tokend = q; 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate /* Done */ 281*7c478bd9Sstevel@tonic-gate return(tokend); 282*7c478bd9Sstevel@tonic-gate } 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate /* 285*7c478bd9Sstevel@tonic-gate * char *noesc(str) 286*7c478bd9Sstevel@tonic-gate * 287*7c478bd9Sstevel@tonic-gate * This function squeezes out all of the escaped character sequences 288*7c478bd9Sstevel@tonic-gate * from the string <str>. It returns a pointer to that string. 289*7c478bd9Sstevel@tonic-gate * 290*7c478bd9Sstevel@tonic-gate * Arguments: 291*7c478bd9Sstevel@tonic-gate * str char * 292*7c478bd9Sstevel@tonic-gate * The string that is to have its escaped characters removed. 293*7c478bd9Sstevel@tonic-gate * 294*7c478bd9Sstevel@tonic-gate * Returns: char * 295*7c478bd9Sstevel@tonic-gate * This function returns its argument <str> always. 296*7c478bd9Sstevel@tonic-gate * 297*7c478bd9Sstevel@tonic-gate * Notes: 298*7c478bd9Sstevel@tonic-gate * This function potentially modifies the string it is given. 299*7c478bd9Sstevel@tonic-gate */ 300*7c478bd9Sstevel@tonic-gate 301*7c478bd9Sstevel@tonic-gate char * 302*7c478bd9Sstevel@tonic-gate noesc(str) 303*7c478bd9Sstevel@tonic-gate char *str; /* String to remove escaped characters from */ 304*7c478bd9Sstevel@tonic-gate { 305*7c478bd9Sstevel@tonic-gate char *p; /* Temp string pointer */ 306*7c478bd9Sstevel@tonic-gate char *q; /* Temp string pointer */ 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate /* Look for an escaped character */ 309*7c478bd9Sstevel@tonic-gate p = str; 310*7c478bd9Sstevel@tonic-gate while (*p && (*p != '\\')) p++; 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate /* 314*7c478bd9Sstevel@tonic-gate * If there was at least one, squeeze them out 315*7c478bd9Sstevel@tonic-gate * Otherwise, don't touch the argument string 316*7c478bd9Sstevel@tonic-gate */ 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate if (*p) { 319*7c478bd9Sstevel@tonic-gate q = p++; 320*7c478bd9Sstevel@tonic-gate while (*q++ = *p++) if (*p == '\\') p++; 321*7c478bd9Sstevel@tonic-gate } 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate /* Finished. Return our argument */ 324*7c478bd9Sstevel@tonic-gate return(str); 325*7c478bd9Sstevel@tonic-gate } 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate /* 328*7c478bd9Sstevel@tonic-gate * struct sevstr *getauxsevs(ptr) 329*7c478bd9Sstevel@tonic-gate * 330*7c478bd9Sstevel@tonic-gate * Parses a string that is in the format of the severity definitions. 331*7c478bd9Sstevel@tonic-gate * Returns a pointer to a (malloc'd) structure that contains the 332*7c478bd9Sstevel@tonic-gate * definition, or (struct sevstr *) NULL if none was parsed. 333*7c478bd9Sstevel@tonic-gate * 334*7c478bd9Sstevel@tonic-gate * Arguments: 335*7c478bd9Sstevel@tonic-gate * ptr char * 336*7c478bd9Sstevel@tonic-gate * References the string from which data is to be extracted. 337*7c478bd9Sstevel@tonic-gate * If (char *) NULL, continue where we left off. Otherwise, 338*7c478bd9Sstevel@tonic-gate * start with the string referenced by ptr. 339*7c478bd9Sstevel@tonic-gate * 340*7c478bd9Sstevel@tonic-gate * Returns: struct sevstr * 341*7c478bd9Sstevel@tonic-gate * A pointer to a malloc'd structure containing the severity definition 342*7c478bd9Sstevel@tonic-gate * parsed from string, or (struct sevstr *) NULL if none. 343*7c478bd9Sstevel@tonic-gate * 344*7c478bd9Sstevel@tonic-gate * Notes: 345*7c478bd9Sstevel@tonic-gate * - This function is destructive to the string referenced by its argument. 346*7c478bd9Sstevel@tonic-gate */ 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate /* Static data */ 350*7c478bd9Sstevel@tonic-gate static char *leftoff = (char *) NULL; 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate static struct sevstr * 353*7c478bd9Sstevel@tonic-gate getauxsevs(ptr) 354*7c478bd9Sstevel@tonic-gate char *ptr; 355*7c478bd9Sstevel@tonic-gate { 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate /* Automatic data */ 358*7c478bd9Sstevel@tonic-gate char *current; /* Ptr to current sev def'n */ 359*7c478bd9Sstevel@tonic-gate char *tokend; /* Ptr to end of current sev def'n */ 360*7c478bd9Sstevel@tonic-gate char *kywd; /* Ptr to extracted kywd */ 361*7c478bd9Sstevel@tonic-gate char *valstr; /* Ptr to extracted sev value */ 362*7c478bd9Sstevel@tonic-gate char *prstr; /* Ptr to extracted print str */ 363*7c478bd9Sstevel@tonic-gate char *p; /* Temp pointer */ 364*7c478bd9Sstevel@tonic-gate int val; /* Converted severity value */ 365*7c478bd9Sstevel@tonic-gate int done; /* Flag, sev def'n found and ok? */ 366*7c478bd9Sstevel@tonic-gate struct sevstr *rtnval; /* Value to return */ 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate /* Start anew or start where we left off? */ 370*7c478bd9Sstevel@tonic-gate current = (ptr == (char *) NULL) ? leftoff : ptr; 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate /* If nothing to parse, return (char *) NULL */ 374*7c478bd9Sstevel@tonic-gate if (current == (char *) NULL) { 375*7c478bd9Sstevel@tonic-gate return ((struct sevstr *) NULL); 376*7c478bd9Sstevel@tonic-gate } 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate /* 380*7c478bd9Sstevel@tonic-gate * Look through the string "current" for a token of the form 381*7c478bd9Sstevel@tonic-gate * <kywd>,<sev>,<printstring> delimited by ':' or '\0' 382*7c478bd9Sstevel@tonic-gate */ 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate /* Loop initializations */ 385*7c478bd9Sstevel@tonic-gate done = FALSE; 386*7c478bd9Sstevel@tonic-gate rtnval = (struct sevstr *) NULL; 387*7c478bd9Sstevel@tonic-gate while (!done) { 388*7c478bd9Sstevel@tonic-gate 389*7c478bd9Sstevel@tonic-gate /* Eat leading junk */ 390*7c478bd9Sstevel@tonic-gate while (*(tokend = exttok(current, ":,")) == ':') { 391*7c478bd9Sstevel@tonic-gate current = tokend + 1; 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate /* If we've found a <kywd>,... */ 395*7c478bd9Sstevel@tonic-gate if (*tokend == ',') { 396*7c478bd9Sstevel@tonic-gate kywd = current; 397*7c478bd9Sstevel@tonic-gate *tokend = '\0'; 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate /* Look for <kywd>,<sev>,... */ 400*7c478bd9Sstevel@tonic-gate current = tokend + 1; 401*7c478bd9Sstevel@tonic-gate if (*(tokend = exttok(current, ":,")) == ',') { 402*7c478bd9Sstevel@tonic-gate valstr = current; 403*7c478bd9Sstevel@tonic-gate *tokend = '\0'; 404*7c478bd9Sstevel@tonic-gate current = tokend+1; 405*7c478bd9Sstevel@tonic-gate prstr = current; 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate /* Make sure <sev> > 4 */ 408*7c478bd9Sstevel@tonic-gate val = (int) strtol(noesc(valstr), &p, 0); 409*7c478bd9Sstevel@tonic-gate if ((val > 4) && (p == tokend)) { 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate /* 412*7c478bd9Sstevel@tonic-gate * Found <kywd>,<sev>,<printstring>. 413*7c478bd9Sstevel@tonic-gate * remember where we left off 414*7c478bd9Sstevel@tonic-gate */ 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate if (*(tokend = exttok(current, ":")) == ':') { 417*7c478bd9Sstevel@tonic-gate *tokend = '\0'; 418*7c478bd9Sstevel@tonic-gate leftoff = tokend + 1; 419*7c478bd9Sstevel@tonic-gate } else leftoff = (char *) NULL; 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate /* Alloc structure to contain severity definition */ 422*7c478bd9Sstevel@tonic-gate if (rtnval = (struct sevstr *) malloc(sizeof(struct sevstr))) { 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate /* Fill in structure */ 425*7c478bd9Sstevel@tonic-gate rtnval->sevkywd = noesc(kywd); 426*7c478bd9Sstevel@tonic-gate rtnval->sevvalue = val; 427*7c478bd9Sstevel@tonic-gate rtnval->sevprstr = noesc(prstr); 428*7c478bd9Sstevel@tonic-gate rtnval->sevnext = (struct sevstr *) NULL; 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate done = TRUE; 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate } else { 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate /* Invalid severity value, eat thru end of token */ 436*7c478bd9Sstevel@tonic-gate current = tokend; 437*7c478bd9Sstevel@tonic-gate if (*(tokend = exttok(prstr, ":")) == ':') 438*7c478bd9Sstevel@tonic-gate current++; 439*7c478bd9Sstevel@tonic-gate } 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate } else { 442*7c478bd9Sstevel@tonic-gate 443*7c478bd9Sstevel@tonic-gate /* Invalid severity definition, eat thru end of token */ 444*7c478bd9Sstevel@tonic-gate current = tokend; 445*7c478bd9Sstevel@tonic-gate if (*tokend == ':') 446*7c478bd9Sstevel@tonic-gate current++; 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate } else { 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate /* End of string found */ 452*7c478bd9Sstevel@tonic-gate done = TRUE; 453*7c478bd9Sstevel@tonic-gate leftoff = (char *) NULL; 454*7c478bd9Sstevel@tonic-gate } 455*7c478bd9Sstevel@tonic-gate 456*7c478bd9Sstevel@tonic-gate } /* while (!done) */ 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate /* Finished */ 459*7c478bd9Sstevel@tonic-gate return(rtnval); 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate /* 463*7c478bd9Sstevel@tonic-gate * fmtmsg [-a action] [-c classification] [-l label] [-s severity] [-t tag] 464*7c478bd9Sstevel@tonic-gate * [-u subclass[,subclass[,...]]] [text] 465*7c478bd9Sstevel@tonic-gate * 466*7c478bd9Sstevel@tonic-gate * Function: 467*7c478bd9Sstevel@tonic-gate * Writes a message in the standard format. Typically used by shell 468*7c478bd9Sstevel@tonic-gate * scripts to write error messages to the user. 469*7c478bd9Sstevel@tonic-gate * 470*7c478bd9Sstevel@tonic-gate * Arguments: 471*7c478bd9Sstevel@tonic-gate * text String that is the text of the message 472*7c478bd9Sstevel@tonic-gate * 473*7c478bd9Sstevel@tonic-gate * Options: 474*7c478bd9Sstevel@tonic-gate * -a action String that describes user action to take to 475*7c478bd9Sstevel@tonic-gate * correct the situation 476*7c478bd9Sstevel@tonic-gate * -c classification Keyword that identifies the type of the message 477*7c478bd9Sstevel@tonic-gate * -l label String that identifies the source of the message 478*7c478bd9Sstevel@tonic-gate * -s severity Keyword that identifies the severity of the message 479*7c478bd9Sstevel@tonic-gate * -t tag String that identifies the message (use unclear) 480*7c478bd9Sstevel@tonic-gate * -u sub_classes Comma-list of keywords that refines the type of 481*7c478bd9Sstevel@tonic-gate * the message 482*7c478bd9Sstevel@tonic-gate * 483*7c478bd9Sstevel@tonic-gate * Environment Variables Used: 484*7c478bd9Sstevel@tonic-gate * MSGVERB Defines the pieces of a message the user expects 485*7c478bd9Sstevel@tonic-gate * to see. It is a list of keywords separated by 486*7c478bd9Sstevel@tonic-gate * colons (':'). 487*7c478bd9Sstevel@tonic-gate * SEV_LEVEL Defines a list of auxiliary severity keywords, values, 488*7c478bd9Sstevel@tonic-gate * and print-strings. It is a list of fields separated 489*7c478bd9Sstevel@tonic-gate * by colons (':'). Each field consists of three 490*7c478bd9Sstevel@tonic-gate * elements, keyword, value (in octal, hex, or decimal), 491*7c478bd9Sstevel@tonic-gate * and print-string, separated by commas (','). 492*7c478bd9Sstevel@tonic-gate * 493*7c478bd9Sstevel@tonic-gate * Needs: 494*7c478bd9Sstevel@tonic-gate * 495*7c478bd9Sstevel@tonic-gate * Open Issues: 496*7c478bd9Sstevel@tonic-gate */ 497*7c478bd9Sstevel@tonic-gate 498*7c478bd9Sstevel@tonic-gate main(argc, argv) 499*7c478bd9Sstevel@tonic-gate int argc; /* Argument count */ 500*7c478bd9Sstevel@tonic-gate char *argv[]; /* Pointers to arguments */ 501*7c478bd9Sstevel@tonic-gate { 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate /* Local automatic data */ 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate long class; /* Classification (built) */ 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate int severity; /* User specified severity */ 508*7c478bd9Sstevel@tonic-gate int msgrtn; /* Value returned by fmtmsg() */ 509*7c478bd9Sstevel@tonic-gate int optchar; /* Opt char on cmdline */ 510*7c478bd9Sstevel@tonic-gate int exitval; /* Value to return */ 511*7c478bd9Sstevel@tonic-gate 512*7c478bd9Sstevel@tonic-gate int found; /* FLAG, kywd found yet? */ 513*7c478bd9Sstevel@tonic-gate int errflg; /* FLAG, error seen in cmd */ 514*7c478bd9Sstevel@tonic-gate int a_seen; /* FLAG, -a option seen */ 515*7c478bd9Sstevel@tonic-gate int c_seen; /* FLAG, -c option seen */ 516*7c478bd9Sstevel@tonic-gate int l_seen; /* FLAG, -l option seen */ 517*7c478bd9Sstevel@tonic-gate int s_seen; /* FLAG, -s option seen */ 518*7c478bd9Sstevel@tonic-gate int t_seen; /* FLAG, -t option seen */ 519*7c478bd9Sstevel@tonic-gate int u_seen; /* FLAG, -u option seen */ 520*7c478bd9Sstevel@tonic-gate int text_seen; /* FLAG, text seen */ 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate char *text; /* Ptr to user's text */ 523*7c478bd9Sstevel@tonic-gate char *label; /* Ptr to user's label */ 524*7c478bd9Sstevel@tonic-gate char *tag; /* Ptr to user's tag */ 525*7c478bd9Sstevel@tonic-gate char *action; /* Ptr to user's action str */ 526*7c478bd9Sstevel@tonic-gate char *sstr; /* Ptr to -s (severity) arg */ 527*7c478bd9Sstevel@tonic-gate char *ustr; /* Ptr to -u (subclass) arg */ 528*7c478bd9Sstevel@tonic-gate char *cstr; /* Ptr to -c (class) arg */ 529*7c478bd9Sstevel@tonic-gate char *sevstrval; /* Ptr to SEV_LEVEL argument */ 530*7c478bd9Sstevel@tonic-gate char *sevval; /* Ptr to temp SEV_LEVEL arg */ 531*7c478bd9Sstevel@tonic-gate char *tokenptr; /* Ptr to current token */ 532*7c478bd9Sstevel@tonic-gate char *cmdname; /* Ptr to base command name */ 533*7c478bd9Sstevel@tonic-gate char *p; /* Multipurpose ptr */ 534*7c478bd9Sstevel@tonic-gate 535*7c478bd9Sstevel@tonic-gate struct class_info *class_info; /* Ptr to class/subclass info structure */ 536*7c478bd9Sstevel@tonic-gate struct sev_info *sev_info; /* Ptr to severity info struct */ 537*7c478bd9Sstevel@tonic-gate struct sevstr *penvsev; /* Ptr to SEV_LEVEL values */ 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate /* 542*7c478bd9Sstevel@tonic-gate * fmtmsg 543*7c478bd9Sstevel@tonic-gate */ 544*7c478bd9Sstevel@tonic-gate 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate /* Initializations */ 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate /* Extract the base command name from the command */ 550*7c478bd9Sstevel@tonic-gate if ((p = strrchr(argv[0], '/')) == (char *) NULL) 551*7c478bd9Sstevel@tonic-gate cmdname = argv[0]; 552*7c478bd9Sstevel@tonic-gate else 553*7c478bd9Sstevel@tonic-gate cmdname = p+1; 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate /* Build the label for messages from "fmtmsg" */ 556*7c478bd9Sstevel@tonic-gate (void) snprintf(labelbuf, sizeof (labelbuf), "UX:%s", cmdname); 557*7c478bd9Sstevel@tonic-gate 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate /* 560*7c478bd9Sstevel@tonic-gate * Extract arguments from the command line 561*7c478bd9Sstevel@tonic-gate */ 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate /* Initializations */ 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate opterr = 0; /* Disable messages from getopt() */ 566*7c478bd9Sstevel@tonic-gate errflg = FALSE; /* No errors seen yet */ 567*7c478bd9Sstevel@tonic-gate 568*7c478bd9Sstevel@tonic-gate a_seen = FALSE; /* No action (-a) text seen yet */ 569*7c478bd9Sstevel@tonic-gate c_seen = FALSE; /* No classification (-c) seen yet */ 570*7c478bd9Sstevel@tonic-gate l_seen = FALSE; /* No label (-l) seen yet */ 571*7c478bd9Sstevel@tonic-gate s_seen = FALSE; /* No severity (-s) seen yet */ 572*7c478bd9Sstevel@tonic-gate t_seen = FALSE; /* No tag (-t) seen yet */ 573*7c478bd9Sstevel@tonic-gate u_seen = FALSE; /* No subclass (-u) seen yet */ 574*7c478bd9Sstevel@tonic-gate text_seen = FALSE; /* No text seen yet */ 575*7c478bd9Sstevel@tonic-gate 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate /* 578*7c478bd9Sstevel@tonic-gate * If only the command name was used, write out a usage string to 579*7c478bd9Sstevel@tonic-gate * the standard output file. 580*7c478bd9Sstevel@tonic-gate */ 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate if (argc == 1) { 583*7c478bd9Sstevel@tonic-gate (void) fputs(BIGUSAGE, stderr); 584*7c478bd9Sstevel@tonic-gate exit(0); 585*7c478bd9Sstevel@tonic-gate } 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate /* Parce command line */ 589*7c478bd9Sstevel@tonic-gate while (((optchar = getopt(argc, argv, "a:c:l:s:t:u:")) != EOF) && 590*7c478bd9Sstevel@tonic-gate !errflg) { 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate switch(optchar) { 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate case 'a': /* -a actiontext */ 595*7c478bd9Sstevel@tonic-gate if (!a_seen) { 596*7c478bd9Sstevel@tonic-gate action = optarg; 597*7c478bd9Sstevel@tonic-gate a_seen = TRUE; 598*7c478bd9Sstevel@tonic-gate } else errflg = TRUE; 599*7c478bd9Sstevel@tonic-gate break; 600*7c478bd9Sstevel@tonic-gate 601*7c478bd9Sstevel@tonic-gate case 'c': /* -c classification */ 602*7c478bd9Sstevel@tonic-gate if (!c_seen) { 603*7c478bd9Sstevel@tonic-gate cstr = optarg; 604*7c478bd9Sstevel@tonic-gate c_seen = TRUE; 605*7c478bd9Sstevel@tonic-gate } else errflg = TRUE; 606*7c478bd9Sstevel@tonic-gate break; 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate case 'l': /* -l label */ 609*7c478bd9Sstevel@tonic-gate if (!l_seen) { 610*7c478bd9Sstevel@tonic-gate label = optarg; 611*7c478bd9Sstevel@tonic-gate l_seen = TRUE; 612*7c478bd9Sstevel@tonic-gate } else errflg = TRUE; 613*7c478bd9Sstevel@tonic-gate break; 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate case 's': /* -s severity */ 616*7c478bd9Sstevel@tonic-gate if (!s_seen) { 617*7c478bd9Sstevel@tonic-gate sstr = optarg; 618*7c478bd9Sstevel@tonic-gate s_seen = TRUE; 619*7c478bd9Sstevel@tonic-gate } else errflg = TRUE; 620*7c478bd9Sstevel@tonic-gate break; 621*7c478bd9Sstevel@tonic-gate 622*7c478bd9Sstevel@tonic-gate case 't': /* -t tag */ 623*7c478bd9Sstevel@tonic-gate if (!t_seen) { 624*7c478bd9Sstevel@tonic-gate tag = optarg; 625*7c478bd9Sstevel@tonic-gate t_seen = TRUE; 626*7c478bd9Sstevel@tonic-gate } else errflg = TRUE; 627*7c478bd9Sstevel@tonic-gate break; 628*7c478bd9Sstevel@tonic-gate 629*7c478bd9Sstevel@tonic-gate case 'u': /* -u subclasslist */ 630*7c478bd9Sstevel@tonic-gate if (!u_seen) { 631*7c478bd9Sstevel@tonic-gate ustr = optarg; 632*7c478bd9Sstevel@tonic-gate u_seen = TRUE; 633*7c478bd9Sstevel@tonic-gate } else errflg = TRUE; 634*7c478bd9Sstevel@tonic-gate break; 635*7c478bd9Sstevel@tonic-gate 636*7c478bd9Sstevel@tonic-gate case '?': /* -? or unknown option */ 637*7c478bd9Sstevel@tonic-gate default: 638*7c478bd9Sstevel@tonic-gate errflg = TRUE; 639*7c478bd9Sstevel@tonic-gate break; 640*7c478bd9Sstevel@tonic-gate 641*7c478bd9Sstevel@tonic-gate } /* esac */ 642*7c478bd9Sstevel@tonic-gate } 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate /* Get the text */ 646*7c478bd9Sstevel@tonic-gate if (!errflg) { 647*7c478bd9Sstevel@tonic-gate if (argc == (optind+1)) { 648*7c478bd9Sstevel@tonic-gate text = argv[optind]; 649*7c478bd9Sstevel@tonic-gate text_seen = TRUE; 650*7c478bd9Sstevel@tonic-gate } 651*7c478bd9Sstevel@tonic-gate else if (argc != optind) { 652*7c478bd9Sstevel@tonic-gate errflg = TRUE; 653*7c478bd9Sstevel@tonic-gate } 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate /* Report syntax errors */ 658*7c478bd9Sstevel@tonic-gate if (errflg) { 659*7c478bd9Sstevel@tonic-gate (void) fputs(BIGUSAGE, stderr); 660*7c478bd9Sstevel@tonic-gate exit(1); 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate /* 665*7c478bd9Sstevel@tonic-gate * Classification. 666*7c478bd9Sstevel@tonic-gate */ 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate class = 0L; 669*7c478bd9Sstevel@tonic-gate if (c_seen) { 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gate /* Search for keyword in list */ 672*7c478bd9Sstevel@tonic-gate for (class_info = &classes[0] ; 673*7c478bd9Sstevel@tonic-gate (class_info->keyword != (char *) NULL) && 674*7c478bd9Sstevel@tonic-gate (strcmp(cstr, class_info->keyword)) ; 675*7c478bd9Sstevel@tonic-gate class_info++) ; 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate /* If invalid (keyword unknown), write a message and exit */ 678*7c478bd9Sstevel@tonic-gate if (class_info->keyword == (char *) NULL) { 679*7c478bd9Sstevel@tonic-gate (void) snprintf(msgbuf, sizeof (msgbuf), 680*7c478bd9Sstevel@tonic-gate "Invalid class: %s", cstr); 681*7c478bd9Sstevel@tonic-gate (void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf, 682*7c478bd9Sstevel@tonic-gate MM_NULLACT, MM_NULLTAG); 683*7c478bd9Sstevel@tonic-gate exit(1); 684*7c478bd9Sstevel@tonic-gate } 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate /* Save classification */ 687*7c478bd9Sstevel@tonic-gate class = class_info->value; 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate } 690*7c478bd9Sstevel@tonic-gate 691*7c478bd9Sstevel@tonic-gate 692*7c478bd9Sstevel@tonic-gate /* 693*7c478bd9Sstevel@tonic-gate * Subclassification. 694*7c478bd9Sstevel@tonic-gate */ 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate if (u_seen) { 697*7c478bd9Sstevel@tonic-gate 698*7c478bd9Sstevel@tonic-gate errflg = FALSE; 699*7c478bd9Sstevel@tonic-gate p = strcpy(malloc((unsigned int) strlen(ustr)+1), ustr); 700*7c478bd9Sstevel@tonic-gate if ((tokenptr = strtok(p, ",")) == (char *) NULL) errflg = TRUE; 701*7c478bd9Sstevel@tonic-gate else do { 702*7c478bd9Sstevel@tonic-gate 703*7c478bd9Sstevel@tonic-gate /* Got a keyword. Look for it in keyword list */ 704*7c478bd9Sstevel@tonic-gate for (class_info = subclasses ; 705*7c478bd9Sstevel@tonic-gate (class_info->keyword != (char *) NULL) && 706*7c478bd9Sstevel@tonic-gate (strcmp(tokenptr, class_info->keyword) != 0) ; 707*7c478bd9Sstevel@tonic-gate class_info++) ; 708*7c478bd9Sstevel@tonic-gate 709*7c478bd9Sstevel@tonic-gate /* If found in list and no conflict, remember in class */ 710*7c478bd9Sstevel@tonic-gate if ((class_info->keyword != (char *) NULL) && ((class & class_info->conflict) == 0L)) 711*7c478bd9Sstevel@tonic-gate class |= class_info->value; 712*7c478bd9Sstevel@tonic-gate else 713*7c478bd9Sstevel@tonic-gate errflg = TRUE; 714*7c478bd9Sstevel@tonic-gate 715*7c478bd9Sstevel@tonic-gate } while (!errflg && ((tokenptr = strtok((char *) NULL, ",")) != (char *) NULL)) ; 716*7c478bd9Sstevel@tonic-gate 717*7c478bd9Sstevel@tonic-gate if (errflg) { 718*7c478bd9Sstevel@tonic-gate (void) snprintf(msgbuf, sizeof (msgbuf), 719*7c478bd9Sstevel@tonic-gate "Invalid subclass: %s", ustr); 720*7c478bd9Sstevel@tonic-gate (void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf, 721*7c478bd9Sstevel@tonic-gate MM_NULLACT, MM_NULLTAG); 722*7c478bd9Sstevel@tonic-gate exit(1); 723*7c478bd9Sstevel@tonic-gate } 724*7c478bd9Sstevel@tonic-gate 725*7c478bd9Sstevel@tonic-gate } 726*7c478bd9Sstevel@tonic-gate 727*7c478bd9Sstevel@tonic-gate if (!c_seen & !u_seen) class = MM_NULLMC; 728*7c478bd9Sstevel@tonic-gate 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate 731*7c478bd9Sstevel@tonic-gate /* 732*7c478bd9Sstevel@tonic-gate * Severity. 733*7c478bd9Sstevel@tonic-gate */ 734*7c478bd9Sstevel@tonic-gate 735*7c478bd9Sstevel@tonic-gate if (s_seen) { 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate /* If the severity is specified as a number, use that value */ 738*7c478bd9Sstevel@tonic-gate severity = strtol(sstr, &p, 10); 739*7c478bd9Sstevel@tonic-gate if (*p || (strlen(sstr) == 0)) { 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate /* Look for the standard severities */ 742*7c478bd9Sstevel@tonic-gate for (sev_info = severities ; 743*7c478bd9Sstevel@tonic-gate (sev_info->keyword != (char *) NULL) && 744*7c478bd9Sstevel@tonic-gate (strcmp(sstr, sev_info->keyword)) ; 745*7c478bd9Sstevel@tonic-gate sev_info++) ; 746*7c478bd9Sstevel@tonic-gate 747*7c478bd9Sstevel@tonic-gate /* 748*7c478bd9Sstevel@tonic-gate * If the "severity" argument is one of the standard keywords, 749*7c478bd9Sstevel@tonic-gate * remember it for fmtmsg(). Otherwise, look at the SEV_LEVEL 750*7c478bd9Sstevel@tonic-gate * environment variable for severity extensions. 751*7c478bd9Sstevel@tonic-gate */ 752*7c478bd9Sstevel@tonic-gate 753*7c478bd9Sstevel@tonic-gate /* If the keyword is one of the standard ones, save severity */ 754*7c478bd9Sstevel@tonic-gate if (sev_info->keyword != (char *) NULL) severity = sev_info->value; 755*7c478bd9Sstevel@tonic-gate 756*7c478bd9Sstevel@tonic-gate else { 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gate /* 759*7c478bd9Sstevel@tonic-gate * Severity keyword may be one of the extended set, if any. 760*7c478bd9Sstevel@tonic-gate */ 761*7c478bd9Sstevel@tonic-gate 762*7c478bd9Sstevel@tonic-gate /* Get the value of the SEV_LEVEL environment variable */ 763*7c478bd9Sstevel@tonic-gate found = FALSE; 764*7c478bd9Sstevel@tonic-gate if ((sevstrval = getenv(SEV_LEVEL)) != (char *) NULL) { 765*7c478bd9Sstevel@tonic-gate sevval = (char *) malloc((unsigned int) strlen(sevstrval)+1); 766*7c478bd9Sstevel@tonic-gate penvsev = getauxsevs(strcpy(sevval, sevstrval)); 767*7c478bd9Sstevel@tonic-gate if (penvsev != (struct sevstr *) NULL) do { 768*7c478bd9Sstevel@tonic-gate if (strcmp(penvsev->sevkywd, sstr) == 0) { 769*7c478bd9Sstevel@tonic-gate severity = penvsev->sevvalue; 770*7c478bd9Sstevel@tonic-gate found = TRUE; 771*7c478bd9Sstevel@tonic-gate } 772*7c478bd9Sstevel@tonic-gate else { 773*7c478bd9Sstevel@tonic-gate free(penvsev); 774*7c478bd9Sstevel@tonic-gate penvsev = getauxsevs((char *) NULL); 775*7c478bd9Sstevel@tonic-gate } 776*7c478bd9Sstevel@tonic-gate } while (!found && (penvsev != (struct sevstr *) NULL)); 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate if (found) free(penvsev); 779*7c478bd9Sstevel@tonic-gate free(sevval); 780*7c478bd9Sstevel@tonic-gate } 781*7c478bd9Sstevel@tonic-gate 782*7c478bd9Sstevel@tonic-gate if (!found) { 783*7c478bd9Sstevel@tonic-gate (void) snprintf(msgbuf, sizeof (msgbuf), 784*7c478bd9Sstevel@tonic-gate "Invalid severity: %s", sstr); 785*7c478bd9Sstevel@tonic-gate (void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf, 786*7c478bd9Sstevel@tonic-gate MM_NULLACT, MM_NULLTAG); 787*7c478bd9Sstevel@tonic-gate exit(1); 788*7c478bd9Sstevel@tonic-gate } 789*7c478bd9Sstevel@tonic-gate 790*7c478bd9Sstevel@tonic-gate } /* <severity> is not one of the standard severities */ 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate } /* <severity> is not numeric */ 793*7c478bd9Sstevel@tonic-gate 794*7c478bd9Sstevel@tonic-gate } /* if (s_seen) */ 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate else severity = MM_NULLSEV; 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate 799*7c478bd9Sstevel@tonic-gate /* 800*7c478bd9Sstevel@tonic-gate * Other options 801*7c478bd9Sstevel@tonic-gate */ 802*7c478bd9Sstevel@tonic-gate 803*7c478bd9Sstevel@tonic-gate if (!a_seen) action = MM_NULLACT; 804*7c478bd9Sstevel@tonic-gate if (!l_seen) label = MM_NULLLBL; 805*7c478bd9Sstevel@tonic-gate if (!t_seen) tag = MM_NULLTAG; 806*7c478bd9Sstevel@tonic-gate if (!text_seen) text = MM_NULLTXT; 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate 809*7c478bd9Sstevel@tonic-gate /* 810*7c478bd9Sstevel@tonic-gate * Write the message 811*7c478bd9Sstevel@tonic-gate */ 812*7c478bd9Sstevel@tonic-gate 813*7c478bd9Sstevel@tonic-gate msgrtn = fmtmsg(class, label, severity, text, action ,tag); 814*7c478bd9Sstevel@tonic-gate 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate /* 817*7c478bd9Sstevel@tonic-gate * Return appropriate value to the shell (or wherever) 818*7c478bd9Sstevel@tonic-gate */ 819*7c478bd9Sstevel@tonic-gate 820*7c478bd9Sstevel@tonic-gate exitval = 0; 821*7c478bd9Sstevel@tonic-gate if (msgrtn == MM_NOTOK) exitval = 32; 822*7c478bd9Sstevel@tonic-gate else { 823*7c478bd9Sstevel@tonic-gate if (msgrtn & MM_NOMSG) exitval += 2; 824*7c478bd9Sstevel@tonic-gate if (msgrtn & MM_NOCON) exitval += 4; 825*7c478bd9Sstevel@tonic-gate } 826*7c478bd9Sstevel@tonic-gate 827*7c478bd9Sstevel@tonic-gate exit(exitval); 828*7c478bd9Sstevel@tonic-gate return(exitval); 829*7c478bd9Sstevel@tonic-gate } 830