fmtmsg.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* Public domain fmtmsg()
  2. * Written by Isaac Dunham, 2014
  3. */
  4. #include <fmtmsg.h>
  5. #include <fcntl.h>
  6. #include <unistd.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <pthread.h>
  11. /*
  12. * If lstr is the first part of bstr, check that the next char in bstr
  13. * is either \0 or :
  14. */
  15. static int _strcolcmp(const char *lstr, const char *bstr)
  16. {
  17. size_t i = 0;
  18. while (lstr[i] && bstr[i] && (bstr[i] == lstr[i])) i++;
  19. if ( lstr[i] || (bstr[i] && bstr[i] != ':')) return 1;
  20. return 0;
  21. }
  22. int fmtmsg(long classification, const char *label, int severity,
  23. const char *text, const char *action, const char *tag)
  24. {
  25. int ret = 0, i, consolefd, verb = 0;
  26. char *errstring = MM_NULLSEV, *cmsg = getenv("MSGVERB");
  27. char *const msgs[] = {
  28. "label", "severity", "text", "action", "tag", NULL
  29. };
  30. int cs;
  31. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
  32. if (severity == MM_HALT) errstring = "HALT: ";
  33. else if (severity == MM_ERROR) errstring = "ERROR: ";
  34. else if (severity == MM_WARNING) errstring = "WARNING: ";
  35. else if (severity == MM_INFO) errstring = "INFO: ";
  36. if (classification & MM_CONSOLE) {
  37. consolefd = open("/dev/console", O_WRONLY);
  38. if (consolefd < 0) {
  39. ret = MM_NOCON;
  40. } else {
  41. if (dprintf(consolefd, "%s%s%s%s%s%s%s%s\n",
  42. label?label:"", label?": ":"",
  43. severity?errstring:"", text?text:"",
  44. action?"\nTO FIX: ":"",
  45. action?action:"", action?" ":"",
  46. tag?tag:"" )<1)
  47. ret = MM_NOCON;
  48. close(consolefd);
  49. }
  50. }
  51. if (classification & MM_PRINT) {
  52. while (cmsg && cmsg[0]) {
  53. for(i=0; msgs[i]; i++) {
  54. if (!_strcolcmp(msgs[i], cmsg)) break;
  55. }
  56. if (msgs[i] == NULL) {
  57. //ignore MSGVERB-unrecognized component
  58. verb = 0xFF;
  59. break;
  60. } else {
  61. verb |= (1 << i);
  62. cmsg = strchr(cmsg, ':');
  63. if (cmsg) cmsg++;
  64. }
  65. }
  66. if (!verb) verb = 0xFF;
  67. if (dprintf(2, "%s%s%s%s%s%s%s%s\n",
  68. (verb&1 && label) ? label : "",
  69. (verb&1 && label) ? ": " : "",
  70. (verb&2 && severity) ? errstring : "",
  71. (verb&4 && text) ? text : "",
  72. (verb&8 && action) ? "\nTO FIX: " : "",
  73. (verb&8 && action) ? action : "",
  74. (verb&8 && action) ? " " : "",
  75. (verb&16 && tag) ? tag : "" ) < 1)
  76. ret |= MM_NOMSG;
  77. }
  78. if ((ret & (MM_NOCON|MM_NOMSG)) == (MM_NOCON|MM_NOMSG))
  79. ret = MM_NOTOK;
  80. pthread_setcancelstate(cs, 0);
  81. return ret;
  82. }