BBS ported from vbbs
This commit is contained in:
128
app/Console/Commands/BBS/Start.php
Normal file
128
app/Console/Commands/BBS/Start.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Viewdata/Videotex Server
|
||||
*
|
||||
* Inspired by Rob O'Donnell at irrelevant.com
|
||||
*/
|
||||
|
||||
namespace App\Console\Commands\BBS;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Classes\BBS\Server\{Ansitex,Videotex};
|
||||
use App\Classes\Sock\{SocketException,SocketServer};
|
||||
use App\Models\Mode;
|
||||
use App\Models\Setup;
|
||||
|
||||
class Start extends Command
|
||||
{
|
||||
private const LOGKEY = 'CBS';
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'bbs:start {--mode=VideoTex : Server Mode Profile}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Start BBS Server';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @throws SocketException
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Log::channel('bbs')->info(sprintf('%s:+ BBS Server Starting (%d)',self::LOGKEY,getmypid()));
|
||||
$o = Setup::findOrFail(config('app.id'));
|
||||
|
||||
$start = collect();
|
||||
|
||||
if (TRUE || $o->ansitex_active)
|
||||
$start->put('ansitex',[
|
||||
'address'=>$o->ansitex_bind,
|
||||
'port'=>$o->ansitex_port,
|
||||
'proto'=>SOCK_STREAM,
|
||||
'class'=>new Ansitex,
|
||||
]);
|
||||
|
||||
if (TRUE || $o->viewdata_active)
|
||||
$start->put('videotex',[
|
||||
'address'=>$o->videotex_bind,
|
||||
'port'=>$o->videotex_port,
|
||||
'proto'=>SOCK_STREAM,
|
||||
'class'=>new Videotex,
|
||||
]);
|
||||
|
||||
$children = collect();
|
||||
|
||||
Log::channel('bbs')->debug(sprintf('%s:# Servers [%d]',self::LOGKEY,$start->count()));
|
||||
|
||||
if (! $start->count()) {
|
||||
Log::channel('bbs')->alert(sprintf('%s:! No servers configured to start',self::LOGKEY));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//pcntl_signal(SIGCHLD,SIG_IGN);
|
||||
|
||||
foreach ($start as $item => $config) {
|
||||
Log::channel('bbs')->debug(sprintf('%s:- Starting [%s] (%d)',self::LOGKEY,$item,getmypid()));
|
||||
|
||||
$pid = pcntl_fork();
|
||||
|
||||
if ($pid === -1)
|
||||
die('could not fork');
|
||||
|
||||
// We are the child
|
||||
if (! $pid) {
|
||||
Log::channel('bbs')->withContext(['pid'=>getmypid()]);
|
||||
Log::channel('bbs')->info(sprintf('%s:= Started [%s]',self::LOGKEY,$item));
|
||||
|
||||
$server = new SocketServer($config['port'],$config['address'],$config['proto']);
|
||||
$server->handler = [$config['class'],'onConnect'];
|
||||
|
||||
try {
|
||||
$server->listen();
|
||||
|
||||
} catch (SocketException $e) {
|
||||
if ($e->getMessage() === 'Can\'t accept connections: "Success"')
|
||||
Log::channel('bbs')->debug(sprintf('%s:! Server Terminated [%s]',self::LOGKEY,$item));
|
||||
else
|
||||
Log::channel('bbs')->emergency(sprintf('%s:! Uncaught Message: %s',self::LOGKEY,$e->getMessage()));
|
||||
}
|
||||
|
||||
Log::channel('bbs')->info(sprintf('%s:= Finished: [%s]',self::LOGKEY,$item));
|
||||
|
||||
// Child finished we need to get out of this loop.
|
||||
exit;
|
||||
}
|
||||
|
||||
Log::channel('bbs')->debug(sprintf('%s:- Forked for [%s] (%d)',self::LOGKEY,$item,$pid));
|
||||
$children->put($pid,$item);
|
||||
}
|
||||
|
||||
// Wait for children to exit
|
||||
while ($x=$children->count()) {
|
||||
// Wait for children to finish
|
||||
$exited = pcntl_wait($status);
|
||||
|
||||
if ($exited < 0)
|
||||
abort(500,sprintf('Something strange for status: [%s] (%d)',pcntl_wifsignaled($status) ? pcntl_wtermsig($status) : 'unknown',$exited));
|
||||
|
||||
Log::channel('bbs')->info(sprintf('%s:= Exited: #%d [%s]',self::LOGKEY,$x,$children->pull($exited)));
|
||||
}
|
||||
|
||||
// Done
|
||||
Log::channel('bbs')->debug(sprintf('%s:= Finished.',self::LOGKEY));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user