+ if(fullread(fd, &greeting, sizeof greeting) == -1) {
+ fprintf(stderr, _("Cannot read greeting from control socket: %s\n"),
+ strerror(errno));
+ return 1;
+ }
+
+ if(greeting.version != TINC_CTL_VERSION_CURRENT) {
+ fprintf(stderr, _("Version mismatch: server %d, client %d\n"),
+ greeting.version, TINC_CTL_VERSION_CURRENT);
+ return 1;
+ }
+
+ struct ucred cred;
+ socklen_t credlen = sizeof cred;
+
+ if(getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cred, &credlen) < 0) {
+ fprintf(stderr, _("Could not obtain PID: %s\n"), strerror(errno));
+ return 1;
+ }
+
+ if(!strcasecmp(argv[optind], "pid")) {
+ printf("%d\n", cred.pid);
+ return 0;
+ }
+
+ if(!strcasecmp(argv[optind], "stop")) {
+ return send_ctl_request_cooked(fd, REQ_STOP, NULL, 0) != -1;
+ }
+
+ if(!strcasecmp(argv[optind], "reload")) {
+ return send_ctl_request_cooked(fd, REQ_RELOAD, NULL, 0) != -1;
+ }
+
+ if(!strcasecmp(argv[optind], "restart")) {
+ return send_ctl_request_cooked(fd, REQ_RESTART, NULL, 0) != -1;
+ }
+
+ if(!strcasecmp(argv[optind], "dump")) {
+ if (argc < optind + 2) {
+ fprintf(stderr, _("Not enough arguments.\n"));
+ usage(true);
+ return 1;
+ }
+
+ if(!strcasecmp(argv[optind+1], "nodes")) {
+ return send_ctl_request_cooked(fd, REQ_DUMP_NODES, NULL, 0) != -1;
+ }
+
+ if(!strcasecmp(argv[optind+1], "edges")) {
+ return send_ctl_request_cooked(fd, REQ_DUMP_EDGES, NULL, 0) != -1;
+ }
+
+ if(!strcasecmp(argv[optind+1], "subnets")) {
+ return send_ctl_request_cooked(fd, REQ_DUMP_SUBNETS, NULL, 0) != -1;
+ }
+
+ if(!strcasecmp(argv[optind+1], "connections")) {
+ return send_ctl_request_cooked(fd, REQ_DUMP_CONNECTIONS, NULL, 0) != -1;
+ }
+
+ if(!strcasecmp(argv[optind+1], "graph")) {
+ return send_ctl_request_cooked(fd, REQ_DUMP_GRAPH, NULL, 0) != -1;
+ }
+
+ fprintf(stderr, _("Unknown dump type '%s'.\n"), argv[optind+1]);
+ usage(true);
+ return 1;
+ }
+
+ if(!strcasecmp(argv[optind], "purge")) {
+ return send_ctl_request_cooked(fd, REQ_PURGE, NULL, 0) != -1;
+ }
+
+ if(!strcasecmp(argv[optind], "debug")) {
+ int debuglevel;
+
+ if(argc != optind + 2) {
+ fprintf(stderr, "Invalid arguments.\n");
+ return 1;
+ }
+ debuglevel = atoi(argv[optind+1]);
+ return send_ctl_request_cooked(fd, REQ_SET_DEBUG, &debuglevel,
+ sizeof(debuglevel)) != -1;
+ }
+
+ if(!strcasecmp(argv[optind], "retry")) {
+ return send_ctl_request_cooked(fd, REQ_RETRY, NULL, 0) != -1;
+ }