From 833ae0ee8f33919ab550fe914ee4a53b475dd7cf Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 11 Dec 2017 15:09:41 -0500 Subject: [PATCH 001/154] alter the type of the Channel field to match the update that occurred in 1.23.3 --- db/zm_create.sql.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 157c55a06..826d775a6 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -291,7 +291,7 @@ CREATE TABLE `MonitorPresets` ( `Name` varchar(64) NOT NULL default '', `Type` enum('Local','Remote','File','Ffmpeg','Libvlc','cURL') NOT NULL default 'Local', `Device` tinytext, - `Channel` tinytext, + `Channel` tinyint(3) unsigned default NULL, `Format` int(10) unsigned default NULL, `Protocol` varchar(16) default NULL, `Method` varchar(16) default NULL, From b017394961dfd8a640d41e57156f2798a02f7aa4 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Wed, 13 Dec 2017 15:49:31 -0600 Subject: [PATCH 002/154] Remove Fedora 25 support from build system --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 916cd5a98..52ba2d486 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,6 @@ env: - OS=el DIST=6 - OS=el DIST=6 ARCH=i386 DOCKER_REPO=knnniggett/packpack - OS=el DIST=7 - - OS=fedora DIST=25 - OS=fedora DIST=26 DOCKER_REPO=knnniggett/packpack - OS=fedora DIST=27 DOCKER_REPO=knnniggett/packpack - OS=ubuntu DIST=trusty From bc096bcc3d6294235a1fd6e87a970bb8ae6b6cf6 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Thu, 14 Dec 2017 14:14:31 -0600 Subject: [PATCH 003/154] make zoneminder rpm depend on zip package --- distros/redhat/zoneminder.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index fc6a0c7ab..10ce1ff0a 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -110,6 +110,7 @@ Requires: perl(Net::SMTP) Requires: perl(Net::FTP) Requires: perl(LWP::Protocol::https) Requires: ca-certificates +Requires: zip %{?with_init_systemd:Requires(post): systemd} %{?with_init_systemd:Requires(post): systemd-sysv} From 0fa11d7c366b817e61a4192a2f2037ee53ee56a9 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 22 Dec 2017 12:32:45 -0800 Subject: [PATCH 004/154] make montagereview load event images from the server that the storage is located on --- web/includes/functions.php | 1 + web/skins/classic/views/js/montagereview.js | 13 +++++++++++-- web/skins/classic/views/js/montagereview.js.php | 15 +++++++++++++-- web/skins/classic/views/montagereview.php | 2 +- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/web/includes/functions.php b/web/includes/functions.php index 10ee34015..fed583f03 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -1280,6 +1280,7 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) { $filter['sql'] .= ' not regexp '.$value; break; case '=[]' : + case 'IN' : $filter['sql'] .= ' in ('.join( ',', $valueList ).')'; break; case '![]' : diff --git a/web/skins/classic/views/js/montagereview.js b/web/skins/classic/views/js/montagereview.js index 0c0237f85..e1f854f66 100644 --- a/web/skins/classic/views/js/montagereview.js +++ b/web/skins/classic/views/js/montagereview.js @@ -55,7 +55,17 @@ function SetImageSource( monId, time ) { if ( eMonId[i] == monId && time >= eStartSecs[i] && time <= eEndSecs[i] ) { var duration = eEndSecs[i]-eStartSecs[i]; var frame = parseInt((time - eStartSecs[i])/(duration)*eventFrames[i])+1; -console.log("SetImageSource: " + time + " duration: " + duration + " frame: " + frame ); + var storage = Storage[eStorageId[i]]; + if ( storage.ServerId ) { + var server = Servers[storage.ServerId]; + if ( server ) { +console.log( server.Hostname + " for event " + eId[i] ); + return location.protocol + '//' + server.Hostname + '/index.php?view=image&eid=' + eId[i] + '&fid='+frame + "&width=" + monitorCanvasObj[monId].width + "&height=" + monitorCanvasObj[monId].height; + } else { + console.log("No server found for " + storage.ServerId ); + } + } + console.log("No storage found for " + eStorageId[i] ); return "index.php?view=image&eid=" + eId[i] + '&fid='+frame + "&width=" + monitorCanvasObj[monId].width + "&height=" + monitorCanvasObj[monId].height; } } // end for @@ -465,7 +475,6 @@ function setSpeed( speed_index ) { currentSpeed = parseFloat(speeds[speed_index]); speedIndex = speed_index; playSecsperInterval = Math.floor( 1000 * currentSpeed * currentDisplayInterval ) / 1000000; -console.log("playSecsPerInterval: " + playSecsperInterval + " = currentspeed:" + currentSpeed + " * " + currentDisplayInterval + " /1000"); showSpeed(speed_index); if ( timerInterval != currentDisplayInterval || currentSpeed == 0 ) timerFire(); // if the timer isn't firing we need to trigger it to update } diff --git a/web/skins/classic/views/js/montagereview.js.php b/web/skins/classic/views/js/montagereview.js.php index b1988ed86..19089a315 100644 --- a/web/skins/classic/views/js/montagereview.js.php +++ b/web/skins/classic/views/js/montagereview.js.php @@ -23,6 +23,7 @@ var imageLoadTimesNeeded=15; // and how many we need var timeLabelsFractOfRow = 0.9; var eMonId = []; var eId = []; +var eStorageId = []; var eStartSecs = []; var eEndSecs = []; var eventFrames = []; // this is going to presume all frames equal durationlength @@ -43,7 +44,6 @@ $index = 0; $anyAlarms = false; if ( ! $initialModeIsLive ) { -Warning($eventsSql); $result = dbQuery( $eventsSql ); if ( ! $result ) { Fatal('SQL-ERR'); @@ -56,6 +56,7 @@ Warning($eventsSql); if ( $maxTimeSecs < $event['CalcEndTimeSecs'] ) $maxTimeSecs = $event['CalcEndTimeSecs']; echo " eMonId[$index]=" . $event['MonitorId'] . "; +eStorageId[$index]=".$event['StorageId'] . "; eId[$index]=" . $event['Id'] . "; eStartSecs[$index]=" . $event['StartTimeSecs'] . "; eEndSecs[$index]=" . $event['CalcEndTimeSecs'] . "; @@ -146,7 +147,17 @@ if ( $mId > 0 ) { echo "var maxScore=$maxScore;\n"; // used to skip frame load if we find no alarms. } // end if initialmodeislive -echo "var monitorName = [];\n"; + +echo "var Storage = []\n"; +foreach ( Storage::find_all() as $Storage ) { +echo 'Storage[' . $Storage->Id() . '] = ' . json_encode($Storage). ";\n"; +} +echo "var Servers = []\n"; +foreach ( Server::find_all() as $Server ) { +echo 'Servers[' . $Server->Id() . '] = ' . json_encode($Server). ";\n"; +} +echo " +var monitorName = [];\n"; echo "var monitorLoading = [];\n"; echo "var monitorImageObject = [];\n"; echo "var monitorImageURL = [];\n"; diff --git a/web/skins/classic/views/montagereview.php b/web/skins/classic/views/montagereview.php index 3452b2f5f..56dadabd1 100644 --- a/web/skins/classic/views/montagereview.php +++ b/web/skins/classic/views/montagereview.php @@ -94,7 +94,7 @@ if (isset($_REQUEST['minTime']) && isset($_REQUEST['maxTime']) && count($display // Note we round up just a bit on the end time as otherwise you get gaps, like 59.78 to 00 in the next second, which can give blank frames when moved through slowly. $eventsSql = ' - SELECT E.Id,E.Name,UNIX_TIMESTAMP(E.StartTime) AS StartTimeSecs, + SELECT E.Id,E.Name,E.StorageId,UNIX_TIMESTAMP(E.StartTime) AS StartTimeSecs, CASE WHEN E.EndTime IS NULL THEN (SELECT UNIX_TIMESTAMP(DATE_ADD(E.StartTime, Interval max(Delta)+0.5 Second)) FROM Frames F WHERE F.EventId=E.Id) ELSE UNIX_TIMESTAMP(E.EndTime) END AS CalcEndTimeSecs, E.Length, From 7f44fb67e82550fd383fe40880cf592e20805027 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 2 Jan 2018 12:44:17 -0800 Subject: [PATCH 005/154] treat File exists as a non-error --- scripts/ZoneMinder/lib/ZoneMinder/Event.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm index 4bf71fa82..52a25ad17 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm @@ -457,10 +457,11 @@ sub MoveTo { if ( @$err ) { for my $diag (@$err) { my ($file, $message) = %$diag; + next if $message eq 'File exists'; if ($file eq '') { $error .= "general error: $message\n"; } else { - $error .= "problem unlinking $file: $message\n"; + $error .= "problem making $file: $message\n"; } } } From 3ac73a9d6cf1f997932987d16dab34d8ab4c6b70 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 5 Jan 2018 10:01:30 -0800 Subject: [PATCH 006/154] switch to updating event counts for all monitors --- scripts/zmwatch.pl.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/zmwatch.pl.in b/scripts/zmwatch.pl.in index 2fc1b26be..da1a1643c 100644 --- a/scripts/zmwatch.pl.in +++ b/scripts/zmwatch.pl.in @@ -108,17 +108,18 @@ UPDATE Monitors INNER JOIN ( Monitors.WeekEventDiskSpace = E.WeekEventDiskSpace, Monitors.MonthEvents = E.MonthEvents, Monitors.MonthEventDiskSpace = E.MonthEventDiskSpace - WHERE Id=? `; my $eventcounts_sth = $dbh->prepare_cached( $eventcounts_sql ); while( 1 ) { + $eventcounts_sth->execute() or Error( "Can't execute: ".$eventcounts_sth->errstr() ); + $eventcounts_sth->finish(); + my $res = $sth->execute( $Config{ZM_SERVER_ID} ? $Config{ZM_SERVER_ID} : () ) or Fatal( "Can't execute: ".$sth->errstr() ); while( my $monitor = $sth->fetchrow_hashref() ) { - $eventcounts_sth->execute( $$monitor{Id} ) or Error( "Can't execute: ".$eventcounts_sth->errstr() ); my $now = time(); next if $monitor->{Function} eq 'None'; @@ -215,7 +216,6 @@ while( 1 ) { } # end foreach monitor - $eventcounts_sth->finish(); sleep( $Config{ZM_WATCH_CHECK_INTERVAL} ); } # end while (1) From d8323a4dacf46eb405071f25b68d0fc73b044470 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Jan 2018 07:28:57 -0800 Subject: [PATCH 007/154] When server is NULL, don't escape the NULL --- scripts/ZoneMinder/lib/ZoneMinder/Filter.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm index 1491f05ef..ed5779b2b 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm @@ -213,6 +213,8 @@ sub Sql { $value = "'$ZoneMinder::Config::Config{ZM_SERVER_ID}'"; # This gets used later, I forget for what $$self{Server} = new ZoneMinder::Server( $ZoneMinder::Config::Config{ZM_SERVER_ID} ); + } elsif ( $temp_value eq 'NULL' ) { + $value = $temp_value; } else { $value = "'$temp_value'"; # This gets used later, I forget for what From 80f0515eae53e608a9288dafcfcc99ab0ae0440c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Jan 2018 09:15:55 -0800 Subject: [PATCH 008/154] break after sending kill --- scripts/zmdc.pl.in | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/zmdc.pl.in b/scripts/zmdc.pl.in index 5d422bb3f..2bbd89f5d 100644 --- a/scripts/zmdc.pl.in +++ b/scripts/zmdc.pl.in @@ -511,6 +511,7 @@ sub kill_until_dead { .". Sending KILL to pid $$process{pid}\n" ); kill( 'KILL', $$process{pid} ); + break; } sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n"; From 5db41803271454b237c4b6ba86b550eadd5c92ba Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 9 Jan 2018 13:21:15 -0800 Subject: [PATCH 009/154] Better logging, test for path existence before DiskSpace update. Fix delete_files when moving --- scripts/ZoneMinder/lib/ZoneMinder/Event.pm | 36 +++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm index 52a25ad17..5c058690a 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm @@ -367,11 +367,11 @@ sub delete_files { Error("No monitor id assigned to event $$event{Id}"); return; } - my $event_path = $event->Path(); - Debug("Deleting files for Event $$event{Id} from $event_path."); + my $event_path = $event->RelativePath(); + Debug("Deleting files for Event $$event{Id} from $storage_path/$event_path."); if ( $event_path ) { - ( $event_path ) = ( $event_path =~ /^(.*)$/ ); # De-taint - my $command = "/bin/rm -rf $event_path"; + #( $event_path ) = ( $event_path =~ /^(.*)$/ ); # De-taint + my $command = "/bin/rm -rf $storage_path/$event_path"; ZoneMinder::General::executeShellCommand( $command ); } @@ -380,7 +380,7 @@ sub delete_files { Debug("Deleting files for Event $$event{Id} from $storage_path/$link_path."); if ( $link_path ) { ( $link_path ) = ( $link_path =~ /^(.*)$/ ); # De-taint - unlink( $storage_path.'/'.$link_path ) or Error( "Unable to unlink '$storage_path/$link_path': $!" ); + unlink( $storage_path.'/'.$link_path ) or Error( "Unable to unlink '$storage_path/$link_path': $!" ); } } } # end sub delete_files @@ -395,11 +395,15 @@ sub Storage { sub check_for_in_filesystem { my $path = $_[0]->Path(); if ( $path ) { - my @files = glob( $path . '/*' ); -Debug("Checking for files for event $_[0]{Id} at $path using glob $path/* found " . scalar @files . " files"); - return 1 if @files; + if ( -e $path ) { + my @files = glob "$path/*"; + Debug("Checking for files for event $_[0]{Id} at $path using glob $path/* found " . scalar @files . " files"); + return 1 if @files; + } else { + Warning("Path not found for Event $_[0]{Id} at $path"); + } } -Debug("Checking for files for event $_[0]{Id} at $path using glob $path/* found no files"); + Debug("Checking for files for event $_[0]{Id} at $path using glob $path/* found no files"); return 0; } @@ -421,11 +425,15 @@ sub DiskSpace { $_[0]{DiskSpace} = $_[1]; } if ( ! defined $_[0]{DiskSpace} ) { - my $size = 0; - File::Find::find( { wanted=>sub { $size += -f $_ ? -s _ : 0 }, untaint=>1 }, $_[0]->Path() ); - $_[0]{DiskSpace} = $size; - Debug("DiskSpace for event $_[0]{Id} at $_[0]{Path} Updated to $size bytes"); - } + if ( -e $_[0]->Path() ) { + my $size = 0; + File::Find::find( { wanted=>sub { $size += -f $_ ? -s _ : 0 }, untaint=>1 }, $_[0]->Path() ); + $_[0]{DiskSpace} = $size; + Debug("DiskSpace for event $_[0]{Id} at $_[0]{Path} Updated to $size bytes"); + } else { + Warning("Event does not exist at $_[0]{Path}"); + } + } # end if ! defined DiskSpace } sub MoveTo { From 90d7fee8bb39c7f51df0ddb37621d58c6da6be64 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 11 Jan 2018 19:14:37 -0800 Subject: [PATCH 010/154] use last, not break --- scripts/zmdc.pl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/zmdc.pl.in b/scripts/zmdc.pl.in index 104de3982..e717ec1ea 100644 --- a/scripts/zmdc.pl.in +++ b/scripts/zmdc.pl.in @@ -533,7 +533,7 @@ sub kill_until_dead { .". Sending KILL to pid $$process{pid}\n" ); kill( 'KILL', $$process{pid} ); - break; + last; } sigprocmask(SIG_UNBLOCK, $blockset) or die "dying at unblock...\n"; From e2ac13d03e6f59e7f7fd5bda42f36ec76a44a856 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 12 Jan 2018 08:10:46 -0800 Subject: [PATCH 011/154] pretty up the add_monitors interface a bit, add some instructions --- web/skins/classic/views/add_monitors.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/add_monitors.php b/web/skins/classic/views/add_monitors.php index b77c048d5..f73a22864 100644 --- a/web/skins/classic/views/add_monitors.php +++ b/web/skins/classic/views/add_monitors.php @@ -44,6 +44,11 @@ xhtmlHeaders(__FILE__, translate('AddMonitors'));
Enter by IP or URL +

+Simply enter the ip address or full url to the stream. +It will be probed for available streams, or checked to see if it has already been entered. +If streams are found, they will be listed in the results column. Click Add to add them. +

@@ -61,7 +66,9 @@ xhtmlHeaders(__FILE__, translate('AddMonitors')); MN1 +

Defaults to apply to each monitor:
+

SettingValue
- +
From 95c3c26edaf1664d3a23486e55e64987f4b7439a Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 12 Jan 2018 08:11:07 -0800 Subject: [PATCH 012/154] cleanup old Add Monitr button --- web/skins/classic/views/console.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index c8ec29020..a8a693bb7 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -271,8 +271,9 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { - - + + /> From ff9f43b5a1b87c2fdd9871e483a21ec8849558a7 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 12 Jan 2018 08:11:25 -0800 Subject: [PATCH 013/154] put back code to switch to add_monitors --- web/skins/classic/views/js/console.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/js/console.js b/web/skins/classic/views/js/console.js index 8a7342897..2121b6e39 100644 --- a/web/skins/classic/views/js/console.js +++ b/web/skins/classic/views/js/console.js @@ -34,8 +34,11 @@ function addMonitor(element) { } } } - dupParam = (monitorId == -1 ) ? '': '&dupId='+monitorId; - createPopup( '?view=monitor'+dupParam, 'zmMonitor0', 'monitor' ); + if ( monitorId != -1 ) { + createPopup( '?view=monitor&dupId='+monitorId, 'zmMonitor0', 'monitor' ); + } else { + window.location = '?view=add_monitors'; + } } function editMonitor( element ) { From 5f8756d7ada4ecf8a2469e9c66e35c0cb73c5407 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 12 Jan 2018 08:11:37 -0800 Subject: [PATCH 014/154] Set Tesla defaults for new monitors --- web/skins/classic/views/monitor.php | 38 ++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index 7e240092b..72ffa746c 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -72,11 +72,11 @@ if ( ! $monitor ) { $monitor->set( array( 'Id' => 0, 'Name' => translate('Monitor').'-'.$nextId, - 'Function' => 'Monitor', + 'Function' => 'Mocord', 'Enabled' => true, 'LinkedMonitors' => '', - 'Type' => '', - 'Device' => "/dev/video0", + 'Type' => 'Ffmpeg', + 'Device' => '/dev/video0', 'Channel' => '0', 'Format' => 0x000000ff, 'Protocol' => '', @@ -87,26 +87,26 @@ if ( ! $monitor ) { 'Port' => '80', 'User' => '', 'Pass' => '', - 'Colours' => 3, + 'Colours' => 4, 'Palette' => 0, - 'Width' => '320', - 'Height' => '240', + 'Width' => '1280', + 'Height' => '962', 'Orientation' => '0', 'Deinterlacing' => 0, 'RTSPDescribe' => 0, - 'SaveJPEGs' => '3', - 'VideoWriter' => '0', + 'SaveJPEGs' => '4', + 'VideoWriter' => '1', 'EncoderParameters' => "# Lines beginning with # are a comment \n# For changing quality, use the crf option\n# 1 is best, 51 is worst quality\n#crf=23\n", 'RecordAudio' => '0', 'LabelFormat' => '%N - %d/%m/%y %H:%M:%S', 'LabelX' => 0, 'LabelY' => 0, 'LabelSize' => 1, - 'ImageBufferCount' => 50, - 'WarmupCount' => 25, - 'PreEventCount' => 25, - 'PostEventCount' => 25, - 'StreamReplayBuffer' => 1000, + 'ImageBufferCount' => 40, + 'WarmupCount' => 1, + 'PreEventCount' => 1, + 'PostEventCount' => 5, + 'StreamReplayBuffer' => 0, 'AlarmFrameCount' => 1, 'Controllable' => 0, 'ControlId' => '', @@ -124,9 +124,9 @@ if ( ! $monitor ) { 'EventPrefix' => 'Event-', 'AnalysisFPSLimit' => '', 'AnalysisUpdateDelay' => 0, - 'MaxFPS' => '', - 'AlarmMaxFPS' => '', - 'FPSReportInterval' => 1000, + 'MaxFPS' => '30', + 'AlarmMaxFPS' => '30', + 'FPSReportInterval' => 100, 'RefBlendPerc' => 6, 'AlarmRefBlendPerc' => 6, 'DefaultView' => 'Events', @@ -138,8 +138,8 @@ if ( ! $monitor ) { 'Triggers' => '', 'V4LMultiBuffer' => '', 'V4LCapturesPerFrame' => 1, - 'ServerId' => $Server['Id'], - 'StorageId' => '0', + 'ServerId' => 'auto', + 'StorageId' => '1', ) ); } # end if $_REQUEST['dupID'] } # end if $_REQUEST['mid'] @@ -675,7 +675,7 @@ switch ( $tab ) { 'None'); + $servers = array(''=>'None','auto','Auto'); $result = dbQuery( 'SELECT * FROM Servers ORDER BY Name'); $results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Server' ); foreach ( $results as $row => $server_obj ) { From 0994b1f211b873b6cf8e109746c00a372fdcc630 Mon Sep 17 00:00:00 2001 From: Andy Bauer Date: Sun, 14 Jan 2018 14:54:10 -0600 Subject: [PATCH 015/154] Dockerfile moved to ZoneMinder/zmdockerfiles --- Dockerfile | 111 ----------------------------------------------------- 1 file changed, 111 deletions(-) delete mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 08bfd406e..000000000 --- a/Dockerfile +++ /dev/null @@ -1,111 +0,0 @@ -# ZoneMinder, you need the GIT repository code and submodules (git submodule update --init --recursive) - -FROM ubuntu:xenial -MAINTAINER Markos Vakondios - -# Resynchronize the package index files -RUN apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ - apache2 \ - build-essential \ - cmake \ - dh-autoreconf \ - dpatch \ - libapache2-mod-php \ - libarchive-zip-perl \ - libavcodec-dev \ - libavdevice-dev \ - libavfilter-dev \ - libavformat-dev \ - libavresample-dev \ - libav-tools \ - libavutil-dev \ - libbz2-dev \ - libcurl4-openssl-dev \ - libdate-manip-perl \ - libdbd-mysql-perl \ - libdbi-perl \ - libdevice-serialport-perl \ - libjpeg-turbo8 \ - libjpeg-turbo8-dev \ - libmime-lite-perl \ - libmime-perl \ - libmp4v2-dev \ - libmysqlclient-dev \ - libnetpbm10-dev \ - libpcre3 \ - libpcre3-dev \ - libpolkit-gobject-1-dev \ - libpostproc-dev \ - libssl-dev \ - libswscale-dev \ - libsys-mmap-perl \ - libtheora-dev \ - libtool \ - libv4l-dev \ - libvlc5 \ - libvlccore8 \ - libvlccore-dev \ - libvlc-dev \ - libvorbis-dev \ - libvpx-dev \ - libwww-perl \ - libx264-dev \ - mysql-client \ - mysql-server \ - php \ - php-cli \ - php-mysql \ - vlc-data \ - yasm \ - zip \ - && rm -rf /var/lib/apt/lists/* - -# Copy local code into our container -ADD cmake /ZoneMinder/cmake/ -ADD db /ZoneMinder/db/ -ADD misc /ZoneMinder/misc/ -ADD onvif /ZoneMinder/onvif/ -ADD scripts /ZoneMinder/scripts/ -ADD src /ZoneMinder/src/ -ADD umutils /ZoneMinder/umutils/ -ADD web /ZoneMinder/web/ -ADD cmakecacheimport.sh CMakeLists.txt version zm.conf.in zmconfgen.pl.in zmlinkcontent.sh.in zoneminder-config.cmake /ZoneMinder/ -ADD conf.d /ZoneMinder/conf.d - -# Change into the ZoneMinder directory -WORKDIR /ZoneMinder - -# Setup the ZoneMinder build environment -#RUN aclocal && autoheader && automake --force-missing --add-missing && autoconf - -# Configure ZoneMinder -#RUN ./configure --with-libarch=lib/$DEB_HOST_GNU_TYPE --disable-debug --host=$DEB_HOST_GNU_TYPE --build=$DEB_BUILD_GNU_TYPE --with-mysql=/usr --with-webdir=/var/www/zm --with-ffmpeg=/usr --with-cgidir=/usr/lib/cgi-bin --with-webuser=www-data --with-webgroup=www-data --enable-mmap=yes --enable-onvif ZM_SSL_LIB=openssl ZM_DB_USER=zm ZM_DB_PASS=zm -RUN cmake . - -# Build & install ZoneMinder -RUN make && make install - -# ensure writable folders -RUN ./zmlinkcontent.sh - -# Adding the start script -ADD utils/docker/start.sh /tmp/start.sh - -# Settings rights for /usr/local/share/zoneminder/ -RUN chown -R www-data:www-data /usr/local/share/zoneminder/ - -# Adding apache virtual hosts file -RUN cp misc/apache.conf /etc/apache2/sites-available/000-default.conf - -# Expose http port -EXPOSE 80 - -VOLUME /var/lib/zoneminder/images /var/lib/zoneminder/events /var/lib/mysql /var/log/zm - -# To speed up configuration testing, we put it here -ADD utils/docker /ZoneMinder/utils/docker/ - -CMD /ZoneMinder/utils/docker/setup.sh && /ZoneMinder/utils/docker/start.sh >/var/log/start.log 2>&1 & /bin/bash - -# Run example docker run -it -p 1080:80 -e PHP_TIMEZONE='Europe/Paris' -v /disk/zoneminder/events:/var/lib/zoneminder/events -v /disk/zoneminder/images:/var/lib/zoneminder/images -v /disk/zoneminder/mysql:/var/lib/mysql -v /disk/zoneminder/logs:/var/log/zm --name zoneminder zoneminder/zoneminder From d53f3e8048589cba9575511297d52a326080b6b2 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 14 Jan 2018 15:21:40 -0600 Subject: [PATCH 016/154] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 1d43ff560..0b9a90f9c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,10 @@ ZoneMinder is an integrated set of applications which provide a complete surveil Before creating an issue in our github forum, please read our posting rules: https://github.com/ZoneMinder/ZoneMinder/wiki/Github-Posting-Rules +## Our Dockerfile has moved +Please file issues against the ZoneMinder Dockerfile here: +https://github.com/ZoneMinder/zmdockerfiles + ## Installation Methods ### Building from Source is Discouraged From e1f82787122112476265252868a464400b70c5d3 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 14 Jan 2018 15:24:47 -0600 Subject: [PATCH 017/154] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 309d79785..5f80fe591 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -5,6 +5,8 @@ You should only file an issue if you found a bug. Feature and enhancement reque **Do not post feature or enhancement requests, general discussions or support questions here.** +Docker related issues should be posted here: https://github.com/ZoneMinder/zmdockerfiles + Make sure you are running the latest version of ZoneMinder before reporting an issue. **ZoneMinder Version (`zmaudit.pl -v`):** From 40928b2f3ca98a9828250de4615735ce2071ffe3 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 14 Jan 2018 16:41:21 -0600 Subject: [PATCH 018/154] Update README.md --- utils/docker/README.md | 49 +++--------------------------------------- 1 file changed, 3 insertions(+), 46 deletions(-) diff --git a/utils/docker/README.md b/utils/docker/README.md index 741039b3d..47bf4d1a2 100644 --- a/utils/docker/README.md +++ b/utils/docker/README.md @@ -1,47 +1,4 @@ -# Overview +## Docker Support Files -[Docker](https://www.docker.io/) allows you to quickly spin up application containers, -which are similar to very lightweight virtual machines. The ZoneMinder Dockerfile will -start an Ubuntu 12.04 container with MySql, Apache, and PHP properly configured, and -will then compile and install ZoneMinder. - -It will also start an SSH server that you can use to log into the container. - -This is still a bit of a work in progress. - -## How To Use - -1. Install [Docker](https://www.docker.io/) -2. Build ZoneMinder container -```sudo docker build -t yourname/zoneminder github.com/ZoneMinder/ZoneMinder``` -3. Run it -```CID=$(sudo docker run -d -p 222:22 -p 8080:80 --name zoneminder yourname/zoneminder)``` -4. Use it -- you can now SSH to port 222 on your host as user root with password root. -You can also browse to your host on port 8080 to access the zoneminder web interface - -## Developing With Docker - -If you wish to contribute to ZoneMinder, Docker can be helpful. By re-running -```docker build``` in your working directory, any code modifications you have -made will be pulled into a new container, compiled, and started, all without -modifying your base system. - -Development is not totally without annoyances, as any change -to the project will require a full rebuild of all C++. Docker notices that the -directory which has been ADD'ed is now different, and therefore all steps after -the ADD command must be recomputed. A fix for this is to update the Dockerfile to -move the configure and make commands into start.sh, and then use a volume mount -to cache the build directory (I think it's ```/tmp```) on your host filesystem. -This would be really useful for a developer, and would remove the annoying build -problem, but some of the Docker push/pull benefits would be lost. - -Docker containers can be both CPU and memory limited, so this can be a practical -method to compile or run multiple development builds of ZoneFinder simultaneously -without taxing your host system. - -## Use Cases - -## TODO -- Describe how to connect to monitors by mounting devices -- Create a 'development' dockerfile to remove the need to rebuild the entire project - after each small change +The files in this folder are used to support our Dockerfiles here: +https://github.com/ZoneMinder/zmdockerfiles From 80362f99fa9085f2f1bbedcfe840e6cef70f71f6 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 14 Jan 2018 20:14:30 -0600 Subject: [PATCH 019/154] fix misaligned db fields for certain presets (#2034) --- db/zm_create.sql.in | 72 ++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 826d775a6..1bf2291af 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -608,46 +608,46 @@ INSERT INTO `Controls` VALUES (NULL,'Floureon 1080P','Ffmpeg','Floureon',0,0,0,1 -- -- Add some monitor preset values -- -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg, B&W','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&color=0',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg, B&W','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&color=0',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, mpjpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 320x240, mpjpeg, B&W','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&color=0',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP, 640x480, mpjpeg, B&W','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&color=0',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=320x240&req_fps=5',NULL,320,240,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=320x240',NULL,320,240,3,5.0,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,1,4,NULL,':',100,100); INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, unicast','Remote','rtsp','rtpUni',NULL,NULL,NULL,'',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, multicast','Remote','rtsp','rtpMulti',NULL,NULL,NULL,'',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP','Remote','rtsp','rtpRtsp',NULL,NULL,NULL,'',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP/HTTP','Remote',NULL,NULL,NULL,'rtsp','rtpRtspHttp','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,1,5,NULL,':',100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, jpeg, max 5 FPS','Remote','http','simple',NULL,NULL,NULL,'',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/GetData.cgi',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, mpjpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'VEO Observer, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Blue Net Video Server, jpeg','Remote','http','simple',NULL,NULL,NULL,'',80,'/cgi-bin/image.cgi?control=0&id=admin&passwd=admin',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,NULL,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=640x480&Quality=Standard',NULL,640,480,3,5.0,1,5,NULL,':',100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, jpeg','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, mpjpeg','Remote','http',0,0,'http','simple','',80,'/GetData.cgi',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Gadspot IP, mpjpeg','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'VEO Observer, jpeg','Remote','http',0,0,'http','simple','',80,'/Jpeg/CamImg.jpg',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Blue Net Video Server, jpeg','Remote','http',0,0,'http','simple','',80,'/cgi-bin/image.cgi?control=0&id=admin&passwd=admin',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); INSERT into MonitorPresets VALUES (NULL,'ACTi IP, mpeg4, unicast','Remote',NULL,NULL,NULL,'rtsp','rtpUni','',7070,'','/track',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp:///axis-media/media.amp?videocodec=h264',NULL,NULL,NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'Vivotek FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://:554/live.sdp',NULL,NULL,NULL,352,240,NULL,NULL,0,NULL,NULL,NULL,100,100); From d54f3f71683bf946fc06ae52f74f3a857c7462d0 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 15 Jan 2018 09:15:57 -0600 Subject: [PATCH 020/154] fix misaligned fields in Axis & Qihan presets --- db/zm_create.sql.in | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 1bf2291af..b006f2c96 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -626,9 +626,9 @@ INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg','Remote', INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, mpjpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=5',NULL,640,480,3,NULL,1,4,NULL,':',100,100); INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,NULL,1,4,NULL,':',100,100); INSERT INTO MonitorPresets VALUES (NULL,'Axis IP PTZ, 640x480, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','',80,'/axis-cgi/jpg/image.cgi?resolution=640x480',NULL,640,480,3,5.0,1,4,NULL,':',100,100); -INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, unicast','Remote','rtsp','rtpUni',NULL,NULL,NULL,'',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, multicast','Remote','rtsp','rtpMulti',NULL,NULL,NULL,'',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP','Remote','rtsp','rtpRtsp',NULL,NULL,NULL,'',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, unicast','Remote','rtsp',0,255,'rtsp','rtpUni','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, multicast','Remote','rtsp',0,255,'rtsp','rtpMulti','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP','Remote','rtsp',0,255,'rtsp','rtpRtsp','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP/HTTP','Remote',NULL,NULL,NULL,'rtsp','rtpRtspHttp','',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg','Remote','http',0,0,'http','simple','',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100); @@ -676,8 +676,8 @@ INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI9821W FFMPEG H.264','Ffmpeg',N INSERT INTO MonitorPresets VALUES (NULL,'Loftek Sentinel PTZ, 640x480, mjpeg','Remote','http',0,0,NULL,NULL,'','80','/videostream.cgi?user=&pwd=&resolution=32&rate=11',NULL,640,480,4,NULL,1,'13','',':@',100,100); INSERT INTO MonitorPresets VALUES (NULL,'Airlink 777W PTZ, 640x480, mjpeg','Remote','http',0,0,NULL,NULL,':@','80','/cgi/mjpg/mjpg.cgi',NULL,640,480,4,NULL,1,'7','',':@',100,100); INSERT INTO MonitorPresets VALUES (NULL,'SunEyes SP-P1802SWPTZ','Libvlc','/dev/video','0',255,'','rtpMulti','','80','rtsp://:554/11','',1920,1080,0,0.00,1,'16','-speed=64',':',100,33); -INSERT INTO MonitorPresets VALUES (NULL,'Qihan IP, 1280x720, RTP/RTSP','Ffmpeg','rtsp','rtpRtsp',255,'rtsp','rtpRtsp',NULL,554,'rtsp:///tcp_live/ch0_0',NULL,1280,720,3,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'Qihan IP, 1920x1080, RTP/RTSP','Ffmpeg','rtsp','rtpRtsp',255,'rtsp','rtpRtsp',NULL,554,'rtsp:///tcp_live/ch0_0',NULL,1920,1080,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Qihan IP, 1280x720, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp',NULL,554,'rtsp:///tcp_live/ch0_0',NULL,1280,720,3,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'Qihan IP, 1920x1080, RTP/RTSP','Ffmpeg','rtsp',0,255,'rtsp','rtpRtsp',NULL,554,'rtsp:///tcp_live/ch0_0',NULL,1920,1080,3,NULL,0,NULL,NULL,NULL,100,100); -- -- Add some zone preset values From 31cc03eafcaad84fef9f3e238911404a294d6cdf Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 15 Jan 2018 09:45:40 -0600 Subject: [PATCH 021/154] fix datatype issue with BTTV Video presets --- db/zm_create.sql.in | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index b006f2c96..243c9886f 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -653,22 +653,22 @@ INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG H.264','Ffmpeg',NULL,NULL,N INSERT INTO MonitorPresets VALUES (NULL,'Vivotek FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://:554/live.sdp',NULL,NULL,NULL,352,240,NULL,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp:///axis-media/media.amp',NULL,NULL,NULL,640,480,NULL,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'ACTi TCM FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://admin:123456@:7070',NULL,NULL,NULL,320,240,NULL,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240','Local','/dev/video','',255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240, max 5 FPS','Local','/dev/video','',255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480','Local','/dev/video','',255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480, max 5 FPS','Local','/dev/video','',255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 320x240','Local','/dev/video','',45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 320x240, max 5 FPS','Local','/dev/video','',45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 640x480','Local','/dev/video','',45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 640x480, max 5 FPS','Local','/dev/video','',45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 320x240','Local','/dev/video','',0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 320x240, max 5 FPS','Local','/dev/video','',0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 640x480','Local','/dev/video','',0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 640x480, max 5 FPS','Local','/dev/video','',0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 320x240','Local','/dev/video','',1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 320x240, max 5 FPS','Local','/dev/video','',1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 640x480','Local','/dev/video','',1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 640x480, max 5 FPS','Local','/dev/video','',1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240','Local','/dev/video','0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240, max 5 FPS','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480, max 5 FPS','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 320x240','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 320x240, max 5 FPS','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 640x480','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), NTSC, 640x480, max 5 FPS','Local','/dev/video',0,45056,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 320x240','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 320x240, max 5 FPS','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 640x480','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), PAL, 640x480, max 5 FPS','Local','/dev/video',0,0,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 320x240','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 320x240, max 5 FPS','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,320,240,13,5.0,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 640x480','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L1), NTSC, 640x480, max 5 FPS','Local','/dev/video',0,1,NULL,'v4l1',NULL,NULL,NULL,NULL,640,480,13,5.0,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'Remote ZoneMinder','Remote',NULL,NULL,NULL,'http','simple','',80,'/cgi-bin/nph-zms?mode=jpeg&monitor=&scale=100&maxfps=5&buffer=0',NULL,NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI8620 FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://:@:554/11',NULL,704,576,0,NULL,1,'10','','',100,100); INSERT INTO MonitorPresets VALUES (NULL,'Foscam FI8608W FFMPEG H.264','Ffmpeg',NULL,NULL,NULL,NULL,'','','','rtsp://:@:554/11',NULL,640,480,0,NULL,1,'11','','',100,100); From 7451afcfab6c169acb31f9fc95e491986e578142 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 15 Jan 2018 11:13:26 -0600 Subject: [PATCH 022/154] delete extra apostraphe --- db/zm_create.sql.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 243c9886f..699008b75 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -653,7 +653,7 @@ INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG H.264','Ffmpeg',NULL,NULL,N INSERT INTO MonitorPresets VALUES (NULL,'Vivotek FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://:554/live.sdp',NULL,NULL,NULL,352,240,NULL,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'Axis FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp:///axis-media/media.amp',NULL,NULL,NULL,640,480,NULL,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'ACTi TCM FFMPEG','Ffmpeg',NULL,NULL,NULL,NULL,NULL,'rtsp://admin:123456@:7070',NULL,NULL,NULL,320,240,NULL,NULL,0,NULL,NULL,NULL,100,100); -INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240','Local','/dev/video','0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100); +INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 320x240, max 5 FPS','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,320,240,1345466932,5.0,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,NULL,0,NULL,NULL,NULL,100,100); INSERT INTO MonitorPresets VALUES (NULL,'BTTV Video (V4L2), PAL, 640x480, max 5 FPS','Local','/dev/video',0,255,NULL,'v4l2',NULL,NULL,NULL,NULL,640,480,1345466932,5.0,0,NULL,NULL,NULL,100,100); From 4af48a5885c2c472b65d32f464f3b29449f0d5d7 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 15 Jan 2018 14:40:04 -0600 Subject: [PATCH 023/154] silence a2enmod output --- utils/docker/setup.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/docker/setup.sh b/utils/docker/setup.sh index d1572d494..ecf915f16 100755 --- a/utils/docker/setup.sh +++ b/utils/docker/setup.sh @@ -55,10 +55,10 @@ setup_mysql() { setup_php() { # Activate CGI - a2enmod cgi + a2enmod -q cgi # Activate modrewrite - a2enmod rewrite + a2enmod -q rewrite # Setting timezone sed -i "s#;date.timezone =#date.timezone = $PHP_TIMEZONE#" /etc/php/7.0/apache2/php.ini From c0955e00430292ac55907a81059e23056464afbf Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 15 Jan 2018 21:01:02 -0600 Subject: [PATCH 024/154] link cakephp tmp folder to /var/tmp This has be done for docker builds --- zmlinkcontent.sh.in | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/zmlinkcontent.sh.in b/zmlinkcontent.sh.in index d6c791823..451605e04 100755 --- a/zmlinkcontent.sh.in +++ b/zmlinkcontent.sh.in @@ -262,5 +262,15 @@ else exit 31 fi +# Link the CakePHP tmp folder to /var/tmp +echo -n "Linking CakePHP folder to /var/tmp" +ln -sf /var/tmp "$ZM_PATH_WEB/api/app" +if [ "$?" = "0" ]; then + echo "OK" +else + echo "Failed" + exit 32 +fi + echo "" echo "All done" From 7b452f693705a7cb5b6ec77d8c63453108385845 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 16 Jan 2018 11:15:59 -0800 Subject: [PATCH 025/154] Fix Debug -> Logger::Debug --- web/includes/Storage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/includes/Storage.php b/web/includes/Storage.php index a108b6e32..48550d78e 100644 --- a/web/includes/Storage.php +++ b/web/includes/Storage.php @@ -120,7 +120,7 @@ public static function find_all( $parameters = null, $options = null ) { } $used = $this->disk_used_space(); $usage = round( ($used / $total) * 100); - Debug("Used $usage = round( ( $used / $total ) * 100 )"); + Logger::Debug("Used $usage = round( ( $used / $total ) * 100 )"); return $usage; } public function disk_total_space() { From 6826ebff9ff72494b913d2e3d36e8a5f02b51508 Mon Sep 17 00:00:00 2001 From: Andy Bauer Date: Tue, 16 Jan 2018 18:00:37 -0600 Subject: [PATCH 026/154] new docker entrypoint script --- utils/docker/entrypoint.sh | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100755 utils/docker/entrypoint.sh diff --git a/utils/docker/entrypoint.sh b/utils/docker/entrypoint.sh new file mode 100755 index 000000000..ab005411a --- /dev/null +++ b/utils/docker/entrypoint.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# ZoneMinder Dockerfile entrypoint script +# Written by Andrew Bauer + +############### +# SUBROUTINES # +############### + +start_mysql () { + service mysql start + # Give MySQL time to wake up + SECONDS_LEFT=120 + while true; do + sleep 1 + mysqladmin ping > /dev/null 2>&1 + if [ $? -eq 0 ];then + break; # Success + fi + let SECONDS_LEFT=SECONDS_LEFT-1 + + # If we have waited >120 seconds, give up + # ZM should never have a database that large! + # if $COUNTER -lt 120 + if [ $SECONDS_LEFT -eq 0 ];then + return -1; + fi + done +} + +close_mysql () { + service mysql stop + sleep 5 +} + +################ +# MAIN PROGRAM # +################ + +# Configure then start Mysql +if [ -n "$MYSQL_SERVER" ] && [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ] && [ -n "$MYSQL_DB" ]; then + sed -i -e "s/ZM_DB_NAME=zm/ZM_DB_NAME=$MYSQL_USER/g" /etc/zm.conf + sed -i -e "s/ZM_DB_USER=zmuser/ZM_DB_USER=$MYSQL_USER/g" /etc/zm.conf + sed -i -e "s/ZM_DB_PASS=zm/ZM_DB_PASS=$MYSQL_PASS/g" /etc/zm.conf + sed -i -e "s/ZM_DB_HOST=localhost/ZM_DB_HOST=$MYSQL_SERVER/g" /etc/zm.conf + start_mysql +else + usermod -d /var/lib/mysql/ mysql + start_mysql + mysql -u root < /usr/local/share/zoneminder/db/zm_create.sql + mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'zmuser'@'localhost' IDENTIFIED BY 'zmpass';" +fi +# Ensure we shut down mysql cleanly later: +trap close_mysql SIGTERM + +# Configure then start Apache +if [ -n "$TZ" ]; then + echo "date.timezone = $TZ" >> /etc/php/7.0/apache2/php.ini +else + echo "date.timezone = UTC" >> /etc/php/7.0/apache2/php.ini +fi +service apache2 start + +# Start ZoneMinder +/usr/local/bin/zmpkg.pl start && echo "ZoneMinder started" + +# Stay in a loop to keep the container running +while : +do + # perhaps output some stuff here or check apache & mysql are still running + sleep 3600 +done + From 7b3f72d7a27487ede6b5a3c56286e788dd32c6ba Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Tue, 16 Jan 2018 20:02:18 -0600 Subject: [PATCH 027/154] update service startup text --- utils/docker/entrypoint.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/docker/entrypoint.sh b/utils/docker/entrypoint.sh index ab005411a..7c83d37e6 100755 --- a/utils/docker/entrypoint.sh +++ b/utils/docker/entrypoint.sh @@ -61,7 +61,9 @@ fi service apache2 start # Start ZoneMinder -/usr/local/bin/zmpkg.pl start && echo "ZoneMinder started" +echo "* Starting ZoneMinder video surveillance recorder" +/usr/local/bin/zmpkg.pl start +echo " ...done." # Stay in a loop to keep the container running while : From fe0bd66f747c9af2cac28178ba8d2b2fcdb1a5d9 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Tue, 16 Jan 2018 20:12:26 -0600 Subject: [PATCH 028/154] fix whitespace in service startup text --- utils/docker/entrypoint.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/docker/entrypoint.sh b/utils/docker/entrypoint.sh index 7c83d37e6..7e25d8526 100755 --- a/utils/docker/entrypoint.sh +++ b/utils/docker/entrypoint.sh @@ -61,9 +61,9 @@ fi service apache2 start # Start ZoneMinder -echo "* Starting ZoneMinder video surveillance recorder" +echo " * Starting ZoneMinder video surveillance recorder" /usr/local/bin/zmpkg.pl start -echo " ...done." +echo " ...done." # Stay in a loop to keep the container running while : From 530e10610eb82185aeaec57c15efb60f426a7679 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Tue, 16 Jan 2018 20:14:42 -0600 Subject: [PATCH 029/154] Update entrypoint.sh --- utils/docker/entrypoint.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utils/docker/entrypoint.sh b/utils/docker/entrypoint.sh index 7e25d8526..a3a45511b 100755 --- a/utils/docker/entrypoint.sh +++ b/utils/docker/entrypoint.sh @@ -36,6 +36,8 @@ close_mysql () { # MAIN PROGRAM # ################ +echo + # Configure then start Mysql if [ -n "$MYSQL_SERVER" ] && [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ] && [ -n "$MYSQL_DB" ]; then sed -i -e "s/ZM_DB_NAME=zm/ZM_DB_NAME=$MYSQL_USER/g" /etc/zm.conf From 0305dfea9281a6234e3d7a0028065128745ac157 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Tue, 16 Jan 2018 20:47:23 -0600 Subject: [PATCH 030/154] Update entrypoint.sh --- utils/docker/entrypoint.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils/docker/entrypoint.sh b/utils/docker/entrypoint.sh index a3a45511b..d92140c90 100755 --- a/utils/docker/entrypoint.sh +++ b/utils/docker/entrypoint.sh @@ -38,6 +38,9 @@ close_mysql () { echo +# Make sure ZoneMinder can write to the log folder +chown www-data:www-data /var/log/zm + # Configure then start Mysql if [ -n "$MYSQL_SERVER" ] && [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ] && [ -n "$MYSQL_DB" ]; then sed -i -e "s/ZM_DB_NAME=zm/ZM_DB_NAME=$MYSQL_USER/g" /etc/zm.conf From 0ddf9633ed33153bac3b1bbbbcf0c997784c6e4f Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Wed, 17 Jan 2018 08:16:15 -0600 Subject: [PATCH 031/154] zmlinkcontent.sh - verify zm temp and log folders --- zmlinkcontent.sh.in | 141 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 132 insertions(+), 9 deletions(-) diff --git a/zmlinkcontent.sh.in b/zmlinkcontent.sh.in index 451605e04..b7d2cc78a 100755 --- a/zmlinkcontent.sh.in +++ b/zmlinkcontent.sh.in @@ -4,22 +4,32 @@ # Set the content dir default to be the one supplied to cmake ZM_PATH_CONTENT="@ZM_CONTENTDIR@" +# Set the zoneminder log dir default to be the one supplied to cmake +ZM_LOGDIR="@ZM_LOGDIR@" + +# Set the zoneminder temp dir default to be the one supplied to cmake +ZM_LOGDIR="@ZM_TMPDIR@" + echo "*** This bash script creates the nessecary symlinks for the zoneminder content" echo "*** It can use an existing content folder or create a new one" echo "*** For usage: use -h" echo "*** The default content directory is: $ZM_PATH_CONTENT" +echo "*** The default log directory is: $ZM_LOGDIR" +echo "*** The default temp directory is: $ZM_TMPDIR" echo "" usage() { cat < Date: Wed, 17 Jan 2018 08:18:41 -0600 Subject: [PATCH 032/154] log folder check moved to zmlinkcontent.sh --- utils/docker/entrypoint.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/utils/docker/entrypoint.sh b/utils/docker/entrypoint.sh index d92140c90..a3a45511b 100755 --- a/utils/docker/entrypoint.sh +++ b/utils/docker/entrypoint.sh @@ -38,9 +38,6 @@ close_mysql () { echo -# Make sure ZoneMinder can write to the log folder -chown www-data:www-data /var/log/zm - # Configure then start Mysql if [ -n "$MYSQL_SERVER" ] && [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ] && [ -n "$MYSQL_DB" ]; then sed -i -e "s/ZM_DB_NAME=zm/ZM_DB_NAME=$MYSQL_USER/g" /etc/zm.conf From 064be68efac05e131d60d7209b7c28101c7dd487 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Wed, 17 Jan 2018 08:46:38 -0600 Subject: [PATCH 033/154] fix typo --- zmlinkcontent.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zmlinkcontent.sh.in b/zmlinkcontent.sh.in index b7d2cc78a..9a9b50d6c 100755 --- a/zmlinkcontent.sh.in +++ b/zmlinkcontent.sh.in @@ -8,7 +8,7 @@ ZM_PATH_CONTENT="@ZM_CONTENTDIR@" ZM_LOGDIR="@ZM_LOGDIR@" # Set the zoneminder temp dir default to be the one supplied to cmake -ZM_LOGDIR="@ZM_TMPDIR@" +ZM_TMPDIR="@ZM_TMPDIR@" echo "*** This bash script creates the nessecary symlinks for the zoneminder content" echo "*** It can use an existing content folder or create a new one" From 5d0defd9fa5deb4c79aef9af9446bcb72331abe8 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Wed, 17 Jan 2018 09:58:18 -0600 Subject: [PATCH 034/154] zmlinkcontent.sh - modify temp folder link command --- zmlinkcontent.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zmlinkcontent.sh.in b/zmlinkcontent.sh.in index 9a9b50d6c..aacaed8e5 100755 --- a/zmlinkcontent.sh.in +++ b/zmlinkcontent.sh.in @@ -387,7 +387,7 @@ fi # Link the CakePHP tmp folder to the zoneminder temp folder echo -n "Linking CakePHP tmp folder to ${ZM_TMPDIR}... " -ln -sf "$ZM_TMPDIR" "$ZM_PATH_WEB/api/app" +ln -sfT "$ZM_TMPDIR" "$ZM_PATH_WEB/api/app/tmp" if [ "$?" = "0" ]; then echo "OK" else From 617331ef328a9ad3a5f62e1a069b106a365b01e0 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Wed, 17 Jan 2018 10:38:20 -0600 Subject: [PATCH 035/154] fix apache alias --- misc/apache.conf.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/apache.conf.in b/misc/apache.conf.in index d1c6d70db..1344bb9b1 100644 --- a/misc/apache.conf.in +++ b/misc/apache.conf.in @@ -8,7 +8,7 @@ ServerAdmin webmaster@localhost DocumentRoot "@WEB_PREFIX@" - Alias /zm/ "@WEB_PREFIX@/" + Alias /zm "@WEB_PREFIX@" Options -Indexes +FollowSymLinks AllowOverride All From 285a3a29580d3a796dd608530fb719a9da849ac9 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Wed, 17 Jan 2018 14:41:44 -0600 Subject: [PATCH 036/154] zmlinkcontent.sh - only symlink events & images folder when -o flag is set --- zmlinkcontent.sh.in | 53 +++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/zmlinkcontent.sh.in b/zmlinkcontent.sh.in index aacaed8e5..cad04dc61 100755 --- a/zmlinkcontent.sh.in +++ b/zmlinkcontent.sh.in @@ -1,5 +1,6 @@ #!/bin/bash -# The purpose of this file is to create the symlinks in the web folder to the content folder. It can use an existing content folder or create a new one. +# This tool is used to verify folders critical to ZoneMinder exist and have the right permissions. +# It will also create symlinks when necessary. It can use an existing content folder or create a new one. # Set the content dir default to be the one supplied to cmake ZM_PATH_CONTENT="@ZM_CONTENTDIR@" @@ -21,7 +22,7 @@ echo "" usage() { cat < Date: Wed, 17 Jan 2018 14:46:21 -0600 Subject: [PATCH 037/154] Update zmlinkcontent.sh.in --- zmlinkcontent.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zmlinkcontent.sh.in b/zmlinkcontent.sh.in index cad04dc61..409202cb1 100755 --- a/zmlinkcontent.sh.in +++ b/zmlinkcontent.sh.in @@ -40,7 +40,7 @@ Otherwise, it will attempt to read zm.conf from the local directory. If that fails, it will try from /etc/zm.conf Newer versions of ZoneMinder no longer require symlinks to the events and -images folder inside the webroot folder. Indeed this is a security risk, and +images folders inside the zm webroot. Indeed this is a security risk, and $0 will no longer create these unless the -o option is specified. EOF From ad8c77550704d2d55615af60a3250c0a21f80220 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 17 Jan 2018 12:53:23 -0800 Subject: [PATCH 038/154] Only update db record if there is a change in diskspace --- scripts/zmfilter.pl.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 4db95e58b..40d519c3a 100644 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -320,8 +320,10 @@ sub checkFilter { if ( $filter->{UpdateDiskSpace} ) { my $Event = new ZoneMinder::Event( $$event{Id}, $event ); - $Event->DiskSpace(undef); - $Event->save(); + my $old_diskspace = $$Event{DiskSpace}; + if ( $old_diskspace != $Event->DiskSpace(undef) ) { + $Event->save(); + } } # end if UpdateDiskSpace } # end foreach event } From 494d0807408d286a138bb7bb833d2eefe23606e6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 17 Jan 2018 13:27:44 -0800 Subject: [PATCH 039/154] show port in source column --- web/skins/classic/views/console.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index a8a693bb7..c60f8b42e 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -230,8 +230,8 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { } elseif ( $monitor['Type'] == 'File' || $monitor['Type'] == 'cURL' ) { $source = preg_replace( '/^.*\//', '', $monitor['Path'] ); } elseif ( $monitor['Type'] == 'Ffmpeg' || $monitor['Type'] == 'Libvlc' ) { - $domain = parse_url( $monitor['Path'], PHP_URL_HOST ); - $source = $domain ? $domain : preg_replace( '/^.*\//', '', $monitor['Path'] ); + $url_parts = parse_url( $monitor['Path'] ); + $source = $url_parts['host']. ( $url_parts['port'] ? ':'.$url_parts['port'] : '' ); } if ( $source == '' ) { $source = 'Monitor ' . $monitor['Id']; From 55fa86c7beed138b6923ae4eaca170248f22bd84 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 17 Jan 2018 16:57:38 -0500 Subject: [PATCH 040/154] Add a few more extensions to the list of files to include in export --- web/skins/classic/includes/export_functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/includes/export_functions.php b/web/skins/classic/includes/export_functions.php index d9dc4f9c8..9a896b30d 100644 --- a/web/skins/classic/includes/export_functions.php +++ b/web/skins/classic/includes/export_functions.php @@ -834,7 +834,7 @@ function exportFileList( $eid, $exportDetail, $exportFrames, $exportImages, $exp $filesLeft = array(); foreach ( $files as $file ) { - if ( preg_match( "/\.(?:mpg|mpeg|avi|asf|3gp)$/", $file ) ) + if ( preg_match( '/\.(?:mpg|mpeg|mov|swf|mp4|mkv|avi|asf|3gp)$/', $file ) ) { $exportFileList[$file] = $eventPath."/".$file; } From 9df7349e8e3ac4ac7a2c5b4146bcf6f405591945 Mon Sep 17 00:00:00 2001 From: Brian Gallimore Date: Wed, 17 Jan 2018 19:57:45 -0600 Subject: [PATCH 041/154] Update packpack.rst added path to git clone command. (I'm following install guide for first time and that step didn't work without the path) --- docs/installationguide/packpack.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installationguide/packpack.rst b/docs/installationguide/packpack.rst index c1f20261d..6b558d11c 100644 --- a/docs/installationguide/packpack.rst +++ b/docs/installationguide/packpack.rst @@ -44,7 +44,7 @@ Clone the ZoneMinder project if you have not done so already. :: - git clone ZoneMinder + git clone https://ZoneMinder/ZoneMinder cd ZoneMinder Alternatively, if you have already cloned the repo and wish to update it, do the following. From 2e4a20dfba968bc2d4b3ae4bc0238e09eca8d0e8 Mon Sep 17 00:00:00 2001 From: Andy Bauer Date: Thu, 18 Jan 2018 09:08:09 -0600 Subject: [PATCH 042/154] entrypoint.sh - add multi-distro compatibility --- utils/docker/entrypoint.sh | 86 +++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/utils/docker/entrypoint.sh b/utils/docker/entrypoint.sh index a3a45511b..cc01216ce 100755 --- a/utils/docker/entrypoint.sh +++ b/utils/docker/entrypoint.sh @@ -6,6 +6,72 @@ # SUBROUTINES # ############### +# Find ciritical files and perform sanity checks +initialze () { + + # Check to see if this script has access to all the commands it needs + for CMD in mysqladmin sed usermod service; do + type $CMD &> /dev/null + + if [ $? -ne 0 ]; then + echo + echo "ERROR: The script cannot find the required command \"${CMD}\"." + echo + exit 1 + fi + done + + # Look in common places for the zoneminder config file - zm.conf + for FILE in "/etc/zm.conf" "/etc/zm/zm.conf" "/usr/local/etc/zm.conf" "/usr/local/etc/zm/zm.conf"; do + if [ -f $FILE ]; then + ZMCONF=$FILE + break + fi + done + + # Look in common places for the zoneminder startup perl script - zmpkg.pl + for FILE in "/usr/bin/zmpkg.pl" "/usr/local/bin/zmpkg.pl"; do + if [ -f $FILE ]; then + ZMPKG=$FILE + break + fi + done + + # Look in common places for the zoneminder dB creation script - zm_create.sql + for FILE in "/usr/share/zoneminder/db/zm_create.sql" "/usr/local/share/zoneminder/db/zm_create.sql"; do + if [ -f $FILE ]; then + ZMCREATE=$FILE + break + fi + done + + # Look in common places for the php.ini relevant to zoneminder - php.ini + # Search order matters here because debian distros commonly have multiple php.ini's + for FILE in "/etc/php/7.0/apache2/php.ini" "/etc/php5/apache2/php.ini" "/etc/php.ini" "/usr/local/etc/php.ini"; do + if [ -f $FILE ]; then + PHPINI=$FILE + break + fi + done + + for FILE in $ZMCONF $ZMPKG $ZMCREATE $PHPINI; do + if [ -z $FILE ]; then + echo + echo "FATAL: This script was unable to determine one or more cirtical files. Cannot continue." + echo + echo "VARIABLE DUMP" + echo "-------------" + echo + echo "Path to zm.conf: ${ZMCONF}" + echo "Path to zmpkg.pl: ${ZMPKG}" + echo "Path to zm_create.sql: ${ZMCREATE}" + echo "Path to php.ini: ${PHPINI}" + echo + exit 98 + fi + done +} + start_mysql () { service mysql start # Give MySQL time to wake up @@ -37,34 +103,34 @@ close_mysql () { ################ echo +initialize # Configure then start Mysql if [ -n "$MYSQL_SERVER" ] && [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ] && [ -n "$MYSQL_DB" ]; then - sed -i -e "s/ZM_DB_NAME=zm/ZM_DB_NAME=$MYSQL_USER/g" /etc/zm.conf - sed -i -e "s/ZM_DB_USER=zmuser/ZM_DB_USER=$MYSQL_USER/g" /etc/zm.conf - sed -i -e "s/ZM_DB_PASS=zm/ZM_DB_PASS=$MYSQL_PASS/g" /etc/zm.conf - sed -i -e "s/ZM_DB_HOST=localhost/ZM_DB_HOST=$MYSQL_SERVER/g" /etc/zm.conf + sed -i -e "s/ZM_DB_NAME=zm/ZM_DB_NAME=$MYSQL_USER/g" $ZMCONF + sed -i -e "s/ZM_DB_USER=zmuser/ZM_DB_USER=$MYSQL_USER/g" $ZMCONF + sed -i -e "s/ZM_DB_PASS=zm/ZM_DB_PASS=$MYSQL_PASS/g" $ZMCONF + sed -i -e "s/ZM_DB_HOST=localhost/ZM_DB_HOST=$MYSQL_SERVER/g" $ZMCONF start_mysql else usermod -d /var/lib/mysql/ mysql start_mysql - mysql -u root < /usr/local/share/zoneminder/db/zm_create.sql + mysql -u root < $ZMCREATE mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'zmuser'@'localhost' IDENTIFIED BY 'zmpass';" fi # Ensure we shut down mysql cleanly later: trap close_mysql SIGTERM # Configure then start Apache -if [ -n "$TZ" ]; then - echo "date.timezone = $TZ" >> /etc/php/7.0/apache2/php.ini -else - echo "date.timezone = UTC" >> /etc/php/7.0/apache2/php.ini +if [ -z "$TZ" ]; then + $TZ = UTC fi +echo "date.timezone = $TZ" >> $PHPINI service apache2 start # Start ZoneMinder echo " * Starting ZoneMinder video surveillance recorder" -/usr/local/bin/zmpkg.pl start +$ZMPKG start echo " ...done." # Stay in a loop to keep the container running From 95edf1b2a85e65bf70a621d0047f633947c744fb Mon Sep 17 00:00:00 2001 From: Andy Bauer Date: Thu, 18 Jan 2018 09:35:04 -0600 Subject: [PATCH 043/154] fix typo --- utils/docker/entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/docker/entrypoint.sh b/utils/docker/entrypoint.sh index cc01216ce..ee01499d1 100755 --- a/utils/docker/entrypoint.sh +++ b/utils/docker/entrypoint.sh @@ -7,7 +7,7 @@ ############### # Find ciritical files and perform sanity checks -initialze () { +initialize () { # Check to see if this script has access to all the commands it needs for CMD in mysqladmin sed usermod service; do From ecd5e01b92543a09011f26f0e94f5c244a3180ac Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 18 Jan 2018 10:21:05 -0800 Subject: [PATCH 044/154] Show port when using Remote Method and Port is non-standard --- web/skins/classic/views/console.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index c60f8b42e..ed8ba1139 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -227,6 +227,9 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { $source = $monitor['Device'].' ('.$monitor['Channel'].')'; } elseif ( $monitor['Type'] == 'Remote' ) { $source = preg_replace( '/^.*@/', '', $monitor['Host'] ); + if ( $monitor['Port'] != '80' and $monitor['Port'] != '554' ) { + $source .= ':'.$monitor['Port']; + } } elseif ( $monitor['Type'] == 'File' || $monitor['Type'] == 'cURL' ) { $source = preg_replace( '/^.*\//', '', $monitor['Path'] ); } elseif ( $monitor['Type'] == 'Ffmpeg' || $monitor['Type'] == 'Libvlc' ) { From cdfa5655793e4f254d3f16f30271ff3a06546e3b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 18 Jan 2018 12:38:26 -0800 Subject: [PATCH 045/154] Fix restarting Monitor --- web/api/app/Controller/MonitorsController.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/web/api/app/Controller/MonitorsController.php b/web/api/app/Controller/MonitorsController.php index 0880cc68e..d06ce1dfe 100644 --- a/web/api/app/Controller/MonitorsController.php +++ b/web/api/app/Controller/MonitorsController.php @@ -162,14 +162,16 @@ class MonitorsController extends AppController { '_serialize' => array('message') )); - // - restart or stop this monitor after change - $func = $this->Monitor->find('first', array( - 'fields' => array('Function'), + $Monitor = $this->Monitor->find('first', array( + 'fields' => array('Function','ServerId'), 'conditions' => array('Id' => $id) - ))['Monitor']['Function']; + ))['Monitor']; + + // - restart or stop this monitor after change + $func = $Monitor['Function']; // We don't pass the request data as the monitor object because it may be a subset of the full monitor array $this->daemonControl( $this->Monitor->id, 'stop' ); - if ( ( $func != 'None' ) and ( $this->Monitor->ServerId == ZM_SERVER_ID ) ) { + if ( ( $func != 'None' ) and ( $Monitor['ServerId'] == ZM_SERVER_ID ) ) { $this->daemonControl( $this->Monitor->id, 'start' ); } } // end function edit From 04eef588832616238cd030ad3493644b85859430 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 18 Jan 2018 12:38:48 -0800 Subject: [PATCH 046/154] Add Triggers to Monitors field to quiet error --- web/includes/Monitor.php | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index b3a9ad633..e98270282 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -18,6 +18,7 @@ private $defaults = array( 'AnalysisFPS' => null, 'CaptureFPS' => null, 'ZoneCount' => 0, +'Triggers' => null, ); private $control_fields = array( 'Name' => '', @@ -126,7 +127,7 @@ private $control_fields = array( if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) { $row = dbFetchOne( 'SELECT * FROM Monitors WHERE Id=?', NULL, array( $IdOrRow ) ); if ( ! $row ) { - Error("Unable to load Server record for Id=" . $IdOrRow ); + Error("Unable to load Monitor record for Id=" . $IdOrRow ); } } elseif ( is_array( $IdOrRow ) ) { $row = $IdOrRow; @@ -324,8 +325,9 @@ private $control_fields = array( if ( $mode == 'restart' ) { daemonControl( 'stop', 'zmc', $zmcArgs ); } - if ( $this->{'Function'} != 'None' ) + if ( $this->{'Function'} != 'None' ) { daemonControl( 'start', 'zmc', $zmcArgs ); + } } } else { $Server = $this->Server(); @@ -341,6 +343,7 @@ private $control_fields = array( $url = '&user='.$_SESSION['username']; } } +Logger::Debug("sending command to $url"); $data = array('Monitor[Function]' => $this->{'Function'} ); // use key 'http' even if you send the request to https://... @@ -352,10 +355,17 @@ private $control_fields = array( ) ); $context = stream_context_create($options); - $result = file_get_contents($url, false, $context); - if ($result === FALSE) { /* Handle error */ } + try { + $result = file_get_contents($url, false, $context); + if ($result === FALSE) { /* Handle error */ + Error("Error restarting zmc using $url"); + } + } catch ( Exception $e ) { + Error("Except $e thrown trying to restart zmc"); + } } } // end function zmcControl + function zmaControl( $mode=false ) { if ( (!defined('ZM_SERVER_ID')) or ( ZM_SERVER_ID==$this->{'ServerId'} ) ) { if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) { From f9d8c349e1aea76afad3749d8f453dd6a466df8e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 18 Jan 2018 12:39:08 -0800 Subject: [PATCH 047/154] Move unparse_url from add_monitors to functions to make it generally available --- web/ajax/add_monitors.php | 19 ------------------- web/includes/functions.php | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/web/ajax/add_monitors.php b/web/ajax/add_monitors.php index b95f0e8f4..65c25d85d 100644 --- a/web/ajax/add_monitors.php +++ b/web/ajax/add_monitors.php @@ -1,23 +1,4 @@ set(array( diff --git a/web/includes/functions.php b/web/includes/functions.php index a05bfe6b2..a5df103da 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -841,6 +841,7 @@ function daemonControl( $command, $daemon=false, $args=false ) { } $string = escapeshellcmd( $string ); #$string .= ' 2>/dev/null >&- <&- >/dev/null'; +Logger::Debug("daemonControl $string"); exec( $string ); } @@ -2314,4 +2315,23 @@ function csrf_startup() { csrf_conf('rewrite-js', 'includes/csrf/csrf-magic.js'); } +function unparse_url($parsed_url, $substitutions = array() ) { + $fields = array('scheme','host','port','user','pass','path','query','fragment'); + + foreach ( $fields as $field ) { + if ( isset( $substitutions[$field] ) ) { + $parsed_url[$field] = $substitutions[$field]; + } + } + $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : ''; + $host = isset($parsed_url['host']) ? $parsed_url['host'] : ''; + $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''; + $user = isset($parsed_url['user']) ? $parsed_url['user'] : ''; + $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; + $pass = ($user || $pass) ? "$pass@" : ''; + $path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; + $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; + $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; + return "$scheme$user$pass$host$port$path$query$fragment"; +} ?> From c08cbdb9dd190e4281a8081031939c2d12578b02 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 18 Jan 2018 12:39:39 -0800 Subject: [PATCH 048/154] Turn off debug --- web/includes/Storage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/includes/Storage.php b/web/includes/Storage.php index 48550d78e..38ba83bf9 100644 --- a/web/includes/Storage.php +++ b/web/includes/Storage.php @@ -120,7 +120,7 @@ public static function find_all( $parameters = null, $options = null ) { } $used = $this->disk_used_space(); $usage = round( ($used / $total) * 100); - Logger::Debug("Used $usage = round( ( $used / $total ) * 100 )"); + //Logger::Debug("Used $usage = round( ( $used / $total ) * 100 )"); return $usage; } public function disk_total_space() { From 30b0d2c5b1df235b3798b38936fcb571de8df5ec Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 18 Jan 2018 12:39:50 -0800 Subject: [PATCH 049/154] Turn off debug --- web/includes/logger.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/includes/logger.php b/web/includes/logger.php index 570840128..0d7334ac7 100644 --- a/web/includes/logger.php +++ b/web/includes/logger.php @@ -154,7 +154,7 @@ class Logger { $this->initialised = true; - Logger::Debug( "LogOpts: level=".self::$codes[$this->level]."/".self::$codes[$this->effectiveLevel].", screen=".self::$codes[$this->termLevel].", database=".self::$codes[$this->databaseLevel].", logfile=".self::$codes[$this->fileLevel]."->".$this->logFile.", weblog=".self::$codes[$this->weblogLevel].", syslog=".self::$codes[$this->syslogLevel] ); + //Logger::Debug( "LogOpts: level=".self::$codes[$this->level]."/".self::$codes[$this->effectiveLevel].", screen=".self::$codes[$this->termLevel].", database=".self::$codes[$this->databaseLevel].", logfile=".self::$codes[$this->fileLevel]."->".$this->logFile.", weblog=".self::$codes[$this->weblogLevel].", syslog=".self::$codes[$this->syslogLevel] ); } private function terminate() { From 484a361af8bf409cca8a788c80d88686486dd9e6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 18 Jan 2018 12:40:10 -0800 Subject: [PATCH 050/154] use Object methods to restart zmc and zma. restart them on save of existing Monitor --- web/includes/actions.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/web/includes/actions.php b/web/includes/actions.php index 1c889f5de..384953940 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -530,6 +530,7 @@ if ( canEdit( 'Monitors' ) ) { } } } + $restart = true; } elseif ( ! $user['MonitorIds'] ) { // Can only create new monitors if we are not restricted to specific monitors # FIXME This is actually a race condition. Should lock the table. $maxSeq = dbFetchOne( 'SELECT max(Sequence) AS MaxSequence FROM Monitors', 'MaxSequence' ); @@ -570,15 +571,16 @@ if ( canEdit( 'Monitors' ) ) { } if ( $restart ) { - $new_monitor = dbFetchOne( 'SELECT * FROM Monitors WHERE Id = ?', NULL, array($mid) ); + + $new_monitor = new Monitor($mid); //fixDevices(); //if ( $cookies ) //session_write_close(); - zmcControl( $new_monitor, 'start' ); - zmaControl( $new_monitor, 'start' ); + $new_monitor->zmcControl('start'); + $new_monitor->zmaControl('start'); - if ( $new_monitor['Controllable'] ) { + if ( $new_monitor->Controllable() ) { require_once( 'control_functions.php' ); sendControlCommand( $mid, 'quit' ); } From 95f054c1e65b38a634dae297f584de4e472f6bc5 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 18 Jan 2018 12:40:41 -0800 Subject: [PATCH 051/154] Show entire path for ffmpeg monitors. Strip out username/password though --- web/skins/classic/views/console.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index ed8ba1139..1b5ea9083 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -234,7 +234,9 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { $source = preg_replace( '/^.*\//', '', $monitor['Path'] ); } elseif ( $monitor['Type'] == 'Ffmpeg' || $monitor['Type'] == 'Libvlc' ) { $url_parts = parse_url( $monitor['Path'] ); - $source = $url_parts['host']. ( $url_parts['port'] ? ':'.$url_parts['port'] : '' ); + unset($url_parts['user']); + unset($url_parts['pass']); + $source = unparse_url( $url_parts ); } if ( $source == '' ) { $source = 'Monitor ' . $monitor['Id']; From 9b7fee03c754c34410b88c8d98bf698228a798d7 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 19 Jan 2018 11:00:46 -0800 Subject: [PATCH 052/154] Add Server auto-selection --- web/includes/actions.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/includes/actions.php b/web/includes/actions.php index 384953940..6f25a40d0 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -485,6 +485,9 @@ if ( canEdit( 'Monitors' ) ) { $columns = getTableColumns( 'Monitors' ); $changes = getFormChanges( $monitor, $_REQUEST['newMonitor'], $types, $columns ); + if ( isset($changes['ServerId']) and $changes['ServerId'] == 'auto' ) { + $changes['ServerId'] = dbFetchOne( 'SELECT Id FROM Servers WHERE Status=\'Running\' ORDER BY FreeMem, CpuLoad LIMIT 1', 'Id' ); + } if ( count( $changes ) ) { if ( $mid ) { From 32bf57d35b8d80824468c30472bd07577f31674d Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Fri, 19 Jan 2018 15:15:11 -0600 Subject: [PATCH 053/154] docker support files moved to zmdockerfiles --- utils/docker/README.md | 2 +- utils/docker/entrypoint.sh | 142 ------------------------------------- utils/docker/phpdate.ini | 5 -- utils/docker/setup.sh | 75 -------------------- utils/docker/start.sh | 48 ------------- 5 files changed, 1 insertion(+), 271 deletions(-) delete mode 100755 utils/docker/entrypoint.sh delete mode 100644 utils/docker/phpdate.ini delete mode 100755 utils/docker/setup.sh delete mode 100755 utils/docker/start.sh diff --git a/utils/docker/README.md b/utils/docker/README.md index 47bf4d1a2..0dd76b32b 100644 --- a/utils/docker/README.md +++ b/utils/docker/README.md @@ -1,4 +1,4 @@ ## Docker Support Files -The files in this folder are used to support our Dockerfiles here: +Docker support files have been moved to the zmdockerfiles repo: https://github.com/ZoneMinder/zmdockerfiles diff --git a/utils/docker/entrypoint.sh b/utils/docker/entrypoint.sh deleted file mode 100755 index ee01499d1..000000000 --- a/utils/docker/entrypoint.sh +++ /dev/null @@ -1,142 +0,0 @@ -#!/bin/bash -# ZoneMinder Dockerfile entrypoint script -# Written by Andrew Bauer - -############### -# SUBROUTINES # -############### - -# Find ciritical files and perform sanity checks -initialize () { - - # Check to see if this script has access to all the commands it needs - for CMD in mysqladmin sed usermod service; do - type $CMD &> /dev/null - - if [ $? -ne 0 ]; then - echo - echo "ERROR: The script cannot find the required command \"${CMD}\"." - echo - exit 1 - fi - done - - # Look in common places for the zoneminder config file - zm.conf - for FILE in "/etc/zm.conf" "/etc/zm/zm.conf" "/usr/local/etc/zm.conf" "/usr/local/etc/zm/zm.conf"; do - if [ -f $FILE ]; then - ZMCONF=$FILE - break - fi - done - - # Look in common places for the zoneminder startup perl script - zmpkg.pl - for FILE in "/usr/bin/zmpkg.pl" "/usr/local/bin/zmpkg.pl"; do - if [ -f $FILE ]; then - ZMPKG=$FILE - break - fi - done - - # Look in common places for the zoneminder dB creation script - zm_create.sql - for FILE in "/usr/share/zoneminder/db/zm_create.sql" "/usr/local/share/zoneminder/db/zm_create.sql"; do - if [ -f $FILE ]; then - ZMCREATE=$FILE - break - fi - done - - # Look in common places for the php.ini relevant to zoneminder - php.ini - # Search order matters here because debian distros commonly have multiple php.ini's - for FILE in "/etc/php/7.0/apache2/php.ini" "/etc/php5/apache2/php.ini" "/etc/php.ini" "/usr/local/etc/php.ini"; do - if [ -f $FILE ]; then - PHPINI=$FILE - break - fi - done - - for FILE in $ZMCONF $ZMPKG $ZMCREATE $PHPINI; do - if [ -z $FILE ]; then - echo - echo "FATAL: This script was unable to determine one or more cirtical files. Cannot continue." - echo - echo "VARIABLE DUMP" - echo "-------------" - echo - echo "Path to zm.conf: ${ZMCONF}" - echo "Path to zmpkg.pl: ${ZMPKG}" - echo "Path to zm_create.sql: ${ZMCREATE}" - echo "Path to php.ini: ${PHPINI}" - echo - exit 98 - fi - done -} - -start_mysql () { - service mysql start - # Give MySQL time to wake up - SECONDS_LEFT=120 - while true; do - sleep 1 - mysqladmin ping > /dev/null 2>&1 - if [ $? -eq 0 ];then - break; # Success - fi - let SECONDS_LEFT=SECONDS_LEFT-1 - - # If we have waited >120 seconds, give up - # ZM should never have a database that large! - # if $COUNTER -lt 120 - if [ $SECONDS_LEFT -eq 0 ];then - return -1; - fi - done -} - -close_mysql () { - service mysql stop - sleep 5 -} - -################ -# MAIN PROGRAM # -################ - -echo -initialize - -# Configure then start Mysql -if [ -n "$MYSQL_SERVER" ] && [ -n "$MYSQL_USER" ] && [ -n "$MYSQL_PASSWORD" ] && [ -n "$MYSQL_DB" ]; then - sed -i -e "s/ZM_DB_NAME=zm/ZM_DB_NAME=$MYSQL_USER/g" $ZMCONF - sed -i -e "s/ZM_DB_USER=zmuser/ZM_DB_USER=$MYSQL_USER/g" $ZMCONF - sed -i -e "s/ZM_DB_PASS=zm/ZM_DB_PASS=$MYSQL_PASS/g" $ZMCONF - sed -i -e "s/ZM_DB_HOST=localhost/ZM_DB_HOST=$MYSQL_SERVER/g" $ZMCONF - start_mysql -else - usermod -d /var/lib/mysql/ mysql - start_mysql - mysql -u root < $ZMCREATE - mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'zmuser'@'localhost' IDENTIFIED BY 'zmpass';" -fi -# Ensure we shut down mysql cleanly later: -trap close_mysql SIGTERM - -# Configure then start Apache -if [ -z "$TZ" ]; then - $TZ = UTC -fi -echo "date.timezone = $TZ" >> $PHPINI -service apache2 start - -# Start ZoneMinder -echo " * Starting ZoneMinder video surveillance recorder" -$ZMPKG start -echo " ...done." - -# Stay in a loop to keep the container running -while : -do - # perhaps output some stuff here or check apache & mysql are still running - sleep 3600 -done - diff --git a/utils/docker/phpdate.ini b/utils/docker/phpdate.ini deleted file mode 100644 index d35b47361..000000000 --- a/utils/docker/phpdate.ini +++ /dev/null @@ -1,5 +0,0 @@ -[Date] -; Defines the default timezone used by the date functions -; http://php.net/date.timezone -date.timezone = GMT - diff --git a/utils/docker/setup.sh b/utils/docker/setup.sh deleted file mode 100755 index ecf915f16..000000000 --- a/utils/docker/setup.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -setup_mysql_first_time(){ - if [ "$(ls /var/lib/mysql)" ]; then - return - fi - - # Set MySQL in the volume - rm -rf /var/lib/mysql/* - chown -R mysql:mysql /var/lib/mysql - mysqld --initialize-insecure - - # Start MySQL - # For Xenial the following won't start mysqld - #/usr/bin/mysqld_safe & - # Use this instead: - service mysql start - - # Give MySQL time to wake up - SECONDS_LEFT=120 - while true; do - sleep 1 - mysqladmin ping - if [ $? -eq 0 ];then - break; # Success - fi - let SECONDS_LEFT=SECONDS_LEFT-1 - - # If we have waited >120 seconds, give up - # ZM should never have a database that large! - # if $COUNTER -lt 120 - if [ $SECONDS_LEFT -eq 0 ];then - return -1; - fi - done - - # Create the ZoneMinder database - mysql -u root < db/zm_create.sql - - # Add the ZoneMinder DB user - mysql -u root -e "grant insert,select,update,delete,lock tables,alter on zm.* to 'zmuser'@'localhost' identified by 'zmpass';" - - # Shut down mysql cleanly: - kill $(cat /var/run/mysqld/mysqld.pid) - sleep 5 -} - -setup_mysql() { - # To configure MySQL if no container did it before - setup_mysql_first_time - - # Add configuration to avoid SQL error when adding monitor - echo "sql_mode=NO_ENGINE_SUBSTITUTION" >> /etc/mysql/mysql.conf.d/mysqld.cnf -} - -setup_php() { - # Activate CGI - a2enmod -q cgi - - # Activate modrewrite - a2enmod -q rewrite - - # Setting timezone - sed -i "s#;date.timezone =#date.timezone = $PHP_TIMEZONE#" /etc/php/7.0/apache2/php.ini - - # Settings rights for volume - chown -R www-data:www-data /var/lib/zoneminder/events - chown -R www-data:www-data /var/lib/zoneminder/images -} - - -setup_mysql -setup_php - -exit 0 diff --git a/utils/docker/start.sh b/utils/docker/start.sh deleted file mode 100755 index 599b6fcb2..000000000 --- a/utils/docker/start.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash - -# Prepare proper amount of shared memory -# For H.264 cameras it may be necessary to increase the amount of shared memory -# to 2048 megabytes. -umount /dev/shm -mount -t tmpfs -o rw,nosuid,nodev,noexec,relatime,size=512M tmpfs /dev/shm - -# Start MySQL -test -e /var/run/mysqld || install -m 755 -o mysql -g root -d /var/run/mysqld -su - mysql -s /bin/sh -c "/usr/bin/mysqld_safe > /dev/null 2>&1 &" - -# Ensure we shut down mysql cleanly later: -trap close_mysql SIGTERM - -# Give MySQL time to wake up -SECONDS_LEFT=120 -while true; do - sleep 1 - mysqladmin ping - if [ $? -eq 0 ];then - break; # Success - fi - let SECONDS_LEFT=SECONDS_LEFT-1 - - # If we have waited >120 seconds, give up - # ZM should never have a database that large! - # if $COUNTER -lt 120 - if [ $SECONDS_LEFT -eq 0 ];then - return -1; - fi -done - -# Restart apache -service apache2 restart - -# Start ZoneMinder -/usr/local/bin/zmpkg.pl start && echo "Zone Minder started" - -while : -do - sleep 3600 -done - -function close_mysql { - kill $(cat /var/run/mysqld/mysqld.pid) - sleep 5 -} From 8dc6910bbd9a87c2a130c20bfacde682ed233f39 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sat, 20 Jan 2018 17:34:37 -0600 Subject: [PATCH 054/154] Remove reference to zm 1.29, update description of isaac's ppa --- docs/installationguide/ubuntu.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/installationguide/ubuntu.rst b/docs/installationguide/ubuntu.rst index fe95754d1..4dbb7c9bf 100644 --- a/docs/installationguide/ubuntu.rst +++ b/docs/installationguide/ubuntu.rst @@ -30,9 +30,14 @@ guide you with a quick search. .. topic :: Latest Release - ZoneMinder 1.29.0 is now part of the current standard Ubuntu repository. But - if you wish to install the later releases of ZoneMinder you will need - to add the iconnor/zoneminder PPA. + ZoneMinder is now part of the current standard Ubuntu repository, but + sometimes the official repository can lag behind. The find out check our + [releases page](https://github.com/ZoneMinder/zoneminder/releases) for + the latest release. + + Alternatively, the ZoneMinder project team maintains a ppa, which is updated immediately + following a new release of ZoneMinder. To use this repository instead of the + official Ubuntu repository, enter the following from the command line: :: From 06c2c1813536c2912875ae27fda856e68f963cd3 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sat, 20 Jan 2018 17:46:15 -0600 Subject: [PATCH 055/154] fix url to display properly --- docs/installationguide/ubuntu.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/installationguide/ubuntu.rst b/docs/installationguide/ubuntu.rst index 4dbb7c9bf..7d9f53995 100644 --- a/docs/installationguide/ubuntu.rst +++ b/docs/installationguide/ubuntu.rst @@ -32,8 +32,8 @@ guide you with a quick search. ZoneMinder is now part of the current standard Ubuntu repository, but sometimes the official repository can lag behind. The find out check our - [releases page](https://github.com/ZoneMinder/zoneminder/releases) for - the latest release. + `releases page `_ for + the latest release. Alternatively, the ZoneMinder project team maintains a ppa, which is updated immediately following a new release of ZoneMinder. To use this repository instead of the From 9a8a72ba278814562b485ba636db954e7a57cc6e Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sat, 20 Jan 2018 17:46:53 -0600 Subject: [PATCH 056/154] typo --- docs/installationguide/ubuntu.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/installationguide/ubuntu.rst b/docs/installationguide/ubuntu.rst index 7d9f53995..e7c821838 100644 --- a/docs/installationguide/ubuntu.rst +++ b/docs/installationguide/ubuntu.rst @@ -31,7 +31,7 @@ guide you with a quick search. .. topic :: Latest Release ZoneMinder is now part of the current standard Ubuntu repository, but - sometimes the official repository can lag behind. The find out check our + sometimes the official repository can lag behind. To find out check our `releases page `_ for the latest release. From ce19c65cc9bf209b187e64e3720b8ea77b86da70 Mon Sep 17 00:00:00 2001 From: Simpler1 Date: Mon, 22 Jan 2018 15:33:11 -0500 Subject: [PATCH 057/154] Ipcc (#2040) * fix(ipcc): Invert up/down to work properly * fix(ipcc): Change the initial values for ipcc camera --- db/zm_create.sql.in | 2 +- .../ZoneMinder/lib/ZoneMinder/Control/IPCC7210W.pm | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 699008b75..7af72b613 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -597,7 +597,7 @@ INSERT INTO `Controls` VALUES (NULL,'Foscam 9831W','Ffmpeg','FI9831W',0,0,1,0,0, INSERT INTO `Controls` VALUES (NULL,'Foscam FI8918W','Ffmpeg','FI8918W',0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,8,0,1,1,1,0,0,0,1,1,0,360,0,360,1,0,4,0,0,1,0,90,0,90,1,0,4,0,0,0,0); INSERT INTO `Controls` VALUES (NULL,'SunEyes SP-P1802SWPTZ','Libvlc','SPP1802SWPTZ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,8,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,64,0,0,1,0,0,0,0,1,0,64,0,0,0,0); INSERT INTO `Controls` VALUES (NULL,'Wanscam HW0025','Libvlc','WanscamHW0025', 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 350, 0, 0, 1, 0, 10, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0); -INSERT INTO `Controls` VALUES (NULL,'IPCC 7210W','Libvlc','IPCC7210W', 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 350, 0, 0, 1, 0, 10, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0); +INSERT INTO `Controls` VALUES (NULL,'IPCC 7210W','Remote','IPCC7210W', 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); INSERT INTO `Controls` VALUES (NULL,'Vivotek ePTZ','Remote','Vivotek_ePTZ',0,0,1,1,0,0,0,1,0,0,0,0,1,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,0,5,0,0,1,0,0,0,0,1,0,5,0,0,0,0); INSERT INTO `Controls` VALUES (NULL,'Netcat ONVIF','Ffmpeg','Netcat',0,0,1,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,100,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,100,5,5,0,0,0,1,255,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0); INSERT INTO `Controls` VALUES (NULL,'Keekoon','Remote','Keekoon', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/IPCC7210W.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/IPCC7210W.pm index 01cff6c62..f3ac081a5 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/IPCC7210W.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/IPCC7210W.pm @@ -139,7 +139,7 @@ sub moveConUp my $self = shift; my $params = shift; Debug( "Move Up" ); - my $cmd = "decoder_control.cgi?command=0&onestep=1&"; + my $cmd = "decoder_control.cgi?command=2&onestep=1&"; $self->sendCmd( $cmd ); my $autostop = $self->getParam( $params, 'autostop', 0 ); if ( $autostop && $self->{Monitor}->{AutoStopTimeout} ) @@ -155,7 +155,7 @@ sub moveConDown my $self = shift; my $params = shift; Debug( "Move Down" ); - my $cmd = "decoder_control.cgi?command=2&onestep=1&"; + my $cmd = "decoder_control.cgi?command=0&onestep=1&"; $self->sendCmd( $cmd ); my $autostop = $self->getParam( $params, 'autostop', 0 ); if ( $autostop && $self->{Monitor}->{AutoStopTimeout} ) @@ -203,7 +203,7 @@ sub moveConUpRight my $self = shift; my $params = shift; Debug( "Move Diagonally Up Right" ); - my $cmd = "decoder_control.cgi?command=91&onestep=1&"; + my $cmd = "decoder_control.cgi?command=93&onestep=1&"; $self->sendCmd( $cmd ); my $autostop = $self->getParam( $params, 'autostop', 0 ); if ( $autostop && $self->{Monitor}->{AutoStopTimeout} ) @@ -219,7 +219,7 @@ sub moveConDownRight my $self = shift; my $params = shift; Debug( "Move Diagonally Down Right" ); - my $cmd = "decoder_control.cgi?command=93&onestep=1&"; + my $cmd = "decoder_control.cgi?command=91&onestep=1&"; $self->sendCmd( $cmd ); my $autostop = $self->getParam( $params, 'autostop', 0 ); if ( $autostop && $self->{Monitor}->{AutoStopTimeout} ) @@ -235,7 +235,7 @@ sub moveConUpLeft my $self = shift; my $params = shift; Debug( "Move Diagonally Up Left" ); - my $cmd = "decoder_control.cgi?command=90&onestep=1&"; + my $cmd = "decoder_control.cgi?command=92&onestep=1&"; $self->sendCmd( $cmd ); my $autostop = $self->getParam( $params, 'autostop', 0 ); if ( $autostop && $self->{Monitor}->{AutoStopTimeout} ) @@ -251,7 +251,7 @@ sub moveConDownLeft my $self = shift; my $params = shift; Debug( "Move Diagonally Down Left" ); - my $cmd = "decoder_control.cgi?command=92&onestep=1&"; + my $cmd = "decoder_control.cgi?command=90&onestep=1&"; $self->sendCmd( $cmd ); my $autostop = $self->getParam( $params, 'autostop', 0 ); if ( $autostop && $self->{Monitor}->{AutoStopTimeout} ) @@ -275,7 +275,7 @@ sub presetHome { my $self = shift; Debug( "Home Preset" ); - my $cmd = "decoder_control.cgi?command=25&onestep=0&"; + my $cmd = "decoder_control.cgi?command=4&onestep=0&"; $self->sendCmd( $cmd ); } From 447a0975c71ff6fdb7fd5f2c96b5ff960fbdaa09 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 23 Jan 2018 13:15:48 -0800 Subject: [PATCH 058/154] fix bracket --- web/api/app/Controller/MonitorsController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/api/app/Controller/MonitorsController.php b/web/api/app/Controller/MonitorsController.php index 77113e892..c372463c1 100644 --- a/web/api/app/Controller/MonitorsController.php +++ b/web/api/app/Controller/MonitorsController.php @@ -171,7 +171,7 @@ class MonitorsController extends AppController { $func = $Monitor['Function']; // We don't pass the request data as the monitor object because it may be a subset of the full monitor array $this->daemonControl( $this->Monitor->id, 'stop' ); - if ( ( $func != 'None' ) and ( (!defined('ZM_SERVER_ID']) or ($Monitor['ServerId']==ZM_SERVER_ID) ) ) { + if ( ( $func != 'None' ) and ( (!defined('ZM_SERVER_ID')) or ($Monitor['ServerId']==ZM_SERVER_ID) ) ) { $this->daemonControl( $this->Monitor->id, 'start' ); } } // end function edit From e364a541d4f34fea9cf64e7cf7fda5c572f62e13 Mon Sep 17 00:00:00 2001 From: Isaac Date: Wed, 24 Jan 2018 22:21:43 +0100 Subject: [PATCH 059/154] Whitespace and use ZM_DIR_EXPORT instead of ZM_DIR_TMP --- web/views/archive.php | 59 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/web/views/archive.php b/web/views/archive.php index ce4e1b274..9238a925e 100644 --- a/web/views/archive.php +++ b/web/views/archive.php @@ -18,45 +18,44 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // -if ( !canView( 'Events' ) ) -{ - $view = "error"; - return; +if ( !canView( 'Events' ) ) { + $view = 'error'; + return; } $archivetype = $_REQUEST['type']; if ( $archivetype ) { - switch ($archivetype) { - case "tar": - $mimetype = "gzip"; - $file_ext = "tar.gz"; - break; - case "zip": - $mimetype = "zip"; - $file_ext = "zip"; - break; - default: - $mimetype = NULL; - $file_ext = NULL; - } + switch ($archivetype) { + case 'tar': + $mimetype = 'gzip'; + $file_ext = 'tar.gz'; + break; + case 'zip': + $mimetype = 'zip'; + $file_ext = 'zip'; + break; + default: + $mimetype = NULL; + $file_ext = NULL; + } - if ( $mimetype ) { - $filename = "zmExport.$file_ext"; - $filename_path = ZM_DIR_TEMP."/".$filename; - if ( is_readable($filename_path) ) { - header( "Content-type: application/$mimetype" ); - header( "Content-Disposition: attachment; filename=$filename"); - set_time_limit(0); - readfile( $filename_path ); - } else { - Error("$filename_path does not exist or is not readable."); - } + if ( $mimetype ) { + $filename = "zmExport.$file_ext"; + $filename_path = ZM_DIR_EXPORTS.'/'.$filename; + if ( is_readable($filename_path) ) { + header( "Content-type: application/$mimetype" ); + header( "Content-Disposition: attachment; filename=$filename"); + set_time_limit(0); + readfile( $filename_path ); } else { - Error("Unsupported archive type specified. Supported archives are tar and zip"); + Error("$filename_path does not exist or is not readable."); } + } else { + Error("Unsupported archive type specified. Supported archives are tar and zip"); + } } else { - Error("No archive type given to archive.php. Please specify a tar or zip archive."); + Error("No archive type given to archive.php. Please specify a tar or zip archive."); } ?> From 5865bbfb1290657b577788f03f7595100108787e Mon Sep 17 00:00:00 2001 From: Isaac Date: Wed, 24 Jan 2018 23:07:21 +0100 Subject: [PATCH 060/154] turn off debugging --- web/index.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/web/index.php b/web/index.php index c3f2269fe..3ebc58a98 100644 --- a/web/index.php +++ b/web/index.php @@ -174,17 +174,13 @@ foreach ( getSkinIncludes( 'skin.php' ) as $includeFile ) require_once $includeFile; if ( ZM_OPT_USE_AUTH && ZM_AUTH_HASH_LOGINS ) { - Logger::Debug("Useing hash"); if ( empty($user) && ! empty($_REQUEST['auth']) ) { if ( $authUser = getAuthUser( $_REQUEST['auth'] ) ) { userLogin( $authUser['Username'], $authUser['Password'], true ); } } else if ( ! empty($user) ) { - Logger::Debug("generating hash"); // generate it once here, while session is open. Value will be cached in session and return when called later on generateAuthHash( ZM_AUTH_HASH_IPS ); - } else { - Logger::Debug(" not generating hash"); } } From e4c28150fe066a17b739e50672b5c0a8732ff423 Mon Sep 17 00:00:00 2001 From: Isaac Date: Wed, 24 Jan 2018 23:07:57 +0100 Subject: [PATCH 061/154] cleanup, code style, quotes. Include jquery source instead of trying to link to it --- .../classic/includes/export_functions.php | 391 ++++++++---------- 1 file changed, 171 insertions(+), 220 deletions(-) diff --git a/web/skins/classic/includes/export_functions.php b/web/skins/classic/includes/export_functions.php index f384594da..8a53394fa 100644 --- a/web/skins/classic/includes/export_functions.php +++ b/web/skins/classic/includes/export_functions.php @@ -71,7 +71,9 @@ html ul.tabs li.active, html ul.tabs li.active a:hover { } --> - + From 984d3a2dd1ed47659e0762c8d780cc951d4e3952 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 07:30:46 -0800 Subject: [PATCH 102/154] add Monitor Name to the response listing the available camera feeds --- web/skins/classic/views/js/add_monitors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/add_monitors.js b/web/skins/classic/views/js/add_monitors.js index 369f69ff3..d8ad8e1ac 100644 --- a/web/skins/classic/views/js/add_monitors.js +++ b/web/skins/classic/views/js/add_monitors.js @@ -34,7 +34,7 @@ function parseStreams( Streams ) { for( i in Streams ) { var stream = Streams[i]; if ( stream.url ) { - html += '

'+stream.url; + html += '

'+stream.Monitor.Name + ' at ' + stream.url; if ( stream.Monitor.Id ) { html += ' is already entered into the system by Monitor ' + stream.Monitor.Id + ' ' + stream.Monitor.Name + '
'; html += ''; From b793e6659bf467ef989fc8f6627905879a862c2e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 07:32:02 -0800 Subject: [PATCH 103/154] add onFailure logger, and change link to chain so that responses don't just disappear --- web/skins/classic/views/js/watch.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 9831bf519..513baee6d 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -106,17 +106,28 @@ function setAlarmState( currentAlarmState ) { var streamCmdParms = "view=request&request=stream&connkey="+connKey; if ( auth_hash ) streamCmdParms += '&auth='+auth_hash; - -var streamCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStreamCmdResponse } ); +console.log("AJAX_TIMEOUT:"+AJAX_TIMEOUT + ' url:' + monitorUrl+thisUrl + ' parms: ' + streamCmdParms ); +var streamCmdReq = new Request.JSON( { + url: monitorUrl+thisUrl, + method: 'get', + timeout: AJAX_TIMEOUT, + link: 'chain', + onSuccess: getStreamCmdResponse, + onFailure: getStreamCmdFailure +} ); var streamCmdTimer = null; var streamStatus; +function getStreamCmdFailure(xhr) { +console.log(xhr); +} function getStreamCmdResponse( respObj, respText ) { +console.log(respText); watchdogOk("stream"); if ( streamCmdTimer ) streamCmdTimer = clearTimeout( streamCmdTimer ); - +console.log(respText); if ( respObj.result == 'Ok' ) { streamStatus = respObj.status; $('fpsValue').set( 'text', streamStatus.fps ); From dc6842bfbd15d43760cf45ef0dee97b505d82443 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 07:32:40 -0800 Subject: [PATCH 104/154] Add remote server port to monitor url --- web/skins/classic/views/js/watch.js.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/watch.js.php b/web/skins/classic/views/js/watch.js.php index c0c8ab590..79b48de94 100644 --- a/web/skins/classic/views/js/watch.js.php +++ b/web/skins/classic/views/js/watch.js.php @@ -48,7 +48,7 @@ var maxDisplayEvents = ; var monitorId = Id() ?>; var monitorWidth = Width() ?>; var monitorHeight = Height() ?>; -var monitorUrl = 'Server()->Url() ) ?>'; +var monitorUrl = 'Server()->Url() . ( ZM_MIN_STREAMING_PORT ? ':'. (ZM_MIN_STREAMING_PORT+$monitor->Id()) : '' ) ) ?>'; var scale = ''; From 03122b9015810a083f19b69dc3b44d7de9fe9804 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 07:32:02 -0800 Subject: [PATCH 105/154] add onFailure logger, and change link to chain so that responses don't just disappear --- web/skins/classic/views/js/watch.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 9831bf519..513baee6d 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -106,17 +106,28 @@ function setAlarmState( currentAlarmState ) { var streamCmdParms = "view=request&request=stream&connkey="+connKey; if ( auth_hash ) streamCmdParms += '&auth='+auth_hash; - -var streamCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStreamCmdResponse } ); +console.log("AJAX_TIMEOUT:"+AJAX_TIMEOUT + ' url:' + monitorUrl+thisUrl + ' parms: ' + streamCmdParms ); +var streamCmdReq = new Request.JSON( { + url: monitorUrl+thisUrl, + method: 'get', + timeout: AJAX_TIMEOUT, + link: 'chain', + onSuccess: getStreamCmdResponse, + onFailure: getStreamCmdFailure +} ); var streamCmdTimer = null; var streamStatus; +function getStreamCmdFailure(xhr) { +console.log(xhr); +} function getStreamCmdResponse( respObj, respText ) { +console.log(respText); watchdogOk("stream"); if ( streamCmdTimer ) streamCmdTimer = clearTimeout( streamCmdTimer ); - +console.log(respText); if ( respObj.result == 'Ok' ) { streamStatus = respObj.status; $('fpsValue').set( 'text', streamStatus.fps ); From 7eaa0180e5a6a4d318c70e34fd0c62fc559cef5b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 07:22:05 -0800 Subject: [PATCH 106/154] Better debugging --- src/zm_monitorstream.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/zm_monitorstream.cpp b/src/zm_monitorstream.cpp index 0dd412786..7baa7fc98 100644 --- a/src/zm_monitorstream.cpp +++ b/src/zm_monitorstream.cpp @@ -338,7 +338,7 @@ void MonitorStream::processCommand( const CmdMsg *msg ) { //exit( -1 ); } } -Debug(2, "NUmber of bytes sent: (%d)", nbytes ); +Debug(2, "NUmber of bytes sent to (%s): (%d)", rem_addr.sun_path, nbytes ); // quit after sending a status, if this was a quit request if ( (MsgCommand)msg->msg_data[0]==CMD_QUIT ) { @@ -663,7 +663,7 @@ Debug(2, "Have checking command Queue for connkey: %d", connkey ); if ( last_read_index != monitor->shared_data->last_write_index ) { int index = monitor->shared_data->last_write_index % monitor->image_buffer_count; // % shouldn't be neccessary last_read_index = monitor->shared_data->last_write_index; - Debug( 1, "index: %d: frame_mod: %d frame count: %d", index, frame_mod, frame_count ); + Debug( 3, "index: %d: frame_mod: %d frame count: %d", index, frame_mod, frame_count ); if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) { if ( !paused && !delayed ) { // Send the next frame @@ -712,11 +712,11 @@ Debug(2, "Have checking command Queue for connkey: %d", connkey ); } // end if buffered playback frame_count++; } else { - Debug(2,"Waiting for capture"); + Debug(5,"Waiting for capture"); } // end if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index ) unsigned long sleep_time = (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2))); - Debug(2, "Sleeping for (%d)", sleep_time); + Debug(4, "Sleeping for (%d)", sleep_time); usleep( sleep_time ); if ( ttl ) { if ( (now.tv_sec - stream_start_time) > ttl ) { From c89d4e424e65191d66012e4bead011c57bfad1f3 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 07:40:37 -0800 Subject: [PATCH 107/154] Add error check for no Storage Areas found for this server --- scripts/zmaudit.pl.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index 25b6e6e39..ee63a0811 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -180,6 +180,9 @@ MAIN: while( $loop ) { Info("Auditing Storage Area $Storage_Areas[0]{Id} $Storage_Areas[0]{Name} at $Storage_Areas[0]{Path}"); } elsif ( $Config{ZM_SERVER_ID} ) { @Storage_Areas = ZoneMinder::Storage->find( ServerId => $Config{ZM_SERVER_ID} ); + if ( ! @Storage_Areas ) { + Fatal("No Storage Area found with ServerId =" . $Config{ZM_SERVER_ID}); + } Info("Auditing All Storage Areas on Server " . $Storage_Areas[0]->Server()->Name()); } else { @Storage_Areas = ZoneMinder::Storage->find(); From bfbd033971356b6fc55222d6d3a2bf8d562e0f69 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 07:21:31 -0800 Subject: [PATCH 108/154] Fix getting stream status updates when # of files open is > 1024. --- web/ajax/stream.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/web/ajax/stream.php b/web/ajax/stream.php index 0337d2c3c..13ad09b29 100644 --- a/web/ajax/stream.php +++ b/web/ajax/stream.php @@ -1,4 +1,5 @@ 0 ) { if ( count($rSockets) != 1 ) { Error( 'Bogus return from select, '.count($rSockets).' sockets available' ); From e672841a8d917dd6ef7b9ecd3fc911b5858f1d79 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 07:32:40 -0800 Subject: [PATCH 109/154] Add remote server port to monitor url --- web/skins/classic/views/js/watch.js.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/watch.js.php b/web/skins/classic/views/js/watch.js.php index c0c8ab590..79b48de94 100644 --- a/web/skins/classic/views/js/watch.js.php +++ b/web/skins/classic/views/js/watch.js.php @@ -48,7 +48,7 @@ var maxDisplayEvents = ; var monitorId = Id() ?>; var monitorWidth = Width() ?>; var monitorHeight = Height() ?>; -var monitorUrl = 'Server()->Url() ) ?>'; +var monitorUrl = 'Server()->Url() . ( ZM_MIN_STREAMING_PORT ? ':'. (ZM_MIN_STREAMING_PORT+$monitor->Id()) : '' ) ) ?>'; var scale = ''; From a782ef1db7173eabdd49429fc3c1e24a82065925 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 07:45:28 -0800 Subject: [PATCH 110/154] Add debug tests for loading all events --- web/skins/classic/views/events.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/skins/classic/views/events.php b/web/skins/classic/views/events.php index 7218b67f6..0636eb3cf 100644 --- a/web/skins/classic/views/events.php +++ b/web/skins/classic/views/events.php @@ -43,6 +43,8 @@ $filterQuery = $_REQUEST['filter']['query']; if ( $_REQUEST['filter']['sql'] ) { $countSql .= $_REQUEST['filter']['sql']; $eventsSql .= $_REQUEST['filter']['sql']; +} else { +Error("No filtering in events, will load ALL!"); } $eventsSql .= " ORDER BY $sortColumn $sortOrder"; @@ -141,6 +143,7 @@ if ( $pages > 1 ) { $count = 0; $disk_space_total = 0; +Logger::Debug("EventSql: $eventsSql"); $results = dbQuery( $eventsSql ); while ( $event_row = dbFetchNext( $results ) ) { $event = new Event( $event_row ); From 73d84c6b0897cdbcd38355bb7187114a24987473 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 07:53:48 -0800 Subject: [PATCH 111/154] fix typo --- web/includes/Monitor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index 357f7a9b8..a32b03a6d 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -18,7 +18,7 @@ private $defaults = array( 'ZoneCount' => 0, 'Triggers' => null, ); -$private $status_fields = array( +private $status_fields = array( 'AnalysisFPS' => null, 'CaptureFPS' => null, ); From a76fcb331c6e074760ab9d2ae1ddcba85b8c0e41 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 08:25:46 -0800 Subject: [PATCH 112/154] Remove debugging. Treat can't get semaphore as a non-error --- web/ajax/stream.php | 5 +- web/skins/classic/views/js/watch.js | 158 ++++++++++++++-------------- 2 files changed, 82 insertions(+), 81 deletions(-) diff --git a/web/ajax/stream.php b/web/ajax/stream.php index 13ad09b29..5dbfae6eb 100644 --- a/web/ajax/stream.php +++ b/web/ajax/stream.php @@ -166,10 +166,11 @@ if ( sem_acquire($semaphore,1) !== false ) { } sem_release($semaphore); } else { - Error("Couldn't get semaphore"); + Logger::Debug("Couldn't get semaphore"); + ajaxResponse( array() ); } -ajaxError( 'Unrecognised action or insufficient permissions' ); +ajaxError('Unrecognised action or insufficient permissions in ajax/stream'); function ajaxCleanup() { global $socket, $localSocketFile; diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 513baee6d..430a9bdb3 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -106,7 +106,6 @@ function setAlarmState( currentAlarmState ) { var streamCmdParms = "view=request&request=stream&connkey="+connKey; if ( auth_hash ) streamCmdParms += '&auth='+auth_hash; -console.log("AJAX_TIMEOUT:"+AJAX_TIMEOUT + ' url:' + monitorUrl+thisUrl + ' parms: ' + streamCmdParms ); var streamCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'get', @@ -123,95 +122,96 @@ function getStreamCmdFailure(xhr) { console.log(xhr); } function getStreamCmdResponse( respObj, respText ) { -console.log(respText); watchdogOk("stream"); if ( streamCmdTimer ) streamCmdTimer = clearTimeout( streamCmdTimer ); -console.log(respText); if ( respObj.result == 'Ok' ) { - streamStatus = respObj.status; - $('fpsValue').set( 'text', streamStatus.fps ); + // The get status command can get backed up, in which case we won't be able to get the semaphore and will exit. + if ( respObj.status ) { + streamStatus = respObj.status; + $('fpsValue').set( 'text', streamStatus.fps ); - setAlarmState( streamStatus.state ); + setAlarmState( streamStatus.state ); - $('levelValue').set( 'text', streamStatus.level ); - if ( streamStatus.level > 95 ) - $('levelValue').className = "alarm"; - else if ( streamStatus.level > 80 ) - $('levelValue').className = "alert"; - else - $('levelValue').className = "ok"; + $('levelValue').set( 'text', streamStatus.level ); + if ( streamStatus.level > 95 ) + $('levelValue').className = "alarm"; + else if ( streamStatus.level > 80 ) + $('levelValue').className = "alert"; + else + $('levelValue').className = "ok"; - var delayString = secsToTime( streamStatus.delay ); + var delayString = secsToTime( streamStatus.delay ); - if ( streamStatus.paused == true ) { - $('modeValue').set( 'text', "Paused" ); - $('rate').addClass( 'hidden' ); - $('delayValue').set( 'text', delayString ); - $('delay').removeClass( 'hidden' ); - $('level').removeClass( 'hidden' ); - streamCmdPause( false ); - } else if ( streamStatus.delayed == true ) { - $('modeValue').set( 'text', "Replay" ); - $('rateValue').set( 'text', streamStatus.rate ); - $('rate').removeClass( 'hidden' ); - $('delayValue').set( 'text', delayString ); - $('delay').removeClass( 'hidden' ); - $('level').removeClass( 'hidden' ); - if ( streamStatus.rate == 1 ) { - streamCmdPlay( false ); - } else if ( streamStatus.rate > 0 ) { - if ( streamStatus.rate < 1 ) - streamCmdSlowFwd( false ); - else - streamCmdFastFwd( false ); - } else { - if ( streamStatus.rate > -1 ) - streamCmdSlowRev( false ); - else - streamCmdFastRev( false ); - } // rate - } else { - $('modeValue').set( 'text', "Live" ); - $('rate').addClass( 'hidden' ); - $('delay').addClass( 'hidden' ); - $('level').addClass( 'hidden' ); - streamCmdPlay( false ); - } // end if paused or delayed - - $('zoomValue').set( 'text', streamStatus.zoom ); - if ( streamStatus.zoom == "1.0" ) - setButtonState( $('zoomOutBtn'), 'unavail' ); - else - setButtonState( $('zoomOutBtn'), 'inactive' ); - - if ( canEditMonitors ) { - if ( streamStatus.enabled ) { - $('enableAlarmsLink').addClass( 'hidden' ); - $('disableAlarmsLink').removeClass( 'hidden' ); - if ( streamStatus.forced ) { - $('forceAlarmLink').addClass( 'hidden' ); - $('cancelAlarmLink').removeClass( 'hidden' ); + if ( streamStatus.paused == true ) { + $('modeValue').set( 'text', "Paused" ); + $('rate').addClass( 'hidden' ); + $('delayValue').set( 'text', delayString ); + $('delay').removeClass( 'hidden' ); + $('level').removeClass( 'hidden' ); + streamCmdPause( false ); + } else if ( streamStatus.delayed == true ) { + $('modeValue').set( 'text', "Replay" ); + $('rateValue').set( 'text', streamStatus.rate ); + $('rate').removeClass( 'hidden' ); + $('delayValue').set( 'text', delayString ); + $('delay').removeClass( 'hidden' ); + $('level').removeClass( 'hidden' ); + if ( streamStatus.rate == 1 ) { + streamCmdPlay( false ); + } else if ( streamStatus.rate > 0 ) { + if ( streamStatus.rate < 1 ) + streamCmdSlowFwd( false ); + else + streamCmdFastFwd( false ); } else { - $('forceAlarmLink').removeClass( 'hidden' ); - $('cancelAlarmLink').addClass( 'hidden' ); - } - $('forceCancelAlarm').removeClass( 'hidden' ); + if ( streamStatus.rate > -1 ) + streamCmdSlowRev( false ); + else + streamCmdFastRev( false ); + } // rate } else { - $('enableAlarmsLink').removeClass( 'hidden' ); - $('disableAlarmsLink').addClass( 'hidden' ); - $('forceCancelAlarm').addClass( 'hidden' ); - } - $('enableDisableAlarms').removeClass( 'hidden' ); - } // end if canEditMonitors + $('modeValue').set( 'text', "Live" ); + $('rate').addClass( 'hidden' ); + $('delay').addClass( 'hidden' ); + $('level').addClass( 'hidden' ); + streamCmdPlay( false ); + } // end if paused or delayed - if ( streamStatus.auth ) { - console.log("Haev a new auth hash" + streamStatus.auth); - // Try to reload the image stream. - var streamImg = $('liveStream'); - if ( streamImg ) - streamImg.src = streamImg.src.replace( /auth=\w+/i, 'auth='+streamStatus.auth ); - } // end if haev a new auth hash + $('zoomValue').set( 'text', streamStatus.zoom ); + if ( streamStatus.zoom == "1.0" ) + setButtonState( $('zoomOutBtn'), 'unavail' ); + else + setButtonState( $('zoomOutBtn'), 'inactive' ); + + if ( canEditMonitors ) { + if ( streamStatus.enabled ) { + $('enableAlarmsLink').addClass( 'hidden' ); + $('disableAlarmsLink').removeClass( 'hidden' ); + if ( streamStatus.forced ) { + $('forceAlarmLink').addClass( 'hidden' ); + $('cancelAlarmLink').removeClass( 'hidden' ); + } else { + $('forceAlarmLink').removeClass( 'hidden' ); + $('cancelAlarmLink').addClass( 'hidden' ); + } + $('forceCancelAlarm').removeClass( 'hidden' ); + } else { + $('enableAlarmsLink').removeClass( 'hidden' ); + $('disableAlarmsLink').addClass( 'hidden' ); + $('forceCancelAlarm').addClass( 'hidden' ); + } + $('enableDisableAlarms').removeClass( 'hidden' ); + } // end if canEditMonitors + + if ( streamStatus.auth ) { + console.log("Haev a new auth hash" + streamStatus.auth); + // Try to reload the image stream. + var streamImg = $('liveStream'); + if ( streamImg ) + streamImg.src = streamImg.src.replace( /auth=\w+/i, 'auth='+streamStatus.auth ); + } // end if haev a new auth hash + } // end if respObj.status } else { checkStreamForErrors("getStreamCmdResponse",respObj);//log them // Try to reload the image stream. From 525749c11a848719823befcaf5c97c2090239689 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 11:44:03 -0500 Subject: [PATCH 113/154] Need drop permissions --- distros/ubuntu1604/zoneminder.postinst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/distros/ubuntu1604/zoneminder.postinst b/distros/ubuntu1604/zoneminder.postinst index 35d839cc2..3d8e09a1c 100644 --- a/distros/ubuntu1604/zoneminder.postinst +++ b/distros/ubuntu1604/zoneminder.postinst @@ -33,9 +33,9 @@ if [ "$1" = "configure" ]; then if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf # This creates the user. - echo "grant lock tables,alter,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql + echo "grant lock tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql else - echo "grant lock tables,alter,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql + echo "grant lock tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql fi zmupdate.pl --nointeractive From 7074681e60723283e7a0b19d7bfac1e43319508d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 11:44:29 -0500 Subject: [PATCH 114/154] Need drop permissions --- distros/ubuntu1204/zoneminder.postinst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/distros/ubuntu1204/zoneminder.postinst b/distros/ubuntu1204/zoneminder.postinst index 7d9a9fe8a..06b976037 100644 --- a/distros/ubuntu1204/zoneminder.postinst +++ b/distros/ubuntu1204/zoneminder.postinst @@ -31,9 +31,9 @@ if [ "$1" = "configure" ]; then if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf # This creates the user. - echo "grant lock tables, alter,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql + echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql else - echo "grant lock tables, alter,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql + echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql fi zmupdate.pl --nointeractive From 1d221dff7ca4b6081dbba8c6b735bd84cdfc7f4c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 11:45:33 -0500 Subject: [PATCH 115/154] Frame throttling is not an error. --- src/zm_monitorstream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_monitorstream.cpp b/src/zm_monitorstream.cpp index 7baa7fc98..fb3c24f75 100644 --- a/src/zm_monitorstream.cpp +++ b/src/zm_monitorstream.cpp @@ -396,7 +396,7 @@ bool MonitorStream::sendFrame( const char *filepath, struct timeval *timestamp ) int frameSendTime = tvDiffMsec( frameStartTime, frameEndTime ); if ( frameSendTime > 1000/maxfps ) { maxfps /= 2; - Error( "Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps ); + Info( "Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps ); } last_frame_sent = TV_2_FLOAT( now ); From e638817cb9a4fde5bc0a359c0b6cbcc9222bfb17 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 10:40:50 -0800 Subject: [PATCH 116/154] Check for ServerId exists in MonitorObject --- web/includes/Monitor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index a32b03a6d..6fb19c1ed 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -314,7 +314,7 @@ private $control_fields = array( } // end function save function zmcControl( $mode=false ) { - if ( (!defined('ZM_SERVER_ID')) or ( ZM_SERVER_ID==$this->{'ServerId'} ) ) { + if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) { if ( $this->{'Type'} == 'Local' ) { $zmcArgs = '-d '.$this->{'Device'}; } else { @@ -369,7 +369,7 @@ Logger::Debug("sending command to $url"); } // end function zmcControl function zmaControl( $mode=false ) { - if ( (!defined('ZM_SERVER_ID')) or ( ZM_SERVER_ID==$this->{'ServerId'} ) ) { + if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) { if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) { if ( ZM_OPT_CONTROL ) { daemonControl( 'stop', 'zmtrack.pl', '-m '.$this->{'Id'} ); From c9e32fb3445e919fc4d551f035d8e11a2f2a0cd8 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 10:41:09 -0800 Subject: [PATCH 117/154] Check for successful Monitor db Insertion --- web/includes/actions.php | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/web/includes/actions.php b/web/includes/actions.php index a69d23732..4e0829e03 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -551,22 +551,26 @@ Logger::Debug('coloumns:'.print_r($columns)); } } $restart = true; - } elseif ( ! $user['MonitorIds'] ) { // Can only create new monitors if we are not restricted to specific monitors + } else if ( ! $user['MonitorIds'] ) { // Can only create new monitors if we are not restricted to specific monitors # FIXME This is actually a race condition. Should lock the table. $maxSeq = dbFetchOne( 'SELECT max(Sequence) AS MaxSequence FROM Monitors', 'MaxSequence' ); $changes[] = 'Sequence = '.($maxSeq+1); - dbQuery( 'INSERT INTO Monitors SET '.implode( ', ', $changes ) ); - $mid = dbInsertId(); - $zoneArea = $_REQUEST['newMonitor']['Width'] * $_REQUEST['newMonitor']['Height']; - dbQuery( "insert into Zones set MonitorId = ?, Name = 'All', Type = 'Active', Units = 'Percent', NumCoords = 4, Coords = ?, Area=?, AlarmRGB = 0xff0000, CheckMethod = 'Blobs', MinPixelThreshold = 25, MinAlarmPixels=?, MaxAlarmPixels=?, FilterX = 3, FilterY = 3, MinFilterPixels=?, MaxFilterPixels=?, MinBlobPixels=?, MinBlobs = 1", array( $mid, sprintf( "%d,%d %d,%d %d,%d %d,%d", 0, 0, $_REQUEST['newMonitor']['Width']-1, 0, $_REQUEST['newMonitor']['Width']-1, $_REQUEST['newMonitor']['Height']-1, 0, $_REQUEST['newMonitor']['Height']-1 ), $zoneArea, intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*2)/100) ) ); - //$view = 'none'; - $Storage = new Storage( $_REQUEST['newMonitor']['StorageId'] ); - mkdir( $Storage->Path().'/'.$mid, 0755 ); - $saferName = basename($_REQUEST['newMonitor']['Name']); - symlink( $mid, $Storage->Path().'/'.$saferName ); - if ( isset($_COOKIE['zmGroup']) ) { - dbQuery( 'INSERT INTO Groups_Monitors (GroupId,MonitorId) VALUES (?,?)', array($_COOKIE['zmGroup'],$mid) ); + if ( dbQuery( 'INSERT INTO Monitors SET '.implode( ', ', $changes ) ) ) { + $mid = dbInsertId(); + $zoneArea = $_REQUEST['newMonitor']['Width'] * $_REQUEST['newMonitor']['Height']; + dbQuery( "insert into Zones set MonitorId = ?, Name = 'All', Type = 'Active', Units = 'Percent', NumCoords = 4, Coords = ?, Area=?, AlarmRGB = 0xff0000, CheckMethod = 'Blobs', MinPixelThreshold = 25, MinAlarmPixels=?, MaxAlarmPixels=?, FilterX = 3, FilterY = 3, MinFilterPixels=?, MaxFilterPixels=?, MinBlobPixels=?, MinBlobs = 1", array( $mid, sprintf( "%d,%d %d,%d %d,%d %d,%d", 0, 0, $_REQUEST['newMonitor']['Width']-1, 0, $_REQUEST['newMonitor']['Width']-1, $_REQUEST['newMonitor']['Height']-1, 0, $_REQUEST['newMonitor']['Height']-1 ), $zoneArea, intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*3)/100), intval(($zoneArea*75)/100), intval(($zoneArea*2)/100) ) ); + //$view = 'none'; + $Storage = new Storage( $_REQUEST['newMonitor']['StorageId'] ); + mkdir( $Storage->Path().'/'.$mid, 0755 ); + $saferName = basename($_REQUEST['newMonitor']['Name']); + symlink( $mid, $Storage->Path().'/'.$saferName ); + if ( isset($_COOKIE['zmGroup']) ) { + dbQuery( 'INSERT INTO Groups_Monitors (GroupId,MonitorId) VALUES (?,?)', array($_COOKIE['zmGroup'],$mid) ); + } + } else { + Error("Error saving new Monitor."); + return; } } else { Error("Users with Monitors restrictions cannot create new monitors."); From 31b7deb1013b3b84c97c26ef91e48aa66cd2658a Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 10:41:24 -0800 Subject: [PATCH 118/154] Return NULL on error in dbQuery --- web/includes/database.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/includes/database.php b/web/includes/database.php index 6bc6c0264..1fb18f0e8 100644 --- a/web/includes/database.php +++ b/web/includes/database.php @@ -142,8 +142,9 @@ function dbQuery( $sql, $params=NULL ) { } } catch(PDOException $e) { Error( "SQL-ERR '".$e->getMessage()."', statement was '".$sql."' params:" . ($params?implode(',',$params):'') ); + return NULL; } - return( $result ); + return $result; } function dbFetchOne( $sql, $col=false, $params=NULL ) { From 06673019f9169edff17bc80f7792f2f701762b6d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 10:41:43 -0800 Subject: [PATCH 119/154] add default values for zmstats, zmaudit, zmtrigger in new Server --- web/skins/classic/views/server.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/skins/classic/views/server.php b/web/skins/classic/views/server.php index 24f849c22..ae78d622f 100644 --- a/web/skins/classic/views/server.php +++ b/web/skins/classic/views/server.php @@ -32,6 +32,9 @@ if ( $_REQUEST['id'] ) { $newServer = array(); $newServer['Name'] = translate('NewServer'); $newServer['Hostname'] = ''; + $newServer['zmstats'] = ''; + $newServer['zmaudit'] = ''; + $newServer['zmtrigger'] = ''; } $focusWindow = true; From d19b8bc5cf32aac28bbc35a9fc5a0e522b689748 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 10:41:59 -0800 Subject: [PATCH 120/154] add default value for ServerId in new Storage Object --- web/skins/classic/views/storage.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/skins/classic/views/storage.php b/web/skins/classic/views/storage.php index 4b041f0f1..65ed57ea5 100644 --- a/web/skins/classic/views/storage.php +++ b/web/skins/classic/views/storage.php @@ -36,6 +36,7 @@ if ( $_REQUEST['id'] ) { $newStorage['Type'] = 'local'; $newStorage['Scheme'] = 'Medium'; $newStorage['StorageId'] = ''; + $newStorage['ServerId'] = ''; } $type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') ); From a60da6811b3244a1d89eee09de8917d0af18e8ea Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 15:17:22 -0500 Subject: [PATCH 121/154] revert adding custom port for status updates. It breaks in the non-multiserver case. --- web/skins/classic/views/js/montage.js.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/montage.js.php b/web/skins/classic/views/js/montage.js.php index b6470da3f..7f749d47a 100644 --- a/web/skins/classic/views/js/montage.js.php +++ b/web/skins/classic/views/js/montage.js.php @@ -35,7 +35,7 @@ monitorData[monitorData.length] = { 'connKey': connKey() ?>, 'width': Width() ?>, 'height':Height() ?>, - 'server_url': 'Server()->Url().(ZM_MIN_STREAMING_PORT?':'.(ZM_MIN_STREAMING_PORT+$monitor->Id()):'').$_SERVER['PHP_SELF'] ?>', + 'server_url': 'Server()->Url().$_SERVER['PHP_SELF'] ?>', 'onclick': function(){createPopup( '?view=watch&mid=Id() ?>', 'zmWatchId() ?>', 'watch', Width(), $monitor->PopupScale() ); ?>, Height(), $monitor->PopupScale() ); ?> );} }; Date: Mon, 29 Jan 2018 19:03:16 -0500 Subject: [PATCH 122/154] strip query and scheme from source --- web/skins/classic/views/console.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index 2d6a38f9e..8201dd674 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -247,6 +247,10 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { $url_parts = parse_url( $monitor['Path'] ); unset($url_parts['user']); unset($url_parts['pass']); + unset($url_parts['scheme']); + unset($url_parts['query']); + if ( isset($url_parts['port']) and ( $url_parts['port'] == '80' or $url_parts['port'] == '554' ) ) + unset($url_parts['port']); $source = unparse_url( $url_parts ); } if ( $source == '' ) { From 9f5c8078fc90f15d4104a401d197193f56dda0e8 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 21:16:41 -0500 Subject: [PATCH 123/154] handle when reading the link returns nothing --- scripts/zmaudit.pl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index ee63a0811..cdd283b28 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -269,7 +269,7 @@ MAIN: while( $loop ) { #Event path is hour/minute/sec my $event_path = readlink( $event_link ); - if ( !-e $event_path ) { + if ( !($event_path and -e $event_path) ) { aud_print( "Event link $day_dir/$event_link does not point to valid target" ); if ( confirm() ) { ( $event_link ) = ( $event_link =~ /^(.*)$/ ); # De-taint From 7ec71868a6875b94e78fa85ffee1150262f2349f Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 21:25:40 -0500 Subject: [PATCH 124/154] Switch CakePHP-Enum-Behavior to my fixed version --- web/api/app/Plugin/CakePHP-Enum-Behavior | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/api/app/Plugin/CakePHP-Enum-Behavior b/web/api/app/Plugin/CakePHP-Enum-Behavior index 7108489f2..ca91b87fd 160000 --- a/web/api/app/Plugin/CakePHP-Enum-Behavior +++ b/web/api/app/Plugin/CakePHP-Enum-Behavior @@ -1 +1 @@ -Subproject commit 7108489f218c54d36d235d3af91d6da2f8311237 +Subproject commit ca91b87fda8e006e4fca2ed870f24f9a29c2905d From 8c90a8a47a6a8c5a0ac9263a775eebe704f87ea8 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Jan 2018 23:06:59 -0500 Subject: [PATCH 125/154] Fix Id => MonitorId in MonitorStatus --- src/zmc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zmc.cpp b/src/zmc.cpp index 5169b0699..02413f0b9 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -223,7 +223,7 @@ int main(int argc, char *argv[]) { Info("Starting Capture version %s", ZM_VERSION); static char sql[ZM_SQL_SML_BUFSIZ]; for ( int i = 0; i < n_monitors; i ++ ) { - snprintf( sql, sizeof(sql), "REPLACE INTO Monitor_Status (Id, Status ) VALUES ('%d','Running')", monitors[i]->Id() ); + snprintf( sql, sizeof(sql), "REPLACE INTO Monitor_Status (MonitorId, Status ) VALUES ('%d','Running')", monitors[i]->Id() ); if ( mysql_query( &dbconn, sql ) ) { Error( "Can't run query: %s", mysql_error( &dbconn ) ); } From aea1816e8e28a8b73d2d66db4f17b7e8dac55615 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 30 Jan 2018 09:19:08 -0500 Subject: [PATCH 126/154] Add in signal handlers to as to complete an action before exiting. --- scripts/zmfilter.pl.in | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 1099d5fc2..12dae98cf 100644 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -73,6 +73,7 @@ use autouse 'Data::Dumper'=>qw(Dumper); my $filter_name = ''; my $filter_id; my $version = 0; +my $zm_terminate = 0; GetOptions( 'filter=s' =>\$filter_name, @@ -94,7 +95,20 @@ use constant EVENT_PATH => ($Config{ZM_DIR_EVENTS}=~m|/|) ; logInit(); -logSetSignal(); +sub HupHandler { + Info("Received HUP, reloading"); + &ZoneMinder::Logger::logHupHandler(); +} +sub TermHandler { + Info("Received TERM, exiting"); + $zm_terminate = 1; +} +sub Term { + exit( 0 ); +} +$SIG{HUP} = \&HupHandler; +$SIG{TERM} = \&TermHandler; +$SIG{INT} = \&TermHandler; if ( $Config{ZM_OPT_UPLOAD} ) { # Comment these out if you don't have them and don't want to upload @@ -166,7 +180,7 @@ if ( ! ( $filter_name or $filter_id ) ) { my @filters; my $last_action = 0; -while( 1 ) { +while( ! $zm_terminate ) { my $now = time; if ( ($now - $last_action) > $Config{ZM_FILTER_RELOAD_DELAY} ) { Debug( "Reloading filters\n" ); @@ -175,6 +189,7 @@ while( 1 ) { } foreach my $filter ( @filters ) { + last if $zm_terminate; if ( $$filter{Concurrent} and ! ( $filter_id or $filter_name ) ) { my ( $proc ) = $0 =~ /(\S+)/; my ( $id ) = $$filter{Id} =~ /(\d+)/; @@ -186,7 +201,7 @@ while( 1 ) { } } - last if ( $filter_name or $filter_id ); + last if $filter_name or $filter_id or $zm_terminate; Debug( "Sleeping for $delay seconds\n" ); sleep( $delay ); @@ -266,6 +281,7 @@ sub checkFilter { ) ); foreach my $event ( @Events ) { + last if $zm_terminate; Debug( "Checking event $event->{Id}" ); my $delete_ok = !undef; $dbh->ping(); From b1f2b677c316ab719b4773622b0c298ec87c727b Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 30 Jan 2018 10:09:12 -0500 Subject: [PATCH 127/154] remove path from source --- web/skins/classic/views/console.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index 8201dd674..60a48d6b3 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -249,6 +249,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { unset($url_parts['pass']); unset($url_parts['scheme']); unset($url_parts['query']); + unset($url_parts['path']); if ( isset($url_parts['port']) and ( $url_parts['port'] == '80' or $url_parts['port'] == '554' ) ) unset($url_parts['port']); $source = unparse_url( $url_parts ); From 4933b37b690a802801a02583cf25898ae9c6bdde Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 30 Jan 2018 10:45:32 -0500 Subject: [PATCH 128/154] fix log levels --- scripts/zmdc.pl.in | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/scripts/zmdc.pl.in b/scripts/zmdc.pl.in index 623769d81..538e2d8f1 100644 --- a/scripts/zmdc.pl.in +++ b/scripts/zmdc.pl.in @@ -183,39 +183,39 @@ use Sys::CpuLoad; socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" ); my $attempts = 0; - while( !connect( CLIENT, $saddr ) ) { + while( !connect(CLIENT, $saddr) ) { $attempts++; - Debug("Waiting for zmdc.pl server process at ".SOCK_FILE.", attempt $attempts" ); - Fatal( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY); + Debug("Waiting for zmdc.pl server process at ".SOCK_FILE.", attempt $attempts"); + Fatal("Can't connect: $!") if $attempts > MAX_CONNECT_DELAY; usleep(200000); } # end while } elsif ( defined($cpid) ) { ZMServer::run(); } else { - Fatal( "Can't fork: $!" ); + Fatal("Can't fork: $!"); } } # end if ! server is up -if ( $command eq 'check' && ! $daemon ) { - print( "running\n" ); +if ( ($command eq 'check') && !$daemon ) { + print("running\n"); exit(); } elsif ( $command eq 'startup' ) { # Our work here is done - exit() if ( !$server_up ); + exit() if !$server_up; } # The server is there, connect to it #print( "Writing commands\n" ); CLIENT->autoflush(); my $message = join(';', $command, ( $daemon ? $daemon : () ), @args ); -print( CLIENT $message ); -shutdown( CLIENT, 1 ); +print(CLIENT $message); +shutdown(CLIENT, 1); while( my $line = ) { - chomp( $line ); - print( "$line\n" ); + chomp($line); + print("$line\n"); } # And we're done! -close( CLIENT ); +close(CLIENT); #print( "Finished writing, bye\n" ); exit; @@ -344,9 +344,9 @@ sub run { } else { dPrint( ZoneMinder::Logger::ERROR, "Invalid command '$command'\n" ); } - close( CLIENT ); + close(CLIENT); } else { - Fatal( 'Bogus descriptor' ); + Fatal('Bogus descriptor'); } } elsif ( $nfound < 0 ) { if ( $! == EINTR ) { @@ -355,9 +355,9 @@ sub run { # See if it needs to start up again restartPending(); } elsif ( $! == EPIPE ) { - Error( "Can't select: $!" ); + Error("Can't select: $!"); } else { - Fatal( "Can't select: $!" ); + Fatal("Can't select: $!"); } } else { #print( "Select timed out\n" ); @@ -566,19 +566,19 @@ sub restart { my $command = $daemon; $command .= ' '.join( ' ', ( @args ) ) if @args; - dPrint ( ZoneMinder::Logger::WARNING, "Restarting $command\n"); + dPrint ( ZoneMinder::Logger::DEBUG, "Restarting $command\n"); my $process = $cmd_hash{$command}; if ( $process ) { - dPrint ( ZoneMinder::Logger::WARNING, "Have process" ); + dPrint( ZoneMinder::Logger::DEBUG, "Have process" ); if ( $process->{pid} ) { - dPrint ( ZoneMinder::Logger::WARNING, "Have process pid " .$process->{pid} ); + dPrint( ZoneMinder::Logger::DEBUG, "Have process pid " .$process->{pid} ); my $cpid = $process->{pid}; if ( defined($pid_hash{$cpid}) ) { - dPrint ( ZoneMinder::Logger::WARNING, "Have process pid hash " .$process->{pid} ); + dPrint( ZoneMinder::Logger::DEBUG, "Have process pid hash " .$process->{pid} ); _stop( 0, $process ); return; } else { - dPrint ( ZoneMinder::Logger::WARNING, "Not sending stop" ); + dPrint( ZoneMinder::Logger::DEBUG, "Not sending stop" ); } } } From 218e34a0797fe75701718e7f658cc98d8b3babe8 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 30 Jan 2018 11:23:09 -0500 Subject: [PATCH 129/154] Can only have 6 digitals, not 8 --- src/zm_event.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 054f0d73d..5beaa00a8 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -468,7 +468,8 @@ void Event::AddFramesInternal( int n_frames, int start_frame, Image **images, st struct DeltaTimeval delta_time; DELTA_TIMEVAL( delta_time, *(timestamps[i]), start_time, DT_PREC_2 ); - if ( delta_time.sec > 99999999 ) { + // Delta is Decimal(8,2) so 6 integer digits and 2 decimal digits + if ( delta_time.sec > 999999 ) { Warning("Invalid delta_time from_unixtime(%ld), %s%ld.%02ld", timestamps[i]->tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec ); delta_time.sec = 0; From 7c3efc02cd765fe3a7d34fe092df44f9206b5ef7 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 11:56:57 -0500 Subject: [PATCH 130/154] put back old add monitor popup --- web/skins/classic/views/console.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/console.php b/web/skins/classic/views/console.php index 60a48d6b3..10a0be72a 100644 --- a/web/skins/classic/views/console.php +++ b/web/skins/classic/views/console.php @@ -292,9 +292,10 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) { - - /> + />--> + From ba2c11176251ec9d90ebbb57d6e9d0a172ad59a4 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 14:32:48 -0500 Subject: [PATCH 131/154] restructure to keep trying to open the camera instead of exiting. --- src/zmc.cpp | 191 ++++++++++++++++++++++++++++------------------------ 1 file changed, 104 insertions(+), 87 deletions(-) diff --git a/src/zmc.cpp b/src/zmc.cpp index 02413f0b9..be1ece3a5 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -223,7 +223,7 @@ int main(int argc, char *argv[]) { Info("Starting Capture version %s", ZM_VERSION); static char sql[ZM_SQL_SML_BUFSIZ]; for ( int i = 0; i < n_monitors; i ++ ) { - snprintf( sql, sizeof(sql), "REPLACE INTO Monitor_Status (MonitorId, Status ) VALUES ('%d','Running')", monitors[i]->Id() ); + snprintf( sql, sizeof(sql), "REPLACE INTO Monitor_Status (MonitorId, Status) VALUES ('%d','Running')", monitors[i]->Id() ); if ( mysql_query( &dbconn, sql ) ) { Error( "Can't run query: %s", mysql_error( &dbconn ) ); } @@ -238,102 +238,119 @@ int main(int argc, char *argv[]) { sigaddset(&block_set, SIGUSR1); sigaddset(&block_set, SIGUSR2); - monitors[0]->setStartupTime((time_t)time(NULL)); - if ( monitors[0]->PrimeCapture() < 0 ) { - Error("Failed to prime capture of initial monitor"); - exit(-1); - } - - long *capture_delays = new long[n_monitors]; - long *alarm_capture_delays = new long[n_monitors]; - long *next_delays = new long[n_monitors]; - struct timeval * last_capture_times = new struct timeval[n_monitors]; - for ( int i = 0; i < n_monitors; i++ ) { - last_capture_times[i].tv_sec = last_capture_times[i].tv_usec = 0; - capture_delays[i] = monitors[i]->GetCaptureDelay(); - alarm_capture_delays[i] = monitors[i]->GetAlarmCaptureDelay(); - } - int result = 0; - struct timeval now; - struct DeltaTimeval delta_time; - while ( !zm_terminate ) { - sigprocmask(SIG_BLOCK, &block_set, 0); - for ( int i = 0; i < n_monitors; i++ ) { - long min_delay = MAXINT; - gettimeofday(&now, NULL); - for ( int j = 0; j < n_monitors; j++ ) { - if ( last_capture_times[j].tv_sec ) { - DELTA_TIMEVAL(delta_time, now, last_capture_times[j], DT_PREC_3); - if ( monitors[i]->GetState() == Monitor::ALARM ) - next_delays[j] = alarm_capture_delays[j]-delta_time.delta; - else - next_delays[j] = capture_delays[j]-delta_time.delta; - if ( next_delays[j] < 0 ) - next_delays[j] = 0; - } else { - next_delays[j] = 0; - } - if ( next_delays[j] <= min_delay ) { - min_delay = next_delays[j]; - } - } - - if ( next_delays[i] <= min_delay || next_delays[i] <= 0 ) { - if ( monitors[i]->PreCapture() < 0 ) { - Error("Failed to pre-capture monitor %d %d (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors); - zm_terminate = true; - result = -1; - break; - } - if ( monitors[i]->Capture() < 0 ) { - Error("Failed to capture image from monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors); - zm_terminate = true; - result = -1; - break; - } - if ( monitors[i]->PostCapture() < 0 ) { - Error("Failed to post-capture monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors); - zm_terminate = true; - result = -1; - break; - } - - if ( next_delays[i] > 0 ) { - gettimeofday(&now, NULL); - DELTA_TIMEVAL(delta_time, now, last_capture_times[i], DT_PREC_3); - long sleep_time = next_delays[i]-delta_time.delta; - if ( sleep_time > 0 ) { - usleep(sleep_time*(DT_MAXGRAN/DT_PREC_3)); - } - } - gettimeofday(&(last_capture_times[i]), NULL); - } // end if next_delay <= min_delay || next_delays[i] <= 0 ) - - } // end foreach n_monitors - sigprocmask(SIG_UNBLOCK, &block_set, 0); - if ( zm_reload ) { - for ( int i = 0; i < n_monitors; i++ ) { - monitors[i]->Reload(); - } - logTerm(); - logInit( log_id_string ); - zm_reload = false; + while( ! zm_terminate ) { + for ( int i = 0; i < n_monitors; i ++ ) { + time_t now = (time_t)time(NULL); + monitors[i]->setStartupTime(now); } - } // end while ! zm_terminate + // Outer primary loop, handles connection to camera + if ( monitors[0]->PrimeCapture() < 0 ) { + Error("Failed to prime capture of initial monitor"); + sleep(10); + continue; + } + static char sql[ZM_SQL_SML_BUFSIZ]; + for ( int i = 0; i < n_monitors; i ++ ) { + snprintf( sql, sizeof(sql), "REPLACE INTO Monitor_Status (MonitorId, Status) VALUES ('%d','Connected')", monitors[i]->Id() ); + if ( mysql_query( &dbconn, sql ) ) { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + } + } + + long *capture_delays = new long[n_monitors]; + long *alarm_capture_delays = new long[n_monitors]; + long *next_delays = new long[n_monitors]; + struct timeval * last_capture_times = new struct timeval[n_monitors]; + for ( int i = 0; i < n_monitors; i++ ) { + last_capture_times[i].tv_sec = last_capture_times[i].tv_usec = 0; + capture_delays[i] = monitors[i]->GetCaptureDelay(); + alarm_capture_delays[i] = monitors[i]->GetAlarmCaptureDelay(); + } + + struct timeval now; + struct DeltaTimeval delta_time; + while ( !zm_terminate ) { + sigprocmask(SIG_BLOCK, &block_set, 0); + for ( int i = 0; i < n_monitors; i++ ) { + long min_delay = MAXINT; + + gettimeofday(&now, NULL); + for ( int j = 0; j < n_monitors; j++ ) { + if ( last_capture_times[j].tv_sec ) { + DELTA_TIMEVAL(delta_time, now, last_capture_times[j], DT_PREC_3); + if ( monitors[i]->GetState() == Monitor::ALARM ) + next_delays[j] = alarm_capture_delays[j]-delta_time.delta; + else + next_delays[j] = capture_delays[j]-delta_time.delta; + if ( next_delays[j] < 0 ) + next_delays[j] = 0; + } else { + next_delays[j] = 0; + } + if ( next_delays[j] <= min_delay ) { + min_delay = next_delays[j]; + } + } // end foreach monitor + + if ( next_delays[i] <= min_delay || next_delays[i] <= 0 ) { + if ( monitors[i]->PreCapture() < 0 ) { + Error("Failed to pre-capture monitor %d %d (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors); + result = -1; + break; + } + if ( monitors[i]->Capture() < 0 ) { + Error("Failed to capture image from monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors); + result = -1; + break; + } + if ( monitors[i]->PostCapture() < 0 ) { + Error("Failed to post-capture monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors); + result = -1; + break; + } + + if ( next_delays[i] > 0 ) { + gettimeofday(&now, NULL); + DELTA_TIMEVAL(delta_time, now, last_capture_times[i], DT_PREC_3); + long sleep_time = next_delays[i]-delta_time.delta; + if ( sleep_time > 0 ) { + usleep(sleep_time*(DT_MAXGRAN/DT_PREC_3)); + } + } + gettimeofday(&(last_capture_times[i]), NULL); + } // end if next_delay <= min_delay || next_delays[i] <= 0 ) + + } // end foreach n_monitors + sigprocmask(SIG_UNBLOCK, &block_set, 0); + if ( zm_reload ) { + for ( int i = 0; i < n_monitors; i++ ) { + monitors[i]->Reload(); + } + logTerm(); + logInit( log_id_string ); + zm_reload = false; + } + if ( result < 0 ) { + // Failure, try reconnecting + break; + } + } // end while ! zm_terminate + delete [] alarm_capture_delays; + delete [] capture_delays; + delete [] next_delays; + delete [] last_capture_times; + } // end while ! zm_terminate outer connection loop + for ( int i = 0; i < n_monitors; i++ ) { delete monitors[i]; } delete [] monitors; - delete [] alarm_capture_delays; - delete [] capture_delays; - delete [] next_delays; - delete [] last_capture_times; Image::Deinitialise(); logTerm(); zmDbClose(); - return( result ); + return result; } From c9bc5a8cd809635c99f6301cdb34ae2ffbfa308c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 14:33:20 -0500 Subject: [PATCH 132/154] if given timestamp is in the future, reset it, it is likely invalid --- src/zm_event.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 5beaa00a8..c37bd04ce 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -60,10 +60,16 @@ Event::Event( std::string notes; createNotes(notes); + struct timeval now; + gettimeofday(&now, 0); + bool untimedEvent = false; if ( !start_time.tv_sec ) { untimedEvent = true; - gettimeofday(&start_time, 0); + start_time = now; + } else if ( start_time.tv_sec > now.tv_sec ) { + Error("StartTime in the future"); + start_time = now; } Storage * storage = monitor->getStorage(); From bdb5176981270f33e46e9c04274499e32e308d6e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 14:33:42 -0500 Subject: [PATCH 133/154] increase debug lvel of dumpPacket --- src/zm_ffmpeg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_ffmpeg.cpp b/src/zm_ffmpeg.cpp index 5ddd8ee82..77e3c90aa 100644 --- a/src/zm_ffmpeg.cpp +++ b/src/zm_ffmpeg.cpp @@ -458,5 +458,5 @@ void dumpPacket(AVPacket *pkt, const char *text) { pkt->flags & AV_PKT_FLAG_KEY, pkt->pos, pkt->duration); - Debug(1, "%s:%d:%s: %s", __FILE__, __LINE__, text, b); + Debug(2, "%s:%d:%s: %s", __FILE__, __LINE__, text, b); } From 31ad807a9041697f892d8dc725d18910d1bd580a Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 14:34:39 -0500 Subject: [PATCH 134/154] If ffmpeg is open in PrimeCapture, close it. Turn all Fatals into Errors --- src/zm_ffmpeg_camera.cpp | 94 ++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 38 deletions(-) diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 8f3078f85..85894e9f2 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -161,6 +161,9 @@ void FfmpegCamera::Terminate() { } int FfmpegCamera::PrimeCapture() { + if ( mCanCapture ) { + CloseFfmpeg(); + } mVideoStreamId = -1; mAudioStreamId = -1; Info( "Priming capture from %s", mPath.c_str() ); @@ -169,6 +172,7 @@ int FfmpegCamera::PrimeCapture() { } int FfmpegCamera::PreCapture() { + Debug(1, "PreCapture"); // If Reopen was called, then ffmpeg is closed and we need to reopen it. if ( ! mCanCapture ) return OpenFfmpeg(); @@ -273,7 +277,7 @@ int FfmpegCamera::Capture( Image &image ) { directbuffer = image.WriteBuffer(width, height, colours, subpixelorder); if ( directbuffer == NULL ) { Error("Failed requesting writeable buffer for the captured image."); - return (-1); + return -1; } #if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) @@ -285,8 +289,10 @@ int FfmpegCamera::Capture( Image &image ) { #endif #if HAVE_LIBSWSCALE - if ( sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mVideoCodecContext->height, mFrame->data, mFrame->linesize) < 0 ) - Fatal("Unable to convert raw format %u to target format %u at frame %d", mVideoCodecContext->pix_fmt, imagePixFormat, frameCount); + if ( sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mVideoCodecContext->height, mFrame->data, mFrame->linesize) < 0 ) { + Error("Unable to convert raw format %u to target format %u at frame %d", mVideoCodecContext->pix_fmt, imagePixFormat, frameCount); + return -1; + } #else // HAVE_LIBSWSCALE Fatal("You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras"); #endif // HAVE_LIBSWSCALE @@ -308,10 +314,10 @@ int FfmpegCamera::PostCapture() { int FfmpegCamera::OpenFfmpeg() { - Debug ( 2, "OpenFfmpeg called." ); + Debug(2, "OpenFfmpeg called."); uint32_t last_event_id = monitor->GetLastEventId() ; uint32_t video_writer_event_id = monitor->GetVideoWriterEventId(); - Debug(2, "last_event(%d), our current (%d)", last_event_id, video_writer_event_id ); + Debug(2, "last_event(%d), our current (%d)", last_event_id, video_writer_event_id); int ret; @@ -359,7 +365,7 @@ int FfmpegCamera::OpenFfmpeg() { #endif { mIsOpening = false; - Error( "Unable to open input %s due to: %s", mPath.c_str(), strerror(errno) ); + Error("Unable to open input %s due to: %s", mPath.c_str(), strerror(errno)); return -1; } AVDictionaryEntry *e=NULL; @@ -370,19 +376,19 @@ int FfmpegCamera::OpenFfmpeg() { mIsOpening = false; Debug ( 1, "Opened input" ); - Info( "Stream open %s", mPath.c_str() ); + Info( "Stream open %s, parsing streams...", mPath.c_str() ); #if !LIBAVFORMAT_VERSION_CHECK(53, 6, 0, 6, 0) - Debug ( 1, "Calling av_find_stream_info" ); + Debug(4, "Calling av_find_stream_info"); if ( av_find_stream_info( mFormatContext ) < 0 ) #else - Debug ( 1, "Calling avformat_find_stream_info" ); + Debug(4, "Calling avformat_find_stream_info"); if ( avformat_find_stream_info( mFormatContext, 0 ) < 0 ) #endif - Fatal( "Unable to find stream info from %s due to: %s", mPath.c_str(), strerror(errno) ); + Fatal("Unable to find stream info from %s due to: %s", mPath.c_str(), strerror(errno)); startTime = av_gettime();//FIXME here or after find_Stream_info - Debug ( 1, "Got stream info" ); + Debug(4, "Got stream info"); // Find first video stream present // The one we want Might not be the first @@ -427,11 +433,11 @@ int FfmpegCamera::OpenFfmpeg() { if ( mAudioStreamId == -1 ) Debug( 3, "Unable to locate audio stream in %s", mPath.c_str() ); - Debug ( 3, "Found video stream at index %d", mVideoStreamId ); - Debug ( 3, "Found audio stream at index %d", mAudioStreamId ); + Debug(3, "Found video stream at index %d", mVideoStreamId); + Debug(3, "Found audio stream at index %d", mAudioStreamId); #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) - mVideoCodecContext = avcodec_alloc_context3( NULL ); + mVideoCodecContext = avcodec_alloc_context3(NULL); avcodec_parameters_to_context( mVideoCodecContext, mFormatContext->streams[mVideoStreamId]->codecpar ); #else mVideoCodecContext = mFormatContext->streams[mVideoStreamId]->codec; @@ -484,7 +490,7 @@ int FfmpegCamera::OpenFfmpeg() { Debug( 1, "Input stream appears to be h265. The stored event file may not be viewable in browser." ); } else { #endif - Error( "Input stream is not h264. The stored event file may not be viewable in browser." ); + Warning( "Input stream is not h264. The stored event file may not be viewable in browser." ); #ifdef AV_CODEC_ID_H265 } #endif @@ -493,7 +499,8 @@ int FfmpegCamera::OpenFfmpeg() { if ( (!mVideoCodec) and ( (mVideoCodec = avcodec_find_decoder(mVideoCodecContext->codec_id)) == NULL ) ) { // Try and get the codec from the codec context - Fatal("Can't find codec for video stream from %s", mPath.c_str()); + Error("Can't find codec for video stream from %s", mPath.c_str()); + return -1; } else { Debug(1, "Video Found decoder"); zm_dump_stream_format(mFormatContext, mVideoStreamId, 0, 0); @@ -509,7 +516,8 @@ int FfmpegCamera::OpenFfmpeg() { while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) { Warning( "Option %s not recognized by ffmpeg", e->key); } - Fatal( "Unable to open codec for video stream from %s", mPath.c_str() ); + Error( "Unable to open codec for video stream from %s", mPath.c_str() ); + return -1; } else { AVDictionaryEntry *e = NULL; @@ -536,18 +544,20 @@ int FfmpegCamera::OpenFfmpeg() { } else { Debug(1, "Audio Found decoder"); zm_dump_stream_format(mFormatContext, mAudioStreamId, 0, 0); - // Open the codec + // Open the codec #if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0) - Debug ( 1, "Calling avcodec_open" ); - if ( avcodec_open(mAudioCodecContext, mAudioCodec) < 0 ) + Debug ( 1, "Calling avcodec_open" ); + if ( avcodec_open(mAudioCodecContext, mAudioCodec) < 0 ) { #else - Debug ( 1, "Calling avcodec_open2" ); - if ( avcodec_open2(mAudioCodecContext, mAudioCodec, 0) < 0 ) + Debug ( 1, "Calling avcodec_open2" ); + if ( avcodec_open2(mAudioCodecContext, mAudioCodec, 0) < 0 ) { #endif - Fatal( "Unable to open codec for video stream from %s", mPath.c_str() ); - } - Debug ( 1, "Opened audio codec" ); - } + Error( "Unable to open codec for video stream from %s", mPath.c_str() ); + return -1; + } + Debug(2, "Opened audio codec"); + } // end if find decoder + } // end if have audio_context // Allocate space for the native video frame mRawFrame = zm_av_frame_alloc(); @@ -555,10 +565,12 @@ int FfmpegCamera::OpenFfmpeg() { // Allocate space for the converted video frame mFrame = zm_av_frame_alloc(); - if ( mRawFrame == NULL || mFrame == NULL ) - Fatal( "Unable to allocate frame for %s", mPath.c_str() ); + if ( mRawFrame == NULL || mFrame == NULL ) { + Error("Unable to allocate frame for %s", mPath.c_str()); + return -1; + } - Debug ( 1, "Allocated frames" ); + Debug( 3, "Allocated frames"); #if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 ); @@ -567,19 +579,22 @@ int FfmpegCamera::OpenFfmpeg() { #endif if ( (unsigned int)pSize != imagesize ) { - Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize); + Error("Image size mismatch. Required: %d Available: %d",pSize,imagesize); + return -1; } - Debug ( 1, "Validated imagesize" ); + Debug(4, "Validated imagesize"); #if HAVE_LIBSWSCALE - Debug ( 1, "Calling sws_isSupportedInput" ); + Debug(1, "Calling sws_isSupportedInput"); if ( !sws_isSupportedInput(mVideoCodecContext->pix_fmt) ) { - Fatal("swscale does not support the codec format: %c%c%c%c", (mVideoCodecContext->pix_fmt)&0xff, ((mVideoCodecContext->pix_fmt >> 8)&0xff), ((mVideoCodecContext->pix_fmt >> 16)&0xff), ((mVideoCodecContext->pix_fmt >> 24)&0xff)); + Error("swscale does not support the codec format: %c%c%c%c", (mVideoCodecContext->pix_fmt)&0xff, ((mVideoCodecContext->pix_fmt >> 8)&0xff), ((mVideoCodecContext->pix_fmt >> 16)&0xff), ((mVideoCodecContext->pix_fmt >> 24)&0xff)); + return -1; } if ( !sws_isSupportedOutput(imagePixFormat) ) { - Fatal("swscale does not support the target format: %c%c%c%c",(imagePixFormat)&0xff,((imagePixFormat>>8)&0xff),((imagePixFormat>>16)&0xff),((imagePixFormat>>24)&0xff)); + Error("swscale does not support the target format: %c%c%c%c",(imagePixFormat)&0xff,((imagePixFormat>>8)&0xff),((imagePixFormat>>16)&0xff),((imagePixFormat>>24)&0xff)); + return -1; } mConvertContext = sws_getContext(mVideoCodecContext->width, @@ -588,8 +603,10 @@ int FfmpegCamera::OpenFfmpeg() { width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL); - if ( mConvertContext == NULL ) - Fatal( "Unable to create conversion context for %s", mPath.c_str() ); + if ( mConvertContext == NULL ) { + Error( "Unable to create conversion context for %s", mPath.c_str() ); + return -1; + } #else // HAVE_LIBSWSCALE Fatal( "You must compile ffmpeg with the --enable-swscale option to use ffmpeg cameras" ); #endif // HAVE_LIBSWSCALE @@ -658,7 +675,7 @@ int FfmpegCamera::CloseFfmpeg() { } return 0; -} +} // end FfmpegCamera::Close //Function to handle capture and store int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event_file ) { @@ -911,8 +928,9 @@ int FfmpegCamera::CaptureAndRecord( Image &image, timeval recording, char* event if (sws_scale(mConvertContext, mRawFrame->data, mRawFrame->linesize, 0, mVideoCodecContext->height, mFrame->data, mFrame->linesize) < 0) { - Fatal("Unable to convert raw format %u to target format %u at frame %d", + Error("Unable to convert raw format %u to target format %u at frame %d", mVideoCodecContext->pix_fmt, imagePixFormat, frameCount); + return -1; } frameCount++; From 882a242b76cc531a63f62690f000b0d6765e9e2e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 14:35:00 -0500 Subject: [PATCH 135/154] Fix mpeg streaming. --- src/zm_mpeg.cpp | 52 +++++++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/zm_mpeg.cpp b/src/zm_mpeg.cpp index 448621921..4ce2e0780 100644 --- a/src/zm_mpeg.cpp +++ b/src/zm_mpeg.cpp @@ -99,6 +99,7 @@ void VideoStream::SetupFormat( ) { } #endif } else { + Debug(1,"No allocating priv_data"); s->priv_data = NULL; } @@ -120,7 +121,6 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei /* ffmpeg format matching */ switch(colours) { case ZM_COLOUR_RGB24: - { if(subpixelorder == ZM_SUBPIX_ORDER_BGR) { /* BGR subpixel order */ pf = AV_PIX_FMT_BGR24; @@ -129,9 +129,7 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei pf = AV_PIX_FMT_RGB24; } break; - } case ZM_COLOUR_RGB32: - { if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) { /* ARGB subpixel order */ pf = AV_PIX_FMT_ARGB; @@ -146,7 +144,6 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei pf = AV_PIX_FMT_RGBA; } break; - } case ZM_COLOUR_GRAY8: pf = AV_PIX_FMT_GRAY8; break; @@ -159,6 +156,7 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei // RTP must have a packet_size. // Not sure what this value should be really... ofc->packet_size = width*height; + Debug(1,"Setting packet_size to %d", ofc->packet_size); if ( of->video_codec == AV_CODEC_ID_NONE ) { // RTP does not have a default codec in ffmpeg <= 0.8. @@ -171,6 +169,7 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei AVCodec *a = avcodec_find_encoder_by_name(codec_name); if ( a ) { codec_id = a->id; + Debug( 1, "Using codec \"%s\"", codec_name ); } else { #if (LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 11, 0) && (LIBAVFORMAT_VERSION_MICRO >= 100)) Debug( 1, "Could not find codec \"%s\". Using default \"%s\"", codec_name, avcodec_get_name( codec_id ) ); @@ -209,13 +208,13 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei Fatal( "Could not alloc stream" ); return; } + Debug( 1, "Allocated stream (%d) !=? (%d)", ost->id , ofc->nb_streams - 1 ); ost->id = ofc->nb_streams - 1; - Debug( 1, "Allocated stream" ); - #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) - codec_context = avcodec_alloc_context3(NULL); - avcodec_parameters_to_context(codec_context, ost->codecpar); + + codec_context = avcodec_alloc_context3(NULL); + //avcodec_parameters_to_context(codec_context, ost->codecpar); #else codec_context = ost->codec; #endif @@ -223,7 +222,7 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei codec_context->codec_id = codec->id; codec_context->codec_type = codec->type; - codec_context->pix_fmt = strcmp( "mjpeg", ofc->oformat->name ) == 0 ? AV_PIX_FMT_YUVJ422P : AV_PIX_FMT_YUV420P; + codec_context->pix_fmt = strcmp("mjpeg", ofc->oformat->name) == 0 ? AV_PIX_FMT_YUVJ422P : AV_PIX_FMT_YUV420P; if ( bitrate <= 100 ) { // Quality based bitrate control (VBR). Scale is 1..31 where 1 is best. // This gets rid of artifacts in the beginning of the movie; and well, even quality. @@ -246,8 +245,11 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei identically 1. */ codec_context->time_base.den = frame_rate; codec_context->time_base.num = 1; + ost->time_base.den = frame_rate; + ost->time_base.num = 1; + - Debug( 1, "Will encode in %d fps.", codec_context->time_base.den ); + Debug( 1, "Will encode in %d fps. %dx%d", codec_context->time_base.den, width, height ); /* emit one intra frame every second */ codec_context->gop_size = frame_rate; @@ -258,6 +260,10 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; #else codec_context->flags |= CODEC_FLAG_GLOBAL_HEADER; +#endif +#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) + avcodec_parameters_from_context(ost->codecpar, codec_context); + zm_dump_codecpar(ost->codecpar); #endif } else { Fatal( "of->video_codec == AV_CODEC_ID_NONE" ); @@ -271,7 +277,7 @@ const char *VideoStream::MimeType( ) const { for ( unsigned int i = 0; i < sizeof (mime_data) / sizeof (*mime_data); i++ ) { if ( strcmp( format, mime_data[i].format ) == 0 ) { Debug( 1, "MimeType is \"%s\"", mime_data[i].mime_type ); - return ( mime_data[i].mime_type); + return mime_data[i].mime_type; } } const char *mime_type = of->mime_type; @@ -282,9 +288,9 @@ const char *VideoStream::MimeType( ) const { Warning( "Unable to determine mime type for '%s' format, using '%s' as default", format, mime_type ); } - Debug( 1, "MimeType is \"%s\"", mime_type ); + Debug(1, "MimeType is \"%s\"", mime_type ); - return ( mime_type); + return mime_type; } void VideoStream::OpenStream( ) { @@ -293,11 +299,13 @@ void VideoStream::OpenStream( ) { /* now that all the parameters are set, we can open the video codecs and allocate the necessary encode buffers */ if ( ost ) { + Debug(1,"Opening codec"); + /* open the codec */ #if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0) - if ( (ret = avcodec_open( codec_context, codec )) < 0 ) + if ( (ret = avcodec_open(codec_context, codec)) < 0 ) #else - if ( (ret = avcodec_open2( codec_context, codec, 0 )) < 0 ) + if ( (ret = avcodec_open2(codec_context, codec, 0)) < 0 ) #endif { Fatal( "Could not open codec. Error code %d \"%s\"", ret, av_err2str(ret) ); @@ -310,6 +318,9 @@ void VideoStream::OpenStream( ) { if ( !opicture ) { Panic( "Could not allocate opicture" ); } + opicture->width = codec_context->width; + opicture->height = codec_context->height; + opicture->format = codec_context->pix_fmt; #if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) int size = av_image_get_buffer_size( codec_context->pix_fmt, codec_context->width, codec_context->height, 1 ); @@ -362,7 +373,7 @@ void VideoStream::OpenStream( ) { tmp_opicture_buf, pf, codec_context->width, codec_context->height ); #endif } - } + } // end if ost /* open the output file, if needed */ if ( !(of->flags & AVFMT_NOFILE) ) { @@ -384,8 +395,8 @@ void VideoStream::OpenStream( ) { video_outbuf = NULL; #if LIBAVFORMAT_VERSION_CHECK(57, 0, 0, 0, 0) - if (codec_context->codec_type == AVMEDIA_TYPE_VIDEO && - codec_context->codec_id == AV_CODEC_ID_RAWVIDEO) { + if (codec_context->codec_type == AVMEDIA_TYPE_VIDEO && + codec_context->codec_id == AV_CODEC_ID_RAWVIDEO) { #else if ( !(of->flags & AVFMT_RAWPICTURE) ) { #endif @@ -408,7 +419,7 @@ void VideoStream::OpenStream( ) { #if !LIBAVFORMAT_VERSION_CHECK(53, 2, 0, 4, 0) ret = av_write_header( ofc ); #else - ret = avformat_write_header( ofc, NULL ); + ret = avformat_write_header(ofc, NULL); #endif if ( ret < 0 ) { @@ -451,6 +462,7 @@ VideoStream::VideoStream( const char *in_filename, const char *in_format, int bi } } + codec_context = NULL; SetupFormat( ); SetupCodec( colours, subpixelorder, width, height, bitrate, frame_rate ); SetParameters( ); @@ -466,7 +478,6 @@ VideoStream::VideoStream( const char *in_filename, const char *in_format, int bi Fatal("pthread_mutex_init failed"); } - codec_context = NULL; } VideoStream::~VideoStream( ) { @@ -627,7 +638,6 @@ double VideoStream::ActuallyEncodeFrame( const uint8_t *buffer, int buffer_size, opicture_ptr->quality = codec_context->global_quality; #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) - // Put encoder into flushing mode avcodec_send_frame(codec_context, opicture_ptr); int ret = avcodec_receive_packet(codec_context, pkt); if ( ret < 0 ) { From 018523134e8ffc2eda4385785d637f584d51667a Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 14:35:23 -0500 Subject: [PATCH 136/154] use ZM_BASE_PROTOCOL when loading plugins. https can't load http content --- web/includes/functions.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/includes/functions.php b/web/includes/functions.php index 14f70d6a7..49c3f7a73 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -269,14 +269,14 @@ function getVideoStreamHTML( $id, $src, $width, $height, $format, $title='' ) { if ( isWindows() ) { return ' @@ -309,13 +309,13 @@ function getVideoStreamHTML( $id, $src, $width, $height, $format, $title='' ) { { return ' Date: Wed, 31 Jan 2018 14:35:48 -0500 Subject: [PATCH 137/154] An ok json return with no status is possible now --- web/skins/classic/views/js/montage.js | 92 ++++++++++++++------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/web/skins/classic/views/js/montage.js b/web/skins/classic/views/js/montage.js index 73d0b132b..152fdcd9b 100644 --- a/web/skins/classic/views/js/montage.js +++ b/web/skins/classic/views/js/montage.js @@ -56,64 +56,66 @@ function Monitor( monitorData ) { var stream = $j('#liveStream'+this.id)[0]; if ( respObj.result == 'Ok' ) { - this.status = respObj.status; - this.alarmState = this.status.state; + if ( respObj.status ) { + this.status = respObj.status; + this.alarmState = this.status.state; - var stateClass = ""; - if ( this.alarmState == STATE_ALARM ) - stateClass = "alarm"; - else if ( this.alarmState == STATE_ALERT ) - stateClass = "alert"; - else - stateClass = "idle"; + var stateClass = ""; + if ( this.alarmState == STATE_ALARM ) + stateClass = "alarm"; + else if ( this.alarmState == STATE_ALERT ) + stateClass = "alert"; + else + stateClass = "idle"; - if ( !COMPACT_MONTAGE ) { - $('fpsValue'+this.id).set( 'text', this.status.fps ); - $('stateValue'+this.id).set( 'text', stateStrings[this.alarmState] ); - this.setStateClass( $('monitorState'+this.id), stateClass ); - } - this.setStateClass( $('monitor'+this.id), stateClass ); + if ( !COMPACT_MONTAGE ) { + $('fpsValue'+this.id).set( 'text', this.status.fps ); + $('stateValue'+this.id).set( 'text', stateStrings[this.alarmState] ); + this.setStateClass( $('monitorState'+this.id), stateClass ); + } + this.setStateClass( $('monitor'+this.id), stateClass ); - /*Stream could be an applet so can't use moo tools*/ - stream.className = stateClass; + /*Stream could be an applet so can't use moo tools*/ + stream.className = stateClass; - var isAlarmed = ( this.alarmState == STATE_ALARM || this.alarmState == STATE_ALERT ); - var wasAlarmed = ( this.lastAlarmState == STATE_ALARM || this.lastAlarmState == STATE_ALERT ); + var isAlarmed = ( this.alarmState == STATE_ALARM || this.alarmState == STATE_ALERT ); + var wasAlarmed = ( this.lastAlarmState == STATE_ALARM || this.lastAlarmState == STATE_ALERT ); - var newAlarm = ( isAlarmed && !wasAlarmed ); - var oldAlarm = ( !isAlarmed && wasAlarmed ); + var newAlarm = ( isAlarmed && !wasAlarmed ); + var oldAlarm = ( !isAlarmed && wasAlarmed ); - if ( newAlarm ) { + if ( newAlarm ) { + if ( false && SOUND_ON_ALARM ) { + // Enable the alarm sound + $('alarmSound').removeClass( 'hidden' ); + } + if ( POPUP_ON_ALARM ) { + windowToFront(); + } + } if ( false && SOUND_ON_ALARM ) { - // Enable the alarm sound - $('alarmSound').removeClass( 'hidden' ); + if ( oldAlarm ) { + // Disable alarm sound + $('alarmSound').addClass( 'hidden' ); + } } - if ( POPUP_ON_ALARM ) { - windowToFront(); - } - } - if ( false && SOUND_ON_ALARM ) { - if ( oldAlarm ) { - // Disable alarm sound - $('alarmSound').addClass( 'hidden' ); - } - } - if ( this.status.auth ) { - if ( this.status.auth != auth_hash ) { - // Try to reload the image stream. - if ( stream ) - stream.src = stream.src.replace( /auth=\w+/i, 'auth='+this.status.auth ); - console.log("Changed auth from " + auth_hash + " to " + this.status.auth ); - auth_hash = this.status.auth; - } - } // end if have a new auth hash + if ( this.status.auth ) { + if ( this.status.auth != auth_hash ) { + // Try to reload the image stream. + if ( stream ) + stream.src = stream.src.replace( /auth=\w+/i, 'auth='+this.status.auth ); + console.log("Changed auth from " + auth_hash + " to " + this.status.auth ); + auth_hash = this.status.auth; + } + } // end if have a new auth hash + } // end if has state } else { console.error( respObj.message ); // Try to reload the image stream. if ( stream ) { if ( stream.src ) { - console.log('Reloading stream: ' + stream.src ); - stream.src = stream.src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) )); + console.log('Reloading stream: ' + stream.src ); + stream.src = stream.src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) )); } else { } } else { From 6942aaed1519dbae14e8a42c63aed1121aa64b40 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 14:36:01 -0500 Subject: [PATCH 138/154] whitespace --- src/zm_videostore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp index d530c6716..e074b1d9d 100644 --- a/src/zm_videostore.cpp +++ b/src/zm_videostore.cpp @@ -235,7 +235,7 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in, #else avformat_new_stream(oc, (AVCodec *)audio_in_ctx->codec); #endif - if (!audio_out_stream) { + if ( !audio_out_stream ) { Error("Unable to create audio out stream\n"); audio_out_stream = NULL; } else { From ef51a21df484baec19ef06a24c277272c36d474e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 14:36:41 -0500 Subject: [PATCH 139/154] add new runstate called Connected --- db/zm_create.sql.in | 2 +- db/zm_update-1.31.30.sql | 20 ++++++++++++++++++++ version | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 db/zm_update-1.31.30.sql diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 3f3889b27..d084cda2a 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -645,7 +645,7 @@ CREATE INDEX `Monitors_ServerId_idx` ON `Monitors` (`ServerId`); DROP TABLE IF EXISTS `Monitor_Status`; CREATE TABLE `Monitor_Status` ( `MonitorId` int(10) unsigned NOT NULL, - `Status` enum('Unknown','NotRunning','Running','NoSignal','Signal') NOT NULL default 'Unknown', + `Status` enum('Unknown','NotRunning','Running','Connected','Signal') NOT NULL default 'Unknown', `CaptureFPS` DECIMAL(10,2) NOT NULL default 0, `AnalysisFPS` DECIMAL(5,2) NOT NULL default 0, PRIMARY KEY (`MonitorId`) diff --git a/db/zm_update-1.31.30.sql b/db/zm_update-1.31.30.sql new file mode 100644 index 000000000..c87b4409a --- /dev/null +++ b/db/zm_update-1.31.30.sql @@ -0,0 +1,20 @@ +DROP TABLE IF EXISTS `Monitor_Status`; +CREATE TABLE `Monitor_Status` ( + `MonitorId` int(10) unsigned NOT NULL, + `Status` enum('Unknown','NotRunning','Running','Connected','Signal') NOT NULL default 'Unknown', + `CaptureFPS` DECIMAL(10,2) NOT NULL default 0, + `AnalysisFPS` DECIMAL(5,2) NOT NULL default 0, + PRIMARY KEY (`MonitorId`) +) ENGINE=MEMORY; + +SET SESSION sql_mode='NO_AUTO_VALUE_ON_ZERO'; + +SET @s = (SELECT IF( + (SELECT COUNT(*) FROM Storage WHERE Name = 'Default' AND Id=0 AND Path='/var/cache/zoneminder/events' + ) > 0, + "SELECT 'Default Storage Area already exists.'", + "INSERT INTO Storage (Id,Name,Path,Scheme,ServerId) VALUES (0,'Default','/var/cache/zoneminder/events','Medium',NULL)" + )); + +PREPARE stmt FROM @s; +EXECUTE stmt; diff --git a/version b/version index 2ec5fa98f..e9c3366c8 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.31.29 +1.31.30 From b390633f70608160ad98de58ca14744de7c04f7d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 14:58:01 -0500 Subject: [PATCH 140/154] Fix authHash generation --- web/index.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/web/index.php b/web/index.php index ced535833..6fbc435f7 100644 --- a/web/index.php +++ b/web/index.php @@ -173,12 +173,15 @@ if ( isset($_REQUEST['request']) ) foreach ( getSkinIncludes( 'skin.php' ) as $includeFile ) require_once $includeFile; -if ( ZM_OPT_USE_AUTH && ZM_AUTH_HASH_LOGINS ) { - if ( empty($user) && ! empty($_REQUEST['auth']) ) { - if ( $authUser = getAuthUser( $_REQUEST['auth'] ) ) { - userLogin( $authUser['Username'], $authUser['Password'], true ); - } - } else if ( ! empty($user) ) { +if ( ZM_OPT_USE_AUTH ) { + if ( ZM_AUTH_HASH_LOGINS ) { + if ( empty($user) && ! empty($_REQUEST['auth']) ) { + if ( $authUser = getAuthUser( $_REQUEST['auth'] ) ) { + userLogin( $authUser['Username'], $authUser['Password'], true ); + } + } + } + if ( ! empty($user) ) { // generate it once here, while session is open. Value will be cached in session and return when called later on generateAuthHash( ZM_AUTH_HASH_IPS ); } From a610d564d1e7a5569ec3effe3b0869b368ad4467 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 15:51:12 -0500 Subject: [PATCH 141/154] tweak timeouts --- web/ajax/stream.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/web/ajax/stream.php b/web/ajax/stream.php index 5dbfae6eb..57e138254 100644 --- a/web/ajax/stream.php +++ b/web/ajax/stream.php @@ -3,19 +3,19 @@ $start_time = time(); -define( 'MSG_TIMEOUT', ZM_WEB_AJAX_TIMEOUT ); +define( 'MSG_TIMEOUT', ZM_WEB_AJAX_TIMEOUT/2 ); define( 'MSG_DATA_SIZE', 4+256 ); if ( !($_REQUEST['connkey'] && $_REQUEST['command']) ) { ajaxError( "Unexpected received message type '$type'" ); } -if ( !($socket = @socket_create( AF_UNIX, SOCK_DGRAM, 0 )) ) { - ajaxError( 'socket_create() failed: '.socket_strerror(socket_last_error()) ); -} $key = ftok(ZM_PATH_SOCKS.'/zms-'.sprintf("%06d",$_REQUEST['connkey']).'w.lock', 'Z'); $semaphore = sem_get($key,1); if ( sem_acquire($semaphore,1) !== false ) { + if ( !($socket = @socket_create( AF_UNIX, SOCK_DGRAM, 0 )) ) { + ajaxError( 'socket_create() failed: '.socket_strerror(socket_last_error()) ); + } $localSocketFile = ZM_PATH_SOCKS.'/zms-'.sprintf('%06d',$_REQUEST['connkey']).'w.sock'; if ( file_exists( $localSocketFile ) ) { @@ -59,9 +59,12 @@ if ( sem_acquire($semaphore,1) !== false ) { $remSockFile = ZM_PATH_SOCKS.'/zms-'.sprintf('%06d',$_REQUEST['connkey']).'s.sock'; $max_socket_tries = 10; // FIXME This should not exceed web_ajax_timeout - while ( !file_exists($remSockFile) && $max_socket_tries-- ) { //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second. + while ( !file_exists($remSockFile) && $max_socket_tries-- ) { //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second. + // WHY? We will just send another one... + // ANSWER: Because otherwise we get a log of errors logged + //Logger::Debug("$remSockFile does not exist, waiting, current " . (time() - $start_time) . ' seconds' ); - usleep(200000); + usleep(1000); } if ( !file_exists($remSockFile) ) { From e7fb0f649b7aaed7cab7013f2c1d80945ad177d9 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 16:56:14 -0500 Subject: [PATCH 142/154] move zmonvif-probe.pl to ../scripts. This is in preparation for removing the onvif library from the Zoneminder source into it's own package. --- onvif/CMakeLists.txt | 2 - onvif/scripts/CMakeLists.txt | 9 - onvif/scripts/zmonvif-probe.pl | 405 --------------------------------- 3 files changed, 416 deletions(-) delete mode 100644 onvif/scripts/CMakeLists.txt delete mode 100755 onvif/scripts/zmonvif-probe.pl diff --git a/onvif/CMakeLists.txt b/onvif/CMakeLists.txt index e1ad01556..a6b9bde4e 100644 --- a/onvif/CMakeLists.txt +++ b/onvif/CMakeLists.txt @@ -3,5 +3,3 @@ # Process the perl modules subdirectory add_subdirectory(proxy) add_subdirectory(modules) -add_subdirectory(scripts) - diff --git a/onvif/scripts/CMakeLists.txt b/onvif/scripts/CMakeLists.txt deleted file mode 100644 index 3405fa756..000000000 --- a/onvif/scripts/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# CMakeLists.txt for the ZoneMinder perl scripts. - -# If this is an out-of-source build, copy the files we need to the binary directory -if(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)) - file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/zmonvif-probe.pl" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") -endif(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)) - -# Install the perl scripts -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmonvif-probe.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/onvif/scripts/zmonvif-probe.pl b/onvif/scripts/zmonvif-probe.pl deleted file mode 100755 index de6c18aa3..000000000 --- a/onvif/scripts/zmonvif-probe.pl +++ /dev/null @@ -1,405 +0,0 @@ -#!/usr/bin/perl -w -use strict; -# -# ========================================================================== -# -# ZoneMinder ONVIF Control Protocol Module -# Copyright (C) 2014 Jan M. Hochstein -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# ========================================================================== -# -# This module contains the implementation of the ONVIF capability prober -# - -use Getopt::Std; -use Data::UUID; - -require ONVIF::Client; - -require WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort; -require WSDiscovery10::Elements::Header; -require WSDiscovery10::Elements::Types; -require WSDiscovery10::Elements::Scopes; - -require WSDiscovery::TransportUDP; - -# -# ======================================================================== -# Globals - -my $verbose = 0; -my $soap_version = undef; -my $client; - -# ========================================================================= -# internal functions - -sub deserialize_message -{ - my ($wsdl_client, $response) = @_; - - # copied and adapted from SOAP::WSDL::Client - - # get deserializer - my $deserializer = $wsdl_client->get_deserializer(); - - if(! $deserializer) { - $deserializer = SOAP::WSDL::Factory::Deserializer->get_deserializer({ - soap_version => $wsdl_client->get_soap_version(), - %{ $wsdl_client->get_deserializer_args() }, - }); - } - # set class resolver if serializer supports it - $deserializer->set_class_resolver( $wsdl_client->get_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 ) { - # 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 )); - }; - if (defined $success) { - return wantarray - ? ($result_body, $result_header) - : $result_body; - } - elsif (blessed $@) { #}&& $@->isa('SOAP::WSDL::SOAP::Typelib::Fault11')) { - return $@; - } - else { - return $deserializer->generate_fault({ - code => 'soap:Server', - role => 'urn:localhost', - message => "Error deserializing message: $@. \n" - . "Message was: \n$response" - }); - } - }; -} - - -sub interpret_messages -{ - my ($svc_discover, $services, @responses ) = @_; - - foreach my $response ( @responses ) { - - if($verbose) { - print "Received message:\n" . $response . "\n"; - } - - my $result = deserialize_message($svc_discover, $response); - if(not $result) { - if($verbose) { - print "Error deserializing message. No message returned from deserializer.\n"; - } - next; - } - - my $xaddr; - foreach my $l_xaddr (split ' ', $result->get_ProbeMatch()->get_XAddrs()) { - # find IPv4 address - if($verbose) { - print "l_xaddr = $l_xaddr\n"; - } - if($l_xaddr =~ m|//[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[:/]|) { - $xaddr = $l_xaddr; - last; - } else { - print STDERR "Unable to find IPv4 address from xaddr $l_xaddr\n"; - } - } - - # No usable address found - next if not $xaddr; - - # ignore multiple responses from one service - next if defined $services->{$xaddr}; - $services->{$xaddr} = 1; - - print "$xaddr, " . $svc_discover->get_soap_version() . ", "; - - print "("; - my $scopes = $result->get_ProbeMatch()->get_Scopes(); - my $count = 0; - foreach my $scope(split ' ', $scopes) { - if($scope =~ m|onvif://www\.onvif\.org/(.+)/(.*)|) { - my ($attr, $value) = ($1,$2); - if( 0 < $count ++) { - print ", "; - } - print $attr . "=\'" . $value . "\'"; - } - } - print ")\n"; - } -} - -# ========================================================================= -# functions - -sub discover -{ - ## collect all responses - my @responses = (); - - no warnings 'redefine'; - - *WSDiscovery::TransportUDP::_notify_response = sub { - my ($transport, $response) = @_; - push @responses, $response; - }; - - ## try both soap versions - my %services; - - my $uuid_gen = Data::UUID->new(); - - if ( ( ! $soap_version ) or ( $soap_version eq '1.1' ) ) { - - if($verbose) { - print "Probing for SOAP 1.1\n" - } - my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({ -# no_dispatch => '1', - }); - $svc_discover->set_soap_version('1.1'); - - my $uuid = $uuid_gen->create_str(); - - 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 - Scopes => { value => '' }, - }, - WSDiscovery10::Elements::Header->new({ - Action => { value => 'http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe' }, - MessageID => { value => "urn:uuid:$uuid" }, - To => { value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' }, - }) - ); - print $result . "\n" if $verbose; - - interpret_messages($svc_discover, \%services, @responses); - @responses = (); - } # end if doing soap 1.1 - - if ( ( ! $soap_version ) or ( $soap_version eq '1.2' ) ) { - if($verbose) { - print "Probing for SOAP 1.2\n" - } - my $svc_discover = WSDiscovery10::Interfaces::WSDiscovery::WSDiscoveryPort->new({ -# no_dispatch => '1', - }); - $svc_discover->set_soap_version('1.2'); - -# copies of the same Probe message must have the same MessageID. -# This is not a copy. So we generate a new uuid. - my $uuid = $uuid_gen->create_str(); - -# Everyone else, like the nodejs onvif code and odm only ask for NetworkVideoTransmitter - my $result = $svc_discover->ProbeOp( - { # WSDiscovery::Types::ProbeType - xmlattr => { 'xmlns:dn' => 'http://www.onvif.org/ver10/network/wsdl', }, - Types => 'dn:NetworkVideoTransmitter', # QNameListType - Scopes => { value => '' }, - }, - WSDiscovery10::Elements::Header->new({ - Action => { value => 'http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe' }, - MessageID => { value => "urn:uuid:$uuid" }, - To => { value => 'urn:schemas-xmlsoap-org:ws:2005:04:discovery' }, - }) - ); - print $result . "\n" if $verbose; - interpret_messages($svc_discover, \%services, @responses); - } # end if doing soap 1.2 - -} - - -sub profiles -{ -# my $result = $services{media}{ep}->GetVideoSources( { } ,, ); -# die $result if not $result; -# print $result . "\n"; - - my $result = $client->get_endpoint('media')->GetProfiles( { } ,, ); - die $result if not $result; - if($verbose) { - print "Received message:\n" . $result . "\n"; - } - - my $profiles = $result->get_Profiles(); - - foreach my $profile ( @{ $profiles } ) { - - my $token = $profile->attr()->get_token() ; - - # Specification gives conflicting values for unicast stream types, try both. - # http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl#op.GetStreamUri - foreach my $streamtype ( 'RTP_unicast', 'RTP-Unicast' ) { - $result = $client->get_endpoint('media')->GetStreamUri( { - StreamSetup => { # ONVIF::Media::Types::StreamSetup - Stream => $streamtype, # StreamType - Transport => { # ONVIF::Media::Types::Transport - Protocol => 'RTSP', # TransportProtocol - }, - }, - ProfileToken => $token, # ReferenceToken - } ,, ); - last if $result; - } - die $result if not $result; - # print $result . "\n"; - - my $VideoEncoderConfiguration = $profile->get_VideoEncoderConfiguration(); - print join(', ', $token, - $profile->get_Name(), - ( $VideoEncoderConfiguration ? ( - $VideoEncoderConfiguration->get_Encoding(), - $VideoEncoderConfiguration->get_Resolution()->get_Width(), - $VideoEncoderConfiguration->get_Resolution()->get_Height(), - $VideoEncoderConfiguration->get_RateControl()->get_FrameRateLimit(), - ) : () ), - $result->get_MediaUri()->get_Uri() , - ). "\n"; - } # end foreach profile - -# -# use message parser without schema validation ??? -# - -} - -sub move -{ - my ($dir) = @_; - - - my $result = $client->get_endpoint('ptz')->GetNodes( { } ,, ); - - die $result if not $result; - print $result . "\n"; - -} - -sub metadata -{ - my $result = $client->get_endpoint('media')->GetMetadataConfigurations( { } ,, ); - die $result if not $result; - print $result . "\n"; - - $result = $client->get_endpoint('media')->GetVideoAnalyticsConfigurations( { } ,, ); - die $result if not $result; - print $result . "\n"; - -# $result = $client->get_endpoint('analytics')->GetServiceCapabilities( { } ,, ); -# die $result if not $result; -# print $result . "\n"; - -} - -# ======================================================================== -# options processing - -$Getopt::Std::STANDARD_HELP_VERSION = 1; - -our ($opt_v); - -my $OPTIONS = "v"; - -sub HELP_MESSAGE -{ - my ($fh, $pkg, $ver, $opts) = @_; - print $fh "Usage: " . __FILE__ . " [-v] probe \n"; - print $fh " " . __FILE__ . " [-v] \n"; - print $fh <new( { - 'url_svc_device' => $url_svc_device, - 'soap_version' => $soap_version } ); - - $client->set_credentials($username, $password, 1); - - $client->create_services(); - - - if($action eq "profiles") { - - profiles(); - } - elsif($action eq "move") { - my $dir = shift; - move($dir); - } - elsif($action eq "metadata") { - metadata(); - } - else { - print("Error: Unknown command\"$action\""); - exit(1); - } -} From c96f47886c94883ae71fb51e6b27e339af9d3d03 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 16:56:46 -0500 Subject: [PATCH 143/154] Fix discover not picking up a 1.2 response if we already have a 1.1 --- scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in index 23914bdd2..9ce556beb 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ONVIF.pm.in @@ -45,7 +45,6 @@ our @EXPORT = qw(); our $VERSION = $ZoneMinder::Base::VERSION; -use Getopt::Std; use Data::UUID; use vars qw( $verbose $soap_version ); @@ -185,11 +184,11 @@ sub discover { }; ## try both soap versions - my %services; my $uuid_gen = Data::UUID->new(); if ( ( ! $soap_version ) or ( $soap_version eq '1.1' ) ) { + my %services; if($verbose) { print "Probing for SOAP 1.1\n" @@ -219,6 +218,7 @@ sub discover { } # end if doing soap 1.1 if ( ( ! $soap_version ) or ( $soap_version eq '1.2' ) ) { + my %services; if($verbose) { print "Probing for SOAP 1.2\n" } @@ -253,8 +253,17 @@ sub discover { sub profiles { my ( $client ) = @_; - my $result = $client->get_endpoint('media')->GetProfiles( { } ,, ); - die $result if not $result; + my $endpoint = $client->get_endpoint('media'); + if ( ! $endpoint ) { + print "No media enpoint for client.\n"; + return; + } + + my $result = $endpoint->GetProfiles( { } ,, ); + if ( ! $result ) { + print "No result from GetProfiles\n"; + return; + } if($verbose) { print "Received message:\n" . $result . "\n"; } From 28617792499d079711853727a3e3db896886cad2 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Jan 2018 16:57:17 -0500 Subject: [PATCH 144/154] move zmonvif-probe.pl from the onvif library code and update it to use ZoneMinder::ONVIF --- scripts/CMakeLists.txt | 3 +- scripts/zmonvif-probe.pl.in | 155 ++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+), 1 deletion(-) create mode 100755 scripts/zmonvif-probe.pl.in diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 81cfdaa56..f1bfa2ed1 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -8,6 +8,7 @@ configure_file(zmaudit.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmaudit.pl" @ONLY) configure_file(zmcontrol.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" @ONLY) configure_file(zmdc.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" @ONLY) configure_file(zmfilter.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" @ONLY) +configure_file(zmonvif-probe.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmonvif-probe.pl" @ONLY) configure_file(zmpkg.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" @ONLY) configure_file(zmtrack.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" @ONLY) configure_file(zmtrigger.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" @ONLY) @@ -34,7 +35,7 @@ FOREACH(PERLSCRIPT ${perlscripts}) ENDFOREACH(PERLSCRIPT ${perlscripts}) # Install the perl scripts -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmaudit.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmupdate.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmvideo.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmwatch.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcamtool.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtelemetry.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmstats.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmaudit.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmonvif-probe.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmupdate.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmvideo.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmwatch.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcamtool.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtelemetry.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmstats.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) if(NOT ZM_NO_X10) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmx10.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) endif(NOT ZM_NO_X10) diff --git a/scripts/zmonvif-probe.pl.in b/scripts/zmonvif-probe.pl.in new file mode 100755 index 000000000..001d89f83 --- /dev/null +++ b/scripts/zmonvif-probe.pl.in @@ -0,0 +1,155 @@ +#!/usr/bin/perl -w +use strict; +# +# ========================================================================== +# +# ZoneMinder ONVIF Control Protocol Module +# Copyright (C) 2014 Jan M. Hochstein +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# ========================================================================== +# +# This module contains the implementation of the ONVIF capability prober +# + +use Getopt::Std; + +require ONVIF::Client; + + +# ======================================================================== +# options processing + +$Getopt::Std::STANDARD_HELP_VERSION = 1; + +our ($opt_v); + +my $OPTIONS = "v"; + +sub HELP_MESSAGE +{ + my ($fh, $pkg, $ver, $opts) = @_; + print $fh "Usage: " . __FILE__ . " [-v] probe \n"; + print $fh " " . __FILE__ . " [-v] \n"; + print $fh <new( { + 'url_svc_device' => $url_svc_device, + 'soap_version' => $soap_version } ); + + $client->set_credentials($username, $password, 1); + + $client->create_services(); + + + if ( $action eq "profiles" ) { + ZoneMinder::ONVIF::profiles($client); + } elsif( $action eq "move" ) { + my $dir = shift; + ZoneMinder::ONVIF::move($client, $dir); + } elsif ( $action eq "metadata" ) { + ZoneMinder::ONVIF::metadata($client); + } else { + print("Error: Unknown command\"$action\""); + exit(1); + } +} + +1; +__END__ + +=head1 NAME + +zmonvif-probe.pl - ZoneMinder ONVIF probing tool + +=head1 SYNOPSIS + + zmonfig-probe.pl [-v] probe + [-v] \n"; + + Commands are: + probe - scan for devices on the local network and list them + profiles - print the device's supported stream configurations + metadata - print some of the device's configuration settings + move - move the device (only ptz cameras) + Common parameters: + -v - increase verbosity + Device access parameters (for all commands but 'probe'): + device URL - the ONVIF Device service URL + soap version - SOAP version (1.1 or 1.2) + user - username of a user with access to the device + password - password for the user + +=head1 DESCRIPTION + + +=head1 OPTIONS + + -c, --continuous - Run continuously + -f, --force - Run even if pid file exists + -i, --interactive - Ask before applying any changes + -m, --monitor_id - Only consider the given monitor + -r, --report - Just report don't actually do anything + -s, --storage_id - Specify a storage area to audit instead of all + -v, --version - Print the installed version of ZoneMinder + +=cut + From 212882efb998c1ad3818e1d7ba00d2d4eb01c165 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 1 Feb 2018 11:31:25 -0500 Subject: [PATCH 145/154] db errors should NOT BE FATAL! --- web/includes/database.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/includes/database.php b/web/includes/database.php index 1fb18f0e8..dfe7f4817 100644 --- a/web/includes/database.php +++ b/web/includes/database.php @@ -98,7 +98,7 @@ function dbLog( $sql, $update=false ) { } function dbError( $sql ) { - Fatal( "SQL-ERR '".$dbConn->errorInfo()."', statement was '".$sql."'" ); + Error( "SQL-ERR '".$dbConn->errorInfo()."', statement was '".$sql."'" ); } function dbEscape( $string ) { @@ -150,7 +150,7 @@ function dbQuery( $sql, $params=NULL ) { function dbFetchOne( $sql, $col=false, $params=NULL ) { $result = dbQuery( $sql, $params ); if ( ! $result ) { - Fatal( "SQL-ERR dbFetchOne no result, statement was '".$sql."'" . ( $params ? 'params: ' . join(',',$params) : '' ) ); + Error( "SQL-ERR dbFetchOne no result, statement was '".$sql."'" . ( $params ? 'params: ' . join(',',$params) : '' ) ); return false; } @@ -169,7 +169,7 @@ function dbFetchOne( $sql, $col=false, $params=NULL ) { function dbFetchAll( $sql, $col=false, $params=NULL ) { $result = dbQuery( $sql, $params ); if ( ! $result ) { - Fatal( "SQL-ERR dbFetchAll no result, statement was '".$sql."'" . ( $params ? 'params: ' .join(',', $params) : '' ) ); + Error( "SQL-ERR dbFetchAll no result, statement was '".$sql."'" . ( $params ? 'params: ' .join(',', $params) : '' ) ); return false; } From 26ac1fd69565f227887266f39950926ebbfa47fb Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 1 Feb 2018 11:32:13 -0500 Subject: [PATCH 146/154] Include soap version in list of onvif cameras --- web/skins/classic/views/onvifprobe.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/onvifprobe.php b/web/skins/classic/views/onvifprobe.php index f2ca662cb..f9c766846 100644 --- a/web/skins/classic/views/onvifprobe.php +++ b/web/skins/classic/views/onvifprobe.php @@ -158,7 +158,7 @@ if( !isset($_REQUEST['step']) || ($_REQUEST['step'] == "1")) { */ // $sourceDesc = htmlspecialchars(serialize($camera['monitor'])); $sourceDesc = base64_encode(serialize($camera['monitor'])); - $sourceString = $camera['model'].' @ '.$host; + $sourceString = $camera['model'].' @ '.$host . ' using version ' . $camera['monitor']['SOAP'] ; $cameras[$sourceDesc] = $sourceString; } From 73edd3221a3fbb72faac4c3445e96c28efe48d1d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 1 Feb 2018 11:32:44 -0500 Subject: [PATCH 147/154] make DiskSpace in storage table be int instead of unsigned. Event deletions can make it go negative and then the delete fails. --- db/zm_create.sql.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index d084cda2a..79eca0056 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -841,7 +841,7 @@ CREATE TABLE `Storage` ( `Path` varchar(64) NOT NULL default '', `Name` varchar(64) NOT NULL default '', `Type` enum('local','s3fs') NOT NULL default 'local', - `DiskSpace` bigint unsigned default NULL, + `DiskSpace` bigint default NULL, `Scheme` enum('Deep','Medium','Shallow') NOT NULL default 'Medium', `ServerId` int(10) unsigned, PRIMARY KEY (`Id`) From 060acffb9d3476b1d927c25636bdfa390b96177c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 1 Feb 2018 11:32:55 -0500 Subject: [PATCH 148/154] make DiskSpace in storage table be int instead of unsigned. Event deletions can make it go negative and then the delete fails. --- db/zm_update-1.31.31.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 db/zm_update-1.31.31.sql diff --git a/db/zm_update-1.31.31.sql b/db/zm_update-1.31.31.sql new file mode 100644 index 000000000..66e25f95c --- /dev/null +++ b/db/zm_update-1.31.31.sql @@ -0,0 +1 @@ +ALTER TABLE Storage MODIFY DiskSpace BIGINT default NULL; From 40379f7df6ccc453e0f78f95d4a613964c9a3d8f Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 1 Feb 2018 11:33:56 -0500 Subject: [PATCH 149/154] bump version --- version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version b/version index e9c3366c8..e5f37b4d8 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.31.30 +1.31.31 From 929e49c3010e38d6b7296e311a8af122c5be05c4 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 2 Feb 2018 10:27:30 -0500 Subject: [PATCH 150/154] early return if there is no rows returned. Improve debug when there is a row but the specified column isn't present --- web/includes/database.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/web/includes/database.php b/web/includes/database.php index dfe7f4817..250e5fce8 100644 --- a/web/includes/database.php +++ b/web/includes/database.php @@ -153,11 +153,15 @@ function dbFetchOne( $sql, $col=false, $params=NULL ) { Error( "SQL-ERR dbFetchOne no result, statement was '".$sql."'" . ( $params ? 'params: ' . join(',',$params) : '' ) ); return false; } + if ( ! $result->rowCount() ) { + # No rows is not an error + return false; + } if ( $result && $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) { if ( $col ) { if ( ! isset( $dbRow[$col] ) ) { - Warning( "$col does not exist in the returned row" ); + Warning( "$col does not exist in the returned row " . print_r($dbRow, true) ); } return $dbRow[$col]; } From 68521aa0d47be3fec9bba8f86abb316cb8815e42 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 2 Feb 2018 10:27:50 -0500 Subject: [PATCH 151/154] spacing, remove debug lines --- web/includes/actions.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/web/includes/actions.php b/web/includes/actions.php index 4e0829e03..3c55af3db 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -484,19 +484,18 @@ if ( canEdit( 'Monitors' ) ) { ); if ( $_REQUEST['newMonitor']['ServerId'] == 'auto' ) { -Logger::Debug("Auto selecting server"); + Logger::Debug("Auto selecting server"); $_REQUEST['newMonitor']['ServerId'] = dbFetchOne( 'SELECT Id FROM Servers WHERE Status=\'Running\' ORDER BY FreeMem ASC, CpuLoad ASC LIMIT 1', 'Id' ); -Logger::Debug("Auto selecting server: Got " . $_REQUEST['newMonitor']['ServerId'] ); + 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); + Logger::Debug("Auto selecting server to " . ZM_SERVER_ID); } } else { Logger::Debug("NOT Auto selecting server" . $_REQUEST['newMonitor']['ServerId']); } $columns = getTableColumns( 'Monitors' ); -Logger::Debug('coloumns:'.print_r($columns)); $changes = getFormChanges( $monitor, $_REQUEST['newMonitor'], $types, $columns ); if ( count( $changes ) ) { @@ -553,7 +552,7 @@ Logger::Debug('coloumns:'.print_r($columns)); $restart = true; } else if ( ! $user['MonitorIds'] ) { // Can only create new monitors if we are not restricted to specific monitors # FIXME This is actually a race condition. Should lock the table. - $maxSeq = dbFetchOne( 'SELECT max(Sequence) AS MaxSequence FROM Monitors', 'MaxSequence' ); + $maxSeq = dbFetchOne('SELECT MAX(Sequence) AS MaxSequence FROM Monitors', 'MaxSequence'); $changes[] = 'Sequence = '.($maxSeq+1); if ( dbQuery( 'INSERT INTO Monitors SET '.implode( ', ', $changes ) ) ) { From 868e17a414a186565f0d6e2729c18d3d00a139cf Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 2 Feb 2018 10:31:55 -0500 Subject: [PATCH 152/154] Allow Method in Monitors to be NULL --- db/zm_create.sql.in | 2 +- db/zm_update-1.31.32.sql | 3 +++ src/zm_monitor.cpp | 4 ++-- version | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 db/zm_update-1.31.32.sql diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 79eca0056..f9bb3866d 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -562,7 +562,7 @@ CREATE TABLE `Monitors` ( `V4LMultiBuffer` tinyint(1) unsigned, `V4LCapturesPerFrame` tinyint(3) unsigned, `Protocol` varchar(16), - `Method` varchar(16) NOT NULL default '', + `Method` varchar(16) default '', `Host` varchar(64), `Port` varchar(8) NOT NULL default '', `SubPath` varchar(64) NOT NULL default '', diff --git a/db/zm_update-1.31.32.sql b/db/zm_update-1.31.32.sql new file mode 100644 index 000000000..781fce1fc --- /dev/null +++ b/db/zm_update-1.31.32.sql @@ -0,0 +1,3 @@ +ALTER TABLE Monitors MODIFY TotalEventDiskSpace BIGINT default NULL; +ALTER TABLE Monitors MODIFY Method VARCHAR(16) default NULL; + diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 9f0b05d31..87cda8c80 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1937,7 +1937,7 @@ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose } Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); col++; - const char *method = dbrow[col]; col++; + const char *method = dbrow[col] ? dbrow[col] : ""; col++; int width = atoi(dbrow[col]); col++; int height = atoi(dbrow[col]); col++; @@ -2438,7 +2438,7 @@ int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose const char *linked_monitors = dbrow[col] ? dbrow[col] : ""; col++; const char *path = dbrow[col]; col++; - const char *method = dbrow[col]; col++; + const char *method = dbrow[col] ? dbrow[col] : ""; col++; const char *options = dbrow[col] ? dbrow[col] : ""; col++; int width = atoi(dbrow[col]); col++; diff --git a/version b/version index e5f37b4d8..71736e954 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.31.31 +1.31.32 From 87ef17dddcf5c9a1c0b6d18d16d37d5748033ae5 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 2 Feb 2018 11:05:56 -0500 Subject: [PATCH 153/154] errors running a command should NOT exit! --- scripts/ZoneMinder/lib/ZoneMinder/General.pm | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/General.pm b/scripts/ZoneMinder/lib/ZoneMinder/General.pm index c362a81bf..f3bc54c5e 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/General.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/General.pm @@ -174,7 +174,6 @@ sub runCommand { if ( $status || logDebugging() ) { if ( $status ) { Error( "Unable to run \"$command\", output is \"$output\"\n" ); - exit( -1 ); } else { Debug( "Output: $output\n" ); } From 0287868f5e98f34814476e21fba75273df26986a Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 2 Feb 2018 11:06:47 -0500 Subject: [PATCH 154/154] include the status when error runCommand --- scripts/ZoneMinder/lib/ZoneMinder/General.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/General.pm b/scripts/ZoneMinder/lib/ZoneMinder/General.pm index f3bc54c5e..692af30d4 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/General.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/General.pm @@ -173,7 +173,7 @@ sub runCommand { chomp( $output ); if ( $status || logDebugging() ) { if ( $status ) { - Error( "Unable to run \"$command\", output is \"$output\"\n" ); + Error( "Unable to run \"$command\", output is \"$output\", status is $status\n" ); } else { Debug( "Output: $output\n" ); }