* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* By default, logging is done on stderr. */
-static int debug = 1;
+static int use_syslog = 0;
+/* Default debug level */
+static int debug = 0;
/* Logging can be modified by providing an appropriate log handler. */
static void (*logh)(int severity, const char *msg) = NULL;
static void vlog(int, const char *, const char *, va_list);
static void logit(int, const char *, const char *, ...);
+#define MAX_DBG_TOKENS 40
+static const char *tokens[MAX_DBG_TOKENS + 1] = {NULL};
+
void
-log_init(int n_debug, const char *progname)
+log_init(int n_syslog, int n_debug, const char *progname)
{
+ use_syslog = n_syslog;
debug = n_debug;
- if (!debug)
+ if (use_syslog)
openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
tzset();
}
+void
+log_level(int n_debug)
+{
+ if (n_debug >= 0)
+ debug = n_debug;
+}
+
void
log_register(void (*cb)(int, const char*))
{
logh = cb;
}
+void
+log_accept(const char *token)
+{
+ int i;
+ for (i = 0; i < MAX_DBG_TOKENS; i++) {
+ if (tokens[i] == NULL) {
+ tokens[i+1] = NULL;
+ tokens[i] = token;
+ return;
+ }
+ }
+}
static void
logit(int pri, const char *token, const char *fmt, ...)
case LOG_WARNING: return "\033[1;33m[WARN";
case LOG_NOTICE: return "\033[1;34m[NOTI";
case LOG_INFO: return "\033[1;34m[INFO";
- case LOG_DEBUG: return "\033[1;30m[ DBG";
+ case LOG_DEBUG: return "\033[36m[ DBG";
}
break;
default:
char *result;
if (vasprintf(&result, fmt, ap) != -1) {
logh(pri, result);
+ free(result);
return;
}
- /* Otherwise, fallback to output on stderr. */
+ /* Otherwise, abort. We don't know if "ap" is still OK. We could
+ * have made a copy, but this is too much overhead for a
+ * situation that shouldn't happen. */
+ return;
}
- if (debug || logh) {
- char *nfmt;
- /* best effort in out of mem situations */
- if (asprintf(&nfmt, "%s %s%s%s]%s %s\n",
- date(),
- translate(STDERR_FILENO, pri),
- token ? "/" : "", token ? token : "",
- isatty(STDERR_FILENO) ? "\033[0m" : "",
- fmt) == -1) {
- vfprintf(stderr, fmt, ap);
- fprintf(stderr, "\n");
- } else {
- vfprintf(stderr, nfmt, ap);
- free(nfmt);
- }
- fflush(stderr);
- } else
- vsyslog(pri, fmt, ap);
+
+ /* Log to syslog if requested */
+ if (use_syslog) {
+ va_list ap2;
+ va_copy(ap2, ap);
+ vsyslog(pri, fmt, ap2);
+ va_end(ap2);
+ }
+
+ /* Log to standard error in all cases */
+ char *nfmt;
+ /* best effort in out of mem situations */
+ if (asprintf(&nfmt, "%s %s%s%s]%s %s\n",
+ date(),
+ translate(STDERR_FILENO, pri),
+ token ? "/" : "", token ? token : "",
+ isatty(STDERR_FILENO) ? "\033[0m" : "",
+ fmt) == -1) {
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+ } else {
+ vfprintf(stderr, nfmt, ap);
+ free(nfmt);
+ }
+ fflush(stderr);
}
{
va_list ap;
- if (debug > 1 || logh) {
+ if (use_syslog || debug > 0 || logh) {
va_start(ap, emsg);
vlog(LOG_INFO, token, emsg, ap);
va_end(ap);
}
}
+static int
+log_debug_accept_token(const char *token)
+{
+ int i;
+ if (tokens[0] == NULL) return 1;
+ for (i = 0;
+ (i < MAX_DBG_TOKENS) && (tokens[i] != NULL);
+ i++) {
+ if (!strcmp(tokens[i], token))
+ return 1;
+ }
+ return 0;
+}
+
void
log_debug(const char *token, const char *emsg, ...)
{
va_list ap;
- if (debug > 2 || logh) {
+ if ((debug > 1 && log_debug_accept_token(token)) || logh) {
va_start(ap, emsg);
vlog(LOG_DEBUG, token, emsg, ap);
va_end(ap);
}
void
-fatalx(const char *emsg)
+fatalx(const char *token, const char *emsg)
{
errno = 0;
- fatal(NULL, emsg);
+ fatal(token, emsg);
}