hooks: Allow to remove hooking (and/or trace)
[src/app-framework-binder.git] / src / afb-config.c
index c10b293..b9552f6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2018 "IoT.bzh"
+ * Copyright (C) 2015-2019 "IoT.bzh"
  * Author José Bollo <jose.bollo@iot.bzh>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
 #define SET_TRACEDITF       25
 #define SET_TRACESVC        26
 #endif
-
+#define SET_TRAP_FAULTS     27
+#define ADD_CALL            28
 #if defined(WITH_DBUS_TRANSPARENCY)
 #   define ADD_DBUS_CLIENT  30
 #   define ADD_DBUS_SERVICE 31
 #endif
 
-
 #define ADD_AUTO_API       'A'
 #define ADD_BINDING        'b'
 #define SET_CONFIG         'C'
-#define ADD_CALL           'c'
+#define SET_COLOR          'c'
 #define SET_DAEMON         'D'
 #define SET_EXEC           'e'
 #define GET_HELP           'h'
@@ -150,6 +150,7 @@ struct option_desc {
 static struct option_desc optdefs[] = {
 /* *INDENT-OFF* */
        {SET_VERBOSE,         0, "verbose",     "Verbose Mode, repeat to increase verbosity"},
+       {SET_COLOR,           0, "color",       "Colorize the ouput"},
        {SET_QUIET,           0, "quiet",       "Quiet Mode, repeat to decrease verbosity"},
        {SET_LOG,             1, "log",         "Tune log level"},
 
@@ -170,8 +171,8 @@ static struct option_desc optdefs[] = {
        {SET_CACHE_TIMEOUT,   1, "cache-eol",   "Client cache end of live [default " d2s(DEFAULT_CACHE_TIMEOUT) "]"},
 
        {SET_WORK_DIR,        1, "workdir",     "Set the working directory [default: $PWD or current working directory]"},
-       {SET_UPLOAD_DIR,      1, "uploaddir",   "Directory for uploading files [default: workdir]"},
-       {SET_ROOT_DIR,        1, "rootdir",     "Root Directory of the application [default: workdir]"},
+       {SET_UPLOAD_DIR,      1, "uploaddir",   "Directory for uploading files [default: workdir] relative to workdir"},
+       {SET_ROOT_DIR,        1, "rootdir",     "Root Directory of the application [default: workdir] relative to workdir"},
 
        {ADD_LDPATH,          1, "ldpaths",     "Load bindings from dir1:dir2:... [default = " BINDING_INSTALL_DIR "]"},
        {ADD_BINDING,         1, "binding",     "Load the binding of path"},
@@ -195,6 +196,7 @@ static struct option_desc optdefs[] = {
 
        {SET_SESSIONMAX,      1, "session-max", "Max count of session simultaneously [default " d2s(DEFAULT_MAX_SESSION_COUNT) "]"},
 
+#if WITH_AFB_HOOK
        {SET_TRACEREQ,        1, "tracereq",    "Log the requests: none, common, extra, all"},
        {SET_TRACEEVT,        1, "traceevt",    "Log the events: none, common, extra, all"},
        {SET_TRACESES,        1, "traceses",    "Log the sessions: none, all"},
@@ -203,6 +205,7 @@ static struct option_desc optdefs[] = {
 #if !defined(REMOVE_LEGACY_TRACE)
        {SET_TRACEDITF,       1, "traceditf",   "Log the daemons: no, common, all"},
        {SET_TRACESVC,        1, "tracesvc",    "Log the services: no, all"},
+#endif
 #endif
 
        {ADD_CALL,            1, "call",        "Call at start, format of val: API/VERB:json-args"},
@@ -220,6 +223,8 @@ static struct option_desc optdefs[] = {
        {ADD_SET,             1, "set",         "Set parameters ([API]/[KEY]:JSON or {\"API\":{\"KEY\":JSON}}" },
        {SET_OUTPUT,          1, "output",      "Redirect stdout and stderr to output file (when --daemon)"},
 
+       {SET_TRAP_FAULTS,     1, "trap-faults", "Trap faults: on, off, yes, no, true, false, 1, 0 (default: true)"},
+
        {0, 0, NULL, NULL}
 /* *INDENT-ON* */
 };
@@ -329,12 +334,14 @@ static void printVersion(FILE * file)
        fprintf(file,
                "\n"
                "  AGL Framework Binder [AFB %s] "
+
 #if defined(WITH_DBUS_TRANSPARENCY)
                "+"
 #else
                "-"
 #endif
                "DBUS "
+
 #if defined(WITH_MONITORING_OPTION)
                "+"
 #else
@@ -346,7 +353,23 @@ static void printVersion(FILE * file)
 #else
                "-"
 #endif
-               "SUPERVISION [BINDINGS "
+               "SUPERVISION "
+
+#if WITH_AFB_HOOK
+               "+"
+#else
+               "-"
+#endif
+               "HOOK "
+
+#if WITH_TRACE
+               "+"
+#else
+               "-"
+#endif
+               "TRACE "
+
+               "[BINDINGS "
 #if defined(WITH_LEGACY_BINDING_V1)
                "+"
 #else
@@ -363,7 +386,7 @@ static void printVersion(FILE * file)
                AFB_VERSION
        );
        fprintf(file,
-               "  Copyright (C) 2015-2018 \"IoT.bzh\"\n"
+               "  Copyright (C) 2015-2019 \"IoT.bzh\"\n"
                "  AFB comes with ABSOLUTELY NO WARRANTY.\n"
                "  Licence Apache 2\n"
                "\n");
@@ -453,6 +476,29 @@ static struct json_object *to_jbool(int value)
 * arguments helpers
 ***********************************/
 
+static int string_to_bool(const char *value)
+{
+       static const char true_names[] = "1\0yes\0true\0on";
+       static const char false_names[] = "0\0no\0false\0off";
+       size_t pos;
+
+       pos = 0;
+       while (pos < sizeof true_names)
+               if (strcasecmp(value, &true_names[pos]))
+                       pos += 1 + strlen(&true_names[pos]);
+               else
+                       return 1;
+
+       pos = 0;
+       while (pos < sizeof false_names)
+               if (strcasecmp(value, &false_names[pos]))
+                       pos += 1 + strlen(&false_names[pos]);
+               else
+                       return 0;
+
+       return -1;
+}
+
 static void noarg(int optid)
 {
        if (optarg) {
@@ -471,6 +517,17 @@ static const char *get_arg(int optid)
        return optarg;
 }
 
+static int get_arg_bool(int optid)
+{
+       int value = string_to_bool(get_arg(optid));
+       if (value < 0) {
+               ERROR("option [--%s] needs a boolean value: yes/no, true/false, on/off, 1/0",
+                               name_of_optid(optid));
+               exit(1);
+       }
+       return value;
+}
+
 static void config_del(struct json_object *config, int optid)
 {
        return json_object_object_del(config, name_of_optid(optid));
@@ -557,6 +614,7 @@ static void config_set_optint(struct json_object *config, int optid, int mini, i
        return config_set_optint_base(config, optid, mini, maxi, 10);
 }
 
+__attribute__((unused))
 static void config_set_optenum(struct json_object *config, int optid, int (*func)(const char*))
 {
        const char *name = get_arg(optid);
@@ -719,6 +777,10 @@ static void parse_arguments_inner(int argc, char **argv, struct json_object *con
                        verbose_inc();
                        break;
 
+               case SET_COLOR:
+                       verbose_colorize();
+                       break;
+
                case SET_QUIET:
                        verbose_dec();
                        break;
@@ -789,6 +851,12 @@ static void parse_arguments_inner(int argc, char **argv, struct json_object *con
                        config_set_bool(config, SET_DAEMON, optid != SET_FOREGROUND);
                        break;
 
+               case SET_TRAP_FAULTS:
+                       config_set_bool(config, optid, get_arg_bool(optid));
+                       break;
+
+
+#if WITH_AFB_HOOK
                case SET_TRACEREQ:
                        config_set_optenum(config, optid, afb_hook_flags_xreq_from_text);
                        break;
@@ -817,6 +885,7 @@ static void parse_arguments_inner(int argc, char **argv, struct json_object *con
                case SET_TRACESVC:
                        config_set_optenum(config, optid, afb_hook_flags_legacy_svc_from_text);
                        break;
+#endif
 #endif
 
                case SET_EXEC:
@@ -923,15 +992,16 @@ void afb_config_dump(struct json_object *config)
 
 static void on_environment(struct json_object *config, int optid, const char *name, void (*func)(struct json_object*, int, const char*))
 {
-       char *value = getenv(name);
+       char *value = secure_getenv(name);
 
        if (value && *value)
                func(config, optid, value);
 }
 
+__attribute__((unused))
 static void on_environment_enum(struct json_object *config, int optid, const char *name, int (*func)(const char*))
 {
-       char *value = getenv(name);
+       char *value = secure_getenv(name);
 
        if (value) {
                if (func(value) == -1)
@@ -941,19 +1011,36 @@ static void on_environment_enum(struct json_object *config, int optid, const cha
        }
 }
 
+static void on_environment_bool(struct json_object *config, int optid, const char *name)
+{
+       char *value = secure_getenv(name);
+       int asbool;
+
+       if (value) {
+               asbool = string_to_bool(value);
+               if (asbool < 0)
+                       WARNING("Unknown value %s for environment variable %s, ignored", value, name);
+               else
+                       config_set_bool(config, optid, asbool);
+       }
+}
+
 static void parse_environment(struct json_object *config)
 {
+#if WITH_AFB_HOOK
        on_environment_enum(config, SET_TRACEREQ, "AFB_TRACEREQ", afb_hook_flags_xreq_from_text);
        on_environment_enum(config, SET_TRACEEVT, "AFB_TRACEEVT", afb_hook_flags_evt_from_text);
        on_environment_enum(config, SET_TRACESES, "AFB_TRACESES", afb_hook_flags_session_from_text);
        on_environment_enum(config, SET_TRACEAPI, "AFB_TRACEAPI", afb_hook_flags_api_from_text);
        on_environment_enum(config, SET_TRACEGLOB, "AFB_TRACEGLOB", afb_hook_flags_global_from_text);
-       on_environment(config, ADD_LDPATH, "AFB_LDPATHS", config_add_str);
-       on_environment(config, ADD_SET, "AFB_SET", config_mix2_str);
 #if !defined(REMOVE_LEGACY_TRACE)
        on_environment_enum(config, SET_TRACEDITF, "AFB_TRACEDITF", afb_hook_flags_legacy_ditf_from_text);
        on_environment_enum(config, SET_TRACESVC, "AFB_TRACESVC", afb_hook_flags_legacy_svc_from_text);
 #endif
+#endif
+       on_environment(config, ADD_LDPATH, "AFB_LDPATHS", config_add_str);
+       on_environment(config, ADD_SET, "AFB_SET", config_mix2_str);
+       on_environment_bool(config, SET_TRAP_FAULTS, "AFB_TRAP_FAULTS");
 }
 
 struct json_object *afb_config_parse_arguments(int argc, char **argv)