xref: /openbsd/regress/sys/net/pf_divert/Remote.pm (revision cecf84d4)
1#	$OpenBSD: Remote.pm,v 1.4 2014/08/18 22:58:19 bluhm Exp $
2
3# Copyright (c) 2010-2014 Alexander Bluhm <bluhm@openbsd.org>
4#
5# Permission to use, copy, modify, and distribute this software for any
6# purpose with or without fee is hereby granted, provided that the above
7# copyright notice and this permission notice appear in all copies.
8#
9# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
17use strict;
18use warnings;
19
20package Remote;
21use parent 'Proc';
22use Carp;
23use Cwd;
24use File::Basename;
25
26sub new {
27	my $class = shift;
28	my %args = @_;
29	$args{logfile} ||= "remote.log";
30	$args{up} ||= "Started";
31	$args{func} = sub { Carp::confess "$class func may not be called" };
32	$args{remotessh}
33	    or croak "$class remote ssh host not given";
34	my $self = Proc::new($class, %args);
35	$self->{af}
36	    or croak "$class address family not given";
37	$self->{bindaddr}
38	    or croak "$class bind addr not given";
39	$self->{connectaddr}
40	    or croak "$class connect addr not given";
41	defined $self->{connectport}
42	    or croak "$class connect port not given";
43	return $self;
44}
45
46sub up {
47	my $self = Proc::up(shift, @_);
48	my $timeout = shift || 10;
49	if ($self->{connect}) {
50		$self->loggrep(qr/^Connected$/, $timeout)
51		    or croak ref($self), " no Connected in $self->{logfile} ".
52			"after $timeout seconds";
53		return $self;
54	}
55	my $lsock = $self->loggrep(qr/^listen sock: /, $timeout)
56	    or croak ref($self), " no listen sock in $self->{logfile} ".
57		"after $timeout seconds";
58	my($addr, $port) = $lsock =~ /: (\S+) (\S+)$/
59	    or croak ref($self), " no listen addr and port in $self->{logfile}";
60	$self->{listenaddr} = $addr;
61	$self->{listenport} = $port;
62	return $self;
63}
64
65sub child {
66	my $self = shift;
67
68	print STDERR $self->{up}, "\n";
69	my @opts = split(' ', $ENV{SSH_OPTIONS}) if $ENV{SSH_OPTIONS};
70	my @sudo = $ENV{SUDO} ? ($ENV{SUDO}, "SUDO=$ENV{SUDO}") : ();
71	my $dir = dirname($0);
72	$dir = getcwd() if ! $dir || $dir eq ".";
73	my @cmd = ("ssh", "-n", @opts, $self->{remotessh}, @sudo, "perl",
74	    "-I", $dir, "$dir/".basename($0), $self->{af},
75	    $self->{bindaddr}, $self->{connectaddr}, $self->{connectport},
76	    ($self->{bindport} ? $self->{bindport} : ()),
77	    ($self->{testfile} ? "$dir/".basename($self->{testfile}) :
78	    ()));
79	print STDERR "execute: @cmd\n";
80	$< = $>;
81	exec @cmd;
82	die ref($self), " exec '@cmd' failed: $!";
83}
84
851;
86