+ if(!strcasecmp(argv[optind], "pid")) {
+ printf("%d\n", pid);
+ return 0;
+ }
+
+ if(!strcasecmp(argv[optind], "stop")) {
+ 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;
+ }
+ return 0;
+ }
+
+ if(!strcasecmp(argv[optind], "reload")) {
+ 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 tinc daemon\n");
+ return 1;
+ }
+ return 0;
+ }
+
+ if(!strcasecmp(argv[optind], "restart")) {
+ sendline(fd, "%d %d", CONTROL, REQ_RESTART);
+ if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RESTART || result) {
+ fprintf(stderr, "Could not restart tinc daemon\n");
+ return 1;
+ }
+ return 0;
+ }
+
+ if(!strcasecmp(argv[optind], "retry")) {
+ sendline(fd, "%d %d", CONTROL, REQ_RETRY);
+ if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &req, &result) != 3 || code != CONTROL || req != REQ_RETRY || result) {
+ fprintf(stderr, "Could not retry outgoing connections\n");
+ return 1;
+ }
+ return 0;
+ }
+
+ if(!strcasecmp(argv[optind], "dump")) {
+ if(argc < optind + 2) {
+ fprintf(stderr, "Not enough arguments.\n");
+ usage(true);
+ return 1;
+ }
+
+ bool do_graph = false;
+
+ if(!strcasecmp(argv[optind+1], "nodes"))
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
+ else if(!strcasecmp(argv[optind+1], "edges"))
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
+ else if(!strcasecmp(argv[optind+1], "subnets"))
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_SUBNETS);
+ else if(!strcasecmp(argv[optind+1], "connections"))
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_CONNECTIONS);
+ else if(!strcasecmp(argv[optind+1], "graph")) {
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_NODES);
+ sendline(fd, "%d %d", CONTROL, REQ_DUMP_EDGES);
+ do_graph = true;
+ printf("digraph {\n");
+ } else {
+ fprintf(stderr, "Unknown dump type '%s'.\n", argv[optind+1]);
+ usage(true);
+ return 1;
+ }
+
+ 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;
+ }
+ }
+ if(n < 2)
+ break;