Delete tftp will move to fusionpbx-apps repo

This commit is contained in:
markjcrane 2018-04-05 01:13:45 +00:00
parent d56fb6f820
commit 4e2bb13242
9 changed files with 0 additions and 1811 deletions

View File

@ -1,57 +0,0 @@
<?php
//application details
$apps[$x]['name'] = "TFTP Service";
$apps[$x]['uuid'] = "4b99ccfb-cb98-40e1-a5e5-aaa89e14a388";
$apps[$x]['category'] = "";;
$apps[$x]['subcategory'] = "";
$apps[$x]['version'] = "1.0";
$apps[$x]['license'] = "Mozilla Public License 1.1";
$apps[$x]['url'] = "http://www.fusionpbx.com";
$apps[$x]['description']['en-us'] = "TFTP Service";
$apps[$x]['description']['ar-eg'] = "";
$apps[$x]['description']['de-at'] = "TFTP Dienst";
$apps[$x]['description']['de-ch'] = "";
$apps[$x]['description']['de-de'] = "TFTP Dienst";
$apps[$x]['description']['es-cl'] = "";
$apps[$x]['description']['es-mx'] = "";
$apps[$x]['description']['fr-ca'] = "";
$apps[$x]['description']['fr-fr'] = "";
$apps[$x]['description']['he-il'] = "";
$apps[$x]['description']['it-it'] = "";
$apps[$x]['description']['nl-nl'] = "";
$apps[$x]['description']['pl-pl'] = "";
$apps[$x]['description']['pt-br'] = "";
$apps[$x]['description']['pt-pt'] = "";
$apps[$x]['description']['ro-ro'] = "";
$apps[$x]['description']['ru-ru'] = "TFTP Сервер";
$apps[$x]['description']['sv-se'] = "";
$apps[$x]['description']['uk-ua'] = "";
//default settings
$y=0;
$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "e13895b7-ef2f-43ed-8d2a-e739ccffccc2";
$apps[$x]['default_settings'][$y]['default_setting_category'] = "provision";
$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "tftp_service_address";
$apps[$x]['default_settings'][$y]['default_setting_name'] = "text";
$apps[$x]['default_settings'][$y]['default_setting_value'] = "0.0.0.0";
$apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true";
$apps[$x]['default_settings'][$y]['default_setting_description'] = "the address for the TFTP service to listen for connection on";
$y++;
$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "3fe87ea5-9633-4af0-bb5c-a61dbba2772c";
$apps[$x]['default_settings'][$y]['default_setting_category'] = "provision";
$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "tftp_service_port";
$apps[$x]['default_settings'][$y]['default_setting_name'] = "numeric";
$apps[$x]['default_settings'][$y]['default_setting_value'] = "69";
$apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true";
$apps[$x]['default_settings'][$y]['default_setting_description'] = "the port for the TFTP service to listen for connection on";
$y++;
$apps[$x]['default_settings'][$y]['default_setting_uuid'] = "5e21c189-ac27-42aa-acaf-57c8cdcbbcef";
$apps[$x]['default_settings'][$y]['default_setting_category'] = "provision";
$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = "tftp_service_file_path";
$apps[$x]['default_settings'][$y]['default_setting_name'] = "numeric";
$apps[$x]['default_settings'][$y]['default_setting_value'] = "/tmp";
$apps[$x]['default_settings'][$y]['default_setting_enabled'] = "true";
$apps[$x]['default_settings'][$y]['default_setting_description'] = "the location for static files e.g. firmware";
?>

View File

@ -1,33 +0,0 @@
<?php
/*
FusionPBX
Version: MPL 1.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is FusionPBX
The Initial Developer of the Original Code is
Sebastian Krupinski <sebastian@ksacorp.com>
Portions created by the Initial Developer are Copyright (C) 2016
the Initial Developer. All Rights Reserved.
Contributor(s):
Sebastian Krupinski <sebastian@ksacorp.com>
*/
//process this code online once
if ($domains_processed == 1) {
}
?>

View File

@ -1,4 +0,0 @@
<?php
#This file was last reorganized on 19th of September 2017 08:54:24 AM UTC
?>

View File

@ -1,3 +0,0 @@
<?php
?>

View File

