about summary refs log tree commit diff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/GeneratePatches.pm.in333
-rw-r--r--scripts/Makefile.am17
-rw-r--r--scripts/NixConfig.pm.in17
-rw-r--r--scripts/NixManifest.pm.in350
-rw-r--r--scripts/SSH.pm52
-rwxr-xr-xscripts/build-remote.pl.in4
-rwxr-xr-x[-rw-r--r--]scripts/copy-from-other-stores.pl.in0
-rwxr-xr-x[-rw-r--r--]scripts/download-using-manifests.pl.in30
-rwxr-xr-x[-rw-r--r--]scripts/find-runtime-roots.pl.in0
-rwxr-xr-x[-rw-r--r--]scripts/nix-build.in0
-rwxr-xr-x[-rw-r--r--]scripts/nix-channel.in0
-rwxr-xr-x[-rw-r--r--]scripts/nix-collect-garbage.in0
-rwxr-xr-x[-rw-r--r--]scripts/nix-copy-closure.in69
-rwxr-xr-x[-rw-r--r--]scripts/nix-generate-patches.in6
-rwxr-xr-x[-rw-r--r--]scripts/nix-install-package.in9
-rwxr-xr-x[-rw-r--r--]scripts/nix-prefetch-url.in17
-rwxr-xr-x[-rw-r--r--]scripts/nix-pull.in20
-rwxr-xr-x[-rw-r--r--]scripts/nix-push.in9
-rwxr-xr-x[-rw-r--r--]scripts/nix-reduce-build.in0
-rwxr-xr-xscripts/update-manifest.pl52
20 files changed, 82 insertions, 903 deletions
diff --git a/scripts/GeneratePatches.pm.in b/scripts/GeneratePatches.pm.in
deleted file mode 100644
index 4bb5b05a8c9e..000000000000
--- a/scripts/GeneratePatches.pm.in
+++ /dev/null
@@ -1,333 +0,0 @@
-use strict;
-use File::Temp qw(tempdir);
-use File::stat;
-
-
-# Some patch generations options.
-
-# Max size of NAR archives to generate patches for.
-my $maxNarSize = $ENV{"NIX_MAX_NAR_SIZE"};
-$maxNarSize = 160 * 1024 * 1024 if !defined $maxNarSize;
-
-# If patch is bigger than this fraction of full archive, reject.
-my $maxPatchFraction = $ENV{"NIX_PATCH_FRACTION"};
-$maxPatchFraction = 0.60 if !defined $maxPatchFraction;
-
-my $timeLimit = $ENV{"NIX_BSDIFF_TIME_LIMIT"};
-$timeLimit = 180 if !defined $timeLimit;
-
-my $hashAlgo = "sha256";
-
-
-sub findOutputPaths {
-    my $narFiles = shift;
-
-    my %outPaths;
-    
-    foreach my $p (keys %{$narFiles}) {
-
-        # Ignore derivations.
-        next if ($p =~ /\.drv$/);
-        
-        # Ignore builders (too much ambiguity -- they're all called
-        # `builder.sh').
-        next if ($p =~ /\.sh$/);
-        next if ($p =~ /\.patch$/);
-        
-        # Don't bother including tar files etc.
-        next if ($p =~ /\.tar$/ || $p =~ /\.tar\.(gz|bz2|Z|lzma|xz)$/ || $p =~ /\.zip$/ || $p =~ /\.bin$/ || $p =~ /\.tgz$/ || $p =~ /\.rpm$/ || $p =~ /cvs-export$/ || $p =~ /fetchhg$/);
-
-        $outPaths{$p} = 1;
-    }
-
-    return %outPaths;
-}
-
-
-sub getNameVersion {
-    my $p = shift;
-    $p =~ /\/[0-9a-z]+((?:-[a-zA-Z][^\/-]*)+)([^\/]*)$/;
-    my $name = $1;
-    my $version = $2;
-    return undef unless defined $name && defined $version;
-    $name =~ s/^-//;
-    $version =~ s/^-//;
-    return ($name, $version);
-}
-
-
-# A quick hack to get a measure of the `distance' between two
-# versions: it's just the position of the first character that differs
-# (or 999 if they are the same).
-sub versionDiff {
-    my $s = shift;
-    my $t = shift;
-    my $i;
-    return 999 if $s eq $t;
-    for ($i = 0; $i < length $s; $i++) {
-        return $i if $i >= length $t or
-            substr($s, $i, 1) ne substr($t, $i, 1);
-    }
-    return $i;
-}
-
-
-sub getNarBz2 {
-    my $narPath = shift;
-    my $narFiles = shift;
-    my $storePath = shift;
-    
-    my $narFileList = $$narFiles{$storePath};
-    die "missing path $storePath" unless defined $narFileList;
-
-    my $narFile = @{$narFileList}[0];
-    die unless defined $narFile;
-
-    $narFile->{url} =~ /\/([^\/]+)$/;
-    die unless defined $1;
-    return "$narPath/$1";
-}
-
-
-sub containsPatch {
-    my $patches = shift;
-    my $storePath = shift;
-    my $basePath = shift;
-    my $patchList = $$patches{$storePath};
-    return 0 if !defined $patchList;
-    my $found = 0;
-    foreach my $patch (@{$patchList}) {
-        # !!! baseHash might differ
-        return 1 if $patch->{basePath} eq $basePath;
-    }
-    return 0;
-}
-
-
-sub generatePatches {
-    my ($srcNarFiles, $dstNarFiles, $srcPatches, $dstPatches, $narPath, $patchesPath, $patchesURL, $tmpDir) = @_;
-
-    my %srcOutPaths = findOutputPaths $srcNarFiles;
-    my %dstOutPaths = findOutputPaths $dstNarFiles;
-
-    # For each output path in the destination, see if we need to / can
-    # create a patch.
-
-    print STDERR "creating patches...\n";
-
-    foreach my $p (keys %dstOutPaths) {
-
-        # If exactly the same path already exists in the source, skip it.
-        next if defined $srcOutPaths{$p};
-    
-        print "  $p\n";
-
-        # If not, then we should find the paths in the source that are
-        # `most' likely to be present on a system that wants to
-        # install this path.
-
-        (my $name, my $version) = getNameVersion $p;
-        next unless defined $name && defined $version;
-
-        my @closest = ();
-        my $closestVersion;
-        my $minDist = -1; # actually, larger means closer
-
-        # Find all source paths with the same name.
-
-        foreach my $q (keys %srcOutPaths) {
-            (my $name2, my $version2) = getNameVersion $q;
-            next unless defined $name2 && defined $version2;
-
-            if ($name eq $name2) {
-
-                my $srcSystem = @{$$dstNarFiles{$p}}[0]->{system};
-                my $dstSystem = @{$$srcNarFiles{$q}}[0]->{system};
-                if (defined $srcSystem && defined $dstSystem && $srcSystem ne $dstSystem) {
-                    print "    SKIPPING $q due to different systems ($srcSystem vs. $dstSystem)\n";
-                    next;
-                }
-
-                # If the sizes differ too much, then skip.  This
-                # disambiguates between, e.g., a real component and a
-                # wrapper component (cf. Firefox in Nixpkgs).
-                my $srcSize = @{$$srcNarFiles{$q}}[0]->{size};
-                my $dstSize = @{$$dstNarFiles{$p}}[0]->{size};
-                my $ratio = $srcSize / $dstSize;
-                $ratio = 1 / $ratio if $ratio < 1;
-                # print "  SIZE $srcSize $dstSize $ratio $q\n";
-
-                if ($ratio >= 3) {
-                    print "    SKIPPING $q due to size ratio $ratio ($srcSize vs. $dstSize)\n";
-                    next;
-                }
-
-                # If there are multiple matching names, include the
-                # ones with the closest version numbers.
-                my $dist = versionDiff $version, $version2;
-                if ($dist > $minDist) {
-                    $minDist = $dist;
-                    @closest = ($q);
-                    $closestVersion = $version2;
-                } elsif ($dist == $minDist) {
-                    push @closest, $q;
-                }
-            }
-        }
-
-        if (scalar(@closest) == 0) {
-            print "    NO BASE: $p\n";
-            next;
-        }
-
-        foreach my $closest (@closest) {
-
-            # Generate a patch between $closest and $p.
-            print STDERR "  $p <- $closest\n";
-
-            # If the patch already exists, skip it.
-            if (containsPatch($srcPatches, $p, $closest) ||
-                containsPatch($dstPatches, $p, $closest))
-            {
-                print "    skipping, already exists\n";
-                next;
-            }
-
-            my $srcNarBz2 = getNarBz2 $narPath, $srcNarFiles, $closest;
-            my $dstNarBz2 = getNarBz2 $narPath, $dstNarFiles, $p;
-
-            if (! -f $srcNarBz2) {
-                warn "patch source archive $srcNarBz2 is missing\n";
-                next;
-            }
-
-            system("@bunzip2@ < $srcNarBz2 > $tmpDir/A") == 0
-                or die "cannot unpack $srcNarBz2";
-
-            if (stat("$tmpDir/A")->size >= $maxNarSize) {
-                print "    skipping, source is too large\n";
-                next;
-            }
-        
-            system("@bunzip2@ < $dstNarBz2 > $tmpDir/B") == 0
-                or die "cannot unpack $dstNarBz2";
-
-            if (stat("$tmpDir/B")->size >= $maxNarSize) {
-                print "    skipping, destination is too large\n";
-                next;
-            }
-        
-            my $time1 = time();
-            my $res = system("ulimit -t $timeLimit; @libexecdir@/bsdiff $tmpDir/A $tmpDir/B $tmpDir/DIFF");
-            my $time2 = time();
-            if ($res) {
-                warn "binary diff computation aborted after ", $time2 - $time1, " seconds\n";
-                next;
-            }
-
-            my $baseHash = `@bindir@/nix-hash --flat --type $hashAlgo --base32 $tmpDir/A` or die;
-            chomp $baseHash;
-
-            my $narHash = `@bindir@/nix-hash --flat --type $hashAlgo --base32 $tmpDir/B` or die;
-            chomp $narHash;
-
-            my $narDiffHash = `@bindir@/nix-hash --flat --type $hashAlgo --base32 $tmpDir/DIFF` or die;
-            chomp $narDiffHash;
-
-            my $narDiffSize = stat("$tmpDir/DIFF")->size;
-            my $dstNarBz2Size = stat($dstNarBz2)->size;
-
-            print "    size $narDiffSize; full size $dstNarBz2Size; ", $time2 - $time1, " seconds\n";
-        
-            if ($narDiffSize >= $dstNarBz2Size) {
-                print "    rejecting; patch bigger than full archive\n";
-                next;
-            }
-    
-            if ($narDiffSize / $dstNarBz2Size >= $maxPatchFraction) {
-                print "    rejecting; patch too large relative to full archive\n";
-                next;
-            }
-    
-            my $finalName = "$narDiffHash.nar-bsdiff";
-
-            if (-e "$patchesPath/$finalName") {
-                print "    not copying, already exists\n";
-            }
-
-            else {
-                system("cp '$tmpDir/DIFF' '$patchesPath/$finalName.tmp'") == 0
-                    or die "cannot copy diff";
-                rename("$patchesPath/$finalName.tmp", "$patchesPath/$finalName")
-                    or die "cannot rename $patchesPath/$finalName.tmp";
-            }
-        
-            # Add the patch to the manifest.
-            addPatch $dstPatches, $p,
-                { url => "$patchesURL/$finalName", hash => "$hashAlgo:$narDiffHash"
-                , size => $narDiffSize, basePath => $closest, baseHash => "$hashAlgo:$baseHash"
-                , narHash => "$hashAlgo:$narHash", patchType => "nar-bsdiff"
-                };
-        }
-    }
-}
-
-
-# Propagate useful patches from $srcPatches to $dstPatches.  A patch
-# is useful if it produces either paths in the $dstNarFiles or paths
-# that can be used as the base for other useful patches.
-sub propagatePatches {
-    my ($srcPatches, $dstNarFiles, $dstPatches) = @_;
-
-    print STDERR "propagating patches...\n";
-
-    my $changed;
-    do {
-        # !!! we repeat this to reach the transitive closure; inefficient
-        $changed = 0;
-
-        print STDERR "loop\n";
-
-        my %dstBasePaths;
-        foreach my $q (keys %{$dstPatches}) {
-            foreach my $patch (@{$$dstPatches{$q}}) {
-                $dstBasePaths{$patch->{basePath}} = 1;
-            }
-        }
-
-        foreach my $p (keys %{$srcPatches}) {
-            my $patchList = $$srcPatches{$p};
-
-            my $include = 0;
-
-            # Is path $p included in the destination?  If so, include
-            # patches that produce it.
-            $include = 1 if defined $$dstNarFiles{$p};
-
-            # Is path $p a path that serves as a base for paths in the
-            # destination?  If so, include patches that produce it.
-            # !!! check baseHash
-            $include = 1 if defined $dstBasePaths{$p};
-
-            if ($include) {
-                foreach my $patch (@{$patchList}) {
-                    $changed = 1 if addPatch $dstPatches, $p, $patch;
-                }
-            }
-        
-        }
-    
-    } while $changed;
-}
-
-
-# Add all new patches in $srcPatches to $dstPatches.
-sub copyPatches {
-    my ($srcPatches, $dstPatches) = @_;
-    foreach my $p (keys %{$srcPatches}) {
-        addPatch $dstPatches, $p, $_ foreach @{$$srcPatches{$p}};
-    }
-}
-
-
-return 1;
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 60bb0a9b8105..a5703760d1f7 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -3,20 +3,16 @@ bin_SCRIPTS = nix-collect-garbage \
   nix-install-package nix-channel nix-build \
   nix-copy-closure nix-generate-patches
 
