put dx.pl into an explicit handle sub
[spider.git] / perl / EphMsg.pm
1 #
2 # This class is the internal subclass that deals with 'Ephmeral'
3 # communications like: querying http servers and other network
4 # connected data services and using Msg.pm
5 #
6 # An instance of this is setup by a command together with a load
7 # of callbacks and then runs with a state machine until completion
8 #
9 #
10 #
11 # Copyright (c) 2001 - Dirk Koopman G1TLH
12 #
13
14 package EphMsg;
15
16 use strict;
17 use Msg;
18 use DXVars;
19 use DXUtil;
20 use DXDebug;
21 use IO::File;
22 use IO::Socket;
23 use IPC::Open3;
24
25 use vars qw(@ISA $deftimeout);
26
27 @ISA = qw(Msg);
28 $deftimeout = 60;
29
30
31 sub new
32 {
33
34 }
35
36 # we probably won't use the normal format
37 sub enqueue
38 {
39         my ($conn, $msg) = @_;
40         push (@{$conn->{outqueue}}, $msg . $conn->{lineend});
41 }
42
43 sub dequeue
44 {
45         my $conn = shift;
46         my $msg;
47
48         if ($conn->ax25 && exists $conn->{msg}) {
49                 $conn->{msg} =~ s/\cM/\cJ/g;
50         }
51
52         if ($conn->{state} eq 'WC') {
53                 $conn->to_connected($conn->{call}, 'O', $conn->{csort});
54         }
55
56         if ($conn->{msg} =~ /\cJ/) {
57                 my @lines =  $conn->{msg} =~ /([^\cM\cJ]*)\cM?\cJ/g;
58                 if ($conn->{msg} =~ /\cJ$/) {
59                         delete $conn->{msg};
60                 } else {
61                         $conn->{msg} =~ s/([^\cM\cJ]*)\cM?\cJ//g;
62                 }
63
64                 while (defined ($msg = shift @lines)) {
65                         dbg("connect $conn->{cnum}: $msg") if $conn->{state} ne 'C' && isdbg('connect');
66
67                         $msg =~ s/\xff\xfa.*\xff\xf0|\xff[\xf0-\xfe].//g; # remove telnet options
68
69                         &{$conn->{rproc}}($conn, $msg);
70                 }
71         }
72 }
73
74 sub start_connect
75 {
76         my $call = shift;
77         my $fn = shift;
78         my $conn = ExtMsg->new(\&main::new_channel);
79         $conn->{outgoing} = 1;
80         $conn->conns($call);
81
82         my $f = new IO::File $fn;
83         push @{$conn->{cmd}}, <$f>;
84         $f->close;
85         $conn->{state} = 'WC';
86         $conn->_dotimeout($deftimeout);
87 }
88
89 sub _doconnect
90 {
91         my ($conn, $sort, $line) = @_;
92         my $r;
93
94         $sort = lc $sort;                       # in this case telnet, ax25 or prog
95         dbg("CONNECT $conn->{cnum} sort: $sort command: $line") if isdbg('connect');
96         if ($sort eq 'telnet') {
97                 # this is a straight network connect
98                 my ($host, $port) = split /\s+/, $line;
99                 $port = 23 if !$port;
100                 $r = $conn->connect($host, $port);
101                 if ($r) {
102                         dbg("Connected $conn->{cnum} to $host $port") if isdbg('connect');
103                 } else {
104                         dbg("***Connect $conn->{cnum} Failed to $host $port $!") if isdbg('connect');
105                 }
106         } elsif ($sort eq 'prog') {
107                 $r = $conn->start_program($line, $sort);
108         } else {
109                 dbg("invalid type of connection ($sort)");
110         }
111         $conn->disconnect unless $r;
112         return $r;
113 }
114
115 sub _doabort
116 {
117         my $conn = shift;
118         my $string = shift;
119         dbg("connect $conn->{cnum}: abort $string") if isdbg('connect');
120         $conn->{abort} = $string;
121 }
122
123 sub _dotimeout
124 {
125         my $conn = shift;
126         my $val = shift;
127         dbg("connect $conn->{cnum}: timeout set to $val") if isdbg('connect');
128         $conn->{timeout}->del if $conn->{timeout};
129         $conn->{timeval} = $val;
130         $conn->{timeout} = Timer->new($val, sub{ &_timedout($conn) });
131 }
132
133
134 sub _timedout
135 {
136         my $conn = shift;
137         dbg("connect $conn->{cnum}: timed out after $conn->{timeval} seconds") if isdbg('connect');
138         $conn->disconnect;
139 }
140
141 # handle callsign and connection type firtling
142 sub _doclient
143 {
144         my $conn = shift;
145         my $line = shift;
146         my @f = split /\s+/, $line;
147         my $call = uc $f[0] if $f[0];
148         $conn->conns($call);
149         $conn->{csort} = $f[1] if $f[1];
150         $conn->{state} = 'C';
151         &{$conn->{rproc}}($conn, "O$call|$conn->{csort}");
152         delete $conn->{cmd};
153         $conn->{timeout}->del if $conn->{timeout};
154 }
155
156 sub _send_file
157 {
158         my $conn = shift;
159         my $fn = shift;
160
161         if (-e $fn) {
162                 my $f = new IO::File $fn;
163                 if ($f) {
164                         while (<$f>) {
165                                 chomp;
166                                 my $l = $_;
167                                 dbg("connect $conn->{cnum}: $l") if isdbg('connll');
168                                 $conn->send_raw($l . $conn->{lineend});
169                         }
170                         $f->close;
171                 }
172         }
173 }