@ -1,293 +0,0 @@
<?php
/*
FusionPBX
Version: MPL 1.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is FusionPBX
The Initial Developer of the Original Code is
Sebastian Krupinski <sebastian@ksacorp.com>
Portions created by the Initial Developer are Copyright (C) 2016
the Initial Developer. All Rights Reserved.
Contributor(s):
Sebastian Krupinski <sebastian@ksacorp.com>
*/
class database {
/**
* generate dsn statement
* @param string $type - sqlite, mysql, pgsql, etc
* @param string $host - fqdn or ip address
* @param string $port - port number
* @param string $name - name of database or filename when using sqlite
* @return object pdo
*/
private static function _dsn($type,$host=null,$port=null,$name)
{
switch ($type) {
case 'sqlite':
return "$type:$name;";
break;
default:
return "$type:host=$host;port=$port;";
break;
}
}
/**
* connect to database
* @param string $type - sqlite, mysql, pgsql, etc
* @param string $host - fqdn or ip address
* @param string $port - port number
* @param string $name - name of database or filename when using sqlite
* @param string $username - authentication username
* @param string $password - authentication password
* @param array $options - array of database options
* @return object pdo
*/
public static function connect($type,$host=null,$port=null,$name,$username=null,$password=null,$options)
{
try
{
$db = new PDO(self::_dsn($type,$host,$port,$name), $username, $password, $options);
}
catch (PDOException $exception)
{
echo "Exception: ".$exception->getMessage();
}
if ($db!==null) return $db;
else return false;
}
/**
* disconnect from database
* @param pdo $db - database object as pdo type
*/
public static function disconnect($db)
{
try
{
$db=null;
return true;
}
catch (Exception $exception)
{
echo "Exception: ".$exception->getMessage();
return false;
}
}
/**
* begin a transaction.
* @param pdo $db - database object as pdo type
*/
public static function begin_transaction($db)
{
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 0);
$db->beginTransaction();
}
/**
* end the transaction.
* @param pdo $db - database object as pdo type
*/
public static function end_transaction($db)
{
$db->commit();
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
}
/**
* revert the transaction.
* @param pdo $db - database object as pdo type
*/
public static function revert_transactions($db)
{
$db->rollBack();
$db->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
}
/**
* get last insert id
* @return int last insert id
*/
public static function get_lastid()
{
return $db->lastInsertId();
}
/**
* get only single row
* @param pdo $db - database object as pdo type
* @param string $table - table name
* @param string $filterc - filter column
* @param string $filterv - filter value
* @return array table row
*/
public static function get_row($db,$table,$filterc,$filterv)
{
$db->prepare("SELECT * FROM $table WHERE $filterc=?");
$db->execute($filterv);
$data = $db->fetch();
return $data;
}
/**
* get only single column
* @param pdo $db - database object as pdo type
* @param string $table - table name
* @param string $column - column to return value from
* @param array $filter - ["filter column",">","filter value"]
* @return array table row
*/
public static function get_col($db,$table,$column,$filter)
{
$db->prepare("SELECT $column FROM $table WHERE $filter[0] $filter[1] ?");
$db->execute($filter[2]);
$data = $cmd->fetchAll();
return $data;
}
/**
* get only single value
* @param pdo $db - database object as pdo type
* @param string $table - table name
* @param string $column - column to return value from
* @param string $filterc - filter column
* @param string $filterv - filter value
* @return mixed data in field
*/
public static function get_value($db,$table,$column,$filterc,$filterv)
{
$cmd = $db->prepare("SELECT $column FROM $table WHERE $filterc=?");
$cmd->bindValue(1, $filterv);
$cmd->execute();
$data = $cmd->fetchColumn(0);
return $data;
}
/**
* get count of rows
* @param pdo $db - database object as pdo type
* @param string $table - table name
* @param array $filter - ["filter column",">","filter value"]
* @return mixed data in field
*/
public static function get_count($db,$table,$filter)
{
$cmd = $db->prepare("SELECT COUNT(0) FROM $table WHERE $filter[0] $filter[1] ?");
$cmd->bindValue(1, $filter[2]);
$cmd->execute();
$data = $cmd->fetchColumn(0);
}
/**
* get specific columns and rows
* @param pdo $db - database object as pdo type
* @param string $table - table name
* @param array $columns - specific columns to return
* @param array $filter - ["filter column",">","filter value"]
* @return array selected tables and rows
*/
public static function get_table($db,$table,$columns,$filter)
{
if($columns === null) $columns=array("*");
$cmd = $db->prepare("SELECT ".implode(',', $columns)." FROM $table WHERE $filter[0] $filter[1] ?");
$cmd->bindValue(1, $filter[2]);
$cmd->execute();
$data = $cmd->fetchAll();
return $data;
}
/**
* get data with custom sql statment
* @param pdo $db - database object as pdo type
* @param string $sql - custom sql statment
* @return mixed - any returned data
*/
public static function execute($db,$sql)
{
if($sql === null) return null;
$cmd = $db->prepare($sql);
$cmd->execute();
$data = $cmd->fetchAll();
return $data;
}
/**
* set single row
* @param pdo $db - database object as pdo type
* @param string $table - table name
* @param array $data - associative array 'col'=>'val'
* @param string $filterc - primary key column name or any other columns name
* @param string $filterv - value to match the condition field to
* @param int $val key value
*/
public static function set_row($db,$table,$data,$filterc,$filterv) {
if($data === null)
exit;
elseif ($filterc !== null&&$filterv !== null)
{
// get values
$v = array_values($data);
// add condition value
array_push($v,$filterv);
// get keys
$c=array();
foreach (array_keys($data) as $k) {
$c[]=$k."=?";
}
// phrase command
$cmd=$db->prepare("UPDATE $table SET ".implode(', ', $c)." WHERE $filterc=?;");
$cmd->execute($v);
}
else
{
// get values
$v = array_values($data);
// get keys
$c=implode(', ', array_keys($data));
// phrase command
$cmd=$db->prepare("INSERT INTO $table ($c) values (".str_repeat("?,",count($c)-1)."?)");
$cmd->execute($v);
}
}
/**
* delete row
* @param string $table table name
* @param string $where column name for condition (commonly primay key column name)
* @param int $id key value
*/
public static function delete_row($db,$table,$filterc,$filterv) {
$cmd=$db->prepare("DELETE FROM $table WHERE $filterc=?");
$cmd->execute($filterv);
}
/**
* delete rows
* @param string $table table name
* @param string $where column name for condition (commonly primay key column name)
* @param int $id key value
*/
public static function delete_rows($db,$table,$filterc,$filterv) {
$cmd=$db->prepare("DELETE FROM $table WHERE $filterc=?");
$cmd->execute($filterv);
}
}
?>

