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}
};
" [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"
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;
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
return 1;
}
+ if(!connect_tincd())
+ return 1;
+
bool do_graph = false;
if(!strcasecmp(argv[1], "nodes"))
return 1;
}
- if(!connect_tincd())
- return 1;
-
if(do_graph)
printf("digraph {\n");
return 1;
}
+ if(!check_id(argv[2])) {
+ fprintf(stderr, "Invalid name for node.\n");
+ return 1;
+ }
+
if(!connect_tincd())
return 1;
return 1;
}
+ if(!check_id(argv[2])) {
+ fprintf(stderr, "Invalid name for node.\n");
+ return 1;
+ }
+
if(!connect_tincd())
return 1;
}
}
+ if(node && !check_id(node)) {
+ fprintf(stderr, "Invalid name for node.\n");
+ return 1;
+ }
+
// Open the right configuration file.
char *filename;
if(node)
return 1;
}
+ // Silently try notifying a running tincd of changes.
+ fclose(stderr);
+
+ if(connect_tincd())
+ sendline(fd, "%d %d", CONTROL, REQ_RELOAD);
+
return 0;
}
+bool check_id(const char *name) {
+ for(int i = 0; i < strlen(name); i++) {
+ if(!isalnum(name[i]) && name[i] != '_')
+ return false;
+ }
+
+ return true;
+}
+
static int cmd_init(int argc, char *argv[]) {
if(!access(tinc_conf, F_OK)) {
fprintf(stderr, "Configuration file %s already exists!\n", tinc_conf);
}
}
- for(int i = 0; i < strlen(name); i++) {
- if(!isalnum(name[i]) && name[i] != '_') {
- fprintf(stderr, "Invalid Name! Only a-z, A-Z, 0-9 and _ are allowed characters.\n");
- return 1;
- }
+ if(!check_id(name)) {
+ fprintf(stderr, "Invalid Name! Only a-z, A-Z, 0-9 and _ are allowed characters.\n");
+ return 1;
}
if(mkdir(CONFDIR, 0755) && errno != EEXIST) {
return 0;
}
+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[]);
{"generate-ecdsa-keys", cmd_generate_ecdsa_keys},
{"help", cmd_help},
{"version", cmd_version},
+ {"edit", cmd_edit},
{NULL, NULL},
};