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