View File

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

View File

@ -1,873 +0,0 @@
<?php
/*
* PHP TFTP Server
*
* Copyright (c) 2011 <mattias.wadman@gmail.com>
*
* MIT License:
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*
* Extend TFTPServer class and then call loop method with UDP URL.
* Possible methods to override:
* exists($peer, $filename)
* Check if file exist, default always true.
* readable($peer, $filename)
* Check if file is readable, default always true.
* get($peer, $filename, $mode)
* Return content of file, default always false.
* Only called if both exists and readable returns true.
* writable($peer, $filename)
* Check if file is writable, default always false.
* put($peer, $filename, $mode, $content)
* Write content to file.
* Only falled if both exists and writable returns true.
*
* $peer is $ip:$port, source ip and port of client
* $filename is filename specified by client
* $mode is probably "octet" or "netascii"
* $content is file content
*
* The server support multiple concurrent read and writes, but the method calls
* are serialized, so make sure to return quickly.
*
* TODO:
* select must handle EINTR, how?
* multiple recv per select?
*
*/
/* Note about the Logger class:
* The "priority" and "minimum should be one of the constants used for syslog.
* See: http://php.net/manual/en/function.syslog.php
* They are: LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE,
* LOG_INFO, LOG_DEBUG
* Note that LOG_EMERG, LOG_ALERT, and LOG_CRIT are not really relevant to a
* tftp server - these represent instability in the entire operating system.
* Note that the number they are represented by are in reverse order -
* LOG_EMERG is the lowest, LOG_DEBUG the highest.
*/
abstract class Logger
{
function __construct($minimum)
{
$this->minimum = $minimum;
}
function shouldlog($priority)
{
// Note: this looks reversed, but is correct
// the priority must be AT LEAST the minimum,
// because higher priorities represent lower numbers.
return $priority <= $this->minimum;
}
abstract function log($priority, $message);
}
class Logger_Null extends Logger
{
function log($priority, $message)
{
}
}
class Logger_Syslog extends Logger
{
function log($priority, $message)
{
if($this->shouldlog($priority))
syslog($priority,$message);
}
}
class Logger_Filehandle extends Logger
{
private $priority_map = array(
LOG_DEBUG => "D",
LOG_INFO => "I",
LOG_NOTICE => "N",
LOG_WARNING => "W",
LOG_ERR => "E",
LOG_CRIT => "C",
LOG_ALERT => "A",
LOG_EMERG => "!"
);
function __construct($minimum, $filehandle, $dateformat = "r")
{
$this->filehandle = $filehandle;
$this->dateformat = $dateformat;
return parent::__construct($minimum);
}
function log($priority, $message)
{
if($this->shouldlog($priority))
fwrite($this->filehandle, date($this->dateformat) . ": " . $this->priority_map[$priority] . " $message\n");
}
}
class Logger_Filename extends Logger_Filehandle
{
function __construct($minimum, $filename, $dateformat = "r")
{
return parent::__construct($minimum, fopen($filename, "a"), $dateformat);
}
}
class Logger_Stderr extends Logger_Filehandle
{
function __construct($minimum, $dateformat = "r")
{
return parent::__construct($minimum, STDERR, $dateformat);
}
}
class Logger_Stdout extends Logger_Filehandle
{
function __construct($minimum, $dateformat = "r")
{
return parent::__construct($minimum, STDOUT, $dateformat);
}
}
class TFTPOpcode
{
public static function name($v)
{
static $names = array(TFTPOpcode::RRQ => "RRQ",
TFTPOpcode::WRQ => "WRQ",
TFTPOpcode::DATA => "DATA",
TFTPOpcode::ACK => "ACK",
TFTPOpcode::ERROR => "ERROR",
TFTPOpcode::OACK => "OACK");
if(isset($names[$v]))
return $names[$v];
else
return "UNKNOWN";
}
const RRQ = 1; // read request
const WRQ = 2; // write request
const DATA = 3; // send data
const ACK = 4; // ack data
const ERROR = 5;
const OACK = 6; // option ack, instead of first ACK/DATA
}
class TFTPError
{
const NOT_DEFINED = 0; // see error message instead of error code
const FILE_NOT_FOUND = 1;
const ACCESS_VIOLATION = 2;
const DISK_FULL = 3;
const ILLEGAL_OPERATION = 4;
const UNKNOWN_TID = 5; // unknown transfer (id is ip:port pair)
const FILE_ALREADY_EXISTS = 6;
const NO_SUCH_USER = 7;
const OACK_FAILURE = 8;
}
class TFTPTransferState
{
const READY = 1;
const SENDING_WAIT_OACK = 2;
const SENDING = 3;
const RECEIVING = 4;
const TERMINATING = 5;
}
abstract class TFTPTransfer {
public $state;
public $peer;
public $retransmit_timeout;
public $block_size;
public $tsize;
protected $_server; // TFTPServer reference
function __construct($server, $peer, $extensions)
{
$this->state = TFTPTransferState::READY;
$this->peer = $peer;
$this->retransmit_timeout = $server->retransmit_timeout;
$this->block_size = $server->block_size;
$this->tsize = 0;
$this->_server = $server;
if(isset($extensions["timeout"])) {
$timeout = (int)$extensions["timeout"];
if($timeout > 0 && $timeout < 256)
$this->retransmit_timeout = $timeout;
}
if(isset($extensions["blksize"])) {
$blksize = (int)$extensions["blksize"];
if($blksize > 0 && $blksize <= $server->max_block_size)
$this->block_size = $blksize;
}
// tsize is only checked for in write transfers
}
protected function log_debug($message)
{
$this->_server->log_debug($this->peer, $message);
}
protected function log_info($message)
{
$this->_server->log_info($this->peer, $message);
}
protected function log_warning($message)
{
$this->_server->log_warning($this->peer, $message);
}
protected function log_error($message)
{
$this->_server->log_error($this->peer, $message);
}
protected function terminal_info($error, $message)
{
$this->log_info($message);
$this->state = TFTPTransferState::TERMINATING;
return TFTPServer::packet_error($error, $message);
}
protected function terminal_error($op, $error, $message)
{
$this->log_debug("$op: $message");
$this->state = TFTPTransferState::TERMINATING;
return TFTPServer::packet_error($error, $message);
}
protected function illegal_operation($op, $message = "Illegal operation")
{
return $this->terminal_error($op, TFTPError::ILLEGAL_OPERATION, $message);
}
public function rrq($filename, $mode)
{
return $this->illegal_operation("RRQ");
}
public function wrq($filename, $mode)
{
return $this->illegal_operation("WRQ");
}
public function data($block, $data)
{
return $this->illegal_operation("DATA");
}
public function ack($block)
{
return $this->illegal_operation("ACK");
}
public function error($error, $message)
{
$this->log_debug("ERROR: $error: $message");
$this->state = TFTPTransferState::TERMINATING;
}
protected function use_extensions() {
return
$this->retransmit_timeout != $this->_server->retransmit_timeout ||
$this->block_size != $this->_server->block_size ||
$this->tsize != 0;
}
protected function packet_oack() {
$options = array();
if($this->retransmit_timeout != $this->_server->retransmit_timeout)
$options["timeout"] = (string)$this->retransmit_timeout;
if($this->block_size != $this->_server->block_size)
$options["blksize"] = (string)$this->block_size;
if($this->tsize != 0)
$options["tsize"] = (string)$this->tsize;
return TFTPServer::packet_oack($options);
}
}
class TFTPReadTransfer extends TFTPTransfer {
private $_last_recv_ack;
private $_last_sent_data;
private $_buffer;
private $_block;
private $_last_block;
function __construct($server, $peer, $extensions)
{
parent::__construct($server, $peer, $extensions);
$this->_last_recv_ack = time();
$this->_last_sent_data = $this->_last_recv_ack;
$this->_buffer = false;
$this->_block = 1;
$this->_last_block = 1;
$this->log_debug("new read transfer");
}
private function current_block()
{
return substr($this->_buffer,
($this->_block - 1) * $this->block_size,
$this->block_size);
}
private function packet_data_current()
{
$this->_last_sent_data = time();
if($this->state == TFTPTransferState::SENDING_WAIT_OACK)
return $this->packet_oack();
else
return TFTPServer::packet_data($this->_block, $this->current_block());
}
public function rrq($filename, $mode)
{
$this->log_debug("RRQ: filename $filename in $mode mode");
if($this->state != TFTPTransferState::READY)
return $this->illegal_operation("RRQ", "Not in ready state");
if(!$this->_server->exists($this->peer, $filename))
return $this->terminal_info(TFTPError::FILE_NOT_FOUND,
"File $filename does not exist");
if(!$this->_server->readable($this->peer, $filename))
return $this->terminal_info(TFTPError::ACCESS_VIOLATION,
"File $filename is not readable");
$this->_buffer = $this->_server->get($this->peer, $filename, $mode);
if($this->_buffer === false)
return $this->terminal_info(TFTPError::FILE_NOT_FOUND,
"Failed to read $filename");
$this->log_info("Reading $filename (" .
strlen($this->_buffer) . " bytes)");
if($this->use_extensions())
$this->state = TFTPTransferState::SENDING_WAIT_OACK;
else
$this->state = TFTPTransferState::SENDING;
$this->_last_block = floor(strlen($this->_buffer) /
$this->block_size) + 1;
$this->log_debug("RRQ: send first block or OACK");
return $this->packet_data_current();
}
public function ack($block)
{
if($this->state == TFTPTransferState::SENDING_WAIT_OACK) {
if($block != 0) {
$this->log_debug("ACK: waiting OACK ACK got block $block");
return false;
}
$this->state = TFTPTransferState::SENDING;
$this->log_debug("ACK: got OACK ACK, send first block");
return $this->packet_data_current();
}
if($this->state != TFTPTransferState::SENDING)
return $this->illegal_operation("ACK", "Not in sending state");
$this->log_debug("ACK: block $block");
$this->_last_recv_ack = time();
if($block < $this->_block) {
$this->log_debug("ACK: duplicate block $block");
// just ignore it
return false;
}
if($block > $this->_last_block)
return $this->illegal_operation("ACK",
"Block $block outside " .
"range 1-{$this->_last_block}");
if($block == $this->_last_block) {
$this->log_debug("ACK: last block, done");
$this->state = TFTPTransferState::TERMINATING;
return false;
}
// move to next block
$this->_block = $block + 1;
$this->log_debug("ACK: sending block {$this->_block}");
return $this->packet_data_current();
}
public function retransmit($now)
{
if($now - $this->_last_recv_ack > $this->_server->timeout) {
$this->log_debug("retransmit: timeout");
$this->state = TFTPTransferState::TERMINATING;
return false;
}
if($now - $this->_last_sent_data > $this->retransmit_timeout) {
$this->log_debug("retransmit: resending block {$this->_block} or OACK");
return $this->packet_data_current();
}
return false;
}
}
class TFTPWriteTransfer extends TFTPTransfer {
private $_last_sent_ack;
private $_last_recv_data;
private $_buffer;
private $_buffer_size;
private $_next_block;
private $_filename;
private $_mode;
function __construct($server, $peer, $extensions)
{
parent::__construct($server, $peer, $extensions);
$this->_last_sent_ack = time();
$this->_last_recv_data = $this->_last_sent_ack;
$this->_buffer = array();
$this->_buffer_size = 0;
$this->_last_recv_block = 0;
$this->_filename = false;
$this->_mode = false;
if(isset($extensions["tsize"]))
$this->tsize = (int)$extensions["tsize"];
$this->log_debug("new write transfer");
}
private function packet_ack_current()
{
$this->_last_sent_ack = time();
if($this->_last_recv_block == 0 && $this->use_extensions())
return $this->packet_oack();
else
return TFTPServer::packet_ack($this->_last_recv_block);
}
public function wrq($filename, $mode)
{
$this->log_debug("WRQ: filename $filename in $mode mode");
if($this->state != TFTPTransferState::READY)
return $this->illegal_operation("WRQ", "Not in ready state");
if(!$this->_server->writable($this->peer, $filename))
return $this->terminal_info(TFTPError::ACCESS_VIOLATION,
"File $filename is not writable");
if($this->tsize != 0 && $this->tsize > $this->_server->max_put_size)
return $this->terminal_info(TFTPError::DISK_FULL,
"File too big, " .
$this->tsize . "(tsize) > " .
$this->_server->max_put_size);
$this->state = TFTPTransferState::RECEIVING;
$this->_filename = $filename;
$this->_mode = $mode;
$this->_last_sent_ack = time();
$this->log_debug("WRQ: ack request");
if($this->use_extensions())
return $this->packet_oack();
else
return TFTPServer::packet_ack(0);
}
public function data($block, $data)
{
if($this->state != TFTPTransferState::RECEIVING)
return $this->illegal_operation("DATA", "Not in receiving state");
$this->log_debug("DATA: block $block");
$this->last_recv_data = time();
if($block <= $this->_last_recv_block) {
$this->log_debug("DATA: duplicate block $block");
// just ignore it
return false;
}
if($block != $this->_last_recv_block + 1)
return $this->illegal_operation("DATA",
"Expected block " .
($this->_last_recv_block + 1) .
" got $block");
$this->_last_recv_block = $block;
$this->_last_recv_data = time();
array_push($this->_buffer, $data);
$this->_buffer_size += strlen($data);
if($this->_buffer_size > $this->_server->max_put_size)
return $this->terminal_info(TFTPError::DISK_FULL,
"File too big, " .
$this->_buffer_size . " > " .
$this->_server->max_put_size);
if(strlen($data) < $this->block_size) {
$this->log_debug("DATA: last, done");
$this->state = TFTPTransferState::TERMINATING;
$this->log_info("Writing {$this->_filename} " .
"({$this->_buffer_size} bytes)");
$this->_server->put($this->peer, $this->_filename, $this->_mode,
implode("", $this->_buffer));
return $this->packet_ack_current();
}
$this->log_debug("DATA: ack block $block");
return $this->packet_ack_current();
}
public function retransmit($now)
{
if($now - $this->_last_recv_data > $this->_server->timeout) {
$this->log_debug("retransmit: timeout");
$this->state = TFTPTransferState::TERMINATING;
return false;
}
if($now - $this->_last_sent_ack > $this->retransmit_timeout) {
$this->log_debug("retransmit: reack block {$this->_last_recv_block}");
return $this->packet_ack_current();
}
return false;
}
}
class TFTPServer {
public $block_size = 512;
public $max_block_size = 65464; // max block size from rfc2348
public $timeout = 10;
public $retransmit_timeout = 1;
public $max_put_size = 10485760; // 10 Mibi
private $_socket_url;
private $_socket;
private $_transfers = array();
private $_logger = NULL;
function __construct($socket_url, $logger = NULL)
{
$this->_socket_url = $socket_url;
$this->_logger = $logger;
}
public function exists($peer, $filename)
{
return true;
}
public function readable($peer, $filename)
{
return true;
}
public function get($peer, $filename, $mode)
{
return false;
}
public function writable($peer, $filename)
{
return false;
}
public function put($peer, $filename, $mode, $content)
{
}
public function logger_log($priority, $message) {
if($this->_logger === NULL)
return;
$this->_logger->log($priority, $message);
}
public function log_debug($peer, $message)
{
$this->logger_log(LOG_DEBUG, "$peer $message");
}
public function log_info($peer, $message)
{
$this->logger_log(LOG_INFO, "$peer $message");
}
public function log_warning($peer, $message)
{
$this->logger_log(LOG_WARNING, "$peer $message");
}
public function log_error($peer, $message)
{
$this->logger_log(LOG_ERR, "$peer $message");
}
public static function packet_ack($block)
{
return pack("nn", TFTPOpcode::ACK, $block);
}
public static function packet_data($block, $data)
{
return pack("nn", TFTPOpcode::DATA, $block) . $data;
}
public static function packet_error($code, $message = "")
{
return pack("nn", TFTPOpcode::ERROR, $code) . $message . "\0";
}
public static function packet_oack($options)
{
$data = "";
foreach($options as $key => $value)
$data .= "$key\0$value\0";
return pack("n", TFTPOpcode::OACK) . $data;
}
public static function escape_string($str)
{
$b = "";
$l = strlen($str);
for($i = 0; $i < $l; $i++) {
$c = $str[$i];
if(ctype_print($c))
$b .= $c;
else
$b .= sprintf("\\x%'02x", ord($c));
}
return $b;
}
public function loop(&$error = false, $user = null)
{
$this->_socket =
stream_socket_server($this->_socket_url, $errno, $errstr,
STREAM_SERVER_BIND);
if(!$this->_socket) {
if($error !== false)
$error = "$errno: $errstr";
return false;
}
if($user != null) {
posix_seteuid($user["uid"]);
posix_setegid($user["gid"]);
}
stream_set_blocking($this->_socket, false);
return $this->loop_ex();
}
private function loop_ex()
{
$now = $last = time();
while(true) {
$read = array($this->_socket);
$write = null;
$excpt = null;
$r = stream_select($read, $write, $excpt, 1);
if($r === false) {
$this->log_error("server", "select returned false");
continue;
}
if(count($read) > 0) {
$packet = stream_socket_recvfrom($this->_socket,
65535, // max udp packet size
0, // no flags
$peer);
// ipv6 hack, convert to [host]:port format
if(strpos($peer, ".") === false) {
$portpos = strrpos($peer, ":");
$host = substr($peer, 0, $portpos);
$port = substr($peer, $portpos + 1);
$peer = "[$host]:$port";
}
$this->log_debug($peer, "request: ".strlen($packet)." bytes");
$this->log_debug($peer, "request: ".TFTPServer::escape_string($packet));
$reply = $this->request($peer, $packet);
if($reply !== false) {
$this->log_debug($peer, "reply: " .
TFTPServer::escape_string($reply));
stream_socket_sendto($this->_socket, $reply, 0, $peer);
}
}
$now = time();
if($now != $last) {
$last = $now;
$this->retransmit($now);
}
}
}
private function retransmit($now)
{
foreach($this->_transfers as $peer => $transfer) {
$reply = $transfer->retransmit($now);
if($reply !== false) {
$this->log_debug($peer, "resend: " .
TFTPServer::escape_string($reply));
stream_socket_sendto($this->_socket, $reply, 0, $peer);
}
if($transfer->state == TFTPTransferState::TERMINATING)
unset($this->_transfers[$peer]);
}
}
private function request($peer, $packet)
{
if(strlen($packet) < 4) {
$this->log_debug($peer, "request: short packet");
return false;
}
$reply = false;
$transfer = false;
if(isset($this->_transfers[$peer])) {
$this->log_debug($peer, "request: existing transfer");
$transfer = $this->_transfers[$peer];
}
$fields = unpack("n", $packet);
$op = $fields[1];
$this->log_debug($peer, "request: opcode " .
TFTPOpcode::name($op) . " ($op)");
switch($op) {
case TFTPOpcode::WRQ:
case TFTPOpcode::RRQ:
$a = explode("\0", substr($packet, 2));
if(count($a) < 3 || $a[count($a) - 1] != "") {
$this->log_warning($peer, "request: malformed " .
TFTPOpcode::name($op));
return false;
}
$rawexts = array_slice($a, 2, -1);
// Cisco IP Phone 7941 (and possibly others) return an extra null
// at the end; a breach of RFC rfc2347. This is a workaround.
// If odd count strip last and continue if empty, else warn and ignore
if(count($rawexts) % 2 != 0) {
if(array_pop($rawexts)!="") {
$this->log_warning($peer, "request: malformed extension " .
"key/value pairs " . TFTPOpcode::name($op));
return false;
}
}
$extensions = array();
foreach(array_chunk($rawexts, 2) as $pair)
$extensions[strtolower($pair[0])] = $pair[1];
if($transfer === false) {
if($op == TFTPOpcode::RRQ)
$transfer = new TFTPReadTransfer($this, $peer, $extensions);
else
$transfer = new TFTPWriteTransfer($this, $peer, $extensions);
$this->_transfers[$peer] = $transfer;
}
if($op == TFTPOpcode::RRQ)
$reply = $transfer->rrq($a[0], $a[1]);
else
$reply = $transfer->wrq($a[0], $a[1]);
break;
case TFTPOpcode::ACK:
if(strlen($packet) != 4) {
$this->log_warning($peer, "request: malformed ACK");
return false;
}
$a = unpack("n", substr($packet, 2));
if($transfer === false) {
// do not warn, some clients like BSD tftp sends ack on read error
$this->log_debug($peer, "request: ack from unknwon peer");
} else
$reply = $transfer->ack($a[1]);
break;
case TFTPOpcode::DATA:
if(strlen($packet) < 4) {
$this->log_warning($peer, "request: malformed DATA");
return false;
}
$a = unpack("n", substr($packet, 2));
$data = substr($packet, 4, strlen($packet) - 4);
if($transfer === false) {
$this->log_warning($peer, "request: data from unknwon peer");
$reply = TFTPServer::packet_error(TFTPError::UNKNOWN_TID,
"Unknown TID for DATA");
} else
$reply = $transfer->data($a[1], $data);
break;
case TFTPOpcode::ERROR:
$a = unpack("n", substr($packet, 2, 2));
$message = substr($packet, 4, strlen($packet) - 5);
if($transfer === false)
$this->log_warning($peer, "request: error from unknwon peer, " .
"{$a[1]}:$message");
else
$transfer->error($a[1], $message);
break;
default:
break;
}
if($transfer !== false &&
$transfer->state == TFTPTransferState::TERMINATING) {
$this->log_debug($peer, "request: terminating");
unset($this->_transfers[$transfer->peer]);
}
return $reply;
}
}
?>

