filename = $file; if ($file) return $this->OpenFile($file); } /** * Open a packet file * * @param string $file * @throws InvalidFidoPacketException */ private function OpenFile(string $file) { $f = fopen($file,'r'); // $fstat = fstat($f); // PKT Header $header = fread($f,0x3a); // Could not read header if (strlen($header) != 0x3a) throw new InvalidFidoPacketException('Length of Header too short: '.$file); // Not a type 2 packet if (array_get(unpack('vv',substr($header,0x12)),'v') != 2) throw new InvalidFidoPacketException('Not a type 2 packet:'. $file); $this->setHeader($header); $this->messages = collect(); while (! feof($f)) { $x = fread($f,2); // End of Packet? if (strlen($x) == 2 and $x == "\00\00") { break; } // Messages start with 02H 00H if (strlen($x) == 2 AND $x != "\02\00") throw new InvalidFidoPacketException('Not a valid packet: '.$x); // No message attached else if (! strlen($x)) break; $message = new FTNMessage(fread($f,0xc)); $message->date = $this->readnullfield($f); $message->to = $this->readnullfield($f); $message->from = $this->readnullfield($f); $message->subject = $this->readnullfield($f); $message->message = $this->readnullfield($f); $this->messages->push($message); } } private function readnullfield($f) { $result = ''; while (($x = fgetc($f) OR strlen($x)) AND $x !== "\00") { $result .= $x; } return $result; } public function setHeader(string $header) { $pack1 = [ 'onode'=>[0x00,'v',2], 'dnode'=>[0x02,'v',2], 'y'=>[0x04,'v',2], 'm'=>[0x06,'v',2], 'd'=>[0x08,'v',2], 'H'=>[0x0a,'v',2], 'M'=>[0x0c,'v',2], 'S'=>[0x0e,'v',2], 'baud'=>[0x10,'v',2], 'pktver'=>[0x12,'v',2], 'onet'=>[0x14,'v',2], 'dnet'=>[0x16,'v',2], 'prodcode-lo'=>[0x18,'C',1], 'prodrev-maj'=>[0x19,'C',1], ]; $pack2 = [ 'qozone'=>[0x22,'v',2], 'qdzone'=>[0x24,'v',2], 'filler'=>[0x26,'v',2], 'capvalid'=>[0x28,'v',2], 'prodcode-hi'=>[0x2a,'C',1], 'prodrev-min'=>[0x2b,'C',1], 'capword'=>[0x2c,'v',1], 'ozone'=>[0x2e,'v',2], 'dzone'=>[0x30,'v',2], 'opoint'=>[0x32,'v',2], 'dpoint'=>[0x34,'v',2], ]; $result1 = unpack($this->unpackheader($pack1),substr($header,0,0x1a)); $result2 = unpack($this->unpackheader($pack2),substr($header,0x22,0x14)); $this->pktsrc = sprintf('%s:%s/%s.%s', array_get($result2,'ozone'), array_get($result1,'onet'), array_get($result1,'onode'), array_get($result2,'dpoint') ); $this->pktdst = sprintf('%s:%s/%s.%s', array_get($result2,'dzone'), array_get($result1,'dnet'), array_get($result1,'dnode'), array_get($result2,'dpoint') ); $this->date = sprintf ('%d-%d-%d %d:%d:%d', array_get($result1,'y'), array_get($result1,'m'), array_get($result1,'d'), array_get($result1,'H'), array_get($result1,'M'), array_get($result1,'S') ); $this->baud = array_get($result1,'baud'); $this->pktver = array_get($result1,'pktver'); $this->password = array_get(unpack('A*p',substr($header,0x1a,8)),'p'); $this->proddata = array_get(unpack('A*p',substr($header,0x36,4)),'p'); } }