#! @perl@ -w use strict; use File::Basename; use IO::Handle; my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@"; STDOUT->autoflush(1); my @remoteStoresAll = split ':', ($ENV{"NIX_OTHER_STORES"} or ""); my @remoteStores; foreach my $dir (@remoteStoresAll) { push @remoteStores, glob($dir); } sub findStorePath { my $storePath = shift; my $storePathName = basename $storePath; foreach my $store (@remoteStores) { # Determine whether $storePath exists by looking for the # existence of the info file, and if so, get store path info # from that file. This rather breaks abstraction: we should # be using `nix-store' for that. But right now there is no # good way to tell nix-store to access a store mounted under a # different location (there's $NIX_STORE, but that only works # if the remote store is mounted under its "real" location). my $infoFile = "$store/var/nix/db/info/$storePathName"; my $storePath2 = "$store/store/$storePathName"; if (-f $infoFile && -e $storePath2) { return ($infoFile, $storePath2); } } } if ($ARGV[0] eq "--query") { while (<STDIN>) { my $cmd = $_; chomp $cmd; if ($cmd eq "have") { my $storePath = <STDIN>; chomp $storePath; (my $infoFile) = findStorePath $storePath; print STDOUT ($infoFile ? "1\n" : "0\n"); } elsif ($cmd eq "info") { my $storePath = <STDIN>; chomp $storePath; (my $infoFile) = findStorePath $storePath; if (!$infoFile) { print "0\n"; next; # not an error } print "1\n"; my $deriver = ""; my @references = (); open INFO, "<$infoFile" or die "cannot read info file $infoFile\n"; while (<INFO>) { chomp; /^([\w-]+): (.*)$/ or die "bad info file"; my $key = $1; my $value = $2; if ($key eq "Deriver") { $deriver = $value; } elsif ($key eq "References") { @references = split ' ', $value; } } close INFO; print "$deriver\n"; print scalar @references, "\n"; print "$_\n" foreach @references; print "0\n"; # !!! showing size not supported (yet) } else { die "unknown command `$cmd'"; } } } elsif ($ARGV[0] eq "--substitute") { die unless scalar @ARGV == 2; my $storePath = $ARGV[1]; (my $infoFile, my $sourcePath) = findStorePath $storePath; die unless $infoFile; print "\n*** Copying `$storePath' from `$sourcePath'\n\n"; system("$binDir/nix-store --dump $sourcePath | $binDir/nix-store --restore $storePath") == 0 or die "cannot copy `$sourcePath' to `$storePath'"; } else { die; }