diff options
-rw-r--r-- | src/afb-api-so.c | 38 | ||||
-rw-r--r-- | src/afb-apis.c | 6 | ||||
-rw-r--r-- | src/afb-hreq.c | 15 | ||||
-rw-r--r-- | src/afb-hsrv.c | 6 | ||||
-rw-r--r-- | src/main.c | 139 | ||||
-rw-r--r-- | src/session.c | 5 | ||||
-rw-r--r-- | src/verbose.c | 23 | ||||
-rw-r--r-- | src/verbose.h | 16 |
8 files changed, 131 insertions, 117 deletions
diff --git a/src/afb-api-so.c b/src/afb-api-so.c index 38621ecf..07d0a5f2 100644 --- a/src/afb-api-so.c +++ b/src/afb-api-so.c @@ -176,25 +176,24 @@ int afb_api_so_add_plugin(const char *path) desc = calloc(1, sizeof *desc); if (desc == NULL) { - fprintf(stderr, "[%s] out of memory\n", path); + ERROR("out of memory"); goto error; } // This is a loadable library let's check if it's a plugin desc->handle = dlopen(path, RTLD_NOW | RTLD_LOCAL); if (desc->handle == NULL) { - fprintf(stderr, "[%s] not loadable, continuing...\n", path); + ERROR("plugin [%s] not loadable", path); goto error2; } /* retrieves the register function */ pluginRegisterFct = dlsym(desc->handle, plugin_register_function); if (!pluginRegisterFct) { - fprintf(stderr, "[%s] not an AFB plugin, continuing...\n", path); + ERROR("plugin [%s] is not an AFB plugin", path); goto error3; } - if (verbosity) - fprintf(stderr, "[%s] is a valid AFB plugin\n", path); + INFO("plugin [%s] is a valid AFB plugin", path); /* init the interface */ desc->interface.verbosity = 0; @@ -205,25 +204,25 @@ int afb_api_so_add_plugin(const char *path) /* init the plugin */ desc->plugin = pluginRegisterFct(&desc->interface); if (desc->plugin == NULL) { - fprintf(stderr, "ERROR: plugin [%s] register function failed. continuing...\n", path); + ERROR("plugin [%s] register function failed. continuing...", path); goto error3; } /* check the returned structure */ if (desc->plugin->type != AFB_PLUGIN_JSON) { - fprintf(stderr, "ERROR: plugin [%s] invalid type %d...\n", path, desc->plugin->type); + ERROR("plugin [%s] invalid type %d...", path, desc->plugin->type); goto error3; } if (desc->plugin->prefix == NULL || *desc->plugin->prefix == 0) { - fprintf(stderr, "ERROR: plugin [%s] bad prefix...\n", path); + ERROR("plugin [%s] bad prefix...", path); goto error3; } if (desc->plugin->info == NULL || *desc->plugin->info == 0) { - fprintf(stderr, "ERROR: plugin [%s] bad description...\n", path); + ERROR("plugin [%s] bad description...", path); goto error3; } if (desc->plugin->apis == NULL) { - fprintf(stderr, "ERROR: plugin [%s] no APIs...\n", path); + ERROR("plugin [%s] no APIs...", path); goto error3; } @@ -232,10 +231,10 @@ int afb_api_so_add_plugin(const char *path) if (afb_apis_add(desc->plugin->prefix, (struct afb_api){ .closure = desc, .call = (void*)call}) < 0) { - fprintf(stderr, "ERROR: plugin [%s] can't be registered...\n", path); + ERROR("plugin [%s] can't be registered...", path); goto error3; } - + NOTICE("plugin %s loaded with API prefix %s", path, desc->plugin->prefix); return 0; error3: @@ -255,11 +254,10 @@ static int adddirs(char path[PATH_MAX], size_t end) /* open the DIR now */ dir = opendir(path); if (dir == NULL) { - fprintf(stderr, "ERROR in scanning plugin directory %s, %m\n", path); + ERROR("can't scan plugin directory %s, %m", path); return -1; } - if (verbosity) - fprintf(stderr, "Scanning dir=[%s] for plugins\n", path); + INFO("Scanning dir=[%s] for plugins", path); /* scan each entry */ if (end) @@ -271,7 +269,7 @@ static int adddirs(char path[PATH_MAX], size_t end) len = strlen(ent.d_name); if (len + end >= PATH_MAX) { - fprintf(stderr, "path too long for %s\n", ent.d_name); + ERROR("path too long while scanning plugins for %s", ent.d_name); continue; } memcpy(&path[end], ent.d_name, len+1); @@ -302,7 +300,7 @@ int afb_api_so_add_directory(const char *path) length = strlen(path); if (length >= sizeof(buffer)) { - fprintf(stderr, "path too long %lu [%.99s...]\n", (unsigned long)length, path); + ERROR("path too long %lu [%.99s...]", (unsigned long)length, path); return -1; } @@ -317,11 +315,13 @@ int afb_api_so_add_path(const char *path) rc = stat(path, &st); if (rc < 0) - fprintf(stderr, "Invalid plugin path [%s]: %m\n", path); + ERROR("Invalid plugin path [%s]: %m", path); else if (S_ISDIR(st.st_mode)) rc = afb_api_so_add_directory(path); - else + else if (strstr(path, ".so")) rc = afb_api_so_add_plugin(path); + else + INFO("not a plugin [%s], skipped", path); return rc; } diff --git a/src/afb-apis.c b/src/afb-apis.c index da0b98f0..834850f2 100644 --- a/src/afb-apis.c +++ b/src/afb-apis.c @@ -51,14 +51,14 @@ int afb_apis_add(const char *name, struct afb_api api) /* check existing or not */ len = strlen(name); if (len == 0) { - fprintf(stderr, "empty api name forbidden\n"); + ERROR("empty api name forbidden"); goto error; } /* check previously existing plugin */ for (i = 0 ; i < apis_count ; i++) { if (!strcasecmp(apis_array[i].name, name)) { - fprintf(stderr, "ERROR: api of name %s already exists\n", name); + ERROR("api of name %s already exists", name); goto error; } } @@ -66,7 +66,7 @@ int afb_apis_add(const char *name, struct afb_api api) /* allocates enough memory */ apis = realloc(apis_array, ((unsigned)apis_count + 1) * sizeof * apis); if (apis == NULL) { - fprintf(stderr, "out of memory\n"); + ERROR("out of memory"); goto error; } apis_array = apis; diff --git a/src/afb-hreq.c b/src/afb-hreq.c index 518bc5cb..5eb0cc56 100644 --- a/src/afb-hreq.c +++ b/src/afb-hreq.c @@ -234,18 +234,15 @@ static magic_t lazy_libmagic() done = 1; /* MAGIC_MIME tells magic to return a mime of the file, but you can specify different things */ - if (verbosity) - fprintf(stderr, "Loading mimetype default magic database\n"); - + INFO("Loading mimetype default magic database"); result = magic_open(MAGIC_MIME_TYPE); if (result == NULL) { - fprintf(stderr,"ERROR: unable to initialize magic library\n"); + ERROR("unable to initialize magic library"); } /* Warning: should not use NULL for DB [libmagic bug wont pass efence check] */ else if (magic_load(result, MAGIC_DB) != 0) { - fprintf(stderr,"cannot load magic database - %s\n", - magic_error(result)); + ERROR("cannot load magic database: %s", magic_error(result)); magic_close(result); result = NULL; } @@ -435,8 +432,7 @@ int afb_hreq_reply_file_if_exist(struct afb_hreq *hreq, int dirfd, const char *f if (inm && 0 == strcmp(inm, etag)) { /* etag ok, return NOT MODIFIED */ close(fd); - if (verbosity) - fprintf(stderr, "Not Modified: [%s]\n", filename); + DEBUG("Not Modified: [%s]", filename); response = MHD_create_response_from_buffer(0, empty_string, MHD_RESPMEM_PERSISTENT); status = MHD_HTTP_NOT_MODIFIED; } else { @@ -477,8 +473,7 @@ int afb_hreq_redirect_to(struct afb_hreq *hreq, const char *url) { afb_hreq_reply_static(hreq, MHD_HTTP_MOVED_PERMANENTLY, 0, NULL, MHD_HTTP_HEADER_LOCATION, url, NULL); - if (verbosity) - fprintf(stderr, "redirect from [%s] to [%s]\n", hreq->url, url); + DEBUG("redirect from [%s] to [%s]", hreq->url, url); return 1; } diff --git a/src/afb-hsrv.c b/src/afb-hsrv.c index e64c5c9a..d2356484 100644 --- a/src/afb-hsrv.c +++ b/src/afb-hsrv.c @@ -388,14 +388,14 @@ int afb_hsrv_start(struct afb_hsrv *hsrv, uint16_t port, unsigned int connection MHD_OPTION_END); /* options-end */ if (httpd == NULL) { - fprintf(stderr, "Error: httpStart invalid httpd port: %d", (int)port); + ERROR("httpStart invalid httpd port: %d", (int)port); return 0; } info = MHD_get_daemon_info(httpd, MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY); if (info == NULL) { MHD_stop_daemon(httpd); - fprintf(stderr, "Error: httpStart no pollfd"); + ERROR("httpStart no pollfd"); return 0; } @@ -403,7 +403,7 @@ int afb_hsrv_start(struct afb_hsrv *hsrv, uint16_t port, unsigned int connection if (rc < 0) { MHD_stop_daemon(httpd); errno = -rc; - fprintf(stderr, "Error: connection to events for httpd failed"); + ERROR("connection to events for httpd failed"); return 0; } @@ -51,7 +51,7 @@ #error "you should define PLUGIN_INSTALL_DIR" #endif -#define AFB_VERSION "0.1" +#define AFB_VERSION "0.4" // Define command line option #define SET_VERBOSE 1 @@ -123,17 +123,42 @@ static AFB_options cliOptions [] = { | printversion | print version and copyright +--------------------------------------------------------- */ -static void printVersion (void) +static void printVersion (FILE *file) { - fprintf (stderr,"\n----------------------------------------- \n"); - fprintf (stderr,"| AFB [Application Framework Binder] version=%s |\n", AFB_VERSION); - fprintf (stderr,"----------------------------------------- \n"); - fprintf (stderr,"| Copyright(C) 2016 /IoT.bzh [fulup -at- iot.bzh]\n"); - fprintf (stderr,"| AFB comes with ABSOLUTELY NO WARRANTY.\n"); - fprintf (stderr,"| Licence Apache 2\n\n"); + fprintf(file, "\n----------------------------------------- \n"); + fprintf(file, " AFB [Application Framework Binder] version=%s |\n", AFB_VERSION); + fprintf(file, " \n"); + fprintf(file, " Copyright(C) 2016 /IoT.bzh [fulup -at- iot.bzh]\n"); + fprintf(file, " AFB comes with ABSOLUTELY NO WARRANTY.\n"); + fprintf(file, " Licence Apache 2\n\n"); exit (0); } +/*---------------------------------------------------------- + | printHelp + | print information from long option array + +--------------------------------------------------------- */ + +static void printHelp(FILE *file, const char *name) +{ + int ind; + char command[50]; + + fprintf (file, "%s:\nallowed options\n", name); + for (ind=0; cliOptions [ind].name != NULL;ind++) + { + // display options + if (cliOptions [ind].has_arg == 0 ) + { + fprintf (file, " --%-15s %s\n", cliOptions [ind].name, cliOptions[ind].help); + } else { + sprintf(command, "%s=xxxx", cliOptions [ind].name); + fprintf (file, " --%-15s %s\n", command, cliOptions[ind].help); + } + } + fprintf (file, "Example:\n %s\\\n --verbose --port=1234 --token='azerty' --ldpaths=build/plugins:/usr/lib64/agl/plugins\n", name); +} + // load config from disk and merge with CLI option static void config_set_default (struct afb_config * config) { @@ -194,30 +219,6 @@ static void config_set_default (struct afb_config * config) } -/*---------------------------------------------------------- - | printHelp - | print information from long option array - +--------------------------------------------------------- */ - - static void printHelp(char *name) { - int ind; - char command[20]; - - fprintf (stderr,"%s:\nallowed options\n", name); - for (ind=0; cliOptions [ind].name != NULL;ind++) - { - // display options - if (cliOptions [ind].has_arg == 0 ) - { - fprintf (stderr," --%-15s %s\n", cliOptions [ind].name, cliOptions[ind].help); - } else { - sprintf(command,"%s=xxxx", cliOptions [ind].name); - fprintf (stderr," --%-15s %s\n", command, cliOptions[ind].help); - } - } - fprintf (stderr,"Example:\n %s\\\n --verbose --port=1234 --token='azerty' --ldpaths=build/plugins:/usr/lib64/agl/plugins\n", name); -} // end printHelp - /*--------------------------------------------------------- | main | Parse option and launch action @@ -235,7 +236,7 @@ static void parse_arguments(int argc, char *argv[], struct afb_config *config) // if no argument print help and return if (argc < 2) { - printHelp(programName); + printHelp(stderr, programName); exit(1); } @@ -277,19 +278,19 @@ static void parse_arguments(int argc, char *argv[], struct afb_config *config) case SET_ROOT_DIR: if (optarg == 0) goto needValueForOption; config->rootdir = optarg; - if (verbosity) fprintf(stderr, "Forcing Rootdir=%s\n",config->rootdir); + INFO("Forcing Rootdir=%s",config->rootdir); break; case SET_ROOT_BASE: if (optarg == 0) goto needValueForOption; config->rootbase = optarg; - if (verbosity) fprintf(stderr, "Forcing Rootbase=%s\n",config->rootbase); + INFO("Forcing Rootbase=%s",config->rootbase); break; case SET_ROOT_API: if (optarg == 0) goto needValueForOption; config->rootapi = optarg; - if (verbosity) fprintf(stderr, "Forcing Rootapi=%s\n",config->rootapi); + INFO("Forcing Rootapi=%s",config->rootapi); break; case SET_ALIAS: @@ -297,14 +298,14 @@ static void parse_arguments(int argc, char *argv[], struct afb_config *config) if ((unsigned)config->aliascount < sizeof (config->aliasdir) / sizeof (config->aliasdir[0])) { config->aliasdir[config->aliascount].url = strsep(&optarg,":"); if (optarg == NULL) { - fprintf(stderr, "missing ':' in alias %s, ignored\n", config->aliasdir[config->aliascount].url); + ERROR("missing ':' in alias %s, ignored", config->aliasdir[config->aliascount].url); } else { config->aliasdir[config->aliascount].path = optarg; - if (verbosity) fprintf(stderr, "Alias url=%s path=%s\n", config->aliasdir[config->aliascount].url, config->aliasdir[config->aliascount].path); + INFO("Alias url=%s path=%s", config->aliasdir[config->aliascount].url, config->aliasdir[config->aliascount].path); config->aliascount++; } } else { - fprintf(stderr, "Too many aliases [max:%d] %s ignored\n", MAX_ALIAS, optarg); + ERROR("Too many aliases [max:%d] %s ignored", MAX_ALIAS, optarg); } break; @@ -353,12 +354,12 @@ static void parse_arguments(int argc, char *argv[], struct afb_config *config) case DISPLAY_VERSION: if (optarg != 0) goto noValueForOption; - printVersion(); - exit(0); + printVersion(stdout); + break; case DISPLAY_HELP: default: - printHelp(programName); + printHelp(stdout, programName); exit(0); } } @@ -369,22 +370,22 @@ static void parse_arguments(int argc, char *argv[], struct afb_config *config) needValueForOption: - fprintf (stderr,"\nERR: AFB-daemon option [--%s] need a value i.e. --%s=xxx\n\n" + ERROR("AFB-daemon option [--%s] need a value i.e. --%s=xxx" ,gnuOptions[optionIndex].name, gnuOptions[optionIndex].name); exit (1); notAnInteger: - fprintf (stderr,"\nERR: AFB-daemon option [--%s] requirer an interger i.e. --%s=9\n\n" + ERROR("AFB-daemon option [--%s] requirer an interger i.e. --%s=9" ,gnuOptions[optionIndex].name, gnuOptions[optionIndex].name); exit (1); noValueForOption: - fprintf (stderr,"\nERR: AFB-daemon option [--%s] don't take value\n\n" + ERROR("AFB-daemon option [--%s] don't take value" ,gnuOptions[optionIndex].name); exit (1); badMode: - fprintf (stderr,"\nERR: AFB-daemon option [--%s] only accepts local, global or remote.\n\n" + ERROR("AFB-daemon option [--%s] only accepts local, global or remote." ,gnuOptions[optionIndex].name); exit (1); } @@ -402,7 +403,7 @@ static void closeSession (int status, void *data) { +--------------------------------------------------------- */ void signalQuit (int signum) { - fprintf(stderr, "Terminating signal received %s\n", strsignal(signum)); + ERROR("Terminating signal received %s", strsignal(signum)); exit(1); } @@ -425,7 +426,7 @@ static void signalError(int signum) } if (signum == SIGALRM) return; - fprintf(stderr, "Unmonitored signal received %s\n", strsignal(signum)); + ERROR("Unmonitored signal received %s", strsignal(signum)); exit(2); } @@ -435,7 +436,7 @@ static void install_error_handlers() for (i = 0; signals[i] != 0; i++) { if (signal(signals[i], signalError) == SIG_ERR) { - fprintf(stderr, "Signal handler error\n"); + ERROR("Signal handler error"); exit(1); } } @@ -453,7 +454,7 @@ static void daemonize(struct afb_config *config) // open /dev/console to redirect output messAFBes consoleFD = open(config->console, O_WRONLY | O_APPEND | O_CREAT , 0640); if (consoleFD < 0) { - fprintf (stderr,"\nERR: AFB-daemon cannot open /dev/console (use --foreground)\n\n"); + ERROR("AFB-daemon cannot open /dev/console (use --foreground)"); exit (1); } @@ -462,7 +463,7 @@ static void daemonize(struct afb_config *config) // if fail nothing much to do if (pid == -1) { - fprintf (stderr,"\nERR: AFB-daemon Failed to fork son process\n\n"); + ERROR("AFB-daemon Failed to fork son process"); exit (1); } @@ -470,7 +471,7 @@ static void daemonize(struct afb_config *config) if (pid != 0) _exit (0); // son process get all data in standalone mode - fprintf (stderr, "\nAFB: background mode [pid:%d console:%s]\n", getpid(),config->console); + NOTICE("background mode [pid:%d console:%s]", getpid(),config->console); // redirect default I/O on console close (2); dup(consoleFD); // redirect stderr @@ -482,10 +483,6 @@ static void daemonize(struct afb_config *config) setsid(); // allow father process to fully exit sleep (2); // allow main to leave and release port #endif - - fprintf (stderr, "----------------------------\n"); - fprintf (stderr, "INF: main background pid=%d\n", getpid()); - fflush (stderr); } /*--------------------------------------------------------- @@ -521,31 +518,29 @@ static struct afb_hsrv *start_http_server(struct afb_config * config) struct afb_hsrv *hsrv; if (afb_hreq_init_download_path("/tmp")) { /* TODO: sessiondir? */ - fprintf(stderr, "unable to set the tmp directory\n"); + ERROR("unable to set the tmp directory"); return NULL; } hsrv = afb_hsrv_create(); if (hsrv == NULL) { - fprintf(stderr, "memory allocation failure\n"); + ERROR("memory allocation failure"); return NULL; } if (!afb_hsrv_set_cache_timeout(hsrv, config->cacheTimeout) || !init_http_server(hsrv, config)) { - fprintf (stderr, "Error: initialisation of httpd failed"); + ERROR("initialisation of httpd failed"); afb_hsrv_put(hsrv); return NULL; } - if (verbosity) { - fprintf (stderr, "AFB:notice Waiting port=%d rootdir=%s\n", config->httpdPort, config->rootdir); - fprintf (stderr, "AFB:notice Browser URL= http:/*localhost:%d\n", config->httpdPort); - } + NOTICE("Waiting port=%d rootdir=%s", config->httpdPort, config->rootdir); + NOTICE("Browser URL= http:/*localhost:%d", config->httpdPort); rc = afb_hsrv_start(hsrv, (uint16_t) config->httpdPort, 15); if (!rc) { - fprintf (stderr, "Error: starting of httpd failed"); + ERROR("starting of httpd failed"); afb_hsrv_put(hsrv); return NULL; } @@ -575,7 +570,7 @@ int main(int argc, char *argv[]) { // ------------------ sanity check ---------------------------------------- if (config->httpdPort <= 0) { - fprintf (stderr, "ERR: no port is defined\n"); + ERROR("no port is defined"); exit (1); } @@ -584,7 +579,7 @@ int main(int argc, char *argv[]) { ctxStoreInit(CTX_NBCLIENTS, config->cntxTimeout, config->token, afb_apis_count()); if (!afb_hreq_init_cookie(config->httpdPort, config->rootapi, DEFLT_CNTX_TIMEOUT)) { - fprintf (stderr, "ERR: initialisation of cookies failed\n"); + ERROR("initialisation of cookies failed"); exit (1); } @@ -592,7 +587,7 @@ int main(int argc, char *argv[]) { // ------------------ clean exit on CTR-C signal ------------------------ if (signal (SIGINT, signalQuit) == SIG_ERR || signal (SIGABRT, signalQuit) == SIG_ERR) { - fprintf (stderr, "ERR: main fail to install Signal handler\n"); + ERROR("main fail to install Signal handler"); return 1; } @@ -603,17 +598,16 @@ int main(int argc, char *argv[]) { // let's not take the risk to run as ROOT //if (getuid() == 0) goto errorNoRoot; - if (verbosity) fprintf (stderr, "AFB: notice Init config done\n"); + DEBUG("Init config done"); // --------- run ----------- if (config->background) { // --------- in background mode ----------- - if (verbosity) fprintf (stderr, "AFB: Entering background mode\n"); + INFO("entering background mode"); daemonize(config); } else { // ---- in foreground mode -------------------- - if (verbosity) fprintf (stderr,"AFB: notice Foreground mode\n"); - + INFO("entering foreground mode"); } hsrv = start_http_server(config); @@ -631,8 +625,7 @@ int main(int argc, char *argv[]) { for(;;) sd_event_run(eventloop, 30000000); - if (verbosity) - fprintf (stderr, "hoops returned from infinite loop [report bug]\n"); + WARNING("hoops returned from infinite loop [report bug]"); return 0; } diff --git a/src/session.c b/src/session.c index d586e517..7a7167ed 100644 --- a/src/session.c +++ b/src/session.c @@ -28,6 +28,7 @@ #include <json.h> #include "session.h" +#include "verbose.h" #define NOW (time(NULL)) @@ -88,7 +89,7 @@ void ctxStoreInit (int max_session_count, int timeout, const char *initok, int c sessions.timeout = timeout; sessions.apicount = context_count; if (strlen(initok) >= sizeof(sessions.store[0]->token)) { - fprintf(stderr, "Error: initial token '%s' too long (max length 36)", initok); + ERROR("initial token '%s' too long (max length 36)", initok); exit(1); } sessions.initok = initok; @@ -145,8 +146,6 @@ static int ctxStoreAdd (struct AFB_clientCtx *client) assert (client != NULL); - //fprintf (stderr, "ctxStoreAdd request uuid=%s count=%d\n", client->uuid, sessions.count); - pthread_mutex_lock(&sessions.mutex); for (idx=0; idx < sessions.max; idx++) { diff --git a/src/verbose.c b/src/verbose.c index 3175cecb..29d2a9e6 100644 --- a/src/verbose.c +++ b/src/verbose.c @@ -16,7 +16,30 @@ limitations under the License. */ +#include <stdio.h> +#include <stdarg.h> #include "verbose.h" int verbosity = 1; +static const char *prefixes[] = { + "<0> EMERGENCY", + "<1> ALERT", + "<2> CRITICAL", + "<3> ERROR", + "<4> WARNING", + "<5> NOTICE", + "<6> INFO", + "<7> DEBUG" +}; + +void verbose(int level, const char *file, int line, const char *fmt, ...) +{ + va_list ap; + + fprintf(stderr, "%s: ", prefixes[level < 0 ? 0 : level > 7 ? 7 : level]); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, " [%s:%d]\n", file, line); +} diff --git a/src/verbose.h b/src/verbose.h index 24479e5c..106df0f8 100644 --- a/src/verbose.h +++ b/src/verbose.h @@ -18,10 +18,14 @@ #pragma once -#include <systemd/sd-journal.h> +#include <systemd/sd-daemon.h> + extern int verbosity; -#define ERROR(...) do{if(verbosity>=0)sd_journal_print(LOG_ERR,__VA_ARGS__);}while(0) -#define WARNING(...) do{if(verbosity>=1)sd_journal_print(LOG_WARNING,__VA_ARGS__);}while(0) -#define NOTICE(...) do{if(verbosity>=0)sd_journal_print(LOG_NOTICE,__VA_ARGS__);}while(0) -#define INFO(...) do{if(verbosity>=2)sd_journal_print(LOG_INFO,__VA_ARGS__);}while(0) -#define DEBUG(...) do{if(verbosity>=3)sd_journal_print(LOG_DEBUG,__VA_ARGS__);}while(0) +extern void verbose(int level, const char *file, int line, const char *fmt, ...); + +#define ERROR(...) do{if(verbosity>=0)verbose(3,__FILE__,__LINE__,__VA_ARGS__);}while(0) +#define WARNING(...) do{if(verbosity>=1)verbose(4,__FILE__,__LINE__,__VA_ARGS__);}while(0) +#define NOTICE(...) do{if(verbosity>=1)verbose(5,__FILE__,__LINE__,__VA_ARGS__);}while(0) +#define INFO(...) do{if(verbosity>=2)verbose(6,__FILE__,__LINE__,__VA_ARGS__);}while(0) +#define DEBUG(...) do{if(verbosity>=3)verbose(7,__FILE__,__LINE__,__VA_ARGS__);}while(0) + |