From 8cf899efc5dbf2f74292014cf80bbdf5ccb5c631 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 25 Oct 2020 10:58:27 -0500 Subject: [PATCH 01/38] remove commented line --- web/ajax/events.php | 1 - 1 file changed, 1 deletion(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index eb74f543a..c27817be3 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -166,7 +166,6 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $sort = $sort == "Monitor" ? 'M.Name' : 'E.'.$sort; $col_str = 'E.*, M.Name AS Monitor'; - //$query['sql'] = 'SELECT ' .$col_str. ' FROM `' .$table. '` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where.' ORDER BY LENGTH(' .$sort. '), ' .$sort. ' ' .$order. ' LIMIT ?, ?'; $query['sql'] = 'SELECT ' .$col_str. ' FROM `' .$table. '` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where.' ORDER BY ' .$sort. ' ' .$order. ' LIMIT ?, ?'; array_push($query['values'], $offset, $limit); From 6d00924c9b23539e9cde6f6bfc9b532f9bea7eb7 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 25 Oct 2020 12:11:34 -0500 Subject: [PATCH 02/38] deploy server pagination for events view --- web/skins/classic/views/events.php | 233 ++------------------------ web/skins/classic/views/js/events.js | 7 - web/skins/classic/views/newevents.php | 128 -------------- 3 files changed, 15 insertions(+), 353 deletions(-) delete mode 100644 web/skins/classic/views/newevents.php diff --git a/web/skins/classic/views/events.php b/web/skins/classic/views/events.php index a70fa8d19..555f13f51 100644 --- a/web/skins/classic/views/events.php +++ b/web/skins/classic/views/events.php @@ -42,73 +42,6 @@ if ( isset($_REQUEST['filter'])) { parseSort(); $filterQuery = $filter->querystring(); -ZM\Debug('Filter '.print_r($filter, true)); - -if ( $filter->sql() ) { - $eventsSql .= ' AND ('.$filter->sql().')'; -} else { - ZM\Warning('No filters'); - exit; -} -$eventsSql .= ' ORDER BY '.$sortColumn.' '.$sortOrder; -if ( $sortColumn != 'E.Id' ) $eventsSql .= ',E.Id '.$sortOrder; - -$page = isset($_REQUEST['page']) ? validInt($_REQUEST['page']) : 0; -$limit = isset($_REQUEST['limit']) ? validInt($_REQUEST['limit']) : $filter['limit']; - -if ( $_POST ) { - // I think this is basically so that a refresh doesn't repost - ZM\Debug('Redirecting to ' . $_SERVER['REQUEST_URI']); - header('Location: ?view=' . $view.htmlspecialchars_decode($filterQuery).htmlspecialchars_decode($sortQuery).$limitQuery.'&page='.$page); - exit(); -} - -$failed = !$filter->test_pre_sql_conditions(); -if ( $failed ) { - ZM\Debug('Pre conditions failed, not doing sql'); -} - -$results = $failed ? null : dbQuery($eventsSql); - -$nEvents = $results ? $results->rowCount() : 0; -if ( ! $results ) { - global $error_message; - $error_message = dbError($eventsSql); -} -ZM\Debug("Pre conditions succeeded sql return $nEvents events"); - -if ( !empty($limit) && ($nEvents > $limit) ) { - $nEvents = $limit; -} -$pages = (int)ceil($nEvents/ZM_WEB_EVENTS_PER_PAGE); -#Debug("Page $page Limit $limit #vents: $nEvents pages: $pages "); -if ( !empty($page) ) { - if ( $page < 0 ) - $page = 1; - else if ( $pages and ( $page > $pages ) ) - $page = $pages; - - $limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE); - if ( empty($limit) ) { - $limitAmount = ZM_WEB_EVENTS_PER_PAGE; - } else { - $limitLeft = $limit - $limitStart; - $limitAmount = ($limitLeft>ZM_WEB_EVENTS_PER_PAGE)?ZM_WEB_EVENTS_PER_PAGE:$limitLeft; - } - $eventsSql .= ' LIMIT '.$limitStart.', '.$limitAmount; -} else if ( !empty($limit) ) { - $eventsSql .= ' LIMIT 0, '.$limit; -} - -$maxShortcuts = 5; - -$focusWindow = true; - -$storage_areas = ZM\Storage::find(); -$StorageById = array(); -foreach ( $storage_areas as $S ) { - $StorageById[$S->Id()] = $S; -} xhtmlHeaders(__FILE__, translate('Events')); getBodyTopHTML(); @@ -136,6 +69,8 @@ getBodyTopHTML(); @@ -168,163 +104,24 @@ getBodyTopHTML(); - - - + + + - - - - - 1 ) { -?> - - + + + + + - - - - - - while ( $event_row = dbFetchNext($results) ) { - $event = new ZM\Event($event_row); - - if ( !$filter->test_post_sql_conditions($event) ) { - $event->remove_from_cache(); - continue; - } - $events[] = $event; - if ( $limit and (count($events) >= $limit) ) { - break; - } - ZM\Debug("Have " . count($events) . " events, limit $limit"); - } - foreach ( $events as $event ) { - - $scale = max(reScale(SCALE_BASE, $event->DefaultScale(), ZM_WEB_DEFAULT_SCALE), SCALE_BASE); -?> - Archived() ? ' class="archived"' : '' ?>> - - - - - - - - - - - - - - - - - - - 1 ) { -?> - - -DiskSpace(); -?> - -'; - $imgSrc = $event->getThumbnailSrc(array(),'&'); - $streamSrc = $event->getStreamSrc(array( - 'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single', 'rate'=>'400'), '&'); - - $imgHtml = ''. validHtmlStr('Event '.$event->Id()) .''; - echo ''.$imgHtml.''; - echo ''; - } // end if ZM_WEB_LIST_THUMBS -?> - - + + - - - - -1 ) { -?> - - - - - - - - - - + diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index b51c679a3..d98d51f4f 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -321,13 +321,6 @@ function initPage() { $j('#deleteConfirm').modal('show'); }); - // Manage the eventdetail links in the events list - $j(".eDetailLink").click(function(evt) { - evt.preventDefault(); - var eid = $j(this).data('eid'); - getEventDetailModal(eid); - }); - // Update table links each time after new data is loaded table.on('post-body.bs.table', function(data) { // Manage the eventdetail links in the events list diff --git a/web/skins/classic/views/newevents.php b/web/skins/classic/views/newevents.php deleted file mode 100644 index 555f13f51..000000000 --- a/web/skins/classic/views/newevents.php +++ /dev/null @@ -1,128 +0,0 @@ -set($_REQUEST['filter']); -} - -parseSort(); - -$filterQuery = $filter->querystring(); - -xhtmlHeaders(__FILE__, translate('Events')); -getBodyTopHTML(); - -?> - -
- -
- - - - - - - - - - - -
- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- From e5563dc901d4563e76109793b4acf51a5c169b7d Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 25 Oct 2020 16:06:37 -0500 Subject: [PATCH 03/38] remove unwanted # --- web/skins/classic/views/js/events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index d98d51f4f..b657c50cf 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -61,7 +61,7 @@ function processRows(rows) { if ( canEditMonitors ) row.Monitor = '' + row.Monitor + ''; if ( canEditEvents ) row.Cause = '' + row.Cause + ''; if ( row.Notes.indexOf('detected:') >= 0 ) { - row.Cause = row.Cause + '
' + row.Notes + '
'; + row.Cause = row.Cause + '
' + row.Notes + '
'; } else if ( row.Notes != 'Forced Web: ' ) { row.Cause = row.Cause + '
' + row.Notes + '
'; } From 706bf085f4b4ab63d8823acad56edf6bef79bd80 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 09:58:47 -0400 Subject: [PATCH 04/38] Add pre and post sql conditions and pre-populate the return --- web/ajax/events.php | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index d224b8742..8a2d735ca 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -115,6 +115,19 @@ function deleteRequest($eid) { } function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $limit) { + $data = array( + 'total' => 0, + 'totalNotFiltered' => 0, + 'rows' => array(), + 'updated' => preg_match('/%/', DATE_FMT_CONSOLE_LONG) ? strftime(DATE_FMT_CONSOLE_LONG) : date(DATE_FMT_CONSOLE_LONG) + ); + + $failed = !$filter->test_pre_sql_conditions(); + if ( $failed ) { + ZM\Debug('Pre conditions failed, not doing sql'); + return $data; + } + // Put server pagination code here // The table we want our data from $table = 'Events'; @@ -138,7 +151,6 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim } } $col_str = implode(', ', $columns); - $data = array(); $query = array(); $query['values'] = array(); $likes = array(); @@ -177,14 +189,8 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $query['sql'] = 'SELECT ' .$col_str. ' FROM `' .$table. '` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where.' ORDER BY LENGTH(' .$sort. '), ' .$sort. ' ' .$order. ' LIMIT ?, ?'; array_push($query['values'], $offset, $limit); - ZM\Warning('Calling the following sql query: ' .$query['sql']); + ZM\Debug('Calling the following sql query: ' .$query['sql']); - $data['totalNotFiltered'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table . ' AS E'. ($filter->sql() ? ' WHERE '.$filter->sql():''), 'Total'); - if ( $search != '' || count($advsearch) ) { - $data['total'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table . ' AS E'.$where , 'Total', $wherevalues); - } else { - $data['total'] = $data['totalNotFiltered']; - } $storage_areas = ZM\Storage::find(); $StorageById = array(); @@ -202,6 +208,10 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim foreach ( dbFetchAll($query['sql'], NULL, $query['values']) as $row ) { ZM\Debug("row".print_r($row,true)); $event = new ZM\Event($row); + if ( !$filter->test_post_sql_conditions($event) ) { + $event->remove_from_cache(); + continue; + } $scale = intval(5*100*ZM_WEB_LIST_THUMB_WIDTH / $event->Width()); $imgSrc = $event->getThumbnailSrc(array(),'&'); $streamSrc = $event->getStreamSrc(array( @@ -223,8 +233,9 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $rows[] = $row; } $data['rows'] = $rows; - $data['updated'] = preg_match('/%/', DATE_FMT_CONSOLE_LONG) ? strftime(DATE_FMT_CONSOLE_LONG) : date(DATE_FMT_CONSOLE_LONG); + $data['totalNotFiltered'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table. ' AS E'. ($filter->sql() ? ' WHERE '.$filter->sql():''), 'Total'); + $data['total'] = count($rows); return $data; } ?> From 4c791b390f73ea5a538569c88c5d46d2a28654b1 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 09:59:15 -0400 Subject: [PATCH 05/38] fix warning due to undefined vars being used --- web/ajax/log.php | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/web/ajax/log.php b/web/ajax/log.php index bde07ed65..22897fd04 100644 --- a/web/ajax/log.php +++ b/web/ajax/log.php @@ -66,7 +66,7 @@ if ( isset($_REQUEST['limit']) ) { switch ( $task ) { case 'create' : - createRequest($task, $eid); + createRequest(); break; case 'query' : $data = queryRequest($search, $advsearch, $sort, $offset, $order, $limit); @@ -82,27 +82,27 @@ ajaxResponse($data); // function createRequest() { - if ( !empty($_POST['level']) && !empty($_POST['message']) ) { - ZM\logInit(array('id'=>'web_js')); + if ( !empty($_POST['level']) && !empty($_POST['message']) ) { + ZM\logInit(array('id'=>'web_js')); - $string = $_POST['message']; + $string = $_POST['message']; - $file = !empty($_POST['file']) ? preg_replace('/\w+:\/\/[\w.:]+\//', '', $_POST['file']) : ''; - if ( !empty($_POST['line']) ) { - $line = validInt($_POST['line']); - } else { - $line = NULL; - } - - $levels = array_flip(ZM\Logger::$codes); - if ( !isset($levels[$_POST['level']]) ) { - ZM\Panic('Unexpected logger level '.$_POST['level']); - } - $level = $levels[$_POST['level']]; - ZM\Logger::fetch()->logPrint($level, $string, $file, $line); + $file = !empty($_POST['file']) ? preg_replace('/\w+:\/\/[\w.:]+\//', '', $_POST['file']) : ''; + if ( !empty($_POST['line']) ) { + $line = validInt($_POST['line']); } else { - ZM\Error('Invalid log create: '.print_r($_POST, true)); + $line = NULL; } + + $levels = array_flip(ZM\Logger::$codes); + if ( !isset($levels[$_POST['level']]) ) { + ZM\Panic('Unexpected logger level '.$_POST['level']); + } + $level = $levels[$_POST['level']]; + ZM\Logger::fetch()->logPrint($level, $string, $file, $line); + } else { + ZM\Error('Invalid log create: '.print_r($_POST, true)); + } } function queryRequest($search, $advsearch, $sort, $offset, $order, $limit) { From 27b39a0258d58480c2ec6c6371bd75aade341710 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 26 Oct 2020 09:19:08 -0500 Subject: [PATCH 06/38] comment out warning used for debug --- web/ajax/events.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index c27817be3..ff2c5b426 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -169,7 +169,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $query['sql'] = 'SELECT ' .$col_str. ' FROM `' .$table. '` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id'.$where.' ORDER BY ' .$sort. ' ' .$order. ' LIMIT ?, ?'; array_push($query['values'], $offset, $limit); - ZM\Warning('Calling the following sql query: ' .$query['sql']); + //ZM\Warning('Calling the following sql query: ' .$query['sql']); $data['totalNotFiltered'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table . ' AS E'. ($filter->sql() ? ' WHERE '.$filter->sql():''), 'Total'); if ( $search != '' || count($advsearch) ) { From 97573122bc090e0a9f88c8b0d54a73d9337739b6 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 26 Oct 2020 09:33:11 -0500 Subject: [PATCH 07/38] fix EndTime --- web/ajax/events.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index ff2c5b426..c13be849d 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -200,7 +200,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $row['Emailed'] = $row['Emailed'] ? translate('Yes') : translate('No'); $row['Cause'] = validHtmlStr($row['Cause']); $row['StartTime'] = strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['StartTime'])); - $row['EndTime'] = strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['StartTime'])); + $row['EndTime'] = strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['EndTime'])); $row['Length'] = gmdate('H:i:s', $row['Length'] ); $row['Storage'] = ( $row['StorageId'] and isset($StorageById[$row['StorageId']]) ) ? $StorageById[$row['StorageId']]->Name() : 'Default'; $row['Notes'] = htmlspecialchars($row['Notes']); From da87b5b475145bbda71d57f8ae1717e676dfd514 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 13:06:05 -0400 Subject: [PATCH 08/38] Make invalid sort field non-fatal. Fix column specification in search and advscearch and fix resulting sql due to = instead of .= --- web/ajax/events.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index 51df45035..4046c69f1 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -139,7 +139,8 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $col_alt = array('Monitor', 'Storage'); if ( !in_array($sort, array_merge($columns, $col_alt)) ) { - ZM\Fatal('Invalid sort field: ' . $sort); + ZM\Error('Invalid sort field: ' . $sort); + $sort = 'Id'; } $data = array(); @@ -153,26 +154,31 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim if ( count($advsearch) ) { foreach ( $advsearch as $col=>$text ) { - if ( !in_array($col, array_merge($columns, $col_alt)) ) { + if ( in_array($col, $columns) ) { + $text = '%' .$text. '%'; + array_push($likes, 'E.'.$col.' LIKE ?'); + array_push($query['values'], $text); + } else if ( in_array($col, $col_alt) ) { + $text = '%' .$text. '%'; + array_push($likes, 'M.'.$col.' LIKE ?'); + array_push($query['values'], $text); + } else { ZM\Error("'$col' is not a sortable column name"); continue; } - $text = '%' .$text. '%'; - array_push($likes, $col.' LIKE ?'); - array_push($query['values'], $text); - } + } # end foreach col in advsearch $wherevalues = $query['values']; - $where = ' AND (' .implode(' OR ', $likes). ')'; + $where .= ($where != '') ? ' AND (' .implode(' OR ', $likes). ')' : implode(' OR ', $likes); } else if ( $search != '' ) { $search = '%' .$search. '%'; foreach ( $columns as $col ) { - array_push($likes, $col.' LIKE ?'); + array_push($likes, 'E.'.$col.' LIKE ?'); array_push($query['values'], $search); } $wherevalues = $query['values']; - $where = ' AND (' .implode(' OR ', $likes). ')'; + $where .= ( $where != '') ? ' AND (' .implode(' OR ', $likes). ')' : implode(' OR ', $likes); } if ( $where ) $where = ' WHERE '.$where; From 59cf5c33c24991c3aeee39b65df9a549228c45a6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 13:06:22 -0400 Subject: [PATCH 09/38] reset search on events load --- web/skins/classic/views/js/events.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index b657c50cf..ed591e510 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -336,6 +336,7 @@ function initPage() { table.find("tr td:nth-child(" + (thumb_ndx+1) + ")").addClass('colThumbnail zoom'); }); + table.bootstrapTable('resetSearch'); // The table is initially given a hidden style, so now that we are done rendering, show it table.show(); } From 1f64a263eb3da2d007bbf6b72c84d4eba1364857 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 13:06:41 -0400 Subject: [PATCH 10/38] give better log when jqxhr is empty --- web/skins/classic/js/skin.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web/skins/classic/js/skin.js b/web/skins/classic/js/skin.js index aec9ee1d5..f6cbb328a 100644 --- a/web/skins/classic/js/skin.js +++ b/web/skins/classic/js/skin.js @@ -351,6 +351,11 @@ if ( currentView != 'none' && currentView != 'login' ) { .done(setNavBar) .fail(function(jqxhr, textStatus, error) { console.log("Request Failed: " + textStatus + ", " + error); + if ( ! jqxhr.responseText ) { + console.log("No responseText in jqxhr"); + console.log(jqxhr); + return; + } console.log("Response Text: " + jqxhr.responseText.replace(/(<([^>]+)>)/gi, '')); if ( textStatus != "timeout" ) { // The idea is that this should only fail due to auth, so reload the page From fad4339713fe5ae8709f5a78d500429a42828f2a Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 26 Oct 2020 12:12:50 -0500 Subject: [PATCH 11/38] no need for full page reload with server pagination --- web/skins/classic/views/js/events.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index ed591e510..f0bd0b3ac 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -135,7 +135,7 @@ function manageDelConfirmModalBtns() { $j.getJSON(thisUrl + '?request=events&task=delete&eids[]='+selections.join('&eids[]=')) .done( function(data) { $j('#eventTable').bootstrapTable('refresh'); - window.location.reload(true); + $j('#deleteConfirm').modal('hide'); }) .fail(logAjaxFail); }); @@ -238,7 +238,6 @@ function initPage() { $j.getJSON(thisUrl + '?request=events&task=archive&eids[]='+selections.join('&eids[]=')) .done( function(data) { $j('#eventTable').bootstrapTable('refresh'); - window.location.reload(true); }) .fail(logAjaxFail); }); @@ -257,11 +256,8 @@ function initPage() { $j.getJSON(thisUrl + '?request=events&task=unarchive&eids[]='+selections.join('&eids[]=')) .done( function(data) { $j('#eventTable').bootstrapTable('refresh'); - window.location.reload(true); }) .fail(logAjaxFail); - - //window.location.reload(true); }); // Manage the EDIT button From 7b106e2522eaa0289391d17e5de45de85fa6ce78 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 26 Oct 2020 12:20:26 -0500 Subject: [PATCH 12/38] don't use wildcards in advanced search --- web/ajax/events.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index 32e8f7ce9..850628109 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -155,11 +155,11 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim foreach ( $advsearch as $col=>$text ) { if ( in_array($col, $columns) ) { - $text = '%' .$text. '%'; + //$text = '%' .$text. '%'; array_push($likes, 'E.'.$col.' LIKE ?'); array_push($query['values'], $text); } else if ( in_array($col, $col_alt) ) { - $text = '%' .$text. '%'; + //$text = '%' .$text. '%'; array_push($likes, 'M.'.$col.' LIKE ?'); array_push($query['values'], $text); } else { From 1fde123ebc9f03de0bf31df5728435716f15a0e0 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 18:47:03 -0400 Subject: [PATCH 13/38] add LockRows to Filters --- db/zm_create.sql.in | 1 + 1 file changed, 1 insertion(+) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 71d07ad07..a8b83826f 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -303,6 +303,7 @@ CREATE TABLE `Filters` ( `UpdateDiskSpace` tinyint(3) unsigned NOT NULL default '0', `Background` tinyint(1) unsigned NOT NULL default '0', `Concurrent` tinyint(1) unsigned NOT NULL default '0', + `LockRows` tinyint(1) unsigned NOT NULL default '0', PRIMARY KEY (`Id`), KEY `Name` (`Name`) ) ENGINE=@ZM_MYSQL_ENGINE@; From a2596505e9ccd604b280af01c346bf89c6761bf7 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 18:47:17 -0400 Subject: [PATCH 14/38] add LockRows to Filters --- web/includes/Filter.php | 1 + web/skins/classic/views/filter.php | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/web/includes/Filter.php b/web/includes/Filter.php index b6c163f91..bd22f3b89 100644 --- a/web/includes/Filter.php +++ b/web/includes/Filter.php @@ -29,6 +29,7 @@ class Filter extends ZM_Object { 'Background' => 0, 'Concurrent' => 0, 'Query_json' => '', + 'LockRows' => 0, ); protected $_querystring; diff --git a/web/skins/classic/views/filter.php b/web/skins/classic/views/filter.php index 96e0b9728..d53fff02a 100644 --- a/web/skins/classic/views/filter.php +++ b/web/skins/classic/views/filter.php @@ -485,6 +485,10 @@ if ( ZM_OPT_MESSAGE ) { Concurrent() ) { ?> checked="checked" data-on-click-this="updateButtons"/>

+

+ + LockRows() ) { ?> checked="checked" data-on-click-this="updateButtons"/> +


From 7a65a6464458a307861139417324faf65518a7c6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 18:47:40 -0400 Subject: [PATCH 15/38] add LockRows to Filters --- scripts/ZoneMinder/lib/ZoneMinder/Filter.pm | 3 +++ scripts/zmfilter.pl.in | 2 ++ 2 files changed, 5 insertions(+) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm index 9bb13132c..85c09b141 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm @@ -77,6 +77,7 @@ UpdateDiskSpace UserId Background Concurrent +LockRows ); sub Execute { @@ -103,6 +104,8 @@ sub Execute { $sql =~ s/zmSystemLoad/$load/g; } + $sql .= ' FOR UPDATE' if $$self{LockRows}; + Debug("Filter::Execute SQL ($sql)"); my $sth = $ZoneMinder::Database::dbh->prepare_cached($sql) or Fatal("Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr()); diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 9a93c8953..5540e6944 100644 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -277,6 +277,7 @@ FILTER: while( my $db_filter = $sth->fetchrow_hashref() ) { sub checkFilter { my $filter = shift; + my $in_transaction = ZoneMinder::Database::start_transaction($dbh) if $$filter{LockRows}; my @Events = $filter->Execute(); Debug( join(' ', @@ -396,6 +397,7 @@ sub checkFilter { $ZoneMinder::Database::dbh->commit(); } # end if UpdateDiskSpace } # end foreach event + ZoneMinder::Database::end_transaction($dbh, $in_transaction) if $$filter{LockRows}; } # end sub checkFilter sub generateVideo { From ffc5249a665edaa1d5bacbe9081d0f1593574a95 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 18:47:55 -0400 Subject: [PATCH 16/38] add LockRows to Filters --- web/lang/en_gb.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index b80121bed..0877f7399 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -371,6 +371,7 @@ $SLANG = array( 'FilterUpdateDiskSpace' => 'Update used disk space', 'FilterDeleteEvents' => 'Delete all matches', 'FilterCopyEvents' => 'Copy all matches', + 'FilterLockRows' => 'Lock Rows', 'FilterMoveEvents' => 'Move all matches', 'FilterEmailEvents' => 'Email details of all matches', 'FilterEmailTo' => 'Email To', From cd9b16a467da7c3ccb6fe2a1453a6d67a51080c9 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 18:48:16 -0400 Subject: [PATCH 17/38] add LockRows to Filters --- db/zm_update-1.35.11.sql | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 db/zm_update-1.35.11.sql diff --git a/db/zm_update-1.35.11.sql b/db/zm_update-1.35.11.sql new file mode 100644 index 000000000..b8c54f713 --- /dev/null +++ b/db/zm_update-1.35.11.sql @@ -0,0 +1,18 @@ +-- +-- Update Filters table to have a LockRows Column +-- + +SELECT 'Checking for LockRows in Filters'; +SET @s = (SELECT IF( + (SELECT COUNT(*) + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'Filters' + AND table_schema = DATABASE() + AND column_name = 'LockRows' + ) > 0, +"SELECT 'Column LockRows already exists in Filters'", +"ALTER TABLE Filters ADD COLUMN `LockRows` tinyint(1) unsigned NOT NULL default '0' AFTER `Concurrent`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; From f3f0a6baff2de703928a23ef2362d5fd4b053cfa Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 18:48:43 -0400 Subject: [PATCH 18/38] remove debug --- src/zm_ffmpeg_camera.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index e04f5e8ca..7d990bcd2 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -664,7 +664,6 @@ int FfmpegCamera::OpenFfmpeg() { } // int FfmpegCamera::OpenFfmpeg() int FfmpegCamera::Close() { - Debug(2, "CloseFfmpeg called."); mCanCapture = false; From a5bb2365b54d09fcc983e72a77a28582a961ab8f Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 18:49:03 -0400 Subject: [PATCH 19/38] update auth_relay when we update auth_hash --- web/skins/classic/js/skin.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/skins/classic/js/skin.js b/web/skins/classic/js/skin.js index f6cbb328a..85449927c 100644 --- a/web/skins/classic/js/skin.js +++ b/web/skins/classic/js/skin.js @@ -372,10 +372,14 @@ if ( currentView != 'none' && currentView != 'login' ) { } if ( data.auth ) { if ( data.auth != auth_hash ) { + console.log("Update auth_hash to "+data.auth); // Update authentication token. auth_hash = data.auth; } } + if ( data.auth_relay ) { + auth_relay = data.auth_relay; + } // iterate through all the keys then update each element id with the same name for (var key of Object.keys(data)) { if ( key == "auth" ) continue; From 1690bcbd381a4f461bbbf5ac72c091212037c116 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 18:49:14 -0400 Subject: [PATCH 20/38] update auth_relay when we update auth_hash --- web/ajax/status.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/ajax/status.php b/web/ajax/status.php index 0bafe16e4..190d239ad 100644 --- a/web/ajax/status.php +++ b/web/ajax/status.php @@ -6,6 +6,7 @@ if ( $_REQUEST['entity'] == 'navBar' ) { $auth_hash = generateAuthHash(ZM_AUTH_HASH_IPS); if ( isset($_REQUEST['auth']) and ($_REQUEST['auth'] != $auth_hash) ) { $data['auth'] = $auth_hash; + $data['auth_relay'] = get_auth_relay(); } } // Each widget on the navbar has its own function From c67b3c5a1f1189e41f2cf617481a7874785378b8 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 26 Oct 2020 18:49:41 -0400 Subject: [PATCH 21/38] fix button disabled status. We now have checkboxes that aren't actions so we need to be more explicit --- web/skins/classic/views/js/filter.js | 53 +++++++++++++--------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/web/skins/classic/views/js/filter.js b/web/skins/classic/views/js/filter.js index fd7ee94ca..707fb06e1 100644 --- a/web/skins/classic/views/js/filter.js +++ b/web/skins/classic/views/js/filter.js @@ -74,35 +74,32 @@ function validateForm(form) { function updateButtons(element) { var form = element.form; - if ( element.type == 'checkbox' && element.checked ) { - form.elements['executeButton'].disabled = false; - } else { - var canExecute = false; - if ( form.elements['filter[AutoArchive]'] && form.elements['filter[AutoArchive]'].checked ) { - canExecute = true; - } else if ( form.elements['filter[AutoUnarchive]'] && form.elements['filter[AutoUnarchive]'].checked ) { - canExecute = true; - } else if ( form.elements['filter[AutoCopy]'] && form.elements['filter[AutoCopy]'].checked ) { - canExecute = true; - } else if ( form.elements['filter[AutoMove]'] && form.elements['filter[AutoMove]'].checked ) { - canExecute = true; - } else if ( form.elements['filter[AutoVideo]'] && form.elements['filter[AutoVideo]'].checked ) { - canExecute = true; - } else if ( form.elements['filter[AutoUpload]'] && form.elements['filter[AutoUpload]'].checked ) { - canExecute = true; - } else if ( form.elements['filter[AutoEmail]'] && form.elements['filter[AutoEmail]'].checked ) { - canExecute = true; - } else if ( form.elements['filter[AutoMessage]'] && form.elements['filter[AutoMessage]'].checked ) { - canExecute = true; - } else if ( form.elements['filter[AutoExecute]'].checked && form.elements['filter[AutoExecuteCmd]'].value != '' ) { - canExecute = true; - } else if ( form.elements['filter[AutoDelete]'].checked ) { - canExecute = true; - } else if ( form.elements['filter[UpdateDiskSpace]'].checked ) { - canExecute = true; - } - form.elements['executeButton'].disabled = !canExecute; + + var canExecute = false; + if ( form.elements['filter[AutoArchive]'] && form.elements['filter[AutoArchive]'].checked ) { + canExecute = true; + } else if ( form.elements['filter[AutoUnarchive]'] && form.elements['filter[AutoUnarchive]'].checked ) { + canExecute = true; + } else if ( form.elements['filter[AutoCopy]'] && form.elements['filter[AutoCopy]'].checked ) { + canExecute = true; + } else if ( form.elements['filter[AutoMove]'] && form.elements['filter[AutoMove]'].checked ) { + canExecute = true; + } else if ( form.elements['filter[AutoVideo]'] && form.elements['filter[AutoVideo]'].checked ) { + canExecute = true; + } else if ( form.elements['filter[AutoUpload]'] && form.elements['filter[AutoUpload]'].checked ) { + canExecute = true; + } else if ( form.elements['filter[AutoEmail]'] && form.elements['filter[AutoEmail]'].checked ) { + canExecute = true; + } else if ( form.elements['filter[AutoMessage]'] && form.elements['filter[AutoMessage]'].checked ) { + canExecute = true; + } else if ( form.elements['filter[AutoExecute]'].checked && form.elements['filter[AutoExecuteCmd]'].value != '' ) { + canExecute = true; + } else if ( form.elements['filter[AutoDelete]'].checked ) { + canExecute = true; + } else if ( form.elements['filter[UpdateDiskSpace]'].checked ) { + canExecute = true; } + form.elements['executeButton'].disabled = !canExecute; if ( form.elements['filter[Name]'].value ) { form.elements['Save'].disabled = false; form.elements['SaveAs'].disabled = false; From 3825af8243e997eaec725aa2a967ba422a3bf652 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 28 Oct 2020 09:19:54 -0400 Subject: [PATCH 22/38] Add FOREIGN KEYS for EventId in Frames, Stats. MonitorId, ZoneId in Stats. MonitorId in Zones. --- db/zm_create.sql.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/db/zm_create.sql.in b/db/zm_create.sql.in index 71d07ad07..940ba2a82 100644 --- a/db/zm_create.sql.in +++ b/db/zm_create.sql.in @@ -315,6 +315,7 @@ DROP TABLE IF EXISTS `Frames`; CREATE TABLE `Frames` ( `Id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `EventId` BIGINT UNSIGNED NOT NULL default '0', + FOREIGN KEY (`EventId`) REFERENCES `Events` (`Id`) ON DELETE CASCADE, `FrameId` int(10) unsigned NOT NULL default '0', `Type` enum('Normal','Bulk','Alarm') NOT NULL default 'Normal', `TimeStamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, @@ -608,8 +609,11 @@ DROP TABLE IF EXISTS `Stats`; CREATE TABLE `Stats` ( `Id` int(10) unsigned NOT NULL AUTO_INCREMENT, `MonitorId` int(10) unsigned NOT NULL default '0', + FOREIGN KEY (`MonitorId`) REFERENCES `Monitors` (`Id`) ON DELETE CASCADE, `ZoneId` int(10) unsigned NOT NULL default '0', + FOREIGN KEY (`ZoneId`) REFERENCES `Zones` (`Id`) ON DELETE CASCADE, `EventId` BIGINT UNSIGNED NOT NULL, + FOREIGN KEY (`EventId`) REFERENCES `Events` (`Id`) ON DELETE CASCADE, `FrameId` int(10) unsigned NOT NULL default '0', `PixelDiff` tinyint(3) unsigned NOT NULL default '0', `AlarmPixels` int(10) unsigned NOT NULL default '0', @@ -704,6 +708,7 @@ DROP TABLE IF EXISTS `Zones`; CREATE TABLE `Zones` ( `Id` int(10) unsigned NOT NULL auto_increment, `MonitorId` int(10) unsigned NOT NULL default '0', + FOREIGN KEY (`MonitorId`) REFERENCES `Monitors` (`Id`) ON DELETE CASCADE, `Name` varchar(64) NOT NULL default '', `Type` enum('Active','Inclusive','Exclusive','Preclusive','Inactive','Privacy') NOT NULL default 'Active', `Units` enum('Pixels','Percent') NOT NULL default 'Pixels', From 59884375fa5df340daa1cb9dbf245111aadda7bc Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 28 Oct 2020 09:23:46 -0400 Subject: [PATCH 23/38] Add references permission so that our zmupdate can add foreign keys --- distros/beowulf/zoneminder.postinst | 4 ++-- distros/ubuntu1604/zoneminder.postinst | 2 +- distros/ubuntu2004/zoneminder.postinst | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/distros/beowulf/zoneminder.postinst b/distros/beowulf/zoneminder.postinst index 603786ff6..032595355 100644 --- a/distros/beowulf/zoneminder.postinst +++ b/distros/beowulf/zoneminder.postinst @@ -39,9 +39,9 @@ if [ "$1" = "configure" ]; then exit 1; fi # This creates the user. - 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 + echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute, REFERENCES 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,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 + echo "grant lock tables, alter,drop,select,insert,update,delete,create,index,alter routine,create routine, trigger,execute, REFERENCES on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql fi zmupdate.pl --nointeractive diff --git a/distros/ubuntu1604/zoneminder.postinst b/distros/ubuntu1604/zoneminder.postinst index 7b7af708b..d89ccf531 100644 --- a/distros/ubuntu1604/zoneminder.postinst +++ b/distros/ubuntu1604/zoneminder.postinst @@ -68,7 +68,7 @@ if [ "$1" = "configure" ]; then echo "CREATE USER '${ZM_DB_USER}'@localhost IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql fi echo "Updating permissions" - 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 + echo "GRANT LOCK TABLES,ALTER,DROP,SELECT,INSERT,UPDATE,DELETE,CREATE,INDEX,ALTER ROUTINE,CREATE ROUTINE, TRIGGER,EXECUTE,REFERENCES ON ${ZM_DB_NAME}.* TO '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql zmupdate.pl --nointeractive zmupdate.pl --nointeractive -f diff --git a/distros/ubuntu2004/zoneminder.postinst b/distros/ubuntu2004/zoneminder.postinst index a8b8eaf51..a50d7cf2e 100644 --- a/distros/ubuntu2004/zoneminder.postinst +++ b/distros/ubuntu2004/zoneminder.postinst @@ -26,7 +26,7 @@ create_update_user () { echo "CREATE USER '${ZM_DB_USER}'@${ZM_DB_HOST} IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql fi echo "Updating permissions" - 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}'@${ZM_DB_HOST};" | 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,REFERENCES ON ${ZM_DB_NAME}.* TO '${ZM_DB_USER}'@${ZM_DB_HOST};" | mysql --defaults-file=/etc/mysql/debian.cnf mysql } update_db () { From 43b7021f9cd3a0b719c721cb9f4c95e7827e55b6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 28 Oct 2020 12:38:44 -0400 Subject: [PATCH 24/38] ALTER Events.Id to BIGINT. This update got lost at somepoint. Add FOREIGN KEYS to Frames, Stats and Zones tables --- db/zm_update-1.35.11.sql | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 db/zm_update-1.35.11.sql diff --git a/db/zm_update-1.35.11.sql b/db/zm_update-1.35.11.sql new file mode 100644 index 000000000..e0257c184 --- /dev/null +++ b/db/zm_update-1.35.11.sql @@ -0,0 +1,22 @@ + +/* Change Id type to BIGINT. */ +ALTER TABLE Events MODIFY Id bigint unsigned NOT NULL auto_increment; + +/* Add FOREIGN KEYS After deleting lost records */ +DELETE FROM Frames WHERE EventId NOT IN (SELECT Id FROM Events); +ALTER TABLE Frames ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE; + +/* Add FOREIGN KEYS After deleting lost records */ +DELETE FROM Stats WHERE EventId NOT IN (SELECT Id FROM Events); +ALTER TABLE Stats ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE; + +DELETE FROM Stats WHERE MonitorId NOT IN (SELECT Id FROM Monitors); +ALTER TABLE Stats ADD FOREIGN KEY (`MonitorId`) REFERENCES `Monitors` (`Id`) ON DELETE CASCADE; + +DELETE FROM Stats WHERE ZoneId NOT IN (SELECT Id FROM Zones); +ALTER TABLE Stats ADD FOREIGN KEY (`ZoneId`) REFERENCES `Zones` (`Id`) ON DELETE CASCADE; + +/* Add FOREIGN KEYS After deleting lost records */ +DELETE FROM Zones WHERE MonitorId NOT IN (SELECT Id FROM Monitors); +ALTER TABLE Zones ADD FOREIGN KEY (`MonitorId`) REFERENCES `Monitors` (`Id`) ON DELETE CASCADE; + From 4c92c99ba17e3b4107c8d40230a69214e926dc26 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 28 Oct 2020 12:39:50 -0400 Subject: [PATCH 25/38] bump version for 1.35.11 db updates --- distros/redhat/zoneminder.spec | 2 +- version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index 5c19dd0c0..3a4d45de8 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -28,7 +28,7 @@ %global _hardened_build 1 Name: zoneminder -Version: 1.35.10 +Version: 1.35.11 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons diff --git a/version b/version index a0b71b46f..5f1e3b58b 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.35.10 +1.35.11 From b3a28b2ba20b858eea71be965bbdeae8662a3cb8 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 28 Oct 2020 12:49:03 -0400 Subject: [PATCH 26/38] fix confusion in syslog reporting web_php when the error was actually web_js --- web/includes/logger.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/includes/logger.php b/web/includes/logger.php index fb7d58f93..ab59b412b 100644 --- a/web/includes/logger.php +++ b/web/includes/logger.php @@ -408,10 +408,10 @@ class Logger { } } - $message = $code.' ['.$string.']'; if ( $level <= $this->syslogLevel ) - syslog( self::$syslogPriorities[$level], $message ); + syslog(self::$syslogPriorities[$level], $message); + $message = $code.' ['.$string.']'; if ( $level <= $this->databaseLevel ) { try { global $dbConn; From 686f793d097973c15f62d89a670c9cf2fb1d648c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 28 Oct 2020 12:49:39 -0400 Subject: [PATCH 27/38] fix truth value for ZM_OPT_USE_GEOLOCATION --- web/skins/classic/views/js/monitor.js.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/monitor.js.php b/web/skins/classic/views/js/monitor.js.php index cc61270d0..bdcc17554 100644 --- a/web/skins/classic/views/js/monitor.js.php +++ b/web/skins/classic/views/js/monitor.js.php @@ -1,4 +1,4 @@ -var ZM_OPT_USE_GEOLOCATION = ''; +var ZM_OPT_USE_GEOLOCATION = '' == '1' ? true : false; Date: Wed, 28 Oct 2020 12:55:32 -0400 Subject: [PATCH 28/38] Add Locking to filters, bump db to 1.35.12. --- db/zm_update-1.35.12.sql | 18 ++++++++++++++++++ distros/redhat/zoneminder.spec | 2 +- version | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 db/zm_update-1.35.12.sql diff --git a/db/zm_update-1.35.12.sql b/db/zm_update-1.35.12.sql new file mode 100644 index 000000000..b8c54f713 --- /dev/null +++ b/db/zm_update-1.35.12.sql @@ -0,0 +1,18 @@ +-- +-- Update Filters table to have a LockRows Column +-- + +SELECT 'Checking for LockRows in Filters'; +SET @s = (SELECT IF( + (SELECT COUNT(*) + FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = 'Filters' + AND table_schema = DATABASE() + AND column_name = 'LockRows' + ) > 0, +"SELECT 'Column LockRows already exists in Filters'", +"ALTER TABLE Filters ADD COLUMN `LockRows` tinyint(1) unsigned NOT NULL default '0' AFTER `Concurrent`" +)); + +PREPARE stmt FROM @s; +EXECUTE stmt; diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index 3a4d45de8..eefba559d 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -28,7 +28,7 @@ %global _hardened_build 1 Name: zoneminder -Version: 1.35.11 +Version: 1.35.12 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons diff --git a/version b/version index 5f1e3b58b..7d872edd4 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.35.11 +1.35.12 From 9a9f80c15c00a050b991355d9edaf85abcfcae4d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 28 Oct 2020 14:07:29 -0400 Subject: [PATCH 29/38] show which user we are updating permissions for --- distros/ubuntu1604/zoneminder.postinst | 2 +- distros/ubuntu2004/zoneminder.postinst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/distros/ubuntu1604/zoneminder.postinst b/distros/ubuntu1604/zoneminder.postinst index d89ccf531..d4010008a 100644 --- a/distros/ubuntu1604/zoneminder.postinst +++ b/distros/ubuntu1604/zoneminder.postinst @@ -67,7 +67,7 @@ if [ "$1" = "configure" ]; then # This creates the user. echo "CREATE USER '${ZM_DB_USER}'@localhost IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql fi - echo "Updating permissions" + echo "Updating permissions for user ${ZM_DB_USER}@localhost" echo "GRANT LOCK TABLES,ALTER,DROP,SELECT,INSERT,UPDATE,DELETE,CREATE,INDEX,ALTER ROUTINE,CREATE ROUTINE, TRIGGER,EXECUTE,REFERENCES ON ${ZM_DB_NAME}.* TO '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql zmupdate.pl --nointeractive diff --git a/distros/ubuntu2004/zoneminder.postinst b/distros/ubuntu2004/zoneminder.postinst index a50d7cf2e..cd147a0e2 100644 --- a/distros/ubuntu2004/zoneminder.postinst +++ b/distros/ubuntu2004/zoneminder.postinst @@ -25,7 +25,7 @@ create_update_user () { # This creates the user. echo "CREATE USER '${ZM_DB_USER}'@${ZM_DB_HOST} IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql fi - echo "Updating permissions" + echo "Updating permissions for user ${ZM_DB_USER}@${ZM_DB_HOST}" echo "GRANT LOCK tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine,trigger,execute,REFERENCES ON ${ZM_DB_NAME}.* TO '${ZM_DB_USER}'@${ZM_DB_HOST};" | mysql --defaults-file=/etc/mysql/debian.cnf mysql } From a35c143094aabc0f515281bf47e0137913bcdd02 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 28 Oct 2020 15:01:14 -0400 Subject: [PATCH 30/38] Prevent extra foreign keys from being created and fix we can't delete from Zones. Must be done manually --- db/zm_update-1.35.11.sql | 78 +++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/db/zm_update-1.35.11.sql b/db/zm_update-1.35.11.sql index c1e9aad64..0b51f2ef5 100644 --- a/db/zm_update-1.35.11.sql +++ b/db/zm_update-1.35.11.sql @@ -1,20 +1,74 @@ /* Change Id type to BIGINT. */ +SELECT 'Updating Events.Id to BIGINT'; ALTER TABLE Events MODIFY Id bigint unsigned NOT NULL auto_increment; /* Add FOREIGN KEYS After deleting lost records */ -DELETE FROM Frames WHERE EventId NOT IN (SELECT Id FROM Events); -ALTER TABLE Frames ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE; +SELECT 'Adding foreign key for EventId to Frames'; +set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Frames' and column_name='EventId' and referenced_table_name='Events' and referenced_column_name='Id'); +set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; -/* Add FOREIGN KEYS After deleting lost records */ -DELETE FROM Stats WHERE EventId NOT IN (SELECT Id FROM Events); -ALTER TABLE Stats ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE; +set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for EventId in Frames already exists'", "DELETE FROM Frames WHERE EventId NOT IN (SELECT Id FROM Events)"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; -DELETE FROM Stats WHERE MonitorId NOT IN (SELECT Id FROM Monitors); -ALTER TABLE Stats ADD FOREIGN KEY (`MonitorId`) REFERENCES `Monitors` (`Id`) ON DELETE CASCADE; +set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Frames ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; -DELETE FROM Stats WHERE ZoneId NOT IN (SELECT Id FROM Zones); -ALTER TABLE Stats ADD FOREIGN KEY (`ZoneId`) REFERENCES `Zones` (`Id`) ON DELETE CASCADE; -/* Add FOREIGN KEYS After deleting lost records */ -DELETE FROM Zones WHERE MonitorId NOT IN (SELECT Id FROM Monitors); -ALTER TABLE Zones ADD FOREIGN KEY (`MonitorId`) REFERENCES `Monitors` (`Id`) ON DELETE CASCADE; +SELECT 'Adding foreign key for EventId to Stats'; +set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='EventId' and referenced_table_name='Events' and referenced_column_name='Id'); +set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; + +set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for EventId in Stats already exists'", "DELETE FROM Stats WHERE EventId NOT IN (SELECT Id FROM Events);"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; + +set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Stats ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; + + +SELECT 'Adding foreign key for MonitorId to Stats'; +set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='MonitorId' and referenced_table_name='Monitors' and referenced_column_name='Id'); +set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; + +set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for MonitorId in Stats already exists'", "DELETE FROM Stats WHERE MonitorId NOT IN (SELECT Id FROM Monitors);"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; + +set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Stats ADD FOREIGN KEY (MonitorId) REFERENCES Monitors (Id) ON DELETE CASCADE"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; + +SELECT 'Adding foreign key for ZoneId to Stats'; +set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='ZoneId' and referenced_table_name='Zones' and referenced_column_name='Id'); +set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; + +set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for ZoneId in Stats already exists'", "DELETE FROM Stats WHERE ZoneId NOT IN (SELECT Id FROM Zones);"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; + +set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Stats ADD FOREIGN KEY (ZoneId) REFERENCES Zones (Id) ON DELETE CASCADE"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; + +SELECT 'Adding foreign key for MonitorId to Zones'; +set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Zones' and column_name='MonitorId' and referenced_table_name='Monitors' and referenced_column_name='Id'); +set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; + +set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for MonitorId in Zones already exists'", "SELECT 'FOREIGN KEY for MonitorId in Zones does not already exist'"); +set @badzones := (select count(*) FROM Zones WHERE MonitorId NOT IN (SELECT Id FROM Monitors)); +set @sqlstmt := if ( @badzones > 0, "SELECT 'You have Zones with no Monitor record in the Monitors table. Please delete them manually'", "ALTER TABLE Zones ADD FOREIGN KEY (MonitorId) REFERENCES Monitors (Id)"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; From 638a05b2079a5787858f67ee7fb686cab0dc7901 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 29 Oct 2020 09:39:48 -0400 Subject: [PATCH 31/38] Fix totalrows in pagination. Still figuring this out. --- web/ajax/events.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index 850628109..d5eb80d24 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -155,11 +155,9 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim foreach ( $advsearch as $col=>$text ) { if ( in_array($col, $columns) ) { - //$text = '%' .$text. '%'; array_push($likes, 'E.'.$col.' LIKE ?'); array_push($query['values'], $text); } else if ( in_array($col, $col_alt) ) { - //$text = '%' .$text. '%'; array_push($likes, 'M.'.$col.' LIKE ?'); array_push($query['values'], $text); } else { @@ -198,7 +196,6 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $rows = array(); foreach ( dbFetchAll($query['sql'], NULL, $query['values']) as $row ) { - ZM\Debug("row".print_r($row,true)); $event = new ZM\Event($row); if ( !$filter->test_post_sql_conditions($event) ) { $event->remove_from_cache(); @@ -207,7 +204,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $scale = intval(5*100*ZM_WEB_LIST_THUMB_WIDTH / $event->Width()); $imgSrc = $event->getThumbnailSrc(array(),'&'); $streamSrc = $event->getStreamSrc(array( - 'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single', 'rate'=>'400'), '&'); + 'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single', 'rate'=>'400'), '&'); // Modify the row data as needed $row['imgHtml'] = '' .validHtmlStr('Event ' .$event->Id()). ''; @@ -225,8 +222,9 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim } $data['rows'] = $rows; - $data['totalNotFiltered'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table. ' AS E'. ($filter->sql() ? ' WHERE '.$filter->sql():''), 'Total'); - $data['total'] = count($rows); + # total has to be the # of available rows. Not sure what totalNotFiltered is actually used for yet. + $data['totalNotFiltered'] = $data['total'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table. ' AS E'. ($filter->sql() ? ' WHERE '.$filter->sql():''), 'Total'); + #$data['total'] = count($rows); return $data; } ?> From 97f4d9e7a2edbbb54602c8da5ab3e2ea45535137 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 29 Oct 2020 09:40:14 -0400 Subject: [PATCH 32/38] Make the event count and diskspace in the storage row be a link to events for that storage area. --- web/skins/classic/views/options.php | 31 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/web/skins/classic/views/options.php b/web/skins/classic/views/options.php index cc8b0b568..a52aca15d 100644 --- a/web/skins/classic/views/options.php +++ b/web/skins/classic/views/options.php @@ -279,17 +279,23 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as 'lower(Name)') ) as $Storage ) { + $filter = new ZM\Filter(); + $filter->addTerm(array('attr'=>'StorageId','op'=>'=','val'=>$Storage->Id())); + if ( $user['MonitorIds'] ) { + $filter = $filter->addTerm(array('cnj'=>'and', 'attr'=>'MonitorId', 'op'=>'IN', 'val'=>$user['MonitorIds'])); + } + $str_opt = 'class="storageCol" data-sid="'.$Storage->Id().'"'; ?> - Id()), $canEdit, $str_opt ) ?> - Name()), $canEdit, $str_opt ) ?> - Path()), $canEdit, $str_opt ) ?> - Type()), $canEdit, $str_opt ) ?> - Scheme()), $canEdit, $str_opt ) ?> - Server()->Name()), $canEdit, $str_opt ) ?> + Id()), $canEdit, $str_opt) ?> + Name()), $canEdit, $str_opt) ?> + Path()), $canEdit, $str_opt) ?> + Type()), $canEdit, $str_opt) ?> + Scheme()), $canEdit, $str_opt) ?> + Server()->Name()), $canEdit, $str_opt) ?> disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?> - EventCount().' using '.human_filesize($Storage->event_disk_space()) ?> + querystring(), $Storage->EventCount().' using '.human_filesize($Storage->event_disk_space()) ); ?> EventCount() or !$canEdit ) { ?> disabled="disabled"EventCount() ? ' title="Can\'t delete as long as there are events stored here."' : ''?>/> @@ -302,13 +308,12 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as APIs are disabled. To enable, please turn on OPT_USE_API in Options->System
"; - } - else { + $apiEnabled = dbFetchOne('SELECT Value FROM Config WHERE Name=\'ZM_OPT_USE_API\''); + if ( $apiEnabled['Value'] != '1' ) { + echo '
APIs are disabled. To enable, please turn on OPT_USE_API in Options->System
'; + } else { ?>
From 41e88fad6eb79761429c9971860a2883c7ebc250 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 29 Oct 2020 15:08:14 -0400 Subject: [PATCH 33/38] translate \n to
. Fixes #3064 --- web/ajax/events.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index d5eb80d24..200416f92 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -216,7 +216,7 @@ function queryRequest($filter, $search, $advsearch, $sort, $offset, $order, $lim $row['EndTime'] = strftime(STRF_FMT_DATETIME_SHORTER, strtotime($row['EndTime'])); $row['Length'] = gmdate('H:i:s', $row['Length'] ); $row['Storage'] = ( $row['StorageId'] and isset($StorageById[$row['StorageId']]) ) ? $StorageById[$row['StorageId']]->Name() : 'Default'; - $row['Notes'] = htmlspecialchars($row['Notes']); + $row['Notes'] = nl2br(htmlspecialchars($row['Notes'])); $row['DiskSpace'] = human_filesize($event->DiskSpace()); $rows[] = $row; } From e4a585eaa328ad85c108efc1bcc8fb9714f7c1a6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 30 Oct 2020 09:18:53 -0400 Subject: [PATCH 34/38] improvements to 1.35.11 db updates --- db/zm_update-1.35.11.sql | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/db/zm_update-1.35.11.sql b/db/zm_update-1.35.11.sql index 0b51f2ef5..3906d8c04 100644 --- a/db/zm_update-1.35.11.sql +++ b/db/zm_update-1.35.11.sql @@ -1,19 +1,26 @@ /* Change Id type to BIGINT. */ -SELECT 'Updating Events.Id to BIGINT'; -ALTER TABLE Events MODIFY Id bigint unsigned NOT NULL auto_increment; +set @exist := (SELECT count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'Events' AND COLUMN_NAME = 'Id' and DATA_TYPE='bigint'); + +set @sqlstmt := if( @exist = 0, "ALTER TABLE Events MODIFY Id bigint unsigned NOT NULL auto_increment", "SELECT 'Ok'"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; /* Add FOREIGN KEYS After deleting lost records */ -SELECT 'Adding foreign key for EventId to Frames'; set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Frames' and column_name='EventId' and referenced_table_name='Events' and referenced_column_name='Id'); + set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); +set @sqlstmt := if( @exist = 1, "SELECT 'FOREIGN KEY EventId in Frames already exists'", @sqlstmt); +set @sqlstmt := if( @exist = 0, "SELECT 'Adding foreign key for EventId to Frames", @sqlstmt); PREPARE stmt FROM @sqlstmt; EXECUTE stmt; -set @sqlstmt := if( @exist > 0, "SELECT 'FOREIGN KEY for EventId in Frames already exists'", "DELETE FROM Frames WHERE EventId NOT IN (SELECT Id FROM Events)"); +set @sqlstmt := if( @exist != 0, "SELECT '.'", "SELECT 'Deleting unlinked Frames'"); PREPARE stmt FROM @sqlstmt; EXECUTE stmt; - -set @sqlstmt := if( @exist > 0, "SELECT 'Ok'", "ALTER TABLE Frames ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE"); +set @sqlstmt := if( @exist != 0, "SELECT '.'", "DELETE FROM Frames WHERE EventId NOT IN (SELECT Id FROM Events)"); +PREPARE stmt FROM @sqlstmt; +EXECUTE stmt; +set @sqlstmt := if( @exist != 0, "SELECT 'Ok'", "ALTER TABLE Frames ADD FOREIGN KEY (EventId) REFERENCES Events (Id) ON DELETE CASCADE"); PREPARE stmt FROM @sqlstmt; EXECUTE stmt; @@ -21,6 +28,8 @@ EXECUTE stmt; SELECT 'Adding foreign key for EventId to Stats'; set @exist := (select count(*) FROM information_schema.key_column_usage where table_name='Stats' and column_name='EventId' and referenced_table_name='Events' and referenced_column_name='Id'); set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); +set @sqlstmt := if( @exist = 1, "SELECT 'FOREIGN KEY already EventId in Stats already exists'", @sqlstmt); +set @sqlstmt := if( @exist = 0, "SELECT 'Adding FOREIGN KEY for EventId to Stats'", @sqlstmt); PREPARE stmt FROM @sqlstmt; EXECUTE stmt; From 65df84ef7efe0bad794ad5cdc99145da4a901f48 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 30 Oct 2020 11:49:00 -0400 Subject: [PATCH 35/38] Make ZoneMinder::Event::delete aware of transactions --- scripts/ZoneMinder/lib/ZoneMinder/Event.pm | 24 ++++++++++++++-------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm index 0af41b2ca..985ac71f3 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm @@ -349,6 +349,10 @@ sub GenerateVideo { return; } # end sub GenerateVideo +# Note about transactions, this function may be called with rows locked and hence in a transaction. +# So we will detect if we are in a transaction, and if not, start one. We will NOT do rollback or +# commits unless we started the transaction. + sub delete { my $event = $_[0]; @@ -378,23 +382,25 @@ sub delete { Info("Deleting event $event->{Id} from Monitor $event->{MonitorId} StartTime:$event->{StartTime} from ".$event->Path()); $ZoneMinder::Database::dbh->ping(); - $ZoneMinder::Database::dbh->begin_work(); - #$event->lock_and_load(); + my $in_transaction = $ZoneMinder::Database::dbh->{AutoCommit} ? 0 : 1; - ZoneMinder::Database::zmDbDo('DELETE FROM Frames WHERE EventId=?', $$event{Id}); - if ( $ZoneMinder::Database::dbh->errstr() ) { - $ZoneMinder::Database::dbh->commit(); - return; - } + $ZoneMinder::Database::dbh->begin_work() if ! $in_transaction; + + # Going to delete in order of least value to greatest value. Stats is least and references Frames ZoneMinder::Database::zmDbDo('DELETE FROM Stats WHERE EventId=?', $$event{Id}); if ( $ZoneMinder::Database::dbh->errstr() ) { - $ZoneMinder::Database::dbh->commit(); + $ZoneMinder::Database::dbh->commit() if ! $in_transaction; + return; + } + ZoneMinder::Database::zmDbDo('DELETE FROM Frames WHERE EventId=?', $$event{Id}); + if ( $ZoneMinder::Database::dbh->errstr() ) { + $ZoneMinder::Database::dbh->commit() if ! $in_transaction; return; } # Do it individually to avoid locking up the table for new events ZoneMinder::Database::zmDbDo('DELETE FROM Events WHERE Id=?', $$event{Id}); - $ZoneMinder::Database::dbh->commit(); + $ZoneMinder::Database::dbh->commit() if ! $in_transaction; } if ( ( $in_zmaudit or (!$Config{ZM_OPT_FAST_DELETE})) and $event->Storage()->DoDelete() ) { From 5fadd366e7f00596835c020c1f09a62a2ee7cfe9 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 30 Oct 2020 11:50:03 -0400 Subject: [PATCH 36/38] Always setup Logging SIG handlers. Implement SIGUSR1 and SIGUSR2 handling to match c++ side behaviour. Fixes #3057 --- scripts/ZoneMinder/lib/ZoneMinder/Logger.pm | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm b/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm index 801dcf199..cf5a0b508 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm @@ -504,9 +504,9 @@ sub openFile { $LOGFILE->autoflush() if $this->{autoFlush}; my $webUid = (getpwnam($ZoneMinder::Config::Config{ZM_WEB_USER}))[2]; - Error("Can't get uid for $ZoneMinder::Config::Config{ZM_WEB_USER}") if ! defined $webUid; + Error('Can\'t get uid for '.$ZoneMinder::Config::Config{ZM_WEB_USER}) if ! defined $webUid; my $webGid = (getgrnam($ZoneMinder::Config::Config{ZM_WEB_GROUP}))[2]; - Error("Can't get gid for $ZoneMinder::Config::Config{ZM_WEB_USER}") if ! defined $webGid; + Error('Can\'t get gid for '.$ZoneMinder::Config::Config{ZM_WEB_USER}) if ! defined $webGid; if ( $> == 0 ) { # If we are root, we want to make sure that www-data or whatever owns the file chown($webUid, $webGid, $this->{logFile} ) or @@ -610,6 +610,7 @@ sub logInit( ;@ ) { my %options = @_ ? @_ : (); $logger = ZoneMinder::Logger->new() if !$logger; $logger->initialise(%options); + logSetSignal(); } sub logReinit { @@ -626,12 +627,26 @@ sub logHupHandler { $do_log_rotate = 1; } +sub logUSR1Handler { + $logger->level($logger->level()+1); + Info('Logger - Level changed to '. $logger->level() . '=>'.$codes{$logger->level()}); +} + +sub logUSR2Handler { + $logger->level($logger->level()-1); + Info('Logger - Level changed to '. $logger->level() . '=>'.$codes{$logger->level()}); +} + sub logSetSignal { $SIG{HUP} = \&logHupHandler; + $SIG{USR1} = \&logUSR1Handler; + $SIG{USR2} = \&logUSR2Handler; } sub logClearSignal { $SIG{HUP} = 'DEFAULT'; + $SIG{USR1} = 'DEFAULT'; + $SIG{USR2} = 'DEFAULT'; } sub logLevel { From e5097d9466150334476f55d2e3517609dd526c40 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 30 Oct 2020 11:50:16 -0400 Subject: [PATCH 37/38] code style --- src/zm_signal.cpp | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/zm_signal.cpp b/src/zm_signal.cpp index 81012c07e..2756802a3 100644 --- a/src/zm_signal.cpp +++ b/src/zm_signal.cpp @@ -29,15 +29,13 @@ bool zm_reload = false; bool zm_terminate = false; -RETSIGTYPE zm_hup_handler(int signal) -{ +RETSIGTYPE zm_hup_handler(int signal) { // Shouldn't do complex things in signal handlers, logging is complex and can block due to mutexes. //Info("Got signal %d (%s), reloading", signal, strsignal(signal)); zm_reload = true; } -RETSIGTYPE zm_term_handler(int signal) -{ +RETSIGTYPE zm_term_handler(int signal) { // Shouldn't do complex things in signal handlers, logging is complex and can block due to mutexes. //Info("Got signal %d (%s), exiting", signal, strsignal(signal)); zm_terminate = true; @@ -55,8 +53,7 @@ RETSIGTYPE zm_die_handler(int signal) #if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) void *ip = nullptr; void *cr2 = nullptr; - if (info && context) { - + if ( info && context ) { Debug(1, "Signal information: number %d code %d errno %d pid %d uid %d status %d", signal, info->si_code, info->si_errno, info->si_pid, @@ -79,7 +76,7 @@ RETSIGTYPE zm_die_handler(int signal) #endif // defined(__x86_64__) // Print the signal address and instruction pointer if available - if (ip) { + if ( ip ) { Error("Signal address is %p, from %p", cr2, ip); } else { Error("Signal address is %p, no instruction pointer", cr2); @@ -115,8 +112,7 @@ RETSIGTYPE zm_die_handler(int signal) exit(signal); } -void zmSetHupHandler(SigHandler * handler) -{ +void zmSetHupHandler(SigHandler * handler) { sigset_t block_set; sigemptyset(&block_set); struct sigaction action, old_action; @@ -127,8 +123,7 @@ void zmSetHupHandler(SigHandler * handler) sigaction(SIGHUP, &action, &old_action); } -void zmSetTermHandler(SigHandler * handler) -{ +void zmSetTermHandler(SigHandler * handler) { sigset_t block_set; sigemptyset(&block_set); struct sigaction action, old_action; @@ -141,8 +136,7 @@ void zmSetTermHandler(SigHandler * handler) sigaction(SIGQUIT, &action, &old_action); } -void zmSetDieHandler(SigHandler * handler) -{ +void zmSetDieHandler(SigHandler * handler) { sigset_t block_set; sigemptyset(&block_set); struct sigaction action, old_action; @@ -163,19 +157,16 @@ void zmSetDieHandler(SigHandler * handler) sigaction(SIGFPE, &action, &old_action); } -void zmSetDefaultHupHandler() -{ +void zmSetDefaultHupHandler() { zmSetHupHandler((SigHandler *) zm_hup_handler); } -void zmSetDefaultTermHandler() -{ +void zmSetDefaultTermHandler() { zmSetTermHandler((SigHandler *) zm_term_handler); } -void zmSetDefaultDieHandler() -{ - if (config.dump_cores) { +void zmSetDefaultDieHandler() { + if ( config.dump_cores ) { // Do nothing } else { zmSetDieHandler((SigHandler *) zm_die_handler); From f7d23ce23bc4523d1a7d3658e124243e42379729 Mon Sep 17 00:00:00 2001 From: jahegu Date: Fri, 30 Oct 2020 17:57:28 +0100 Subject: [PATCH 38/38] Update zm_update-1.35.11.sql Missing " ' " simbol that generates a MariaDB problem: ERROR 1064 (42000) at line 14: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''Adding foreign key for EventId to Frames' at line 1 --- db/zm_update-1.35.11.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/zm_update-1.35.11.sql b/db/zm_update-1.35.11.sql index 3906d8c04..ad73b7bf4 100644 --- a/db/zm_update-1.35.11.sql +++ b/db/zm_update-1.35.11.sql @@ -10,7 +10,7 @@ set @exist := (select count(*) FROM information_schema.key_column_usage where ta set @sqlstmt := if( @exist > 1, "SELECT 'You have more than 1 FOREIGN KEY. Please do manual cleanup'", "SELECT 'Ok'"); set @sqlstmt := if( @exist = 1, "SELECT 'FOREIGN KEY EventId in Frames already exists'", @sqlstmt); -set @sqlstmt := if( @exist = 0, "SELECT 'Adding foreign key for EventId to Frames", @sqlstmt); +set @sqlstmt := if( @exist = 0, "SELECT 'Adding foreign key for EventId to Frames'", @sqlstmt); PREPARE stmt FROM @sqlstmt; EXECUTE stmt;