1570af302Sopenharmony_ci/* Public domain fmtmsg() 2570af302Sopenharmony_ci * Written by Isaac Dunham, 2014 3570af302Sopenharmony_ci */ 4570af302Sopenharmony_ci#include <fmtmsg.h> 5570af302Sopenharmony_ci#include <fcntl.h> 6570af302Sopenharmony_ci#include <unistd.h> 7570af302Sopenharmony_ci#include <stdio.h> 8570af302Sopenharmony_ci#include <string.h> 9570af302Sopenharmony_ci#include <stdlib.h> 10570af302Sopenharmony_ci#include <pthread.h> 11570af302Sopenharmony_ci 12570af302Sopenharmony_ci/* 13570af302Sopenharmony_ci * If lstr is the first part of bstr, check that the next char in bstr 14570af302Sopenharmony_ci * is either \0 or : 15570af302Sopenharmony_ci */ 16570af302Sopenharmony_cistatic int _strcolcmp(const char *lstr, const char *bstr) 17570af302Sopenharmony_ci{ 18570af302Sopenharmony_ci size_t i = 0; 19570af302Sopenharmony_ci while (lstr[i] && bstr[i] && (bstr[i] == lstr[i])) i++; 20570af302Sopenharmony_ci if ( lstr[i] || (bstr[i] && bstr[i] != ':')) return 1; 21570af302Sopenharmony_ci return 0; 22570af302Sopenharmony_ci} 23570af302Sopenharmony_ci 24570af302Sopenharmony_ciint fmtmsg(long classification, const char *label, int severity, 25570af302Sopenharmony_ci const char *text, const char *action, const char *tag) 26570af302Sopenharmony_ci{ 27570af302Sopenharmony_ci int ret = 0, i, consolefd, verb = 0; 28570af302Sopenharmony_ci char *errstring = MM_NULLSEV, *cmsg = getenv("MSGVERB"); 29570af302Sopenharmony_ci char *const msgs[] = { 30570af302Sopenharmony_ci "label", "severity", "text", "action", "tag", NULL 31570af302Sopenharmony_ci }; 32570af302Sopenharmony_ci int cs; 33570af302Sopenharmony_ci 34570af302Sopenharmony_ci pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); 35570af302Sopenharmony_ci 36570af302Sopenharmony_ci if (severity == MM_HALT) errstring = "HALT: "; 37570af302Sopenharmony_ci else if (severity == MM_ERROR) errstring = "ERROR: "; 38570af302Sopenharmony_ci else if (severity == MM_WARNING) errstring = "WARNING: "; 39570af302Sopenharmony_ci else if (severity == MM_INFO) errstring = "INFO: "; 40570af302Sopenharmony_ci 41570af302Sopenharmony_ci if (classification & MM_CONSOLE) { 42570af302Sopenharmony_ci consolefd = open("/dev/console", O_WRONLY); 43570af302Sopenharmony_ci if (consolefd < 0) { 44570af302Sopenharmony_ci ret = MM_NOCON; 45570af302Sopenharmony_ci } else { 46570af302Sopenharmony_ci if (dprintf(consolefd, "%s%s%s%s%s%s%s%s\n", 47570af302Sopenharmony_ci label?label:"", label?": ":"", 48570af302Sopenharmony_ci severity?errstring:"", text?text:"", 49570af302Sopenharmony_ci action?"\nTO FIX: ":"", 50570af302Sopenharmony_ci action?action:"", action?" ":"", 51570af302Sopenharmony_ci tag?tag:"" )<1) 52570af302Sopenharmony_ci ret = MM_NOCON; 53570af302Sopenharmony_ci close(consolefd); 54570af302Sopenharmony_ci } 55570af302Sopenharmony_ci } 56570af302Sopenharmony_ci 57570af302Sopenharmony_ci if (classification & MM_PRINT) { 58570af302Sopenharmony_ci while (cmsg && cmsg[0]) { 59570af302Sopenharmony_ci for(i=0; msgs[i]; i++) { 60570af302Sopenharmony_ci if (!_strcolcmp(msgs[i], cmsg)) break; 61570af302Sopenharmony_ci } 62570af302Sopenharmony_ci if (msgs[i] == NULL) { 63570af302Sopenharmony_ci //ignore MSGVERB-unrecognized component 64570af302Sopenharmony_ci verb = 0xFF; 65570af302Sopenharmony_ci break; 66570af302Sopenharmony_ci } else { 67570af302Sopenharmony_ci verb |= (1 << i); 68570af302Sopenharmony_ci cmsg = strchr(cmsg, ':'); 69570af302Sopenharmony_ci if (cmsg) cmsg++; 70570af302Sopenharmony_ci } 71570af302Sopenharmony_ci } 72570af302Sopenharmony_ci if (!verb) verb = 0xFF; 73570af302Sopenharmony_ci if (dprintf(2, "%s%s%s%s%s%s%s%s\n", 74570af302Sopenharmony_ci (verb&1 && label) ? label : "", 75570af302Sopenharmony_ci (verb&1 && label) ? ": " : "", 76570af302Sopenharmony_ci (verb&2 && severity) ? errstring : "", 77570af302Sopenharmony_ci (verb&4 && text) ? text : "", 78570af302Sopenharmony_ci (verb&8 && action) ? "\nTO FIX: " : "", 79570af302Sopenharmony_ci (verb&8 && action) ? action : "", 80570af302Sopenharmony_ci (verb&8 && action) ? " " : "", 81570af302Sopenharmony_ci (verb&16 && tag) ? tag : "" ) < 1) 82570af302Sopenharmony_ci ret |= MM_NOMSG; 83570af302Sopenharmony_ci } 84570af302Sopenharmony_ci if ((ret & (MM_NOCON|MM_NOMSG)) == (MM_NOCON|MM_NOMSG)) 85570af302Sopenharmony_ci ret = MM_NOTOK; 86570af302Sopenharmony_ci 87570af302Sopenharmony_ci pthread_setcancelstate(cs, 0); 88570af302Sopenharmony_ci 89570af302Sopenharmony_ci return ret; 90570af302Sopenharmony_ci} 91