PHP Classes

File: scripts/freq_pickup.php

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   scripts/freq_pickup.php   Download  
File: scripts/freq_pickup.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: 6 days ago
Size: 6,476 bytes
 

Contents

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

/**
 * freq_pickup.php - Connect to a remote node to pick up queued FREQ files
 *
 * Use this when you have sent a FREQ request to a node that cannot reach you
 * via crashmail. The remote system will queue the files for you; run this
 * script to connect outbound and collect them.
 *
 * Usage:
 * php scripts/freq_pickup.php <ftn-address> [options]
 *
 * Examples:
 * php scripts/freq_pickup.php 1:123/456
 * php scripts/freq_pickup.php 1:123/456 --hostname=bbs.example.com
 * php scripts/freq_pickup.php 1:123/456 --hostname=bbs.example.com --port=24554
 * php scripts/freq_pickup.php 1:123/456 --password=secret
 */

chdir(__DIR__ . '/../');

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

use
BinktermPHP\Binkp\Protocol\BinkpClient;
use
BinktermPHP\Binkp\Config\BinkpConfig;
use
BinktermPHP\Binkp\Logger;
use
BinktermPHP\Nodelist\NodelistManager;

// ---------------------------------------------------------------------------
// Argument parsing
// ---------------------------------------------------------------------------

function parseArgs(array $argv): array
{
   
$opts = [];
   
$positional = [];

    for (
$i = 1; $i < count($argv); $i++) {
       
$arg = $argv[$i];
        if (
strpos($arg, '--') === 0) {
            if (
strpos($arg, '=') !== false) {
                [
$key, $value] = explode('=', substr($arg, 2), 2);
               
$opts[$key] = $value;
            } else {
               
$opts[substr($arg, 2)] = true;
            }
        } else {
           
$positional[] = $arg;
        }
    }

    return [
$opts, $positional];
}

function
showUsage(): void
{
    echo
"Usage: php scripts/freq_pickup.php <ftn-address> [options]\n";
    echo
"\n";
    echo
"Options:\n";
    echo
" --hostname=HOST Hostname or IP to connect to (auto-resolved from nodelist if omitted)\n";
    echo
" --port=PORT Port number (default: 24554)\n";
    echo
" --password=PASS Session password (default: none)\n";
    echo
" --log-level=LVL DEBUG, INFO, WARNING, ERROR (default: INFO)\n";
    echo
" --help Show this help\n";
    echo
"\n";
    echo
"Examples:\n";
    echo
" php scripts/freq_pickup.php 1:123/456\n";
    echo
" php scripts/freq_pickup.php 1:123/456 --hostname=bbs.example.com\n";
    echo
" php scripts/freq_pickup.php 1:123/456 --hostname=bbs.example.com --port=24554 --password=secret\n";
}

// ---------------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------------

[$opts, $positional] = parseArgs($argv);

if (isset(
$opts['help']) || empty($positional)) {
   
showUsage();
    exit(empty(
$positional) ? 1 : 0);
}

$address = $positional[0];
$hostname = $opts['hostname'] ?? null;
$port = isset($opts['port']) ? (int)$opts['port'] : 24554;
$password = $opts['password'] ?? '';
$logLevel = $opts['log-level'] ?? 'INFO';

// Validate FTN address format
if (!preg_match('/^\d+:\d+\/\d+(\.\d+)?$/', $address)) {
    echo
"Error: '{$address}' is not a valid FTN address (expected zone:net/node or zone:net/node.point)\n";
    exit(
1);
}

try {
   
$config = BinkpConfig::getInstance();
   
$logger = new Logger(\BinktermPHP\Config::getLogPath('binkp_poll.log'), $logLevel, true);
   
$db = \BinktermPHP\Database::getInstance()->getPdo();

   
// ------------------------------------------------------------------
    // Resolve hostname from nodelist if not supplied
    // ------------------------------------------------------------------
   
if (!$hostname) {
        echo
"Looking up {$address} in nodelist...\n";
       
$nodelistManager = new NodelistManager();
       
$routeInfo = (new \BinktermPHP\Crashmail\CrashmailService())->resolveDestination($address);
        if (!empty(
$routeInfo['hostname'])) {
           
$hostname = $routeInfo['hostname'];
           
$port = $routeInfo['port'] ?? $port;
           
$sysName = $routeInfo['system_name'] ?? '';
            echo
"Resolved: {$hostname}:{$port}" . ($sysName ? " ({$sysName})" : '') . "\n";
        } else {
            echo
"Error: Cannot resolve hostname for {$address}.\n";
            echo
"The node may not have an IBN/INA flag in the nodelist.\n";
            echo
"Use --hostname=<host> to specify the address manually.\n";
            exit(
1);
        }
    }

   
// ------------------------------------------------------------------
    // Show what's waiting for us on the remote (from our local outbound)
    // This is informational ? freq_outbound is on the REMOTE system.
    // We just show any packets we have queued outbound for that address.
    // ------------------------------------------------------------------
   
$outboundPath = $config->getOutboundPath();
   
$outboundPkts = glob($outboundPath . '/*.pkt') ?: [];

    echo
"\nConnecting to {$address} at {$hostname}:{$port}...\n";
    if (!empty(
$outboundPkts)) {
        echo
"Note: " . count($outboundPkts) . " outbound packet(s) will also be sent during this session.\n";
    }
    echo
"\n";

   
// ------------------------------------------------------------------
    // Connect ? BinkpSession::sendFreqFiles() runs at session start and
    // will collect any files the remote has queued for our address.
    // ------------------------------------------------------------------
   
$client = new BinkpClient($config, $logger);
   
$result = $client->connect($address, $hostname, $port, $password);

    echo
"\n";
    if (
$result['success']) {
       
$received = $result['files_received'] ?? [];
       
$sent = $result['files_sent'] ?? [];

        if (!empty(
$received)) {
            echo
"Files received (" . count($received) . "):\n";
            foreach (
$received as $f) {
                echo
" {$f}\n";
            }
        } else {
            echo
"No files received. The remote may not have any queued for you,\n";
            echo
"or your FREQ has not been processed yet.\n";
        }

        if (!empty(
$sent)) {
            echo
"\nFiles sent (" . count($sent) . "):\n";
            foreach (
$sent as $f) {
                echo
" {$f}\n";
            }
        }

        echo
"\nSession completed successfully.\n";
        exit(
0);
    } else {
        echo
"Session failed: " . ($result['error'] ?? 'unknown error') . "\n";
        exit(
1);
    }

} catch (\
Exception $e) {
    echo
"Error: " . $e->getMessage() . "\n";
    exit(
1);
}