Move sendControlCommand out of includes/control_functions.php into Monitor.php. Make it smarted about talking to zmcontrol.pl. Fix sending the quit command

This commit is contained in:
Isaac Connor 2019-10-08 18:07:33 -04:00
parent 55b1d29927
commit 4126554092
7 changed files with 95 additions and 84 deletions

View File

@ -16,41 +16,12 @@ if ( canView('Control', $_REQUEST['id']) ) {
return; return;
} }
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0); if ( $monitor->sendControlCommand($ctrlCommand) ) {
if ( !$socket ) ajaxResponse('Success');
ajaxError('socket_create() failed: '.socket_strerror(socket_last_error()));
$sock_file = ZM_PATH_SOCKS.'/zmcontrol-'.$monitor->Id().'.sock';
if ( @socket_connect($socket, $sock_file) ) {
$options = array();
foreach ( explode(' ', $ctrlCommand) as $option ) {
if ( preg_match('/--([^=]+)(?:=(.+))?/', $option, $matches) ) {
$options[$matches[1]] = !empty($matches[2])?$matches[2]:1;
}
}
$option_string = jsonEncode($options);
if ( !socket_write($socket, $option_string) )
ajaxError("socket_write() failed: ".socket_strerror(socket_last_error()));
ajaxResponse('Used socket');
//socket_close( $socket );
} else { } else {
$ctrlCommand .= ' --id='.$monitor->Id(); ajaxError('Failed');
// Can't connect so use script
$ctrlStatus = '';
$ctrlOutput = array();
exec( escapeshellcmd( $ctrlCommand ), $ctrlOutput, $ctrlStatus );
if ( $ctrlStatus )
ajaxError($ctrlCommand.'=>'.join(' // ', $ctrlOutput));
ajaxResponse('Used script');
} }
} }
ajaxError('Unrecognised action or insufficient permissions'); ajaxError('Unrecognised action or insufficient permissions');
function ajaxCleanup() {
global $socket;
if ( !empty( $socket ) )
@socket_close($socket);
}
?> ?>

View File

@ -459,5 +459,85 @@ private $status_fields = array(
//ZM_MIN_STREAMING_PORT ? (ZM_MIN_STREAMING_PORT+$this->Id()) : null); //ZM_MIN_STREAMING_PORT ? (ZM_MIN_STREAMING_PORT+$this->Id()) : null);
} }
public function sendControlCommand($command) {
// command is generally a command option list like --command=blah but might be just the word quit
$options = array();
# Convert from a command line params to an option array
foreach ( explode(' ', $command) as $option ) {
if ( preg_match('/--([^=]+)(?:=(.+))?/', $option, $matches) ) {
$options[$matches[1]] = $matches[2]?$matches[2]:1;
} else if ( $option != 'quit' ) {
Warning("Ignored command for zmcontrol $option in $command");
}
}
if ( !count($options) ) {
if ( $command == 'quit' ) {
$options['command'] = 'quit';
} else {
Warning("No commands to send to zmcontrol from $command");
return false;
}
}
if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
# Local
Logger::Debug('Trying to send options ' . print_r($options, true));
$optionString = jsonEncode($options);
Logger::Debug("Trying to send options $optionString");
// Either connects to running zmcontrol.pl or runs zmcontrol.pl to send the command.
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
if ( $socket < 0 ) {
Error('socket_create() failed: '.socket_strerror($socket));
return false;
}
$sockFile = ZM_PATH_SOCKS.'/zmcontrol-'.$this->{'Id'}.'.sock';
if ( @socket_connect($socket, $sockFile) ) {
if ( !socket_write($socket, $optionString) ) {
Error('Can\'t write to control socket: '.socket_strerror(socket_last_error($socket)));
return false;
}
} else if ( $command != 'quit' ) {
$command = ZM_PATH_BIN.'/zmcontrol.pl '.$command.' --id='.$this->{'Id'};
// Can't connect so use script
$ctrlOutput = exec(escapeshellcmd($command));
}
socket_close($socket);
} else if ( $this->ServerId() ) {
$Server = $this->Server();
$url = ZM_BASE_PROTOCOL . '://'.$Server->Hostname().'/zm/api/monitors/daemonControl/'.$this->{'Id'}.'/'.$mode.'/zmcontrol.json';
if ( ZM_OPT_USE_AUTH ) {
if ( ZM_AUTH_RELAY == 'hashed' ) {
$url .= '?auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
} else if ( ZM_AUTH_RELAY == 'plain' ) {
$url = '?user='.$_SESSION['username'];
$url = '?pass='.$_SESSION['password'];
} else if ( ZM_AUTH_RELAY == 'none' ) {
$url = '?user='.$_SESSION['username'];
}
}
Logger::Debug("sending command to $url");
$context = stream_context_create();
try {
$result = file_get_contents($url, false, $context);
if ($result === FALSE) { /* Handle error */
Error("Error restarting zma using $url");
return false;
}
} catch ( Exception $e ) {
Error("Except $e thrown trying to restart zma");
return false;
}
} else {
Error('Server not assigned to Monitor in a multi-server setup. Please assign a server to the Monitor.');
return false;
} // end if we are on the recording server
return true;
} // end function sendControlCommand($mid, $command)
} // end class Monitor } // end class Monitor
?> ?>

View File

@ -35,7 +35,7 @@ if ( $action == 'control' ) {
$monitor = new ZM\Monitor($mid); $monitor = new ZM\Monitor($mid);
$ctrlCommand = buildControlCommand($monitor); $ctrlCommand = buildControlCommand($monitor);
sendControlCommand($monitor->Id(), $ctrlCommand); $monitor->sendControlCommand($ctrlCommand);
$view = 'none'; $view = 'none';
} }
?> ?>