-noinst_SCRIPTS = nix-profile.sh GeneratePatches.pm \
+noinst_SCRIPTS = nix-profile.sh \
   find-runtime-roots.pl build-remote.pl nix-reduce-build \
   copy-from-other-stores.pl nix-http-export.cgi
 
-nix-pull nix-push: NixManifest.pm NixConfig.pm download-using-manifests.pl
+nix-pull nix-push: download-using-manifests.pl
 
-install-exec-local: NixManifest.pm GeneratePatches.pm download-using-manifests.pl copy-from-other-stores.pl find-runtime-roots.pl
+install-exec-local: download-using-manifests.pl copy-from-other-stores.pl find-runtime-roots.pl
 	$(INSTALL) -d $(DESTDIR)$(sysconfdir)/profile.d
 	$(INSTALL_PROGRAM) nix-profile.sh $(DESTDIR)$(sysconfdir)/profile.d/nix.sh
 	$(INSTALL) -d $(DESTDIR)$(libexecdir)/nix
-	$(INSTALL_DATA) NixManifest.pm $(DESTDIR)$(libexecdir)/nix 
-	$(INSTALL_DATA) NixConfig.pm $(DESTDIR)$(libexecdir)/nix 
-	$(INSTALL_DATA) SSH.pm $(DESTDIR)$(libexecdir)/nix 
-	$(INSTALL_DATA) GeneratePatches.pm $(DESTDIR)$(libexecdir)/nix 
 	$(INSTALL_PROGRAM) find-runtime-roots.pl $(DESTDIR)$(libexecdir)/nix 
 	$(INSTALL_PROGRAM) build-remote.pl $(DESTDIR)$(libexecdir)/nix 
 	$(INSTALL) -d $(DESTDIR)$(libexecdir)/nix/substituters
