"tincctl info" gives more human readable information about nodes or subnets.
[tinc] / src / tincctl.c
index 523bbb4..f3a73b7 100644 (file)
@@ -25,6 +25,7 @@
 #include "protocol.h"
 #include "control_common.h"
 #include "ecdsagen.h"
+#include "info.h"
 #include "rsagen.h"
 #include "utils.h"
 #include "tincctl.h"
@@ -62,10 +63,18 @@ static struct WSAData wsa_state;
 
 static struct option const long_options[] = {
        {"config", required_argument, NULL, 'c'},
+       {"debug", optional_argument, NULL, 0},
+       {"no-detach", no_argument, NULL, 0},
+       {"mlock", no_argument, NULL, 0},
        {"net", required_argument, NULL, 'n'},
        {"help", no_argument, NULL, 1},
        {"version", no_argument, NULL, 2},
        {"pidfile", required_argument, NULL, 5},
+       {"logfile", required_argument, NULL, 0},
+       {"bypass-security", no_argument, NULL, 0},
+       {"chroot", no_argument, NULL, 0},
+       {"user", required_argument, NULL, 0},
+       {"option", required_argument, NULL, 0},
        {NULL, 0, NULL, 0}
 };
 
@@ -98,7 +107,7 @@ static void usage(bool status) {
                                "    [set] VARIABLE VALUE     - set VARIABLE to VALUE\n"
                                "    add VARIABLE VALUE       - add VARIABLE with the given VALUE\n"
                                "    del VARIABLE [VALUE]     - remove VARIABLE [only ones with watching VALUE]\n"
-                               "  start                      Start tincd.\n"
+                               "  start [tincd options]      Start tincd.\n"
                                "  stop                       Stop tincd.\n"
                                "  restart                    Restart tincd.\n"
                                "  reload                     Partially reload configuration of running tincd.\n"
@@ -112,6 +121,7 @@ static void usage(bool status) {
                                "    subnets                  - all known subnets in the VPN\n"
                                "    connections              - all meta connections with ourself\n"
                                "    graph                    - graph of the VPN in dotty format\n"
+                               "  info NODE|SUBNET|ADDRESS   Give information about a particular NODE, SUBNET or ADDRESS.\n"
                                "  purge                      Purge unreachable nodes\n"
                                "  debug N                    Set debug level\n"
                                "  retry                      Retry all outgoing connections\n"
@@ -130,7 +140,7 @@ static bool parse_options(int argc, char **argv) {
        int r;
        int option_index = 0;
 
-       while((r = getopt_long(argc, argv, "c:n:", long_options, &option_index)) != EOF) {
+       while((r = getopt_long(argc, argv, "c:n:Dd::Lo:RU:", long_options, &option_index)) != EOF) {
                switch (r) {
                        case 0:                         /* long option */
                                break;
@@ -655,6 +665,9 @@ static bool connect_tincd() {
 static int cmd_start(int argc, char *argv[]) {
        int i, j;
        char *c;
+
+       argc += optind;
+       argv -= optind;
        char *slash = strrchr(argv[0], '/');
 
 #ifdef HAVE_MINGW
@@ -723,6 +736,9 @@ static int cmd_dump(int argc, char *argv[]) {
                return 1;
        }
 
+       if(!connect_tincd())
+               return 1;
+
        bool do_graph = false;
 
        if(!strcasecmp(argv[1], "nodes"))
@@ -743,9 +759,6 @@ static int cmd_dump(int argc, char *argv[]) {
                return 1;
        }
 
-       if(!connect_tincd())
-               return 1;
-
        if(do_graph)
                printf("digraph {\n");
 
@@ -1163,6 +1176,12 @@ static int cmd_config(int argc, char *argv[]) {
                return 1;
        }
 
+       // Silently try notifying a running tincd of changes.
+       fclose(stderr);
+
+       if(connect_tincd())
+               sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
+
        return 0;
 }
 
@@ -1269,6 +1288,81 @@ static int cmd_version(int argc, char *argv[]) {
        return 0;
 }
 
+static int cmd_info(int argc, char *argv[]) {
+       if(argc != 2) {
+               fprintf(stderr, "Invalid number of arguments.\n");
+               return 1;
+       }
+
+       if(!connect_tincd())
+               return 1;
+
+       return info(fd, argv[1]);
+}
+
+static const char *conffiles[] = {
+       "tinc.conf",
+       "tinc-up",
+       "tinc-down",
+       "subnet-up",
+       "subnet-down",
+       "host-up",
+       "host-down",
+       NULL,
+};
+
+static int cmd_edit(int argc, char *argv[]) {
+       if(argc != 2) {
+               fprintf(stderr, "Invalid number of arguments.\n");
+               return 1;
+       }
+
+       char *filename = NULL;
+
+       if(strncmp(argv[1], "hosts/", 6)) {
+               for(int i = 0; conffiles[i]; i++) {
+                       if(!strcmp(argv[1], conffiles[i])) {
+                               xasprintf(&filename, "%s/%s", confbase, argv[1]);
+                               break;
+                       }
+               }
+       } else {
+               argv[1] += 6;
+       }
+
+       if(!filename) {
+               xasprintf(&filename, "%s/%s", hosts_dir, argv[1]);
+               char *dash = strchr(argv[1], '-');
+               if(dash) {
+                       *dash++ = 0;
+                       if((strcmp(dash, "up") && strcmp(dash, "down")) || !check_id(argv[1])) {
+                               fprintf(stderr, "Invalid configuration filename.\n");
+                               return 1;
+                       }
+               }
+       }
+
+#ifndef HAVE_MINGW
+       char *editor = getenv("VISUAL") ?: getenv("EDITOR") ?: "vi";
+#else
+       char *editor = "edit"
+#endif
+
+       char *command;
+       xasprintf(&command, "\"%s\" \"%s\"", editor, filename);
+       int result = system(command);
+       if(result)
+               return result;
+
+       // Silently try notifying a running tincd of changes.
+       fclose(stderr);
+
+       if(connect_tincd())
+               sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
+
+       return 0;
+}
+
 static const struct {
        const char *command;
        int (*function)(int argc, char *argv[]);
@@ -1294,6 +1388,8 @@ static const struct {
        {"generate-ecdsa-keys", cmd_generate_ecdsa_keys},
        {"help", cmd_help},
        {"version", cmd_version},
+       {"info", cmd_info},
+       {"edit", cmd_edit},
        {NULL, NULL},
 };