17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
5004388ecasper * Common Development and Distribution License (the "License").
6004388ecasper * You may not use this file except in compliance with the License.
77c478bdstevel@tonic-gate *
87c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bdstevel@tonic-gate * See the License for the specific language governing permissions
117c478bdstevel@tonic-gate * and limitations under the License.
127c478bdstevel@tonic-gate *
137c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bdstevel@tonic-gate *
197c478bdstevel@tonic-gate * CDDL HEADER END
207c478bdstevel@tonic-gate */
217257d1braf
227c478bdstevel@tonic-gate/*
237257d1braf * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
247c478bdstevel@tonic-gate * Use is subject to license terms.
257c478bdstevel@tonic-gate */
267c478bdstevel@tonic-gate
277c478bdstevel@tonic-gate/*	Copyright (c) 1988 AT&T	*/
287c478bdstevel@tonic-gate/*	  All Rights Reserved  	*/
297c478bdstevel@tonic-gate
307c478bdstevel@tonic-gate/*
317c478bdstevel@tonic-gate * fmtmsg.c
327c478bdstevel@tonic-gate *
337c478bdstevel@tonic-gate *  Contains:
347c478bdstevel@tonic-gate *	fmtmsg()	Writes a message in standard format.
357c478bdstevel@tonic-gate *	addseverity()	Adds a severity definition to the list of known
367c478bdstevel@tonic-gate *			severity definitions.
377c478bdstevel@tonic-gate *
387c478bdstevel@tonic-gate *	Notes:
397c478bdstevel@tonic-gate *	  - None of these functions can use strtok().
407c478bdstevel@tonic-gate */
417c478bdstevel@tonic-gate
427c478bdstevel@tonic-gate/*
437c478bdstevel@tonic-gate * Header Files Referenced:
447c478bdstevel@tonic-gate *	<stdio.h>		C Standard I/O Definitions
457c478bdstevel@tonic-gate *	<string.h>		C string handling definitions
467c478bdstevel@tonic-gate *	<fcntl.h>		UNIX file control definitions
477c478bdstevel@tonic-gate *	<errno.h>		UNIX error numbers and definitions
487c478bdstevel@tonic-gate *	<fmtmsg.h>		Global definitions for fmtmsg()
497c478bdstevel@tonic-gate *	<stdlib.h>		miscellaneous function declarations
507c478bdstevel@tonic-gate */
517c478bdstevel@tonic-gate
527257d1braf#pragma weak _fmtmsg = fmtmsg
537257d1braf#pragma weak _addseverity = addseverity
547257d1braf
557257d1braf#include "lint.h"
567c478bdstevel@tonic-gate#include "mtlib.h"
577c478bdstevel@tonic-gate#include "libc.h"
587c478bdstevel@tonic-gate#include <sys/types.h>
597c478bdstevel@tonic-gate#include <stddef.h>
607c478bdstevel@tonic-gate#include <stdio.h>
617c478bdstevel@tonic-gate#include <string.h>
627c478bdstevel@tonic-gate#include <fcntl.h>
637c478bdstevel@tonic-gate#include <errno.h>
647c478bdstevel@tonic-gate#include <fmtmsg.h>
657c478bdstevel@tonic-gate#include <stdlib.h>
667c478bdstevel@tonic-gate#include <thread.h>
677c478bdstevel@tonic-gate#include <synch.h>
687c478bdstevel@tonic-gate#include <alloca.h>
697c478bdstevel@tonic-gate
707c478bdstevel@tonic-gate/*
717c478bdstevel@tonic-gate * External functions referenced:
727c478bdstevel@tonic-gate *	(Others may be defined in header files above)
737c478bdstevel@tonic-gate *
747c478bdstevel@tonic-gate *	getenv		Extracts data from the environment
757c478bdstevel@tonic-gate *	libc_malloc	Allocates space from main memory
767c478bdstevel@tonic-gate *	libc_free	Frees space allocated via libc_malloc()
777c478bdstevel@tonic-gate *	strtol		Convert string to "long"
787c478bdstevel@tonic-gate *	clearerr	Clears an error on a stream (this is to make "lint"
797c478bdstevel@tonic-gate *			happy)
807c478bdstevel@tonic-gate */
817c478bdstevel@tonic-gate
827c478bdstevel@tonic-gate
837c478bdstevel@tonic-gate/*
847c478bdstevel@tonic-gate * Local Constant Definitions
857c478bdstevel@tonic-gate */
867c478bdstevel@tonic-gate
877c478bdstevel@tonic-gate/*
887c478bdstevel@tonic-gate * Boolean constants
897c478bdstevel@tonic-gate *	TRUE	Boolean value for "true" (any bits on)
907c478bdstevel@tonic-gate *	FALSE	Boolean value for "false" (all bits off)
917c478bdstevel@tonic-gate */
927c478bdstevel@tonic-gate
937c478bdstevel@tonic-gate#ifndef	FALSE
947c478bdstevel@tonic-gate#define	FALSE		(0)
957c478bdstevel@tonic-gate#endif
967c478bdstevel@tonic-gate
977c478bdstevel@tonic-gate#ifndef TRUE
987c478bdstevel@tonic-gate#define	TRUE		(1)
997c478bdstevel@tonic-gate#endif
1007c478bdstevel@tonic-gate
1017c478bdstevel@tonic-gate#define	MAX_MSG_SIZE	1024
1027c478bdstevel@tonic-gate
1037c478bdstevel@tonic-gate/*
1047c478bdstevel@tonic-gate * Keywords for fields named in the MSGVERB environment variable.
1057c478bdstevel@tonic-gate */
1067c478bdstevel@tonic-gate
1077c478bdstevel@tonic-gate#define	ST_LBL		"label"
1087c478bdstevel@tonic-gate#define	ST_SEV		"severity"
1097c478bdstevel@tonic-gate#define	ST_TXT		"text"
1107c478bdstevel@tonic-gate#define	ST_TAG		"tag"
1117c478bdstevel@tonic-gate#define	ST_ACT		"action"
1127c478bdstevel@tonic-gate
1137c478bdstevel@tonic-gate
1147c478bdstevel@tonic-gate/*
1157c478bdstevel@tonic-gate *	The following constants define the value of the "msgverb"
1167c478bdstevel@tonic-gate *	variable.  This variable tells fmtmsg() which parts of the
1177c478bdstevel@tonic-gate *	standard message it is to display.  If !(msgverb&MV_SET),
1187c478bdstevel@tonic-gate *	fmtmsg() will interrogate the "MSGVERB" environment variable
1197c478bdstevel@tonic-gate *	and set "msgverb" accordingly.
1207c478bdstevel@tonic-gate *
1217c478bdstevel@tonic-gate *	NOTE:  This means that if MSGVERB changes after the first call
1227c478bdstevel@tonic-gate *	       to fmtmsg(), it will be ignored.
1237c478bdstevel@tonic-gate *
1247c478bdstevel@tonic-gate *	Constants:
1257c478bdstevel@tonic-gate *		MV_INV	Check MSGVERB environment variable (invalidates value)
1267c478bdstevel@tonic-gate *		MV_SET	MSGVERB checked, msgverb value valid
1277c478bdstevel@tonic-gate *		MV_LBL	"label" selected
1287c478bdstevel@tonic-gate *		MV_SEV	"severity" selected
1297c478bdstevel@tonic-gate *		MV_TXT	"text" selected
1307c478bdstevel@tonic-gate *		MV_TAG	"messageID" selected
1317c478bdstevel@tonic-gate *		MV_ACT	"action" selected
1327c478bdstevel@tonic-gate *
1337c478bdstevel@tonic-gate *		MV_ALL	All components selected
1347c478bdstevel@tonic-gate *		MV_DFLT	Default value for MSGVERB
1357c478bdstevel@tonic-gate */
1367c478bdstevel@tonic-gate
1377c478bdstevel@tonic-gate#define	MV_INV		0
1387c478bdstevel@tonic-gate#define	MV_SET		0x0001
1397c478bdstevel@tonic-gate#define	MV_LBL		0x0002
1407c478bdstevel@tonic-gate#define	MV_SEV		0x0004
1417c478bdstevel@tonic-gate#define	MV_TXT		0x0008
1427c478bdstevel@tonic-gate#define	MV_TAG		0x0010
1437c478bdstevel@tonic-gate#define	MV_ACT		0x0020
1447c478bdstevel@tonic-gate
1457c478bdstevel@tonic-gate#define	MV_ALL		(MV_LBL|MV_SEV|MV_TXT|MV_TAG|MV_ACT)
1467c478bdstevel@tonic-gate#define	MV_DFLT		(MV_LBL|MV_SEV|MV_TXT|MV_TAG|MV_ACT)
1477c478bdstevel@tonic-gate
1487c478bdstevel@tonic-gate
1497c478bdstevel@tonic-gate
1507c478bdstevel@tonic-gate/*
1517c478bdstevel@tonic-gate * Strings defining the different severities of a message.
1527c478bdstevel@tonic-gate * Internationalization may demand that these come from the message database
1537c478bdstevel@tonic-gate */
1547c478bdstevel@tonic-gate
1557c478bdstevel@tonic-gate#define	SV_UNK		"UNKNOWN"
1567c478bdstevel@tonic-gate#define	SV_HALT		"HALT"
1577c478bdstevel@tonic-gate#define	SV_ERROR	"ERROR"
1587c478bdstevel@tonic-gate#define	SV_WARN		"WARNING"
1597c478bdstevel@tonic-gate#define	SV_INF		"INFO"
1607c478bdstevel@tonic-gate
1617c478bdstevel@tonic-gate
1627c478bdstevel@tonic-gate/*
1637c478bdstevel@tonic-gate * Text string if none is provided:
1647c478bdstevel@tonic-gate */
1657c478bdstevel@tonic-gate
1667c478bdstevel@tonic-gate#define	DEFLT_TEXT	"No text provided with this message"
1677c478bdstevel@tonic-gate
1687c478bdstevel@tonic-gate
1697c478bdstevel@tonic-gate/*
1707c478bdstevel@tonic-gate * Text string introduction for "action".  This may have to come from
1717c478bdstevel@tonic-gate * the message database because of internationalization.
1727c478bdstevel@tonic-gate */
1737c478bdstevel@tonic-gate
1747c478bdstevel@tonic-gate#define	ACTINTRO	"TO FIX: "
1757c478bdstevel@tonic-gate#define	ACTINTROLN	8
1767c478bdstevel@tonic-gate
1777c478bdstevel@tonic-gate
1787c478bdstevel@tonic-gate/*
1797c478bdstevel@tonic-gate * SEPSTR is the string that separates the "label" from what follows it,
1807c478bdstevel@tonic-gate * and the severity from what follows it.
1817c478bdstevel@tonic-gate */
1827c478bdstevel@tonic-gate
1837c478bdstevel@tonic-gate#define	SEPSTR		": "
1847c478bdstevel@tonic-gate#define	SEPSTRLN	2
1857c478bdstevel@tonic-gate
1867c478bdstevel@tonic-gate
1877c478bdstevel@tonic-gate/*
1887c478bdstevel@tonic-gate * Miscellaneous constants:
1897c478bdstevel@tonic-gate *	CONNAME		Filesystem entry name for the system console
1907c478bdstevel@tonic-gate */
1917c478bdstevel@tonic-gate
1927c478bdstevel@tonic-gate#define	CONNAME		"/dev/console"
1937c478bdstevel@tonic-gate
1947c478bdstevel@tonic-gate/*
1957c478bdstevel@tonic-gate * Local data type definitions
1967c478bdstevel@tonic-gate */
1977c478bdstevel@tonic-gate
1987c478bdstevel@tonic-gate/*
1997c478bdstevel@tonic-gate * Severity string structure
2007c478bdstevel@tonic-gate *
2017c478bdstevel@tonic-gate *	struct sevstr
2027c478bdstevel@tonic-gate *		sevvalue	Value of the severity-level being defined
2037c478bdstevel@tonic-gate *		sevkywd		Keyword identifying the severity
2047c478bdstevel@tonic-gate *		sevprptr	Pointer to the string associated with the value
2057c478bdstevel@tonic-gate *		sevnext		Pointer to the next value in the list.
2067c478bdstevel@tonic-gate *
2077c478bdstevel@tonic-gate *	Restrictions:
2087c478bdstevel@tonic-gate *		sevvalue	Must be a non-negative integer (>=0)
2097c478bdstevel@tonic-gate *
2107c478bdstevel@tonic-gate *	There are three (possibly null) lists of these structures.
2117c478bdstevel@tonic-gate *	  1)	is the list of standard severities
2127c478bdstevel@tonic-gate *	  2)	is the list of severity-levels defined by SEV_LEVEL
2137c478bdstevel@tonic-gate *	  3)	is the list of severity-levels defined by calls to
2147c478bdstevel@tonic-gate *		addseverity()
2157c478bdstevel@tonic-gate */
2167c478bdstevel@tonic-gate
2177c478bdstevel@tonic-gatestruct sevstr {
2187c478bdstevel@tonic-gate	int		sevvalue;
2197c478bdstevel@tonic-gate	const char	*sevkywd;
2207c478bdstevel@tonic-gate	const char	*sevprstr;
2217c478bdstevel@tonic-gate	struct sevstr  *sevnext;
2227c478bdstevel@tonic-gate};
2237c478bdstevel@tonic-gate
2247c478bdstevel@tonic-gate/*
2257c478bdstevel@tonic-gate * Local Static Data
2267c478bdstevel@tonic-gate *	msgverb		int
2277c478bdstevel@tonic-gate *			Contains the internal representation or the
2287c478bdstevel@tonic-gate *			MSGVERB environment variable.
2297c478bdstevel@tonic-gate *	sevlook		TRUE if fmtmsg() has to look at SEV_LEVEL the
2307c478bdstevel@tonic-gate *			next time it is called.
2317c478bdstevel@tonic-gate *	paugsevs	struct sevstr *
2327c478bdstevel@tonic-gate *			Head of the linked list of structures that define
2337c478bdstevel@tonic-gate *			severities that augment the standard severities,
2347c478bdstevel@tonic-gate *			as defined by addseverity().
2357c478bdstevel@tonic-gate *	penvsevs	struct sevstrs *
2367c478bdstevel@tonic-gate *			Head of the linked list of structures that define
2377c478bdstevel@tonic-gate *			severities that augment the standard severities,
2387c478bdstevel@tonic-gate *			as defined by SEV_LEVEL.
2397c478bdstevel@tonic-gate *	pstdsevs	struct sevstrs *
2407c478bdstevel@tonic-gate *			Head of the linked list of structures that define
2417c478bdstevel@tonic-gate *			the standard severities.
2427c478bdstevel@tonic-gate */
2437c478bdstevel@tonic-gate
2447c478bdstevel@tonic-gatestatic mutex_t fmt_lock = DEFAULTMUTEX;
2457c478bdstevel@tonic-gate
2467c478bdstevel@tonic-gatestatic	int		msgverb		= 0;
2477c478bdstevel@tonic-gatestatic	int		sevlook		= TRUE;
2487c478bdstevel@tonic-gate
2497c478bdstevel@tonic-gatestatic	struct sevstr  *paugsevs	= (struct sevstr *)NULL;
2507c478bdstevel@tonic-gatestatic	struct sevstr  *penvsevs	= (struct sevstr *)NULL;
2517c478bdstevel@tonic-gate
2527c478bdstevel@tonic-gatestatic	struct sevstr	sevstrs[]	= {
2537c478bdstevel@tonic-gate	{ MM_HALT,	"", SV_HALT,	&sevstrs[1]},
2547c478bdstevel@tonic-gate	{ MM_ERROR,    "", SV_ERROR,	&sevstrs[2]},
2557c478bdstevel@tonic-gate	{ MM_WARNING,  "", SV_WARN, 	&sevstrs[3]},
2567c478bdstevel@tonic-gate	{ MM_INFO,	"", SV_INF,  	(struct sevstr *)NULL},
2577c478bdstevel@tonic-gate};
2587c478bdstevel@tonic-gatestatic	struct sevstr  *pstdsevs	= &sevstrs[0];
2597c478bdstevel@tonic-gate
2607c478bdstevel@tonic-gate/*
2617c478bdstevel@tonic-gate * static char *exttok(str, delims)
2627c478bdstevel@tonic-gate *	const char   *str
2637c478bdstevel@tonic-gate *	const char   *delims
2647c478bdstevel@tonic-gate *
2657c478bdstevel@tonic-gate *	This function examines the string pointed to by "str", looking
2667c478bdstevel@tonic-gate *	for the first occurrence of any of the characters in the string
2677c478bdstevel@tonic-gate *	whose address is "delims".  It returns the address of that
2687c478bdstevel@tonic-gate *	character or (char *)NULL if there was nothing to search.
2697c478bdstevel@tonic-gate *
2707c478bdstevel@tonic-gate * Arguments:
2717c478bdstevel@tonic-gate *	str	Address of the string to search
2727c478bdstevel@tonic-gate *	delims	Address of the string containing delimiters
2737c478bdstevel@tonic-gate *
2747c478bdstevel@tonic-gate * Returns:  char *
2757c478bdstevel@tonic-gate *	Returns the address of the first occurrence of any of the characters
2767c478bdstevel@tonic-gate *	in "delim" in the string "str" (incl '\0').  If there was nothing
2777c478bdstevel@tonic-gate *	to search, the function returns (char *)NULL.
2787c478bdstevel@tonic-gate *
2797c478bdstevel@tonic-gate * Notes:
2807c478bdstevel@tonic-gate *    - This function is needed because strtok() can't be used inside a
2817c478bdstevel@tonic-gate *	function.  Besides, strtok() is destructive in the string, which
2827c478bdstevel@tonic-gate *	is undesirable in many circumstances.
2837c478bdstevel@tonic-gate *    - This function understands escaped delimiters as non-delimiters.
2847c478bdstevel@tonic-gate *	Delimiters are escaped by preceding them with '\' characters.
2857c478bdstevel@tonic-gate *	The '\' character also must be escaped.
2867c478bdstevel@tonic-gate */
2877c478bdstevel@tonic-gate
2887c478bdstevel@tonic-gatestatic char *
2897c478bdstevel@tonic-gateexttok(const char *tok, const char *delims)
2907c478bdstevel@tonic-gate{
2917c478bdstevel@tonic-gate	char	*tokend;	/* Ptr to the end of the token */
2927c478bdstevel@tonic-gate	char	*p, *q;		/* Temp pointers */
2937c478bdstevel@tonic-gate
2947c478bdstevel@tonic-gate	/*
2957c478bdstevel@tonic-gate	 * Algorithm:
2967c478bdstevel@tonic-gate	 *    1.  Get the starting address(new string or where we
2977c478bdstevel@tonic-gate	 *	  left off).  If nothing to search, return(char *)NULL
2987c478bdstevel@tonic-gate	 *    2.  Find the end of the string
2997c478bdstevel@tonic-gate	 *    3.  Look for the first unescaped delimiter closest to the
3007c478bdstevel@tonic-gate	 *	  beginning of the string
3017c478bdstevel@tonic-gate	 *    4.  Remember where we left off
3027c478bdstevel@tonic-gate	 *    5.  Return a pointer to the delimiter we found
3037c478bdstevel@tonic-gate	 */
3047c478bdstevel@tonic-gate
3057c478bdstevel@tonic-gate	/* Begin at the beginning, if any */
3067c478bdstevel@tonic-gate	if (tok == (char *)NULL) {
3077c478bdstevel@tonic-gate		return ((char *)NULL);
3087c478bdstevel@tonic-gate	}
3097c478bdstevel@tonic-gate
3107c478bdstevel@tonic-gate	/* Find end of the token string */
3117c478bdstevel@tonic-gate	tokend = (char *)tok + (ptrdiff_t)strlen(tok);
3127c478bdstevel@tonic-gate
3137c478bdstevel@tonic-gate	/* Look for the 1st occurrence of any delimiter */
3147c478bdstevel@tonic-gate	for (p = (char *)delims; *p != '\0'; p++) {
3157c478bdstevel@tonic-gate		for (q = strchr(tok, (int)*p);
3167c478bdstevel@tonic-gate		    (q != 0) && (q != tok) && (*(q - (ptrdiff_t)1) == '\\');
3177c478bdstevel@tonic-gate		    q = strchr(q + (ptrdiff_t)1, (int)*p))
3187c478bdstevel@tonic-gate			;
3197c478bdstevel@tonic-gate		if ((q != 0) && (q < tokend))
3207c478bdstevel@tonic-gate			tokend = q;
3217c478bdstevel@tonic-gate	}
3227c478bdstevel@tonic-gate
3237c478bdstevel@tonic-gate	/* Done */
3247c478bdstevel@tonic-gate	return (tokend);
3257c478bdstevel@tonic-gate}
3267c478bdstevel@tonic-gate
3277c478bdstevel@tonic-gate/*
3287c478bdstevel@tonic-gate * char *noesc(str)
3297c478bdstevel@tonic-gate *
3307c478bdstevel@tonic-gate *	This function squeezes out all of the escaped character sequences
3317c478bdstevel@tonic-gate *	from the string <str>.  It returns a pointer to that string.
3327c478bdstevel@tonic-gate *
3337c478bdstevel@tonic-gate *  Arguments:
3347c478bdstevel@tonic-gate *	str	char *
3357c478bdstevel@tonic-gate *		The string that is to have its escaped characters removed.
3367c478bdstevel@tonic-gate *
3377c478bdstevel@tonic-gate *  Returns:  char *
3387c478bdstevel@tonic-gate *	This function returns its argument <str> always.
3397c478bdstevel@tonic-gate *
3407c478bdstevel@tonic-gate *  Notes:
3417c478bdstevel@tonic-gate *	This function potentially modifies the string it is given.
3427c478bdstevel@tonic-gate */
3437c478bdstevel@tonic-gate
3447c478bdstevel@tonic-gatestatic char *
3457c478bdstevel@tonic-gatenoesc(char *str)
3467c478bdstevel@tonic-gate{
3477c478bdstevel@tonic-gate	char   *p;		/* Temp string pointer */
3487c478bdstevel@tonic-gate	char   *q;		/* Temp string pointer */
3497c478bdstevel@tonic-gate
3507c478bdstevel@tonic-gate	/* Look for an escaped character */
3517c478bdstevel@tonic-gate	p = str;
3527c478bdstevel@tonic-gate	while (*p && (*p != '\\')) p++;
3537c478bdstevel@tonic-gate
3547c478bdstevel@tonic-gate
3557c478bdstevel@tonic-gate	/*
3567c478bdstevel@tonic-gate	 * If there was at least one, squeeze them out
3577c478bdstevel@tonic-gate	 * Otherwise, don't touch the argument string
3587c478bdstevel@tonic-gate	 */
3597c478bdstevel@tonic-gate
3607c478bdstevel@tonic-gate	if (*p) {
3617c478bdstevel@tonic-gate		q = p++;
3627c478bdstevel@tonic-gate		while (*q++ = *p++) {
3637c478bdstevel@tonic-gate			if (*p == '\\')
3647c478bdstevel@tonic-gate				p++;
3657c478bdstevel@tonic-gate		}
3667c478bdstevel@tonic-gate	}
3677c478bdstevel@tonic-gate
3687c478bdstevel@tonic-gate	/* Finished.  Return our argument */
3697c478bdstevel@tonic-gate	return (str);
3707c478bdstevel@tonic-gate}
3717c478bdstevel@tonic-gate
3727c478bdstevel@tonic-gate/*
3737c478bdstevel@tonic-gate * struct sevstr *getauxsevs(ptr)
3747c478bdstevel@tonic-gate *
3757c478bdstevel@tonic-gate *	Parses a string that is in the format of the severity definitions.
3767c478bdstevel@tonic-gate *	Returns a pointer to a (malloc'd) structure that contains the
3777c478bdstevel@tonic-gate *	definition, or (struct sevstr *)NULL if none was parsed.
3787c478bdstevel@tonic-gate *
3797c478bdstevel@tonic-gate * Arguments:
3807c478bdstevel@tonic-gate *	ptr	char *
3817c478bdstevel@tonic-gate *		References the string from which data is to be extracted.
3827c478bdstevel@tonic-gate *		If (char *)NULL, continue where we left off.  Otherwise,
3837c478bdstevel@tonic-gate *		start with the string referenced by ptr.
3847c478bdstevel@tonic-gate *
3857c478bdstevel@tonic-gate * Returns: struct sevstr *
3867c478bdstevel@tonic-gate *	A pointer to a malloc'd structure containing the severity definition
3877c478bdstevel@tonic-gate *	parsed from string, or (struct sevstr *)NULL if none.
3887c478bdstevel@tonic-gate *
3897c478bdstevel@tonic-gate * Notes:
3907c478bdstevel@tonic-gate *    - This function is destructive to the string referenced by its argument.
3917c478bdstevel@tonic-gate */
3927c478bdstevel@tonic-gate
3937c478bdstevel@tonic-gate/* Static data */
3947c478bdstevel@tonic-gatestatic	char		*leftoff = (char *)NULL;
3957c478bdstevel@tonic-gate
3967c478bdstevel@tonic-gatestatic	struct sevstr *
3977c478bdstevel@tonic-gategetauxsevs(char *ptr)
3987c478bdstevel@tonic-gate{
3997c478bdstevel@tonic-gate	char		*current;	/* Ptr to current sev def'n */
4007c478bdstevel@tonic-gate	char		*tokend;	/* Ptr to end of current sev def'n */
4017c478bdstevel@tonic-gate	char		*kywd;		/* Ptr to extracted kywd */
4027c478bdstevel@tonic-gate	char		*valstr;		/* Ptr to extracted sev value */
4037c478bdstevel@tonic-gate	char		*prstr;		/* Ptr to extracted print str */
4047c478bdstevel@tonic-gate	char		*p;		/* Temp pointer */
4057c478bdstevel@tonic-gate	int		val;		/* Converted severity value */
4067c478bdstevel@tonic-gate	int		done;		/* Flag, sev def'n found and ok? */
4077c478bdstevel@tonic-gate	struct sevstr  *rtnval;		/* Value to return */
4087c478bdstevel@tonic-gate
4097c478bdstevel@tonic-gate
4107c478bdstevel@tonic-gate	/* Start anew or start where we left off? */
4117c478bdstevel@tonic-gate	current = (ptr == (char *)NULL) ? leftoff : ptr;
4127c478bdstevel@tonic-gate
4137c478bdstevel@tonic-gate
4147c478bdstevel@tonic-gate	/* If nothing to parse, return (char *)NULL */
4157c478bdstevel@tonic-gate	if (current == (char *)NULL) {
4167c478bdstevel@tonic-gate		return ((struct sevstr *)NULL);
4177c478bdstevel@tonic-gate	}
4187c478bdstevel@tonic-gate
4197c478bdstevel@tonic-gate
4207c478bdstevel@tonic-gate	/*
4217c478bdstevel@tonic-gate	 * Look through the string "current" for a token of the form
4227c478bdstevel@tonic-gate	 * <kywd>,<sev>,<printstring> delimited by ':' or '\0'
4237c478bdstevel@tonic-gate	 */
4247c478bdstevel@tonic-gate
4257c478bdstevel@tonic-gate	/* Loop initializations */
4267c478bdstevel@tonic-gate	done = FALSE;
4277c478bdstevel@tonic-gate	rtnval = (struct sevstr *)NULL;
4287c478bdstevel@tonic-gate	while (!done) {
4297c478bdstevel@tonic-gate		/* Eat leading junk */
4307c478bdstevel@tonic-gate		while (*(tokend = exttok(current, ":,")) == ':') {
4317c478bdstevel@tonic-gate			current = tokend + (ptrdiff_t)1;
4327c478bdstevel@tonic-gate		}
4337c478bdstevel@tonic-gate
4347c478bdstevel@tonic-gate		/* If we've found a <kywd>,... */
4357c478bdstevel@tonic-gate		if (*tokend == ',') {
4367c478bdstevel@tonic-gate			kywd = current;
4377c478bdstevel@tonic-gate			*tokend = '\0';
4387c478bdstevel@tonic-gate
4397c478bdstevel@tonic-gate			/* Look for <kywd>,<sev>,... */
4407c478bdstevel@tonic-gate			current = tokend + (ptrdiff_t)1;
4417c478bdstevel@tonic-gate			if (*(tokend = exttok(current, ":,")) == ',') {
4427c478bdstevel@tonic-gate				valstr = current;
4437c478bdstevel@tonic-gate				*tokend = '\0';
4447c478bdstevel@tonic-gate
4457c478bdstevel@tonic-gate				current = tokend + (ptrdiff_t)1;
4467c478bdstevel@tonic-gate				prstr = current;
4477c478bdstevel@tonic-gate
4487c478bdstevel@tonic-gate				/* Make sure <sev> > 4 */
4497c478bdstevel@tonic-gate				val = (int)strtol(noesc(valstr), &p, 0);
4507c478bdstevel@tonic-gate				if ((val > 4) && (p == tokend)) {
4517c478bdstevel@tonic-gate
4527c478bdstevel@tonic-gate					/*
4537c478bdstevel@tonic-gate					 * Found <kywd>,<sev>,<printstring>.
4547c478bdstevel@tonic-gate					 * remember where we left off
4557c478bdstevel@tonic-gate					 */
4567c478bdstevel@tonic-gate
4577c478bdstevel@tonic-gate					if (*(tokend =
4587257d1braf					    exttok(current, ":")) == ':') {
4597c478bdstevel@tonic-gate						*tokend = '\0';
4607c478bdstevel@tonic-gate						leftoff = tokend +
4617c478bdstevel@tonic-gate						    (ptrdiff_t)1;
4627c478bdstevel@tonic-gate					} else {
4637c478bdstevel@tonic-gate						leftoff = (char *)NULL;
4647c478bdstevel@tonic-gate					}
4657c478bdstevel@tonic-gate
4667c478bdstevel@tonic-gate					/*
4677c478bdstevel@tonic-gate					 * Alloc structure to contain
4687c478bdstevel@tonic-gate					 * severity definition
4697c478bdstevel@tonic-gate					 */
4707c478bdstevel@tonic-gate					rtnval = libc_malloc(
4717c478bdstevel@tonic-gate					    sizeof (struct sevstr));
4727c478bdstevel@tonic-gate					if (rtnval != NULL) {
4737c478bdstevel@tonic-gate
4747c478bdstevel@tonic-gate						/* Fill in structure */
4757c478bdstevel@tonic-gate						rtnval->sevkywd = noesc(kywd);
4767c478bdstevel@tonic-gate						rtnval->sevvalue = val;
4777c478bdstevel@tonic-gate						rtnval->sevprstr = noesc(prstr);
4787c478bdstevel@tonic-gate						rtnval->sevnext =
4797c478bdstevel@tonic-gate						    (struct sevstr *)NULL;
4807c478bdstevel@tonic-gate					}
4817c478bdstevel@tonic-gate					done = TRUE;
4827c478bdstevel@tonic-gate				} else {
4837c478bdstevel@tonic-gate					/*
4847c478bdstevel@tonic-gate					 * Invalid severity value,
4857c478bdstevel@tonic-gate					 * eat thru end of token
4867c478bdstevel@tonic-gate					 */
4877c478bdstevel@tonic-gate					current = tokend;
4887c478bdstevel@tonic-gate					if (*(tokend = exttok(prstr, ":")) ==
4897c478bdstevel@tonic-gate					    ':') {
4907c478bdstevel@tonic-gate						current++;
4917c478bdstevel@tonic-gate					}
4927c478bdstevel@tonic-gate				}
4937c478bdstevel@tonic-gate			} else {
4947c478bdstevel@tonic-gate				/*
4957c478bdstevel@tonic-gate				 * Invalid severity definition,
4967c478bdstevel@tonic-gate				 * eat thru end of token
4977c478bdstevel@tonic-gate				 */
4987c478bdstevel@tonic-gate				current = tokend;
4997c478bdstevel@tonic-gate				if (*tokend == ':')
5007c478bdstevel@tonic-gate					current++;
5017c478bdstevel@tonic-gate			}
5027c478bdstevel@tonic-gate		} else {
5037c478bdstevel@tonic-gate			/* End of string found */
5047c478bdstevel@tonic-gate			done = TRUE;
5057c478bdstevel@tonic-gate			leftoff = (char *)NULL;
5067c478bdstevel@tonic-gate		}
5077c478bdstevel@tonic-gate	} /* while (!done) */
5087c478bdstevel@tonic-gate
5097c478bdstevel@tonic-gate	/* Finished */
5107c478bdstevel@tonic-gate	return (rtnval);
5117c478bdstevel@tonic-gate}
5127c478bdstevel@tonic-gate
5137c478bdstevel@tonic-gate/*
5147c478bdstevel@tonic-gate * void msgverbset()
5157c478bdstevel@tonic-gate *
5167c478bdstevel@tonic-gate *	Parces the argument of the MSGVERB environment variable and places
5177c478bdstevel@tonic-gate *	a representation of the value of that value in "msgverb"
5187c478bdstevel@tonic-gate *
5197c478bdstevel@tonic-gate * Arguments:
5207c478bdstevel@tonic-gate *	None:
5217c478bdstevel@tonic-gate *
5227c478bdstevel@tonic-gate * Returns: void
5237c478bdstevel@tonic-gate *
5247c478bdstevel@tonic-gate * Notes:
5257c478bdstevel@tonic-gate */
5267c478bdstevel@tonic-gate
5277c478bdstevel@tonic-gatestatic void
5287c478bdstevel@tonic-gatemsgverbset(void)
5297c478bdstevel@tonic-gate{
5307c478bdstevel@tonic-gate	char   *opts;			/* Pointer to MSGVERB's value */
5317c478bdstevel@tonic-gate	char   *alloced;		/* Pointer to MSGVERB's value */
5327c478bdstevel@tonic-gate	char   *tok;			/* Pointer to current token */
5337c478bdstevel@tonic-gate	char   *tokend;			/* Pointer to end of current token */
5347c478bdstevel@tonic-gate	char   *nexttok;		/* Pointer to next token */
5357c478bdstevel@tonic-gate
5367c478bdstevel@tonic-gate
5377c478bdstevel@tonic-gate	/* Rid ourselves of junk in "msgverb" */
5387c478bdstevel@tonic-gate	msgverb = 0;
5397c478bdstevel@tonic-gate
5407c478bdstevel@tonic-gate	/* Get the value of MSGVERB.  If none, use default value */
5417c478bdstevel@tonic-gate	if ((opts = getenv(MSGVERB)) == (char *)NULL) {
5427c478bdstevel@tonic-gate		msgverb = MV_DFLT;
5437c478bdstevel@tonic-gate	} else { /* MSGVERB has a value.  Interpret it */
5447c478bdstevel@tonic-gate		if ((alloced = libc_malloc(strlen(opts) + 1)) == NULL) {
5457c478bdstevel@tonic-gate			msgverb = MV_DFLT;
5467c478bdstevel@tonic-gate		} else {
5477c478bdstevel@tonic-gate			/* Make a copy of the value of MSGVERB */
5487c478bdstevel@tonic-gate			nexttok = strcpy(alloced, opts);
5497c478bdstevel@tonic-gate
5507c478bdstevel@tonic-gate			/* Parse the options given by the user */
5517c478bdstevel@tonic-gate			while ((tok = nexttok) != (char *)NULL) {
5527c478bdstevel@tonic-gate				/*
5537c478bdstevel@tonic-gate				 * Find end of the next token and squeeze
5547c478bdstevel@tonic-gate				 * out escaped characters
5557c478bdstevel@tonic-gate				 */
5567c478bdstevel@tonic-gate				tokend = exttok(tok, ":");
5577c478bdstevel@tonic-gate				tok = noesc(tok);
5587c478bdstevel@tonic-gate
5597c478bdstevel@tonic-gate				/* Delimit token and mark next, if any */
5607c478bdstevel@tonic-gate				if (*tokend == ':') {
5617c478bdstevel@tonic-gate					nexttok = tokend + (ptrdiff_t)1;
5627c478bdstevel@tonic-gate					*tokend = '\0';
5637c478bdstevel@tonic-gate				} else {
5647c478bdstevel@tonic-gate					nexttok = (char *)NULL;
5657c478bdstevel@tonic-gate				}
5667c478bdstevel@tonic-gate
5677c478bdstevel@tonic-gate				/* Check for "text" */
5687c478bdstevel@tonic-gate				if (strcmp(tok, ST_TXT) == 0) {
5697c478bdstevel@tonic-gate					msgverb |= MV_TXT;
5707c478bdstevel@tonic-gate
5717c478bdstevel@tonic-gate					/* Check for "label" */
5727c478bdstevel@tonic-gate				} else if (strcmp(tok, ST_LBL) == 0) {
5737c478bdstevel@tonic-gate					msgverb |= MV_LBL;
5747c478bdstevel@tonic-gate
5757c478bdstevel@tonic-gate					/* Check for "action */
5767c478bdstevel@tonic-gate				} else if (strcmp(tok, ST_ACT) == 0) {
5777c478bdstevel@tonic-gate					msgverb |= MV_ACT;
5787c478bdstevel@tonic-gate
5797c478bdstevel@tonic-gate					/* Check for "severity" */
5807c478bdstevel@tonic-gate				} else if (strcmp(tok, ST_SEV) == 0) {
5817c478bdstevel@tonic-gate					msgverb |= MV_SEV;
5827c478bdstevel@tonic-gate
5837c478bdstevel@tonic-gate					/* Check for "tag" */
5847c478bdstevel@tonic-gate				} else if (strcmp(tok, ST_TAG) == 0) {
5857c478bdstevel@tonic-gate					msgverb |= MV_TAG;
5867c478bdstevel@tonic-gate
5877c478bdstevel@tonic-gate					/* Unknown, ignore MSGVERB value */
5887c478bdstevel@tonic-gate				} else {
5897c478bdstevel@tonic-gate					msgverb = MV_DFLT;
5907c478bdstevel@tonic-gate					nexttok = (char *)NULL;
5917c478bdstevel@tonic-gate				}
5927c478bdstevel@tonic-gate			} /* do while */
5937c478bdstevel@tonic-gate
5947c478bdstevel@tonic-gate			/*
5957c478bdstevel@tonic-gate			 * Use default if no keywords on MSGVERB
5967c478bdstevel@tonic-gate			 * environment variable
5977c478bdstevel@tonic-gate			 */
5987c478bdstevel@tonic-gate			if (msgverb == 0)
5997c478bdstevel@tonic-gate				msgverb = MV_DFLT;
6007c478bdstevel@tonic-gate
6017c478bdstevel@tonic-gate			/* Free allocated space */
6027c478bdstevel@tonic-gate			libc_free(alloced);
6037c478bdstevel@tonic-gate		}
6047c478bdstevel@tonic-gate	}
6057c478bdstevel@tonic-gate	/* Finished */
6067c478bdstevel@tonic-gate	/* return; */
6077c478bdstevel@tonic-gate}
6087c478bdstevel@tonic-gate
6097c478bdstevel@tonic-gate/*
6107c478bdstevel@tonic-gate * void sevstrset()
6117c478bdstevel@tonic-gate *
6127c478bdstevel@tonic-gate *	This function builds a structure containing auxillary severity
6137c478bdstevel@tonic-gate *	definitions.
6147c478bdstevel@tonic-gate *
6157c478bdstevel@tonic-gate *  Arguments:  None
6167c478bdstevel@tonic-gate *
6177c478bdstevel@tonic-gate *  Returns:  Void
6187c478bdstevel@tonic-gate */
6197c478bdstevel@tonic-gate
6207c478bdstevel@tonic-gatestatic char *sevspace = (char *)NULL;
6217c478bdstevel@tonic-gate
6227c478bdstevel@tonic-gatestatic void
6237c478bdstevel@tonic-gatesevstrset(void)
6247c478bdstevel@tonic-gate{
6257c478bdstevel@tonic-gate	struct sevstr  *plast;
6267c478bdstevel@tonic-gate	struct sevstr  *psev;
6277c478bdstevel@tonic-gate	char		*value;
6287c478bdstevel@tonic-gate
6297c478bdstevel@tonic-gate
6307c478bdstevel@tonic-gate	/* Look for SEV_LEVEL definition */
6317c478bdstevel@tonic-gate	if ((value = getenv(SEV_LEVEL)) != (char *)NULL) {
6327c478bdstevel@tonic-gate
6337c478bdstevel@tonic-gate		/* Allocate space and make a copy of the value of SEV_LEVEL */
6347c478bdstevel@tonic-gate		if ((sevspace = libc_malloc(strlen(value) + 1)) != NULL) {
6357c478bdstevel@tonic-gate			(void) strcpy(sevspace, value);
6367c478bdstevel@tonic-gate
6377c478bdstevel@tonic-gate			/* Continue for all severity descriptions */
6387c478bdstevel@tonic-gate			psev = getauxsevs(sevspace);
6397c478bdstevel@tonic-gate			plast = (struct sevstr *)NULL;
6407c478bdstevel@tonic-gate			if (psev != (struct sevstr *)NULL) {
6417c478bdstevel@tonic-gate				penvsevs = psev;
6427c478bdstevel@tonic-gate				plast = psev;
6437c478bdstevel@tonic-gate				while (psev = getauxsevs((char *)NULL)) {
6447c478bdstevel@tonic-gate					plast->sevnext = psev;
6457c478bdstevel@tonic-gate					plast = psev;
6467c478bdstevel@tonic-gate				}
6477c478bdstevel@tonic-gate			}
6487c478bdstevel@tonic-gate		} /* if sevspace != (char *)NULL */
6497c478bdstevel@tonic-gate	} /* if value != (char *)NULL */
6507c478bdstevel@tonic-gate}
6517c478bdstevel@tonic-gate
6527c478bdstevel@tonic-gate/*
6537c478bdstevel@tonic-gate * int addseverity(value, string)
6547c478bdstevel@tonic-gate *	int	value		Value of the severity
6557c478bdstevel@tonic-gate *	const char   *string	Print-string for the severity
6567c478bdstevel@tonic-gate *
6577c478bdstevel@tonic-gate *  Arguments:
6587c478bdstevel@tonic-gate *	value		int
6597c478bdstevel@tonic-gate *			The integer value of the severity being added
6607c478bdstevel@tonic-gate *	string		char *
6617c478bdstevel@tonic-gate *			A pointer to the character-string to be printed
6627c478bdstevel@tonic-gate *			whenever a severity of "value" is printed
6637c478bdstevel@tonic-gate *
6647c478bdstevel@tonic-gate *  Returns:  int
6657c478bdstevel@tonic-gate *	Zero if successful, -1 if failed. The function can fail under
6667c478bdstevel@tonic-gate *	the following circumstances:
6677c478bdstevel@tonic-gate *	  - libc_malloc() fails
6687c478bdstevel@tonic-gate *	  - The "value" is one of the reserved values.
6697c478bdstevel@tonic-gate *
6707c478bdstevel@tonic-gate *	This function permits C applications to define severity-levels
6717c478bdstevel@tonic-gate *	that augment the standard levels and those defined by the
6727c478bdstevel@tonic-gate *	SEV_LEVEL environment variable.
6737c478bdstevel@tonic-gate */
6747c478bdstevel@tonic-gate
6757c478bdstevel@tonic-gateint
6767c478bdstevel@tonic-gateaddseverity(int value, const char *string)
6777c478bdstevel@tonic-gate{
6787c478bdstevel@tonic-gate	struct sevstr  *p;		/* Temp ptr to severity structs */
6797c478bdstevel@tonic-gate	struct sevstr  *q;		/* Temp ptr(follower) to severity */
6807c478bdstevel@tonic-gate	int		found;		/* FLAG, element found in the list */
6817c478bdstevel@tonic-gate	int		rtnval;		/* Value to return to the caller */
6827c478bdstevel@tonic-gate
6837c478bdstevel@tonic-gate	/* Make sure we're not trying to redefine one of the reserved values */
6847c478bdstevel@tonic-gate	if (value <= 4) {
6857c478bdstevel@tonic-gate		errno = EINVAL;
6867c478bdstevel@tonic-gate		return (-1);
6877c478bdstevel@tonic-gate	}
6887c478bdstevel@tonic-gate
6897c478bdstevel@tonic-gate	lmutex_lock(&fmt_lock);
6907c478bdstevel@tonic-gate
6917c478bdstevel@tonic-gate	/* Make sure we've interpreted SEV_LEVEL */
6927c478bdstevel@tonic-gate
6937c478bdstevel@tonic-gate	if (sevlook) {
6947c478bdstevel@tonic-gate		sevstrset();
6957c478bdstevel@tonic-gate		sevlook = FALSE;
6967c478bdstevel@tonic-gate	}
6977c478bdstevel@tonic-gate
6987c478bdstevel@tonic-gate
6997c478bdstevel@tonic-gate	/*
7007c478bdstevel@tonic-gate	 * Leaf through the list.  We may be redefining or removing a
7017c478bdstevel@tonic-gate	 * definition
7027c478bdstevel@tonic-gate	 */
7037c478bdstevel@tonic-gate	q = (struct sevstr *)NULL;
7047c478bdstevel@tonic-gate	found = FALSE;
7057c478bdstevel@tonic-gate	for (p = paugsevs; !found && (p != (struct sevstr *)NULL);
7067c478bdstevel@tonic-gate	    p = p->sevnext) {
7077c478bdstevel@tonic-gate		if (p->sevvalue == value) {
7087c478bdstevel@tonic-gate			/* We've a match.  Remove or modify the entry */
7097c478bdstevel@tonic-gate			if (string == (char *)NULL) {
7107c478bdstevel@tonic-gate				if (q == (struct sevstr *)NULL) {
7117c478bdstevel@tonic-gate					paugsevs = p->sevnext;
7127c478bdstevel@tonic-gate				} else {
7137c478bdstevel@tonic-gate					q->sevnext = p->sevnext;
7147c478bdstevel@tonic-gate				}
7157c478bdstevel@tonic-gate				libc_free(p);
7167c478bdstevel@tonic-gate			} else {
7177c478bdstevel@tonic-gate				p->sevprstr = string;
7187c478bdstevel@tonic-gate			}
7197c478bdstevel@tonic-gate			found = TRUE;
7207c478bdstevel@tonic-gate		}
7217c478bdstevel@tonic-gate		q = p;
7227c478bdstevel@tonic-gate	}
7237c478bdstevel@tonic-gate
7247c478bdstevel@tonic-gate	/* Adding a definition */
7257c478bdstevel@tonic-gate	if (!found && (string != (char *)NULL)) {
7267c478bdstevel@tonic-gate		/* Allocate space for the severity structure */
7277c478bdstevel@tonic-gate		if ((p = libc_malloc(sizeof (struct sevstr))) == NULL) {
7287c478bdstevel@tonic-gate			lmutex_unlock(&fmt_lock);
7297c478bdstevel@tonic-gate			return (-1);
7307c478bdstevel@tonic-gate		}
7317c478bdstevel@tonic-gate
7327c478bdstevel@tonic-gate		/*
7337c478bdstevel@tonic-gate		 * Fill in the new structure with the data supplied and add to
7347c478bdstevel@tonic-gate		 * the head of the augmented severity list.
7357c478bdstevel@tonic-gate		 */
7367c478bdstevel@tonic-gate
7377c478bdstevel@tonic-gate		p->sevkywd = (char *)NULL;
7387c478bdstevel@tonic-gate		p->sevprstr = string;
7397c478bdstevel@tonic-gate		p->sevvalue = value;
7407c478bdstevel@tonic-gate		p->sevnext = paugsevs;
7417c478bdstevel@tonic-gate		paugsevs = p;
7427c478bdstevel@tonic-gate
7437c478bdstevel@tonic-gate		/* Successfully added a new severity */
7447c478bdstevel@tonic-gate		rtnval = 0;
7457c478bdstevel@tonic-gate	} else if (string == (char *)NULL) {
7467c478bdstevel@tonic-gate		/* Attempting to undefined a non-defined severity */
7477c478bdstevel@tonic-gate		rtnval = -1;
7487c478bdstevel@tonic-gate		errno = EINVAL;
7497c478bdstevel@tonic-gate	} else {
7507c478bdstevel@tonic-gate		/* Successfully redefined a severity */
7517c478bdstevel@tonic-gate		rtnval = 0;
7527c478bdstevel@tonic-gate	}
7537c478bdstevel@tonic-gate	/* Finished, successful */
7547c478bdstevel@tonic-gate	lmutex_unlock(&fmt_lock);
7557c478bdstevel@tonic-gate	return (rtnval);
7567c478bdstevel@tonic-gate}
7577c478bdstevel@tonic-gate
7587c478bdstevel@tonic-gate/*
7597c478bdstevel@tonic-gate * Utility function for converting an integer to a string, avoiding stdio.
7607c478bdstevel@tonic-gate */
7617c478bdstevel@tonic-gatestatic void
7627c478bdstevel@tonic-gateitoa(int n, char *s)
7637c478bdstevel@tonic-gate{
7647c478bdstevel@tonic-gate	char buf[12];		/* 32 bits fits in 10 decimal digits */
7657c478bdstevel@tonic-gate	char *cp = buf;
7667c478bdstevel@tonic-gate	uint_t un = (n < 0)? -n : n;
7677c478bdstevel@tonic-gate
7687c478bdstevel@tonic-gate	do {
7697c478bdstevel@tonic-gate		*cp++ = "0123456789"[un % 10];
7707c478bdstevel@tonic-gate		un /= 10;
7717c478bdstevel@tonic-gate	} while (un);
7727c478bdstevel@tonic-gate
7737c478bdstevel@tonic-gate	if (n < 0)
7747c478bdstevel@tonic-gate		*s++ = '-';
7757c478bdstevel@tonic-gate
7767c478bdstevel@tonic-gate	do {
7777c478bdstevel@tonic-gate		*s++ = *--cp;
7787c478bdstevel@tonic-gate	} while (cp > buf);
7797c478bdstevel@tonic-gate
7807c478bdstevel@tonic-gate	*s = '\0';
7817c478bdstevel@tonic-gate}
7827c478bdstevel@tonic-gate
7837c478bdstevel@tonic-gate/*
7847c478bdstevel@tonic-gate * void writemsg(buf, size, verbosity, label, severity, text, action, tag)
7857c478bdstevel@tonic-gate *
7867c478bdstevel@tonic-gate * Arguments:
7877c478bdstevel@tonic-gate *	char	*buf		The buffer in which to format the message
7887c478bdstevel@tonic-gate *	size_t	size		The size of the buffer
7897c478bdstevel@tonic-gate * 	int	verbosity	A bit-string that indicates which components
7907c478bdstevel@tonic-gate *				are to be written
7917c478bdstevel@tonic-gate * 	const char   *label	The address of the label-component
7927c478bdstevel@tonic-gate * 	int	severity	The severity value of the message
7937c478bdstevel@tonic-gate * 	const char   *text	The address of the text-component
7947c478bdstevel@tonic-gate * 	const char   *action	The address of the action-component
7957c478bdstevel@tonic-gate * 	const char   *tag	The address of the tag-component
7967c478bdstevel@tonic-gate *
7977c478bdstevel@tonic-gate *	This function formats the message consisting of the label-component,
7987c478bdstevel@tonic-gate *	severity-component, text-component, action-component, and tag-
7997c478bdstevel@tonic-gate *	component into the provided buffer.  The "verbosity" argument
8007c478bdstevel@tonic-gate *	tells which components can be selected.  Any or all of the
8017c478bdstevel@tonic-gate *	components can be their null-values.
8027c478bdstevel@tonic-gate *
8037c478bdstevel@tonic-gate * Returns:  void
8047c478bdstevel@tonic-gate *
8057c478bdstevel@tonic-gate * Notes:
8067c478bdstevel@tonic-gate */
8077c478bdstevel@tonic-gate
8087c478bdstevel@tonic-gatestatic void
8097c478bdstevel@tonic-gatewritemsg(char *buf, size_t size,
8107c478bdstevel@tonic-gate	int verbosity, const char *label, int severity,
8117c478bdstevel@tonic-gate	const char *text, const char *action, const char *tag)
8127c478bdstevel@tonic-gate{
8137c478bdstevel@tonic-gate	struct sevstr  *psev;		/* Ptr for severity str list */
8147c478bdstevel@tonic-gate	char		*p;		/* General purpose pointer */
8157c478bdstevel@tonic-gate	char		*sevpstr = NULL;  /* Pointer to severity string */
8167c478bdstevel@tonic-gate	int		l1indent;	/* # chars to indent line 1 */
8177c478bdstevel@tonic-gate	int		l2indent;	/* # chars to indent line 2 */
8187c478bdstevel@tonic-gate	int		textindent;	/* # spaces to indent text */
8197c478bdstevel@tonic-gate	int		actindent = 0;	/* # spaces to indent action */
8207c478bdstevel@tonic-gate	int		i;		/* General purpose counter */
8217c478bdstevel@tonic-gate	int		dolabel;	/* TRUE if label to be written */
8227c478bdstevel@tonic-gate	int		dotext;		/* TRUE if text to be written */
8237c478bdstevel@tonic-gate	int		dosev;		/* TRUE if severity to be written */
8247c478bdstevel@tonic-gate	int		doaction;	/* TRUE if action to be written */
8257c478bdstevel@tonic-gate	int		dotag;		/* TRUE if tag to be written */
8267c478bdstevel@tonic-gate	char		c;		/* Temp, multiuse character */
8277c478bdstevel@tonic-gate	char		sevpstrbuf[15];	/* Space for SV=%d */
8287c478bdstevel@tonic-gate
8297c478bdstevel@tonic-gate	char		lcllbl[MM_MXLABELLN+1];	/* Space for (possibly */
8307c478bdstevel@tonic-gate						/* truncated) label */
8317c478bdstevel@tonic-gate	char		lcltag[MM_MXTAGLN+1];	/* Space for (possibly */
8327c478bdstevel@tonic-gate						/* truncated) tag */
8337c478bdstevel@tonic-gate	char		*ebuf = buf + size - 2;
8347c478bdstevel@tonic-gate
8357c478bdstevel@tonic-gate	/*
8367c478bdstevel@tonic-gate	 * initialize variables.
8377c478bdstevel@tonic-gate	 */
8387c478bdstevel@tonic-gate	sevpstrbuf[0] = (char)0;
8397c478bdstevel@tonic-gate	lcllbl[0] = (char)0;
8407c478bdstevel@tonic-gate	lcltag[0] = (char)0;
8417c478bdstevel@tonic-gate
8427c478bdstevel@tonic-gate	/*
8437c478bdstevel@tonic-gate	 * Figure out what fields are to be written (all are optional)
8447c478bdstevel@tonic-gate	 */
8457c478bdstevel@tonic-gate
8467c478bdstevel@tonic-gate	dolabel  = (verbosity & MV_LBL) && (label != MM_NULLLBL);
8477c478bdstevel@tonic-gate	dosev    = (verbosity & MV_SEV) && (severity != MM_NULLSEV);
8487c478bdstevel@tonic-gate	dotext   = (verbosity & MV_TXT) && (text != MM_NULLTXT);
8497c478bdstevel@tonic-gate	doaction = (verbosity & MV_ACT) && (action != MM_NULLACT);
8507c478bdstevel@tonic-gate	dotag    = (verbosity & MV_TAG) && (tag != MM_NULLTAG);
8517c478bdstevel@tonic-gate
8527c478bdstevel@tonic-gate	/*
8537c478bdstevel@tonic-gate	 * Figure out how much we'll need to indent the text of the message
8547c478bdstevel@tonic-gate	 */
8557c478bdstevel@tonic-gate
8567c478bdstevel@tonic-gate	/* Count the label of the message, if requested */
8577c478bdstevel@tonic-gate	textindent = 0;
8587c478bdstevel@tonic-gate	if (dolabel) {
8597c478bdstevel@tonic-gate		(void) strncpy(lcllbl, label, (size_t)MM_MXLABELLN);
8607c478bdstevel@tonic-gate		lcllbl[MM_MXLABELLN] = '\0';
8617c478bdstevel@tonic-gate		textindent = (int)strlen(lcllbl) + SEPSTRLN;
8627c478bdstevel@tonic-gate	}
8637c478bdstevel@tonic-gate
8647c478bdstevel@tonic-gate	/*
8657c478bdstevel@tonic-gate	 * If severity req'd, determine the severity string and factor
8667c478bdstevel@tonic-gate	 * into indent count.  Severity string generated by:
8677c478bdstevel@tonic-gate	 *	1.  Search the standard list of severities.
8687c478bdstevel@tonic-gate	 *	2.  Search the severities added by the application.
8697c478bdstevel@tonic-gate	 *	3.  Search the severities added by the environment.
8707c478bdstevel@tonic-gate	 *	4.  Use the default (SV=n where n is the value of the severity).
8717c478bdstevel@tonic-gate	 */
8727c478bdstevel@tonic-gate
8737c478bdstevel@tonic-gate	if (dosev) {
8747c478bdstevel@tonic-gate		/* Search the default severity definitions */
8757c478bdstevel@tonic-gate		psev = pstdsevs;
8767c478bdstevel@tonic-gate		while (psev != (struct sevstr *)NULL) {
8777c478bdstevel@tonic-gate			if (psev->sevvalue == severity)
8787c478bdstevel@tonic-gate				break;
8797c478bdstevel@tonic-gate			psev = psev->sevnext;
8807c478bdstevel@tonic-gate		}
8817c478bdstevel@tonic-gate
8827c478bdstevel@tonic-gate		if (psev == (struct sevstr *)NULL) {
8837c478bdstevel@tonic-gate			/*
8847c478bdstevel@tonic-gate			 * Search the severity definitions
8857c478bdstevel@tonic-gate			 * added by the application
8867c478bdstevel@tonic-gate			 */
8877c478bdstevel@tonic-gate			psev = paugsevs;
8887c478bdstevel@tonic-gate			while (psev != (struct sevstr *)NULL) {
8897c478bdstevel@tonic-gate				if (psev->sevvalue == severity)
8907c478bdstevel@tonic-gate					break;
8917c478bdstevel@tonic-gate				psev = psev->sevnext;
8927c478bdstevel@tonic-gate			}
8937c478bdstevel@tonic-gate			if (psev == (struct sevstr *)NULL) {
8947c478bdstevel@tonic-gate				/*
8957c478bdstevel@tonic-gate				 * Search the severity definitions
8967c478bdstevel@tonic-gate				 * added by the environment
8977c478bdstevel@tonic-gate				 */
8987c478bdstevel@tonic-gate				psev = penvsevs;
8997c478bdstevel@tonic-gate				while (psev != (struct sevstr *)NULL) {
9007c478bdstevel@tonic-gate					if (psev->sevvalue == severity)
9017c478bdstevel@tonic-gate						break;
9027c478bdstevel@tonic-gate					psev = psev->sevnext;
9037c478bdstevel@tonic-gate				}
9047c478bdstevel@tonic-gate				if (psev == (struct sevstr *)NULL) {
9057c478bdstevel@tonic-gate					/* Use default string, SV=severity */
9067c478bdstevel@tonic-gate					(void) strcpy(sevpstrbuf, "SV=");
9077c478bdstevel@tonic-gate					itoa(severity, &sevpstrbuf[3]);
9087c478bdstevel@tonic-gate					sevpstr = sevpstrbuf;
9097c478bdstevel@tonic-gate				} else {
9107c478bdstevel@tonic-gate					sevpstr = (char *)psev->sevprstr;
9117c478bdstevel@tonic-gate				}
9127c478bdstevel@tonic-gate			} else {
9137c478bdstevel@tonic-gate				sevpstr = (char *)psev->sevprstr;
9147c478bdstevel@tonic-gate			}
9157c478bdstevel@tonic-gate		} else {
9167c478bdstevel@tonic-gate			sevpstr = (char *)psev->sevprstr;
9177c478bdstevel@tonic-gate		}
9187c478bdstevel@tonic-gate		/* Factor into indent counts */
9197c478bdstevel@tonic-gate		textindent += (int)strlen(sevpstr) + SEPSTRLN;
9207c478bdstevel@tonic-gate	}
9217c478bdstevel@tonic-gate
9227c478bdstevel@tonic-gate	/*
9237c478bdstevel@tonic-gate	 * Figure out the indents.
9247c478bdstevel@tonic-gate	 */
9257c478bdstevel@tonic-gate
9267c478bdstevel@tonic-gate	if (doaction && dotext) {
9277c478bdstevel@tonic-gate		if (textindent > ACTINTROLN) {
9287c478bdstevel@tonic-gate			l1indent = 0;
9297c478bdstevel@tonic-gate			l2indent = textindent - ACTINTROLN;
9307c478bdstevel@tonic-gate			actindent = textindent;
9317c478bdstevel@tonic-gate		} else {
9327c478bdstevel@tonic-gate			l2indent = 0;
9337c478bdstevel@tonic-gate			actindent = ACTINTROLN;
9347c478bdstevel@tonic-gate			if (dosev || dolabel) {
9357c478bdstevel@tonic-gate				l1indent = ACTINTROLN - textindent;
9367c478bdstevel@tonic-gate				textindent = ACTINTROLN;
9377c478bdstevel@tonic-gate			} else {
9387c478bdstevel@tonic-gate				textindent = 0;
9397c478bdstevel@tonic-gate				l1indent = 0;
9407c478bdstevel@tonic-gate			}
9417c478bdstevel@tonic-gate		}
9427c478bdstevel@tonic-gate	} else {
9437c478bdstevel@tonic-gate		l1indent = 0;
9447c478bdstevel@tonic-gate		l2indent = 0;
9457c478bdstevel@tonic-gate		if (doaction) {
9467c478bdstevel@tonic-gate			actindent = textindent + ACTINTROLN;
9477c478bdstevel@tonic-gate		} else if (dotext) {
9487c478bdstevel@tonic-gate			actindent = 0;
9497c478bdstevel@tonic-gate		}
9507c478bdstevel@tonic-gate	}
9517c478bdstevel@tonic-gate
9527c478bdstevel@tonic-gate	/*
9537c478bdstevel@tonic-gate	 * Write the message.
9547c478bdstevel@tonic-gate	 */
9557c478bdstevel@tonic-gate
9567c478bdstevel@tonic-gate	/* Write the LABEL, if requested */
9577c478bdstevel@tonic-gate	if (dolabel) {
9587c478bdstevel@tonic-gate		/* Write spaces to align on the ':' char, if needed */
9597c478bdstevel@tonic-gate		while (--l1indent >= 0 && buf < ebuf)
9607c478bdstevel@tonic-gate			*buf++ = ' ';
9617c478bdstevel@tonic-gate
9627c478bdstevel@tonic-gate		/* Write the label */
9637c478bdstevel@tonic-gate		buf += strlcpy(buf, lcllbl, ebuf - buf);
9647c478bdstevel@tonic-gate
9657c478bdstevel@tonic-gate		/*
9667c478bdstevel@tonic-gate		 * Write the separator string
9677c478bdstevel@tonic-gate		 * (if another component is to follow)
9687c478bdstevel@tonic-gate		 */
9697c478bdstevel@tonic-gate		if (dosev || dotext || doaction || dotag)
9707c478bdstevel@tonic-gate			buf += strlcpy(buf, SEPSTR, ebuf - buf);
9717c478bdstevel@tonic-gate	}
9727c478bdstevel@tonic-gate
9737c478bdstevel@tonic-gate	/* Write the SEVERITY, if requested */
9747c478bdstevel@tonic-gate	if (dosev) {
9757c478bdstevel@tonic-gate		/* Write spaces to align on the ':' char, if needed */
9767c478bdstevel@tonic-gate		while (--l1indent >= 0 && buf < ebuf)
9777c478bdstevel@tonic-gate			*buf++ = ' ';
9787c478bdstevel@tonic-gate
9797c478bdstevel@tonic-gate		/* Write the severity print-string */
9807c478bdstevel@tonic-gate		buf += strlcpy(buf, sevpstr, ebuf - buf);
9817c478bdstevel@tonic-gate
9827c478bdstevel@tonic-gate		/*
9837c478bdstevel@tonic-gate		 * Write the separator string
9847c478bdstevel@tonic-gate		 * (if another component is to follow)
9857c478bdstevel@tonic-gate		 */
9867c478bdstevel@tonic-gate		if (dotext || doaction || dotag)
9877c478bdstevel@tonic-gate			buf += strlcpy(buf, SEPSTR, ebuf - buf);
9887c478bdstevel@tonic-gate	}
9897c478bdstevel@tonic-gate
9907c478bdstevel@tonic-gate	/* Write the TEXT, if requested */
9917c478bdstevel@tonic-gate	if (dotext) {
9927c478bdstevel@tonic-gate		p = (char *)text;
993e86c3f0Toomas Soome		for (c = *p++; c != '\0' && buf < ebuf; c = *p++) {
9947c478bdstevel@tonic-gate			*buf++ = c;
9957c478bdstevel@tonic-gate			if (c == '\n') {
9967c478bdstevel@tonic-gate				for (i = 0; i < textindent && buf < ebuf; i++)
9977c478bdstevel@tonic-gate					*buf++ = ' ';
9987c478bdstevel@tonic-gate			}
9997c478bdstevel@tonic-gate		}
10007c478bdstevel@tonic-gate	}
10017c478bdstevel@tonic-gate
10027c478bdstevel@tonic-gate	/*
10037c478bdstevel@tonic-gate	 * Write ACTION if requested.
10047c478bdstevel@tonic-gate	 */
10057c478bdstevel@tonic-gate
10067c478bdstevel@tonic-gate	if (doaction) {
10077c478bdstevel@tonic-gate		if (dotext && buf < ebuf) {
10087c478bdstevel@tonic-gate			*buf++ = '\n';
10097c478bdstevel@tonic-gate			while (--l2indent >= 0 && buf < ebuf)
10107c478bdstevel@tonic-gate				*buf++ = ' ';
10117c478bdstevel@tonic-gate		}
10127c478bdstevel@tonic-gate
10137c478bdstevel@tonic-gate		/* Write the action-string's introduction */
10147c478bdstevel@tonic-gate		buf += strlcpy(buf, ACTINTRO, ebuf - buf);
10157c478bdstevel@tonic-gate
10167c478bdstevel@tonic-gate		/* Write the "action" string */
10177c478bdstevel@tonic-gate		p = (char *)action;
1018e86c3f0Toomas Soome		for (c = *p++; c != '\0' && buf < ebuf; c = *p++) {
10197c478bdstevel@tonic-gate			*buf++ = c;
10207c478bdstevel@tonic-gate			if (c == '\n') {
10217c478bdstevel@tonic-gate				for (i = 0; i < actindent && buf < ebuf; i++)
10227c478bdstevel@tonic-gate					*buf++ = ' ';
10237c478bdstevel@tonic-gate			}
10247c478bdstevel@tonic-gate		}
10257c478bdstevel@tonic-gate	}
10267c478bdstevel@tonic-gate
10277c478bdstevel@tonic-gate	/*
10287c478bdstevel@tonic-gate	 * Write the TAG if requested
10297c478bdstevel@tonic-gate	 */
10307c478bdstevel@tonic-gate
10317c478bdstevel@tonic-gate	if (dotag) {
10327c478bdstevel@tonic-gate		if (doaction)
10337c478bdstevel@tonic-gate			buf += strlcpy(buf, "  ", ebuf - buf);
10347c478bdstevel@tonic-gate		else if (dotext && buf < ebuf)
10357c478bdstevel@tonic-gate			*buf++ = '\n';
10367c478bdstevel@tonic-gate		(void) strncpy(lcltag, tag, (size_t)MM_MXTAGLN);
10377c478bdstevel@tonic-gate		lcltag[MM_MXTAGLN] = '\0';
10387c478bdstevel@tonic-gate		buf += strlcpy(buf, lcltag, ebuf - buf);
10397c478bdstevel@tonic-gate	}
10407c478bdstevel@tonic-gate
10417c478bdstevel@tonic-gate	/*
10427c478bdstevel@tonic-gate	 * Write terminating newline and null byte.
10437c478bdstevel@tonic-gate	 * We reserved space for these at the start.
10447c478bdstevel@tonic-gate	 */
10457c478bdstevel@tonic-gate	*buf++ = '\n';
10467c478bdstevel@tonic-gate	*buf++ = '\0';
10477c478bdstevel@tonic-gate}
10487c478bdstevel@tonic-gate
10497c478bdstevel@tonic-gate/*
10507c478bdstevel@tonic-gate * int	fmtmsg(class, label, severity, text, action, tag)
10517c478bdstevel@tonic-gate *	long	class
10527c478bdstevel@tonic-gate *	const char   *label
10537c478bdstevel@tonic-gate *	int	severity
10547c478bdstevel@tonic-gate *	const char   *text
10557c478bdstevel@tonic-gate *	const char   *action
10567c478bdstevel@tonic-gate *	const char   *tag
10577c478bdstevel@tonic-gate *
10587c478bdstevel@tonic-gate *	If requested, the fmtmsg() function writes a message to the standard
10597c478bdstevel@tonic-gate *      error stream in the standard message format.  Also if requested, it
10607c478bdstevel@tonic-gate *	will write a message to the system console.
10617c478bdstevel@tonic-gate *
10627c478bdstevel@tonic-gate *	Arguments:
10637c478bdstevel@tonic-gate *	    class	Fields which classify the message for the system
10647c478bdstevel@tonic-gate *			logging facility
10657c478bdstevel@tonic-gate *	    label	A character-string that is printed as the "label"
10667c478bdstevel@tonic-gate *			of the message.  Typically identifies the source
10677c478bdstevel@tonic-gate *			of the message
10687c478bdstevel@tonic-gate *	    severity	Identifies the severity of the message.  Either one
10697c478bdstevel@tonic-gate *			of the standard severities, or possibly one of the
10707c478bdstevel@tonic-gate *			augmented severities
10717c478bdstevel@tonic-gate *	    text	Pointer to the text of the message
10727c478bdstevel@tonic-gate *	    action	Pointer to a char string that describes some type
10737c478bdstevel@tonic-gate *			of corrective action.
10747c478bdstevel@tonic-gate *	    tag		A character-string that is printed as the "tag" or
10757c478bdstevel@tonic-gate *			the message.  Typically a pointer to documentation
10767c478bdstevel@tonic-gate *
10777c478bdstevel@tonic-gate *	Returns:
10787c478bdstevel@tonic-gate *	    -1 if nothing was generated, 0 if everything requested was
10797c478bdstevel@tonic-gate *	    generated, or flags if partially generated.
10807c478bdstevel@tonic-gate *
10817c478bdstevel@tonic-gate *	Needs:
10827c478bdstevel@tonic-gate *	  - Nothing special for 4.0.
10837c478bdstevel@tonic-gate */
10847c478bdstevel@tonic-gate
10857c478bdstevel@tonic-gateint
10867c478bdstevel@tonic-gatefmtmsg(long class, const char *label, int severity,
10877c478bdstevel@tonic-gateconst char *text, const char *action, const char *tag)
10887c478bdstevel@tonic-gate{
10897c478bdstevel@tonic-gate	int	rtnval;		/* Value to return */
10907c478bdstevel@tonic-gate	FILE	*console;	/* Ptr to "console" stream */
10917c478bdstevel@tonic-gate	char	*message1;
10927c478bdstevel@tonic-gate	char	*message2;
10937c478bdstevel@tonic-gate
10947c478bdstevel@tonic-gate	/*
10957c478bdstevel@tonic-gate	 * Determine the "verbosity" of the message.  If "msgverb" is
10967c478bdstevel@tonic-gate	 * already set, don't interrogate the "MSGVERB" environment vbl.
10977c478bdstevel@tonic-gate	 * If so, interrogate "MSGVERB" and do initialization stuff also.
10987c478bdstevel@tonic-gate	 */
10997c478bdstevel@tonic-gate
11007c478bdstevel@tonic-gate	lmutex_lock(&fmt_lock);
11017c478bdstevel@tonic-gate
11027c478bdstevel@tonic-gate	if (!(msgverb & MV_SET)) {
11037c478bdstevel@tonic-gate		msgverbset();
11047c478bdstevel@tonic-gate		msgverb |= MV_SET;
11057c478bdstevel@tonic-gate	}
11067c478bdstevel@tonic-gate
11077c478bdstevel@tonic-gate
11087c478bdstevel@tonic-gate	/*
11097c478bdstevel@tonic-gate	 * Extract the severity definitions from the SEV_LEVEL
11107c478bdstevel@tonic-gate	 * environment variable and save away for later.
11117c478bdstevel@tonic-gate	 */
11127c478bdstevel@tonic-gate
11137c478bdstevel@tonic-gate	if (sevlook) {
11147c478bdstevel@tonic-gate		sevstrset();
11157c478bdstevel@tonic-gate		sevlook = FALSE;
11167c478bdstevel@tonic-gate	}
11177c478bdstevel@tonic-gate
11187c478bdstevel@tonic-gate
11197c478bdstevel@tonic-gate	/* Set up the default text component [if text==(char *)NULL] */
11207c478bdstevel@tonic-gate	if (text == (char *)NULL)
11217c478bdstevel@tonic-gate		text = DEFLT_TEXT;
11227c478bdstevel@tonic-gate
11237c478bdstevel@tonic-gate	/* Prepare the message for stderr if requested */
11247c478bdstevel@tonic-gate	if (class & MM_PRINT) {
11257c478bdstevel@tonic-gate		message1 = alloca(MAX_MSG_SIZE);
11267c478bdstevel@tonic-gate		writemsg(message1, MAX_MSG_SIZE,
11277c478bdstevel@tonic-gate		    msgverb, label, severity, text, action, tag);
11287c478bdstevel@tonic-gate	}
11297c478bdstevel@tonic-gate
11307c478bdstevel@tonic-gate	/* Prepare the message for the console if requested */
11317c478bdstevel@tonic-gate	if (class & MM_CONSOLE) {
11327c478bdstevel@tonic-gate		message2 = alloca(MAX_MSG_SIZE);
11337c478bdstevel@tonic-gate		writemsg(message2, MAX_MSG_SIZE,
11347c478bdstevel@tonic-gate		    MV_ALL, label, severity, text, action, tag);
11357c478bdstevel@tonic-gate	}
11367c478bdstevel@tonic-gate
11377c478bdstevel@tonic-gate	lmutex_unlock(&fmt_lock);
11387c478bdstevel@tonic-gate
11397c478bdstevel@tonic-gate	rtnval = MM_OK;
11407c478bdstevel@tonic-gate
11417c478bdstevel@tonic-gate	/* Write the message to stderr if requested */
11427c478bdstevel@tonic-gate	if (class & MM_PRINT) {
11437c478bdstevel@tonic-gate		clearerr(stderr);
11447c478bdstevel@tonic-gate		(void) fputs(message1, stderr);
11457c478bdstevel@tonic-gate		if (ferror(stderr))
11467c478bdstevel@tonic-gate			rtnval |= MM_NOMSG;
11477c478bdstevel@tonic-gate	}
11487c478bdstevel@tonic-gate
11497c478bdstevel@tonic-gate	/* Write the message to the console if requested */
11507c478bdstevel@tonic-gate	if (class & MM_CONSOLE) {
1151004388ecasper		if ((console = fopen(CONNAME, "wF")) != NULL) {
11527c478bdstevel@tonic-gate			clearerr(console);
11537c478bdstevel@tonic-gate			(void) fputs(message2, console);
11547c478bdstevel@tonic-gate			if (ferror(console))
11557c478bdstevel@tonic-gate				rtnval |= MM_NOCON;
11567c478bdstevel@tonic-gate			(void) fclose(console);
11577c478bdstevel@tonic-gate		} else {
11587c478bdstevel@tonic-gate			rtnval |= MM_NOCON;
11597c478bdstevel@tonic-gate		}
11607c478bdstevel@tonic-gate	}
11617c478bdstevel@tonic-gate
11627c478bdstevel@tonic-gate	if ((rtnval & (MM_NOCON | MM_NOMSG)) == (MM_NOCON | MM_NOMSG))
11637c478bdstevel@tonic-gate		rtnval = MM_NOTOK;
11647c478bdstevel@tonic-gate	return (rtnval);
11657c478bdstevel@tonic-gate}
1166