View File

@ -256,7 +256,7 @@ if ( $action == 'monitor' ) {
if ( $monitor->Controllable() ) { if ( $monitor->Controllable() ) {
require_once('includes/control_functions.php'); require_once('includes/control_functions.php');
sendControlCommand($mid, 'quit'); $monitor->sendControlCommand('quit');
} }
} }
// really should thump zmwatch and maybe zmtrigger too. // really should thump zmwatch and maybe zmtrigger too.

View File

@ -29,7 +29,6 @@ if ( ! canView('Control', $_REQUEST['mid']) ) {
return; return;
} }
require_once('control_functions.php');
require_once('Monitor.php'); require_once('Monitor.php');
$mid = validInt($_REQUEST['mid']); $mid = validInt($_REQUEST['mid']);
if ( $action == 'settings' ) { if ( $action == 'settings' ) {

View File

@ -23,7 +23,7 @@ if ( !empty($_REQUEST['mid']) && canEdit('Monitors', $_REQUEST['mid']) ) {
$mid = validInt($_REQUEST['mid']); $mid = validInt($_REQUEST['mid']);
if ( $action == 'zone' && isset($_REQUEST['zid']) ) { if ( $action == 'zone' && isset($_REQUEST['zid']) ) {
$zid = validInt($_REQUEST['zid']); $zid = validInt($_REQUEST['zid']);
$monitor = dbFetchOne('SELECT * FROM Monitors WHERE Id=?', NULL, array($mid)); $monitor = new ZM\Monitor($mid);
if ( !empty($zid) ) { if ( !empty($zid) ) {
$zone = dbFetchOne('SELECT * FROM Zones WHERE MonitorId=? AND Id=?', NULL, array($mid, $zid)); $zone = dbFetchOne('SELECT * FROM Zones WHERE MonitorId=? AND Id=?', NULL, array($mid, $zid));
@ -60,21 +60,20 @@ if ( !empty($_REQUEST['mid']) && canEdit('Monitors', $_REQUEST['mid']) ) {
} else { } else {
dbQuery('INSERT INTO Zones SET MonitorId=?, '.implode(', ', $changes), array($mid)); dbQuery('INSERT INTO Zones SET MonitorId=?, '.implode(', ', $changes), array($mid));
} }
if ( daemonCheck() && ($monitor['Type'] != 'WebSite') ) { if ( daemonCheck() && ($monitor->Type() != 'WebSite') ) {
if ( $_REQUEST['newZone']['Type'] == 'Privacy' ) { if ( $_REQUEST['newZone']['Type'] == 'Privacy' ) {
zmaControl($monitor, 'stop'); $monitor->zmaControl('stop');
zmcControl($monitor, 'restart'); $monitor->zmcControl('restart');
zmaControl($monitor, 'start'); $monitor->zmaControl('start');
} else { } else {
zmaControl($monitor, 'restart'); $monitor->zmaControl('restart');
} }
} }
if ( ($_REQUEST['newZone']['Type'] == 'Privacy') && $monitor['Controllable'] ) { if ( ($_REQUEST['newZone']['Type'] == 'Privacy') && $monitor->Controllable() ) {
require_once('control_functions.php'); $monitor->sendControlCommand('quit');
sendControlCommand($mid, 'quit');
} }
$refreshParent = true; $refreshParent = true;
} } // end if changes
$view = 'none'; $view = 'none';
} // end if action } // end if action
} // end if $mid and canEdit($mid) } // end if $mid and canEdit($mid)

View File

@ -1,7 +1,7 @@
<?php <?php
function buildControlCommand($monitor) { function buildControlCommand($monitor) {
$ctrlCommand = ZM_PATH_BIN.'/zmcontrol.pl'; $ctrlCommand = '';
$control = $monitor->Control(); $control = $monitor->Control();
if ( isset($_REQUEST['xge']) || isset($_REQUEST['yge']) ) { if ( isset($_REQUEST['xge']) || isset($_REQUEST['yge']) ) {
@ -740,41 +740,3 @@ function buildControlCommand($monitor) {
return $ctrlCommand; return $ctrlCommand;
} }
function sendControlCommand($mid, $command) {
$options = array();
foreach ( explode(' ', $command) as $option ) {
if ( preg_match('/--([^=]+)(?:=(.+))?/', $option, $matches) ) {
$options[$matches[1]] = $matches[2]?$matches[2]:1;
} else {
ZM\Warning("Ignored command for zmcontrol $option in $command");
}
}
if ( !count($options) ) {
if ( $command == 'quit' ) {
$options['quit'] = 1;
} else {
ZM\Warning("No commands to send to zmcontrol from $command");
return;
}
}
$optionString = jsonEncode($options);
// Either connects to running zmcontrol.pl or runs zmcontrol.pl to send the command.
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
if ( $socket < 0 ) {
ZM\Fatal('socket_create() failed: '.socket_strerror($socket));
}
$sockFile = ZM_PATH_SOCKS.'/zmcontrol-'.$mid.'.sock';
if ( @socket_connect($socket, $sockFile) ) {
if ( !socket_write($socket, $optionString) ) {
ZM\Fatal("Can't write to control socket: ".socket_strerror(socket_last_error($socket)));
}
socket_close($socket);
} else if ( $command != 'quit' ) {
$command .= ' --id='.$mid;
// Can't connect so use script
$ctrlOutput = exec(escapeshellcmd($command));
}
} // end function sendControlCommand($mid, $command)