TFTP Service 1.0.7 (#1877)

* TFTP Service v1.0.7

Fixed linux and windows run as service issues
Fixed linux systemd service self install issues
Modified windows service self install process

* Revert "TFTP Service v1.0.7"

This reverts commit 4418ca7a11.

* TFTP Service v1.0.7

Fixed linux and windows run as service issues
Fixed linux systemd service self install issues
Modified windows service self install process
This commit is contained in:
minotaur01 2016-08-30 10:27:21 -04:00 committed by FusionPBX
parent 66f26cf2e6
commit 8b4eeaaf1a
3 changed files with 212 additions and 68 deletions

View File

@ -1,19 +1,26 @@
[Unit] [Unit]
Description={$name} Description={$fullname}
After=syslog.target network.target {$database} After=syslog.target network.target {$database}
Requires={$database} Requires={$database}
[Service] [Service]
User=www-data
Group=www-data
WorkingDirectory={$scriptfolder}
Type=simple Type=simple
PIDFile=/run/{$shortname}.pid
WorkingDirectory={$scriptfolder}
StandardOutput=null StandardOutput=null
StandardError=syslog StandardError=syslog
ExecStart=/usr/bin/php {$scriptname} ExecStart=/usr/bin/php {$scriptpath}
ExecStop=/bin/kill $MAINPID
PrivateTmp=true PrivateTmp=true
InaccessibleDirectories=/home /root /boot /opt /mnt /media /etc /usr InaccessibleDirectories=/home /root /boot /opt /mnt /media
ReadOnlyDirectories= ReadOnlyDirectories=/etc /usr
;Permissions
User=root
Group=daemon
;Limits
LimitCORE=1
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@ -30,7 +30,8 @@ require_once 'tftpserver.class.php';
class tftpservice extends TFTPServer class tftpservice extends TFTPServer
{ {
private $_debug=true; private $_headless=true;
private $_debug=false;
private $_dbtype; private $_dbtype;
private $_dbhost; private $_dbhost;
private $_dbport; private $_dbport;
@ -42,6 +43,7 @@ class tftpservice extends TFTPServer
function __construct($server_url, $config) function __construct($server_url, $config)
{ {
parent::__construct($server_url); parent::__construct($server_url);
if (isset($config['headless'])) $this->_headless=$config['headless'];
if (isset($config['debug'])) $this->_debug=$config['debug']; if (isset($config['debug'])) $this->_debug=$config['debug'];
if (isset($config['db_type'])) $this->_dbtype=$config['db_type']; if (isset($config['db_type'])) $this->_dbtype=$config['db_type'];
if (isset($config['db_host'])) $this->_dbhost=$config['db_host']; if (isset($config['db_host'])) $this->_dbhost=$config['db_host'];
@ -57,12 +59,14 @@ class tftpservice extends TFTPServer
} }
private function log($client, $level, $message) { private function log($client, $level, $message) {
if($level!='D'||$this->_debug) if(!$this->_headless && ($level!='D' || $this->_debug)) {
echo echo
date("H:i:s") . " " . date("H:i:s") . " " .
$level . " " . $level . " " .
$client . " " . $client . " " .
$message . "\n"; $message . "\n";
}
} }
public function get($client, $filepath, $mode) public function get($client, $filepath, $mode)

View File

@ -46,44 +46,59 @@ function Service_Install()
// check if we found the executable binary // check if we found the executable binary
if (file_exists(PHP_BINARY)) if (file_exists(PHP_BINARY))
{ {
exec('sc create '.$appname.' type=own binPath="'.PHP_BINARY.' '.$_SERVER["SCRIPT_FILENAME"].'" DisplayName="'.$appdesc.'" start=auto'); win32_create_service( Array(
die($appdesc.' was successfully installed.\n'); 'service' => $appname,
'display' => $appdesc,
'params' => __FILE__ . " --Service",
'path' => PHP_BINARY
));
//exec('sc create '.$appname.' type=own binPath="'.PHP_BINARY.' '.$_SERVER["SCRIPT_FILENAME"].'" DisplayName="'.$appdesc.'" start=auto');
die($appdesc." was successfully installed.\n");
} }
else else
{ {
die($appdesc.' could not be installed because the php executable was not found.\n'); die($appdesc." could not be installed because the php executable was not found.\n");
} }
} }
else else
{ {
require_once __DIR__.'/../../resources/config.php'; // load required files
require_once __DIR__.'/../../resources/config.php'; //required for database type
// read template file // read template file
$template=file_get_contents('resources/systemd.service.template'); $template=file_get_contents(dirname(__FILE__).'/resources/systemd.service.template');
// service name // service short name
$template=str_replace('\{\$name\}',$appdesc,$template); $template=str_replace('{$shortname}',$appname,$template);
// service full name
$template=str_replace('{$fullname}',$appdesc,$template);
// service dependencies // service dependencies
switch ($dbtype) { switch ($db_type) {
case 'pgsql': case 'pgsql':
$template=str_replace('\{\$database\}','postgresql.service',$template); $template=str_replace('{$database}','postgresql.service',$template);
break; break;
case 'mysql': case 'mysql':
$template=str_replace('\{\$database\}','mariadb.service',$template); $template=str_replace('{$database}','mariadb.service',$template);
break; break;
default: default:
$template=str_replace('\{\$database\}','',$template); $template=str_replace('{$database}','',$template);
break; break;
} }
// script path
$template=str_replace('{$scriptpath}',__FILE__,$template);
// script folder // script folder
$template=str_replace('\{\$scriptfolder\}',dirname(__FILE__),$template); $template=str_replace('{$scriptfolder}',dirname(__FILE__),$template);
// script name // script filename
$template=str_replace('\{\$scriptname\}',basename(__FILE__),$template); $template=str_replace('{$scriptfilename}',basename(__FILE__),$template);
// write service file // write service file
file_put_contents('/lib/systemd/system/'.$appname.'.service'); file_put_contents('/lib/systemd/system/'.$appname.'.service', $template);
// reload systemd and enable service
exec('systemctl daemon-reload');
exec('systemctl enable '.$appname);
die($appdesc.' was successfully installed.\n'); die($appdesc." was successfully installed.\n");
} }
} }
@ -95,34 +110,28 @@ function Service_Uninstall()
// uninstall for specific os // uninstall for specific os
if (strpos(PHP_OS,"WIN") !== false) if (strpos(PHP_OS,"WIN") !== false)
{ {
exec('sc delete "'.$appname.'"'); win32_delete_service($appname);
die($appdesc.' was successfully uninstalled.\n'); //exec('sc delete "'.$appname.'"');
die($appdesc." was successfully uninstalled.\n");
} }
else else
{ {
// stop service and disable in systemd
exec('systemctl stop '.$appname);
exec('systemctl disable '.$appname);
// delete systemd service file
unlink('/lib/systemd/system/'.$appname.'.service'); unlink('/lib/systemd/system/'.$appname.'.service');
die($appdesc.' was successfully uninstalled.\n'); die($appdesc." was successfully uninstalled.\n");
} }
} }
function Run() function Service_Run()
{ {
global $appname; global $appname;
global $appdesc; global $appdesc;
global $pid; global $pid;
global $pidfile; global $pidfile;
global $tftpservice_address;
global $tftpservice_port;
global $tftpservice_fileslocation;
// required for php 4.3.0
/*
declare(ticks = 1);
function _process_term() { exit(0);}
function _process_output($buffer) { }
*/
// check for existing process // check for existing process
if (file_exists($pidfile)) { if (file_exists($pidfile)) {
$pid = file_get_contents($pidfile); $pid = file_get_contents($pidfile);
@ -132,37 +141,37 @@ function Run()
exec('tasklist -NH -FO TABLE -FI "PID eq '.$pid.'" 2>NUL', $data); exec('tasklist -NH -FO TABLE -FI "PID eq '.$pid.'" 2>NUL', $data);
foreach($data as $line) foreach($data as $line)
{ {
if (strpos($line,$pid) !== false) die($appdesc.' already running with process id '.$pid); if (strpos($line,$pid) !== false) die($appdesc." already running with process id ".$pid);
} }
Service_Windows_Run();
} }
else else
{ {
if (file_exists('/proc/'.$pid)) die($appdesc.' already running with process id'.$pid); if (file_exists('/proc/'.$pid)) die($appdesc." already running with process id".$pid);
Service_Linux_Run();
} }
} }
} }
/* }
// fork process
$pid = pcntl_fork();
if ($pid < 0)
die("fusionpbx-tftpservice process fork failed\n");
else if ($pid) // parent
die("fusionpbx-tftpservice process fork failed\n");
posix_setsid(); function Service_Linux_Run()
pcntl_signal(SIGTERM, "_process_term"); {
pcntl_signal(SIGHUP, SIG_IGN); global $appname;
// redirect normal output to null function global $appdesc;
ob_start("_process_output"); global $pid;
*/ global $pidfile;
global $tftpservice_address;
global $tftpservice_port;
global $tftpservice_fileslocation;
// write pid file // write pid file
file_put_contents($pidfile, getmypid()); file_put_contents($pidfile, getmypid());
// load required files // load required files
require_once __DIR__.'/../../resources/config.php'; require_once __DIR__.'/../../resources/config.php';
require_once 'resources/tftpservice.class.php';
require_once 'resources/dbhelper.php'; require_once 'resources/dbhelper.php';
// get service settings from database // get service settings from database
@ -189,21 +198,145 @@ function Run()
// destroy data // destroy data
unset($s); unset($s);
// load required files
require_once 'resources/tftpservice.class.php';
// start service // start service
$server = new tftpservice("udp://$tftpservice_address:$tftpservice_port", array('db_type'=>$db_type,'db_host'=>$db_host, "db_port"=>$db_port, "db_name"=>$db_name, "db_username"=>$db_username, "db_password"=>$db_password, "files_location"=>$tftpservice_fileslocation)); $server = new tftpservice("udp://$tftpservice_address:$tftpservice_port", array("headless"=>true, "db_type"=>$db_type, "db_host"=>$db_host, "db_port"=>$db_port, "db_name"=>$db_name, "db_username"=>$db_username, "db_password"=>$db_password, "files_location"=>$tftpservice_fileslocation));
echo $appdesc.' has started.';
if(!$server->loop($error, $user)) die("$error\n"); if(!$server->loop($error, $user)) die("$error\n");
echo $appdesc.' has stopped.';
} }
// Install System Service function Service_Windows_Run()
{
global $appname;
global $appdesc;
global $pid;
global $pidfile;
global $tftpservice_address;
global $tftpservice_port;
global $tftpservice_fileslocation;
// write pid file
file_put_contents($pidfile, getmypid());
// load required files
require_once __DIR__.'/../../resources/config.php';
require_once 'resources/dbhelper.php';
// get service settings from database
// connect to database
$db = database::connect($db_type,$db_host,$db_port,$db_name,$db_username,$db_password);
// get settings
$s = database::get_table($db,'v_default_settings',array('default_setting_subcategory','default_setting_value'),array('default_setting_subcategory','LIKE','tftp_service_%'));
// set local variables
foreach ($s as $i) {
switch ($i[0]) {
case 'tftp_service_address':
$tftpservice_address=$i[1];
break;
case 'tftp_service_port':
$tftpservice_port=$i[1];
break;
case 'tftp_service_fileslocation':
$tftpservice_fileslocation=$i[1];
break;
}
}
// disconnect from database
unset($db);
// destroy data
unset($s);
// load required files
require_once 'resources/tftpservice.class.php';
// start service
$server = new tftpservice("udp://$tftpservice_address:$tftpservice_port", array("headless"=>true, "db_type"=>$db_type, "db_host"=>$db_host, "db_port"=>$db_port, "db_name"=>$db_name, "db_username"=>$db_username, "db_password"=>$db_password, "files_location"=>$tftpservice_fileslocation));
// signal running to service controller
win32_start_service_ctrl_dispatcher($appname);
win32_set_service_status(WIN32_SERVICE_RUNNING);
// execute run loop
if(!$server->loop($error, $user)) die("$error\n");
// signal stopped to service controller
win32_set_service_status(WIN32_SERVICE_STOPPED);
}
function Run()
{
global $appname;
global $appdesc;
global $pid;
global $pidfile;
global $tftpservice_address;
global $tftpservice_port;
global $tftpservice_fileslocation;
// check for existing process
if (file_exists($pidfile)) {
$pid = file_get_contents($pidfile);
if (is_numeric($pid)) {
if (strpos(PHP_OS,"WIN") !== false)
{
exec('tasklist -NH -FO TABLE -FI "PID eq '.$pid.'" 2>NUL', $data);
foreach($data as $line)
{
if (strpos($line,$pid) !== false) die($appdesc." already running with process id ".$pid);
}
}
else
{
if (file_exists('/proc/'.$pid)) die($appdesc." already running with process id".$pid);
}
}
}
// write pid file
file_put_contents($pidfile, getmypid());
// load required files
require_once __DIR__.'/../../resources/config.php';
require_once 'resources/dbhelper.php';
// get service settings from database
// connect to database
$db = database::connect($db_type,$db_host,$db_port,$db_name,$db_username,$db_password);
// get settings
$s = database::get_table($db,'v_default_settings',array('default_setting_subcategory','default_setting_value'),array('default_setting_subcategory','LIKE','tftp_service_%'));
// set local variables
foreach ($s as $i) {
switch ($i[0]) {
case 'tftp_service_address':
$tftpservice_address=$i[1];
break;
case 'tftp_service_port':
$tftpservice_port=$i[1];
break;
case 'tftp_service_fileslocation':
$tftpservice_fileslocation=$i[1];
break;
}
}
// disconnect from database
unset($db);
// destroy data
unset($s);
// load required files
require_once 'resources/tftpservice.class.php';
// start service
$server = new tftpservice("udp://$tftpservice_address:$tftpservice_port", array('db_type'=>$db_type,'db_host'=>$db_host, "db_port"=>$db_port, "db_name"=>$db_name, "db_username"=>$db_username, "db_password"=>$db_password, "files_location"=>$tftpservice_fileslocation));
echo $appdesc." has started.\n";
if(!$server->loop($error, $user)) die("$error\n");
echo $appdesc." has stopped.\n";
}
if(isset($_SERVER["argv"][1])&&$_SERVER["argv"][1]=="--InstallService") if(isset($_SERVER["argv"][1])&&$_SERVER["argv"][1]=="--InstallService")
Service_Install(); Service_Install(); // Install System Service
// Uninstall System Service
elseif(isset($_SERVER["argv"][1])&&$_SERVER["argv"][1]=="--UninstallService") elseif(isset($_SERVER["argv"][1])&&$_SERVER["argv"][1]=="--UninstallService")
Service_Uninstall(); Service_Uninstall(); // Uninstall System Service
// Run Service elseif(isset($_SERVER["argv"][1])&&$_SERVER["argv"][1]=="--Service")
else Run(); Service_Run(); // Run as a Service
else
Run(); // Run
?> ?>