diff --git a/distros/redhat/readme/README.Fedora b/distros/redhat/readme/README.Fedora index d0ccf8c4e..3366c31a6 100644 --- a/distros/redhat/readme/README.Fedora +++ b/distros/redhat/readme/README.Fedora @@ -3,6 +3,11 @@ What's New 1. See the ZoneMinder release notes for a list of new features: https://github.com/ZoneMinder/zoneminder/releases + +2. The contents of the ZoneMinder Apache config file have changed. In + addition, this ZoneMinder package now requires you to manually symlink the + ZoneMinder Apache config file. See new install step 6 and upgrade step 3 + below for details. New installs ============ diff --git a/distros/redhat/readme/README.Redhat7 b/distros/redhat/readme/README.Redhat7 index b70e7768d..d8d1b4bde 100644 --- a/distros/redhat/readme/README.Redhat7 +++ b/distros/redhat/readme/README.Redhat7 @@ -4,6 +4,11 @@ What's New 1. See the ZoneMinder release notes for a list of new features: https://github.com/ZoneMinder/zoneminder/releases +2. The contents of the ZoneMinder Apache config file have changed. In + addition, this ZoneMinder package now requires you to manually symlink the + ZoneMinder Apache config file. See new install step 6 and upgrade step 3 + below for details. + New installs ============ diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index c52ccbad9..efe4a88e2 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -26,7 +26,7 @@ %global _hardened_build 1 Name: zoneminder -Version: 1.31.43 +Version: 1.31.44 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons diff --git a/scripts/zmdc.pl.in b/scripts/zmdc.pl.in index fee01658f..b65388892 100644 --- a/scripts/zmdc.pl.in +++ b/scripts/zmdc.pl.in @@ -315,7 +315,6 @@ sub run { $secs_count += 1; } my $nfound = select(my $rout = $rin, undef, undef, $timeout); -Debug("Aftere select $nfound"); if ( $nfound > 0 ) { if ( vec($rout, fileno(SERVER), 1) ) { my $paddr = accept(CLIENT, SERVER); diff --git a/web/ajax/stream.php b/web/ajax/stream.php index 1c2fb3d62..44aaec8e6 100644 --- a/web/ajax/stream.php +++ b/web/ajax/stream.php @@ -22,13 +22,9 @@ if ( sem_acquire($semaphore,1) !== false ) { if ( file_exists( $localSocketFile ) ) { Warning("sock file $localSocketFile already exists?! Is someone else talking to zms?"); // They could be. We can maybe have concurrent requests from a browser. - } else { - Logger::Debug("socket file does not exist, we should be good to connect."); } if ( ! socket_bind( $socket, $localSocketFile ) ) { - ajaxError( "socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()) ); - } else { - Logger::Debug("Bound to $localSocketFile"); + ajaxError("socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()) ); } switch ( $_REQUEST['command'] ) { @@ -81,7 +77,6 @@ if ( sem_acquire($semaphore,1) !== false ) { $eSockets = NULL; $timeout = MSG_TIMEOUT - ( time() - $start_time ); - Logger::Debug("TImeout is: $timeout/1000 seconds. " ); $numSockets = socket_select( $rSockets, $wSockets, $eSockets, intval($timeout/1000), ($timeout%1000)*1000 ); diff --git a/web/api/app/Controller/MonitorsController.php b/web/api/app/Controller/MonitorsController.php index 660bee5ce..5801c1e9e 100644 --- a/web/api/app/Controller/MonitorsController.php +++ b/web/api/app/Controller/MonitorsController.php @@ -332,25 +332,18 @@ class MonitorsController extends AppController { } public function daemonControl($id, $command, $monitor=null, $daemon=null) { - $args = ''; $daemons = array(); - if (!$monitor) { + if ( !$monitor ) { // Need to see if it is local or remote $monitor = $this->Monitor->find('first', array( - 'fields' => array('Type', 'Function'), + 'fields' => array('Type', 'Function', 'Device'), 'conditions' => array('Id' => $id) )); $monitor = $monitor['Monitor']; } - if ($monitor['Type'] == 'Local') { - $args = '-d ' . $monitor['Device']; - } else { - $args = '-m ' . $id; - } - - if ($monitor['Function'] == 'Monitor') { + if ( $monitor['Function'] == 'Monitor' ) { array_push($daemons, 'zmc'); } else { array_push($daemons, 'zmc', 'zma'); @@ -359,6 +352,13 @@ class MonitorsController extends AppController { $zm_path_bin = Configure::read('ZM_PATH_BIN'); foreach ($daemons as $daemon) { + $args = ''; + if ( $daemon == 'zmc' and $monitor['Type'] == 'Local') { + $args = '-d ' . $monitor['Device']; + } else { + $args = '-m ' . $id; + } + $shellcmd = escapeshellcmd("$zm_path_bin/zmdc.pl $command $daemon $args"); $status = exec( $shellcmd ); } diff --git a/web/includes/Filter.php b/web/includes/Filter.php index de51b9876..721302edb 100644 --- a/web/includes/Filter.php +++ b/web/includes/Filter.php @@ -20,7 +20,7 @@ public $defaults = array( 'limit' => 100, 'Query' => array(), 'sort_field' => ZM_WEB_EVENT_SORT_FIELD, - 'sort_asc' => ZM_WEB_EVENT_SORT_ORDER == 'asc' ? 'asc' : 'desc', + 'sort_asc' => ZM_WEB_EVENT_SORT_ORDER, ); public function __construct( $IdOrRow=NULL ) { diff --git a/web/includes/actions.php b/web/includes/actions.php index 8549d3978..54402da7c 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -476,15 +476,12 @@ if ( canEdit( 'Monitors' ) ) { ); if ( $_REQUEST['newMonitor']['ServerId'] == 'auto' ) { - Logger::Debug("Auto selecting server"); $_REQUEST['newMonitor']['ServerId'] = dbFetchOne('SELECT Id FROM Servers WHERE Status=\'Running\' ORDER BY FreeMem DESC, CpuLoad ASC LIMIT 1', 'Id'); Logger::Debug("Auto selecting server: Got " . $_REQUEST['newMonitor']['ServerId'] ); if ( ( ! $_REQUEST['newMonitor'] ) and defined('ZM_SERVER_ID') ) { $_REQUEST['newMonitor']['ServerId'] = ZM_SERVER_ID; Logger::Debug("Auto selecting server to " . ZM_SERVER_ID); } - } else { - Logger::Debug("NOT Auto selecting server" . $_REQUEST['newMonitor']['ServerId']); } $columns = getTableColumns('Monitors'); @@ -571,22 +568,23 @@ if ( canEdit( 'Monitors' ) ) { $restart = true; } # end if count(changes) - if ( - ( !isset($_POST['newMonitor']['GroupIds']) ) - or - ( count($_POST['newMonitor']['GroupIds']) != count($Monitor->GroupIds()) ) - or - array_diff($_POST['newMonitor']['GroupIds'], $Monitor->GroupIds()) - ) { - if ( $Monitor->Id() ) - dbQuery('DELETE FROM Groups_Monitors WHERE MonitorId=?', array($mid)); - if ( isset($_POST['newMonitor']['GroupIds']) ) { - foreach ( $_POST['newMonitor']['GroupIds'] as $group_id ) { - dbQuery('INSERT INTO Groups_Monitors (GroupId,MonitorId) VALUES (?,?)', array($group_id, $mid)); - } + if ( + ( !isset($_POST['newMonitor']['GroupIds']) ) + or + ( count($_POST['newMonitor']['GroupIds']) != count($Monitor->GroupIds()) ) + or + array_diff($_POST['newMonitor']['GroupIds'], $Monitor->GroupIds()) + ) { + if ( $Monitor->Id() ) + dbQuery('DELETE FROM Groups_Monitors WHERE MonitorId=?', array($mid)); + + if ( isset($_POST['newMonitor']['GroupIds']) ) { + foreach ( $_POST['newMonitor']['GroupIds'] as $group_id ) { + dbQuery('INSERT INTO Groups_Monitors (GroupId,MonitorId) VALUES (?,?)', array($group_id, $mid)); } - } // end if there has been a change of groups + } + } // end if there has been a change of groups if ( ZM_OPT_X10 ) { $x10Changes = getFormChanges( $x10Monitor, $_REQUEST['newX10Monitor'] ); diff --git a/web/index.php b/web/index.php index d93b46e23..4cc7cf75c 100644 --- a/web/index.php +++ b/web/index.php @@ -200,7 +200,7 @@ isset($view) || $view = NULL; isset($request) || $request = NULL; isset($action) || $action = NULL; -if ( ZM_ENABLE_CSRF_MAGIC && $action != 'login' && $view != 'view_video' && $view != 'video' && $request != 'control' && $view != 'frames' && $view != 'archive' ) { +if ( ZM_ENABLE_CSRF_MAGIC && $action != 'login' && $view != 'view_video' && $request != 'control' && $view != 'frames' && $view != 'archive' ) { require_once( 'includes/csrf/csrf-magic.php' ); #Logger::Debug("Calling csrf_check with the following values: \$request = \"$request\", \$view = \"$view\", \$action = \"$action\""); csrf_check(); diff --git a/web/skins/classic/includes/functions.php b/web/skins/classic/includes/functions.php index e1808410a..3d7777ef1 100644 --- a/web/skins/classic/includes/functions.php +++ b/web/skins/classic/includes/functions.php @@ -373,18 +373,13 @@ function xhtmlFooter() { global $view; global $skin; global $running; -if ( canEdit('System') ) { - include("skins/$skin/views/state.php"); + if ( canEdit('System') ) { + include("skins/$skin/views/state.php"); + } ?> - - - + + diff --git a/web/skins/classic/views/options.php b/web/skins/classic/views/options.php index 0a70ed96a..31c1f57cb 100644 --- a/web/skins/classic/views/options.php +++ b/web/skins/classic/views/options.php @@ -279,7 +279,7 @@ foreach( array_map( 'basename', glob('skins/'.$current_skin.'/css/*',GLOB_ONLYDI Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Scheme()), $canEdit ) ?> Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Name()), $canEdit ) ?> - disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?> + disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?> disabled="disabled"/> diff --git a/web/skins/classic/views/video.php b/web/skins/classic/views/video.php index 0c7c4e153..2a6a41424 100644 --- a/web/skins/classic/views/video.php +++ b/web/skins/classic/views/video.php @@ -18,8 +18,8 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // -if ( !canView( 'Events' ) ) { - $view = "error"; +if ( !canView('Events') ) { + $view = 'error'; return; } @@ -28,31 +28,31 @@ require_once('includes/Event.php'); $eid = validInt($_REQUEST['eid']); $sql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultRate,M.DefaultScale FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE E.Id = ?'; -$sql_values = array( $eid ); +$sql_values = array($eid); if ( $user['MonitorIds'] ) { - $monitor_ids = explode( ',', $user['MonitorIds'] ); - $sql .= ' AND MonitorId IN (' .implode( ',', array_fill(0,count($monitor_ids),'?') ) . ')'; - $sql_values = array_merge( $sql_values, $monitor_ids ); + $monitor_ids = explode(',', $user['MonitorIds']); + $sql .= ' AND MonitorId IN ('.implode(',', array_fill(0,count($monitor_ids),'?')).')'; + $sql_values = array_merge($sql_values, $monitor_ids); } -$event = dbFetchOne( $sql, NULL, $sql_values ); +$event = dbFetchOne($sql, NULL, $sql_values); -if ( isset( $_REQUEST['rate'] ) ) +if ( isset($_REQUEST['rate']) ) $rate = validInt($_REQUEST['rate']); else - $rate = reScale( RATE_BASE, $event['DefaultRate'], ZM_WEB_DEFAULT_RATE ); -if ( isset( $_REQUEST['scale'] ) ) + $rate = reScale(RATE_BASE, $event['DefaultRate'], ZM_WEB_DEFAULT_RATE); +if ( isset($_REQUEST['scale']) ) $scale = validInt($_REQUEST['scale']); else - $scale = reScale( SCALE_BASE, $event['DefaultScale'], ZM_WEB_DEFAULT_SCALE ); + $scale = reScale(SCALE_BASE, $event['DefaultScale'], ZM_WEB_DEFAULT_SCALE); -$Event = new Event( $event['Id'] ); +$Event = new Event($event['Id']); $eventPath = $Event->Path(); $videoFormats = array(); -$ffmpegFormats = preg_split( '/\s+/', ZM_FFMPEG_FORMATS ); +$ffmpegFormats = preg_split('/\s+/', ZM_FFMPEG_FORMATS); foreach ( $ffmpegFormats as $ffmpegFormat ) { - if ( preg_match( '/^([^*]+)(\*\*?)$/', $ffmpegFormat, $matches ) ) { + if ( preg_match('/^([^*]+)(\*\*?)$/', $ffmpegFormat, $matches) ) { $videoFormats[$matches[1]] = $matches[1]; if ( !isset($videoFormat) && $matches[2] == '*' ) { $videoFormat = $matches[1]; @@ -63,42 +63,44 @@ foreach ( $ffmpegFormats as $ffmpegFormat ) { } $videoFiles = array(); -if ( $dir = opendir( $eventPath ) ) { - while ( ($file = readdir( $dir )) !== false ) { +if ( $dir = opendir($eventPath) ) { + while ( ($file = readdir($dir)) !== false ) { $file = $eventPath.'/'.$file; - if ( is_file( $file ) ) { - if ( preg_match( '/\.(?:'.join( '|', $videoFormats ).')$/', $file ) ) { + if ( is_file($file) ) { + if ( preg_match('/\.(?:'.join('|', $videoFormats).')$/', $file) ) { $videoFiles[] = $file; } } } - closedir( $dir ); + closedir($dir); } if ( isset($_REQUEST['deleteIndex']) ) { $deleteIndex = validInt($_REQUEST['deleteIndex']); - unlink( $videoFiles[$deleteIndex] ); - unset( $videoFiles[$deleteIndex] ); + unlink($videoFiles[$deleteIndex]); + unset($videoFiles[$deleteIndex]); } if ( isset($_REQUEST['downloadIndex']) ) { + // can't be output buffering, as this file might be large + ob_end_clean(); $downloadIndex = validInt($_REQUEST['downloadIndex']); - header( 'Pragma: public' ); - header( 'Expires: 0' ); - header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' ); - header( 'Cache-Control: private', false ); // required by certain browsers - header( 'Content-Description: File Transfer' ); - header( 'Content-disposition: attachment; filename="'.basename($videoFiles[$downloadIndex]).'"' ); // basename is required because the video index contains the path and firefox doesn't strip the path but simply replaces the slashes with an underscore. - header( 'Content-Transfer-Encoding: binary' ); - header( 'Content-Type: application/force-download' ); - header( 'Content-Length: '.filesize($videoFiles[$downloadIndex]) ); - readfile( $videoFiles[$downloadIndex] ); + header('Pragma: public'); + header('Expires: 0'); + header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); + header('Cache-Control: private', false); // required by certain browsers + header('Content-Description: File Transfer'); + header('Content-disposition: attachment; filename="'.basename($videoFiles[$downloadIndex]).'"'); // basename is required because the video index contains the path and firefox doesn't strip the path but simply replaces the slashes with an underscore. + header('Content-Transfer-Encoding: binary'); + header('Content-Type: application/force-download'); + header('Content-Length: '.filesize($videoFiles[$downloadIndex])); + readfile($videoFiles[$downloadIndex]); exit; } $focusWindow = true; -xhtmlHeaders(__FILE__, translate('Video') ); +xhtmlHeaders(__FILE__, translate('Video')); ?>
@@ -112,30 +114,30 @@ xhtmlHeaders(__FILE__, translate('Video') ); -