View File

@ -1,178 +0,0 @@
<?php
/*
FusionPBX
Version: MPL 1.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is FusionPBX
The Initial Developer of the Original Code is
Sebastian Krupinski <sebastian@ksacorp.com>
Portions created by the Initial Developer are Copyright (C) 2016
the Initial Developer. All Rights Reserved.
Contributor(s):
Sebastian Krupinski <sebastian@ksacorp.com>
*/
// load required files
require_once 'tftpserver.class.php';
class tftpservice extends TFTPServer
{
private $_headless=true;
private $_debug=false;
private $_dbtype;
private $_dbhost;
private $_dbport;
private $_dbname;
private $_dbusername;
private $_dbpassword;
private $_fileslocation;
function __construct($server_url, $config)
{
parent::__construct($server_url);
if (isset($config['headless'])) $this->_headless=$config['headless'];
if (isset($config['debug'])) $this->_debug=$config['debug'];
if (isset($config['db_type'])) $this->_dbtype=$config['db_type'];
if (isset($config['db_host'])) $this->_dbhost=$config['db_host'];
if (isset($config['db_port'])) $this->_dbport=$config['db_port'];
if (isset($config['db_name'])) $this->_dbname=$config['db_name'];
if (isset($config['db_username'])) $this->_dbusername=$config['db_username'];
if (isset($config['db_password'])) $this->_dbpassword=$config['db_password'];
if (isset($config['files_location'])) $this->_fileslocation=$config['files_location'];
if (!file_exists($_fileslocation)) {
$_fileslocation = (strpos(PHP_OS,"WIN") !== false) ? $_SERVER["TMP"] : "/tmp";
}
}
private function log($client, $level, $message) {
if(!$this->_headless && ($level!='D' || $this->_debug)) {
echo
date("H:i:s") . " " .
$level . " " .
$client . " " .
$message . "\n";
}
}
public function get($client, $filepath, $mode)
{
$this->log($client,"N", "Requested File ".$filepath);
try {
$regex_filter='/provision\/(?<domain>\b(?:(?-)[A-Za-z0-9-\_]{1,63}(?-)\.)+[A-Za-z]{1,63}\b|\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)\/(?<mac>\b(?:[0-9a-fA-F]{2}(?:\-|\:)?){6}\b)/';
preg_match($regex_filter,$filepath,$regex_matches);
// check if filepath is in a specific format and respond acordingly
if ($regex_matches['domain']&&$regex_matches['mac'])
{
// generate file from db
$filedata = $this->generate_file($client,$regex_matches['domain'],$regex_matches['mac']);
}
else
{
// retrieve file from disk
$filedata = $this->retrieve_file($client,$filepath);
}
if($filedata !== false)
{
$this->log($client,"N", "Transmitting File ".$filepath);
return $filedata;
}
else
{
return false;
}
}
catch (Exception $exception)
{
$this->log($client,"E", "Exception: ".$exception->getMessage());
return false;
}
}
public function generate_file($client, $domain, $mac)
{
// load required files
require_once __DIR__.'/dbhelper.php';
require_once __DIR__.'/../../../resources/functions.php';
require_once __DIR__.'/../../../resources/classes/template.php';
require_once __DIR__.'/../../provision/resources/classes/provision.php';
$this->log($client,"D", "Generating File ".$domain." ".$mac);
// connect to database
$db = database::connect($this->_dbtype,$this->_dbhost,$this->_dbport,$this->_dbname,$this->_dbusername,$this->_dbpassword);
// get domain uuid
$domain_uuid = database::get_value($db,'v_domains','domain_uuid','domain_name',$domain);
// set temporary folder for template engine
$_SESSION['server']['temp']['dir'] = (strpos(PHP_OS,"WIN") !== false) ? $_SERVER["TMP"] : "/tmp";
// update device provisioned status
$data=array('device_provisioned_date'=>date("Y-m-d H:i:s"),'device_provisioned_method'=>'tftp','device_provisioned_ip'=>$client);
database::set_row($db,'v_devices',$data,'device_mac_address',$mac);
// generate file
$prov = new provision;
$prov->db = $db;
$prov->domain_uuid = $domain_uuid;
$prov->mac = $mac;
$data = $prov->render();
// return data or false
if($data === false)
{
$this->log($client,"W", "Generating File Failed ".$domain." ".$mac);
return false;
}
else
{
return $data;
}
}
public function retrieve_file($client, $path){
$this->log($client,"D", "Retrieve File ".$path);
// check for reletive path directive
if(strstr($path, "../") != false || strstr($path, "/..") != false) return false;
// combine base and path
$path = rtrim($this->_fileslocation,'/').'/'.ltrim($path,'/');
if(substr($path, 0, strlen($this->_fileslocation)) != $this->_fileslocation) return false;
// read contents
if($this->_debug) $this->log($client,"D", "Reading File ".$path);
$data = @file_get_contents($path);
// return data or false
if($data === false)
{
$this->log($client,"W", "Retrieving File Failed ".$path);
return false;
}
else
{
return $data;
}
}
}
?>