@@ -30,10 +26,6 @@ EXTRA_DIST = nix-collect-garbage.in \
   nix-pull.in nix-push.in nix-profile.sh.in \
   nix-prefetch-url.in nix-install-package.in \
   nix-channel.in \
-  NixManifest.pm.in \
-  NixConfig.pm.in \
-  SSH.pm \
-  GeneratePatches.pm.in \
   nix-build.in \
   download-using-manifests.pl.in \
   copy-from-other-stores.pl.in \
@@ -43,3 +35,6 @@ EXTRA_DIST = nix-collect-garbage.in \
   nix-reduce-build.in \
   nix-http-export.cgi.in \
   nix-generate-patches.in
+
+clean:
+	rm -f $(bin_SCRIPTS) $(noinst_SCRIPTS)
diff --git a/scripts/NixConfig.pm.in b/scripts/NixConfig.pm.in
deleted file mode 100644
index aeb443aeed3a..000000000000
--- a/scripts/NixConfig.pm.in
+++ /dev/null
@@ -1,17 +0,0 @@
-use strict;
-
-sub readConfig {
-    my %config;
-    my $config = "@sysconfdir@/nix/nix.conf";
-    return unless -f $config;
-    
-    open CONFIG, "<$config" or die "cannot open `$config'";
-    while (<CONFIG>) {
-        /^\s*([\w|-]+)\s*=\s*(.*)$/ or next;
-        $config{$1} = $2;
-        print "|$1| -> |$2|\n";
-    }
-    close CONFIG;
-}
-
-return 1;
diff --git a/scripts/NixManifest.pm.in b/scripts/NixManifest.pm.in
deleted file mode 100644
index d080dcee7478..000000000000
--- a/scripts/NixManifest.pm.in
+++ /dev/null
@@ -1,350 +0,0 @@
-use strict;
-use DBI;
-use Cwd;
-use File::stat;
-use File::Path;
-use Fcntl ':flock';
-
-
-sub addNAR {
-    my ($narFiles, $storePath, $info) = @_;
-    
-    $$narFiles{$storePath} = []
-        unless defined $$narFiles{$storePath};
-
-    my $narFileList = $$narFiles{$storePath};
-
-    my $found = 0;
-    foreach my $narFile (@{$narFileList}) {
-        $found = 1 if $narFile->{url} eq $info->{url};
-    }
-    
-    push @{$narFileList}, $info if !$found;
-}
-
-
-sub addPatch {
-    my ($patches, $storePath, $patch) = @_;
-
-    $$patches{$storePath} = []
-        unless defined $$patches{$storePath};
-
-    my $patchList = $$patches{$storePath};
-
-    my $found = 0;
-    foreach my $patch2 (@{$patchList}) {
-        $found = 1 if
-            $patch2->{url} eq $patch->{url} &&
-            $patch2->{basePath} eq $patch->{basePath};
-    }
-    
-    push @{$patchList}, $patch if !$found;
-
-    return !$found;
-}
-
-
-sub readManifest_ {
-    my ($manifest, $addNAR, $addPatch) = @_;
-
-    open MANIFEST, "<$manifest"
-        or die "cannot open `$manifest': $!";
-
-    my $inside = 0;
-    my $type;
-
-    my $manifestVersion = 2;
-
-    my ($storePath, $url, $hash, $size, $basePath, $baseHash, $patchType);
-    my ($narHash, $narSize, $references, $deriver, $copyFrom, $system);
-
-    while (<MANIFEST>) {
-        chomp;
-        s/\#.*$//g;
-        next if (/^$/);
-
-        if (!$inside) {
-
-            if (/^\s*(\w*)\s*\{$/) {
-                $type = $1;
-                $type = "narfile" if $type eq "";
-                $inside = 1;
-                undef $storePath;
-                undef $url;
-                undef $hash;
-                undef $size;
-                undef $narHash;
-                undef $narSize;
-                undef $basePath;
-                undef $baseHash;
-                undef $patchType;
-                undef $system;
-                $references = "";
-                $deriver = "";
-	    }
-
-        } else {
-            
-            if (/^\}$/) {
-                $inside = 0;
-
-                if ($type eq "narfile") {
-                    &$addNAR($storePath,
-                        { url => $url, hash => $hash, size => $size
-                        , narHash => $narHash, narSize => $narSize
-                        , references => $references
-                        , deriver => $deriver
-                        , system => $system
-                        });
-                }
-
-                elsif ($type eq "patch") {
-                    &$addPatch($storePath,
-                        { url => $url, hash => $hash, size => $size
-                        , basePath => $basePath, baseHash => $baseHash
-                        , narHash => $narHash, narSize => $narSize
-                        , patchType => $patchType
-                        });
-                }
-
-            }
-            
-            elsif (/^\s*StorePath:\s*(\/\S+)\s*$/) { $storePath = $1; }
-            elsif (/^\s*CopyFrom:\s*(\/\S+)\s*$/) { $copyFrom = $1; }
-            elsif (/^\s*Hash:\s*(\S+)\s*$/) { $hash = $1; }
-            elsif (/^\s*URL:\s*(\S+)\s*$/) { $url = $1; }
-            elsif (/^\s*Size:\s*(\d+)\s*$/) { $size = $1; }
-            elsif (/^\s*SuccOf:\s*(\/\S+)\s*$/) { } # obsolete
-            elsif (/^\s*BasePath:\s*(\/\S+)\s*$/) { $basePath = $1; }
-            elsif (/^\s*BaseHash:\s*(\S+)\s*$/) { $baseHash = $1; }
-            elsif (/^\s*Type:\s*(\S+)\s*$/) { $patchType = $1; }
-            elsif (/^\s*NarHash:\s*(\S+)\s*$/) { $narHash = $1; }
-            elsif (/^\s*NarSize:\s*(\d+)\s*$/) { $narSize = $1; }
-            elsif (/^\s*References:\s*(.*)\s*$/) { $references = $1; }
-            elsif (/^\s*Deriver:\s*(\S+)\s*$/) { $deriver = $1; }
-            elsif (/^\s*ManifestVersion:\s*(\d+)\s*$/) { $manifestVersion = $1; }
-            elsif (/^\s*System:\s*(\S+)\s*$/) { $system = $1; }
-
-            # Compatibility;
-            elsif (/^\s*NarURL:\s*(\S+)\s*$/) { $url = $1; }
-            elsif (/^\s*MD5:\s*(\S+)\s*$/) { $hash = "md5:$1"; }
-
-        }
-    }
-
-    close MANIFEST;
-
-    return $manifestVersion;
-}
-
-
-sub readManifest {
-    my ($manifest, $narFiles, $patches) = @_;
-    readManifest_($manifest,
-        sub { addNAR($narFiles, @_); },
-        sub { addPatch($patches, @_); } );
-}
-
-
-sub writeManifest {
-    my ($manifest, $narFiles, $patches, $noCompress) = @_;
-
-    open MANIFEST, ">$manifest.tmp"; # !!! check exclusive
-
-    print MANIFEST "version {\n";
-    print MANIFEST "  ManifestVersion: 3\n";
-    print MANIFEST "}\n";
-
-    foreach my $storePath (sort (keys %{$narFiles})) {
-        my $narFileList = $$narFiles{$storePath};
-        foreach my $narFile (@{$narFileList}) {
-            print MANIFEST "{\n";
-            print MANIFEST "  StorePath: $storePath\n";
-            print MANIFEST "  NarURL: $narFile->{url}\n";
-            print MANIFEST "  Hash: $narFile->{hash}\n" if defined $narFile->{hash};
-            print MANIFEST "  Size: $narFile->{size}\n" if defined $narFile->{size};
-            print MANIFEST "  NarHash: $narFile->{narHash}\n";
-            print MANIFEST "  NarSize: $narFile->{narSize}\n" if $narFile->{narSize};
-            print MANIFEST "  References: $narFile->{references}\n"
-                if defined $narFile->{references} && $narFile->{references} ne "";
-            print MANIFEST "  Deriver: $narFile->{deriver}\n"
-                if defined $narFile->{deriver} && $narFile->{deriver} ne "";
-            print MANIFEST "  System: $narFile->{system}\n" if defined $narFile->{system};
-            print MANIFEST "}\n";
-        }
-    }
-    
-    foreach my $storePath (sort (keys %{$patches})) {
-        my $patchList = $$patches{$storePath};
-        foreach my $patch (@{$patchList}) {
-            print MANIFEST "patch {\n";
-            print MANIFEST "  StorePath: $storePath\n";
-            print MANIFEST "  NarURL: $patch->{url}\n";
-            print MANIFEST "  Hash: $patch->{hash}\n";
-            print MANIFEST "  Size: $patch->{size}\n";
-            print MANIFEST "  NarHash: $patch->{narHash}\n";
-            print MANIFEST "  NarSize: $patch->{narSize}\n" if $patch->{narSize};
-            print MANIFEST "  BasePath: $patch->{basePath}\n";
-            print MANIFEST "  BaseHash: $patch->{baseHash}\n";
-            print MANIFEST "  Type: $patch->{patchType}\n";
-            print MANIFEST "}\n";
-        }
-    }
-    
-    
-    close MANIFEST;
-
-    rename("$manifest.tmp", $manifest)
-        or die "cannot rename $manifest.tmp: $!";
-
-
-    # Create a bzipped manifest.
-    unless (defined $noCompress) {
-	system("@bzip2@ < $manifest > $manifest.bz2.tmp") == 0
-	    or die "cannot compress manifest";
-
-	rename("$manifest.bz2.tmp", "$manifest.bz2")
-	    or die "cannot rename $manifest.bz2.tmp: $!";
-    }
-}
-
-
-sub updateManifestDB {
-    my $manifestDir = ($ENV{"NIX_MANIFESTS_DIR"} or "@localstatedir@/nix/manifests");
-
-    mkpath($manifestDir);
-    
-    my $dbPath = "$manifestDir/cache.sqlite";
-
-    # Open/create the database.
-    our $dbh = DBI->connect("dbi:SQLite:dbname=$dbPath", "", "")
-        or die "cannot open database `$dbPath'";
-    $dbh->{RaiseError} = 1;
-    $dbh->{PrintError} = 0;
-
-    $dbh->do("pragma foreign_keys = on");
-    $dbh->do("pragma synchronous = off"); # we can always reproduce the cache
-    $dbh->do("pragma journal_mode = truncate");
-
-    # Initialise the database schema, if necessary.
-    $dbh->do(<<EOF);
-        create table if not exists Manifests (
-            id        integer primary key autoincrement not null,
-            path      text unique not null,
-            timestamp integer not null
-        );
-EOF
-    
-    $dbh->do(<<EOF);
-        create table if not exists NARs (
-            id               integer primary key autoincrement not null,
-            manifest         integer not null,
-            storePath        text not null,
-            url              text not null,
-            hash             text,
-            size             integer,
-            narHash          text,
-            narSize          integer,
-            refs             text,
-            deriver          text,
-            system           text,
-            foreign key (manifest) references Manifests(id) on delete cascade
-        );
-EOF
-
-    $dbh->do("create index if not exists NARs_storePath on NARs(storePath)");
-
-    $dbh->do(<<EOF);
-        create table if not exists Patches (
-            id               integer primary key autoincrement not null,
-            manifest         integer not null,
-            storePath        text not null,
-            basePath         text not null,
-            baseHash         text not null,
-            url              text not null,
-            hash             text,
-            size             integer,
-            narHash          text,
-            narSize          integer,
-            patchType        text not null,
-            foreign key (manifest) references Manifests(id) on delete cascade
-        );
-EOF
-
-    $dbh->do("create index if not exists Patches_storePath on Patches(storePath)");
-
-    # Acquire an exclusive lock to ensure that only one process
-    # updates the DB at the same time.  This isn't really necessary,
-    # but it prevents work duplication and lock contention in SQLite.
-    open MAINLOCK, ">>$manifestDir/cache.lock" or die;
-    flock(MAINLOCK, LOCK_EX) or die;
-
-    $dbh->begin_work;
-
-    # Read each manifest in $manifestDir and add it to the database,
-    # unless we've already done so on a previous run.
-    my %seen;
-    
-    for my $manifest (glob "$manifestDir/*.nixmanifest") {
-        $manifest = Cwd::abs_path($manifest);
-        my $timestamp = lstat($manifest)->mtime;
-        $seen{$manifest} = 1;
-
-        next if scalar @{$dbh->selectcol_arrayref(
-            "select 1 from Manifests where path = ? and timestamp = ?",
-            {}, $manifest, $timestamp)} == 1;
-
-        print STDERR "caching $manifest...\n";
-        
-        $dbh->do("delete from Manifests where path = ?", {}, $manifest);
-                 
-        $dbh->do("insert into Manifests(path, timestamp) values (?, ?)",
-                 {}, $manifest, $timestamp);
-
-        our $id = $dbh->last_insert_id("", "", "", "");
-
-        sub addNARToDB {
-            my ($storePath, $narFile) = @_;
-            $dbh->do(
-                "insert into NARs(manifest, storePath, url, hash, size, narHash, " .
-                "narSize, refs, deriver, system) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
-                {}, $id, $storePath, $narFile->{url}, $narFile->{hash}, $narFile->{size},
-                $narFile->{narHash}, $narFile->{narSize}, $narFile->{references},
-                $narFile->{deriver}, $narFile->{system});
-        };
-        
-        sub addPatchToDB {
-            my ($storePath, $patch) = @_;
-            $dbh->do(
-                "insert into Patches(manifest, storePath, basePath, baseHash, url, hash, " .
-                "size, narHash, narSize, patchType) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
-                {}, $id, $storePath, $patch->{basePath}, $patch->{baseHash}, $patch->{url},
-                $patch->{hash}, $patch->{size}, $patch->{narHash}, $patch->{narSize},
-                $patch->{patchType});
-        };
-
-        my $version = readManifest_($manifest, \&addNARToDB, \&addPatchToDB);
-        
-        if ($version < 3) {
-            die "you have an old-style manifest `$manifest'; please delete it";
-        }
-        if ($version >= 10) {
-            die "manifest `$manifest' is too new; please delete it or upgrade Nix";
-        }
-    }
-
-    # Removed cached information for removed manifests from the DB.
-    foreach my $manifest (@{$dbh->selectcol_arrayref("select path from Manifests")}) {
-        next if defined $seen{$manifest};
-        $dbh->do("delete from Manifests where path = ?", {}, $manifest);
-    }
-
-    $dbh->commit;
-
-    close MAINLOCK;
-
-    return $dbh;
-}
-
-
-return 1;
diff --git a/scripts/SSH.pm b/scripts/SSH.pm
deleted file mode 100644
index 68f4a628b072..000000000000
--- a/scripts/SSH.pm
+++ /dev/null
@@ -1,52 +0,0 @@
-use strict;
-use File::Temp qw(tempdir);
-
-our @sshOpts = split ' ', ($ENV{"NIX_SSHOPTS"} or "");
-
-push @sshOpts, "-x";
-
-my $sshStarted = 0;
-my $sshHost;
-
-# Open a master SSH connection to `host', unless there already is a
-# running master connection (as determined by `-O check').
-sub openSSHConnection {
-    my ($host) = @_;
-    die if $sshStarted;
-    $sshHost = $host;
-    return 1 if system("ssh $sshHost @sshOpts -O check 2> /dev/null") == 0;
-
-    my $tmpDir = tempdir("nix-ssh.XXXXXX", CLEANUP => 1, TMPDIR => 1)
-        or die "cannot create a temporary directory";
-    
-    push @sshOpts, "-S", "$tmpDir/control";
-
-    # Start the master.  We can't use the `-f' flag (fork into
-    # background after establishing the connection) because then the
-    # child continues to run if we are killed.  So instead make SSH
-    # print "started" when it has established the connection, and wait
-    # until we see that.
-    open SSHPIPE, "ssh $sshHost @sshOpts -M -N -o LocalCommand='echo started' -o PermitLocalCommand=yes |" or die;
-
-    while (<SSHPIPE>) {
-        chomp;
-        if ($_ eq "started") {
-            $sshStarted = 1;
-            return 1;
-        }
-    }
-
-    return 0;
-}
-
-# Tell the master SSH client to exit.
-sub closeSSHConnection {
-    if ($sshStarted) {
-        system("ssh $sshHost @sshOpts -O exit 2> /dev/null") == 0
-            or warn "unable to stop SSH master: $?";
-    }
-}
-
-END { my $saved = $?; closeSSHConnection; $? = $saved; }
-
-return 1;
diff --git a/scripts/build-remote.pl.in b/scripts/build-remote.pl.in
index e943b0d9e304..e8c76086dae2 100755
--- a/scripts/build-remote.pl.in
+++ b/scripts/build-remote.pl.in
@@ -1,9 +1,9 @@
-#! @perl@ -w -I@libexecdir@/nix
+#! @perl@ -w @perlFlags@
 
 use Fcntl ':flock';
 use English '-no_match_vars';
 use IO::Handle;
