mega-merge of major parts of mojo
[spider.git] / cmd / send.pl
1 #
2 # send a message
3 #
4 # this should handle
5 #
6 # send <call> [<call> .. ]
7 # send private <call> [<call> .. ]
8 # send private rr <call> [<call> .. ]
9 # send rr <call> [<call> .. ]
10 # send noprivate <call> [<call> .. ]
11 # send b <call> [<call> .. ]
12 # send copy <call> [<call> .. ]
13 # send copy rr <call> [<call> .. ]
14
15 # Copyright (c) Dirk Koopman G1TLH
16 #
17 #
18 #
19 my ($self, $line) = @_;
20 return (1, $self->msg('e5')) if $self->remotecmd || $self->inscript;
21 return (1, $self->msg('e36')) unless $self->state =~ /^prompt/;
22
23 my @out;
24 my $loc = $self->{loc} = {};
25 my $notincalls = 1;
26 my @to;
27
28 # set up defaults
29 $loc->{private} = '1';
30 $loc->{rrreq} = '0';
31
32 # $DB::single = 1;
33
34 if ($self->state eq "prompt") {
35
36         my @f = split /([\s\@\$,])/, $line;
37         @f = map {s/\s+//g; length $_ ? $_ : ()} @f;
38         @f = grep {$_ ne ','} @f;
39         
40         # any thing after send?
41         return (1, $self->msg('e6')) if !@f;
42         return (1, $self->msg('e28')) unless $self->isregistered || uc $f[0] eq $main::myalias;
43
44         while (@f) {
45                 my $f = uc shift @f; 
46
47                 # first deal with copies
48                 if ($f eq 'C' || $f eq 'CC' || $f eq 'COPY') {
49                         my $rr = '0';
50                         if (@f && uc $f[0] eq 'RR') {
51                                 shift @f;
52                                 $rr = '1';
53                         }
54                         
55                         if (@f) {
56                                 my $m = shift @f;
57                                 my $oref = DXMsg::get($m);
58                                 return (0, $self->msg('m4', $m)) unless $oref;
59                                 return (0, $self->msg('m16')) unless @f;
60                         
61                                 # separate copy to everyone listed
62                                 while (@f) {
63                                         my $newcall = uc shift @f;
64                                         my $msgno = DXMsg::next_transno('Msgno');
65                                         my $newsubj = "CC: " . $oref->subject;
66                                         my $nref = DXMsg->alloc($msgno, 
67                                                                                         $newcall, 
68                                                                                         $self->call,  
69                                                                                         $main::systime, 
70                                                                                         '1',  
71                                                                                         $newsubj, 
72                                                                                         $main::mycall,
73                                                                                         '0',
74                                                                                         $rr);
75                                         my @list;
76                                         my $from = $oref->from;
77                                         my $to = $oref->to;
78                                         my $date = cldate($oref->t);
79                                         my $time = ztime($oref->t);
80                                         my $buf = "Original from: $from To: $to Date: $date $time";
81                                         push @list, $buf; 
82                                         push @list, $oref->read_msg_body();
83                                         $nref->store(\@list);
84                                         $nref->add_dir();
85                                         push @out, $self->msg('m2', $oref->msgno, $newcall);
86                                 } 
87                         }
88                         DXMsg::queue_msg();
89                         return (1, @out);
90                 }
91
92                 # private / noprivate / rr
93                 if ($notincalls && ($f eq 'B' || $f =~ /^NOP/oi)) {
94                         $loc->{private} = '0';
95                 } elsif ($notincalls && ($f eq 'P' || $f =~ /^PRI/oi)) {
96                         ;
97                 } elsif ($notincalls && ($f eq 'RR')) {
98                         $loc->{rrreq} = '1';
99                 } elsif ($f eq '<' && @f) {     # this is bbs syntax  for from call
100                         $loc->{from} = uc shift @f;
101                 } elsif (($f =~ /^[\@\.\#\$]$/ || $f eq '.#') && @f) {       # this is bbs syntax, for send it 'to node'
102                         shift @f;
103                 } elsif ($f =~ /^\$/) {     # this is bbs syntax  for a bid
104                         next;
105                 } elsif ($f =~ /^<(\S+)/) {     # this is bbs syntax  for from call
106                         $loc->{from} = $1;
107                 } elsif ($f =~ /^\$\S+/) {     # this is bbs syntax  for bid
108                         ;
109                 } else {
110
111                         # callsign ?
112                         $notincalls = 0;
113
114 #                       $DB::single = 1;
115                         
116                         # is this callsign a distro?
117                         # but be careful about messages to 'sysop'
118                         if ($self->priv < 5 && $f eq 'SYSOP') {
119                                 push @to, $main::myalias;
120                                 $loc->{private} = 1;
121                         } else {
122                                 my $fn = "/spider/msg/distro/$f.pl";
123                                 if (-e $fn) {
124                                         my $fh = new IO::File $fn;
125                                         if ($fh) {
126                                                 local $/ = undef;
127                                                 my $s = <$fh>;
128                                                 $fh->close;
129                                                 my @call;
130                                                 @call = eval $s;
131                                                 return (1, "Error in Distro $f.pl:", $@) if $@;
132                                                 if (@call > 0) {
133                                                         push @f, @call;
134                                                         next;
135                                                 }
136                                         }
137                                 }
138                         }
139
140                         if (($loc->{private} && is_callsign($f)) || (!$loc->{private} && DXMsg::valid_bull_addr($f))) {
141                                 if (grep $_ eq $f, @DXMsg::badmsg) {
142                                         push @out, $self->msg('m3', $f);
143                                 } else {
144                                         push @to, $f;
145                                 }
146                         } else {
147                                 push @out, $self->msg('m3', $f);
148                         }
149                 }
150         }
151
152         # check we have some callsigns
153         if (@to) {
154                 $loc->{to} = \@to;
155         } else {
156                 delete $self->{loc};
157                 return (1, @out, $self->msg('e6'));
158         }
159         $loc->{from} ||= $self->call;
160         unless (is_callsign($loc->{from})) {
161                 delete $self->{loc};
162                 return (1, $self->msg('e22', $loc->{from}));
163         }
164
165         # find me and set the state and the function on my state variable to
166         # keep calling me for every line until I relinquish control
167         $self->func("DXMsg::do_send_stuff");
168         $self->state('send1');
169         push @out, $self->msg('m1');
170 } else {
171         push @out, $self->msg('m17', $self->state);
172 }
173
174 return (1, @out);