/*
tincctl.c -- Controlling a running tincd
- Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
"\n"
"Valid commands are:\n"
" init [name] Create initial configuration files.\n"
- " config Change configuration:\n"
- " [get] VARIABLE - print current value of VARIABLE\n"
- " [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"
+ " get VARIABLE Print current value of VARIABLE\n"
+ " 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 [tincd options] Start tincd.\n"
" stop Stop tincd.\n"
" restart Restart tincd.\n"
}
#endif
+#ifndef HAVE_MINGW
+ struct sockaddr_un sa;
+ sa.sun_family = AF_UNIX;
+ strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path);
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if(fd < 0) {
+ if(verbose)
+ fprintf(stderr, "Cannot create UNIX socket: %s\n", sockstrerror(sockerrno));
+ return false;
+ }
+
+ if(connect(fd, (struct sockaddr *)&sa, sizeof sa) < 0) {
+ if(verbose)
+ fprintf(stderr, "Cannot connect to UNIX socket %s: %s\n", unixsocketname, sockstrerror(sockerrno));
+ close(fd);
+ fd = -1;
+ return false;
+ }
+#else
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
}
freeaddrinfo(res);
+#endif
char data[4096];
int version;
}
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;
- }
- // Wait for tincd to close the connection...
- fd_set r;
- FD_ZERO(&r);
- FD_SET(fd, &r);
- select(fd + 1, &r, NULL, NULL, NULL);
+ while(recvline(fd, line, sizeof line)) {
+ // Wait for tincd to close the connection...
+ }
#else
if(!remove_service())
return 1;
top(fd);
return 0;
#else
- fprintf(stderr, "This version of tincctl was compiled without support for the curses library.\n");
+ fprintf(stderr, "This version of tinc was compiled without support for the curses library.\n");
return 1;
#endif
}
return len;
}
-static char *get_my_name() {
+static char *get_my_name(bool verbose) {
FILE *f = fopen(tinc_conf, "r");
if(!f) {
- fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno));
+ if(verbose)
+ fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno));
return NULL;
}
}
fclose(f);
- fprintf(stderr, "Could not find Name in %s.\n", tinc_conf);
+ if(verbose)
+ fprintf(stderr, "Could not find Name in %s.\n", tinc_conf);
return NULL;
}
return 1;
}
+ if(strcasecmp(argv[0], "config"))
+ argv--, argc++;
+
int action = -2;
if(!strcasecmp(argv[1], "get")) {
argv++, argc--;
/* Should this go into our own host config file? */
if(!node && !(variables[i].type & VAR_SERVER)) {
- node = get_my_name();
+ node = get_my_name(true);
if(!node)
return 1;
}
return 1;
}
+ if(!name)
+ name = get_my_name(false);
+
return !(rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true) && ecdsa_keygen(true));
}
return 1;
}
+ if(!name)
+ name = get_my_name(false);
+
return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true);
}
return 1;
}
+ if(!name)
+ name = get_my_name(false);
+
return !ecdsa_keygen(true);
}
return 1;
}
- char *name = get_my_name();
+ char *name = get_my_name(true);
if(!name)
return 1;
int result = export(name, stdout);
if(!tty)
fclose(stdout);
+
+ free(name);
return result;
}
{"log", cmd_log},
{"pid", cmd_pid},
{"config", cmd_config},
+ {"add", cmd_config},
+ {"del", cmd_config},
+ {"get", cmd_config},
+ {"set", cmd_config},
+ {"change", cmd_config},
+ {"replace", cmd_config},
{"init", cmd_init},
{"generate-keys", cmd_generate_keys},
{"generate-rsa-keys", cmd_generate_rsa_keys},