X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Ftincctl.c;h=00757c47a57b96d7c3f258acd92652be66e9cac1;hb=91355b9ac5a80d6d7da6951a72ea0c22651bdfa8;hp=fc59c580c36fffefa842f56465b2417b0b08ca77;hpb=3ccdf50beb6b2d3f2730bdc66006b43190537cde;p=tinc diff --git a/src/tincctl.c b/src/tincctl.c index fc59c580..00757c47 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -89,7 +89,7 @@ static struct option const long_options[] = { static void version(void) { printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR); - printf("Copyright (C) 1998-2014 Ivo Timmermans, Guus Sliepen and others.\n" + printf("Copyright (C) 1998-2015 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" "and you are welcome to redistribute it under certain conditions;\n" @@ -233,6 +233,12 @@ FILE *fopenmask(const char *filename, const char *mode, mode_t perms) { perms &= ~mask; umask(~perms); FILE *f = fopen(filename, mode); + + if(!f) { + fprintf(stderr, "Could not open %s: %s\n", filename, strerror(errno)); + return NULL; + } + #ifdef HAVE_FCHMOD if((perms & 0444) && f) fchmod(fileno(f), perms); @@ -853,6 +859,13 @@ static int cmd_start(int argc, char *argv[]) { } return status; #else + int pfd[2] = {-1, -1}; + if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) { + fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno)); + free(nargv); + return 1; + } + pid_t pid = fork(); if(pid == -1) { fprintf(stderr, "Could not fork: %s\n", strerror(errno)); @@ -860,8 +873,15 @@ static int cmd_start(int argc, char *argv[]) { return 1; } - if(!pid) + if(!pid) { + close(pfd[0]); + char buf[100] = ""; + snprintf(buf, sizeof buf, "%d", pfd[1]); + setenv("TINC_UMBILICAL", buf, true); exit(execvp(c, nargv)); + } else { + close(pfd[1]); + } free(nargv); @@ -869,12 +889,33 @@ static int cmd_start(int argc, char *argv[]) { #ifdef SIGINT signal(SIGINT, SIG_IGN); #endif + + // Pass all log messages from the umbilical to stderr. + // A nul-byte right before closure means tincd started succesfully. + bool failure = true; + char buf[1024]; + ssize_t len; + + while((len = read(pfd[0], buf, sizeof buf)) > 0) { + failure = buf[len - 1]; + if(!failure) + len--; + write(2, buf, len); + } + + if(len) + failure = true; + + close(pfd[0]); + + // Make sure the child process is really gone. result = waitpid(pid, &status, 0); + #ifdef SIGINT signal(SIGINT, SIG_DFL); #endif - if(result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) { + if(failure || result != pid || !WIFEXITED(status) || WEXITSTATUS(status)) { fprintf(stderr, "Error starting %s\n", c); return 1; } @@ -2558,7 +2599,7 @@ int main(int argc, char *argv[]) { if(!parse_options(argc, argv)) return 1; - make_names(); + make_names(false); xasprintf(&tinc_conf, "%s" SLASH "tinc.conf", confbase); xasprintf(&hosts_dir, "%s" SLASH "hosts", confbase);