added email forwarding
[spider.git] / perl / DXMsg.pm
index 7cab1d02f18336d930ab1c6da7c118f973c0eacd..f60b59038e274f77b6468b85886ab1c998c9a8c0 100644 (file)
@@ -26,6 +26,10 @@ use DXLog;
 use IO::File;
 use Fcntl;
 
+eval {
+       require Mail::Send;
+};
+
 use strict;
 
 use vars qw($VERSION $BRANCH);
@@ -282,7 +286,7 @@ sub process
                                                # does an identical message already exist?
                                                my $m;
                                                for $m (@msg) {
-                                                       if ($ref->{subject} eq $m->{subject} && $ref->{t} == $m->{t} && $ref->{from} eq $m->{from} && $ref->{to} eq $m->{to}) {
+                                                       if (substr($ref->{subject},0,28) eq substr($m->{subject},0,28) && $ref->{t} == $m->{t} && $ref->{from} eq $m->{from} && $ref->{to} eq $m->{to}) {
                                                                $ref->stop_msg($fromnode);
                                                                my $msgno = $m->{msgno};
                                                                dbg("duplicate message from $ref->{from} -> $ref->{to} to msg: $msgno") if isdbg('msg');
@@ -309,8 +313,8 @@ sub process
                                                }
                                                push @words, BadWords::check($ref->{subject});
                                                if (@words) {
-                                                       dbg("message with badwords '@words' $ref->{from} -> $ref->{to} '$ref->{subject}' origin: $ref->{origin} via " . $self->call) if isdbg('msg');
-                                                       Log('msg',"message with badwords '@words' $ref->{from} -> $ref->{to} origin: $ref->{origin} via " . $self->call);
+                                                       dbg("$ref->{from} swore: '@words' -> $ref->{to} '$ref->{subject}' origin: $ref->{origin} via " . $self->call) if isdbg('msg');
+                                                       Log('msg',"$ref->{from} swore: '@words' -> $ref->{to} origin: $ref->{origin} via " . $self->call);
                                                        Log('msg',"subject: $ref->{subject}");
                                                        for (@{$ref->{lines}}) {
                                                                Log('msg', "line: $_");
@@ -322,9 +326,8 @@ sub process
                                                $ref->{msgno} = next_transno("Msgno");
                                                push @{$ref->{gotit}}, $fromnode; # mark this up as being received
                                                $ref->store($ref->{lines});
+                                               $ref->notify;
                                                add_dir($ref);
-                                               my $dxchan = DXChannel->get($ref->{to});
-                                               $dxchan->send($dxchan->msg('m9')) if $dxchan && $dxchan->is_user;
                                                Log('msg', "Message $ref->{msgno} from $ref->{from} received from $fromnode for $ref->{to}");
                                        }
                                }
@@ -418,6 +421,30 @@ sub process
 }
 
 
+sub notify
+{
+       my $ref = shift;
+       my $to = $ref->{to};
+       my $uref = DXUser->get($to);
+       my $dxchan = DXChannel->get($to);
+       if (*Mail::Send && $uref && $uref->wantemail) {
+               my $email = $uref->email;
+               if ($email) {
+                       my @list = ref $email ? @{$email} : $email;
+                       my $msg = new Mail::Send Subject=>"[DXSpider: $ref->{from}] $ref->{subject}";
+                       $msg->to(@list);
+                       my $fh = $msg->open;
+                       print $fh "From: $ref->{from} To: $to On Node: $main::mycall Origin: $ref->{origin} Msgno: $ref->{msgno}\r\n\r\n";
+                       print $fh map {"$_\r\n"} $ref->read_msg_body;
+                       $fh->close;
+                       for (@list) {
+                               Log('msg', "Msgno $ref->{msgno} from $ref->{from} emailed to $_");
+                       }
+               }
+       }
+       $dxchan->send($dxchan->msg('m9')) if $dxchan && $dxchan->is_user;
+}
+
 # store a message away on disc or whatever
 #
 # NOTE the second arg is a REFERENCE not a list
@@ -482,15 +509,12 @@ sub del_msg
                $self->{delete}++;
                $self->{deletetime} = 0;
        } else {
-               my $call;
-               if ($dxchan) {
-                       $call = " by " . $dxchan->call;
-               } else {
-                       $call = '';
-               }
-
                # remove it from the active message list
                @msg = grep { $_ != $self } @msg;
+
+               my $call = '';
+               $call = ' by ' . $dxchan->call if $dxchan;
+               Log('msg', "Msgno $self->{msgno} expunged$call");
                
                # remove the file
                unlink filename($self->{msgno});
@@ -659,7 +683,7 @@ sub queue_msg
                next if $ref->{tonode};           # ignore it if it already being processed
                
                # is it awaiting deletion?
-               if ($ref->{delete} && $main::systime > $ref->{deletetime}) {
+               if ($ref->{delete} && $main::systime >= $ref->{deletetime}) {
                        $ref->del_msg;
                        next;
                }
@@ -962,7 +986,7 @@ sub do_send_stuff
                if (my @ans = BadWords::check($line)) {
                        $self->{badcount} += @ans;
                        Log('msg', $self->call . " used badwords: @ans to @{$loc->{to}} in msg");
-                       return ($self->msg('e17', @ans), $self->msg('m1'));
+                       $loc->{reject}++;
                }
                $loc->{subject} = $line;
                $loc->{lines} = [];
@@ -974,33 +998,31 @@ sub do_send_stuff
                my $loc = $self->{loc};
                if ($line eq "\032" || $line eq '%1A' || uc $line eq "/EX") {
                        my $to;
-                       
-                       foreach $to (@{$loc->{to}}) {
-                               my $ref;
-                               my $systime = $main::systime;
-                               my $mycall = $main::mycall;
-                               $ref = DXMsg->alloc(DXMsg::next_transno('Msgno'),
-                                                                       uc $to,
-                                                                       exists $loc->{from} ? $loc->{from} : $self->call, 
-                                                                       $systime,
-                                                                       $loc->{private}, 
-                                                                       $loc->{subject}, 
-                                                                       exists $loc->{origin} ? $loc->{origin} : $mycall,
-                                                                       '0',
-                                                                       $loc->{rrreq});
-                               $ref->swop_it($self->call);
-                               $ref->store($loc->{lines});
-                               $ref->add_dir();
-                               push @out, $self->msg('m11', $ref->{msgno}, $to);
-                               #push @out, "msgno $ref->{msgno} sent to $to";
-                               my $dxchan = DXChannel->get(uc $to);
-                               if ($dxchan) {
-                                       if ($dxchan->is_user()) {
-                                               $dxchan->send($dxchan->msg('m9'));
-                                       }
+                       unless ($loc->{reject}) {
+                               foreach $to (@{$loc->{to}}) {
+                                       my $ref;
+                                       my $systime = $main::systime;
+                                       my $mycall = $main::mycall;
+                                       $ref = DXMsg->alloc(DXMsg::next_transno('Msgno'),
+                                                                               uc $to,
+                                                                               exists $loc->{from} ? $loc->{from} : $self->call, 
+                                                                               $systime,
+                                                                               $loc->{private}, 
+                                                                               $loc->{subject}, 
+                                                                               exists $loc->{origin} ? $loc->{origin} : $mycall,
+                                                                               '0',
+                                                                               $loc->{rrreq});
+                                       $ref->swop_it($self->call);
+                                       $ref->store($loc->{lines});
+                                       $ref->add_dir();
+                                       push @out, $self->msg('m11', $ref->{msgno}, $to);
+                                       #push @out, "msgno $ref->{msgno} sent to $to";
+                                       $ref->notify;
                                }
+                       } else {
+                               Log('msg', $self->call . " swore to @{$loc->{to}} subject: '$loc->{subject}' in msg, REJECTED");
                        }
-
+                       
                        delete $loc->{lines};
                        delete $loc->{to};
                        delete $self->{loc};
@@ -1018,9 +1040,9 @@ sub do_send_stuff
                } else {
                        if (my @ans = BadWords::check($line)) {
                                $self->{badcount} += @ans;
-                               Log('msg', $self->call . " used badwords: @ans to @{$loc->{to}} subject: '$loc->{subject}' in msg");
+                               Log('msg', $self->call . " used badwords: @ans to @{$loc->{to}} subject: '$loc->{subject}' in msg") unless $loc->{reject};
                                Log('msg', "line: $line");
-                               return ($self->msg('e17', @ans));
+                               $loc->{reject}++;
                        }
                        
                        # i.e. it ain't and end or abort, therefore store the line
@@ -1218,7 +1240,6 @@ sub import_msgs
                my @out = import_one($main::me, \@msg, $splitit);
                Log('msg', @out);
        }
-       queue_msg(0);
 }
 
 # import one message as a list in bbs (as extended) mode
@@ -1238,7 +1259,7 @@ sub import_one
                                
        # first line;
        my $line = shift @$ref;
-       my @f = split /\b/, $line;
+       my @f = split /([\s\@\$])/, $line;
        @f = map {s/\s+//g; length $_ ? $_ : ()} @f;
 
        unless (@f && $f[0] =~ /^(:?S|SP|SB|SEND)$/ ) {
@@ -1326,7 +1347,18 @@ sub import_one
        } else {
                push @chunk, $ref;
        }
-                                 
+
+       # does an identical message already exist?
+       my $m;
+       for $m (@msg) {
+               if (substr($subject,0,28) eq substr($m->{subject},0,28) && $from eq $m->{from} && grep $m->{to} eq $_, @to) {
+                       my $msgno = $m->{msgno};
+                       dbg("duplicate message from $from -> $m->{to} to msg: $msgno") if isdbg('msg');
+                       Log('msg', "duplicate message from $from -> $m->{to} to msg: $msgno");
+                       return;
+               }
+       }
+
     # write all the messages away
        my $i;
        for ( $i = 0;  $i < @chunk; $i++) {
@@ -1356,12 +1388,7 @@ sub import_one
                        $mref->add_dir();
                        push @out, $dxchan->msg('m11', $mref->{msgno}, $to);
                        #push @out, "msgno $ref->{msgno} sent to $to";
-                       my $todxchan = DXChannel->get(uc $to);
-                       if ($todxchan) {
-                               if ($todxchan->is_user()) {
-                                       $todxchan->send($todxchan->msg('m9'));
-                               }
-                       }
+                       $mref->notify;
                }
        }
        return @out;