Transfering netmail via EMSI

This commit is contained in:
Deon George
2021-07-17 15:48:07 +10:00
parent 6ce4e64cb6
commit 1fa566b26c
15 changed files with 226 additions and 83 deletions

38
app/Classes/File/Mail.php Normal file
View File

@@ -0,0 +1,38 @@
<?php
namespace App\Classes\File;
use Carbon\Carbon;
use App\Classes\FTN\Packet;
class Mail extends Item
{
private Packet $file;
/**
* @throws \Exception
*/
public function __construct(Packet $mail,int $action)
{
$this->action |= $action;
switch ($action) {
case self::I_SEND:
$this->file = $mail;
$this->file_name = sprintf('%08X.PKT',Carbon::now()->timestamp);
$this->file_size = strlen($mail);
$this->file_mtime = Carbon::now()->timestamp; // @todo This timestamp should be consistent incase of retries
break;
default:
throw new \Exception('Unknown action: '.$action);
}
}
public function read(int $start,int $length): string
{
return substr((string)$this->file,$start,$length);
}
}

View File

@@ -8,6 +8,8 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use League\Flysystem\UnreadableFileException;
use App\Models\Address;
/**
* Object representing the files we are sending
*
@@ -24,6 +26,7 @@ final class Send extends Item
{
private Collection $list;
private ?Item $sending;
private Collection $packets;
private mixed $f; // File descriptor
private int $start; // Time we started sending
@@ -33,6 +36,7 @@ final class Send extends Item
{
// Initialise our variables
$this->list = collect();
$this->packets = collect();
$this->sending = NULL;
$this->file_pos = 0;
$this->f = NULL;
@@ -60,12 +64,14 @@ final class Send extends Item
case 'mail_count':
return $this->list
->filter(function($item) { return $item->isType(self::IS_ARC|self::IS_PKT); })
->count();
->count()
+ $this->packets->count();
case 'mail_size':
return $this->list
->filter(function($item) { return $item->isType(self::IS_ARC|self::IS_PKT); })
->sum(function($item) { return $item->file_size; });
->sum(function($item) { return $item->file_size; })
+ $this->packets->sum(function($item) { return $item->file_size; });
case 'sendas':
return $this->sending ? $this->sending->{$key} : NULL;
@@ -78,21 +84,31 @@ final class Send extends Item
case 'total_sent':
return $this->list
->filter(function($item) { return ($item->action & self::I_SEND) && $item->sent === TRUE; })
->count();
->count()
+ $this->packets
->filter(function($item) { return ($item->action & self::I_SEND) && $item->sent === TRUE; })
->count();
case 'total_sent_bytes':
return $this->list
->filter(function($item) { return ($item->action & self::I_SEND) && $item->sent === TRUE; })
->sum(function($item) { return $item->file_size; });
->sum(function($item) { return $item->file_size; })
+ $this->packets
->filter(function($item) { return ($item->action & self::I_SEND) && $item->sent === TRUE; })
->sum(function($item) { return $item->file_size; });
case 'total_count':
return $this->list
->filter(function($item) { return ($item->action & self::I_SEND) && $item->sent === FALSE; })
->count();
->count()
+ $this->packets
->filter(function($item) { return ($item->action & self::I_SEND) && $item->sent === FALSE; })
->count();
case 'total_size':
return $this->list
->sum(function($item) { return $item->file_size; });
->sum(function($item) { return $item->file_size; })
+ $this->packets->sum(function($item) { return $item->file_size; });
default:
throw new Exception('Unknown key: '.$key);
@@ -143,7 +159,9 @@ final class Send extends Item
Log::debug(sprintf('%s: - Closing [%s], sent in [%d]',__METHOD__,$this->sending->file_name,$end));
}
fclose($this->f);
if (! $this->sending instanceof Mail)
fclose($this->f);
$this->sending = NULL;
$this->file_pos = 0;
$this->f = NULL;
@@ -156,7 +174,7 @@ final class Send extends Item
*/
public function feof(): bool
{
return feof($this->f);
return ($this->sending instanceof Mail) ? ($this->file_pos == $this->size) : feof($this->f);
}
/**
@@ -169,6 +187,18 @@ final class Send extends Item
{
Log::debug(sprintf('%s: + Start',__METHOD__));
// If we have mail, we'll send that first
if ($this->sending = $this->packets
->filter(function($item) { return ($item->action & self::I_SEND) && $item->sent === FALSE; })
->first())
{
$this->file_pos = 0;
$this->start = time();
$this->f = TRUE;
return TRUE;
}
$this->sending = $this->list
->filter(function($item) { return ($item->action & self::I_SEND) && $item->sent === FALSE; })
->first();
@@ -189,6 +219,19 @@ final class Send extends Item
return TRUE;
}
/**
* Add our mail to the send queue
*
* @param Address $ao
* @throws Exception
*/
public function mail(Address $ao): void
{
// Netmail
if ($x=$ao->getNetmail())
$this->packets->push(new Mail($x,self::I_SEND));
}
/**
* Read bytes of the sending file
*
@@ -202,7 +245,13 @@ final class Send extends Item
if (! $this->f)
throw new Exception('No file open for read');
$data = fread($this->f,$length);
// We are sending mail
if ($this->sending instanceof Mail) {
$data = $this->sending->read($this->file_pos,$length);
} else {
$data = fread($this->f,$length);
}
$this->file_pos += strlen($data);
Log::debug(sprintf('%s: - Read [%d] bytes, file pos now [%d]',__METHOD__,strlen($data),$this->file_pos));
@@ -224,7 +273,13 @@ final class Send extends Item
if (! $this->f)
throw new Exception('No file open for seek');
$rc = (fseek($this->f,$pos,SEEK_SET) === 0);
if ($this->sending instanceof Mail) {
$rc = ($pos < $this->size) ? $pos : $this->size;
} else {
$rc = (fseek($this->f,$pos,SEEK_SET) === 0);
}
if ($rc)
$this->file_pos = $pos;