-use SSH qw/sshOpts openSSHConnection/;
+use Nix::SSH qw/sshOpts openSSHConnection/;
 no warnings('once');
 
 
diff --git a/scripts/copy-from-other-stores.pl.in b/scripts/copy-from-other-stores.pl.in
index 10130c0893ea..10130c0893ea 100644..100755
--- a/scripts/copy-from-other-stores.pl.in
+++ b/scripts/copy-from-other-stores.pl.in
diff --git a/scripts/download-using-manifests.pl.in b/scripts/download-using-manifests.pl.in
index ca4d97b51aa6..a827a995f919 100644..100755
--- a/scripts/download-using-manifests.pl.in
+++ b/scripts/download-using-manifests.pl.in
@@ -1,16 +1,14 @@
-#! @perl@ -w -I@libexecdir@/nix @perlFlags@
+#! @perl@ -w @perlFlags@
 
 use strict;
-use NixManifest;
+use Nix::Config;
+use Nix::Manifest;
 use POSIX qw(strftime);
 use File::Temp qw(tempdir);
 
-my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
-
 STDOUT->autoflush(1);
 
-my $manifestDir = ($ENV{"NIX_MANIFESTS_DIR"} or "@localstatedir@/nix/manifests");
-my $logFile = "@localstatedir@/log/nix/downloads";
+my $logFile = "$Nix::Config::logDir/downloads";
 
 # For queries, skip expensive calls to nix-hash etc.  We're just
 # estimating the expected download size.
