swanctl: Read default socket from swanctl.socket option
[strongswan.git] / src / swanctl / command.c
index 29f6be9..7f65d2b 100644 (file)
@@ -80,7 +80,7 @@ static void build_opts()
        memset(command_optstring, 0, sizeof(command_optstring));
        if (active == help_idx)
        {
-               for (i = 0; cmds[i].cmd; i++)
+               for (i = 0; i < MAX_COMMANDS && cmds[i].cmd; i++)
                {
                        command_opts[i].name = cmds[i].cmd;
                        command_opts[i].val = cmds[i].op;
@@ -124,17 +124,8 @@ int command_getopt(char **arg)
                switch (op)
                {
                        case '+':
-                               if (!options->from(options, optarg, &argc, &argv, optind))
-                               {
-                                       /* a error value */
-                                       return 255;
-                               }
-                               continue;
                        case 'v':
-                               dbg_default_set_level(atoi(optarg));
-                               continue;
                        case 'u':
-                               uri = optarg;
                                continue;
                        default:
                                *arg = optarg;
@@ -185,6 +176,15 @@ void command_register(command_t command)
                                "uri",          'u', 1, "service URI to connect to"
                        };
                }
+               for (i = 0; cmds[registered].line[i]; i++)
+               {
+                       if (i == MAX_LINES - 1)
+                       {
+                               fprintf(stderr, "command '%s' specifies too many usage summary "
+                                               "lines, please increase MAX_LINES\n", command.cmd);
+                               break;
+                       }
+               }
        }
        registered++;
 }
@@ -218,15 +218,15 @@ int command_usage(char *error, ...)
        fprintf(out, "usage:\n");
        if (active == help_idx)
        {
-               for (i = 0; cmds[i].cmd; i++)
+               for (i = 0; i < MAX_COMMANDS && cmds[i].cmd; i++)
                {
-                       fprintf(out, "  swanctl --%-10s (-%c)  %s\n",
+                       fprintf(out, "  swanctl --%-16s (-%c)  %s\n",
                                        cmds[i].cmd, cmds[i].op, cmds[i].description);
                }
        }
        else
        {
-               for (i = 0; cmds[active].line[i]; i++)
+               for (i = 0; i < MAX_LINES && cmds[active].line[i]; i++)
                {
                        if (i == 0)
                        {
@@ -257,6 +257,37 @@ static void cleanup()
 }
 
 /**
+ * Process options common for all commands
+ */
+static bool process_common_opts()
+{
+       while (TRUE)
+       {
+               switch (getopt_long(argc, argv, command_optstring, command_opts, NULL))
+               {
+                       case '+':
+                               if (!options->from(options, optarg, &argc, &argv, optind))
+                               {
+                                       return FALSE;
+                               }
+                               continue;
+                       case 'v':
+                               dbg_default_set_level(atoi(optarg));
+                               continue;
+                       case 'u':
+                               uri = optarg;
+                               continue;
+                       default:
+                               continue;
+                       case '?':
+                               return FALSE;
+                       case EOF:
+                               return TRUE;
+               }
+       }
+}
+
+/**
  * Open vici connection, call a command
  */
 static int call_command(command_t *cmd)
@@ -267,9 +298,10 @@ static int call_command(command_t *cmd)
        conn = vici_connect(uri);
        if (!conn)
        {
+               ret = errno;
                command_usage("connecting to '%s' URI failed: %s",
                                          uri ?: "default", strerror(errno));
-               return errno;
+               return ret;
        }
        ret = cmd->call(conn);
        vici_disconnect(conn);
@@ -283,6 +315,10 @@ int command_dispatch(int c, char *v[])
 {
        int op, i;
 
+       uri = lib->settings->get_str(lib->settings, "%s.socket",
+                       lib->settings->get_str(lib->settings, "%s.plugins.vici.socket",
+                                                                  NULL, lib->ns), lib->ns);
+
        options = options_create();
        atexit(cleanup);
        active = help_idx = registered;
@@ -292,7 +328,7 @@ int command_dispatch(int c, char *v[])
 
        build_opts();
        op = getopt_long(c, v, command_optstring, command_opts, NULL);
-       for (i = 0; cmds[i].cmd; i++)
+       for (i = 0; i < MAX_COMMANDS && cmds[i].cmd; i++)
        {
                if (cmds[i].op == op)
                {
@@ -302,6 +338,11 @@ int command_dispatch(int c, char *v[])
                        {
                                return command_usage(NULL);
                        }
+                       if (!process_common_opts())
+                       {
+                               return command_usage("invalid options");
+                       }
+                       optind = 2;
                        return call_command(&cmds[i]);
                }
        }