xref: /onnv-gate/usr/src/lib/libast/common/comp/fmtmsglib.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin  * fmtmsg implementation
254887Schin  */
264887Schin 
274887Schin #include <ast.h>
284887Schin 
294887Schin #if _lib_fmtmsg
304887Schin 
314887Schin NoN(fmtmsg)
324887Schin 
334887Schin #else
344887Schin 
354887Schin #define MM_TABLES
364887Schin 
374887Schin #include <fmtmsg.h>
384887Schin 
394887Schin #define INIT_VERB	0x1
404887Schin #define INIT_CONSOLE	0x2
414887Schin 
424887Schin static struct
434887Schin {
444887Schin 	int		console;
454887Schin 	unsigned int	init;
464887Schin 	unsigned int	mask;
474887Schin } mm;
484887Schin 
494887Schin const MM_table_t	mm_class[] =
504887Schin {
514887Schin 	"null",		0,		0,
524887Schin 	"hard",		"HARDWARE",	MM_HARD,
534887Schin 	"soft",		"SOFTWARE",	MM_SOFT,
544887Schin 	"firm",		"FIRMWARE",	MM_FIRM,
554887Schin 	"appl",		"APPLICATION",	MM_APPL,
564887Schin 	"util",		"UTILITY",	MM_UTIL,
574887Schin 	"opsys",	"KERNEL",	MM_OPSYS,
584887Schin 	"print",	0,		MM_PRINT,
594887Schin 	"console",	0,		MM_CONSOLE,
604887Schin 	"recov",	"RECOVERABLE",	MM_RECOVER,
614887Schin 	"nrecov",	"PANIC",	MM_NRECOV,
624887Schin 	0,		0,		0
634887Schin };
644887Schin 
654887Schin static const MM_table_t	mm_severity_init[] =
664887Schin {
674887Schin 	"nosev",	0,		MM_NOSEV,
684887Schin 	"halt",		"HALT",		MM_HALT,
694887Schin 	"error",	"ERROR",	MM_ERROR,
704887Schin 	"warn",		"WARNING",	MM_WARNING,
714887Schin 	"info",		"INFO",		MM_INFO,
724887Schin 	0,		0,		0
734887Schin };
744887Schin 
754887Schin const MM_table_t	mm_verb[] =
764887Schin {
774887Schin 	"all",		0,		MM_all,
784887Schin 	"action",	0,		MM_action,
794887Schin 	"class",	0,		MM_class,
804887Schin 	"default",	0,		MM_default,
814887Schin 	"label",	0,		MM_label,
824887Schin 	"severity",	0,		MM_severity,
834887Schin 	"source",	0,		MM_source,
844887Schin 	"tag",		0,		MM_tag,
854887Schin 	"text",		0,		MM_text,
864887Schin 	0,		0,		0
874887Schin };
884887Schin 
894887Schin const MM_table_t*
904887Schin _mm_severity(void)
914887Schin {
924887Schin 	static MM_table_t*	severity;
934887Schin 
944887Schin 	if (!severity)
954887Schin 	{
964887Schin 		register char*		s;
974887Schin 		register MM_table_t*	p;
984887Schin 		register int		n;
994887Schin 		register int		c;
1004887Schin 		char*			e;
1014887Schin 		MM_table_t*		q;
1024887Schin 
1034887Schin 		n = 0;
1044887Schin 		if ((s = getenv(MM_SEVERITY_ENV)) && *s)
1054887Schin 		{
1064887Schin 			e = s;
1074887Schin 			c = 0;
1084887Schin 			for (;;)
1094887Schin 			{
1104887Schin 				switch (*s++)
1114887Schin 				{
1124887Schin 				case 0:
1134887Schin 					break;
1144887Schin 				case ',':
1154887Schin 					if (++c > 2)
1164887Schin 					{
1174887Schin 						n = 0;
1184887Schin 						break;
1194887Schin 					}
1204887Schin 					continue;
1214887Schin 				case ':':
1224887Schin 					if (c != 2)
1234887Schin 					{
1244887Schin 						n = 0;
1254887Schin 						break;
1264887Schin 					}
1274887Schin 					c = 0;
1284887Schin 					n++;
1294887Schin 					continue;
1304887Schin 				default:
1314887Schin 					continue;
1324887Schin 				}
1334887Schin 				break;
1344887Schin 			}
1354887Schin 			if (c == 2)
1364887Schin 				n++;
1374887Schin 			else n = 0;
1384887Schin 			if (n)
1394887Schin 			{
1404887Schin 				for (p = (MM_table_t*)mm_severity_init; p->name; p++);
1414887Schin 				n += p - (MM_table_t*)mm_severity_init + 1;
1424887Schin 				if (severity = newof(0, MM_table_t, n, s - e))
1434887Schin 				{
1444887Schin 					s = (char*)severity + n * sizeof(MM_table_t);
1454887Schin 					strcpy(s, e);
1464887Schin 					p = severity;
1474887Schin 					for (q = (MM_table_t*)mm_severity_init; q->name; q++)
1484887Schin 						*p++ = *q;
1494887Schin 					p->name = s;
1504887Schin 					c = 0;
1514887Schin 					for (;;)
1524887Schin 					{
1534887Schin 						switch (*s++)
1544887Schin 						{
1554887Schin 						case 0:
1564887Schin 							break;
1574887Schin 						case ',':
1584887Schin 							switch (c++)
1594887Schin 							{
1604887Schin 							case 0:
1614887Schin 								*(s - 1) = 0;
1624887Schin 								p->value = strtol(s, NiL, 0);
1634887Schin 								break;
1644887Schin 							case 1:
1654887Schin 								p->display = s;
1664887Schin 								break;
1674887Schin 							}
1684887Schin 							continue;
1694887Schin 						case ':':
1704887Schin 							c = 0;
1714887Schin 							*(s - 1) = 0;
1724887Schin 							(++p)->name = s;
1734887Schin 							continue;
1744887Schin 						default:
1754887Schin 							continue;
1764887Schin 						}
1774887Schin 						break;
1784887Schin 					}
1794887Schin 				}
1804887Schin 			}
1814887Schin 		}
1824887Schin 		if (!severity)
1834887Schin 			severity = (MM_table_t*)mm_severity_init;
1844887Schin 	}
1854887Schin 	return (const MM_table_t*)severity;
1864887Schin }
1874887Schin 
1884887Schin static char*
1894887Schin display(register const MM_table_t* tab, int value, int mask)
1904887Schin {
1914887Schin 	while (tab->name)
1924887Schin 	{
1934887Schin 		if (value == tab->value || mask && (value & tab->value))
1944887Schin 			return (char*)tab->display;
1954887Schin 		tab++;
1964887Schin 	}
1974887Schin 	return 0;
1984887Schin }
1994887Schin 
2004887Schin int
2014887Schin fmtmsg(long classification, const char* label, int severity, const char* text, const char* action, const char* tag)
2024887Schin {
2034887Schin 	register int		c;
2044887Schin 	register char*		s;
2054887Schin 	register char*		t;
2064887Schin 	register MM_table_t*	p;
2074887Schin 	int			n;
2084887Schin 	int			m;
2094887Schin 	int			r;
2104887Schin 	int			fd;
2114887Schin 	unsigned int		mask;
2124887Schin 	Sfio_t*			sp;
2134887Schin 	char			lab[MM_LABEL_1_MAX + MM_LABEL_2_MAX + 3];
2144887Schin 
2154887Schin 	if (!mm.init)
2164887Schin 	{
2174887Schin 		mm.init = INIT_VERB;
2184887Schin 		if (!(s = getenv(MM_VERB_ENV)))
2194887Schin 			mm.mask = MM_default;
2204887Schin 		else for (;;)
2214887Schin 		{
2224887Schin 			if (t = strchr(s, ':'))
2234887Schin 				*t = 0;
2244887Schin 			if (!(p = (MM_table_t*)strlook(mm_verb, sizeof(MM_table_t), s)))
2254887Schin 			{
2264887Schin 				mm.mask = MM_default;
2274887Schin 				if (t)
2284887Schin 					*t = ':';
2294887Schin 				break;
2304887Schin 			}
2314887Schin 			mm.mask |= p->value;
2324887Schin 			if (!t)
2334887Schin 				break;
2344887Schin 			*t++ = ':';
2354887Schin 			s = t;
2364887Schin 		}
2374887Schin 	}
2384887Schin 	if (!(classification & (MM_CONSOLE|MM_PRINT)))
2394887Schin 		return 0;
2404887Schin 	if (!(sp = sfstropen()))
2414887Schin 		return MM_NOTOK;
2424887Schin 	r = 0;
2434887Schin 	if (s = (char*)label)
2444887Schin 	{
2454887Schin 		if (t = strchr(s, ':'))
2464887Schin 		{
2474887Schin 			if ((n = t - s) > MM_LABEL_1_MAX)
2484887Schin 				n = MM_LABEL_1_MAX;
2494887Schin 			sfprintf(sp, "%*.*s:", n, n, s);
2504887Schin 			s = ++t;
2514887Schin 			if ((n = strlen(t)) > MM_LABEL_2_MAX)
2524887Schin 				n = MM_LABEL_2_MAX;
2534887Schin 			sfprintf(sp, "%*.*s", n, n, s);
2544887Schin 		}
2554887Schin 		else
2564887Schin 		{
2574887Schin 			if ((n = strlen(t)) > MM_LABEL_1_MAX)
2584887Schin 				n = MM_LABEL_1_MAX;
2594887Schin 			sfprintf(sp, "%*.*s", n, n, s);
2604887Schin 		}
2614887Schin 		if (!(s = sfstruse(sp)))
2624887Schin 		{
2634887Schin 			sfstrclose(sp);
2644887Schin 			return MM_NOTOK;
2654887Schin 		}
2664887Schin 		strcpy(lab, s);
2674887Schin 	}
2684887Schin 	for (;;)
2694887Schin 	{
2704887Schin 		if (classification & MM_CONSOLE)
2714887Schin 		{
2724887Schin 			classification &= ~MM_CONSOLE;
2734887Schin 			if (!(mm.init & INIT_CONSOLE))
2744887Schin 				mm.console = open("/dev/console", O_WRONLY|O_APPEND|O_NOCTTY);
2754887Schin 			if (mm.console < 0)
2764887Schin 			{
2774887Schin 				r |= MM_NOCON;
2784887Schin 				continue;
2794887Schin 			}
2804887Schin 			c = MM_NOCON;
2814887Schin 			fd = mm.console;
2824887Schin 			mask = MM_all;
2834887Schin 		}
2844887Schin 		else if (classification & MM_PRINT)
2854887Schin 		{
2864887Schin 			classification &= ~MM_PRINT;
2874887Schin 			c = MM_NOMSG;
2884887Schin 			fd = 2;
2894887Schin 			mask = mm.mask;
2904887Schin 		}
2914887Schin 		else break;
2924887Schin 		if ((mask & MM_label) && label)
2934887Schin 			sfprintf(sp, "%s: ", lab);
2944887Schin 		if ((mask & MM_severity) && (s = display(mm_severity, severity, 0)))
2954887Schin 			sfprintf(sp, "%s: ", s);
2964887Schin 		n = sfstrtell(sp);
2974887Schin 		if ((mask & MM_text) && text)
2984887Schin 			sfprintf(sp, "%s\n", text);
2994887Schin 		else sfputc(sp, '\n');
3004887Schin 		if ((mask & MM_action) && action || (mask & MM_tag) && (label || tag))
3014887Schin 		{
3024887Schin 			if (fd != mm.console && (n -= 8) > 0)
3034887Schin 				sfprintf(sp, "%*.*s", n, n, "");
3044887Schin 			sfprintf(sp, "TO FIX:");
3054887Schin 			if ((mask & MM_action) && action)
3064887Schin 				sfprintf(sp, " %s", action);
3074887Schin 			if ((mask & MM_tag) && (label || tag))
3084887Schin 			{
3094887Schin 				sfprintf(sp, "  ");
3104887Schin 				if (!tag || label && !strchr(tag, ':'))
3114887Schin 					sfprintf(sp, "%s%s", lab, tag ? ":" : "");
3124887Schin 				if (tag)
3134887Schin 					sfprintf(sp, "%s", tag);
3144887Schin 			}
3154887Schin 			if (mask & (MM_class|MM_source|MM_status))
3164887Schin 			{
3174887Schin 				sfputc(sp, ' ');
3184887Schin 				if ((mask & MM_source) && (m = classification & (MM_APPL|MM_UTIL|MM_OPSYS)) && (s = display(mm_class, m, 1)))
3194887Schin 					sfprintf(sp, " %s", s);
3204887Schin 				if ((mask & MM_class) && (m = classification & (MM_HARD|MM_SOFT|MM_FIRM)) && (s = display(mm_class, m, 1)))
3214887Schin 					sfprintf(sp, " %s", s);
3224887Schin 				if ((mask & MM_status) && (m = classification & (MM_RECOVER|MM_NRECOV)) && (s = display(mm_class, m, 1)))
3234887Schin 					sfprintf(sp, " %s", s);
3244887Schin 			}
3254887Schin 			sfputc(sp, '\n');
3264887Schin 		}
3274887Schin 		n = sfstrtell(sp);
3284887Schin 		if (!(s = sfstruse(sp)) || write(fd, s, n) != n)
3294887Schin 			r |= c;
3304887Schin 	}
3314887Schin 	sfstrclose(sp);
3324887Schin 	return r;
3334887Schin }
3344887Schin 
3354887Schin #endif
336