PHP Classes

File: scripts/regenerate_packet.php

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   scripts/regenerate_packet.php   Download  
File: scripts/regenerate_packet.php
Role: Example script
Content type: text/plain
Description: Example script
Class: Binkterm PHP
Bulletin board system based on the Web
Author: By
Last change:
Date: 5 days ago
Size: 6,674 bytes
 

Contents

Class file image Download
#!/usr/bin/env php
<?php

/**
 * regenerate_packet.php ? Regenerate an outbound echomail packet from the database.
 *
 * Useful for re-sending a message that was lost or misrouted by an upstream.
 * The regenerated packet is written to data/outbound/regenerated/ and is NOT
 * automatically polled ? review it first, then move it to data/outbound/ or
 * send it manually.
 *
 * Usage:
 * php scripts/regenerate_packet.php --id=<echomail_id>
 * php scripts/regenerate_packet.php --msgid=<MSGID>
 *
 * Options:
 * --id=N Database row ID from the echomail table
 * --msgid=STR Full or partial MSGID kludge value (e.g. "1:154/10 AB12CD34")
 * --dry-run Print message details without writing a packet
 */

chdir(__DIR__);

require_once
__DIR__ . '/../vendor/autoload.php';
require_once
__DIR__ . '/../src/functions.php';

use
BinktermPHP\BinkdProcessor;
use
BinktermPHP\Binkp\Config\BinkpConfig;
use
BinktermPHP\Database;

// ---------------------------------------------------------------------------
// Parse arguments
// ---------------------------------------------------------------------------

$opts = getopt('', ['id:', 'msgid:', 'dry-run']);

$echoId = isset($opts['id']) ? (int)$opts['id'] : null;
$msgid = isset($opts['msgid']) ? trim($opts['msgid']) : null;
$dryRun = array_key_exists('dry-run', $opts);

if (!
$echoId && !$msgid) {
   
fwrite(STDERR, "Usage:\n");
   
fwrite(STDERR, " php scripts/regenerate_packet.php --id=<echomail_id>\n");
   
fwrite(STDERR, " php scripts/regenerate_packet.php --msgid=<MSGID>\n");
   
fwrite(STDERR, " Add --dry-run to inspect without writing a packet.\n");
    exit(
1);
}

// ---------------------------------------------------------------------------
// Database lookup
// ---------------------------------------------------------------------------

$db = Database::getInstance()->getPdo();

if (
$echoId) {
   
$stmt = $db->prepare("
        SELECT em.*, ea.tag AS echoarea_tag, ea.domain AS echoarea_domain,
               ea.uplink_address, ea.is_local
        FROM echomail em
        JOIN echoareas ea ON em.echoarea_id = ea.id
        WHERE em.id = ?
    "
);
   
$stmt->execute([$echoId]);
} else {
   
// MSGID is stored as the full value after ^AMSGID: (e.g. "1:154/10 AB12CD34")
    // Allow partial match so the user can pass just the hash portion
   
$stmt = $db->prepare("
        SELECT em.*, ea.tag AS echoarea_tag, ea.domain AS echoarea_domain,
               ea.uplink_address, ea.is_local
        FROM echomail em
        JOIN echoareas ea ON em.echoarea_id = ea.id
        WHERE em.message_id LIKE ?
        ORDER BY em.id DESC
        LIMIT 5
    "
);
   
$stmt->execute(['%' . $msgid . '%']);
}

$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

if (empty(
$rows)) {
   
fwrite(STDERR, "No echomail message found.\n");
    exit(
1);
}

if (
count($rows) > 1) {
    echo
"Multiple messages matched ? please refine your query or use --id:\n\n";
    foreach (
$rows as $r) {
       
printf(" id=%-6d area=%-20s from=%-20s subject=%s\n",
           
$r['id'],
           
$r['echoarea_tag'],
           
$r['from_name'] . ' <' . $r['from_address'] . '>',
           
$r['subject']
        );
    }
    exit(
1);
}

$message = $rows[0];

// ---------------------------------------------------------------------------
// Print message details
// ---------------------------------------------------------------------------

echo "\n";
echo
"Message details:\n";
echo
" ID : " . $message['id'] . "\n";
echo
" Area : " . $message['echoarea_tag'] . "@" . $message['echoarea_domain'] . "\n";
echo
" From : " . $message['from_name'] . " <" . $message['from_address'] . ">\n";
echo
" To : " . $message['to_name'] . "\n";
echo
" Subject : " . $message['subject'] . "\n";
echo
" Date written: " . $message['date_written'] . "\n";
echo
" MSGID : " . $message['message_id'] . "\n";
echo
" Local area : " . ($message['is_local'] ? 'yes' : 'no') . "\n";
echo
"\n";

if (
$message['is_local']) {
   
fwrite(STDERR, "Error: This message is in a local-only echo area and was never sent to any uplink.\n");
    exit(
1);
}

// ---------------------------------------------------------------------------
// Resolve uplink address
// ---------------------------------------------------------------------------

$domain = $message['echoarea_domain'] ?? '';
$uplinkAddress = $message['uplink_address'] ?? null;

if (!
$uplinkAddress && $domain) {
    try {
       
$binkpConfig = BinkpConfig::getInstance();
       
$uplinkAddress = $binkpConfig->getUplinkAddressForDomain($domain);
    } catch (\
Exception $e) {
       
// fall through
   
}
}

if (!
$uplinkAddress) {
   
fwrite(STDERR, "Error: Cannot determine uplink address for area " . $message['echoarea_tag'] . "@{$domain}.\n");
   
fwrite(STDERR, "Check that the domain is configured in BinkP settings.\n");
    exit(
1);
}

echo
" Uplink : " . $uplinkAddress . "\n\n";

if (
$dryRun) {
    echo
"[dry-run] No packet written.\n";
    exit(
0);
}

// ---------------------------------------------------------------------------
// Build output path
// ---------------------------------------------------------------------------

$regeneratedDir = __DIR__ . '/../data/outbound/regenerated';
if (!
is_dir($regeneratedDir) && !mkdir($regeneratedDir, 0755, true)) {
   
fwrite(STDERR, "Error: Cannot create directory: {$regeneratedDir}\n");
    exit(
1);
}

$packetFilename = 'regen_' . $message['id'] . '_' . substr(uniqid(), -6) . '.pkt';
$outputPath = $regeneratedDir . '/' . $packetFilename;

// ---------------------------------------------------------------------------
// Assemble message array for createOutboundPacket
// ---------------------------------------------------------------------------

$message['attributes'] = 0x0000;
$message['is_echomail'] = true;
$message['to_address'] = $uplinkAddress;
// echoarea_tag and echoarea_domain are already set from the JOIN

// ---------------------------------------------------------------------------
// Write packet
// ---------------------------------------------------------------------------

try {
   
$processor = new BinkdProcessor();
   
$processor->createOutboundPacket([$message], $uplinkAddress, $outputPath);
} catch (\
Exception $e) {
   
fwrite(STDERR, "Error creating packet: " . $e->getMessage() . "\n");
    exit(
1);
}

echo
"Packet written to: data/outbound/regenerated/{$packetFilename}\n";
echo
"\n";
echo
"To send it, move it to data/outbound/ and trigger a poll:\n";
echo
" mv data/outbound/regenerated/{$packetFilename} data/outbound/\n";
echo
" php scripts/binkp_poll.php\n";
echo
"\n";