summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-06-17 09:57:22 +0200
committerEelco Dolstra <edolstra@gmail.com>2019-06-25 12:45:59 +0200
commit09dde33c19129b949a064d35e248a3e318178b08 (patch)
treee0158028616c7f27869700b68b29ecde270e7399
parent5600b070a766b83200a68d3632793917cf19a550 (diff)
Automatically use --no-net if there are no network interfaces
(cherry picked from commit 04a59769963fe2a28d10ba15de743fe499333c80)
-rw-r--r--src/libmain/common-args.cc11
-rw-r--r--src/nix/main.cc55
2 files changed, 55 insertions, 11 deletions
diff --git a/src/libmain/common-args.cc b/src/libmain/common-args.cc
index 0486932b2..9e1d7cee6 100644
--- a/src/libmain/common-args.cc
+++ b/src/libmain/common-args.cc
@@ -1,6 +1,5 @@
#include "common-args.hh"
#include "globals.hh"
-#include "download.hh"
namespace nix {
@@ -45,16 +44,6 @@ MixCommonArgs::MixCommonArgs(const string & programName)
settings.set("max-jobs", s);
});
- mkFlag()
- .longName("no-net")
- .description("disable substituters and consider all previously downloaded files up-to-date")
- .handler([]() {
- settings.useSubstitutes = false;
- settings.tarballTtl = std::numeric_limits<unsigned int>::max();
- downloadSettings.tries = 0;
- downloadSettings.connectTimeout = 1;
- });
-
std::string cat = "config";
globalConfig.convertToArgs(*this, cat);
diff --git a/src/nix/main.cc b/src/nix/main.cc
index 19bb7a543..73c4b8db1 100644
--- a/src/nix/main.cc
+++ b/src/nix/main.cc
@@ -8,19 +8,52 @@
#include "shared.hh"
#include "store-api.hh"
#include "progress-bar.hh"
+#include "download.hh"
#include "finally.hh"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <ifaddrs.h>
+#include <netdb.h>
+
extern std::string chrootHelperName;
void chrootHelper(int argc, char * * argv);
namespace nix {
+/* Check if we have a non-loopback/link-local network interface. */
+static bool haveInternet()
+{
+ struct ifaddrs * addrs;
+
+ if (getifaddrs(&addrs))
+ return true;
+
+ Finally free([&]() { freeifaddrs(addrs); });
+
+ for (auto i = addrs; i; i = i->ifa_next) {
+ if (!i->ifa_addr) continue;
+ if (i->ifa_addr->sa_family == AF_INET) {
+ if (ntohl(((sockaddr_in *) i->ifa_addr)->sin_addr.s_addr) != INADDR_LOOPBACK) {
+ return true;
+ }
+ } else if (i->ifa_addr->sa_family == AF_INET6) {
+ if (!IN6_IS_ADDR_LOOPBACK(((sockaddr_in6 *) i->ifa_addr)->sin6_addr.s6_addr) &&
+ !IN6_IS_ADDR_LINKLOCAL(((sockaddr_in6 *) i->ifa_addr)->sin6_addr.s6_addr))
+ return true;
+ }
+ }
+
+ return false;
+}
+
std::string programPath;
struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
{
bool printBuildLogs = false;
+ bool useNet = true;
NixArgs() : MultiCommand(*RegisterCommand::commands), MixCommonArgs("nix")
{
@@ -53,6 +86,11 @@ struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
.longName("version")
.description("show version information")
.handler([&]() { printVersion(programName); });
+
+ mkFlag()
+ .longName("no-net")
+ .description("disable substituters and consider all previously downloaded files up-to-date")
+ .handler([&]() { useNet = false; });
}
void printFlags(std::ostream & out) override
@@ -108,6 +146,23 @@ void mainWrapped(int argc, char * * argv)
startProgressBar(args.printBuildLogs);
+ if (args.useNet && !haveInternet()) {
+ warn("you don't have Internet access; disabling some network-dependent features");
+ args.useNet = false;
+ }
+
+ if (!args.useNet) {
+ // FIXME: should check for command line overrides only.
+ if (!settings.useSubstitutes.overriden)
+ settings.useSubstitutes = false;
+ if (!settings.tarballTtl.overriden)
+ settings.tarballTtl = std::numeric_limits<unsigned int>::max();
+ if (!downloadSettings.tries.overriden)
+ downloadSettings.tries = 0;
+ if (!downloadSettings.connectTimeout.overriden)
+ downloadSettings.connectTimeout = 1;
+ }
+
args.command->prepare();
args.command->run();
}