tvl-depot/perl/lib/Nix/SSH.pm
Eelco Dolstra 215b70f51e
Revert "Get rid of unicode quotes (#1140)"
This reverts commit f78126bfd6. There
really is no need for such a massive change...
2016-11-26 00:38:01 +01:00

110 lines
2.3 KiB
Perl
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package Nix::SSH;
use utf8;
use strict;
use File::Temp qw(tempdir);
use IPC::Open2;
our @ISA = qw(Exporter);
our @EXPORT = qw(
@globalSshOpts
readN readInt readString readStrings
writeInt writeString writeStrings
connectToRemoteNix
);
our @globalSshOpts = split ' ', ($ENV{"NIX_SSHOPTS"} or "");
sub readN {
my ($bytes, $from) = @_;
my $res = "";
while ($bytes > 0) {
my $s;
my $n = sysread($from, $s, $bytes);
die "I/O error reading from remote side\n" if !defined $n;
die "got EOF while expecting $bytes bytes from remote side\n" if !$n;
$bytes -= $n;
$res .= $s;
}
return $res;
}
sub readInt {
my ($from) = @_;
return unpack("L<x4", readN(8, $from));
}
sub readString {
my ($from) = @_;
my $len = readInt($from);
my $s = readN($len, $from);
readN(8 - $len % 8, $from) if $len % 8; # skip padding
return $s;
}
sub readStrings {
my ($from) = @_;
my $n = readInt($from);
my @res;
push @res, readString($from) while $n--;
return @res;
}
sub writeInt {
my ($n, $to) = @_;
syswrite($to, pack("L<x4", $n)) or die;
}
sub writeString {
my ($s, $to) = @_;
my $len = length $s;
my $req .= pack("L<x4", $len);
$req .= $s;
$req .= "\000" x (8 - $len % 8) if $len % 8;
syswrite($to, $req) or die;
}
sub writeStrings {
my ($ss, $to) = @_;
writeInt(scalar(@{$ss}), $to);
writeString($_, $to) foreach @{$ss};
}
sub connectToRemoteNix {
my ($sshHost, $sshOpts, $extraFlags) = @_;
$extraFlags ||= "";
# Start nix-store --serve on the remote host.
my ($from, $to);
# FIXME: don't start a shell, start ssh directly.
my $pid = open2($from, $to, "exec ssh -x -a $sshHost @globalSshOpts @{$sshOpts} nix-store --serve --write $extraFlags");
# Do the handshake.
my $magic;
eval {
my $SERVE_MAGIC_1 = 0x390c9deb; # FIXME
my $clientVersion = 0x200;
syswrite($to, pack("L<x4L<x4", $SERVE_MAGIC_1, $clientVersion)) or die;
$magic = readInt($from);
};
die "unable to connect to $sshHost\n" if $@;
die "did not get valid handshake from remote host\n" if $magic != 0x5452eecb;
my $serverVersion = readInt($from);
die "unsupported server version\n" if $serverVersion < 0x200 || $serverVersion >= 0x300;
return ($from, $to, $pid);
}
1;