diff options
Diffstat (limited to 'src/logmsg.c')
-rw-r--r-- | src/logmsg.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/logmsg.c b/src/logmsg.c new file mode 100644 index 0000000..97d832e --- /dev/null +++ b/src/logmsg.c @@ -0,0 +1,97 @@ +#include <unistd.h> +#include <stdarg.h> +#include <errno.h> +#include "buffer.h" +#include "fmt.h" +#include "str.h" +#include "stralloc.h" +#include "logmsg.h" + +/** + * @file logmsg.c + * @author kp, feh + * @ref 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); +} |