X-Git-Url: http://dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=perl%2Fclient.pl;h=376587645c8599abb15b2bb43ac82238afad2722;hb=918827ec5a9023edeb2ce0140692566591af0af8;hp=cc185a17838622f4c2631464ca4ea5554947b39a;hpb=3643ef870e040d437448632209039477eac4e52c;p=spider.git diff --git a/perl/client.pl b/perl/client.pl index cc185a17..37658764 100755 --- a/perl/client.pl +++ b/perl/client.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w # # A thing that implements dxcluster 'protocol' # @@ -26,6 +26,7 @@ # $Id$ # +require 5.004; # search local then perl directories BEGIN { @@ -40,12 +41,11 @@ BEGIN { use Msg; use DXVars; use DXDebug; -use DXUser; +use Net::Telnet qw(TELOPT_ECHO); use IO::File; use IO::Socket; use IPC::Open2; -use Net::Telnet qw(TELOPT_ECHO); -use Carp; +use Carp qw{cluck}; # cease communications sub cease @@ -55,7 +55,12 @@ sub cease $conn->send_now("Z$call|bye...\n"); } $stdout->flush if $stdout; - kill(15, $pid) if $pid; + if ($pid) { + dbg('connect', "killing $pid"); + kill(9, $pid); + } + dbgclose(); +# $SIG{__WARN__} = sub {my $a = shift; cluck($a); }; sleep(1); exit(0); } @@ -71,6 +76,7 @@ sub sig_chld { $SIG{CHLD} = \&sig_chld; $waitedpid = wait; + dbg('connect', "caught $pid"); } @@ -92,7 +98,7 @@ sub rec_socket cease(1); } if (defined $msg) { - my ($sort, $call, $line) = $msg =~ /^(\w)(\S+)\|(.*)$/; + my ($sort, $call, $line) = $msg =~ /^(\w)([A-Z0-9\-]+)\|(.*)$/; if ($sort eq 'D') { my $snl = $mynl; @@ -105,7 +111,7 @@ sub rec_socket $line =~ s/\n/\r/og if $mode == 1; #my $p = qq($line$snl); if ($buffered) { - if (length $outqueue >= 128) { + if (length $outqueue >= $client_buffer_lth) { print $stdout $outqueue; $outqueue = ""; } @@ -123,7 +129,8 @@ sub rec_socket $mode = $line; # set echo mode from cluster my $term = POSIX::Termios->new; $term->getattr(fileno($sock)); - $term->setflag( &POSIX::ISIG ); + $term->setiflag( 0 ); + $term->setoflag( 0 ); $term->setattr(fileno($sock), &POSIX::TCSANOW ); } } elsif ($sort eq 'I') { @@ -156,7 +163,9 @@ sub rec_stdin # $prbuf =~ s/\r/\\r/; # $prbuf =~ s/\n/\\n/; # print "sys: $r ($prbuf)\n"; - if ($r > 0) { + if (!defined $r || $r == 0) { + cease(1); + } elsif ($r > 0) { if ($mode) { $buf =~ s/\r/\n/og if $mode == 1; $buf =~ s/\r\n/\n/og if $mode == 2; @@ -182,9 +191,7 @@ sub rec_stdin } else { $conn->send_later("I$call|$buf"); } - } elsif ($r == 0) { - cease(1); - } + } $lasttime = time; } @@ -201,24 +208,26 @@ sub doconnect my ($host, $port) = split /\s+/, $line; $port = 23 if !$port; - if ($port == 23) { - $sock = new Net::Telnet (Timeout => $timeout); +# if ($port == 23) { + + $sock = new Net::Telnet (Timeout => $timeout, Port => $port); $sock->option_callback(\&optioncb); $sock->output_record_separator(''); - $sock->option_log('option_log'); - $sock->dump_log('dump'); - $sock->option_accept(Wont => TELOPT_ECHO); +# $sock->option_log('option_log'); +# $sock->dump_log('dump'); + $sock->option_accept(Dont => TELOPT_ECHO, Wont => TELOPT_ECHO); $sock->open($host) or die "Can't connect to $host port $port $!"; - } else { - $sock = IO::Socket::INET->new(PeerAddr => "$host:$port", Proto => 'tcp') - or die "Can't connect to $host port $port $!"; - - } +# } else { +# $sock = IO::Socket::INET->new(PeerAddr => "$host:$port", Proto => 'tcp') +# or die "Can't connect to $host port $port $!"; +# } } elsif ($sort eq 'ax25' || $sort eq 'prog') { my @args = split /\s+/, $line; $rfh = new IO::File; $wfh = new IO::File; $pid = open2($rfh, $wfh, "$line") or die "can't do $line $!"; + die "no receive channel $!" unless $rfh; + die "no transmit channel $!" unless $wfh; dbg('connect', "got pid $pid"); $wfh->autoflush(1); } else { @@ -253,6 +262,7 @@ sub dochat for (;;) { if ($csort eq 'telnet') { $line = $sock->get(); + cease(11) unless $line; # the socket has gone away? $line =~ s/\r\n/\n/og; chomp; } elsif ($csort eq 'ax25' || $csort eq 'prog') { @@ -282,7 +292,7 @@ sub dochat sub timeout { dbg('connect', "timed out after $timeout seconds"); - cease(10); + cease(0); } @@ -292,12 +302,12 @@ sub timeout $mode = 2; # 1 - \n = \r as EOL, 2 - \n = \n, 0 - transparent $call = ""; # the callsign being used -@stdoutq = (); # the queue of stuff to send out to the user $conn = 0; # the connection object for the cluster $lastbit = ""; # the last bit of an incomplete input line $mynl = "\n"; # standard terminator $lasttime = time; # lasttime something happened on the interface -$outqueue = ""; # the output queue length +$outqueue = ""; # the output queue +$client_buffer_lth = 200; # how many characters are buffered up on outqueue $buffered = 1; # buffer output $savenl = ""; # an NL that has been saved from last time $timeout = 60; # default timeout for connects @@ -313,14 +323,15 @@ $stdout = *STDOUT; $rfh = 0; $wfh = 0; +$waitedpid = 0; # # deal with args # -$call = uc shift @ARGV; +$call = uc shift @ARGV if @ARGV; $call = uc $myalias if !$call; -$connsort = lc shift @ARGV; +$connsort = lc shift @ARGV if @ARGV; $connsort = 'local' if !$connsort; $loginreq = $call eq 'LOGIN'; @@ -340,6 +351,7 @@ $SIG{'INT'} = \&sig_term; $SIG{'TERM'} = \&sig_term; $SIG{'HUP'} = 'IGNORE'; $SIG{'CHLD'} = \&sig_chld; +$SIG{'ALRM'} = \&timeout; dbgadd('connect'); @@ -348,28 +360,50 @@ if ($loginreq) { my $user; my $s; + if (-e "$data/issue") { + open(I, "$data/issue") or die; + local $/ = undef; + $issue = ; + close(I); + $issue = s/\n/\r/og if $mode == 1; + local $/ = $nl; + $stdout->print($issue) if $issue; + } + + + use DXUser; + DXUser->init($userfn); + # allow a login from an existing user. I could create a user but + # I want to check for valid callsigns and I don't have the + # necessary info / regular expression yet for ($state = 0; $state < 2; ) { alarm($timeout); if ($state == 0) { $stdout->print('login: '); $stdout->flush(); - local $/ = $mode == 1 ? "\r" : "\n"; + local $\ = $nl; $s = $stdin->getline(); chomp $s; + $s =~ s/\s+//og; + $s =~ s/-\d+$//o; # no ssids! + cease(0) unless $s gt ' '; $call = uc $s; $user = DXUser->get($call); $state = 1; } elsif ($state == 1) { $stdout->print('password: '); $stdout->flush(); - local $/ = $mode == 1 ? "\r" : "\n"; + local $\ = $nl; $s = $stdin->getline(); chomp $s; $state = 2; - cease(0) if !$user || ($user->passwd && $user->passwd ne $s); + if (!$user || ($user->passwd && $user->passwd ne $s)) { + $stdout->print("sorry...$nl"); + cease(0); + } } } } @@ -390,8 +424,8 @@ if ($connsort eq "connect") { open(IN, "$cpath/$mcall") or cease(2); @in = ; close IN; - - # alarm($timeout); + + alarm($timeout); for (@in) { chomp; @@ -418,7 +452,7 @@ if ($connsort eq "connect") { # close W; $stdin = $rfh; $stdout = $wfh; - $csort = 'telnet' if $sort eq 'prog'; + $csort = 'telnet' if $csort eq 'prog'; } elsif ($csort eq 'telnet') { # open(STDIN, "<&$sock"); # open(STDOUT, ">&$sock"); @@ -444,7 +478,7 @@ if (! $conn) { open IN, "$data/offline" or die; while () { s/\n/\r/og if $mode == 1; - print $stdout; + print $stdout $_; } close IN; } else {