From c9db5f44a4a210e81e1da69b3c2db2d4f1b3f2e9 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 12 Jan 2022 12:05:29 -0500 Subject: [PATCH 1/5] cherry pick Add check to prevent tight busy loop if ONVIF setup fails --- src/zm_monitor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 4feea00fe..958410efe 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -1077,7 +1077,7 @@ bool Monitor::connect() { //ONVIF Setup #ifdef WITH_GSOAP ONVIF_Trigger_State = FALSE; - if (onvif_event_listener) { //Temporarily using this option to enable the feature + if (onvif_event_listener) { Debug(1, "Starting ONVIF"); ONVIF_Healthy = FALSE; if (onvif_options.find("closes_event") != std::string::npos) { //Option to indicate that ONVIF will send a close event message @@ -3130,7 +3130,7 @@ int Monitor::PrimeCapture() { #ifdef WITH_GSOAP //For now, just don't run the thread if no ONVIF support. This may change if we add other long polling options. //ONVIF Thread - if (onvif_event_listener) { + if (onvif_event_listener && ONVIF_Healthy) { if (!Poller) { Poller = zm::make_unique(this); } else { From 3dad3a5200dc62844fbb6d12c3421ae5482283d3 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 13 Jan 2022 09:37:54 -0500 Subject: [PATCH 2/5] update description to reflect that zmupdate.pl now does all the things it will someday do. Meantion how -c works better. When in interactive mode, check once and print out the result instead of daemonising. Fix formatting osf usage --- scripts/zmupdate.pl.in | 51 ++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/scripts/zmupdate.pl.in b/scripts/zmupdate.pl.in index 0253fadc2..095218940 100644 --- a/scripts/zmupdate.pl.in +++ b/scripts/zmupdate.pl.in @@ -2,7 +2,7 @@ # # ========================================================================== # -# ZoneMinder Update Script, $Date$, $Revision$ +# ZoneMinder Update Script # Copyright (C) 2001-2008 Philip Coombes # # This program is free software; you can redistribute it and/or @@ -31,29 +31,29 @@ zmupdate.pl -c,--check | -f,--freshen | -v,--version= [-u , --version= - Force upgrade to the current version from --u , --user= - Alternate DB user with privileges to alter DB --p , --pass= - Password of alternate DB user with privileges to alter DB --s, --super - Use system maintenance account on debian based systems instead of unprivileged account --d , --dir= - Directory containing update files if not in default build location --interactive - interact with the user --nointeractive - do not interact with the user + -c, --check - Check for updated versions of ZoneMinder. + If not interactive zmupdate.pl will stay running, checking every hour. + If interactive will try once, print out result and quit. + -f, --freshen - Freshen the configuration in the database. Equivalent of old zmconfig.pl -noi + --migrate-events - Update database structures as per USE_DEEP_STORAGE setting. + -v , --version= - Force upgrade to the current version from + -u , --user= - Alternate DB user with privileges to alter DB + -p , --pass= - Password of alternate DB user with privileges to alter DB + -s, --super - Use system maintenance account on debian based systems instead of unprivileged account + -d , --dir= - Directory containing update files if not in default build location + -interactive - interact with the user + -nointeractive - do not interact with the user =cut use strict; use bytes; use version; -use Crypt::Eksblowfish::Bcrypt; -use Data::Entropy::Algorithms qw(rand_bits); # ========================================================================== # @@ -122,9 +122,8 @@ GetOptions( ) or pod2usage(-exitstatus => -1); my $dbh = zmDbConnect(undef, { mysql_multi_statements=>1 } ); -if ( !$dbh ) { - die "Unable to connect to db\n"; -} +die "Unable to connect to db\n" if !$dbh; + $Config{ZM_DB_USER} = $dbUser; $Config{ZM_DB_PASS} = $dbPass; # we escape dbpass with single quotes so that $ in the password has no effect, but dbpass could have a ' in it. @@ -181,6 +180,7 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) { Info('Got version: '.$lastVersion); + my $lv_sql = 'UPDATE Config SET Value = ? WHERE Name = \'ZM_DYN_LAST_VERSION\''; my $lv_sth = $dbh->prepare_cached($lv_sql) or die("Can't prepare '$lv_sql': ".$dbh->errstr()); my $lv_res = $lv_sth->execute($lastVersion) or die("Can't execute: ".$lv_sth->errstr()); @@ -190,6 +190,11 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) { my $lc_sth = $dbh->prepare_cached($lc_sql) or die("Can't prepare '$lc_sql': ".$dbh->errstr()); my $lc_res = $lc_sth->execute($lastCheck) or die("Can't execute: ".$lc_sth->errstr()); $lc_sth->finish(); + if ($interactive) { +print("Hello"); + print("Latest version $lastVersion, our version " . ZM_VERSION."\n"); + exit(0); + } } else { Error('Error check failed: \''.$res->status_line().'\''); } @@ -1044,14 +1049,16 @@ sub patchDB { } # end sub patchDB sub migratePasswords { - print ("Migratings passwords, if any...\n"); + use Crypt::Eksblowfish::Bcrypt; + use Data::Entropy::Algorithms qw(rand_bits); + print("Migratings passwords, if any...\n"); my $sql = 'SELECT * FROM `Users`'; my $sth = $dbh->prepare_cached($sql) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $res = $sth->execute() or die("Can't execute: ".$sth->errstr()); - while( my $user = $sth->fetchrow_hashref() ) { + while ( my $user = $sth->fetchrow_hashref() ) { my $scheme = substr($user->{Password}, 0, 1); if ($scheme eq '*') { - print ('-->'.$user->{Username}." password will be migrated\n"); + print('-->'.$user->{Username}." password will be migrated\n"); my $salt = Crypt::Eksblowfish::Bcrypt::en_base64(rand_bits(16*8)); my $settings = '$2a$10$'.$salt; my $pass_hash = Crypt::Eksblowfish::Bcrypt::bcrypt($user->{Password},$settings); From 3ec6c7e32fc17e2025966ba5efe3655b9630a6cf Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 13 Jan 2022 09:54:36 -0500 Subject: [PATCH 3/5] Fix behaviour of update check to support interactive mode. Use zmDbDo functions to simplify code. When interactive print out lastVersion, latestVersion and currentVersion --- scripts/zmupdate.pl.in | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/scripts/zmupdate.pl.in b/scripts/zmupdate.pl.in index 095218940..9ad5a1a02 100644 --- a/scripts/zmupdate.pl.in +++ b/scripts/zmupdate.pl.in @@ -52,6 +52,7 @@ It can also apply and configure upgrades etc, including on the fly upgrades. =cut use strict; +use warnings; use bytes; use version; @@ -143,8 +144,10 @@ if ( ($check + $freshen + $rename + $zoneFix + $migrateEvents + ($version?1:0)) pod2usage(-exitstatus => -1); } -if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) { - print('Update agent starting at '.strftime('%y/%m/%d %H:%M:%S', localtime() )."\n"); +if ($check and ($Config{ZM_CHECK_FOR_UPDATES} or $interactive) ) { + if (!$interactive) { + Info('Update agent starting at '.strftime('%y/%m/%d %H:%M:%S', localtime() )."\n"); + } my $currVersion = $Config{ZM_DYN_CURR_VERSION}; my $lastVersion = $Config{ZM_DYN_LAST_VERSION}; @@ -152,16 +155,14 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) { if ( !$currVersion ) { $currVersion = $Config{ZM_VERSION}; - - my $sql = "update Config set Value = ? where Name = 'ZM_DYN_CURR_VERSION'"; - my $sth = $dbh->prepare_cached($sql) or die("Can't prepare '$sql': ".$dbh->errstr()); - my $res = $sth->execute($currVersion) or die("Can't execute: ".$sth->errstr()); - $sth->finish(); + zmDbDo("UPDATE `Config` SET `Value` = ? WHERE `Name` = 'ZM_DYN_CURR_VERSION'", $currVersion); } while ( 1 ) { my $now = time(); - if ( !$lastVersion || !$lastCheck || (($now-$lastCheck) > CHECK_INTERVAL) ) { + if ( !$interactive and $lastVersion and $lastCheck and (($now-$lastCheck) <= CHECK_INTERVAL) ) { + Debug("Not checking for updates since we already have less than " . CHECK_INTERVAL . " seconds ago."); + } else { Info('Checking for updates'); use LWP::UserAgent; @@ -174,25 +175,16 @@ if ( $check && $Config{ZM_CHECK_FOR_UPDATES} ) { my $res = $ua->request($req); if ( $res->is_success ) { - $lastVersion = $res->content; - chomp($lastVersion); + my $latestVersion = $res->content; + chomp($latestVersion); $lastCheck = $now; - Info('Got version: '.$lastVersion); + Info('Got version: '.$latestVersion); - - my $lv_sql = 'UPDATE Config SET Value = ? WHERE Name = \'ZM_DYN_LAST_VERSION\''; - my $lv_sth = $dbh->prepare_cached($lv_sql) or die("Can't prepare '$lv_sql': ".$dbh->errstr()); - my $lv_res = $lv_sth->execute($lastVersion) or die("Can't execute: ".$lv_sth->errstr()); - $lv_sth->finish(); - - my $lc_sql = 'UPDATE Config SET Value = ? WHERE Name = \'ZM_DYN_LAST_CHECK\''; - my $lc_sth = $dbh->prepare_cached($lc_sql) or die("Can't prepare '$lc_sql': ".$dbh->errstr()); - my $lc_res = $lc_sth->execute($lastCheck) or die("Can't execute: ".$lc_sth->errstr()); - $lc_sth->finish(); + zmDbDo('UPDATE Config SET Value = ? WHERE Name = \'ZM_DYN_LAST_VERSION\'', $latestVersion); + zmDbDo('UPDATE Config SET Value = ? WHERE Name = \'ZM_DYN_LAST_CHECK\'', $lastCheck); if ($interactive) { -print("Hello"); - print("Latest version $lastVersion, our version " . ZM_VERSION."\n"); + print("Last version $lastVersion, Latest version $latestVersion, our version " . ZM_VERSION."\n"); exit(0); } } else { From 58bd09d83d674e5920c3fe781087035bf814fe6a Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 13 Jan 2022 09:54:47 -0500 Subject: [PATCH 4/5] Fix debug output from zmDbDo --- dep/RtspServer | 2 +- scripts/ZoneMinder/lib/ZoneMinder/Database.pm | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dep/RtspServer b/dep/RtspServer index 1b40f1661..cd7fd49be 160000 --- a/dep/RtspServer +++ b/dep/RtspServer @@ -1 +1 @@ -Subproject commit 1b40f1661f93f50fd5805f239d1e466a3bcf888f +Subproject commit cd7fd49becad6010a1b8466bfebbd93999a39878 diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Database.pm b/scripts/ZoneMinder/lib/ZoneMinder/Database.pm index 35d2dc6fa..ae1259814 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Database.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Database.pm @@ -273,6 +273,9 @@ sub zmDbDo { if ( ! defined $rows ) { $sql =~ s/\?/'%s'/; Error(sprintf("Failed $sql :", @_).$dbh->errstr()); + } elsif ( ZoneMinder::Logger::logLevel() > INFO ) { + $sql =~ s/\?/'%s'/; + Debug(sprintf("Succeeded $sql : $rows rows affected", @_)); } return $rows; } From 162e12bf92322fda18eab98c7ecc0933d2cc34f2 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 13 Jan 2022 10:21:32 -0500 Subject: [PATCH 5/5] default interactive to whether we have stdio. So now when running from console it will default to interactive and when running from zmdc.pl will be non-interactive. Do check regardless of ZM_UPDATE_CHECK setting. --- scripts/zmupdate.pl.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/zmupdate.pl.in b/scripts/zmupdate.pl.in index 9ad5a1a02..d096c70b5 100644 --- a/scripts/zmupdate.pl.in +++ b/scripts/zmupdate.pl.in @@ -96,7 +96,7 @@ my $use_log = (($> == 0) || ($> == $web_uid)); logInit( toFile=>$use_log?DEBUG:NOLOG ); logSetSignal(); -my $interactive = 1; +my $interactive = -t STDERR; # interactive if we have IO my $check = 0; my $freshen = 0; my $rename = 0; @@ -144,7 +144,7 @@ if ( ($check + $freshen + $rename + $zoneFix + $migrateEvents + ($version?1:0)) pod2usage(-exitstatus => -1); } -if ($check and ($Config{ZM_CHECK_FOR_UPDATES} or $interactive) ) { +if ($check) { if (!$interactive) { Info('Update agent starting at '.strftime('%y/%m/%d %H:%M:%S', localtime() )."\n"); }