xref: /illumos-gate/usr/src/contrib/ast/src/lib/libast/comp/fmtmsglib.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
19*b30d1939SAndy Fiddaman *                   Phong Vo <kpv@research.att.com>                    *
20*b30d1939SAndy Fiddaman *                                                                      *
21*b30d1939SAndy Fiddaman ***********************************************************************/
22*b30d1939SAndy Fiddaman #pragma prototyped
23*b30d1939SAndy Fiddaman /*
24*b30d1939SAndy Fiddaman  * fmtmsg implementation
25*b30d1939SAndy Fiddaman  */
26*b30d1939SAndy Fiddaman 
27*b30d1939SAndy Fiddaman #include <ast.h>
28*b30d1939SAndy Fiddaman 
29*b30d1939SAndy Fiddaman #if _lib_fmtmsg
30*b30d1939SAndy Fiddaman 
31*b30d1939SAndy Fiddaman NoN(fmtmsg)
32*b30d1939SAndy Fiddaman 
33*b30d1939SAndy Fiddaman #else
34*b30d1939SAndy Fiddaman 
35*b30d1939SAndy Fiddaman #define MM_TABLES
36*b30d1939SAndy Fiddaman 
37*b30d1939SAndy Fiddaman #include <fmtmsg.h>
38*b30d1939SAndy Fiddaman 
39*b30d1939SAndy Fiddaman #define INIT_VERB	0x1
40*b30d1939SAndy Fiddaman #define INIT_CONSOLE	0x2
41*b30d1939SAndy Fiddaman 
42*b30d1939SAndy Fiddaman static struct
43*b30d1939SAndy Fiddaman {
44*b30d1939SAndy Fiddaman 	int		console;
45*b30d1939SAndy Fiddaman 	unsigned int	init;
46*b30d1939SAndy Fiddaman 	unsigned int	mask;
47*b30d1939SAndy Fiddaman } mm;
48*b30d1939SAndy Fiddaman 
49*b30d1939SAndy Fiddaman const MM_table_t	mm_class[] =
50*b30d1939SAndy Fiddaman {
51*b30d1939SAndy Fiddaman 	"null",		0,		0,
52*b30d1939SAndy Fiddaman 	"hard",		"HARDWARE",	MM_HARD,
53*b30d1939SAndy Fiddaman 	"soft",		"SOFTWARE",	MM_SOFT,
54*b30d1939SAndy Fiddaman 	"firm",		"FIRMWARE",	MM_FIRM,
55*b30d1939SAndy Fiddaman 	"appl",		"APPLICATION",	MM_APPL,
56*b30d1939SAndy Fiddaman 	"util",		"UTILITY",	MM_UTIL,
57*b30d1939SAndy Fiddaman 	"opsys",	"KERNEL",	MM_OPSYS,
58*b30d1939SAndy Fiddaman 	"print",	0,		MM_PRINT,
59*b30d1939SAndy Fiddaman 	"console",	0,		MM_CONSOLE,
60*b30d1939SAndy Fiddaman 	"recov",	"RECOVERABLE",	MM_RECOVER,
61*b30d1939SAndy Fiddaman 	"nrecov",	"PANIC",	MM_NRECOV,
62*b30d1939SAndy Fiddaman 	0,		0,		0
63*b30d1939SAndy Fiddaman };
64*b30d1939SAndy Fiddaman 
65*b30d1939SAndy Fiddaman static const MM_table_t	mm_severity_init[] =
66*b30d1939SAndy Fiddaman {
67*b30d1939SAndy Fiddaman 	"nosev",	0,		MM_NOSEV,
68*b30d1939SAndy Fiddaman 	"halt",		"HALT",		MM_HALT,
69*b30d1939SAndy Fiddaman 	"error",	"ERROR",	MM_ERROR,
70*b30d1939SAndy Fiddaman 	"warn",		"WARNING",	MM_WARNING,
71*b30d1939SAndy Fiddaman 	"info",		"INFO",		MM_INFO,
72*b30d1939SAndy Fiddaman 	0,		0,		0
73*b30d1939SAndy Fiddaman };
74*b30d1939SAndy Fiddaman 
75*b30d1939SAndy Fiddaman const MM_table_t	mm_verb[] =
76*b30d1939SAndy Fiddaman {
77*b30d1939SAndy Fiddaman 	"all",		0,		MM_all,
78*b30d1939SAndy Fiddaman 	"action",	0,		MM_action,
79*b30d1939SAndy Fiddaman 	"class",	0,		MM_class,
80*b30d1939SAndy Fiddaman 	"default",	0,		MM_default,
81*b30d1939SAndy Fiddaman 	"label",	0,		MM_label,
82*b30d1939SAndy Fiddaman 	"severity",	0,		MM_severity,
83*b30d1939SAndy Fiddaman 	"source",	0,		MM_source,
84*b30d1939SAndy Fiddaman 	"tag",		0,		MM_tag,
85*b30d1939SAndy Fiddaman 	"text",		0,		MM_text,
86*b30d1939SAndy Fiddaman 	0,		0,		0
87*b30d1939SAndy Fiddaman };
88*b30d1939SAndy Fiddaman 
89*b30d1939SAndy Fiddaman const MM_table_t*
90*b30d1939SAndy Fiddaman _mm_severity(void)
91*b30d1939SAndy Fiddaman {
92*b30d1939SAndy Fiddaman 	static MM_table_t*	severity;
93*b30d1939SAndy Fiddaman 
94*b30d1939SAndy Fiddaman 	if (!severity)
95*b30d1939SAndy Fiddaman 	{
96*b30d1939SAndy Fiddaman 		register char*		s;
97*b30d1939SAndy Fiddaman 		register MM_table_t*	p;
98*b30d1939SAndy Fiddaman 		register int		n;
99*b30d1939SAndy Fiddaman 		register int		c;
100*b30d1939SAndy Fiddaman 		char*			e;
101*b30d1939SAndy Fiddaman 		MM_table_t*		q;
102*b30d1939SAndy Fiddaman 
103*b30d1939SAndy Fiddaman 		n = 0;
104*b30d1939SAndy Fiddaman 		if ((s = getenv(MM_SEVERITY_ENV)) && *s)
105*b30d1939SAndy Fiddaman 		{
106*b30d1939SAndy Fiddaman 			e = s;
107*b30d1939SAndy Fiddaman 			c = 0;
108*b30d1939SAndy Fiddaman 			for (;;)
109*b30d1939SAndy Fiddaman 			{
110*b30d1939SAndy Fiddaman 				switch (*s++)
111*b30d1939SAndy Fiddaman 				{
112*b30d1939SAndy Fiddaman 				case 0:
113*b30d1939SAndy Fiddaman 					break;
114*b30d1939SAndy Fiddaman 				case ',':
115*b30d1939SAndy Fiddaman 					if (++c > 2)
116*b30d1939SAndy Fiddaman 					{
117*b30d1939SAndy Fiddaman 						n = 0;
118*b30d1939SAndy Fiddaman 						break;
119*b30d1939SAndy Fiddaman 					}
120*b30d1939SAndy Fiddaman 					continue;
121*b30d1939SAndy Fiddaman 				case ':':
122*b30d1939SAndy Fiddaman 					if (c != 2)
123*b30d1939SAndy Fiddaman 					{
124*b30d1939SAndy Fiddaman 						n = 0;
125*b30d1939SAndy Fiddaman 						break;
126*b30d1939SAndy Fiddaman 					}
127*b30d1939SAndy Fiddaman 					c = 0;
128*b30d1939SAndy Fiddaman 					n++;
129*b30d1939SAndy Fiddaman 					continue;
130*b30d1939SAndy Fiddaman 				default:
131*b30d1939SAndy Fiddaman 					continue;
132*b30d1939SAndy Fiddaman 				}
133*b30d1939SAndy Fiddaman 				break;
134*b30d1939SAndy Fiddaman 			}
135*b30d1939SAndy Fiddaman 			if (c == 2)
136*b30d1939SAndy Fiddaman 				n++;
137*b30d1939SAndy Fiddaman 			else n = 0;
138*b30d1939SAndy Fiddaman 			if (n)
139*b30d1939SAndy Fiddaman 			{
140*b30d1939SAndy Fiddaman 				for (p = (MM_table_t*)mm_severity_init; p->name; p++);
141*b30d1939SAndy Fiddaman 				n += p - (MM_table_t*)mm_severity_init + 1;
142*b30d1939SAndy Fiddaman 				if (severity = newof(0, MM_table_t, n, s - e))
143*b30d1939SAndy Fiddaman 				{
144*b30d1939SAndy Fiddaman 					s = (char*)severity + n * sizeof(MM_table_t);
145*b30d1939SAndy Fiddaman 					strcpy(s, e);
146*b30d1939SAndy Fiddaman 					p = severity;
147*b30d1939SAndy Fiddaman 					for (q = (MM_table_t*)mm_severity_init; q->name; q++)
148*b30d1939SAndy Fiddaman 						*p++ = *q;
149*b30d1939SAndy Fiddaman 					p->name = s;
150*b30d1939SAndy Fiddaman 					c = 0;
151*b30d1939SAndy Fiddaman 					for (;;)
152*b30d1939SAndy Fiddaman 					{
153*b30d1939SAndy Fiddaman 						switch (*s++)
154*b30d1939SAndy Fiddaman 						{
155*b30d1939SAndy Fiddaman 						case 0:
156*b30d1939SAndy Fiddaman 							break;
157*b30d1939SAndy Fiddaman 						case ',':
158*b30d1939SAndy Fiddaman 							switch (c++)
159*b30d1939SAndy Fiddaman 							{
160*b30d1939SAndy Fiddaman 							case 0:
161*b30d1939SAndy Fiddaman 								*(s - 1) = 0;
162*b30d1939SAndy Fiddaman 								p->value = strtol(s, NiL, 0);
163*b30d1939SAndy Fiddaman 								break;
164*b30d1939SAndy Fiddaman 							case 1:
165*b30d1939SAndy Fiddaman 								p->display = s;
166*b30d1939SAndy Fiddaman 								break;
167*b30d1939SAndy Fiddaman 							}
168*b30d1939SAndy Fiddaman 							continue;
169*b30d1939SAndy Fiddaman 						case ':':
170*b30d1939SAndy Fiddaman 							c = 0;
171*b30d1939SAndy Fiddaman 							*(s - 1) = 0;
172*b30d1939SAndy Fiddaman 							(++p)->name = s;
173*b30d1939SAndy Fiddaman 							continue;
174*b30d1939SAndy Fiddaman 						default:
175*b30d1939SAndy Fiddaman 							continue;
176*b30d1939SAndy Fiddaman 						}
177*b30d1939SAndy Fiddaman 						break;
178*b30d1939SAndy Fiddaman 					}
179*b30d1939SAndy Fiddaman 				}
180*b30d1939SAndy Fiddaman 			}
181*b30d1939SAndy Fiddaman 		}
182*b30d1939SAndy Fiddaman 		if (!severity)
183*b30d1939SAndy Fiddaman 			severity = (MM_table_t*)mm_severity_init;
184*b30d1939SAndy Fiddaman 	}
185*b30d1939SAndy Fiddaman 	return (const MM_table_t*)severity;
186*b30d1939SAndy Fiddaman }
187*b30d1939SAndy Fiddaman 
188*b30d1939SAndy Fiddaman static char*
189*b30d1939SAndy Fiddaman display(register const MM_table_t* tab, int value, int mask)
190*b30d1939SAndy Fiddaman {
191*b30d1939SAndy Fiddaman 	while (tab->name)
192*b30d1939SAndy Fiddaman 	{
193*b30d1939SAndy Fiddaman 		if (value == tab->value || mask && (value & tab->value))
194*b30d1939SAndy Fiddaman 			return (char*)tab->display;
195*b30d1939SAndy Fiddaman 		tab++;
196*b30d1939SAndy Fiddaman 	}
197*b30d1939SAndy Fiddaman 	return 0;
198*b30d1939SAndy Fiddaman }
199*b30d1939SAndy Fiddaman 
200*b30d1939SAndy Fiddaman int
201*b30d1939SAndy Fiddaman fmtmsg(long classification, const char* label, int severity, const char* text, const char* action, const char* tag)
202*b30d1939SAndy Fiddaman {
203*b30d1939SAndy Fiddaman 	register int		c;
204*b30d1939SAndy Fiddaman 	register char*		s;
205*b30d1939SAndy Fiddaman 	register char*		t;
206*b30d1939SAndy Fiddaman 	register MM_table_t*	p;
207*b30d1939SAndy Fiddaman 	int			n;
208*b30d1939SAndy Fiddaman 	int			m;
209*b30d1939SAndy Fiddaman 	int			r;
210*b30d1939SAndy Fiddaman 	int			fd;
211*b30d1939SAndy Fiddaman 	unsigned int		mask;
212*b30d1939SAndy Fiddaman 	Sfio_t*			sp;
213*b30d1939SAndy Fiddaman 	char			lab[MM_LABEL_1_MAX + MM_LABEL_2_MAX + 3];
214*b30d1939SAndy Fiddaman 
215*b30d1939SAndy Fiddaman 	if (!mm.init)
216*b30d1939SAndy Fiddaman 	{
217*b30d1939SAndy Fiddaman 		mm.init = INIT_VERB;
218*b30d1939SAndy Fiddaman 		if (!(s = getenv(MM_VERB_ENV)))
219*b30d1939SAndy Fiddaman 			mm.mask = MM_default;
220*b30d1939SAndy Fiddaman 		else for (;;)
221*b30d1939SAndy Fiddaman 		{
222*b30d1939SAndy Fiddaman 			if (t = strchr(s, ':'))
223*b30d1939SAndy Fiddaman 				*t = 0;
224*b30d1939SAndy Fiddaman 			if (!(p = (MM_table_t*)strlook(mm_verb, sizeof(MM_table_t), s)))
225*b30d1939SAndy Fiddaman 			{
226*b30d1939SAndy Fiddaman 				mm.mask = MM_default;
227*b30d1939SAndy Fiddaman 				if (t)
228*b30d1939SAndy Fiddaman 					*t = ':';
229*b30d1939SAndy Fiddaman 				break;
230*b30d1939SAndy Fiddaman 			}
231*b30d1939SAndy Fiddaman 			mm.mask |= p->value;
232*b30d1939SAndy Fiddaman 			if (!t)
233*b30d1939SAndy Fiddaman 				break;
234*b30d1939SAndy Fiddaman 			*t++ = ':';
235*b30d1939SAndy Fiddaman 			s = t;
236*b30d1939SAndy Fiddaman 		}
237*b30d1939SAndy Fiddaman 	}
238*b30d1939SAndy Fiddaman 	if (!(classification & (MM_CONSOLE|MM_PRINT)))
239*b30d1939SAndy Fiddaman 		return 0;
240*b30d1939SAndy Fiddaman 	if (!(sp = sfstropen()))
241*b30d1939SAndy Fiddaman 		return MM_NOTOK;
242*b30d1939SAndy Fiddaman 	r = 0;
243*b30d1939SAndy Fiddaman 	if (s = (char*)label)
244*b30d1939SAndy Fiddaman 	{
245*b30d1939SAndy Fiddaman 		if (t = strchr(s, ':'))
246*b30d1939SAndy Fiddaman 		{
247*b30d1939SAndy Fiddaman 			if ((n = t - s) > MM_LABEL_1_MAX)
248*b30d1939SAndy Fiddaman 				n = MM_LABEL_1_MAX;
249*b30d1939SAndy Fiddaman 			sfprintf(sp, "%*.*s:", n, n, s);
250*b30d1939SAndy Fiddaman 			s = ++t;
251*b30d1939SAndy Fiddaman 			if ((n = strlen(t)) > MM_LABEL_2_MAX)
252*b30d1939SAndy Fiddaman 				n = MM_LABEL_2_MAX;
253*b30d1939SAndy Fiddaman 			sfprintf(sp, "%*.*s", n, n, s);
254*b30d1939SAndy Fiddaman 		}
255*b30d1939SAndy Fiddaman 		else
256*b30d1939SAndy Fiddaman 		{
257*b30d1939SAndy Fiddaman 			if ((n = strlen(t)) > MM_LABEL_1_MAX)
258*b30d1939SAndy Fiddaman 				n = MM_LABEL_1_MAX;
259*b30d1939SAndy Fiddaman 			sfprintf(sp, "%*.*s", n, n, s);
260*b30d1939SAndy Fiddaman 		}
261*b30d1939SAndy Fiddaman 		if (!(s = sfstruse(sp)))
262*b30d1939SAndy Fiddaman 		{
263*b30d1939SAndy Fiddaman 			sfstrclose(sp);
264*b30d1939SAndy Fiddaman 			return MM_NOTOK;
265*b30d1939SAndy Fiddaman 		}
266*b30d1939SAndy Fiddaman 		strcpy(lab, s);
267*b30d1939SAndy Fiddaman 	}
268*b30d1939SAndy Fiddaman 	for (;;)
269*b30d1939SAndy Fiddaman 	{
270*b30d1939SAndy Fiddaman 		if (classification & MM_CONSOLE)
271*b30d1939SAndy Fiddaman 		{
272*b30d1939SAndy Fiddaman 			classification &= ~MM_CONSOLE;
273*b30d1939SAndy Fiddaman 			if (!(mm.init & INIT_CONSOLE))
274*b30d1939SAndy Fiddaman 				mm.console = open("/dev/console", O_WRONLY|O_APPEND|O_NOCTTY);
275*b30d1939SAndy Fiddaman 			if (mm.console < 0)
276*b30d1939SAndy Fiddaman 			{
277*b30d1939SAndy Fiddaman 				r |= MM_NOCON;
278*b30d1939SAndy Fiddaman 				continue;
279*b30d1939SAndy Fiddaman 			}
280*b30d1939SAndy Fiddaman 			c = MM_NOCON;
281*b30d1939SAndy Fiddaman 			fd = mm.console;
282*b30d1939SAndy Fiddaman 			mask = MM_all;
283*b30d1939SAndy Fiddaman 		}
284*b30d1939SAndy Fiddaman 		else if (classification & MM_PRINT)
285*b30d1939SAndy Fiddaman 		{
286*b30d1939SAndy Fiddaman 			classification &= ~MM_PRINT;
287*b30d1939SAndy Fiddaman 			c = MM_NOMSG;
288*b30d1939SAndy Fiddaman 			fd = 2;
289*b30d1939SAndy Fiddaman 			mask = mm.mask;
290*b30d1939SAndy Fiddaman 		}
291*b30d1939SAndy Fiddaman 		else break;
292*b30d1939SAndy Fiddaman 		if ((mask & MM_label) && label)
293*b30d1939SAndy Fiddaman 			sfprintf(sp, "%s: ", lab);
294*b30d1939SAndy Fiddaman 		if ((mask & MM_severity) && (s = display(mm_severity, severity, 0)))
295*b30d1939SAndy Fiddaman 			sfprintf(sp, "%s: ", s);
296*b30d1939SAndy Fiddaman 		n = sfstrtell(sp);
297*b30d1939SAndy Fiddaman 		if ((mask & MM_text) && text)
298*b30d1939SAndy Fiddaman 			sfprintf(sp, "%s\n", text);
299*b30d1939SAndy Fiddaman 		else sfputc(sp, '\n');
300*b30d1939SAndy Fiddaman 		if ((mask & MM_action) && action || (mask & MM_tag) && (label || tag))
301*b30d1939SAndy Fiddaman 		{
302*b30d1939SAndy Fiddaman 			if (fd != mm.console && (n -= 8) > 0)
303*b30d1939SAndy Fiddaman 				sfprintf(sp, "%*.*s", n, n, "");
304*b30d1939SAndy Fiddaman 			sfprintf(sp, "TO FIX:");
305*b30d1939SAndy Fiddaman 			if ((mask & MM_action) && action)
306*b30d1939SAndy Fiddaman 				sfprintf(sp, " %s", action);
307*b30d1939SAndy Fiddaman 			if ((mask & MM_tag) && (label || tag))
308*b30d1939SAndy Fiddaman 			{
309*b30d1939SAndy Fiddaman 				sfprintf(sp, "  ");
310*b30d1939SAndy Fiddaman 				if (!tag || label && !strchr(tag, ':'))
311*b30d1939SAndy Fiddaman 					sfprintf(sp, "%s%s", lab, tag ? ":" : "");
312*b30d1939SAndy Fiddaman 				if (tag)
313*b30d1939SAndy Fiddaman 					sfprintf(sp, "%s", tag);
314*b30d1939SAndy Fiddaman 			}
315*b30d1939SAndy Fiddaman 			if (mask & (MM_class|MM_source|MM_status))
316*b30d1939SAndy Fiddaman 			{
317*b30d1939SAndy Fiddaman 				sfputc(sp, ' ');
318*b30d1939SAndy Fiddaman 				if ((mask & MM_source) && (m = classification & (MM_APPL|MM_UTIL|MM_OPSYS)) && (s = display(mm_class, m, 1)))
319*b30d1939SAndy Fiddaman 					sfprintf(sp, " %s", s);
320*b30d1939SAndy Fiddaman 				if ((mask & MM_class) && (m = classification & (MM_HARD|MM_SOFT|MM_FIRM)) && (s = display(mm_class, m, 1)))
321*b30d1939SAndy Fiddaman 					sfprintf(sp, " %s", s);
322*b30d1939SAndy Fiddaman 				if ((mask & MM_status) && (m = classification & (MM_RECOVER|MM_NRECOV)) && (s = display(mm_class, m, 1)))
323*b30d1939SAndy Fiddaman 					sfprintf(sp, " %s", s);
324*b30d1939SAndy Fiddaman 			}
325*b30d1939SAndy Fiddaman 			sfputc(sp, '\n');
326*b30d1939SAndy Fiddaman 		}
327*b30d1939SAndy Fiddaman 		n = sfstrtell(sp);
328*b30d1939SAndy Fiddaman 		if (!(s = sfstruse(sp)) || write(fd, s, n) != n)
329*b30d1939SAndy Fiddaman 			r |= c;
330*b30d1939SAndy Fiddaman 	}
331*b30d1939SAndy Fiddaman 	sfstrclose(sp);
332*b30d1939SAndy Fiddaman 	return r;
333*b30d1939SAndy Fiddaman }
334*b30d1939SAndy Fiddaman 
335*b30d1939SAndy Fiddaman #endif
336