+ argv[0] = c;
+
+ for(i = j = 1; argv[i]; ++i)
+ if (i != optind && strcmp(argv[i], "--") != 0)
+ argv[j++] = argv[i];
+
+ argv[j] = NULL;
+ execvp(c, argv);
+ fprintf(stderr, "Could not start %s: %s\n", c, strerror(errno));
+ return 1;
+}
+
+static int cmd_stop(int argc, char *argv[]) {
+#ifndef HAVE_MINGW
+ if(!connect_tincd())
+ return 1;
+
+ sendline(fd, "%d %d", CONTROL, REQ_STOP);
+ if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_STOP || result) {
+ fprintf(stderr, "Could not stop tinc daemon.\n");
+ return 1;
+ }
+#else
+ if(!remove_service())
+ return 1;
+#endif
+ return 0;
+}
+
+static int cmd_restart(int argc, char *argv[]) {
+ return cmd_stop(argc, argv) ?: cmd_start(argc, argv);
+}
+
+static int cmd_reload(int argc, char *argv[]) {
+ if(!connect_tincd())
+ return 1;
+
+ sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
+ if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RELOAD || result) {
+ fprintf(stderr, "Could not reload configuration.\n");
+ return 1;
+ }
+
+ return 0;
+
+}
+
+static int cmd_dump(int argc, char *argv[]) {
+ if(argc != 2) {
+ fprintf(stderr, "Invalid number of arguments.\n");
+ usage(true);
+ return 1;
+ }
+
+ bool do_graph = false;
+
+ if(!strcasecmp(argv[1], "nodes"))
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
+ else if(!strcasecmp(argv[1], "edges"))
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
+ else if(!strcasecmp(argv[1], "subnets"))
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS);
+ else if(!strcasecmp(argv[1], "connections"))
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS);
+ else if(!strcasecmp(argv[1], "graph")) {
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
+ do_graph = true;
+ } else {
+ fprintf(stderr, "Unknown dump type '%s'.\n", argv[1]);
+ usage(true);
+ return 1;
+ }
+
+ if(!connect_tincd())
+ return 1;
+
+ if(do_graph)
+ printf("digraph {\n");
+
+ while(recvline(fd, line, sizeof line)) {
+ char node1[4096], node2[4096];
+ int n = sscanf(line, "%d %d %s to %s", &code, &req, node1, node2);
+ if(n == 2) {
+ if(do_graph && req == REQ_DUMP_NODES)
+ continue;
+ else {
+ if(do_graph)
+ printf("}\n");
+ return 0;