3 # A thing that implements dxcluster 'protocol'
5 # This is a perl module/program that sits on the end of a dxcluster
6 # 'protocol' connection and deals with anything that might come along.
8 # this program is called by ax25d and gets raw ax25 text on its input
10 # Copyright (c) 1998 Dirk Koopman G1TLH
15 # search local then perl directories
17 unshift @INC, "/spider/perl"; # this IS the right way round!
18 unshift @INC, "/spider/local";
24 $mode = 2; # 1 - \n = \r as EOL, 2 - \n = \n, 0 - transparent
25 $call = ""; # the callsign being used
26 @stdoutq = (); # the queue of stuff to send out to the user
27 $conn = 0; # the connection object for the cluster
28 $lastbit = ""; # the last bit of an incomplete input line
29 $mynl = "\n"; # standard terminator
30 $lasttime = time; # lasttime something happened on the interface
31 $outqueue = ""; # the output queue length
32 $buffered = 1; # buffer output
33 $savenl = ""; # an NL that has been saved from last time
35 # cease communications
39 if (defined $conn && $sendz) {
40 $conn->send_now("Z$call|bye...\n");
45 # terminate program from signal
61 # handle incoming messages
64 my ($con, $msg, $err) = @_;
65 if (defined $err && $err) {
69 my ($sort, $call, $line) = $msg =~ /^(\w)(\S+)\|(.*)$/;
74 $snl = "" if $mode == 0;
75 if ($mode && $line =~ />$/) {
79 $line =~ s/\n/\r/og if $mode == 1;
80 #my $p = qq($line$snl);
82 if (length $outqueue >= 128) {
86 $outqueue .= "$savenl$line$snl";
89 print $savenl, $line, $snl;;
92 } elsif ($sort eq 'M') {
93 $mode = $line; # set new mode from cluster
95 } elsif ($sort eq 'B') {
96 if ($buffered && $outqueue) {
100 $buffered = $line; # set buffered or unbuffered
101 } elsif ($sort eq 'Z') { # end, disconnect, go, away .....
117 $r = sysread($fh, $buf, 1024);
118 # print "sys: $r $buf";
121 $buf =~ s/\r/\n/og if $mode == 1;
122 $dangle = !($buf =~ /\n$/);
123 @lines = split /\n/, $buf;
124 if ($dangle) { # pull off any dangly bits
129 $first = shift @lines;
130 unshift @lines, ($lastbit . $first) if ($first);
131 foreach $first (@lines) {
132 $conn->send_now("D$call|$first");
135 $savenl = ""; # reset savenl 'cos we will have done a newline on input
137 $conn->send_now("D$call|$buf");
145 $call = uc shift @ARGV;
146 $call = uc $myalias if !$call;
147 $connsort = lc shift @ARGV;
148 $connsort = 'local' if !$connsort;
149 $mode = ($connsort =~ /^ax/o) ? 1 : 2;
151 if ($call eq $mycall) {
152 print "You cannot connect as your cluster callsign ($mycall)", $nl;
156 #select STDOUT; $| = 1;
157 STDOUT->autoflush(1);
159 $SIG{'INT'} = \&sig_term;
160 $SIG{'TERM'} = \&sig_term;
161 $SIG{'HUP'} = \&sig_term;
163 $conn = Msg->connect("$clusteraddr", $clusterport, \&rec_socket);
164 $conn->send_now("A$call|$connsort");
165 Msg->set_event_handler(\*STDIN, "read" => \&rec_stdin);
169 Msg->event_loop(1, 0.010);
171 if ($t > $lasttime) {