afb-args: Use secure_getenv
[src/app-framework-binder.git] / src / afb-config.c
index 38dd9b7..87fad97 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"},
 
@@ -220,6 +221,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* */
 };
@@ -363,7 +366,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 +456,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 +497,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));
@@ -719,6 +756,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 +830,11 @@ 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;
+
+
                case SET_TRACEREQ:
                        config_set_optenum(config, optid, afb_hook_flags_xreq_from_text);
                        break;
@@ -923,7 +969,7 @@ 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);
@@ -931,7 +977,7 @@ static void on_environment(struct json_object *config, int optid, const char *na
 
 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,6 +987,20 @@ 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)
 {
        on_environment_enum(config, SET_TRACEREQ, "AFB_TRACEREQ", afb_hook_flags_xreq_from_text);
@@ -954,6 +1014,7 @@ static void parse_environment(struct json_object *config)
        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
+       on_environment_bool(config, SET_TRAP_FAULTS, "AFB_TRAP_FAULTS");
 }
 
 struct json_object *afb_config_parse_arguments(int argc, char **argv)