Removed debug statements
[clearscm.git] / bin / tunnel.pl
1 #!/usr/bin/perl
2
3 =pod
4
5 =head1 NAME $RCSfile: tunnel.pl,v $
6
7 Set up a tunnel for emailing
8
9 =head1 VERSION
10
11 =over
12
13 =item Author
14
15 Andrew DeFaria <Andrew@ClearSCM.com>
16
17 =item Revision:
18
19 $Revision: 1.0 $
20
21 =item Created:
22
23 Wed 19 Aug 2020 09:09:09 AM MST
24
25 =item Modified:
26
27 $Date: $
28
29 =back
30
31 =head1 SYNOPSIS
32
33   Usage: tunnel.pl [-u|sage] [-h|elp] [-ve|rbose] [-d|ebug]
34
35   Where:
36     -u|sage:      Displays this usage
37     -h|elp:       Display full help
38     -ve|rbose:    Be verbose
39     -d|ebug:      Output debug messages
40     -host1:       First host for tunnel (Default: localhost)
41     -port1:       Port for host1
42     -host2:       Second host for tunnel (Default: defaria.com)
43     -port2:       Port for host2
44     -a|nnounce:   Whether to announce startup (Default false)
45     -ap|pend      Append to logfile (Default: Noappend)
46     -maxtretries: Maximum number of retry attempt to reestablish tunnel
47                   (Default 3)
48     -nodaemon:    Whether to go into daemon mode (Default: Daemon mode)
49
50 =head1 DESCRIPTION
51
52 This script sets up an SSH tunnel for the purposes of emailing.
53
54 =cut
55
56 use strict;
57 use warnings;
58
59 use File::Temp qw(tempfile);
60 use FindBin;
61 use Getopt::Long;
62 use Net::OpenSSH;
63 use POSIX ':sys_wait_h';
64
65 use lib "$FindBin::Bin/../lib";
66
67 use Pod::Usage;
68
69 use Display;
70 use Logger;
71 use Speak;
72 use Utils;
73
74 my $VERSION  = '$Revision: 1.0 $';
75   ($VERSION) = ($VERSION =~ /\$Revision: (.*) /);
76
77 my %opts = (
78   usage      => sub { pod2usage },
79   help       => sub { pod2usage (-verbose => 2)},
80   verbose    => sub { set_verbose },
81   debug      => sub { set_debug },
82   host1      => 'localhost',
83   port1      => 1025,
84   host2      => 'defaria.com',
85   port2      => 25,
86   remotehost => 'defaria.com',
87   maxretries => 3,
88   daemon     => 1,
89 );
90
91 my ($log, $ssh);
92
93 sub Report ($;$) {
94   my ($msg, $err) = @_;
95
96   speak $msg, $log;
97
98   if ($err) {
99     $log->err($msg, $err);
100   } else {
101     $log->err($msg);
102   } # if
103
104   return;
105 } # Report
106
107 sub interrupt {
108    Report "Tunnel killed unexpectedly", 1;
109
110    kill 'INT', $ssh->get_master_pid;
111
112    return;
113 } # interrupt
114
115 sub tunnel() {
116   my $tunnelStr = "-NL$opts{host1}:$opts{port1}:$opts{host2}:$opts{port2}";
117
118   my $retryattempts = 0;
119
120 RETRY:
121   my ($fh, $filename) = tempfile;
122
123   my $ssh = Net::OpenSSH->new(
124     $opts{remotehost},
125     master_opts         => $tunnelStr,
126     default_stderr_file => $filename
127   );
128
129   Report("Unable to establish ssh tunnel " . $ssh->error, 1) if $ssh->error;
130
131   # Check to see if address is already in use
132   my @lines = <$fh>;
133
134   close $fh;
135
136   unlink $filename;
137
138   if (grep /address already in use/i, @lines) {
139     Report 'Unable to start tunnel - Address already in use', 1;
140   } else {
141     my $msg  = 'Ssh tunnel ';
142        $msg .= $retryattempts ? 'reestablished' : 'established';
143
144     speak $msg, $log if $opts{announce};
145
146     $log->msg($msg);
147
148     # Reset retry attempts since we reestablished the tunnel
149     $retryattempts = 0 if $retryattempts;
150
151     # Wait for master to exit
152     waitpid($ssh->get_master_pid, WUNTRACED);
153
154     Report("Ssh tunnel terminated unexpectedly - Maximum retry count hit ($opts{maxretries}) - giving up", 1)
155       if $retryattempts++ >= $opts{maxretries};
156
157     $opts{announce} = $retryattempts;
158
159     Report 'Ssh tunnel terminated unexpectedly - Attempting restart';
160
161     undef $ssh;
162
163     goto RETRY;
164   } # if
165
166   return;
167 } # tunnel
168
169 ## Main
170 GetOptions (
171   \%opts,
172   'usage',
173   'help',
174   'verbose',
175   'debug',
176   'host1',
177   'host2',
178   'port1',
179   'port2',
180   'announce!',
181   'maxretries=i',
182   'daemon!',
183   'append',
184 ) || Usage;
185
186 # Turn off daemon mode if we are in the Perl debugger;
187 no warnings; # Ignore warning about used only once $DB::OUT when not in debugger
188 $opts{daemon} = 0 if defined $DB::OUT;
189 use warnings;
190
191 $log = Logger->new(
192   path        => '/var/local/log',
193   name        => "$Logger::me",
194   timestamped => 'yes',
195   append      => $opts{append},
196 );
197
198 $log->msg("$FindBin::Script v$VERSION");
199
200 $SIG{INT} = $SIG{TERM} = \&interrupt;
201
202 if ($opts{daemon}) {
203   # Perl complains if we reference $DB::OUT only once
204   no warnings;
205   EnterDaemonMode unless defined $DB::OUT or get_debug;
206   use warnings;
207 } # if
208
209 tunnel;