- # get the next msg no - note that this has NOTHING to do with the stream number in PC protocol
- # store the file or message
- # remove extraneous rubbish from the hash
- # remove it from the work in progress vector
- # stuff it on the msg queue
- $ref->{msgno} = next_transno("Msgno") if !$ref->{file};
- $ref->store($ref->{lines});
- $ref->workclean;
- delete $work{"$f[1]$f[2]$f[3]"};
- push @msg, $ref;
- }
- last SWITCH;
- }
-
- if ($pcno == 33) {
- last SWITCH;
- }
-
- if ($pcno == 40) { # this is a file request
- $f[3] =~ s/\\/\//og; # change the slashes
- $f[3] =~ s/\.//og; # remove dots
- $f[3] = lc $f[3]; # to lower case;
- dbg('msg', "incoming file $f[3]\n");
- last SWITCH if $f[3] =~ /^\/(perl|cmd|local_cmd|src|lib|include|sys|msg)\//; # prevent access to executables
-
- # create any directories
- my @part = split /\//, $f[3];
- my $part;
- my $fn = "$main::root";
- pop @part; # remove last part
- foreach $part (@part) {
- $fn .= "/$part";
- next if -e $fn;
- last SWITCH if !mkdir $fn, 0777;
- dbg('msg', "created directory $fn\n");
- }
- my $stream = next_transno($f[2]);
- my $ref = DXMsg->alloc($stream, "$main::root/$f[3]", $self->call, time, !$f[4], $f[3], ' ', '0');
-
- # forwarding variables
- $ref->{fromnode} = $f[1];
- $ref->{tonode} = $f[2];
- $ref->{linesreq} = $f[5];
- $ref->{stream} = $stream;
- $ref->{count} = 0; # no of lines between PC31s
- $ref->{file} = 1;
- $work{"$f[1]$f[2]$stream"} = $ref; # store in work
- $self->send(DXProt::pc30($f[2], $f[1], $stream)); # send ack
-
- last SWITCH;
+ if ($pcno == 29) { # incoming text
+ my $ref = $work{"$f[2]$f[3]"};
+ if ($ref) {
+ push @{$ref->{lines}}, $f[4];
+ $ref->{count}++;
+ if ($ref->{count} >= $ref->{linesreq}) {
+ $self->send(DXProt::pc31($f[2], $f[1], $f[3]));
+ dbg('msg', "stream $f[3]: $ref->{linereq} lines received\n");
+ $ref->{count} = 0;
+ }
+ }
+ last SWITCH;
+ }
+
+ if ($pcno == 30) { # this is a incoming subject ack
+ my $ref = $work{$f[2]}; # note no stream at this stage
+ delete $work{$f[2]};
+ $ref->{stream} = $f[3];
+ $ref->{count} = 0;
+ $ref->{linesreq} = 5;
+ $work{"$f[2]$f[3]"} = $ref; # new ref
+ dbg('msg', "incoming subject ack stream $f[3]\n");
+ $busy{$f[2]} = $ref; # interlock
+ $ref->{lines} = [];
+ push @{$ref->{lines}}, ($ref->read_msg_body);
+ $ref->send_tranche($self);
+ last SWITCH;
+ }
+
+ if ($pcno == 31) { # acknowledge a tranche of lines
+ my $ref = $work{"$f[2]$f[3]"};
+ if ($ref) {
+ dbg('msg', "tranche ack stream $f[3]\n");
+ $ref->send_tranche($self);
+ } else {
+ $self->send(DXProt::pc42($f[2], $f[1], $f[3])); # unknown stream
+ }
+ last SWITCH;
+ }
+
+ if ($pcno == 32) { # incoming EOM
+ dbg('msg', "stream $f[3]: EOM received\n");
+ my $ref = $work{"$f[2]$f[3]"};
+ if ($ref) {
+ $self->send(DXProt::pc33($f[2], $f[1], $f[3])); # acknowledge it
+
+ # get the next msg no - note that this has NOTHING to do with the stream number in PC protocol
+ # store the file or message
+ # remove extraneous rubbish from the hash
+ # remove it from the work in progress vector
+ # stuff it on the msg queue
+ if ($ref->{lines} && @{$ref->{lines}} > 0) { # ignore messages with 0 lines
+ $ref->{msgno} = next_transno("Msgno") if !$ref->{file};
+ push @{$ref->{gotit}}, $f[2]; # mark this up as being received
+ $ref->store($ref->{lines});
+ add_dir($ref);
+ my $dxchan = DXChannel->get($ref->{to});
+ $dxchan->send("New mail has arrived for you") if $dxchan;
+ Log('msg', "Message $ref->{msgno} from $ref->{from} received from $f[2] for $ref->{to}");
+ }
+ $ref->stop_msg($self);
+ queue_msg();
+ } else {
+ $self->send(DXProt::pc42($f[2], $f[1], $f[3])); # unknown stream
+ }
+ queue_msg();
+ last SWITCH;
+ }
+
+ if ($pcno == 33) { # acknowledge the end of message
+ my $ref = $work{"$f[2]$f[3]"};
+ if ($ref) {
+ if ($ref->{private}) { # remove it if it private and gone off site#
+ Log('msg', "Message $ref->{msgno} from $ref->{from} sent to $f[2] and deleted");
+ $ref->del_msg;
+ } else {
+ Log('msg', "Message $ref->{msgno} from $ref->{from} sent to $f[2]");
+ push @{$ref->{gotit}}, $f[2]; # mark this up as being received
+ $ref->store($ref->{lines}); # re- store the file
+ }
+ $ref->stop_msg($self);
+ } else {
+ $self->send(DXProt::pc42($f[2], $f[1], $f[3])); # unknown stream
+ }
+ queue_msg();
+ last SWITCH;
+ }
+
+ if ($pcno == 40) { # this is a file request
+ $f[3] =~ s/\\/\//og; # change the slashes
+ $f[3] =~ s/\.//og; # remove dots
+ $f[3] = lc $f[3]; # to lower case;
+ dbg('msg', "incoming file $f[3]\n");
+ last SWITCH if $f[3] =~ /^\/(perl|cmd|local_cmd|src|lib|include|sys|msg)\//; # prevent access to executables
+
+ # create any directories
+ my @part = split /\//, $f[3];
+ my $part;
+ my $fn = "$main::root";
+ pop @part; # remove last part
+ foreach $part (@part) {
+ $fn .= "/$part";
+ next if -e $fn;
+ last SWITCH if !mkdir $fn, 0777;
+ dbg('msg', "created directory $fn\n");
+ }
+ my $stream = next_transno($f[2]);
+ my $ref = DXMsg->alloc($stream, "$main::root/$f[3]", $self->call, time, !$f[4], $f[3], ' ', '0', '0');
+
+ # forwarding variables
+ $ref->{fromnode} = $f[1];
+ $ref->{tonode} = $f[2];
+ $ref->{linesreq} = $f[5];
+ $ref->{stream} = $stream;
+ $ref->{count} = 0; # no of lines between PC31s
+ $ref->{file} = 1;
+ $work{"$f[2]$stream"} = $ref; # store in work
+ $self->send(DXProt::pc30($f[2], $f[1], $stream)); # send ack
+
+ last SWITCH;
+ }
+
+ if ($pcno == 42) { # abort transfer
+ dbg('msg', "stream $f[3]: abort received\n");
+ my $ref = $work{"$f[2]$f[3]"};
+ if ($ref) {
+ $ref->stop_msg($self);
+ $ref = undef;
+ }
+
+ last SWITCH;
+ }