-
+

+
- +
- + - + - + @@ -143,16 +145,22 @@ if ( isset($_REQUEST['showIndex']) ) {
- disabled="disabled"/> + disabled="disabled"/>
-

+

+ + +

- + @@ -164,7 +172,7 @@ if ( isset($_REQUEST['showIndex']) ) { - +
@@ -178,29 +186,29 @@ if ( isset($_REQUEST['showIndex']) ) { 0 ) { - preg_match( '/^(.+)-((?:r[_\d]+)|(?:F[_\d]+))-((?:s[_\d]+)|(?:S[0-9a-z]+))\.([^.]+)$/', $file, $matches ); - if ( preg_match( '/^r(.+)$/', $matches[2], $temp_matches ) ) { + if ( filesize($file) > 0 ) { + preg_match('/^(.+)-((?:r[_\d]+)|(?:F[_\d]+))-((?:s[_\d]+)|(?:S[0-9a-z]+))\.([^.]+)$/', $file, $matches); + if ( preg_match('/^r(.+)$/', $matches[2], $temp_matches) ) { $rate = (int)(100 * preg_replace( '/_/', '.', $temp_matches[1] ) ); $rateText = isset($rates[$rate])?$rates[$rate]:($rate."x"); - } elseif ( preg_match( '/^F(.+)$/', $matches[2], $temp_matches ) ) { - $rateText = $temp_matches[1]."fps"; + } elseif ( preg_match('/^F(.+)$/', $matches[2], $temp_matches) ) { + $rateText = $temp_matches[1].'fps'; } - if ( preg_match( '/^s(.+)$/', $matches[3], $temp_matches ) ) { - $scale = (int)(100 * preg_replace( '/_/', '.', $temp_matches[1] ) ); - $scaleText = isset($scales[$scale])?$scales[$scale]:($scale."x"); - } elseif ( preg_match( '/^S(.+)$/', $matches[3], $temp_matches ) ) { + if ( preg_match('/^s(.+)$/', $matches[3], $temp_matches) ) { + $scale = (int)(100 * preg_replace('/_/', '.', $temp_matches[1]) ); + $scaleText = isset($scales[$scale])?$scales[$scale]:($scale.'x'); + } elseif ( preg_match('/^S(.+)$/', $matches[3], $temp_matches) ) { $scaleText = $temp_matches[1]; } - $width = $scale?reScale( $event['Width'], $scale ):$event['Width']; - $height = $scale?reScale( $event['Height'], $scale ):$event['Height']; + $width = $scale?reScale($event['Width'], $scale):$event['Width']; + $height = $scale?reScale($event['Height'], $scale):$event['Height']; ?> - + - + Delta(1); $Frame->FrameId('snapshot'); } - $path = $Event->Path().'/snapshot.jpg'; + $Monitor = $Event->Monitor(); + if ( $Monitor->SaveJPEGs() & 1 ) { + # If we store Frames as jpgs, then we don't store a snapshot + $path = $Event->Path().'/'.sprintf('%0'.ZM_EVENT_IMAGE_DIGITS.'d',$Frame->FrameId()).'-'.$show.'.jpg'; + } else { + $path = $Event->Path().'/snapshot.jpg'; + } } else { $Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'FrameId'=>$_REQUEST['fid']));
 /  /  /  /