PHP Classes

File: scripts/binkp_poll.php

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   scripts/binkp_poll.php   Download  
File: scripts/binkp_poll.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: 7,342 bytes
 

Contents

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

chdir
(__DIR__."/../");

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

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

function
showUsage()
{
    echo
"Usage: php binkp_poll.php [options] [address]\n";
    echo
"Options:\n";
    echo
" --all Poll all configured uplinks\n";
    echo
" --test Test connection without polling\n";
    echo
" --hostname=HOST Override hostname for connection\n";
    echo
" --port=PORT Override port for connection\n";
    echo
" --password=PASS Override password for connection\n";
    echo
" --log-level=LEVEL Log level: DEBUG, INFO, WARNING, ERROR, CRITICAL\n";
    echo
" --log-file=FILE Log file path (default: " . \BinktermPHP\Config::getLogPath('binkp_poll.log') . ")\n";
    echo
" --no-console Disable console logging\n";
    echo
" --quiet Minimal output\n";
    echo
" --queued-only Only connect to uplink if queued packets are available\n";
    echo
" --help Show this help message\n";
    echo
"\n";
    echo
"Examples:\n";
    echo
" php binkp_poll.php --all\n";
    echo
" php binkp_poll.php 1:123/456\n";
    echo
" php binkp_poll.php --test --hostname=bbs.example.com 1:123/456\n";
    echo
"\n";
}

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

function
formatResult($result, $quiet = false)
{
    if (
$quiet) {
        return
$result['success'] ? 'OK' : 'FAIL';
    }
   
// Non-quiet callers should use logResult() instead.
   
return '';
}

function
logResult($result, $logger, $address = null)
{
   
$prefix = $address ? "[{$address}] " : '';
    if (
$result['success']) {
       
$logger->log('INFO', $prefix . 'SUCCESS');
        if (isset(
$result['remote_address'])) {
           
$logger->log('INFO', $prefix . " Remote: {$result['remote_address']}");
        }
        if (isset(
$result['auth_method'])) {
           
$logger->log('INFO', $prefix . " Auth: {$result['auth_method']}");
        }
        if (isset(
$result['files_sent']) && !empty($result['files_sent'])) {
           
$logger->log('INFO', $prefix . ' Files sent: ' . implode(', ', $result['files_sent']));
        }
        if (isset(
$result['files_received']) && !empty($result['files_received'])) {
           
$logger->log('INFO', $prefix . ' Files received: ' . implode(', ', $result['files_received']));
        }
        if (isset(
$result['connect_time'])) {
           
$logger->log('INFO', $prefix . ' Connection time: ' . number_format($result['connect_time'], 3) . 's');
        }
    } else {
       
$logger->log('ERROR', $prefix . 'FAILED: ' . ($result['error'] ?? 'Unknown error'));
    }
}

list(
$args, $positional) = parseArgs($argv);

if (isset(
$args['help'])) {
   
showUsage();
    exit(
0);
}

try {
   
$config = BinkpConfig::getInstance();
   
$queued_only=false;
   
$logLevel = isset($args['log-level']) ? $args['log-level'] : 'INFO';
   
$logFile = isset($args['log-file']) ? $args['log-file'] : \BinktermPHP\Config::getLogPath('binkp_poll.log');
    if(isset(
$args['queued-only'])){
       
$queued_only=true;
    }
   
$logToConsole = !isset($args['no-console']);
   
$quiet = isset($args['quiet']);
   
    if (
$quiet) {
       
$logToConsole = false;
    }
   
   
$logger = new Logger($logFile, $logLevel, $logToConsole);
   
$client = new BinkpClient($config, $logger);

   
/**
     * Route any FREQ response files received during a session.
     */
   
$routeFreqResponses = function(array $result) use ($logger): void {
        if (empty(
$result['success']) || empty($result['files_received']) || empty($result['remote_address'])) {
            return;
        }
        try {
           
$db = \BinktermPHP\Database::getInstance()->getPdo();
           
$router = new \BinktermPHP\Freq\FreqResponseRouter($db, $logger);
           
$router->routeReceivedFiles($result['remote_address'], $result['files_received']);
        } catch (\
Exception $e) {
           
$logger->log('WARNING', "FREQ response routing failed: " . $e->getMessage());
        }
    };
   
    if (isset(
$args['all'])) {
        if (!
$quiet) $logger->log('INFO', 'Polling all configured uplinks...');

       
$results = $client->pollAllUplinks($queued_only);
       
        foreach (
$results as $address => $result) {
           
$routeFreqResponses($result);
            if (
$quiet) {
                echo
"{$address}: " . formatResult($result, true) . "\n";
            } else {
               
logResult($result, $logger, $address);
            }
        }
       
       
$successCount = count(array_filter($results, function($r) { return $r['success']; }));
       
$totalCount = count($results);
       
        if (!
$quiet) {
           
$logger->log('INFO', "Summary: {$successCount}/{$totalCount} successful");
        }
       
        exit(
$successCount === $totalCount ? 0 : 1);
       
    } elseif (!empty(
$positional)) {
       
$address = $positional[0];
       
        if (isset(
$args['test'])) {
            if (!
$quiet) $logger->log('INFO', "Testing connection to {$address}...");

           
$uplink = $config->getUplinkByAddress($address);
           
$hostname = isset($args['hostname']) ? $args['hostname'] : ($uplink['hostname'] ?? null);
           
$port = isset($args['port']) ? (int) $args['port'] : ($uplink['port'] ?? 24554);
           
            if (!
$hostname) {
                echo
"Error: No hostname specified and no uplink configuration found\n";
                exit(
1);
            }
           
           
$result = $client->testConnection($hostname, $port);
           
            if (
$quiet) {
                echo
formatResult($result, true) . "\n";
            } else {
               
logResult($result, $logger, $address);
            }

            exit(
$result['success'] ? 0 : 1);

        } else {
            if (!
$quiet) $logger->log('INFO', "Polling {$address}...");
           
           
$hostname = isset($args['hostname']) ? $args['hostname'] : null;
           
$port = isset($args['port']) ? (int) $args['port'] : null;
           
$password = isset($args['password']) ? $args['password'] : null;
           
           
$result = $client->connect($address, $hostname, $port, $password);
           
$routeFreqResponses($result);

            if (
$quiet) {
                echo
formatResult($result, true) . "\n";
            } else {
               
logResult($result, $logger, $address);
            }

            exit(
$result['success'] ? 0 : 1);
        }

    } else {
        echo
"Error: No address specified and --all not used\n";
       
showUsage();
        exit(
1);
    }
   
} catch (
Exception $e) {
    if (isset(
$quiet) && $quiet) {
        echo
"ERROR\n";
    } else {
        echo
"Error: " . $e->getMessage() . "\n";
    }
    exit(
1);
}