diff options
author | Tobias Brunner <tobias@strongswan.org> | 2016-06-07 16:51:04 +0200 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2016-06-10 18:39:53 +0200 |
commit | f1064ca59a38a7cd0c5cfaa48d7b95ffe36321bb (patch) | |
tree | 73099dce2b500324462b43c573499515ffd7f266 /src/libcharon/plugins/resolve/resolve_handler.c | |
parent | f4a20b74fdf4affdae6042c4cbbfbc35cf6ce1bc (diff) | |
download | strongswan-f1064ca59a38a7cd0c5cfaa48d7b95ffe36321bb.tar.bz2 strongswan-f1064ca59a38a7cd0c5cfaa48d7b95ffe36321bb.tar.xz |
resolve: Use process abstraction when calling resolvconf
This allows us to capture output written to stderr/stdout.
Diffstat (limited to 'src/libcharon/plugins/resolve/resolve_handler.c')
-rw-r--r-- | src/libcharon/plugins/resolve/resolve_handler.c | 78 |
1 files changed, 60 insertions, 18 deletions
diff --git a/src/libcharon/plugins/resolve/resolve_handler.c b/src/libcharon/plugins/resolve/resolve_handler.c index aa0bea34d..f7b148c8d 100644 --- a/src/libcharon/plugins/resolve/resolve_handler.c +++ b/src/libcharon/plugins/resolve/resolve_handler.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2016 Tobias Brunner * Copyright (C) 2009 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR Hochschule fuer Technik Rapperswil * * 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 the @@ -21,6 +21,7 @@ #include <unistd.h> #include <utils/debug.h> +#include <utils/process.h> #include <threading/mutex.h> /* path to resolvconf executable */ @@ -148,38 +149,79 @@ static bool invoke_resolvconf(private_resolve_handler_t *this, identification_t *server, host_t *addr, bool install) { - char cmd[128]; + process_t *process; + FILE *shell; + int in, out, retval; /* we use the nameserver's IP address as part of the interface name to * make them unique */ - if (snprintf(cmd, sizeof(cmd), "%s %s %s%H", RESOLVCONF_EXEC, - install ? "-a" : "-d", this->iface_prefix, addr) >= sizeof(cmd)) + process = process_start_shell(NULL, install ? &in : NULL, &out, NULL, + "2>&1 %s %s %s%H", RESOLVCONF_EXEC, + install ? "-a" : "-d", this->iface_prefix, addr); + + if (!process) { return FALSE; } - if (install) { - FILE *out; - bool success; - - out = popen(cmd, "w"); - if (!out) + shell = fdopen(in, "w"); + if (shell) { - return FALSE; + DBG1(DBG_IKE, "installing DNS server %H via resolvconf", addr); + fprintf(shell, "nameserver %H\n", addr); + fclose(shell); } - DBG1(DBG_IKE, "installing DNS server %H via resolvconf", addr); - fprintf(out, "nameserver %H\n", addr); - success = !ferror(out); - if (pclose(out) || !success) + else { - invoke_resolvconf(this, server, addr, FALSE); + close(in); + close(out); + process->wait(process, NULL); return FALSE; } } else { - ignore_result(system(cmd)); + DBG1(DBG_IKE, "removing DNS server %H via resolvconf", addr); + } + shell = fdopen(out, "r"); + if (shell) + { + while (TRUE) + { + char resp[128], *e; + + if (fgets(resp, sizeof(resp), shell) == NULL) + { + if (ferror(shell)) + { + DBG1(DBG_IKE, "error reading from resolvconf"); + } + break; + } + else + { + e = resp + strlen(resp); + if (e > resp && e[-1] == '\n') + { + e[-1] = '\0'; + } + DBG1(DBG_IKE, "resolvconf: %s", resp); + } + } + fclose(shell); + } + else + { + close(out); + } + if (!process->wait(process, &retval) || retval != EXIT_SUCCESS) + { + if (install) + { /* revert changes when installing fails */ + invoke_resolvconf(this, server, addr, FALSE); + return FALSE; + } } return TRUE; } |