From a6b804bb62b7b2327772d5733ab6ab6c503bcb99 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Wed, 13 May 2020 07:58:53 -0400
Subject: [PATCH 01/45] As params are passed in command, they should not be
fatal to the control process
---
scripts/ZoneMinder/lib/ZoneMinder/Control.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control.pm
index 06c116626..acce8eb4a 100644
--- a/scripts/ZoneMinder/lib/ZoneMinder/Control.pm
+++ b/scripts/ZoneMinder/lib/ZoneMinder/Control.pm
@@ -116,7 +116,7 @@ sub getParam {
} elsif ( defined($default) ) {
return $default;
}
- Fatal("Missing mandatory parameter '$name'");
+ Error("Missing mandatory parameter '$name'");
}
sub executeCommand {
From 807efde5237cba83b803a10b0b2153b16c31ec90 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Wed, 13 May 2020 08:01:04 -0400
Subject: [PATCH 02/45] xtell and ytell are data-xtell and data-ytell fixes
#2932
---
web/skins/classic/views/js/watch.js | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js
index 8a38afea4..19f74333b 100644
--- a/web/skins/classic/views/js/watch.js
+++ b/web/skins/classic/views/js/watch.js
@@ -695,12 +695,11 @@ function getControlResponse(respObj, respText) {
function controlCmd(event) {
button = event.target;
control = button.getAttribute('value');
- xtell = button.getAttribute('xtell');
- ytell = button.getAttribute('ytell');
+ xtell = button.getAttribute('data-xtell');
+ ytell = button.getAttribute('data-ytell');
var locParms = '';
if ( event && (xtell || ytell) ) {
- console.log(event);
var target = event.target;
var coords = $(target).getCoordinates();
From f72ad1023c56da9ff42df4830ef03119459f0e06 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Wed, 13 May 2020 07:58:53 -0400
Subject: [PATCH 03/45] As params are passed in command, they should not be
fatal to the control process
---
scripts/ZoneMinder/lib/ZoneMinder/Control.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control.pm
index 896d10c07..98abab744 100644
--- a/scripts/ZoneMinder/lib/ZoneMinder/Control.pm
+++ b/scripts/ZoneMinder/lib/ZoneMinder/Control.pm
@@ -116,7 +116,7 @@ sub getParam {
} elsif ( defined($default) ) {
return $default;
}
- Fatal("Missing mandatory parameter '$name'");
+ Error("Missing mandatory parameter '$name'");
}
sub executeCommand {
From edd718afd24ec447ffce16f3cbfc1eff33bb9b0e Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Wed, 13 May 2020 08:01:04 -0400
Subject: [PATCH 04/45] xtell and ytell are data-xtell and data-ytell fixes
#2932
---
web/skins/classic/views/js/watch.js | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js
index 633d507a5..0056f0a08 100644
--- a/web/skins/classic/views/js/watch.js
+++ b/web/skins/classic/views/js/watch.js
@@ -695,12 +695,11 @@ function getControlResponse(respObj, respText) {
function controlCmd(event) {
button = event.target;
control = button.getAttribute('value');
- xtell = button.getAttribute('xtell');
- ytell = button.getAttribute('ytell');
+ xtell = button.getAttribute('data-xtell');
+ ytell = button.getAttribute('data-ytell');
var locParms = '';
if ( event && (xtell || ytell) ) {
- console.log(event);
var target = event.target;
var coords = $(target).getCoordinates();
From bbf64de40eb50ed54d258a2260e38d23e6fc8501 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Tue, 12 May 2020 15:10:08 -0400
Subject: [PATCH 05/45] If there is a failure when decoding due to lack of
support for the codec profile, re-init without hwaccel
---
src/zm_ffmpeg_camera.cpp | 10 ++++++++--
src/zm_ffmpeg_camera.h | 1 +
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp
index ea13f9382..109be4083 100644
--- a/src/zm_ffmpeg_camera.cpp
+++ b/src/zm_ffmpeg_camera.cpp
@@ -148,6 +148,7 @@ FfmpegCamera::FfmpegCamera(
have_video_keyframe = false;
packetqueue = NULL;
error_count = 0;
+ use_hwaccel = true;
#if HAVE_LIBAVUTIL_HWCONTEXT_H
hwFrame = NULL;
hw_device_ctx = NULL;
@@ -471,7 +472,7 @@ int FfmpegCamera::OpenFfmpeg() {
zm_dump_stream_format(mFormatContext, mVideoStreamId, 0, 0);
- if ( hwaccel_name != "" ) {
+ if ( use_hwaccel && (hwaccel_name != "") ) {
#if HAVE_LIBAVUTIL_HWCONTEXT_H
// 3.2 doesn't seem to have all the bits in place, so let's require 3.3 and up
#if LIBAVCODEC_VERSION_CHECK(57, 89, 0, 89, 0)
@@ -503,8 +504,9 @@ int FfmpegCamera::OpenFfmpeg() {
hw_pix_fmt = config->pix_fmt;
break;
} else {
- Debug(1, "decoder %s hwConfig doesn't match our type: %s, pix_fmt %s.",
+ Debug(1, "decoder %s hwConfig doesn't match our type: %s != %s, pix_fmt %s.",
mVideoCodec->name,
+ av_hwdevice_get_type_name(type),
av_hwdevice_get_type_name(config->device_type),
av_get_pix_fmt_name(config->pix_fmt)
);
@@ -973,6 +975,10 @@ int FfmpegCamera::CaptureAndRecord(
Error("Error count over 100, going to close and re-open stream");
return -1;
}
+ if ( (ret == AVERROR_INVALIDDATA ) && (hw_pix_fmt != AV_PIX_FMT_NONE) ) {
+ use_hwaccel = false;
+ return -1;
+ }
}
zm_av_packet_unref(&packet);
continue;
diff --git a/src/zm_ffmpeg_camera.h b/src/zm_ffmpeg_camera.h
index 7a6439ee4..badf90834 100644
--- a/src/zm_ffmpeg_camera.h
+++ b/src/zm_ffmpeg_camera.h
@@ -60,6 +60,7 @@ class FfmpegCamera : public Camera {
AVFrame *input_frame; // Use to point to mRawFrame or hwFrame;
AVFrame *hwFrame; // Will also be used to indicate if hwaccel is in use
+ bool use_hwaccel; //will default to on if hwaccel specified, will get turned off if there is a failure
#if HAVE_LIBAVUTIL_HWCONTEXT_H
AVBufferRef *hw_device_ctx = NULL;
#endif
From e24b6214b18d97a93bfce40785ad8d961d6be895 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Mon, 11 May 2020 18:35:31 -0400
Subject: [PATCH 06/45] test logFile before doing regexps on it
---
scripts/ZoneMinder/lib/ZoneMinder/Logger.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm b/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm
index 5d05ae7c5..39c10a058 100644
--- a/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm
+++ b/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm
@@ -490,7 +490,7 @@ sub closeSyslog {
sub logFile {
my $this = shift;
my $logFile = shift;
- if ( $logFile =~ /^(.+)\+$/ ) {
+ if ( $logFile and ( $logFile =~ /^(.+)\+$/ ) ) {
$this->{logFile} = $1.'.'.$$;
} else {
$this->{logFile} = $logFile;
From 88a910793cf75e9486634527a5a056fcd8a25517 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Mon, 11 May 2020 09:19:33 -0400
Subject: [PATCH 07/45] Spacing
---
web/includes/logger.php | 49 ++++++++++++++++++++++-------------------
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/web/includes/logger.php b/web/includes/logger.php
index 2b5463dfb..f4e16221e 100644
--- a/web/includes/logger.php
+++ b/web/includes/logger.php
@@ -1,7 +1,7 @@
terminate();
}
- public function initialise( $options=array() ) {
+ public function initialise($options=array()) {
if ( !empty($options['id']) )
$this->id = $options['id'];
@@ -237,31 +237,31 @@ class Logger {
$this->effectiveLevel = $this->level;
if ( !$this->hasTerm ) {
if ( $lastLevel < self::DEBUG && $this->level >= self::DEBUG ) {
- $this->savedErrorReporting = error_reporting( E_ALL );
- $this->savedDisplayErrors = ini_set( 'display_errors', true );
+ $this->savedErrorReporting = error_reporting(E_ALL);
+ $this->savedDisplayErrors = ini_set('display_errors', true);
} elseif ( $lastLevel >= self::DEBUG && $this->level < self::DEBUG ) {
- error_reporting( $this->savedErrorReporting );
- ini_set( 'display_errors', $this->savedDisplayErrors );
+ error_reporting($this->savedErrorReporting);
+ ini_set('display_errors', $this->savedDisplayErrors);
}
}
}
- return( $this->level );
+ return $this->level;
}
public function debugOn() {
return( $this->effectiveLevel >= self::DEBUG );
}
- public function termLevel( $termLevel ) {
+ public function termLevel($termLevel) {
if ( isset($termLevel) ) {
$termLevel = $this->limit($termLevel);
if ( $this->termLevel != $termLevel )
$this->termLevel = $termLevel;
}
- return( $this->termLevel );
+ return $this->termLevel;
}
- public function databaseLevel( $databaseLevel=NULL ) {
+ public function databaseLevel($databaseLevel=NULL) {
if ( !is_null($databaseLevel) ) {
$databaseLevel = $this->limit($databaseLevel);
if ( $this->databaseLevel != $databaseLevel ) {
@@ -269,7 +269,7 @@ class Logger {
if ( $this->databaseLevel > self::NOLOG ) {
if ( (include_once 'database.php') === FALSE ) {
$this->databaseLevel = self::NOLOG;
- Warning( 'Unable to write log entries to DB, database.php not found' );
+ Warning('Unable to write log entries to DB, database.php not found');
}
}
}
@@ -277,7 +277,7 @@ class Logger {
return $this->databaseLevel;
}
- public function fileLevel( $fileLevel ) {
+ public function fileLevel($fileLevel) {
if ( isset($fileLevel) ) {
$fileLevel = $this->limit($fileLevel);
if ( $this->fileLevel != $fileLevel ) {
@@ -291,14 +291,14 @@ class Logger {
return $this->fileLevel;
}
- public function weblogLevel( $weblogLevel ) {
+ public function weblogLevel($weblogLevel) {
if ( isset($weblogLevel) ) {
$weblogLevel = $this->limit($weblogLevel);
if ( $this->weblogLevel != $weblogLevel ) {
if ( $weblogLevel > self::NOLOG && $this->weblogLevel <= self::NOLOG ) {
- $this->savedLogErrors = ini_set( 'log_errors', true );
+ $this->savedLogErrors = ini_set('log_errors', true);
} elseif ( $weblogLevel <= self::NOLOG && $this->weblogLevel > self::NOLOG ) {
- ini_set( 'log_errors', $this->savedLogErrors );
+ ini_set('log_errors', $this->savedLogErrors);
}
$this->weblogLevel = $weblogLevel;
}
@@ -306,7 +306,7 @@ class Logger {
return $this->weblogLevel;
}
- public function syslogLevel( $syslogLevel ) {
+ public function syslogLevel($syslogLevel) {
if ( isset($syslogLevel) ) {
$syslogLevel = $this->limit($syslogLevel);
if ( $this->syslogLevel != $syslogLevel ) {
@@ -353,7 +353,7 @@ class Logger {
fclose($this->logFd);
}
- public function logPrint( $level, $string, $file=NULL, $line=NULL ) {
+ public function logPrint($level, $string, $file=NULL, $line=NULL) {
if ( $level > $this->effectiveLevel ) {
return;
}
@@ -375,21 +375,21 @@ class Logger {
$rootPath = getcwd();
else
$rootPath = $_SERVER['DOCUMENT_ROOT'];
- $file = preg_replace('/^'.addcslashes($rootPath,'/').'\/?/', '', $file);
+ $file = preg_replace('/^'.addcslashes($rootPath, '/').'\/?/', '', $file);
}
}
if ( $this->useErrorLog ) {
$message .= ' at '.$file.' line '.$line;
- } else {
- $message = $message;
}
if ( $level <= $this->termLevel ) {
- if ( $this->hasTerm )
+ if ( $this->hasTerm ) {
print($message."\n");
- else
- print(preg_replace("/\n/", '
', htmlspecialchars($message)).'
');
+ } else {
+ // Didn't we already replace all newlines with spaces above?
+ print(preg_replace('/\n/', '
', htmlspecialchars($message)).'
');
+ }
}
if ( $level <= $this->fileLevel ) {
@@ -402,6 +402,9 @@ class Logger {
}
} else if ( $this->logFd ) {
fprintf($this->logFd, $message."\n");
+ } else {
+ $this->fileLevel = self::NOLOG;
+ Error('No logFd but have fileLevel logging!?');
}
}
From fc12b61750af8354699d86aba3c0056aa392419f Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Wed, 13 May 2020 15:09:31 -0400
Subject: [PATCH 08/45] Fix probing
---
scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in | 60 +++++++++----------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in
index 86cb859c6..2341e1748 100644
--- a/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in
+++ b/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in
@@ -39,12 +39,10 @@ our %EXPORT_TAGS = (
);
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
-our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );
our @EXPORT = qw();
-our $VERSION = $ZoneMinder::Base::VERSION;
-
use Data::UUID;
use vars qw( $verbose $soap_version );
@@ -60,6 +58,9 @@ require WSDiscovery::TransportUDP;
sub deserialize_message {
my ($wsdl_client, $response) = @_;
+ if ( ! $response ) {
+ return;
+ }
# copied and adapted from SOAP::WSDL::Client
@@ -74,20 +75,16 @@ sub deserialize_message {
}
# set class resolver if serializer supports it
$deserializer->set_class_resolver( $wsdl_client->get_class_resolver() )
- if ( $deserializer->can('set_class_resolver') );
+ if $deserializer->can('set_class_resolver');
# Try deserializing response - there may be some,
-# even if transport did not succeed (got a 500 response)
- if ( ! $response ) {
- return;
- }
-
+# even if transport did not succeed (got a 500 response)
# as our faults are false, returning a success marker is the only
# reliable way of determining whether the deserializer succeeded.
# Custom deserializers may return an empty list, or undef,
# and $@ is not guaranteed to be undefined.
my ($success, $result_body, $result_header) = eval {
- (1, $deserializer->deserialize( $response ));
+ (1, $deserializer->deserialize($response));
};
if ( defined $success ) {
return wantarray
@@ -110,10 +107,7 @@ sub interpret_messages {
my @results;
foreach my $response ( @responses ) {
-
- if ( $verbose ) {
- print "Received message:\n" . $response . "\n";
- }
+ print "Received message:\n" . $response . "\n" if $verbose;
my $result = deserialize_message($svc_discover, $response);
if ( not $result ) {
@@ -151,17 +145,16 @@ sub interpret_messages {
foreach my $scope (split ' ', $scopes) {
if ( $scope =~ m|onvif://www\.onvif\.org/(.+)/(.*)| ) {
my ($attr, $value) = ($1,$2);
- if ( 0 < $count ++) {
- print ', ';
- }
+ print ', ' if 0 < $count ++;
print $attr . '=\'' . $value . '\'';
$scopes{$attr} = $value;
}
}
print ")\n";
- push @results, { xaddr=>$xaddr,
+ push @results, {
+ xaddr => $xaddr,
soap_version => $svc_discover->get_soap_version(),
- scopes => \%scopes,
+ scopes => \%scopes,
};
}
return @results;
@@ -170,7 +163,7 @@ sub interpret_messages {
# functions
sub discover {
- my ( $soap_version, $net_interface ) = @_;
+ my ($soap_version, $net_interface) = @_;
my @results;
## collect all responses
@@ -195,7 +188,7 @@ sub discover {
$svc_discover->set_soap_version($version);
if ( $net_interface ) {
my $transport = $svc_discover->get_transport();
- print "Setting net interface for $transport to $net_interface\n";
+ print "Setting net interface for $transport to $net_interface\n" if $verbose;
$transport->set_net_interface($net_interface);
}
@@ -203,7 +196,15 @@ sub discover {
my $result = $svc_discover->ProbeOp(
{ # WSDiscovery::Types::ProbeType
- Types => 'http://www.onvif.org/ver10/network/wsdl:NetworkVideoTransmitter http://www.onvif.org/ver10/device/wsdl:Device', # QNameListType
+ (
+ ($version eq '1.1') ?
+ (
+ Types => 'http://www.onvif.org/ver10/network/wsdl:NetworkVideoTransmitter http://www.onvif.org/ver10/device/wsdl:Device', # QNameListType
+ ) : (
+ xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl', },
+ Types => 'dn:NetworkVideoTransmitter', # QNameListType
+ )
+ ),
Scopes => { value => '' },
},
WSDiscovery10::Elements::Header->new({
@@ -215,22 +216,23 @@ sub discover {
print $result."\n" if $verbose;
push @results, interpret_messages($svc_discover, \%services, @responses);
+ @responses = ();
} # end foreach version
return @results;
} # end sub discover
sub profiles {
- my ( $client ) = @_;
+ my ($client) = @_;
my $media = $client->get_endpoint('media');
- if ( ! $media ) {
+ if ( !$media ) {
print "No media endpoint for client.\n";
return;
}
my $result = $media->GetProfiles( { } ,, );
- if ( ! $result ) {
+ if ( !$result ) {
print "No result from GetProfiles.\n";
return;
}
@@ -244,7 +246,7 @@ sub profiles {
print "No profiles returned from get_Profiles\n";
return;
}
- print "Number of profiles found: " .(scalar @Profiles)."\n" if $verbose;
+ print 'Number of profiles found: ' .(scalar @Profiles)."\n" if $verbose;
my @profiles;
foreach my $profile ( @Profiles ) {
@@ -339,12 +341,12 @@ sub move {
} # end sub move
sub metadata {
- my ( $client ) = @_;
+ my ($client) = @_;
my $media = $client->get_endpoint('media');
die 'No media endpoint.' if !$media;
my $result = $media->GetMetadataConfigurations( { } ,, );
- if ( ! $result ) {
+ if ( !$result ) {
print "No MetaDataConfigurations\n" if $verbose;
} else {
print $result . "\n";
@@ -363,8 +365,6 @@ sub metadata {
}
-
-
1;
__END__
From 437a96915fbae05dfe3df6c09e28530be500feb6 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Wed, 13 May 2020 15:24:58 -0400
Subject: [PATCH 09/45] sketchy fix for soap 1.1
---
scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in
index 2341e1748..01536bf77 100644
--- a/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in
+++ b/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in
@@ -202,9 +202,9 @@ sub discover {
Types => 'http://www.onvif.org/ver10/network/wsdl:NetworkVideoTransmitter http://www.onvif.org/ver10/device/wsdl:Device', # QNameListType
) : (
xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl', },
- Types => 'dn:NetworkVideoTransmitter', # QNameListType
)
),
+ Types => 'dn:NetworkVideoTransmitter', # QNameListType
Scopes => { value => '' },
},
WSDiscovery10::Elements::Header->new({
From 880b456d933e611c670e0a51095356640f607fcc Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Wed, 13 May 2020 15:30:56 -0400
Subject: [PATCH 10/45] Rrename MetaConfig to ONVIF
---
web/skins/classic/views/monitor.php | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php
index be4df7b16..f137c58cd 100644
--- a/web/skins/classic/views/monitor.php
+++ b/web/skins/classic/views/monitor.php
@@ -169,12 +169,6 @@ if ( !ZM_PCRE )
// Currently unsupported
unset($httpMethods['jpegTags']);
-$configTypes = array(
- 'None' => translate('None'),
- 'ONVIF' => 'ONVIF',
- 'PSIA' => 'PSIA',
-);
-
if ( ZM_HAS_V4L1 ) {
$v4l1DeviceFormats = array(
'PAL' => 0,
@@ -419,7 +413,7 @@ if ( canEdit('Monitors') ) {
$tabs = array();
$tabs['general'] = translate('General');
$tabs['source'] = translate('Source');
-$tabs["config"] = translate('MetaConfig');
+$tabs['onvif'] = translate('ONVIF');
if ( $monitor->Type() != 'WebSite' ) {
$tabs['storage'] = translate('Storage');
$tabs['timestamp'] = translate('Timestamp');
From 992ac144a9a728a6b88c93290920d2c706ab21ed Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Wed, 13 May 2020 16:04:26 -0400
Subject: [PATCH 11/45] Fix ONVIF_User => ONVIF_Username
---
web/skins/classic/views/monitor.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php
index f137c58cd..910adc539 100644
--- a/web/skins/classic/views/monitor.php
+++ b/web/skins/classic/views/monitor.php
@@ -492,7 +492,7 @@ if ( ZM_HAS_V4L && ($tab != 'source' || $monitor->Type() != 'Local') ) {
if ( $tab != 'onvif' ) {
?>
-
+
Date: Wed, 13 May 2020 16:06:26 -0400
Subject: [PATCH 12/45] Fix log file containing - or _
---
scripts/ZoneMinder/lib/ZoneMinder/Logger.pm | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm b/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm
index 39c10a058..0513f563e 100644
--- a/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm
+++ b/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm
@@ -210,7 +210,7 @@ sub initialise( @ ) {
if ( my $logFile = $this->getTargettedEnv('LOG_FILE') ) {
$tempLogFile = $logFile;
}
- ($tempLogFile) = $tempLogFile =~ /^([\w\.\/]+)$/;
+ ($tempLogFile) = $tempLogFile =~ /^([_\-\w\.\/]+)$/;
my $tempLevel = INFO;
my $tempTermLevel = $this->{termLevel};
@@ -456,9 +456,9 @@ sub fileLevel {
if ( defined($fileLevel) ) {
$fileLevel = $this->limit($fileLevel);
# The filename might have changed, so always close and re-open
- $this->closeFile() if ( $this->{fileLevel} > NOLOG );
+ $this->closeFile() if $this->{fileLevel} > NOLOG;
$this->{fileLevel} = $fileLevel;
- $this->openFile() if ( $this->{fileLevel} > NOLOG );
+ $this->openFile() if $this->{fileLevel} > NOLOG;
}
return $this->{fileLevel};
}
@@ -499,6 +499,7 @@ sub logFile {
sub openFile {
my $this = shift;
+
if ( open($LOGFILE, '>>', $this->{logFile}) ) {
$LOGFILE->autoflush() if $this->{autoFlush};
@@ -519,7 +520,6 @@ sub openFile {
}
sub closeFile {
- #my $this = shift;
close($LOGFILE) if fileno($LOGFILE);
}
From efbab4e2bcc1ef06c8ea89c8a5af48a2035fbf61 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Thu, 14 May 2020 12:00:36 -0400
Subject: [PATCH 13/45] Dont' call mysql_library_end as it segfaults and hangs.
---
src/zm_db.cpp | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/zm_db.cpp b/src/zm_db.cpp
index 8e6258b0b..35982ce50 100644
--- a/src/zm_db.cpp
+++ b/src/zm_db.cpp
@@ -81,10 +81,11 @@ bool zmDbConnect() {
void zmDbClose() {
if ( zmDbConnected ) {
db_mutex.lock();
- mysql_close( &dbconn );
+ mysql_close(&dbconn);
// mysql_init() call implicitly mysql_library_init() but
// mysql_close() does not call mysql_library_end()
- mysql_library_end();
+ // We get segfaults and a hang when we call this. So just don't.
+ //mysql_library_end();
zmDbConnected = false;
db_mutex.unlock();
}
@@ -96,6 +97,12 @@ MYSQL_RES * zmDbFetch(const char * query) {
return NULL;
}
db_mutex.lock();
+ // Might have been disconnected while we waited for the lock
+ if ( !zmDbConnected ) {
+ db_mutex.unlock();
+ Error("Not connected.");
+ return NULL;
+ }
if ( mysql_query(&dbconn, query) ) {
db_mutex.unlock();
From 402c0c6a1bb7ac28a57b448769a39660b8143346 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Thu, 14 May 2020 12:01:03 -0400
Subject: [PATCH 14/45] Fix build on older ffmpeg
---
src/zm_ffmpeg_camera.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp
index 109be4083..11c25addc 100644
--- a/src/zm_ffmpeg_camera.cpp
+++ b/src/zm_ffmpeg_camera.cpp
@@ -975,10 +975,12 @@ int FfmpegCamera::CaptureAndRecord(
Error("Error count over 100, going to close and re-open stream");
return -1;
}
+#if HAVE_LIBAVUTIL_HWCONTEXT_H
if ( (ret == AVERROR_INVALIDDATA ) && (hw_pix_fmt != AV_PIX_FMT_NONE) ) {
use_hwaccel = false;
return -1;
}
+#endif
}
zm_av_packet_unref(&packet);
continue;
From 16e7ca5a513bfbe6542b11855795ef6d2458a87e Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Thu, 14 May 2020 12:01:24 -0400
Subject: [PATCH 15/45] failure opening a monitor should not be fatal.
---
src/zm_monitor.cpp | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp
index b2a3b56c5..d06baf271 100644
--- a/src/zm_monitor.cpp
+++ b/src/zm_monitor.cpp
@@ -555,14 +555,18 @@ bool Monitor::connect() {
snprintf(mem_file, sizeof(mem_file), "%s/zm.mmap.%d", staticConfig.PATH_MAP.c_str(), id);
map_fd = open(mem_file, O_RDWR|O_CREAT, (mode_t)0600);
if ( map_fd < 0 ) {
- Fatal("Can't open memory map file %s, probably not enough space free: %s", mem_file, strerror(errno));
+ Error("Can't open memory map file %s, probably not enough space free: %s", mem_file, strerror(errno));
+ return false;
} else {
Debug(3, "Success opening mmap file at (%s)", mem_file);
}
struct stat map_stat;
- if ( fstat(map_fd, &map_stat) < 0 )
- Fatal("Can't stat memory map file %s: %s, is the zmc process for this monitor running?", mem_file, strerror(errno));
+ if ( fstat(map_fd, &map_stat) < 0 ) {
+ Error("Can't stat memory map file %s: %s, is the zmc process for this monitor running?", mem_file, strerror(errno));
+ close(map_fd);
+ return false;
+ }
if ( map_stat.st_size != mem_size ) {
if ( purpose == CAPTURE ) {
From 25a772c5eb85e7f5045405f926e3bf258d7446aa Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Thu, 14 May 2020 12:02:02 -0400
Subject: [PATCH 16/45] reorder logic a bit to make it easier to read. Make
exit_zmu not return a value.
---
src/zmu.cpp | 459 ++++++++++++++++++++++++++--------------------------
1 file changed, 233 insertions(+), 226 deletions(-)
diff --git a/src/zmu.cpp b/src/zmu.cpp
index 33eb730e5..b5e951100 100644
--- a/src/zmu.cpp
+++ b/src/zmu.cpp
@@ -196,12 +196,12 @@ bool ValidateAccess(User *user, int mon_id, int function) {
return allowed;
}
-int exit_zmu(int exit_code) {
+void exit_zmu(int exit_code) {
logTerm();
+ printf("closing db\n");
zmDbClose();
exit(exit_code);
- return exit_code;
}
int main(int argc, char *argv[]) {
@@ -477,228 +477,233 @@ int main(int argc, char *argv[]) {
if ( mon_id > 0 ) {
Monitor *monitor = Monitor::Load(mon_id, function&(ZMU_QUERY|ZMU_ZONES), Monitor::QUERY);
- if ( monitor ) {
- if ( verbose ) {
- printf("Monitor %d(%s)\n", monitor->Id(), monitor->Name());
- }
- if ( !monitor->connect() ) {
- Error("Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name());
- exit_zmu(-1);
- }
+ if ( !monitor ) {
+ Error("Unable to load monitor %d", mon_id);
+ exit_zmu(-1);
+ } // end if ! MONITOR
- char separator = ' ';
- bool have_output = false;
- if ( function & ZMU_STATE ) {
- Monitor::State state = monitor->GetState();
- if ( verbose ) {
- printf("Current state: %s\n", state==Monitor::ALARM?"Alarm":(state==Monitor::ALERT?"Alert":"Idle"));
- } else {
- if ( have_output ) fputc(separator, stdout);
- printf("%d", state);
- have_output = true;
- }
- }
- if ( function & ZMU_TIME ) {
- struct timeval timestamp = monitor->GetTimestamp(image_idx);
- if ( verbose ) {
- char timestamp_str[64] = "None";
- if ( timestamp.tv_sec )
- strftime(timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S", localtime(×tamp.tv_sec));
- if ( image_idx == -1 )
- printf("Time of last image capture: %s.%02ld\n", timestamp_str, timestamp.tv_usec/10000);
- else
- printf("Time of image %d capture: %s.%02ld\n", image_idx, timestamp_str, timestamp.tv_usec/10000);
- } else {
- if ( have_output ) fputc(separator, stdout);
- printf("%ld.%02ld", timestamp.tv_sec, timestamp.tv_usec/10000);
- have_output = true;
- }
- }
- if ( function & ZMU_READ_IDX ) {
- if ( verbose )
- printf("Last read index: %d\n", monitor->GetLastReadIndex());
- else {
- if ( have_output ) fputc(separator, stdout);
- printf("%d", monitor->GetLastReadIndex());
- have_output = true;
- }
- }
- if ( function & ZMU_WRITE_IDX ) {
- if ( verbose ) {
- printf("Last write index: %d\n", monitor->GetLastWriteIndex());
- } else {
- if ( have_output ) fputc(separator, stdout);
- printf("%d", monitor->GetLastWriteIndex());
- have_output = true;
- }
- }
- if ( function & ZMU_EVENT ) {
- if ( verbose ) {
- printf("Last event id: %" PRIu64 "\n", monitor->GetLastEventId());
- } else {
- if ( have_output ) fputc(separator, stdout);
- printf("%" PRIu64, monitor->GetLastEventId());
- have_output = true;
- }
- }
- if ( function & ZMU_FPS ) {
- if ( verbose ) {
- printf("Current capture rate: %.2f frames per second\n", monitor->GetFPS());
- } else {
- if ( have_output ) fputc(separator, stdout);
- printf("%.2f", monitor->GetFPS());
- have_output = true;
- }
- }
- if ( function & ZMU_IMAGE ) {
- if ( verbose ) {
- if ( image_idx == -1 )
- printf("Dumping last image captured to Monitor%d.jpg", monitor->Id());
- else
- printf("Dumping buffer image %d to Monitor%d.jpg", image_idx, monitor->Id());
- if ( scale != -1 )
- printf(", scaling by %d%%", scale);
- printf("\n");
- }
- monitor->GetImage(image_idx, scale>0?scale:100);
- }
- if ( function & ZMU_ZONES ) {
- if ( verbose )
- printf("Dumping zone image to Zones%d.jpg\n", monitor->Id());
- monitor->DumpZoneImage(zoneString);
- }
- if ( function & ZMU_ALARM ) {
- if ( monitor->GetFunction() == Monitor::Function::MONITOR ) {
- printf("A Monitor in monitor mode cannot handle alarms. Please use NoDect\n");
- } else {
- Monitor::State state = monitor->GetState();
-
- if ( verbose ) {
- printf("Forcing alarm on current state: %s, event %" PRIu64 "\n",
- state==Monitor::ALARM?"Alarm":(state==Monitor::ALERT?"Alert":"Idle"),
- monitor->GetLastEventId()
- );
- }
- monitor->ForceAlarmOn(config.forced_alarm_score, "Forced Web");
- while ( ((state = monitor->GetState()) != Monitor::ALARM) && !zm_terminate ) {
- // Wait for monitor to notice.
- usleep(1000);
- }
- printf("Alarmed event id: %" PRIu64 "\n", monitor->GetLastEventId());
- } // end if ! MONITOR
- }
- if ( function & ZMU_NOALARM ) {
- if ( verbose )
- printf("Forcing alarm off\n");
- monitor->ForceAlarmOff();
- }
- if ( function & ZMU_CANCEL ) {
- if ( verbose )
- printf("Cancelling forced alarm on/off\n");
- monitor->CancelForced();
- }
- if ( function & ZMU_RELOAD ) {
- if ( verbose )
- printf("Reloading monitor settings\n");
- monitor->actionReload();
- }
- if ( function & ZMU_ENABLE ) {
- if ( verbose )
- printf("Enabling event generation\n");
- monitor->actionEnable();
- }
- if ( function & ZMU_DISABLE ) {
- if ( verbose )
- printf("Disabling event generation\n");
- monitor->actionDisable();
- }
- if ( function & ZMU_SUSPEND ) {
- if ( verbose )
- printf("Suspending event generation\n");
- monitor->actionSuspend();
- }
- if ( function & ZMU_RESUME ) {
- if ( verbose )
- printf("Resuming event generation\n");
- monitor->actionResume();
- }
- if ( function & ZMU_QUERY ) {
- char monString[16382] = "";
- monitor->DumpSettings(monString, verbose);
- printf("%s\n", monString);
- }
- if ( function & ZMU_BRIGHTNESS ) {
- if ( verbose ) {
- if ( brightness >= 0 )
- printf("New brightness: %d\n", monitor->actionBrightness(brightness));
- else
- printf("Current brightness: %d\n", monitor->actionBrightness());
- } else {
- if ( have_output ) fputc(separator, stdout);
- if ( brightness >= 0 )
- printf("%d", monitor->actionBrightness(brightness));
- else
- printf("%d", monitor->actionBrightness());
- have_output = true;
- }
- }
- if ( function & ZMU_CONTRAST ) {
- if ( verbose ) {
- if ( contrast >= 0 )
- printf("New brightness: %d\n", monitor->actionContrast(contrast));
- else
- printf("Current contrast: %d\n", monitor->actionContrast());
- } else {
- if ( have_output ) fputc(separator, stdout);
- if ( contrast >= 0 )
- printf("%d", monitor->actionContrast(contrast));
- else
- printf("%d", monitor->actionContrast());
- have_output = true;
- }
- }
- if ( function & ZMU_HUE ) {
- if ( verbose ) {
- if ( hue >= 0 )
- printf("New hue: %d\n", monitor->actionHue(hue));
- else
- printf("Current hue: %d\n", monitor->actionHue());
- } else {
- if ( have_output ) fputc(separator, stdout);
- if ( hue >= 0 )
- printf("%d", monitor->actionHue(hue));
- else
- printf("%d", monitor->actionHue());
- have_output = true;
- }
- }
- if ( function & ZMU_COLOUR ) {
- if ( verbose ) {
- if ( colour >= 0 )
- printf("New colour: %d\n", monitor->actionColour(colour));
- else
- printf("Current colour: %d\n", monitor->actionColour());
- } else {
- if ( have_output ) fputc(separator, stdout);
- if ( colour >= 0 )
- printf("%d", monitor->actionColour(colour));
- else
- printf("%d", monitor->actionColour());
- have_output = true;
- }
- }
- if ( have_output ) {
- printf("\n");
- }
- if ( !function ) {
- Usage();
- }
+ if ( verbose ) {
+ printf("Monitor %d(%s)\n", monitor->Id(), monitor->Name());
+ }
+ if ( !monitor->connect() ) {
+ Error("Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name());
delete monitor;
- } else {
- Error("Invalid monitor id %d", mon_id);
+ monitor = NULL;
exit_zmu(-1);
}
- } else {
+
+ char separator = ' ';
+ bool have_output = false;
+ if ( function & ZMU_STATE ) {
+ Monitor::State state = monitor->GetState();
+ if ( verbose ) {
+ printf("Current state: %s\n", state==Monitor::ALARM?"Alarm":(state==Monitor::ALERT?"Alert":"Idle"));
+ } else {
+ if ( have_output ) fputc(separator, stdout);
+ printf("%d", state);
+ have_output = true;
+ }
+ }
+ if ( function & ZMU_TIME ) {
+ struct timeval timestamp = monitor->GetTimestamp(image_idx);
+ if ( verbose ) {
+ char timestamp_str[64] = "None";
+ if ( timestamp.tv_sec )
+ strftime(timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S", localtime(×tamp.tv_sec));
+ if ( image_idx == -1 )
+ printf("Time of last image capture: %s.%02ld\n", timestamp_str, timestamp.tv_usec/10000);
+ else
+ printf("Time of image %d capture: %s.%02ld\n", image_idx, timestamp_str, timestamp.tv_usec/10000);
+ } else {
+ if ( have_output ) fputc(separator, stdout);
+ printf("%ld.%02ld", timestamp.tv_sec, timestamp.tv_usec/10000);
+ have_output = true;
+ }
+ }
+ if ( function & ZMU_READ_IDX ) {
+ if ( verbose )
+ printf("Last read index: %d\n", monitor->GetLastReadIndex());
+ else {
+ if ( have_output ) fputc(separator, stdout);
+ printf("%d", monitor->GetLastReadIndex());
+ have_output = true;
+ }
+ }
+ if ( function & ZMU_WRITE_IDX ) {
+ if ( verbose ) {
+ printf("Last write index: %d\n", monitor->GetLastWriteIndex());
+ } else {
+ if ( have_output ) fputc(separator, stdout);
+ printf("%d", monitor->GetLastWriteIndex());
+ have_output = true;
+ }
+ }
+ if ( function & ZMU_EVENT ) {
+ if ( verbose ) {
+ printf("Last event id: %" PRIu64 "\n", monitor->GetLastEventId());
+ } else {
+ if ( have_output ) fputc(separator, stdout);
+ printf("%" PRIu64, monitor->GetLastEventId());
+ have_output = true;
+ }
+ }
+ if ( function & ZMU_FPS ) {
+ if ( verbose ) {
+ printf("Current capture rate: %.2f frames per second\n", monitor->GetFPS());
+ } else {
+ if ( have_output ) fputc(separator, stdout);
+ printf("%.2f", monitor->GetFPS());
+ have_output = true;
+ }
+ }
+ if ( function & ZMU_IMAGE ) {
+ if ( verbose ) {
+ if ( image_idx == -1 )
+ printf("Dumping last image captured to Monitor%d.jpg", monitor->Id());
+ else
+ printf("Dumping buffer image %d to Monitor%d.jpg", image_idx, monitor->Id());
+ if ( scale != -1 )
+ printf(", scaling by %d%%", scale);
+ printf("\n");
+ }
+ monitor->GetImage(image_idx, scale>0?scale:100);
+ }
+ if ( function & ZMU_ZONES ) {
+ if ( verbose )
+ printf("Dumping zone image to Zones%d.jpg\n", monitor->Id());
+ monitor->DumpZoneImage(zoneString);
+ }
+ if ( function & ZMU_ALARM ) {
+ if ( monitor->GetFunction() == Monitor::Function::MONITOR ) {
+ printf("A Monitor in monitor mode cannot handle alarms. Please use NoDect\n");
+ } else {
+ Monitor::State state = monitor->GetState();
+
+ if ( verbose ) {
+ printf("Forcing alarm on current state: %s, event %" PRIu64 "\n",
+ state==Monitor::ALARM?"Alarm":(state==Monitor::ALERT?"Alert":"Idle"),
+ monitor->GetLastEventId()
+ );
+ }
+ monitor->ForceAlarmOn(config.forced_alarm_score, "Forced Web");
+ while ( ((state = monitor->GetState()) != Monitor::ALARM) && !zm_terminate ) {
+ // Wait for monitor to notice.
+ usleep(1000);
+ }
+ printf("Alarmed event id: %" PRIu64 "\n", monitor->GetLastEventId());
+ }
+ } // end if ZMU_ALARM
+
+ if ( function & ZMU_NOALARM ) {
+ if ( verbose )
+ printf("Forcing alarm off\n");
+ monitor->ForceAlarmOff();
+ }
+ if ( function & ZMU_CANCEL ) {
+ if ( verbose )
+ printf("Cancelling forced alarm on/off\n");
+ monitor->CancelForced();
+ }
+ if ( function & ZMU_RELOAD ) {
+ if ( verbose )
+ printf("Reloading monitor settings\n");
+ monitor->actionReload();
+ }
+ if ( function & ZMU_ENABLE ) {
+ if ( verbose )
+ printf("Enabling event generation\n");
+ monitor->actionEnable();
+ }
+ if ( function & ZMU_DISABLE ) {
+ if ( verbose )
+ printf("Disabling event generation\n");
+ monitor->actionDisable();
+ }
+ if ( function & ZMU_SUSPEND ) {
+ if ( verbose )
+ printf("Suspending event generation\n");
+ monitor->actionSuspend();
+ }
+ if ( function & ZMU_RESUME ) {
+ if ( verbose )
+ printf("Resuming event generation\n");
+ monitor->actionResume();
+ }
+ if ( function & ZMU_QUERY ) {
+ char monString[16382] = "";
+ monitor->DumpSettings(monString, verbose);
+ printf("%s\n", monString);
+ }
+ if ( function & ZMU_BRIGHTNESS ) {
+ if ( verbose ) {
+ if ( brightness >= 0 )
+ printf("New brightness: %d\n", monitor->actionBrightness(brightness));
+ else
+ printf("Current brightness: %d\n", monitor->actionBrightness());
+ } else {
+ if ( have_output ) fputc(separator, stdout);
+ if ( brightness >= 0 )
+ printf("%d", monitor->actionBrightness(brightness));
+ else
+ printf("%d", monitor->actionBrightness());
+ have_output = true;
+ }
+ }
+ if ( function & ZMU_CONTRAST ) {
+ if ( verbose ) {
+ if ( contrast >= 0 )
+ printf("New brightness: %d\n", monitor->actionContrast(contrast));
+ else
+ printf("Current contrast: %d\n", monitor->actionContrast());
+ } else {
+ if ( have_output ) fputc(separator, stdout);
+ if ( contrast >= 0 )
+ printf("%d", monitor->actionContrast(contrast));
+ else
+ printf("%d", monitor->actionContrast());
+ have_output = true;
+ }
+ }
+ if ( function & ZMU_HUE ) {
+ if ( verbose ) {
+ if ( hue >= 0 )
+ printf("New hue: %d\n", monitor->actionHue(hue));
+ else
+ printf("Current hue: %d\n", monitor->actionHue());
+ } else {
+ if ( have_output ) fputc(separator, stdout);
+ if ( hue >= 0 )
+ printf("%d", monitor->actionHue(hue));
+ else
+ printf("%d", monitor->actionHue());
+ have_output = true;
+ }
+ }
+ if ( function & ZMU_COLOUR ) {
+ if ( verbose ) {
+ if ( colour >= 0 )
+ printf("New colour: %d\n", monitor->actionColour(colour));
+ else
+ printf("Current colour: %d\n", monitor->actionColour());
+ } else {
+ if ( have_output ) fputc(separator, stdout);
+ if ( colour >= 0 )
+ printf("%d", monitor->actionColour(colour));
+ else
+ printf("%d", monitor->actionColour());
+ have_output = true;
+ }
+ }
+
+ if ( have_output ) {
+ printf("\n");
+ }
+ if ( !function ) {
+ Usage();
+ }
+ delete monitor;
+ monitor = NULL;
+ } else { // non monitor functions
if ( function & ZMU_QUERY ) {
#if ZM_HAS_V4L
char vidString[0x10000] = "";
@@ -712,11 +717,11 @@ int main(int argc, char *argv[]) {
}
if ( function & ZMU_LIST ) {
- std::string sql = "select Id, Function+0 from Monitors";
+ std::string sql = "SELECT Id, `Function`+0 FROM Monitors";
if ( !verbose ) {
- sql += "where Function != 'None'";
+ sql += "WHERE `Function` != 'None'";
}
- sql += " order by Id asc";
+ sql += " ORDER BY Id ASC";
if ( mysql_query(&dbconn, sql.c_str()) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
@@ -770,8 +775,10 @@ int main(int argc, char *argv[]) {
} // end foreach row
mysql_free_result(result);
} // end if function && ZMU_LIST
- }
+ } // end if monitor id or not
delete user;
- return exit_zmu(0);
-}
+ printf("Exiting");
+ exit_zmu(0);
+ return 0;
+} // end int main()
From 4fed2d6d267ff849de73e9971cb1062334a663db Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Thu, 14 May 2020 12:20:14 -0400
Subject: [PATCH 17/45] bump version to 1.34.13 for release
---
distros/redhat/zoneminder.spec | 2 +-
version | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec
index 10fd82e4f..73f66e958 100644
--- a/distros/redhat/zoneminder.spec
+++ b/distros/redhat/zoneminder.spec
@@ -28,7 +28,7 @@
%global _hardened_build 1
Name: zoneminder
-Version: 1.34.12
+Version: 1.34.13
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons
diff --git a/version b/version
index 7355e24bb..9c9f16d07 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-1.34.12
+1.34.13
From 7a85be59be946cf9605360deaddd8b4c7fe45f42 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Fri, 15 May 2020 10:22:58 -0400
Subject: [PATCH 18/45] Remove errant closing db debug output
---
src/zmu.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/zmu.cpp b/src/zmu.cpp
index b5e951100..ef8a9276e 100644
--- a/src/zmu.cpp
+++ b/src/zmu.cpp
@@ -198,7 +198,6 @@ bool ValidateAccess(User *user, int mon_id, int function) {
void exit_zmu(int exit_code) {
logTerm();
- printf("closing db\n");
zmDbClose();
exit(exit_code);
From 94b29c6c7a86ab51671ea9a3b0ad13a69f6b58db Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Fri, 15 May 2020 10:44:48 -0400
Subject: [PATCH 19/45] replace inline javascript in timeline zoom
---
web/api/app/Plugin/Crud | 2 +-
web/skins/classic/views/js/timeline.js | 5 ++++-
web/skins/classic/views/timeline.php | 4 ++--
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/web/api/app/Plugin/Crud b/web/api/app/Plugin/Crud
index 0bd63fb46..c3976f147 160000
--- a/web/api/app/Plugin/Crud
+++ b/web/api/app/Plugin/Crud
@@ -1 +1 @@
-Subproject commit 0bd63fb464957080ead342db58ca9e01532cf1ef
+Subproject commit c3976f1478c681b0bbc132ec3a3e82c3984eeed5
diff --git a/web/skins/classic/views/js/timeline.js b/web/skins/classic/views/js/timeline.js
index 8d3f01d4c..cbebfc0d7 100644
--- a/web/skins/classic/views/js/timeline.js
+++ b/web/skins/classic/views/js/timeline.js
@@ -179,7 +179,10 @@ function loadEventImage( imagePath, eid, fid, width, height, fps, videoName, dur
eventData.addEvent('click', showEvent.pass());
}
-function tlZoomBounds( minTime, maxTime ) {
+function tlZoomBounds(event) {
+ var target = event.target;
+ var minTime = target.getAttribute('data-zoom-min-time');
+ var maxTime = target.getAttribute('data-zoom-max-time');
location.replace('?view='+currentView+filterQuery+'&minTime='+minTime+'&maxTime='+maxTime);
}
diff --git a/web/skins/classic/views/timeline.php b/web/skins/classic/views/timeline.php
index 794b99c20..2f1218b3e 100644
--- a/web/skins/classic/views/timeline.php
+++ b/web/skins/classic/views/timeline.php
@@ -616,7 +616,7 @@ function drawXGrid( $chart, $scale, $labelClass, $tickClass, $gridClass, $zoomCl
$zoomMinTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($lastTick * $chart['data']['x']['density'])) );
$zoomMaxTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($i * $chart['data']['x']['density'])) );
?>
-
+
-
+
From 0dd426d64ce207a97cb2b8b529283176b6dcc527 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Fri, 15 May 2020 11:33:10 -0400
Subject: [PATCH 20/45] handle range being set to an empty value. Fixes zoom
out on timeline. Fix on-click to data-on-click
---
web/skins/classic/views/timeline.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/web/skins/classic/views/timeline.php b/web/skins/classic/views/timeline.php
index 2f1218b3e..cab313f52 100644
--- a/web/skins/classic/views/timeline.php
+++ b/web/skins/classic/views/timeline.php
@@ -154,7 +154,7 @@ if ( isset($_REQUEST['midTime']) )
if ( isset($_REQUEST['maxTime']) )
$maxTime = validHtmlStr($_REQUEST['maxTime']);
-if ( isset($range) ) {
+if ( isset($range) and validInt($range) ) {
$halfRange = (int)($range/2);
if ( isset($midTime) ) {
$midTimeT = strtotime($midTime);
@@ -616,7 +616,7 @@ function drawXGrid( $chart, $scale, $labelClass, $tickClass, $gridClass, $zoomCl
$zoomMinTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($lastTick * $chart['data']['x']['density'])) );
$zoomMaxTime = strftime( STRF_FMT_DATETIME_DB, (int)($chart['data']['x']['lo'] + ($i * $chart['data']['x']['density'])) );
?>
-
+
-
+
From 424a4ed0b12579f50fe92e3e69dd9b0e4b1db032 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Fri, 15 May 2020 11:34:23 -0400
Subject: [PATCH 21/45] add onclick to div.zoom
---
web/skins/classic/views/js/timeline.js | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/web/skins/classic/views/js/timeline.js b/web/skins/classic/views/js/timeline.js
index cbebfc0d7..0b4d1d5fc 100644
--- a/web/skins/classic/views/js/timeline.js
+++ b/web/skins/classic/views/js/timeline.js
@@ -36,14 +36,14 @@ function createEventHtml(zm_event, frame) {
return eventHtml;
}
-function showEventDetail( eventHtml ) {
- $('instruction').addClass( 'hidden' );
+function showEventDetail(eventHtml) {
+ $('instruction').addClass('hidden');
$('eventData').empty();
- $('eventData').adopt( eventHtml );
- $('eventData').removeClass( 'hidden' );
+ $('eventData').adopt(eventHtml);
+ $('eventData').removeClass('hidden');
}
-function eventDataResponse( respObj, respText ) {
+function eventDataResponse(respObj, respText) {
var zm_event = respObj.event;
if ( !zm_event ) {
console.log('Null event');
@@ -197,14 +197,18 @@ function tlPanRight() {
location.replace('?view='+currentView+filterQuery+'&midTime='+maxTime+'&range='+range);
}
-window.addEventListener("DOMContentLoaded", function() {
- document.querySelectorAll("div.event").forEach(function(el) {
+window.addEventListener('DOMContentLoaded', function() {
+ // These look like the code in skin.js, but that code doesn't select for divs.
+ document.querySelectorAll('div.event').forEach(function(el) {
el.onclick = window[el.getAttribute('data-on-click-this')].bind(el, el);
el.onmouseover = window[el.getAttribute('data-on-mouseover-this')].bind(el, el);
});
- document.querySelectorAll("div.activity").forEach(function(el) {
+ document.querySelectorAll('div.activity').forEach(function(el) {
el.onclick = window[el.getAttribute('data-on-click-this')].bind(el, el);
el.onmouseover = window[el.getAttribute('data-on-mouseover-this')].bind(el, el);
});
+ document.querySelectorAll('div.zoom').forEach(function(el) {
+ el.onclick = function(ev) { window[el.getAttribute('data-on-click')](ev); };
+ });
});
From c4c4c5bcbfa3aeb94f1f0947c0757f02750b2440 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Fri, 15 May 2020 11:34:34 -0400
Subject: [PATCH 22/45] fix Crud submodule version
---
web/api/app/Plugin/Crud | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/web/api/app/Plugin/Crud b/web/api/app/Plugin/Crud
index c3976f147..0bd63fb46 160000
--- a/web/api/app/Plugin/Crud
+++ b/web/api/app/Plugin/Crud
@@ -1 +1 @@
-Subproject commit c3976f1478c681b0bbc132ec3a3e82c3984eeed5
+Subproject commit 0bd63fb464957080ead342db58ca9e01532cf1ef
From f79a17f3023169afee9adde5fc0d179aec14d928 Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Fri, 15 May 2020 11:35:59 -0400
Subject: [PATCH 23/45] Bump version to 1.34.14 for release
---
distros/redhat/zoneminder.spec | 2 +-
version | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec
index 73f66e958..c3458074c 100644
--- a/distros/redhat/zoneminder.spec
+++ b/distros/redhat/zoneminder.spec
@@ -28,7 +28,7 @@
%global _hardened_build 1
Name: zoneminder
-Version: 1.34.13
+Version: 1.34.14
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons
diff --git a/version b/version
index 9c9f16d07..46a99f18d 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-1.34.13
+1.34.14
From 9ea1c637f96a5de2ac8f17778abf54e9fece0b7d Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Fri, 15 May 2020 11:48:41 -0400
Subject: [PATCH 24/45] Remove debug Exiting message
---
src/zmu.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/zmu.cpp b/src/zmu.cpp
index ef8a9276e..d3e9d96c5 100644
--- a/src/zmu.cpp
+++ b/src/zmu.cpp
@@ -777,7 +777,6 @@ int main(int argc, char *argv[]) {
} // end if monitor id or not
delete user;
- printf("Exiting");
exit_zmu(0);
return 0;
} // end int main()
From 4dc693022e4bd0f7afd3142b1210faa958a4892d Mon Sep 17 00:00:00 2001
From: Isaac Connor
Date: Fri, 15 May 2020 16:02:19 -0400
Subject: [PATCH 25/45] Failure to parse output shouldn't be fatal. Just skp
to the next instead. Use json_encode instead of serialize
---
web/skins/classic/views/monitorprobe.php | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/web/skins/classic/views/monitorprobe.php b/web/skins/classic/views/monitorprobe.php
index 9cab32b3e..a76c67810 100644
--- a/web/skins/classic/views/monitorprobe.php
+++ b/web/skins/classic/views/monitorprobe.php
@@ -39,16 +39,18 @@ function probeV4L() {
}
$monitors = array();
- foreach ( dbFetchAll("SELECT Id, Name, Device,Channel FROM Monitors WHERE Type = 'Local' ORDER BY Device, Channel" ) as $monitor )
+ foreach ( dbFetchAll("SELECT Id, Name, Device, Channel FROM Monitors WHERE Type = 'Local' ORDER BY Device, Channel" ) as $monitor )
$monitors[$monitor['Device'].':'.$monitor['Channel']] = $monitor;
$devices = array();
$preferredStandards = array('PAL', 'NTSC');
$preferredFormats = array('BGR3', 'RGB3', 'YUYV', 'UYVY', 'JPEG', 'MJPG', '422P', 'YU12', 'GREY');
foreach ( $output as $line ) {
- if ( !preg_match('/^d:([^|]+).*S:([^|]*).*F:([^|]+).*I:(\d+)\|(.+)$/', $line, $deviceMatches) )
- ZM\Fatal("Can't parse command output '$line'");
- $standards = explode('/',$deviceMatches[2]);
+ if ( !preg_match('/^d:([^|]+).*S:([^|]*).*F:([^|]+).*I:(\d+)\|(.+)$/', $line, $deviceMatches) ) {
+ ZM\Error("Can't parse command output '$line'");
+ continue;
+ }
+ $standards = explode('/', $deviceMatches[2]);
$preferredStandard = false;
foreach ( $preferredStandards as $standard ) {
if ( in_array( $standard, $standards ) ) {
@@ -56,7 +58,7 @@ function probeV4L() {
break;
}
}
- $formats = explode('/',$deviceMatches[3]);
+ $formats = explode('/', $deviceMatches[3]);
$preferredFormat = false;
foreach ( $preferredFormats as $format ) {
if ( in_array($format, $formats) ) {
@@ -73,8 +75,10 @@ function probeV4L() {
);
$inputs = array();
for ( $i = 0; $i < $deviceMatches[4]; $i++ ) {
- if ( !preg_match('/i'.$i.':([^|]+)\|i'.$i.'T:([^|]+)\|/', $deviceMatches[5], $inputMatches) )
- ZM\Fatal("Can't parse input '".$deviceMatches[5]."'");
+ if ( !preg_match('/i'.$i.':([^|]+)\|i'.$i.'T:([^|]+)\|/', $deviceMatches[5], $inputMatches) ) {
+ ZM\Error("Can't parse input '".$deviceMatches[5]."'");
+ continue;
+ }
if ( $inputMatches[2] == 'Camera' ) {
$input = array(
'index' => $i,
@@ -101,7 +105,7 @@ function probeV4L() {
$inputMonitor['Colours'] = 1;
$inputMonitor['SignalCheckColour'] = '#000023';
}
- $inputDesc = base64_encode(serialize($inputMonitor));
+ $inputDesc = base64_encode(json_encode($inputMonitor));
$inputString = $deviceMatches[1].', chan '.$i.($input['free']?(' - '.translate('Available')):(' ('.$monitors[$input['id']]['Name'].')'));
$inputs[] = $input;
$cameras[$inputDesc] = $inputString;
@@ -288,7 +292,7 @@ function probeNetwork() {
if ( isset($macBases[$macRoot]) ) {
$macBase = $macBases[$macRoot];
$camera = call_user_func($macBase['probeFunc'], $ip);
- $sourceDesc = base64_encode(serialize($camera['monitor']));
+ $sourceDesc = base64_encode(json_encode($camera['monitor']));
$sourceString = $camera['model'].' @ '.$host;
if ( isset($monitors[$ip]) ) {
$monitor = $monitors[$ip];
@@ -330,7 +334,7 @@ xhtmlHeaders(__FILE__, translate('MonitorProbe') );
-
+ 'configureButtons(this)')); ?>