added Ids and changed the name of DXConnect to DXChannel
[spider.git] / perl / client.pl
1 #!/usr/bin/perl
2 #
3 # A thing that implements dxcluster 'protocol'
4 #
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.
7 #
8 # this program is called by ax25d and gets raw ax25 text on its input
9 #
10 # Copyright (c) 1998 Dirk Koopman G1TLH
11 #
12 # $Id$
13
14
15 use Msg;
16 use DXVars;
17
18 $mode = 1;                      # 1 - \n = \r as EOL, 2 - \n = \n, 0 - transparent
19 $call = "";                     # the callsign being used
20 @stdoutq = ();                  # the queue of stuff to send out to the user
21 $conn = 0;                      # the connection object for the cluster
22 $lastbit = "";                  # the last bit of an incomplete input line
23
24 # cease communications
25 sub cease
26 {
27   my $sendz = shift;
28   if (defined $conn && $sendz) {
29     $conn->send_now("Z$call|bye...\n");
30   }
31   exit(0);      
32 }
33
34 # terminate program from signal
35 sub sig_term
36 {
37   cease(1);
38 }
39
40 # handle incoming messages
41 sub rec_socket
42 {
43   my ($con, $msg, $err) = @_;
44   if (defined $err && $err) {
45     cease(1);
46   }
47   if (defined $msg) {
48     my ($sort, $call, $line) = $msg =~ /^(\w)(\S+)|(.*)$/;
49         
50         if ($sort eq 'D') {
51            my $nl = ($mode == 1) ? "\r" : "\n";
52            $nl = "" if $mode == 0;
53            $line =~ s/\n/\r/o if $mode == 1;
54            print $line, $nl;
55         } elsif ($sort eq 'M') {
56           $mode = $line;               # set new mode from cluster
57         } elsif ($sort eq 'Z') {       # end, disconnect, go, away .....
58           cease(0);
59     }     
60   } 
61 }
62
63 sub rec_stdin
64 {
65   my ($fh) = @_;
66   my $buf;
67   my @lines;
68   my $r;
69   my $first;
70   my $dangle = 0;
71   
72   $r = sysread($fh, $buf, 1024);
73 #  print "sys: $r $buf";
74   if ($r > 0) {
75     if ($mode) {
76           $buf =~ s/\r/\n/o if $mode == 1;
77           $dangle = !($buf =~ /\n$/);
78           @lines = split /\n/, $buf;
79           if ($dangle) {                # pull off any dangly bits
80             $buf = pop @lines;
81           } else {
82             $buf = "";
83           }
84           $first = shift @lines;
85           unshift @lines, ($lastbit . $first) if ($first);
86           foreach $first (@lines) {
87             $conn->send_now("D$call|$first");
88           }
89           $lastbit = $buf;  
90         } else {
91           $conn->send_now("D$call|$buf");
92         }
93   } elsif ($r == 0) {
94     cease(1);
95   }
96 }
97
98 $call = uc $ARGV[0];
99 die "client.pl <call> [<mode>]\r\n" if (!$call);
100 $mode = $ARGV[1] if (@ARGV > 1);
101
102 select STDOUT; $| = 1;
103
104 $SIG{'INT'} = \&sig_term;
105 $SIG{'TERM'} = \&sig_term;
106 $SIG{'HUP'} = \&sig_term;
107
108 $conn = Msg->connect("$clusteraddr", $clusterport, \&rec_socket);
109 $conn->send_now("A$call|start");
110 Msg->set_event_handler(\*STDIN, "read" => \&rec_stdin);
111 Msg->event_loop();
112