tools/mesh-cfgclient: Command line option for config
authorInga Stotland <inga.stotland@intel.com>
Fri, 1 Nov 2019 18:57:27 +0000 (11:57 -0700)
committerAnupam Roy <anupam.r@samsung.com>
Tue, 17 Dec 2019 20:31:58 +0000 (02:01 +0530)
This adds "-c" option to specify full path to configuration file.
If the path is not provided, the application will attempt to open
in the following order:
1) $XDG_CONFIG_HOME/meshcfg/config_db.json
2) $HOME/meshcfg/config_db.json

if the file does not exist, it will be generated for a newly created
network, i.e., upon successful completion of "create" command.

Change-Id: Ica273fe3803a09ab8d54434dbbcb586c0620f16a
Signed-off-by: Anupam Roy <anupam.r@samsung.com>
tools/mesh-cfgclient.c

index ebd2c5a..7a21fe7 100644 (file)
 #include <assert.h>
 #include <ctype.h>
 #include <dbus/dbus.h>
+#include <errno.h>
 #include <stdio.h>
 #include <time.h>
+
+#include <sys/stat.h>
+
 #include <ell/ell.h>
 
 #include "src/shared/shell.h"
@@ -54,6 +58,8 @@
 #define DEFAULT_START_ADDRESS  0x00aa
 #define DEFAULT_NET_INDEX      0x0000
 
+#define DEFAULT_CFG_FILE       "config_db.json"
+
 struct meshcfg_el {
        const char *path;
        uint8_t index;
@@ -108,6 +114,8 @@ static struct l_queue *devices;
 static bool prov_in_progress;
 static const char *caps[2] = {"out-numeric", "in-numeric"};
 
+static bool have_config;
+
 static struct meshcfg_app app = {
        .path = "/mesh/cfgclient",
        .agent_path = "/mesh/cfgclient/agent",
@@ -123,23 +131,28 @@ static struct meshcfg_app app = {
 };
 
 static const struct option options[] = {
-       { "address",    optional_argument, 0, 'a' },
-       { "net-index",  optional_argument, 0, 'n' },
+       { "config",     required_argument, 0, 'c' },
+       { "address",    required_argument, 0, 'a' },
+       { "net-index",  required_argument, 0, 'n' },
        { 0, 0, 0, 0 }
 };
 
 static const char *address_opt;
 static const char *net_idx_opt;
+static const char *config_opt;
 
 static uint16_t prov_address;
 static uint16_t prov_net_idx;
+static const char *cfg_fname;
 
 static const char **optargs[] = {
+       &config_opt,
        &address_opt,
        &net_idx_opt,
 };
 
 static const char *help[] = {
+       "Configuration file",
        "Starting unicast address for remote nodes",
        "Net index for provisioning subnet"
 };
@@ -147,7 +160,7 @@ static const char *help[] = {
 static const struct bt_shell_opt opt = {
        .options = options,
        .optno = sizeof(options) / sizeof(struct option),
-       .optstr = "a:n:",
+       .optstr = "c:a:n:",
        .optarg = optargs,
        .help = help,
 };
@@ -1623,18 +1636,65 @@ static void ready_callback(void *user_data)
                bt_shell_printf("Failed to register the ObjectManager\n");
 }
 
+static bool setup_cfg_storage(void)
+{
+       struct stat st;
+
+       if (!config_opt) {
+               char *home;
+               char *mesh_dir;
+
+               home = getenv("XDG_CONFIG_HOME");
+
+               if (home) {
+                       mesh_dir = l_strdup_printf("%s/meshcfg", home);
+               } else {
+                       home = getenv("HOME");
+                       if (!home) {
+                               l_error("\"HOME\" not set\n");
+                               return false;
+                       }
+
+                       mesh_dir = l_strdup_printf("%s/.config/meshcfg", home);
+               }
+
+               if (!mesh_dir)
+                       return false;
+
+               cfg_fname = l_strdup_printf("mesh_dir/%s", DEFAULT_CFG_FILE);
+               l_free(mesh_dir);
+
+       } else {
+               cfg_fname = l_strdup_printf("%s", config_opt);
+       }
+
+       if (stat(cfg_fname, &st) == -1) {
+               if (errno == ENOENT) {
+                       l_warn("\nWarning: config file \"%s\" not found",
+                                                               cfg_fname);
+                       return true;
+               }
+
+               perror("\nFailed to open config file");
+               return false;
+       }
+
+       have_config = true;
+       return true;
+}
+
 int main(int argc, char *argv[])
 {
        struct l_dbus_client *client;
        uint32_t val;
        int status;
 
-       l_log_set_stderr();
-
        bt_shell_init(argc, argv, &opt);
        bt_shell_set_menu(&main_menu);
        bt_shell_set_prompt(PROMPT_OFF);
 
+       l_log_set_stderr();
+
        if (address_opt && sscanf(address_opt, "%04x", &val) == 1)
                prov_address = (uint16_t) val;
        else
@@ -1645,6 +1705,11 @@ int main(int argc, char *argv[])
        else
                prov_net_idx = DEFAULT_NET_INDEX;
 
+       if (!setup_cfg_storage()) {
+               bt_shell_cleanup();
+               return EXIT_FAILURE;
+       }
+
        dbus = l_dbus_new_default(L_DBUS_SYSTEM_BUS);
 
        l_dbus_set_ready_handler(dbus, ready_callback, NULL, NULL);