1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
#include "logmsg.h"
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include "buffer.h"
#include "fmt.h"
#include "str.h"
#include "stralloc.h"
/**
@file logmsg.c
@author kp, feh
@source qlibs
@brief unified system and error message handling
*/
#define WHO "logmsg"
char *build_log_msg(const char *x[])
{
stralloc sa = {0};
stralloc_copys(&sa, "");
while (*x) {
if (!stralloc_cats(&sa, *x++)) err_sys(WHO, errno);
} /* concatenate *x */
if (!stralloc_0(&sa)) err_sys(WHO, errno);
return (sa.s);
}
void logmsg(const char *who, int ecode, unsigned int class, const char *msg)
{
char strnum[FMT_ULONG];
char *codestr = "";
char *classstr = "";
char *errmsg = "";
errno = 0; /* re-initialize errno, value is in 'code' now */
/* Part 1: obtain the (error) code -- perhaps received from OS */
if (ecode != 0) {
codestr = "";
if (ecode < 0) { // check for negative error codes
ecode = (ecode ^ -1) + 1;
codestr = "-";
}
strnum[fmt_ulong(strnum, ecode)] = 0; /* format for output */
char *temp = strnum;
codestr = str_cat(codestr, temp);
}
/* Part 2: behavioral on error */
switch (class) {
case ERROR: classstr = "error: "; break; // info + exit
case FATAL: classstr = "fatal: "; break; // info + exit
case DROP: classstr = "drop: "; break; // info + next call/iteration
case ALERT: classstr = "alert: "; break; // info + next statement
case WARN: classstr = "warning: "; break; // info + next statement
case INFO: classstr = "info: "; break; // info + continue
case SYNTAX: classstr = "syntax: "; break; // info + exit
case USAGE: classstr = "usage: "; break; // info + exit
case TEMP: classstr = "temp: "; break; // info + exit
case CAT: classstr = ""; break; // info w/o \n
default:
class = LOG;
classstr = "";
break; // custom info + continue
}
/* Part 3: get system error message */
if (class == FATAL || class == DROP) errmsg = error_str(errno);
/* Part 4: construct log message: Source: Class (Ecode) Message: Errmsg */
buffer_puts(buffer_2, who);
buffer_puts(buffer_2, ": ");
buffer_puts(buffer_2, classstr);
if (class == FATAL || class == DROP || class == ERROR) {
buffer_puts(buffer_2, "(");
buffer_puts(buffer_2, codestr);
buffer_puts(buffer_2, ") ");
}
buffer_puts(buffer_2, msg);
if (errno) {
buffer_puts(buffer_2, ": ");
buffer_puts(buffer_2, errmsg);
}
if (class != CAT) {
buffer_puts(buffer_2, "\n");
buffer_flush(buffer_2);
}
if (class == USAGE) _exit(USAGE);
if (class == SYNTAX) _exit(SYNTAX);
if (class == FATAL || class == DROP || class == ERROR) _exit(ecode);
}
|