b2dcfa3a7223d4cebba279b334de3e66a7525d64
[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 BEGIN {
16   unshift @INC, "/spider/local";
17   unshift @INC, "/spider/perl";
18 }
19
20 use Msg;
21 use DXVars;
22
23 $mode = 1;                      # 1 - \n = \r as EOL, 2 - \n = \n, 0 - transparent
24 $call = "";                     # the callsign being used
25 @stdoutq = ();                  # the queue of stuff to send out to the user
26 $conn = 0;                      # the connection object for the cluster
27 $lastbit = "";                  # the last bit of an incomplete input line
28
29 # cease communications
30 sub cease
31 {
32   my $sendz = shift;
33   if (defined $conn && $sendz) {
34     $conn->send_now("Z$call|bye...\n");
35   }
36   exit(0);      
37 }
38
39 # terminate program from signal
40 sub sig_term
41 {
42   cease(1);
43 }
44
45 sub setmode
46 {
47   if ($mode == 1) {
48     $nl = "\r";
49   } else {
50         $nl = "\n";
51   }
52   $/ = $nl;
53   if ($mode == 0) {
54     $\ = undef;
55   } else {
56     $\ = $nl;
57   }
58 }
59
60 # handle incoming messages
61 sub rec_socket
62 {
63   my ($con, $msg, $err) = @_;
64   if (defined $err && $err) {
65     cease(1);
66   }
67   if (defined $msg) {
68     my ($sort, $call, $line) = $msg =~ /^(\w)(\S+)\|(.*)$/;
69         
70         if ($sort eq 'D') {
71            $nl = "" if $mode == 0;
72            $line =~ s/\n/\r/og if $mode == 1;
73            print $line;
74         } elsif ($sort eq 'M') {
75           $mode = $line;               # set new mode from cluster
76       setmode();
77     } elsif ($sort eq 'Z') {       # end, disconnect, go, away .....
78           cease(0);
79     }     
80   } 
81 }
82
83 sub rec_stdin
84 {
85   my ($fh) = @_;
86   my $buf;
87   my @lines;
88   my $r;
89   my $first;
90   my $dangle = 0;
91   
92   $r = sysread($fh, $buf, 1024);
93 #  print "sys: $r $buf";
94   if ($r > 0) {
95     if ($mode) {
96           $buf =~ s/\r/\n/og if $mode == 1;
97           $dangle = !($buf =~ /\n$/);
98           @lines = split /\n/, $buf;
99           if ($dangle) {                # pull off any dangly bits
100             $buf = pop @lines;
101           } else {
102             $buf = "";
103           }
104           $first = shift @lines;
105           unshift @lines, ($lastbit . $first) if ($first);
106           foreach $first (@lines) {
107             $conn->send_now("D$call|$first");
108           }
109           $lastbit = $buf;  
110         } else {
111           $conn->send_now("D$call|$buf");
112         }
113   } elsif ($r == 0) {
114     cease(1);
115   }
116 }
117
118 $call = uc $ARGV[0];
119 die "client.pl <call> [<mode>]\r\n" if (!$call);
120 $mode = $ARGV[1] if (@ARGV > 1);
121 setmode();
122
123
124 #select STDOUT; $| = 1;
125 STDOUT->autoflush(1);
126
127 $SIG{'INT'} = \&sig_term;
128 $SIG{'TERM'} = \&sig_term;
129 $SIG{'HUP'} = \&sig_term;
130
131 $conn = Msg->connect("$clusteraddr", $clusterport, \&rec_socket);
132 $conn->send_now("A$call|start");
133 Msg->set_event_handler(\*STDIN, "read" => \&rec_stdin);
134 Msg->event_loop();
135