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 *
exttok(tok,delims)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 *
noesc(str)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 *
getauxsevs(ptr)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
main(int argc,char ** argv)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