diff --git a/app/Classes/FTN/Message.php b/app/Classes/FTN/Message.php index 8b3c0cd..c1f2866 100644 --- a/app/Classes/FTN/Message.php +++ b/app/Classes/FTN/Message.php @@ -211,87 +211,6 @@ class Message extends FTNBase $this->unknown = collect(); } - /** - * Parse a message from a packet - * - * @param string $msg - * @param Zone|null $zone - * @return Message - * @throws \Exception - */ - public static function parseMessage(string $msg,Zone $zone=NULL): self - { - Log::info(sprintf('%s:Processing message [%d] bytes from zone [%d]',self::LOGKEY,strlen($msg),$zone?->zone_id)); - - $o = new self($zone); - - try { - $o->header = unpack(self::unpackheader(self::header),substr($msg,0,self::HEADER_LEN)); - - } catch (\Exception $e) { - Log::error(sprintf('%s:! Error bad packet header',self::LOGKEY)); - $validator = Validator::make([ - 'header' => substr($msg,0,self::HEADER_LEN), - ],[ - 'header' => [function ($attribute,$value,$fail) use ($e) { return $fail($e->getMessage()); }] - ]); - - if ($validator->fails()) - $o->errors = $validator; - - return $o; - } - - $ptr = 0; - // To User - $o->user_to = strstr(substr($msg,self::HEADER_LEN+$ptr),"\x00",TRUE); - $ptr += strlen($o->user_to)+1; - - // From User - $o->user_from = strstr(substr($msg,self::HEADER_LEN+$ptr),"\x00",TRUE); - $ptr += strlen($o->user_from)+1; - - // Subject - $o->subject = strstr(substr($msg,self::HEADER_LEN+$ptr),"\x00",TRUE); - $ptr += strlen($o->subject)+1; - - // Check if this is an Echomail - if (! strncmp(substr($msg,self::HEADER_LEN+$ptr),'AREA:',5)) { - $o->echoarea = substr($msg,self::HEADER_LEN+$ptr+5,strpos($msg,"\r",self::HEADER_LEN+$ptr+5)-(self::HEADER_LEN+$ptr+5)); - $ptr += strlen($o->echoarea)+5+1; - } - - $o->unpackMessage(substr($msg,self::HEADER_LEN+$ptr)); - - if (($x=$o->validate())->fails()) { - Log::debug(sprintf('%s:Message fails validation (%s@%s->%s@%s)',self::LOGKEY,$o->user_from,$o->fftn,$o->user_to,$o->tftn),['result'=>$x->errors()]); - //throw new \Exception('Message validation fails:'.join(' ',$x->errors()->all())); - } - - return $o; - } - - /** - * Translate the string into something printable via the web - * - * @param string $string - * @param array $skip - * @return string - */ - public static function tr(string $string,array $skip=[0x0a,0x0d]): string - { - $tr = []; - - foreach (self::CP437 as $k=>$v) { - if (in_array($k,$skip)) - continue; - - $tr[chr($k)] = '&#'.$v; - } - - return strtr($string,$tr); - } - public function __get($key) { switch ($key) { @@ -403,6 +322,16 @@ class Message extends FTNBase } } + /** + * When we serialise this object, we'll need to utf8_encode some values + * + * @return array + */ + public function __serialize(): array + { + return $this->encode(); + } + public function __set($key,$value) { switch ($key) { @@ -438,26 +367,6 @@ class Message extends FTNBase } } - /** - * When we serialise this object, we'll need to utf8_encode some values - * - * @return array - */ - public function __serialize(): array - { - return $this->encode(); - } - - /** - * When we unserialize, we'll restore (utf8_decode) some values - * - * @param array $values - */ - public function __unserialize(array $values): void - { - $this->decode($values); - } - /** * Export an FTN message, ready for sending. * @@ -530,6 +439,97 @@ class Message extends FTNBase return $return; } + /** + * When we unserialize, we'll restore (utf8_decode) some values + * + * @param array $values + */ + public function __unserialize(array $values): void + { + $this->decode($values); + } + + /** + * Parse a message from a packet + * + * @param string $msg + * @param Zone|null $zone + * @return Message + * @throws \Exception + */ + public static function parseMessage(string $msg,Zone $zone=NULL): self + { + Log::info(sprintf('%s:Processing message [%d] bytes from zone [%d]',self::LOGKEY,strlen($msg),$zone?->zone_id)); + + $o = new self($zone); + + try { + $o->header = unpack(self::unpackheader(self::header),substr($msg,0,self::HEADER_LEN)); + + } catch (\Exception $e) { + Log::error(sprintf('%s:! Error bad packet header',self::LOGKEY)); + $validator = Validator::make([ + 'header' => substr($msg,0,self::HEADER_LEN), + ],[ + 'header' => [function ($attribute,$value,$fail) use ($e) { return $fail($e->getMessage()); }] + ]); + + if ($validator->fails()) + $o->errors = $validator; + + return $o; + } + + $ptr = 0; + // To User + $o->user_to = strstr(substr($msg,self::HEADER_LEN+$ptr),"\x00",TRUE); + $ptr += strlen($o->user_to)+1; + + // From User + $o->user_from = strstr(substr($msg,self::HEADER_LEN+$ptr),"\x00",TRUE); + $ptr += strlen($o->user_from)+1; + + // Subject + $o->subject = strstr(substr($msg,self::HEADER_LEN+$ptr),"\x00",TRUE); + $ptr += strlen($o->subject)+1; + + // Check if this is an Echomail + if (! strncmp(substr($msg,self::HEADER_LEN+$ptr),'AREA:',5)) { + $o->echoarea = substr($msg,self::HEADER_LEN+$ptr+5,strpos($msg,"\r",self::HEADER_LEN+$ptr+5)-(self::HEADER_LEN+$ptr+5)); + $ptr += strlen($o->echoarea)+5+1; + } + + $o->unpackMessage(substr($msg,self::HEADER_LEN+$ptr)); + + if (($x=$o->validate())->fails()) { + Log::debug(sprintf('%s:Message fails validation (%s@%s->%s@%s)',self::LOGKEY,$o->user_from,$o->fftn,$o->user_to,$o->tftn),['result'=>$x->errors()]); + //throw new \Exception('Message validation fails:'.join(' ',$x->errors()->all())); + } + + return $o; + } + + /** + * Translate the string into something printable via the web + * + * @param string $string + * @param array $skip + * @return string + */ + public static function tr(string $string,array $skip=[0x0a,0x0d]): string + { + $tr = []; + + foreach (self::CP437 as $k=>$v) { + if (in_array($k,$skip)) + continue; + + $tr[chr($k)] = '&#'.$v; + } + + return strtr($string,$tr); + } + /** * If this message doesnt have an AREATAG, then its a netmail. * diff --git a/app/Classes/Protocol/Binkp.php b/app/Classes/Protocol/Binkp.php index 1bdf811..f48cebd 100644 --- a/app/Classes/Protocol/Binkp.php +++ b/app/Classes/Protocol/Binkp.php @@ -1300,7 +1300,7 @@ final class Binkp extends BaseProtocol if (strlen($buf) == 0) break; - Log::warning(sprintf('%s: - Purged (%s) [%d] bytes from input stream',self::LOGKEY,serialize($buf),strlen($buf))); + Log::warning(sprintf('%s: - Purged (%s) [%d] bytes from input stream',self::LOGKEY,hex_dump($buf),strlen($buf))); } while (! $this->error && ($this->mqueue->count() || $this->tx_left) && $this->binkp_send()); diff --git a/app/helpers.php b/app/helpers.php index 4c99787..f1e7e57 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -4,11 +4,10 @@ * Calculate CCITT-CRC16 checksum */ if (! function_exists('crc16')) { - function crc16($data) + function crc16($data): int { $crc = 0x0000; - for ($i = 0; $i < strlen($data); $i++) - { + for ($i = 0; $i < strlen($data); $i++) { $x = (($crc >> 8) ^ ord($data[$i])) & 0xFF; $x ^= $x >> 4; $crc = (($crc << 8) ^ ($x << 12) ^ ($x << 5) ^ $x) & 0xFFFF; @@ -21,15 +20,14 @@ if (! function_exists('crc16')) { * Dump out data into a hex dump */ if (! function_exists('hex_dump')) { - function hex_dump($data,$newline="\n",$width=16) + function hex_dump($data,$newline="\n",$width=16): string { $result = ''; $pad = '.'; # padding for non-visible characters $to = $from = ''; - for ($i=0; $i<=0xFF; $i++) - { + for ($i=0; $i<=0xFF; $i++) { $from .= chr($i); $to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad; } @@ -38,8 +36,7 @@ if (! function_exists('hex_dump')) { $chars = str_split(strtr($data,$from,$to),$width); $offset = 0; - foreach ($hex as $i => $line) - { + foreach ($hex as $i => $line) { $result .= sprintf('%08X: %-48s [%s]%s', $offset, substr_replace(implode(' ',str_split($line,2)),' ',8*3,0), @@ -57,7 +54,7 @@ if (! function_exists('hex_dump')) { * Send a value has hex chars */ if (! function_exists('hexstr')) { - function hexstr(int $int) + function hexstr(int $int): string { if ($int > 0xffff) throw new Exception('Int too large for hexstr'); @@ -176,6 +173,7 @@ if (! function_exists('optimize_path')) { if ($host !== $cur) { $cur = $host; $result->push($address); + } else { $result->push($node); }