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