@@ -26,7 +24,7 @@ sub isValidPath {
     if ($fast) {
         return -e $p;
     } else {
-        return system("$binDir/nix-store --check-validity '$p' 2> /dev/null") == 0;
+        return system("$Nix::Config::binDir/nix-store --check-validity '$p' 2> /dev/null") == 0;
     }
 }
 
@@ -108,8 +106,8 @@ sub computeSmallestDownload {
                     my $format = "--base32";
                     $format = "" if $baseHashAlgo eq "md5";
                     my $hash = $fast && $baseHashAlgo eq "sha256"
-                        ? `$binDir/nix-store -q --hash "$patch->{basePath}"`
-                        : `$binDir/nix-hash --type '$baseHashAlgo' $format "$patch->{basePath}"`;
+                        ? `$Nix::Config::binDir/nix-store -q --hash "$patch->{basePath}"`
+                        : `$Nix::Config::binDir/nix-hash --type '$baseHashAlgo' $format "$patch->{basePath}"`;
                     chomp $hash;
                     $hash =~ s/.*://;
                     next if $hash ne $baseHash;
@@ -282,7 +280,7 @@ sub downloadFile {
     my $url = shift; 
     $ENV{"PRINT_PATH"} = 1;
     $ENV{"QUIET"} = 1;
-    my ($hash, $path) = `$binDir/nix-prefetch-url '$url'`;
+    my ($hash, $path) = `$Nix::Config::binDir/nix-prefetch-url '$url'`;
     die "download of `$url' failed" . ($! ? ": $!" : "") unless $? == 0;
     chomp $path;
     return $path;
@@ -306,7 +304,7 @@ while (scalar @path > 0) {
             # as a base to one or more patches.  So turn the base path
             # into a NAR archive, to which we can apply the patch.
             print "  packing base path...\n";
-            system("$binDir/nix-store --dump $v > $tmpNar") == 0
+            system("$Nix::Config::binDir/nix-store --dump $v > $tmpNar") == 0
                 or die "cannot dump `$v'";
         }
     }
@@ -324,7 +322,7 @@ while (scalar @path > 0) {
         # Apply the patch to the NAR archive produced in step 1 (for
         # the already present path) or a later step (for patch sequences).
         print "  applying patch...\n";
-        system("@libexecdir@/bspatch $tmpNar $tmpNar2 $patchPath") == 0
+        system("$Nix::Config::libexecDir/bspatch $tmpNar $tmpNar2 $patchPath") == 0
             or die "cannot apply patch `$patchPath' to $tmpNar";
 
         if ($curStep < $maxStep) {
@@ -334,7 +332,7 @@ while (scalar @path > 0) {
             # This was the last patch.  Unpack the final NAR archive
             # into the target path.
             print "  unpacking patched archive...\n";
-            system("$binDir/nix-store --restore $v < $tmpNar2") == 0
+            system("$Nix::Config::binDir/nix-store --restore $v < $tmpNar2") == 0
                 or die "cannot unpack $tmpNar2 into `$v'";
         }
 
@@ -354,12 +352,12 @@ while (scalar @path > 0) {
 
         if ($curStep < $maxStep) {
             # The archive will be used a base to a patch.
-            system("@bunzip2@ < '$narFilePath' > $tmpNar") == 0
+            system("$Nix::Config::bzip2 -d < '$narFilePath' > $tmpNar") == 0
                 or die "cannot unpack `$narFilePath' into `$v'";
         } else {
             # Unpack the archive into the target path.
             print "  unpacking archive...\n";
-            system("@bunzip2@ < '$narFilePath' | $binDir/nix-store --restore '$v'") == 0
+            system("$Nix::Config::bzip2 -d < '$narFilePath' | $Nix::Config::binDir/nix-store --restore '$v'") == 0
                 or die "cannot unpack `$narFilePath' into `$v'";
         }
 
@@ -382,7 +380,7 @@ if (defined $finalNarHash) {
         ($hashAlgo eq "sha256" && length($hash) != 64)
         ? "--base32" : "";
     
-    my $hash2 = `@bindir@/nix-hash --type $hashAlgo $extraFlag $targetPath`
+    my $hash2 = `$Nix::Config::binDir/nix-hash --type $hashAlgo $extraFlag $targetPath`
         or die "cannot compute hash of path `$targetPath'";
     chomp $hash2;
     
diff --git a/scripts/find-runtime-roots.pl.in b/scripts/find-runtime-roots.pl.in
index 64c17419ff7b..64c17419ff7b 100644..100755
--- a/scripts/find-runtime-roots.pl.in
+++ b/scripts/find-runtime-roots.pl.in
diff --git a/scripts/nix-build.in b/scripts/nix-build.in
index d9d1da73b12f..d9d1da73b12f 100644..100755
--- a/scripts/nix-build.in
+++ b/scripts/nix-build.in
diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in
index 3688063cba4e..3688063cba4e 100644..100755
--- a/scripts/nix-channel.in
+++ b/scripts/nix-channel.in
diff --git a/scripts/nix-collect-garbage.in b/scripts/nix-collect-garbage.in
index f445c1c71256..f445c1c71256 100644..100755
--- a/scripts/nix-collect-garbage.in
+++ b/scripts/nix-collect-garbage.in
diff --git a/scripts/nix-copy-closure.in b/scripts/nix-copy-closure.in
index c037f003f0d0..172acd9e7da2 100644..100755
--- a/scripts/nix-copy-closure.in
+++ b/scripts/nix-copy-closure.in
@@ -1,8 +1,8 @@
-#! @perl@ -w -I@libexecdir@/nix
+#! @perl@ -w @perlFlags@
 
-use SSH;
-
-my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
+use Nix::SSH;
+use Nix::Config;
+use Nix::Store;
 
 
 if (scalar @ARGV < 1) {
@@ -24,6 +24,10 @@ my $decompressor = "";
 
 my $toMode = 1;
 
+my $includeOutputs = 0;
+
+my $dryRun = 0;
+
 
 # !!! Copied from nix-pack-closure, should put this in a module.
 my @storePaths = ();
@@ -44,6 +48,12 @@ while (@ARGV) {
     elsif ($arg eq "--to") {
         $toMode = 1;
     }
+    elsif ($arg eq "--include-outputs") {
+        $includeOutputs = 1;
+    }
+    elsif ($arg eq "--dry-run") {
+        $dryRun = 1;
+    }
     elsif (!defined $sshHost) {
         $sshHost = $arg;
     }
@@ -58,19 +68,8 @@ openSSHConnection $sshHost or die "$0: unable to start SSH\n";
 
 if ($toMode) { # Copy TO the remote machine.
 
-    my @allStorePaths;
-
     # Get the closure of this path.
-    my $pid = open(READ, "set -f; $binDir/nix-store --query --requisites @storePaths|") or die;
-    
-    while (<READ>) {
-        chomp;
-        die "bad: $_" unless /^\//;
-        push @allStorePaths, $_;
-    }
-
-    close READ or die "nix-store failed: $?";
-
+    my @allStorePaths = reverse(topoSortPaths(computeFSClosure(0, $includeOutputs, map { followLinksToStorePath $_ } @storePaths)));
 
     # Ask the remote host which paths are invalid.
     open(READ, "set -f; ssh $sshHost @sshOpts nix-store --check-validity --print-invalid @allStorePaths|");
@@ -81,57 +80,45 @@ if ($toMode) { # Copy TO the remote machine.
     }
     close READ or die;
 
-
     # Export the store paths and import them on the remote machine.
     if (scalar @missing > 0) {
         print STDERR "copying these missing paths:\n";
         print STDERR "  $_\n" foreach @missing;
-        my $extraOpts = "";
-        $extraOpts .= "--sign" if $sign == 1;
-        system("set -f; nix-store --export $extraOpts @missing $compressor | ssh $sshHost @sshOpts '$decompressor nix-store --import'") == 0
-            or die "copying store paths to remote machine `$sshHost' failed: $?";
+        unless ($dryRun) {
+            my $extraOpts = $sign ? "--sign" : "";
+            system("set -f; nix-store --export $extraOpts @missing $compressor | ssh $sshHost @sshOpts '$decompressor nix-store --import'") == 0
+                or die "copying store paths to remote machine `$sshHost' failed: $?";
+        }
     }
 
 }
 
-
 else { # Copy FROM the remote machine.
 
     # Query the closure of the given store paths on the remote
     # machine.  Paths are assumed to be store paths; there is no
     # resolution (following of symlinks).
+    my $extraOpts = $includeOutputs ? "--include-outputs" : "";
     my $pid = open(READ,
-        "set -f; ssh @sshOpts $sshHost nix-store --query --requisites @storePaths|") or die;
+        "set -f; ssh @sshOpts $sshHost nix-store --query --requisites $extraOpts @storePaths|") or die;
     
-    my @allStorePaths;
-
     while (<READ>) {
         chomp;
         die "bad: $_" unless /^\//;
-        push @allStorePaths, $_;
+        push @missing, $_ unless isValidPath($_);
     }
 
     close READ or die "nix-store on remote machine `$sshHost' failed: $?";
 
-
-    # What paths are already valid locally?
-    open(READ, "set -f; @bindir@/nix-store --check-validity --print-invalid @allStorePaths|");
-    my @missing = ();
-    while (<READ>) {
-        chomp;
-        push @missing, $_;
-    }
-    close READ or die;
-    
-
     # Export the store paths on the remote machine and import them on locally.
     if (scalar @missing > 0) {
         print STDERR "copying these missing paths:\n";
         print STDERR "  $_\n" foreach @missing;
-        my $extraOpts = "";
-        $extraOpts .= "--sign" if $sign == 1;
-        system("set -f; ssh $sshHost @sshOpts 'nix-store --export $extraOpts @missing $compressor' | $decompressor @bindir@/nix-store --import") == 0
-            or die "copying store paths from remote machine `$sshHost' failed: $?";
+        unless ($dryRun) {
+            my $extraOpts = $sign ? "--sign" : "";
+            system("set -f; ssh $sshHost @sshOpts 'nix-store --export $extraOpts @missing $compressor' | $decompressor $Nix::Config::binDir/nix-store --import") == 0
+                or die "copying store paths from remote machine `$sshHost' failed: $?";
+        }
     }
 
 }
diff --git a/scripts/nix-generate-patches.in b/scripts/nix-generate-patches.in
index 1f32ab410920..4cb843382b52 100644..100755
--- a/scripts/nix-generate-patches.in
+++ b/scripts/nix-generate-patches.in
@@ -1,9 +1,9 @@
-#! @perl@ -w -I@libexecdir@/nix @perlFlags@
+#! @perl@ -w @perlFlags@
 
 use strict;
 use File::Temp qw(tempdir);
-use NixManifest;
-use GeneratePatches;
+use Nix::Manifest;
+use Nix::GeneratePatches;
 
 if (scalar @ARGV != 5) {
     print STDERR <<EOF;
diff --git a/scripts/nix-install-package.in b/scripts/nix-install-package.in
index f40cfc7d0b23..178b14c7468f 100644..100755
--- a/scripts/nix-install-package.in
+++ b/scripts/nix-install-package.in
@@ -2,8 +2,7 @@
 
 use strict;
 use File::Temp qw(tempdir);
-
-my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
+use Nix::Config;
 
 
 sub usageError {
@@ -61,7 +60,7 @@ if ($interactive && !defined $ENV{"NIX_HAVE_TERMINAL"}) {
     $ENV{"NIX_HAVE_TERMINAL"} = "1";
     $ENV{"LD_LIBRARY_PATH"} = "";
     foreach my $term ("xterm", "konsole", "gnome-terminal", "xterm") {
-        exec($term, "-e", "$binDir/nix-install-package", @ARGV);
+        exec($term, "-e", "$Nix::Config::binDir/nix-install-package", @ARGV);
     }
     die "cannot execute `xterm'";
 }
@@ -132,12 +131,12 @@ $ENV{NIX_REMOTE} = "";
 
 
 print "\nPulling manifests...\n";
-system("$binDir/nix-pull", $manifestURL) == 0
+system("$Nix::Config::binDir/nix-pull", $manifestURL) == 0
     or barf "nix-pull failed: $?";
 
 
 print "\nInstalling package...\n";
-system("$binDir/nix-env", "--install", $outPath, "--force-name", $drvName, @extraNixEnvArgs) == 0
+system("$Nix::Config::binDir/nix-env", "--install", $outPath, "--force-name", $drvName, @extraNixEnvArgs) == 0
     or barf "nix-env failed: $?";
 
 
diff --git a/scripts/nix-prefetch-url.in b/scripts/nix-prefetch-url.in
index 31170fa953ea..45bad75f3e9f 100644..100755
--- a/scripts/nix-prefetch-url.in
+++ b/scripts/nix-prefetch-url.in
@@ -3,6 +3,9 @@
 url=$1
 expHash=$2
 
+binDir=@bindir@
+if [ -n "$NIX_BIN_DIR" ]; then binDir="$NIX_BIN_DIR"; fi
+
 # needed to make it work on NixOS
 export PATH=$PATH:@coreutils@
 
@@ -31,8 +34,8 @@ if test -z "$name"; then echo "invalid url"; exit 1; fi
 # If the hash was given, a file with that hash may already be in the
 # store.
 if test -n "$expHash"; then
-    finalPath=$(@bindir@/nix-store --print-fixed-path "$hashType" "$expHash" "$name")
-    if ! @bindir@/nix-store --check-validity "$finalPath" 2> /dev/null; then
+    finalPath=$($binDir/nix-store --print-fixed-path "$hashType" "$expHash" "$name")
+    if ! $bindir/nix-store --check-validity "$finalPath" 2> /dev/null; then
         finalPath=
     fi
     hash=$expHash
@@ -103,7 +106,7 @@ if test -z "$finalPath"; then
     # garbage-collected independently.
     if test -n "$NIX_DOWNLOAD_CACHE"; then
         echo -n "$url" > $tmpPath/url
-        urlHash=$(@bindir@/nix-hash --type sha256 --base32 --flat $tmpPath/url)
+        urlHash=$($binDir/nix-hash --type sha256 --base32 --flat $tmpPath/url)
         echo "$url" > "$NIX_DOWNLOAD_CACHE/$urlHash.url"
         cachedHashFN="$NIX_DOWNLOAD_CACHE/$urlHash.$hashType"
         cachedTimestampFN="$NIX_DOWNLOAD_CACHE/$urlHash.stamp"
@@ -121,8 +124,8 @@ if test -z "$finalPath"; then
         # Curl didn't create $tmpFile, so apparently there's no newer
         # file on the server.
         hash=$(cat $cachedHashFN)
-        finalPath=$(@bindir@/nix-store --print-fixed-path "$hashType" "$hash" "$name") 
-        if ! @bindir@/nix-store --check-validity "$finalPath" 2> /dev/null; then
+        finalPath=$($binDir/nix-store --print-fixed-path "$hashType" "$hash" "$name") 
+        if ! $binDir/nix-store --check-validity "$finalPath" 2> /dev/null; then
             echo "cached contents of \`$url' disappeared, redownloading..." >&2
             finalPath=
             cacheFlags="--remote-time"
@@ -133,7 +136,7 @@ if test -z "$finalPath"; then
     if test -z "$finalPath"; then
 
         # Compute the hash.
-        hash=$(@bindir@/nix-hash --type "$hashType" $hashFormat --flat $tmpFile)
+        hash=$($binDir/nix-hash --type "$hashType" $hashFormat --flat $tmpFile)
         if ! test -n "$QUIET"; then echo "hash is $hash" >&2; fi
 
         if test -n "$NIX_DOWNLOAD_CACHE"; then
@@ -142,7 +145,7 @@ if test -z "$finalPath"; then
         fi
 
         # Add the downloaded file to the Nix store.
-        finalPath=$(@bindir@/nix-store --add-fixed "$hashType" $tmpFile)
+        finalPath=$($binDir/nix-store --add-fixed "$hashType" $tmpFile)
 
         if test -n "$expHash" -a "$expHash" != "$hash"; then
             echo "hash mismatch for URL \`$url'" >&2
diff --git a/scripts/nix-pull.in b/scripts/nix-pull.in
index 51c7e681a5a7..f3cba0c02619 100644..100755
--- a/scripts/nix-pull.in
+++ b/scripts/nix-pull.in
@@ -1,17 +1,17 @@
-#! @perl@ -w -I@libexecdir@/nix @perlFlags@
+#! @perl@ -w @perlFlags@
 
 use strict;
 use File::Temp qw(tempdir);
-use NixManifest;
+use Nix::Config;
+use Nix::Manifest;
 
 my $tmpDir = tempdir("nix-pull.XXXXXX", CLEANUP => 1, TMPDIR => 1)
     or die "cannot create a temporary directory";
 
-my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@";
 my $libexecDir = ($ENV{"NIX_LIBEXEC_DIR"} or "@libexecdir@");
 my $storeDir = ($ENV{"NIX_STORE_DIR"} or "@storedir@");
 my $stateDir = ($ENV{"NIX_STATE_DIR"} or "@localstatedir@/nix");
-my $manifestDir = ($ENV{"NIX_MANIFESTS_DIR"} or "$stateDir/manifests");
+my $manifestDir = $Nix::Config::manifestDir;
 
 
 # Prevent access problems in shared-stored installations.
@@ -42,7 +42,7 @@ sub downloadFile {
     my $url = shift;
     $ENV{"PRINT_PATH"} = 1;
     $ENV{"QUIET"} = 1;
-    my ($dummy, $path) = `$binDir/nix-prefetch-url '$url'`;
+    my ($dummy, $path) = `$Nix::Config::binDir/nix-prefetch-url '$url'`;
     die "cannot fetch `$url'" if $? != 0;
     die "nix-prefetch-url did not return a path" unless defined $path;
     chomp $path;
@@ -57,23 +57,23 @@ sub processURL {
     my $manifest;
 
     # First see if a bzipped manifest is available.
-    if (system("@curl@ --fail --silent --head '$url'.bz2 > /dev/null") == 0) {
+    if (system("$Nix::Config::curl --fail --silent --head '$url'.bz2 > /dev/null") == 0) {
         print "fetching list of Nix archives at `$url.bz2'...\n";
         my $bzipped = downloadFile "$url.bz2";
 
         $manifest = "$tmpDir/MANIFEST";
 
-        system("@bunzip2@ < $bzipped > $manifest") == 0
+        system("$Nix::Config::bzip2 -d < $bzipped > $manifest") == 0
             or die "cannot decompress manifest";
 
-        $manifest = (`$binDir/nix-store --add $manifest`
+        $manifest = (`$Nix::Config::binDir/nix-store --add $manifest`
                      or die "cannot copy $manifest to the store");
         chomp $manifest;
     }
 
     # Otherwise, just get the uncompressed manifest.
     else {
-        print "obtaining list of Nix archives at `$url'...\n";
+        print "fetching list of Nix archives at `$url'...\n";
         $manifest = downloadFile $url;
     }
 
@@ -96,7 +96,7 @@ sub processURL {
         $baseName = $1;
     }
 
-    my $hash = `$binDir/nix-hash --flat '$manifest'`
+    my $hash = `$Nix::Config::binDir/nix-hash --flat '$manifest'`
         or die "cannot hash `$manifest'";
     chomp $hash;
 
diff --git a/scripts/nix-push.in b/scripts/nix-push.in
index fd1ec21485e2..dcdad5721265 100644..100755
--- a/scripts/nix-push.in
+++ b/scripts/nix-push.in
@@ -1,9 +1,10 @@
-#! @perl@ -w -I@libexecdir@/nix @perlFlags@
+#! @perl@ -w @perlFlags@
 
 use strict;
 use File::Temp qw(tempdir);
 use File::stat;
-use NixManifest;
+use Nix::Config;
+use Nix::Manifest;
 
 my $hashAlgo = "sha256";
 
@@ -13,7 +14,7 @@ my $tmpDir = tempdir("nix-push.XXXXXX", CLEANUP => 1, TMPDIR => 1)
 my $nixExpr = "$tmpDir/create-nars.nix";
 my $manifest = "$tmpDir/MANIFEST";
 
-my $curl = "@curl@ --fail --silent";
+my $curl = "$Nix::Config::curl --fail --silent";
 my $extraCurlFlags = ${ENV{'CURL_FLAGS'}};
 $curl = "$curl $extraCurlFlags" if defined $extraCurlFlags;
 
@@ -107,7 +108,7 @@ foreach my $storePath (@storePaths) {
     # Construct a Nix expression that creates a Nix archive.
     my $nixexpr = 
         "((import $dataDir/nix/corepkgs/nar/nar.nix) " .
-        "{storePath = builtins.storePath \"$storePath\"; system = \"@system@\"; hashAlgo = \"$hashAlgo\";}) ";
+        "{ storePath = builtins.storePath \"$storePath\"; system = \"@system@\"; hashAlgo = \"$hashAlgo\"; }) ";
     
     print NIX $nixexpr;
 }
diff --git a/scripts/nix-reduce-build.in b/scripts/nix-reduce-build.in
index 0c33275d5eb0..0c33275d5eb0 100644..100755
--- a/scripts/nix-reduce-build.in
+++ b/scripts/nix-reduce-build.in
diff --git a/scripts/update-manifest.pl b/scripts/update-manifest.pl
deleted file mode 100755
index 566f6467328d..000000000000
--- a/scripts/update-manifest.pl
+++ /dev/null
@@ -1,52 +0,0 @@
-#! /usr/bin/perl -w -I.
-
-use strict;
-use readmanifest;
-
-die unless scalar @ARGV == 2;
-
-my $cache = $ARGV[0];
-my $manifest = $ARGV[1];
-my %narFiles;
-my %patches;
-
-readManifest $manifest, \%narFiles, \%patches;
-
-foreach my $storePath (keys %narFiles) {
-    my $narFileList = $narFiles{$storePath};
-
-    foreach my $narFile (@{$narFileList}) {
-        if (!defined $narFile->{size} or
-            !defined $narFile->{narHash})
-        {
-            $narFile->{url} =~ /\/([^\/]+)$/;
-            die unless defined $1;
-            my $fn = "$cache/$1";
-            
-            my @info = stat $fn or die;
-            $narFile->{size} = $info[7];
-
-            my $narHash;
-            my $hashFile = "$fn.NARHASH";
-            if (-e $hashFile) {
-                open HASH, "<$hashFile" or die;
-                $narHash = <HASH>;
-                close HASH;
-            } else {
-                print "$fn\n";
-                $narHash = `bunzip2 < '$fn' | nix-hash --flat /dev/stdin` or die;
-                open HASH, ">$hashFile" or die;
-                print HASH $narHash;
-                close HASH;
-            }
-            chomp $narHash;
-            $narFile->{narHash} = $narHash;
-        }
-    }
-}
-
-if (! -e "$manifest.backup") {
-    system "mv --reply=no '$manifest' '$manifest.backup'";
-}
-
-writeManifest $manifest, \%narFiles, \%patches;