From 365f3028ddfb5487f35ebbb9adc42ddf9459113d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Sun, 5 Dec 2010 17:50:29 +0000 Subject: * Use CamelCase for the Perl modules. --- scripts/GeneratePatches.pm.in | 1 - scripts/Makefile.am | 20 ++-- scripts/NixConfig.pm.in | 17 +++ scripts/NixManifest.pm.in | 211 +++++++++++++++++++++++++++++++++ scripts/SSH.pm | 50 ++++++++ scripts/build-remote.pl.in | 2 +- scripts/download-using-manifests.pl.in | 2 +- scripts/nix-copy-closure.in | 2 +- scripts/nix-generate-patches.in | 2 +- scripts/nix-pull.in | 2 +- scripts/nix-push.in | 2 +- scripts/readconfig.pm.in | 17 --- scripts/readmanifest.pm.in | 211 --------------------------------- scripts/ssh.pm | 50 -------- 14 files changed, 294 insertions(+), 295 deletions(-) create mode 100644 scripts/NixConfig.pm.in create mode 100644 scripts/NixManifest.pm.in create mode 100644 scripts/SSH.pm delete mode 100644 scripts/readconfig.pm.in delete mode 100644 scripts/readmanifest.pm.in delete mode 100644 scripts/ssh.pm (limited to 'scripts') diff --git a/scripts/GeneratePatches.pm.in b/scripts/GeneratePatches.pm.in index bb7111f8e34b..2d2653255e54 100755 --- a/scripts/GeneratePatches.pm.in +++ b/scripts/GeneratePatches.pm.in @@ -2,7 +2,6 @@ use strict; use File::Temp qw(tempdir); -use readmanifest; # Some patch generations options. diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 5f20dcfaf7a2..60bb0a9b8105 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -7,17 +7,17 @@ noinst_SCRIPTS = nix-profile.sh GeneratePatches.pm \ find-runtime-roots.pl build-remote.pl nix-reduce-build \ copy-from-other-stores.pl nix-http-export.cgi -nix-pull nix-push: readmanifest.pm readconfig.pm download-using-manifests.pl +nix-pull nix-push: NixManifest.pm NixConfig.pm download-using-manifests.pl -install-exec-local: readmanifest.pm download-using-manifests.pl copy-from-other-stores.pl find-runtime-roots.pl +install-exec-local: NixManifest.pm GeneratePatches.pm 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) readmanifest.pm $(DESTDIR)$(libexecdir)/nix - $(INSTALL_DATA) readconfig.pm $(DESTDIR)$(libexecdir)/nix - $(INSTALL_DATA) ssh.pm $(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) GeneratePatches.pm $(DESTDIR)$(libexecdir)/nix $(INSTALL_PROGRAM) build-remote.pl $(DESTDIR)$(libexecdir)/nix $(INSTALL) -d $(DESTDIR)$(libexecdir)/nix/substituters $(INSTALL_PROGRAM) download-using-manifests.pl $(DESTDIR)$(libexecdir)/nix/substituters @@ -30,13 +30,13 @@ 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 \ - readmanifest.pm.in \ - readconfig.pm.in \ - ssh.pm \ + 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 \ - GeneratePatches.pm.in \ nix-copy-closure.in \ find-runtime-roots.pl.in \ build-remote.pl.in \ diff --git a/scripts/NixConfig.pm.in b/scripts/NixConfig.pm.in new file mode 100644 index 000000000000..aeb443aeed3a --- /dev/null +++ b/scripts/NixConfig.pm.in @@ -0,0 +1,17 @@ +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 () { + /^\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 new file mode 100644 index 000000000000..be0dda616922 --- /dev/null +++ b/scripts/NixManifest.pm.in @@ -0,0 +1,211 @@ +use strict; + + +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, $narFiles, $localPaths, $patches) = @_; + + 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, $hashAlgo, $copyFrom, $system); + + while () { + 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 = ""; + $hashAlgo = "md5"; + } + + } else { + + if (/^\}$/) { + $inside = 0; + + if ($type eq "narfile") { + + $$narFiles{$storePath} = [] + unless defined $$narFiles{$storePath}; + + my $narFileList = $$narFiles{$storePath}; + + my $found = 0; + foreach my $narFile (@{$narFileList}) { + $found = 1 if $narFile->{url} eq $url; + } + if (!$found) { + push @{$narFileList}, + { url => $url, hash => $hash, size => $size + , narHash => $narHash, narSize => $narSize + , references => $references + , deriver => $deriver, hashAlgo => $hashAlgo + , system => $system + }; + } + + } + + elsif ($type eq "patch") { + addPatch $patches, $storePath, + { url => $url, hash => $hash, size => $size + , basePath => $basePath, baseHash => $baseHash + , narHash => $narHash, narSize => $narSize + , patchType => $patchType, hashAlgo => $hashAlgo + }; + } + + elsif ($type eq "localPath") { + + $$localPaths{$storePath} = [] + unless defined $$localPaths{$storePath}; + + my $localPathsList = $$localPaths{$storePath}; + + # !!! remove duplicates + + push @{$localPathsList}, + { copyFrom => $copyFrom, references => $references + , deriver => "" + }; + } + + } + + 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 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: $!"; + } +} + + +return 1; diff --git a/scripts/SSH.pm b/scripts/SSH.pm new file mode 100644 index 000000000000..44a0e6f31b1c --- /dev/null +++ b/scripts/SSH.pm @@ -0,0 +1,50 @@ +use strict; +use File::Temp qw(tempdir); + +our @sshOpts = split ' ', ($ENV{"NIX_SSHOPTS"} or ""); + +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 SSH, "ssh $sshHost @sshOpts -M -N -o LocalCommand='echo started' -o PermitLocalCommand=yes |" or die; + + while () { + 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 f9bff9c41d72..c551f63607bc 100755 --- a/scripts/build-remote.pl.in +++ b/scripts/build-remote.pl.in @@ -3,7 +3,7 @@ use Fcntl ':flock'; use English '-no_match_vars'; use IO::Handle; -use ssh qw/sshOpts openSSHConnection/; +use SSH qw/sshOpts openSSHConnection/; no warnings('once'); diff --git a/scripts/download-using-manifests.pl.in b/scripts/download-using-manifests.pl.in index c50f540f3464..47ff09e609c7 100644 --- a/scripts/download-using-manifests.pl.in +++ b/scripts/download-using-manifests.pl.in @@ -1,7 +1,7 @@ #! @perl@ -w -I@libexecdir@/nix use strict; -use readmanifest; +use NixManifest; use POSIX qw(strftime); use File::Temp qw(tempdir); diff --git a/scripts/nix-copy-closure.in b/scripts/nix-copy-closure.in index a477cc01a4cf..1f1fded36669 100644 --- a/scripts/nix-copy-closure.in +++ b/scripts/nix-copy-closure.in @@ -1,6 +1,6 @@ #! @perl@ -w -I@libexecdir@/nix -use ssh; +use SSH; my $binDir = $ENV{"NIX_BIN_DIR"} || "@bindir@"; diff --git a/scripts/nix-generate-patches.in b/scripts/nix-generate-patches.in index d22098a109de..c96cc704a1e8 100644 --- a/scripts/nix-generate-patches.in +++ b/scripts/nix-generate-patches.in @@ -2,7 +2,7 @@ use strict; use File::Temp qw(tempdir); -use readmanifest; +use NixManifest; use GeneratePatches; if (scalar @ARGV != 5) { diff --git a/scripts/nix-pull.in b/scripts/nix-pull.in index e2a0cc1fafdf..f3b533ff7a4c 100644 --- a/scripts/nix-pull.in +++ b/scripts/nix-pull.in @@ -2,7 +2,7 @@ use strict; use File::Temp qw(tempdir); -use readmanifest; +use NixManifest; my $tmpDir = tempdir("nix-pull.XXXXXX", CLEANUP => 1, TMPDIR => 1) or die "cannot create a temporary directory"; diff --git a/scripts/nix-push.in b/scripts/nix-push.in index 6760baa7e937..1d8ba86a8d0c 100644 --- a/scripts/nix-push.in +++ b/scripts/nix-push.in @@ -2,7 +2,7 @@ use strict; use File::Temp qw(tempdir); -use readmanifest; +use NixManifest; my $hashAlgo = "sha256"; diff --git a/scripts/readconfig.pm.in b/scripts/readconfig.pm.in deleted file mode 100644 index aeb443aeed3a..000000000000 --- a/scripts/readconfig.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 () { - /^\s*([\w|-]+)\s*=\s*(.*)$/ or next; - $config{$1} = $2; - print "|$1| -> |$2|\n"; - } - close CONFIG; -} - -return 1; diff --git a/scripts/readmanifest.pm.in b/scripts/readmanifest.pm.in deleted file mode 100644 index be0dda616922..000000000000 --- a/scripts/readmanifest.pm.in +++ /dev/null @@ -1,211 +0,0 @@ -use strict; - - -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, $narFiles, $localPaths, $patches) = @_; - - 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, $hashAlgo, $copyFrom, $system); - - while () { - 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 = ""; - $hashAlgo = "md5"; - } - - } else { - - if (/^\}$/) { - $inside = 0; - - if ($type eq "narfile") { - - $$narFiles{$storePath} = [] - unless defined $$narFiles{$storePath}; - - my $narFileList = $$narFiles{$storePath}; - - my $found = 0; - foreach my $narFile (@{$narFileList}) { - $found = 1 if $narFile->{url} eq $url; - } - if (!$found) { - push @{$narFileList}, - { url => $url, hash => $hash, size => $size - , narHash => $narHash, narSize => $narSize - , references => $references - , deriver => $deriver, hashAlgo => $hashAlgo - , system => $system - }; - } - - } - - elsif ($type eq "patch") { - addPatch $patches, $storePath, - { url => $url, hash => $hash, size => $size - , basePath => $basePath, baseHash => $baseHash - , narHash => $narHash, narSize => $narSize - , patchType => $patchType, hashAlgo => $hashAlgo - }; - } - - elsif ($type eq "localPath") { - - $$localPaths{$storePath} = [] - unless defined $$localPaths{$storePath}; - - my $localPathsList = $$localPaths{$storePath}; - - # !!! remove duplicates - - push @{$localPathsList}, - { copyFrom => $copyFrom, references => $references - , deriver => "" - }; - } - - } - - 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 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: $!"; - } -} - - -return 1; diff --git a/scripts/ssh.pm b/scripts/ssh.pm deleted file mode 100644 index 44a0e6f31b1c..000000000000 --- a/scripts/ssh.pm +++ /dev/null @@ -1,50 +0,0 @@ -use strict; -use File::Temp qw(tempdir); - -our @sshOpts = split ' ', ($ENV{"NIX_SSHOPTS"} or ""); - -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 SSH, "ssh $sshHost @sshOpts -M -N -o LocalCommand='echo started' -o PermitLocalCommand=yes |" or die; - - while () { - 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; -- cgit 1.4.1