View File

@ -1,344 +0,0 @@
#!/usr/bin/env php
<?php
/*
FusionPBX
Version: MPL 1.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is FusionPBX
The Initial Developer of the Original Code is
Sebastian Krupinski <sebastian@ksacorp.com>
Portions created by the Initial Developer are Copyright (C) 2016
the Initial Developer. All Rights Reserved.
Contributor(s):
Sebastian Krupinski <sebastian@ksacorp.com>
*/
// define variables and constants
$appname = "fusionpbx-tftp";
$appdesc = "FusionPBX TFTP Service";
$pid=null;
$pidfile = (strpos(PHP_OS,"WIN") !== false) ? $_SERVER["TMP"]."\\$appname.pid" : "/var/run/$appname.pid";
$tftpservice_address="0.0.0.0";
$tftpservice_port=69;
$tftpservice_file_path=(strpos(PHP_OS,"WIN") !== false) ? $_SERVER["TMP"] : "/tmp";
function Service_Install()
{
global $appname;
global $appdesc;
// install for specific os
if (strpos(PHP_OS,"WIN") !== false)
{
// check if we found the executable binary
if (file_exists(PHP_BINARY))
{
win32_create_service( Array(
'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
{
die($appdesc." could not be installed because the php executable was not found.\n");
}
}
else
{
// load required files
require_once __DIR__.'/../../resources/config.php'; //required for database type
// read template file
$template=file_get_contents(dirname(__FILE__).'/resources/systemd.service.template');
// service short name
$template=str_replace('{$shortname}',$appname,$template);
// service full name
$template=str_replace('{$fullname}',$appdesc,$template);
// service dependencies
switch ($db_type) {
case 'pgsql':
$template=str_replace('{$database}','postgresql.service',$template);
break;
case 'mysql':
$template=str_replace('{$database}','mariadb.service',$template);
break;
default:
$template=str_replace('{$database}','',$template);
break;
}
// script path
$template=str_replace('{$scriptpath}',__FILE__,$template);
// script folder
$template=str_replace('{$scriptfolder}',dirname(__FILE__),$template);
// script filename
$template=str_replace('{$scriptfilename}',basename(__FILE__),$template);
// write service file
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");
}
}
function Service_Uninstall()
{
global $appname;
global $appdesc;
// uninstall for specific os
if (strpos(PHP_OS,"WIN") !== false)
{
win32_delete_service($appname);
//exec('sc delete "'.$appname.'"');
die($appdesc." was successfully uninstalled.\n");
}
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');
die($appdesc." was successfully uninstalled.\n");
}
}
function Service_Run()
{
global $appname;
global $appdesc;
global $pid;
global $pidfile;
// 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);
}
Service_Windows_Run();
}
else
{
if (file_exists('/proc/'.$pid)) die($appdesc." already running with process id".$pid);
Service_Linux_Run();
}
}
}
}
function Service_Linux_Run()
{
global $appname;
global $appdesc;
global $pid;
global $pidfile;
global $tftpservice_address;
global $tftpservice_port;
global $tftpservice_file_path;
// 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_file_path':
$tftpservice_file_path=$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_file_path));
if(!$server->loop($error, $user)) die("$error\n");
}
function Service_Windows_Run()
{
global $appname;
global $appdesc;
global $pid;
global $pidfile;
global $tftpservice_address;
global $tftpservice_port;
global $tftpservice_file_path;
// 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_file_path':
$tftpservice_file_path=$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_file_path));
// 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_file_path;
// 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_file_path':
$tftpservice_file_path=$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_file_path));
echo $appdesc." has started.\n";
if(!$server->loop($error, $user)) die("$error\n");
echo $appdesc." has stopped.\n";
}
if (php_sapi_name() === 'cli') {
if(isset($_SERVER["argv"][1])&&$_SERVER["argv"][1]=="--InstallService")
Service_Install(); // Install System Service
elseif(isset($_SERVER["argv"][1])&&$_SERVER["argv"][1]=="--UninstallService")
Service_Uninstall(); // Uninstall System Service
elseif(isset($_SERVER["argv"][1])&&$_SERVER["argv"][1]=="--Service")
Service_Run(); // Run as a Service
else
Run(); // Run
}
?>