X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Ftincctl.c;h=b15676c88f55f4e9423bd384f5a9e5aba132620e;hb=1ac9a3fbd18f961d604c2c080374b8fc32f155d6;hp=18fc05ac1aa66ac87ae7e97c0c77de3004374a1d;hpb=bfce56d473e1e01a8af0260262ca84f09154e71f;p=tinc diff --git a/src/tincctl.c b/src/tincctl.c index 18fc05ac..b15676c8 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -38,6 +38,7 @@ #include "utils.h" #include "tincctl.h" #include "top.h" +#include "version.h" #ifndef MSG_NOSIGNAL #define MSG_NOSIGNAL 0 @@ -74,6 +75,7 @@ char *scriptextension = ""; static char *prompt; static struct option const long_options[] = { + {"batch", no_argument, NULL, 'b'}, {"config", required_argument, NULL, 'c'}, {"net", required_argument, NULL, 'n'}, {"help", no_argument, NULL, 1}, @@ -85,7 +87,7 @@ static struct option const long_options[] = { static void version(void) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, - VERSION, __DATE__, __TIME__, PROT_MAJOR, PROT_MINOR); + VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); printf("Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen and others.\n" "See the AUTHORS file for a complete list.\n\n" "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n" @@ -99,6 +101,7 @@ static void usage(bool status) { } else { printf("Usage: %s [options] command\n\n", program_name); printf("Valid options are:\n" + " -b, --batch Don't ask for anything (non-interactive mode).\n" " -c, --config=DIR Read configuration options from DIR.\n" " -n, --net=NETNAME Connect to net NETNAME.\n" " --pidfile=FILENAME Read control cookie from FILENAME.\n" @@ -157,6 +160,10 @@ static bool parse_options(int argc, char **argv) { case 0: /* long option */ break; + case 'b': + tty = false; + break; + case 'c': /* config file */ confbase = xstrdup(optarg); confbasegiven = true; @@ -756,7 +763,7 @@ bool connect_tincd(bool verbose) { #ifdef SO_NOSIGPIPE static const int one = 1; - setsockopt(c, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof one); + setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&one, sizeof one); #endif char data[4096]; @@ -809,16 +816,31 @@ static int cmd_start(int argc, char *argv[]) { int nargc = 0; char **nargv = xzalloc((optind + argc) * sizeof *nargv); - nargv[nargc++] = c; + char *arg0 = c; +#ifdef HAVE_MINGW + /* + Windows has no real concept of an "argv array". A command line is just one string. + The CRT of the new process will decode the command line string to generate argv before calling main(), and (by convention) + it uses quotes to handle spaces in arguments. + Therefore we need to quote all arguments that might contain spaces. No, execvp() won't do that for us (see MSDN). + If we don't do that, then execvp() will run fine but any spaces in the filename contained in arg0 will bleed + into the next arguments when the spawned process' CRT parses its command line, resulting in chaos. + */ + xasprintf(&arg0, "\"%s\"", arg0); +#endif + nargv[nargc++] = arg0; for(int i = 1; i < optind; i++) nargv[nargc++] = orig_argv[i]; for(int i = 1; i < argc; i++) nargv[nargc++] = argv[i]; #ifdef HAVE_MINGW - execvp(c, nargv); - fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno)); - return 1; + int status = spawnvp(_P_WAIT, c, nargv); + if (status == -1) { + fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno)); + return 1; + } + return status; #else pid_t pid = fork(); if(pid == -1) { @@ -1283,7 +1305,7 @@ char *get_my_name(bool verbose) { continue; if(*value) { fclose(f); - return strdup(value); + return replace_name(value); } } @@ -1613,9 +1635,12 @@ static int cmd_config(int argc, char *argv[]) { } if(action < -1) { - if(!found) + if(found) { + return 0; + } else { fprintf(stderr, "No matching configuration variables found.\n"); - return 1; + return 1; + } } // Make sure we wrote everything... @@ -1650,18 +1675,6 @@ static int cmd_config(int argc, char *argv[]) { return 0; } -bool check_id(const char *name) { - if(!name || !*name) - return false; - - for(int i = 0; i < strlen(name); i++) { - if(!isalnum(name[i]) && name[i] != '_') - return false; - } - - return true; -} - static bool try_bind(int port) { struct addrinfo *ai = NULL; struct addrinfo hint = { @@ -2423,6 +2436,7 @@ int main(int argc, char *argv[]) { program_name = argv[0]; orig_argv = argv; orig_argc = argc; + tty = isatty(0) && isatty(1); if(!parse_options(argc, argv)) return 1; @@ -2453,8 +2467,6 @@ int main(int argc, char *argv[]) { srand(time(NULL)); crypto_init(); - tty = isatty(0) && isatty(1); - if(optind >= argc) return cmd_shell(argc, argv);