17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate 237c478bd9Sstevel@tonic-gate /* 247c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 257c478bd9Sstevel@tonic-gate * Use is subject to license terms. 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 28*b390fe2cSmuffin /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 29*b390fe2cSmuffin /* All Rights Reserved */ 30*b390fe2cSmuffin 317c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate /* 357c478bd9Sstevel@tonic-gate * fmtmsg.c 367c478bd9Sstevel@tonic-gate * 377c478bd9Sstevel@tonic-gate * Contains: 387c478bd9Sstevel@tonic-gate * fmtmsg Command that writes a message in the standard 397c478bd9Sstevel@tonic-gate * message format. May in future make these 407c478bd9Sstevel@tonic-gate * messages available for logging. 417c478bd9Sstevel@tonic-gate */ 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate /* 457c478bd9Sstevel@tonic-gate * Header files used: 467c478bd9Sstevel@tonic-gate * <stdio.h> C Standard I/O function definitions 477c478bd9Sstevel@tonic-gate * <string.h> C string-handling definitions 487c478bd9Sstevel@tonic-gate * <errno.h> UNIX error-code "errno" definitions 497c478bd9Sstevel@tonic-gate * <fmtmsg.h> Standard Message definitions 507c478bd9Sstevel@tonic-gate */ 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #include <stdio.h> 537c478bd9Sstevel@tonic-gate #include <string.h> 547c478bd9Sstevel@tonic-gate #include <errno.h> 557c478bd9Sstevel@tonic-gate #include <fmtmsg.h> 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate /* 597c478bd9Sstevel@tonic-gate * Externals referenced: 607c478bd9Sstevel@tonic-gate * strtol Function that converts char strings to "long" 617c478bd9Sstevel@tonic-gate * fmtmsg Function that writes a message in standard format 627c478bd9Sstevel@tonic-gate * getenv Function that extracts an environment variable's 637c478bd9Sstevel@tonic-gate * value 647c478bd9Sstevel@tonic-gate * malloc Allocate memory from the memory pool 657c478bd9Sstevel@tonic-gate * free Frees allocated memory 667c478bd9Sstevel@tonic-gate * getopt Function that extracts arguments from the command- 677c478bd9Sstevel@tonic-gate * optarg Points to option's argument (from getopt()) 687c478bd9Sstevel@tonic-gate * optind Option's argument index (from getopt()) 697c478bd9Sstevel@tonic-gate * opterr FLAG, write error if invalid option (for getopt()) 707c478bd9Sstevel@tonic-gate * line. 717c478bd9Sstevel@tonic-gate * exit Exits the command 727c478bd9Sstevel@tonic-gate */ 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate extern long strtol(); 757c478bd9Sstevel@tonic-gate extern int fmtmsg(); 767c478bd9Sstevel@tonic-gate extern char *getenv(); 777c478bd9Sstevel@tonic-gate extern void *malloc(); 787c478bd9Sstevel@tonic-gate extern void free(); 797c478bd9Sstevel@tonic-gate extern int getopt(); 807c478bd9Sstevel@tonic-gate extern char *optarg; 817c478bd9Sstevel@tonic-gate extern int optind; 827c478bd9Sstevel@tonic-gate extern int opterr; 837c478bd9Sstevel@tonic-gate extern void exit(); 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate /* 867c478bd9Sstevel@tonic-gate * Local definitions 877c478bd9Sstevel@tonic-gate */ 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate /* 907c478bd9Sstevel@tonic-gate * Local constants 917c478bd9Sstevel@tonic-gate */ 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate /* 957c478bd9Sstevel@tonic-gate * Boolean constants 967c478bd9Sstevel@tonic-gate * TRUE Boolean value for "true" (any bits on) 977c478bd9Sstevel@tonic-gate * FALSE Boolean value for "false" (all bits off) 987c478bd9Sstevel@tonic-gate */ 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate #ifndef FALSE 1017c478bd9Sstevel@tonic-gate #define FALSE (0) 1027c478bd9Sstevel@tonic-gate #endif 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate #ifndef TRUE 1057c478bd9Sstevel@tonic-gate #define TRUE (1) 1067c478bd9Sstevel@tonic-gate #endif 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate #define CLASS (MM_PRINT|MM_SOFT|MM_NRECOV|MM_UTIL) 1107c478bd9Sstevel@tonic-gate #define BIGUSAGE "fmtmsg [-a action] [-c class] [-l label] [-s severity] [-t tag]\n [-u subclass[,subclass[,...]]] [text]\n" 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate /* 1147c478bd9Sstevel@tonic-gate * Local data-type definitions 1157c478bd9Sstevel@tonic-gate */ 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate /* 1187c478bd9Sstevel@tonic-gate * Structure used for tables containing keywords and integer values 1197c478bd9Sstevel@tonic-gate */ 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate struct sev_info { 1227c478bd9Sstevel@tonic-gate char *keyword; 1237c478bd9Sstevel@tonic-gate int value; 1247c478bd9Sstevel@tonic-gate }; 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate /* 1287c478bd9Sstevel@tonic-gate * Structure used for tables containing keywords, long values 1297c478bd9Sstevel@tonic-gate */ 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate struct class_info { 1327c478bd9Sstevel@tonic-gate char *keyword; 1337c478bd9Sstevel@tonic-gate long value; 1347c478bd9Sstevel@tonic-gate long conflict; 1357c478bd9Sstevel@tonic-gate }; 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate /* 1397c478bd9Sstevel@tonic-gate * Severity string structure 1407c478bd9Sstevel@tonic-gate * 1417c478bd9Sstevel@tonic-gate * struct sevstr 1427c478bd9Sstevel@tonic-gate * sevvalue Value of the severity-level being defined 1437c478bd9Sstevel@tonic-gate * sevkywd Keyword identifying the severity 1447c478bd9Sstevel@tonic-gate * sevprptr Pointer to the string associated with the value 1457c478bd9Sstevel@tonic-gate * sevnext Pointer to the next value in the list. 1467c478bd9Sstevel@tonic-gate */ 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate struct sevstr { 1497c478bd9Sstevel@tonic-gate int sevvalue; 1507c478bd9Sstevel@tonic-gate char *sevkywd; 1517c478bd9Sstevel@tonic-gate char *sevprstr; 1527c478bd9Sstevel@tonic-gate struct sevstr *sevnext; 1537c478bd9Sstevel@tonic-gate }; 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate /* 1577c478bd9Sstevel@tonic-gate * Local static data 1587c478bd9Sstevel@tonic-gate */ 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate /* 1627c478bd9Sstevel@tonic-gate * Table contains the keywords for the classes of a message 1637c478bd9Sstevel@tonic-gate */ 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate static struct class_info classes[] = { 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate {"hard", MM_HARD, MM_SOFT|MM_FIRM}, /* hardware */ 1687c478bd9Sstevel@tonic-gate {"soft", MM_SOFT, MM_HARD|MM_FIRM}, /* software */ 1697c478bd9Sstevel@tonic-gate {"firm", MM_FIRM, MM_SOFT|MM_FIRM}, /* firmware */ 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate {(char *) NULL, 0L, 0L} /* end of list */ 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate }; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate /* 1777c478bd9Sstevel@tonic-gate * Table contains the keywords for the subclasses for a message 1787c478bd9Sstevel@tonic-gate */ 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate static struct class_info subclasses[] = { 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate {"appl", MM_APPL, MM_UTIL|MM_OPSYS}, /* Application */ 1837c478bd9Sstevel@tonic-gate {"util", MM_UTIL, MM_APPL|MM_OPSYS}, /* Utility */ 1847c478bd9Sstevel@tonic-gate {"opsys", MM_OPSYS, MM_APPL|MM_UTIL}, /* Operating System */ 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate {"recov", MM_RECOVER, MM_NRECOV}, /* Recoverable */ 1877c478bd9Sstevel@tonic-gate {"nrecov", MM_NRECOV, MM_RECOVER}, /* Non-recoverable */ 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate {"print", MM_PRINT, 0L}, /* Write message to stderr */ 1907c478bd9Sstevel@tonic-gate {"console", MM_CONSOLE, 0L}, /* Write message on /dev/console */ 1917c478bd9Sstevel@tonic-gate {(char *) NULL, 0L, 0L} /* End of list */ 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate }; 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate /* 1977c478bd9Sstevel@tonic-gate * Table contains the keywords for the standard severities of a message. 1987c478bd9Sstevel@tonic-gate * User may supply more through the SEV_LEVEL environment variable. 1997c478bd9Sstevel@tonic-gate */ 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate static struct sev_info severities[] = { 2027c478bd9Sstevel@tonic-gate {"halt", MM_HALT}, /* halt */ 2037c478bd9Sstevel@tonic-gate {"error", MM_ERROR}, /* error */ 2047c478bd9Sstevel@tonic-gate {"warn", MM_WARNING}, /* warn */ 2057c478bd9Sstevel@tonic-gate {"info", MM_INFO}, /* info */ 2067c478bd9Sstevel@tonic-gate {(char *) NULL, 0} /* end of list */ 2077c478bd9Sstevel@tonic-gate }; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate /* 2117c478bd9Sstevel@tonic-gate * Buffers used by the command 2127c478bd9Sstevel@tonic-gate */ 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate static char labelbuf[128]; /* Buf for message label */ 2157c478bd9Sstevel@tonic-gate static char msgbuf[256]; /* Buf for messages */ 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate /* 2187c478bd9Sstevel@tonic-gate * static char *exttok(str, delims) 2197c478bd9Sstevel@tonic-gate * char *str 2207c478bd9Sstevel@tonic-gate * char *delims 2217c478bd9Sstevel@tonic-gate * 2227c478bd9Sstevel@tonic-gate * This function examines the string pointed to by "str", looking 2237c478bd9Sstevel@tonic-gate * for the first occurrence of any of the characters in the string 2247c478bd9Sstevel@tonic-gate * whose address is "delims". It returns the address of that 2257c478bd9Sstevel@tonic-gate * character or (char *) NULL if there was nothing to search. 2267c478bd9Sstevel@tonic-gate * 2277c478bd9Sstevel@tonic-gate * Arguments: 2287c478bd9Sstevel@tonic-gate * str Address of the string to search 2297c478bd9Sstevel@tonic-gate * delims Address of the string containing delimiters 2307c478bd9Sstevel@tonic-gate * 2317c478bd9Sstevel@tonic-gate * Returns: char * 2327c478bd9Sstevel@tonic-gate * Returns the address of the first occurrence of any of the characters 2337c478bd9Sstevel@tonic-gate * in "delim" in the string "str" (incl '\0'). If there was nothing 2347c478bd9Sstevel@tonic-gate * to search, the function returns (char *) NULL. 2357c478bd9Sstevel@tonic-gate * 2367c478bd9Sstevel@tonic-gate * Notes: 2377c478bd9Sstevel@tonic-gate * - This function is needed because strtok() can't be used inside a 2387c478bd9Sstevel@tonic-gate * function. Besides, strtok() is destructive in the string, which 2397c478bd9Sstevel@tonic-gate * is undesirable in many circumstances. 2407c478bd9Sstevel@tonic-gate * - This function understands escaped delimiters as non-delimiters. 2417c478bd9Sstevel@tonic-gate * Delimiters are escaped by preceding them with '\' characters. 2427c478bd9Sstevel@tonic-gate * The '\' character also must be escaped. 2437c478bd9Sstevel@tonic-gate */ 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate static char * 2467c478bd9Sstevel@tonic-gate exttok(tok, delims) 2477c478bd9Sstevel@tonic-gate char *tok; /* Ptr to the token we're parsing */ 2487c478bd9Sstevel@tonic-gate char *delims; /* Ptr to string with delimiters */ 2497c478bd9Sstevel@tonic-gate { 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate /* Automatic Data */ 2527c478bd9Sstevel@tonic-gate char *tokend; /* Ptr to the end of the token */ 2537c478bd9Sstevel@tonic-gate char *p, *q; /* Temp pointers */ 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate /* Algorithm: 2577c478bd9Sstevel@tonic-gate * 1. Get the starting address (new string or where we 2587c478bd9Sstevel@tonic-gate * left off). If nothing to search, return (char *) NULL 2597c478bd9Sstevel@tonic-gate * 2. Find the end of the string 2607c478bd9Sstevel@tonic-gate * 3. Look for the first unescaped delimiter closest to the 2617c478bd9Sstevel@tonic-gate * beginning of the string 2627c478bd9Sstevel@tonic-gate * 4. Remember where we left off 2637c478bd9Sstevel@tonic-gate * 5. Return a pointer to the delimiter we found 2647c478bd9Sstevel@tonic-gate */ 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate /* Begin at the beginning, if any */ 2677c478bd9Sstevel@tonic-gate if (tok == (char *) NULL) { 2687c478bd9Sstevel@tonic-gate return ((char *) NULL); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate /* Find end of the token string */ 2727c478bd9Sstevel@tonic-gate tokend = tok + strlen(tok); 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate /* Look for the 1st occurrence of any delimiter */ 2757c478bd9Sstevel@tonic-gate for (p = delims ; *p != '\0' ; p++) { 2767c478bd9Sstevel@tonic-gate for (q = strchr(tok, *p) ; q && (q != tok) && (*(q-1) == '\\') ; q = strchr(q+1, *p)) ; 2777c478bd9Sstevel@tonic-gate if (q && (q < tokend)) tokend = q; 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate /* Done */ 2817c478bd9Sstevel@tonic-gate return(tokend); 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate /* 2857c478bd9Sstevel@tonic-gate * char *noesc(str) 2867c478bd9Sstevel@tonic-gate * 2877c478bd9Sstevel@tonic-gate * This function squeezes out all of the escaped character sequences 2887c478bd9Sstevel@tonic-gate * from the string <str>. It returns a pointer to that string. 2897c478bd9Sstevel@tonic-gate * 2907c478bd9Sstevel@tonic-gate * Arguments: 2917c478bd9Sstevel@tonic-gate * str char * 2927c478bd9Sstevel@tonic-gate * The string that is to have its escaped characters removed. 2937c478bd9Sstevel@tonic-gate * 2947c478bd9Sstevel@tonic-gate * Returns: char * 2957c478bd9Sstevel@tonic-gate * This function returns its argument <str> always. 2967c478bd9Sstevel@tonic-gate * 2977c478bd9Sstevel@tonic-gate * Notes: 2987c478bd9Sstevel@tonic-gate * This function potentially modifies the string it is given. 2997c478bd9Sstevel@tonic-gate */ 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate char * 3027c478bd9Sstevel@tonic-gate noesc(str) 3037c478bd9Sstevel@tonic-gate char *str; /* String to remove escaped characters from */ 3047c478bd9Sstevel@tonic-gate { 3057c478bd9Sstevel@tonic-gate char *p; /* Temp string pointer */ 3067c478bd9Sstevel@tonic-gate char *q; /* Temp string pointer */ 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate /* Look for an escaped character */ 3097c478bd9Sstevel@tonic-gate p = str; 3107c478bd9Sstevel@tonic-gate while (*p && (*p != '\\')) p++; 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate /* 3147c478bd9Sstevel@tonic-gate * If there was at least one, squeeze them out 3157c478bd9Sstevel@tonic-gate * Otherwise, don't touch the argument string 3167c478bd9Sstevel@tonic-gate */ 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate if (*p) { 3197c478bd9Sstevel@tonic-gate q = p++; 3207c478bd9Sstevel@tonic-gate while (*q++ = *p++) if (*p == '\\') p++; 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate /* Finished. Return our argument */ 3247c478bd9Sstevel@tonic-gate return(str); 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate /* 3287c478bd9Sstevel@tonic-gate * struct sevstr *getauxsevs(ptr) 3297c478bd9Sstevel@tonic-gate * 3307c478bd9Sstevel@tonic-gate * Parses a string that is in the format of the severity definitions. 3317c478bd9Sstevel@tonic-gate * Returns a pointer to a (malloc'd) structure that contains the 3327c478bd9Sstevel@tonic-gate * definition, or (struct sevstr *) NULL if none was parsed. 3337c478bd9Sstevel@tonic-gate * 3347c478bd9Sstevel@tonic-gate * Arguments: 3357c478bd9Sstevel@tonic-gate * ptr char * 3367c478bd9Sstevel@tonic-gate * References the string from which data is to be extracted. 3377c478bd9Sstevel@tonic-gate * If (char *) NULL, continue where we left off. Otherwise, 3387c478bd9Sstevel@tonic-gate * start with the string referenced by ptr. 3397c478bd9Sstevel@tonic-gate * 3407c478bd9Sstevel@tonic-gate * Returns: struct sevstr * 3417c478bd9Sstevel@tonic-gate * A pointer to a malloc'd structure containing the severity definition 3427c478bd9Sstevel@tonic-gate * parsed from string, or (struct sevstr *) NULL if none. 3437c478bd9Sstevel@tonic-gate * 3447c478bd9Sstevel@tonic-gate * Notes: 3457c478bd9Sstevel@tonic-gate * - This function is destructive to the string referenced by its argument. 3467c478bd9Sstevel@tonic-gate */ 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate /* Static data */ 3507c478bd9Sstevel@tonic-gate static char *leftoff = (char *) NULL; 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate static struct sevstr * 3537c478bd9Sstevel@tonic-gate getauxsevs(ptr) 3547c478bd9Sstevel@tonic-gate char *ptr; 3557c478bd9Sstevel@tonic-gate { 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate /* Automatic data */ 3587c478bd9Sstevel@tonic-gate char *current; /* Ptr to current sev def'n */ 3597c478bd9Sstevel@tonic-gate char *tokend; /* Ptr to end of current sev def'n */ 3607c478bd9Sstevel@tonic-gate char *kywd; /* Ptr to extracted kywd */ 3617c478bd9Sstevel@tonic-gate char *valstr; /* Ptr to extracted sev value */ 3627c478bd9Sstevel@tonic-gate char *prstr; /* Ptr to extracted print str */ 3637c478bd9Sstevel@tonic-gate char *p; /* Temp pointer */ 3647c478bd9Sstevel@tonic-gate int val; /* Converted severity value */ 3657c478bd9Sstevel@tonic-gate int done; /* Flag, sev def'n found and ok? */ 3667c478bd9Sstevel@tonic-gate struct sevstr *rtnval; /* Value to return */ 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate /* Start anew or start where we left off? */ 3707c478bd9Sstevel@tonic-gate current = (ptr == (char *) NULL) ? leftoff : ptr; 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate /* If nothing to parse, return (char *) NULL */ 3747c478bd9Sstevel@tonic-gate if (current == (char *) NULL) { 3757c478bd9Sstevel@tonic-gate return ((struct sevstr *) NULL); 3767c478bd9Sstevel@tonic-gate } 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate /* 3807c478bd9Sstevel@tonic-gate * Look through the string "current" for a token of the form 3817c478bd9Sstevel@tonic-gate * <kywd>,<sev>,<printstring> delimited by ':' or '\0' 3827c478bd9Sstevel@tonic-gate */ 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate /* Loop initializations */ 3857c478bd9Sstevel@tonic-gate done = FALSE; 3867c478bd9Sstevel@tonic-gate rtnval = (struct sevstr *) NULL; 3877c478bd9Sstevel@tonic-gate while (!done) { 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate /* Eat leading junk */ 3907c478bd9Sstevel@tonic-gate while (*(tokend = exttok(current, ":,")) == ':') { 3917c478bd9Sstevel@tonic-gate current = tokend + 1; 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate /* If we've found a <kywd>,... */ 3957c478bd9Sstevel@tonic-gate if (*tokend == ',') { 3967c478bd9Sstevel@tonic-gate kywd = current; 3977c478bd9Sstevel@tonic-gate *tokend = '\0'; 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate /* Look for <kywd>,<sev>,... */ 4007c478bd9Sstevel@tonic-gate current = tokend + 1; 4017c478bd9Sstevel@tonic-gate if (*(tokend = exttok(current, ":,")) == ',') { 4027c478bd9Sstevel@tonic-gate valstr = current; 4037c478bd9Sstevel@tonic-gate *tokend = '\0'; 4047c478bd9Sstevel@tonic-gate current = tokend+1; 4057c478bd9Sstevel@tonic-gate prstr = current; 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate /* Make sure <sev> > 4 */ 4087c478bd9Sstevel@tonic-gate val = (int) strtol(noesc(valstr), &p, 0); 4097c478bd9Sstevel@tonic-gate if ((val > 4) && (p == tokend)) { 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate /* 4127c478bd9Sstevel@tonic-gate * Found <kywd>,<sev>,<printstring>. 4137c478bd9Sstevel@tonic-gate * remember where we left off 4147c478bd9Sstevel@tonic-gate */ 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate if (*(tokend = exttok(current, ":")) == ':') { 4177c478bd9Sstevel@tonic-gate *tokend = '\0'; 4187c478bd9Sstevel@tonic-gate leftoff = tokend + 1; 4197c478bd9Sstevel@tonic-gate } else leftoff = (char *) NULL; 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate /* Alloc structure to contain severity definition */ 4227c478bd9Sstevel@tonic-gate if (rtnval = (struct sevstr *) malloc(sizeof(struct sevstr))) { 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate /* Fill in structure */ 4257c478bd9Sstevel@tonic-gate rtnval->sevkywd = noesc(kywd); 4267c478bd9Sstevel@tonic-gate rtnval->sevvalue = val; 4277c478bd9Sstevel@tonic-gate rtnval->sevprstr = noesc(prstr); 4287c478bd9Sstevel@tonic-gate rtnval->sevnext = (struct sevstr *) NULL; 4297c478bd9Sstevel@tonic-gate } 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate done = TRUE; 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate } else { 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate /* Invalid severity value, eat thru end of token */ 4367c478bd9Sstevel@tonic-gate current = tokend; 4377c478bd9Sstevel@tonic-gate if (*(tokend = exttok(prstr, ":")) == ':') 4387c478bd9Sstevel@tonic-gate current++; 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate } else { 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate /* Invalid severity definition, eat thru end of token */ 4447c478bd9Sstevel@tonic-gate current = tokend; 4457c478bd9Sstevel@tonic-gate if (*tokend == ':') 4467c478bd9Sstevel@tonic-gate current++; 4477c478bd9Sstevel@tonic-gate } 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate } else { 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate /* End of string found */ 4527c478bd9Sstevel@tonic-gate done = TRUE; 4537c478bd9Sstevel@tonic-gate leftoff = (char *) NULL; 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate } /* while (!done) */ 4577c478bd9Sstevel@tonic-gate 4587c478bd9Sstevel@tonic-gate /* Finished */ 4597c478bd9Sstevel@tonic-gate return(rtnval); 4607c478bd9Sstevel@tonic-gate } 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate /* 4637c478bd9Sstevel@tonic-gate * fmtmsg [-a action] [-c classification] [-l label] [-s severity] [-t tag] 4647c478bd9Sstevel@tonic-gate * [-u subclass[,subclass[,...]]] [text] 4657c478bd9Sstevel@tonic-gate * 4667c478bd9Sstevel@tonic-gate * Function: 4677c478bd9Sstevel@tonic-gate * Writes a message in the standard format. Typically used by shell 4687c478bd9Sstevel@tonic-gate * scripts to write error messages to the user. 4697c478bd9Sstevel@tonic-gate * 4707c478bd9Sstevel@tonic-gate * Arguments: 4717c478bd9Sstevel@tonic-gate * text String that is the text of the message 4727c478bd9Sstevel@tonic-gate * 4737c478bd9Sstevel@tonic-gate * Options: 4747c478bd9Sstevel@tonic-gate * -a action String that describes user action to take to 4757c478bd9Sstevel@tonic-gate * correct the situation 4767c478bd9Sstevel@tonic-gate * -c classification Keyword that identifies the type of the message 4777c478bd9Sstevel@tonic-gate * -l label String that identifies the source of the message 4787c478bd9Sstevel@tonic-gate * -s severity Keyword that identifies the severity of the message 4797c478bd9Sstevel@tonic-gate * -t tag String that identifies the message (use unclear) 4807c478bd9Sstevel@tonic-gate * -u sub_classes Comma-list of keywords that refines the type of 4817c478bd9Sstevel@tonic-gate * the message 4827c478bd9Sstevel@tonic-gate * 4837c478bd9Sstevel@tonic-gate * Environment Variables Used: 4847c478bd9Sstevel@tonic-gate * MSGVERB Defines the pieces of a message the user expects 4857c478bd9Sstevel@tonic-gate * to see. It is a list of keywords separated by 4867c478bd9Sstevel@tonic-gate * colons (':'). 4877c478bd9Sstevel@tonic-gate * SEV_LEVEL Defines a list of auxiliary severity keywords, values, 4887c478bd9Sstevel@tonic-gate * and print-strings. It is a list of fields separated 4897c478bd9Sstevel@tonic-gate * by colons (':'). Each field consists of three 4907c478bd9Sstevel@tonic-gate * elements, keyword, value (in octal, hex, or decimal), 4917c478bd9Sstevel@tonic-gate * and print-string, separated by commas (','). 4927c478bd9Sstevel@tonic-gate * 4937c478bd9Sstevel@tonic-gate * Needs: 4947c478bd9Sstevel@tonic-gate * 4957c478bd9Sstevel@tonic-gate * Open Issues: 4967c478bd9Sstevel@tonic-gate */ 4977c478bd9Sstevel@tonic-gate 498*b390fe2cSmuffin int 499*b390fe2cSmuffin main(int argc, char **argv) 5007c478bd9Sstevel@tonic-gate { 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate /* Local automatic data */ 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate long class; /* Classification (built) */ 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate int severity; /* User specified severity */ 5077c478bd9Sstevel@tonic-gate int msgrtn; /* Value returned by fmtmsg() */ 5087c478bd9Sstevel@tonic-gate int optchar; /* Opt char on cmdline */ 5097c478bd9Sstevel@tonic-gate int exitval; /* Value to return */ 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate int found; /* FLAG, kywd found yet? */ 5127c478bd9Sstevel@tonic-gate int errflg; /* FLAG, error seen in cmd */ 5137c478bd9Sstevel@tonic-gate int a_seen; /* FLAG, -a option seen */ 5147c478bd9Sstevel@tonic-gate int c_seen; /* FLAG, -c option seen */ 5157c478bd9Sstevel@tonic-gate int l_seen; /* FLAG, -l option seen */ 5167c478bd9Sstevel@tonic-gate int s_seen; /* FLAG, -s option seen */ 5177c478bd9Sstevel@tonic-gate int t_seen; /* FLAG, -t option seen */ 5187c478bd9Sstevel@tonic-gate int u_seen; /* FLAG, -u option seen */ 5197c478bd9Sstevel@tonic-gate int text_seen; /* FLAG, text seen */ 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate char *text; /* Ptr to user's text */ 5227c478bd9Sstevel@tonic-gate char *label; /* Ptr to user's label */ 5237c478bd9Sstevel@tonic-gate char *tag; /* Ptr to user's tag */ 5247c478bd9Sstevel@tonic-gate char *action; /* Ptr to user's action str */ 5257c478bd9Sstevel@tonic-gate char *sstr; /* Ptr to -s (severity) arg */ 5267c478bd9Sstevel@tonic-gate char *ustr; /* Ptr to -u (subclass) arg */ 5277c478bd9Sstevel@tonic-gate char *cstr; /* Ptr to -c (class) arg */ 5287c478bd9Sstevel@tonic-gate char *sevstrval; /* Ptr to SEV_LEVEL argument */ 5297c478bd9Sstevel@tonic-gate char *sevval; /* Ptr to temp SEV_LEVEL arg */ 5307c478bd9Sstevel@tonic-gate char *tokenptr; /* Ptr to current token */ 5317c478bd9Sstevel@tonic-gate char *cmdname; /* Ptr to base command name */ 5327c478bd9Sstevel@tonic-gate char *p; /* Multipurpose ptr */ 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate struct class_info *class_info; /* Ptr to class/subclass info structure */ 5357c478bd9Sstevel@tonic-gate struct sev_info *sev_info; /* Ptr to severity info struct */ 5367c478bd9Sstevel@tonic-gate struct sevstr *penvsev; /* Ptr to SEV_LEVEL values */ 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate /* 5417c478bd9Sstevel@tonic-gate * fmtmsg 5427c478bd9Sstevel@tonic-gate */ 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate /* Initializations */ 5467c478bd9Sstevel@tonic-gate 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate /* Extract the base command name from the command */ 5497c478bd9Sstevel@tonic-gate if ((p = strrchr(argv[0], '/')) == (char *) NULL) 5507c478bd9Sstevel@tonic-gate cmdname = argv[0]; 5517c478bd9Sstevel@tonic-gate else 5527c478bd9Sstevel@tonic-gate cmdname = p+1; 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate /* Build the label for messages from "fmtmsg" */ 5557c478bd9Sstevel@tonic-gate (void) snprintf(labelbuf, sizeof (labelbuf), "UX:%s", cmdname); 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate /* 5597c478bd9Sstevel@tonic-gate * Extract arguments from the command line 5607c478bd9Sstevel@tonic-gate */ 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate /* Initializations */ 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate opterr = 0; /* Disable messages from getopt() */ 5657c478bd9Sstevel@tonic-gate errflg = FALSE; /* No errors seen yet */ 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate a_seen = FALSE; /* No action (-a) text seen yet */ 5687c478bd9Sstevel@tonic-gate c_seen = FALSE; /* No classification (-c) seen yet */ 5697c478bd9Sstevel@tonic-gate l_seen = FALSE; /* No label (-l) seen yet */ 5707c478bd9Sstevel@tonic-gate s_seen = FALSE; /* No severity (-s) seen yet */ 5717c478bd9Sstevel@tonic-gate t_seen = FALSE; /* No tag (-t) seen yet */ 5727c478bd9Sstevel@tonic-gate u_seen = FALSE; /* No subclass (-u) seen yet */ 5737c478bd9Sstevel@tonic-gate text_seen = FALSE; /* No text seen yet */ 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate /* 5777c478bd9Sstevel@tonic-gate * If only the command name was used, write out a usage string to 5787c478bd9Sstevel@tonic-gate * the standard output file. 5797c478bd9Sstevel@tonic-gate */ 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate if (argc == 1) { 5827c478bd9Sstevel@tonic-gate (void) fputs(BIGUSAGE, stderr); 5837c478bd9Sstevel@tonic-gate exit(0); 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate /* Parce command line */ 5887c478bd9Sstevel@tonic-gate while (((optchar = getopt(argc, argv, "a:c:l:s:t:u:")) != EOF) && 5897c478bd9Sstevel@tonic-gate !errflg) { 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate switch(optchar) { 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate case 'a': /* -a actiontext */ 5947c478bd9Sstevel@tonic-gate if (!a_seen) { 5957c478bd9Sstevel@tonic-gate action = optarg; 5967c478bd9Sstevel@tonic-gate a_seen = TRUE; 5977c478bd9Sstevel@tonic-gate } else errflg = TRUE; 5987c478bd9Sstevel@tonic-gate break; 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate case 'c': /* -c classification */ 6017c478bd9Sstevel@tonic-gate if (!c_seen) { 6027c478bd9Sstevel@tonic-gate cstr = optarg; 6037c478bd9Sstevel@tonic-gate c_seen = TRUE; 6047c478bd9Sstevel@tonic-gate } else errflg = TRUE; 6057c478bd9Sstevel@tonic-gate break; 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate case 'l': /* -l label */ 6087c478bd9Sstevel@tonic-gate if (!l_seen) { 6097c478bd9Sstevel@tonic-gate label = optarg; 6107c478bd9Sstevel@tonic-gate l_seen = TRUE; 6117c478bd9Sstevel@tonic-gate } else errflg = TRUE; 6127c478bd9Sstevel@tonic-gate break; 6137c478bd9Sstevel@tonic-gate 6147c478bd9Sstevel@tonic-gate case 's': /* -s severity */ 6157c478bd9Sstevel@tonic-gate if (!s_seen) { 6167c478bd9Sstevel@tonic-gate sstr = optarg; 6177c478bd9Sstevel@tonic-gate s_seen = TRUE; 6187c478bd9Sstevel@tonic-gate } else errflg = TRUE; 6197c478bd9Sstevel@tonic-gate break; 6207c478bd9Sstevel@tonic-gate 6217c478bd9Sstevel@tonic-gate case 't': /* -t tag */ 6227c478bd9Sstevel@tonic-gate if (!t_seen) { 6237c478bd9Sstevel@tonic-gate tag = optarg; 6247c478bd9Sstevel@tonic-gate t_seen = TRUE; 6257c478bd9Sstevel@tonic-gate } else errflg = TRUE; 6267c478bd9Sstevel@tonic-gate break; 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate case 'u': /* -u subclasslist */ 6297c478bd9Sstevel@tonic-gate if (!u_seen) { 6307c478bd9Sstevel@tonic-gate ustr = optarg; 6317c478bd9Sstevel@tonic-gate u_seen = TRUE; 6327c478bd9Sstevel@tonic-gate } else errflg = TRUE; 6337c478bd9Sstevel@tonic-gate break; 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gate case '?': /* -? or unknown option */ 6367c478bd9Sstevel@tonic-gate default: 6377c478bd9Sstevel@tonic-gate errflg = TRUE; 6387c478bd9Sstevel@tonic-gate break; 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate } /* esac */ 6417c478bd9Sstevel@tonic-gate } 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate 6447c478bd9Sstevel@tonic-gate /* Get the text */ 6457c478bd9Sstevel@tonic-gate if (!errflg) { 6467c478bd9Sstevel@tonic-gate if (argc == (optind+1)) { 6477c478bd9Sstevel@tonic-gate text = argv[optind]; 6487c478bd9Sstevel@tonic-gate text_seen = TRUE; 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate else if (argc != optind) { 6517c478bd9Sstevel@tonic-gate errflg = TRUE; 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate } 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate /* Report syntax errors */ 6577c478bd9Sstevel@tonic-gate if (errflg) { 6587c478bd9Sstevel@tonic-gate (void) fputs(BIGUSAGE, stderr); 6597c478bd9Sstevel@tonic-gate exit(1); 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate 6637c478bd9Sstevel@tonic-gate /* 6647c478bd9Sstevel@tonic-gate * Classification. 6657c478bd9Sstevel@tonic-gate */ 6667c478bd9Sstevel@tonic-gate 6677c478bd9Sstevel@tonic-gate class = 0L; 6687c478bd9Sstevel@tonic-gate if (c_seen) { 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate /* Search for keyword in list */ 6717c478bd9Sstevel@tonic-gate for (class_info = &classes[0] ; 6727c478bd9Sstevel@tonic-gate (class_info->keyword != (char *) NULL) && 6737c478bd9Sstevel@tonic-gate (strcmp(cstr, class_info->keyword)) ; 6747c478bd9Sstevel@tonic-gate class_info++) ; 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate /* If invalid (keyword unknown), write a message and exit */ 6777c478bd9Sstevel@tonic-gate if (class_info->keyword == (char *) NULL) { 6787c478bd9Sstevel@tonic-gate (void) snprintf(msgbuf, sizeof (msgbuf), 6797c478bd9Sstevel@tonic-gate "Invalid class: %s", cstr); 6807c478bd9Sstevel@tonic-gate (void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf, 6817c478bd9Sstevel@tonic-gate MM_NULLACT, MM_NULLTAG); 6827c478bd9Sstevel@tonic-gate exit(1); 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate /* Save classification */ 6867c478bd9Sstevel@tonic-gate class = class_info->value; 6877c478bd9Sstevel@tonic-gate 6887c478bd9Sstevel@tonic-gate } 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate 6917c478bd9Sstevel@tonic-gate /* 6927c478bd9Sstevel@tonic-gate * Subclassification. 6937c478bd9Sstevel@tonic-gate */ 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate if (u_seen) { 6967c478bd9Sstevel@tonic-gate 6977c478bd9Sstevel@tonic-gate errflg = FALSE; 6987c478bd9Sstevel@tonic-gate p = strcpy(malloc((unsigned int) strlen(ustr)+1), ustr); 6997c478bd9Sstevel@tonic-gate if ((tokenptr = strtok(p, ",")) == (char *) NULL) errflg = TRUE; 7007c478bd9Sstevel@tonic-gate else do { 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate /* Got a keyword. Look for it in keyword list */ 7037c478bd9Sstevel@tonic-gate for (class_info = subclasses ; 7047c478bd9Sstevel@tonic-gate (class_info->keyword != (char *) NULL) && 7057c478bd9Sstevel@tonic-gate (strcmp(tokenptr, class_info->keyword) != 0) ; 7067c478bd9Sstevel@tonic-gate class_info++) ; 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate /* If found in list and no conflict, remember in class */ 7097c478bd9Sstevel@tonic-gate if ((class_info->keyword != (char *) NULL) && ((class & class_info->conflict) == 0L)) 7107c478bd9Sstevel@tonic-gate class |= class_info->value; 7117c478bd9Sstevel@tonic-gate else 7127c478bd9Sstevel@tonic-gate errflg = TRUE; 7137c478bd9Sstevel@tonic-gate 7147c478bd9Sstevel@tonic-gate } while (!errflg && ((tokenptr = strtok((char *) NULL, ",")) != (char *) NULL)) ; 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate if (errflg) { 7177c478bd9Sstevel@tonic-gate (void) snprintf(msgbuf, sizeof (msgbuf), 7187c478bd9Sstevel@tonic-gate "Invalid subclass: %s", ustr); 7197c478bd9Sstevel@tonic-gate (void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf, 7207c478bd9Sstevel@tonic-gate MM_NULLACT, MM_NULLTAG); 7217c478bd9Sstevel@tonic-gate exit(1); 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate if (!c_seen & !u_seen) class = MM_NULLMC; 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate /* 7317c478bd9Sstevel@tonic-gate * Severity. 7327c478bd9Sstevel@tonic-gate */ 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate if (s_seen) { 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate /* If the severity is specified as a number, use that value */ 7377c478bd9Sstevel@tonic-gate severity = strtol(sstr, &p, 10); 7387c478bd9Sstevel@tonic-gate if (*p || (strlen(sstr) == 0)) { 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate /* Look for the standard severities */ 7417c478bd9Sstevel@tonic-gate for (sev_info = severities ; 7427c478bd9Sstevel@tonic-gate (sev_info->keyword != (char *) NULL) && 7437c478bd9Sstevel@tonic-gate (strcmp(sstr, sev_info->keyword)) ; 7447c478bd9Sstevel@tonic-gate sev_info++) ; 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate /* 7477c478bd9Sstevel@tonic-gate * If the "severity" argument is one of the standard keywords, 7487c478bd9Sstevel@tonic-gate * remember it for fmtmsg(). Otherwise, look at the SEV_LEVEL 7497c478bd9Sstevel@tonic-gate * environment variable for severity extensions. 7507c478bd9Sstevel@tonic-gate */ 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate /* If the keyword is one of the standard ones, save severity */ 7537c478bd9Sstevel@tonic-gate if (sev_info->keyword != (char *) NULL) severity = sev_info->value; 7547c478bd9Sstevel@tonic-gate 7557c478bd9Sstevel@tonic-gate else { 7567c478bd9Sstevel@tonic-gate 7577c478bd9Sstevel@tonic-gate /* 7587c478bd9Sstevel@tonic-gate * Severity keyword may be one of the extended set, if any. 7597c478bd9Sstevel@tonic-gate */ 7607c478bd9Sstevel@tonic-gate 7617c478bd9Sstevel@tonic-gate /* Get the value of the SEV_LEVEL environment variable */ 7627c478bd9Sstevel@tonic-gate found = FALSE; 7637c478bd9Sstevel@tonic-gate if ((sevstrval = getenv(SEV_LEVEL)) != (char *) NULL) { 7647c478bd9Sstevel@tonic-gate sevval = (char *) malloc((unsigned int) strlen(sevstrval)+1); 7657c478bd9Sstevel@tonic-gate penvsev = getauxsevs(strcpy(sevval, sevstrval)); 7667c478bd9Sstevel@tonic-gate if (penvsev != (struct sevstr *) NULL) do { 7677c478bd9Sstevel@tonic-gate if (strcmp(penvsev->sevkywd, sstr) == 0) { 7687c478bd9Sstevel@tonic-gate severity = penvsev->sevvalue; 7697c478bd9Sstevel@tonic-gate found = TRUE; 7707c478bd9Sstevel@tonic-gate } 7717c478bd9Sstevel@tonic-gate else { 7727c478bd9Sstevel@tonic-gate free(penvsev); 7737c478bd9Sstevel@tonic-gate penvsev = getauxsevs((char *) NULL); 7747c478bd9Sstevel@tonic-gate } 7757c478bd9Sstevel@tonic-gate } while (!found && (penvsev != (struct sevstr *) NULL)); 7767c478bd9Sstevel@tonic-gate 7777c478bd9Sstevel@tonic-gate if (found) free(penvsev); 7787c478bd9Sstevel@tonic-gate free(sevval); 7797c478bd9Sstevel@tonic-gate } 7807c478bd9Sstevel@tonic-gate 7817c478bd9Sstevel@tonic-gate if (!found) { 7827c478bd9Sstevel@tonic-gate (void) snprintf(msgbuf, sizeof (msgbuf), 7837c478bd9Sstevel@tonic-gate "Invalid severity: %s", sstr); 7847c478bd9Sstevel@tonic-gate (void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf, 7857c478bd9Sstevel@tonic-gate MM_NULLACT, MM_NULLTAG); 7867c478bd9Sstevel@tonic-gate exit(1); 7877c478bd9Sstevel@tonic-gate } 7887c478bd9Sstevel@tonic-gate 7897c478bd9Sstevel@tonic-gate } /* <severity> is not one of the standard severities */ 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate } /* <severity> is not numeric */ 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate } /* if (s_seen) */ 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate else severity = MM_NULLSEV; 7967c478bd9Sstevel@tonic-gate 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate /* 7997c478bd9Sstevel@tonic-gate * Other options 8007c478bd9Sstevel@tonic-gate */ 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate if (!a_seen) action = MM_NULLACT; 8037c478bd9Sstevel@tonic-gate if (!l_seen) label = MM_NULLLBL; 8047c478bd9Sstevel@tonic-gate if (!t_seen) tag = MM_NULLTAG; 8057c478bd9Sstevel@tonic-gate if (!text_seen) text = MM_NULLTXT; 8067c478bd9Sstevel@tonic-gate 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate /* 8097c478bd9Sstevel@tonic-gate * Write the message 8107c478bd9Sstevel@tonic-gate */ 8117c478bd9Sstevel@tonic-gate 8127c478bd9Sstevel@tonic-gate msgrtn = fmtmsg(class, label, severity, text, action ,tag); 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate /* 8167c478bd9Sstevel@tonic-gate * Return appropriate value to the shell (or wherever) 8177c478bd9Sstevel@tonic-gate */ 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate exitval = 0; 8207c478bd9Sstevel@tonic-gate if (msgrtn == MM_NOTOK) exitval = 32; 8217c478bd9Sstevel@tonic-gate else { 8227c478bd9Sstevel@tonic-gate if (msgrtn & MM_NOMSG) exitval += 2; 8237c478bd9Sstevel@tonic-gate if (msgrtn & MM_NOCON) exitval += 4; 8247c478bd9Sstevel@tonic-gate } 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate return(exitval); 8277c478bd9Sstevel@tonic-gate } 828