Merge ~ahasenack/ubuntu/+source/zoneminder:focal-zoneminder-mysql8 into ~ahasenack/ubuntu/+source/zoneminder:master

Proposed by Andreas Hasenack
Status: Merged
Approved by: Andreas Hasenack
Approved revision: 6dfc7d363f874e9417bd563ed95c96031ae9568b
Merged at revision: ebdcb0ab8587f01cf4c6b448bf0d5773e2be7dcf
Proposed branch: ~ahasenack/ubuntu/+source/zoneminder:focal-zoneminder-mysql8
Merge into: ~ahasenack/ubuntu/+source/zoneminder:master
Diff against target: 569 lines (+484/-4)
9 files modified
debian/README.Debian (+9/-2)
debian/changelog (+14/-0)
debian/control (+2/-1)
debian/patches/mysql8-password-deprecated.patch (+26/-0)
debian/patches/mysql8-replace-password-call.patch (+58/-0)
debian/patches/mysql8-reserved-keywords.patch (+326/-0)
debian/patches/mysql8_my_bool.patch (+43/-0)
debian/patches/series (+4/-0)
debian/rules (+2/-1)
Reviewer Review Type Date Requested Status
Christian Ehrhardt  (community) Approve
Canonical Server Pending
Review via email: mp+379771@code.launchpad.net

Description of the change

PPA: https://launchpad.net/~ahasenack/+archive/ubuntu/zoneminder-mysql8/

zoneminder isn't in git-ubuntu, and currently fails to import (see bug #1864255).

This fixes several things:
- ftbfs due to mysql8
- another unrelated ftbfs
- runtime issue with mysql8

Newer upstream version claims to work with mysql8, but debian hasn't grabbed it yet. One of the upstream fixes isn't really a good candidate for a patch here, as it's a kind of a refactoring (getting rid of mysql's password()).

I decided to update d/README.Debian a bit because the instructions there didn't work out of the box, and I wanted to try out the package to avoid another bug like #1859295). At least now it comes up and one can see its web interface at http://<ip>/zm. I also updated the php links, expecting 7.4 for focal.

The auth issue workaround I gathered from https://forums.zoneminder.com/viewtopic.php?t=28742

I could add a simple dep8 test without too much extra effort, and that would be one that simply loaded the sql dump into mysql: cat /usr/share/zoneminder/db/zm_create.sql | sudo mysql

It would have caught one issue (using password() in that sql file), but not the rest. Let me know if you think it's worth it. I didn't do it now because it's late :)

All those other steps from the README.Debian file are also doable as a dep8 test, up to the license displayed at first in http://<ip>/zm. We can still do it after feature freeze.

To post a comment you must log in.
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

I don't think we need to add the test for it, would it be nice: yes; is it really necessary: no.
At least not needed right now.

The mysql8 patches are a bit messy, but I agree that it does the job in as-minimal-as-possible fashion. And when moving to the next version it can be dropped.

Changelog:
- [√] changelog entry correct version and targeted codename
- [√] changelog entries correct
- [√] update-maintainer has been run

Actual changes:
- [√] no further upstream version that we want right now

New Delta:
- [√] new patches are good and while not matching the final way they are from upstream and do the job for now.
- [√] new patches correctly included in debian/patches/series
- [√] new patches have correct DEP3 metadata linking to discussions and such

Build/Test:
- [√] build is ok
- [√] sanity checks test fine

I tested it with mythzoneminder and the basics there worked - if we could long term add an autopkgtest that would be good (as discussed above).

I ran this with a mix of php 7.4 and zoneminder to represent how focal will soon look like:
... mysql-server-8.0 mysql-server-core-8.0 ocl-icd-libopencl1 php-apcu php-apcu-bc php-gd php-mysql php7.3-cli php7.3-common php7.3-json php7.3-opcache
  php7.3-phpdbg php7.3-readline php7.4-gd php7.4-mysql zoneminder zoneminder-doc ...
All the perl installs also looked a lot.
But so far things worked.

One thing you might want to look at before an upload is this (up to you):
Setting up zoneminder (1.32.3-2ubuntu1~ppa2) ...
I: Generating /etc/zm/core.php from /usr/share/zoneminder/www/api/app/Config/core.php.default ...
zoneminder.conf:1: Line references path below legacy directory /var/run/, updating /var/run/zm → /run/zm; please update the tmpfiles.d/ drop-in file accordingly.

It feels a bit less stable than usual, but ok still: +1 for this

review: Approve
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Thanks, I filed https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1864645 for the dep8 test.

I'll take a look at the tmpfile bit

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Hmm, RUNDIR is set all over the place at /var/run, even in d/rules, just changing it in the systemd tmpfile would be incomplete, and I'm not ready to test such a larger change at this moment. I'll drop that bit for now, and file a bug to do it properly.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Uploading (no tagging, since this isn't in g-u) ebdcb0ab8587f01cf4c6b448bf0d5773e2be7dcf

$ dput ubuntu ../zoneminder_1.32.3-2ubuntu1_source.changes
Checking signature on .changes
gpg: ../zoneminder_1.32.3-2ubuntu1_source.changes: Valid signature from AC983EB5BF6BCBA9
Checking signature on .dsc
gpg: ../zoneminder_1.32.3-2ubuntu1.dsc: Valid signature from AC983EB5BF6BCBA9
Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading zoneminder_1.32.3-2ubuntu1.dsc: done.
  Uploading zoneminder_1.32.3-2ubuntu1.debian.tar.xz: done.
  Uploading zoneminder_1.32.3-2ubuntu1_source.buildinfo: done.
  Uploading zoneminder_1.32.3-2ubuntu1_source.changes: done.
Successfully uploaded packages.

Revision history for this message
Joseph Yasi (joe-yasi) :
Revision history for this message
Andreas Hasenack (ahasenack) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/README.Debian b/debian/README.Debian
2index 712526a..1ee8bb5 100644
3--- a/debian/README.Debian
4+++ b/debian/README.Debian
5@@ -11,6 +11,13 @@ OR
6 echo 'grant lock tables,alter,create,select,insert,update,delete,index on zm.* to 'zmuser'@localhost identified by "zmpass";'\
7 | sudo mysql --defaults-file=/etc/mysql/debian.cnf mysql
8
9+With MySQL8:
10+
11+ echo "CREATE USER 'zmuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'zmpass';"\
12+ | sudo mysql --defaults-file=/etc/mysql/debian.cnf mysql
13+ echo 'grant lock tables,alter,create,select,insert,update,delete,index on zm.* to 'zmuser'@localhost;'\
14+ | sudo mysql --defaults-file=/etc/mysql/debian.cnf mysql
15+
16 Hint: generate secure password with `pwgen` and update "/etc/zm/zm.conf"
17 accordingly.
18
19@@ -128,8 +135,8 @@ System time zone can be set by the following command:
20 PHP time zone can be configured by changing value of "date.timezone" in one
21 of the following files:
22
23- /etc/php/7.2/fpm/php.ini
24- /etc/php/7.2/apache2/php.ini
25+ /etc/php/7.4/fpm/php.ini
26+ /etc/php/7.4/apache2/php.ini
27
28 Please note that MariaDB/MySQL time zone should be identical to system and
29 PHP time zones. By default MariaDB uses system time zone but it might be
30diff --git a/debian/changelog b/debian/changelog
31index 68b6007..3d575f6 100644
32--- a/debian/changelog
33+++ b/debian/changelog
34@@ -1,3 +1,17 @@
35+zoneminder (1.32.3-2ubuntu1) focal; urgency=medium
36+
37+ * d/p/mysql8_my_bool.patch: Reintroduce my_bool to fix build with MySQL 8.
38+ (LP: #1863026)
39+ * d/rules: override build-dep to fix FTBFS (thanks to
40+ robie.basak@canonical.com) (LP: #1863793, Closes: #951600)
41+ * MySQL8 runtime fixes (LP: #1859295):
42+ - d/p/mysql8-password-deprecated.patch: password() is deprecated
43+ - d/p/mysql8-reserved-keywords.patch: quote MySQL8 reserved keywords
44+ - d/p/mysql8-replace-password-call.patch: replace password()
45+ * d/README.Debian: quick update for MySQL8 and Focal
46+
47+ -- Andreas Hasenack <andreas@canonical.com> Tue, 25 Feb 2020 10:22:20 -0300
48+
49 zoneminder (1.32.3-2build1) eoan; urgency=medium
50
51 * No change rebuild for libmysqlclient21.
52diff --git a/debian/control b/debian/control
53index d435117..c561ce0 100644
54--- a/debian/control
55+++ b/debian/control
56@@ -2,7 +2,8 @@ Source: zoneminder
57 Section: net
58 Priority: optional
59 Standards-Version: 4.3.0
60-Maintainer: Dmitry Smirnov <onlyjob@debian.org>
61+Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
62+XSBC-Original-Maintainer: Dmitry Smirnov <onlyjob@debian.org>
63 Uploaders: Chris Lamb <lamby@debian.org>
64 Build-Depends: debhelper (>= 11~) ,dh-linktree
65 ,apache2-dev
66diff --git a/debian/patches/mysql8-password-deprecated.patch b/debian/patches/mysql8-password-deprecated.patch
67new file mode 100644
68index 0000000..f16dc63
69--- /dev/null
70+++ b/debian/patches/mysql8-password-deprecated.patch
71@@ -0,0 +1,26 @@
72+From 5b896b5e5ca57fe9780e852d570a31c7a5b2ecfb Mon Sep 17 00:00:00 2001
73+From: Isaac Connor <isaac@zoneminder.com>
74+Date: Mon, 8 Jul 2019 14:16:57 -0400
75+Subject: [PATCH] Replace password('admin') with the resulting string because
76+ use of password is deprecated
77+
78+---
79+ db/zm_create.sql.in | 2 +-
80+ 1 file changed, 1 insertion(+), 1 deletion(-)
81+
82+Origin: https://github.com/ZoneMinder/zoneminder/commit/5b896b5e5ca57fe9780e852d570a31c7a5b2ecfb
83+Bug: https://github.com/ZoneMinder/zoneminder/issues/2658
84+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1859295
85+Last-Updated: 2020-02-21
86+
87+--- a/db/zm_create.sql.in
88++++ b/db/zm_create.sql.in
89+@@ -738,7 +738,7 @@
90+ --
91+ -- Create a default admin user.
92+ --
93+-insert into Users VALUES (NULL,'admin',password('admin'),'',1,'View','Edit','Edit','Edit','Edit','Edit','Edit','','');
94++insert into Users VALUES (NULL,'admin','$2b$12$NHZsm6AM2f2LQVROriz79ul3D6DnmFiZC.ZK5eqbF.ZWfwH9bqUJ6','',1,'View','Edit','Edit','Edit','Edit','Edit','Edit','','');
95+
96+ --
97+ -- Add a sample filter to purge the oldest 100 events when the disk is 95% full
98diff --git a/debian/patches/mysql8-replace-password-call.patch b/debian/patches/mysql8-replace-password-call.patch
99new file mode 100644
100index 0000000..574bf24
101--- /dev/null
102+++ b/debian/patches/mysql8-replace-password-call.patch
103@@ -0,0 +1,58 @@
104+Description: replace password()
105+ password() is deprecated in MySQL8, replace it with an equivalent implementation:
106+ .
107+ mysql> select password('secret'),CONCAT('*',UPPER(SHA1(UNHEX(SHA1('secret')))));
108+ +-------------------------------------------+------------------------------------------------+
109+ | password('secret') | CONCAT('*',UPPER(SHA1(UNHEX(SHA1('secret'))))) |
110+ +-------------------------------------------+------------------------------------------------+
111+ | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 | *14E65567ABDB5135D0CFD9A70B3032C179A49EE7 |
112+ +-------------------------------------------+------------------------------------------------+
113+Author: Joseph Yasi <joe.yasi@gmail.com>
114+Origin: other, https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1859295/comments/1
115+Bug: https://github.com/ZoneMinder/zoneminder/issues/2659
116+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1859295
117+Last-Update: 2020-02-24
118+---
119+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
120+--- a/src/zm_user.cpp
121++++ b/src/zm_user.cpp
122+@@ -99,7 +99,7 @@
123+ int password_length = strlen(password);
124+ char *safer_password = new char[(password_length * 2) + 1];
125+ mysql_real_escape_string(&dbconn, safer_password, password, password_length);
126+- snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds from Users where Username = '%s' and Password = password('%s') and Enabled = 1", safer_username, safer_password );
127++ snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds from Users where Username = '%s' and Password = CONCAT('*',UPPER(SHA1(UNHEX(SHA1('%s'))))) and Enabled = 1", safer_username, safer_password );
128+ delete safer_password;
129+ } else {
130+ snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username );
131+--- a/web/includes/actions.php
132++++ b/web/includes/actions.php
133+@@ -960,7 +960,7 @@
134+ $changes = getFormChanges($dbUser, $_REQUEST['newUser'], $types);
135+
136+ if ( $_REQUEST['newUser']['Password'] )
137+- $changes['Password'] = 'Password = password('.dbEscape($_REQUEST['newUser']['Password']).')';
138++ $changes['Password'] = 'Password = CONCAT(\'*\',UPPER(SHA1(UNHEX(SHA1('.dbEscape($_REQUEST['newUser']['Password']).')))))';
139+ else
140+ unset($changes['Password']);
141+
142+@@ -1015,7 +1015,7 @@
143+ $changes = getFormChanges($dbUser, $_REQUEST['newUser'], $types);
144+
145+ if ( !empty($_REQUEST['newUser']['Password']) )
146+- $changes['Password'] = 'Password = password('.dbEscape($_REQUEST['newUser']['Password']).')';
147++ $changes['Password'] = 'Password = CONCAT(\'*\',UPPER(SHA1(UNHEX(SHA1('.dbEscape($_REQUEST['newUser']['Password']).')))))';
148+ else
149+ unset($changes['Password']);
150+ if ( count($changes) ) {
151+--- a/web/includes/auth.php
152++++ b/web/includes/auth.php
153+@@ -27,7 +27,7 @@
154+ if ( $passwordHashed ) {
155+ $sql .= ' AND Username=? AND Password=?';
156+ } else {
157+- $sql .= ' AND Username=? AND Password=password(?)';
158++ $sql .= ' AND Username=? AND Password=CONCAT(\'*\',UPPER(SHA1(UNHEX(SHA1(?)))))';
159+ }
160+ $sql_values = array($username, $password);
161+ } else {
162diff --git a/debian/patches/mysql8-reserved-keywords.patch b/debian/patches/mysql8-reserved-keywords.patch
163new file mode 100644
164index 0000000..bc067d1
165--- /dev/null
166+++ b/debian/patches/mysql8-reserved-keywords.patch
167@@ -0,0 +1,326 @@
168+Description: Quote MySQL8 reserved keywords
169+Author: Joseph Yasi <joe.yasi@gmail.com>
170+Origin: other, https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1859295/comments/1
171+Bug: https://github.com/ZoneMinder/zoneminder/issues/2659
172+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/zoneminder/+bug/1859295
173+Last-Update: 2020-02-21
174+---
175+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
176+--- a/scripts/zmtelemetry.pl.in
177++++ b/scripts/zmtelemetry.pl.in
178+@@ -243,7 +243,7 @@
179+ sub getMonitorRef {
180+ my $dbh = shift;
181+
182+- my $sql = 'SELECT Id,Name,Type,Function,Width,Height,Colours,MaxFPS,AlarmMaxFPS FROM Monitors';
183++ my $sql = 'SELECT Id,Name,Type,`Function`,Width,Height,Colours,MaxFPS,AlarmMaxFPS FROM Monitors';
184+ my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
185+ my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
186+ my $arrayref = $sth->fetchall_arrayref({});
187+--- a/scripts/zmtrigger.pl.in
188++++ b/scripts/zmtrigger.pl.in
189+@@ -333,7 +333,7 @@
190+ my %new_monitors = ();
191+
192+ my $sql = "SELECT * FROM Monitors
193+- WHERE find_in_set( Function, 'Modect,Mocord,Nodect' )".
194++ WHERE find_in_set( `Function`, 'Modect,Mocord,Nodect' )".
195+ ( $Config{ZM_SERVER_ID} ? 'AND ServerId=?' : '' )
196+ ;
197+ my $sth = $dbh->prepare_cached( $sql )
198+--- a/scripts/zmx10.pl.in
199++++ b/scripts/zmx10.pl.in
200+@@ -464,7 +464,7 @@
201+
202+ my $sql = "SELECT M.*,T.* from Monitors as M
203+ INNER JOIN TriggersX10 as T on (M.Id = T.MonitorId)
204+- WHERE find_in_set( M.Function, 'Modect,Record,Mocord,Nodect' )
205++ WHERE find_in_set( M.`Function`, 'Modect,Record,Mocord,Nodect' )
206+ AND M.Enabled = 1
207+ AND find_IN_set( 'X10', M.Triggers )"
208+ ;
209+--- a/scripts/ZoneMinder/lib/ZoneMinder/Database.pm
210++++ b/scripts/ZoneMinder/lib/ZoneMinder/Database.pm
211+@@ -145,15 +145,15 @@
212+
213+ if ( $function ) {
214+ if ( $function == DB_MON_CAPT ) {
215+- $sql .= " where Function >= 'Monitor'";
216++ $sql .= " where `Function` >= 'Monitor'";
217+ } elsif ( $function == DB_MON_ACTIVE ) {
218+- $sql .= " where Function > 'Monitor'";
219++ $sql .= " where `Function` > 'Monitor'";
220+ } elsif ( $function == DB_MON_MOTION ) {
221+- $sql .= " where Function = 'Modect' or Function = 'Mocord'";
222++ $sql .= " where `Function` = 'Modect' or `Function` = 'Mocord'";
223+ } elsif ( $function == DB_MON_RECORD ) {
224+- $sql .= " where Function = 'Record' or Function = 'Mocord'";
225++ $sql .= " where `Function` = 'Record' or `Function` = 'Mocord'";
226+ } elsif ( $function == DB_MON_PASSIVE ) {
227+- $sql .= " where Function = 'Nodect'";
228++ $sql .= " where `Function` = 'Nodect'";
229+ }
230+ }
231+ my $sth = $dbh->prepare_cached( $sql );
232+--- a/src/zm_monitor.cpp
233++++ b/src/zm_monitor.cpp
234+@@ -67,7 +67,7 @@
235+ // This is the official SQL (and ordering of the fields) to load a Monitor.
236+ // It will be used whereever a Monitor dbrow is needed. WHERE conditions can be appended
237+ std::string load_monitor_sql =
238+-"SELECT Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, "
239++"SELECT Id, Name, ServerId, StorageId, Type, `Function`+0, Enabled, LinkedMonitors, "
240+ "AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS,"
241+ "Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings
242+ "Protocol, Method, Options, User, Pass, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, "
243+@@ -1770,7 +1770,7 @@
244+
245+ static char sql[ZM_SQL_MED_BUFSIZ];
246+ // This seems to have fallen out of date.
247+- snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id );
248++ snprintf( sql, sizeof(sql), "select `Function`+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id );
249+
250+ zmDbRow *row = zmDbFetchOne(sql);
251+ if ( !row ) {
252+@@ -1904,7 +1904,7 @@
253+
254+ db_mutex.lock();
255+ static char sql[ZM_SQL_SML_BUFSIZ];
256+- snprintf(sql, sizeof(sql), "select Id, Name from Monitors where Id = %d and Function != 'None' and Function != 'Monitor' and Enabled = 1", link_ids[i] );
257++ snprintf(sql, sizeof(sql), "select Id, Name from Monitors where Id = %d and `Function` != 'None' and `Function` != 'Monitor' and Enabled = 1", link_ids[i] );
258+ if ( mysql_query(&dbconn, sql) ) {
259+ Error("Can't run query: %s", mysql_error(&dbconn));
260+ db_mutex.unlock();
261+@@ -1961,7 +1961,7 @@
262+ #if ZM_HAS_V4L
263+ int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ) {
264+
265+- std::string sql = load_monitor_sql + " WHERE Function != 'None' AND Type = 'Local'";
266++ std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND Type = 'Local'";
267+
268+ if ( device[0] )
269+ sql += " AND Device='" + std::string(device) + "'";
270+@@ -1972,7 +1972,7 @@
271+ #endif // ZM_HAS_V4L
272+
273+ int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose ) {
274+- std::string sql = load_monitor_sql + " WHERE Function != 'None' AND Type = 'Remote'";
275++ std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND Type = 'Remote'";
276+ if ( staticConfig.SERVER_ID )
277+ sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID );
278+
279+@@ -1982,7 +1982,7 @@
280+ }
281+
282+ int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ) {
283+- std::string sql = load_monitor_sql + " WHERE Function != 'None' AND Type = 'File'";
284++ std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND Type = 'File'";
285+ if ( file[0] )
286+ sql += " AND Path='" + std::string(file) + "'";
287+ if ( staticConfig.SERVER_ID ) {
288+@@ -1993,7 +1993,7 @@
289+
290+ #if HAVE_LIBAVFORMAT
291+ int Monitor::LoadFfmpegMonitors(const char *file, Monitor **&monitors, Purpose purpose) {
292+- std::string sql = load_monitor_sql + " WHERE Function != 'None' AND Type = 'Ffmpeg'";
293++ std::string sql = load_monitor_sql + " WHERE `Function` != 'None' AND Type = 'Ffmpeg'";
294+ if ( file[0] )
295+ sql += " AND Path = '" + std::string(file) + "'";
296+
297+@@ -2006,7 +2006,7 @@
298+
299+ /*
300+ std::string load_monitor_sql =
301+- "SELECT Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, "
302++ "SELECT Id, Name, ServerId, StorageId, Type, `Function`+0, Enabled, LinkedMonitors, "
303+ "AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS,"
304+ "Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings
305+ "Protocol, Method, Options, User, Pass, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, "
306+@@ -2811,7 +2811,7 @@
307+ // At the moment, only load groups once.
308+ if ( ! groups.size() ) {
309+ std::string sql = stringtf(
310+- "SELECT Id,ParentId,Name FROM Groups WHERE Groups.Id IN "
311++ "SELECT Id,ParentId,Name FROM `Groups` WHERE `Groups`.Id IN "
312+ "(SELECT GroupId FROM Groups_Monitors WHERE MonitorId=%d)",id);
313+ MYSQL_RES *result = zmDbFetch(sql.c_str());
314+ if ( !result ) {
315+--- a/src/zm_rtsp.cpp
316++++ b/src/zm_rtsp.cpp
317+@@ -93,7 +93,7 @@
318+ int RtspThread::requestPorts() {
319+ if ( !smMinDataPort ) {
320+ char sql[ZM_SQL_SML_BUFSIZ];
321+- strncpy( sql, "select Id from Monitors where Function != 'None' and Type = 'Remote' and Protocol = 'rtsp' and Method = 'rtpUni' order by Id asc", sizeof(sql) );
322++ strncpy( sql, "select Id from Monitors where `Function` != 'None' and Type = 'Remote' and Protocol = 'rtsp' and Method = 'rtpUni' order by Id asc", sizeof(sql) );
323+ if ( mysql_query( &dbconn, sql ) ) {
324+ Error( "Can't run query: %s", mysql_error( &dbconn ) );
325+ exit( mysql_errno( &dbconn ) );
326+--- a/src/zmu.cpp
327++++ b/src/zmu.cpp
328+@@ -691,9 +691,9 @@
329+ }
330+
331+ if ( function & ZMU_LIST ) {
332+- std::string sql = "select Id, Function+0 from Monitors";
333++ std::string sql = "select Id, `Function`+0 from Monitors";
334+ if ( !verbose ) {
335+- sql += "where Function != 'None'";
336++ sql += "where `Function` != 'None'";
337+ }
338+ sql += " order by Id asc";
339+
340+--- a/src/zm_user.cpp
341++++ b/src/zm_user.cpp
342+@@ -99,10 +99,10 @@
343+ int password_length = strlen(password);
344+ char *safer_password = new char[(password_length * 2) + 1];
345+ mysql_real_escape_string(&dbconn, safer_password, password, password_length);
346+- snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Password = password('%s') and Enabled = 1", safer_username, safer_password );
347++ snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds from Users where Username = '%s' and Password = password('%s') and Enabled = 1", safer_username, safer_password );
348+ delete safer_password;
349+ } else {
350+- snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username );
351++ snprintf( sql, sizeof(sql), "select Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username );
352+ }
353+
354+ if ( mysql_query( &dbconn, sql ) ) {
355+@@ -157,7 +157,7 @@
356+
357+ Debug( 1, "Attempting to authenticate user from auth string '%s'", auth );
358+ char sql[ZM_SQL_SML_BUFSIZ] = "";
359+- snprintf( sql, sizeof(sql), "SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds FROM Users WHERE Enabled = 1" );
360++ snprintf( sql, sizeof(sql), "SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, `System`+0, MonitorIds FROM Users WHERE Enabled = 1" );
361+
362+ if ( mysql_query( &dbconn, sql ) ) {
363+ Error( "Can't run query: %s", mysql_error( &dbconn ) );
364+--- a/utils/zm-alarm.pl
365++++ b/utils/zm-alarm.pl
366+@@ -16,7 +16,7 @@
367+ my $dbh = zmDbConnect();
368+
369+ my $sql = "SELECT * FROM Monitors
370+- WHERE find_in_set( Function, 'Modect,Mocord,Nodect' )".
371++ WHERE find_in_set( `Function`, 'Modect,Mocord,Nodect' )".
372+ ( $Config{ZM_SERVER_ID} ? 'AND ServerId=?' : '' )
373+ ;
374+
375+--- a/web/ajax/status.php
376++++ b/web/ajax/status.php
377+@@ -16,7 +16,7 @@
378+ 'limit' => 1,
379+ 'elements' => array(
380+ 'MonitorCount' => array( 'sql' => 'count(*)' ),
381+- 'ActiveMonitorCount' => array( 'sql' => "count(if(Function != 'None',1,NULL))" ),
382++ 'ActiveMonitorCount' => array( 'sql' => "count(if(`Function` != 'None',1,NULL))" ),
383+ 'State' => array( 'func' => 'daemonCheck()?'.translate('Running').':'.translate('Stopped') ),
384+ 'Load' => array( 'func' => 'getLoad()' ),
385+ 'Disk' => array( 'func' => 'getDiskPercent()' ),
386+--- a/web/includes/database.php
387++++ b/web/includes/database.php
388+@@ -227,7 +227,7 @@
389+ }
390+
391+ function getEnumValues( $table, $column ) {
392+- $row = dbFetchOne( "describe $table $column" );
393++ $row = dbFetchOne( "describe `$table` `$column`" );
394+ preg_match_all( "/'([^']+)'/", $row['Type'], $matches );
395+ return( $matches[1] );
396+ }
397+@@ -238,7 +238,7 @@
398+
399+ function getUniqueValues( $table, $column, $asString=1 ) {
400+ $values = array();
401+- $sql = "select distinct $column from $table where (not isnull($column) and $column != '') order by $column";
402++ $sql = "select distinct `$column` from `$table` where (not isnull(`$column`) and `$column` != '') order by `$column`";
403+ foreach( dbFetchAll( $sql ) as $row ) {
404+ if ( $asString )
405+ $values[$row[$column]] = $row[$column];
406+@@ -250,7 +250,7 @@
407+
408+ function getTableColumns( $table, $asString=1 ) {
409+ $columns = array();
410+- $sql = "describe $table";
411++ $sql = "describe `$table`";
412+ foreach( dbFetchAll( $sql ) as $row ) {
413+ if ( $asString )
414+ $columns[$row['Field']] = $row['Type'];
415+@@ -267,7 +267,7 @@
416+
417+ function getTableDescription( $table, $asString=1 ) {
418+ $columns = array();
419+- foreach( dbFetchAll( "describe $table" ) as $row ) {
420++ foreach( dbFetchAll( "describe `$table`" ) as $row ) {
421+ $desc = array(
422+ 'name' => $row['Field'],
423+ 'required' => ($row['Null']=='NO')?true:false,
424+@@ -377,7 +377,7 @@
425+ }
426+
427+ function dbFetchGroup( $gid ) {
428+- return( dbFetchOne( 'select * from Groups where Id = ?', NULL, array($gid) ) );
429++ return( dbFetchOne( 'select * from `Groups` where Id = ?', NULL, array($gid) ) );
430+ }
431+
432+ ?>
433+--- a/web/includes/Group.php
434++++ b/web/includes/Group.php
435+@@ -16,7 +16,7 @@
436+ $row = NULL;
437+ if ( $IdOrRow ) {
438+ if ( is_integer($IdOrRow) or is_numeric($IdOrRow) ) {
439+- $row = dbFetchOne('SELECT * FROM Groups WHERE Id=?', NULL, array($IdOrRow));
440++ $row = dbFetchOne('SELECT * FROM `Groups` WHERE Id=?', NULL, array($IdOrRow));
441+ if ( ! $row ) {
442+ Error('Unable to load Group record for Id=' . $IdOrRow);
443+ }
444+@@ -59,7 +59,7 @@
445+ }
446+
447+ public static function find( $parameters = null, $options = null ) {
448+- $sql = 'SELECT * FROM Groups ';
449++ $sql = 'SELECT * FROM `Groups` ';
450+ $values = array();
451+
452+ if ( $parameters ) {
453+@@ -125,7 +125,7 @@
454+ public function delete() {
455+ if ( array_key_exists('Id', $this) ) {
456+ dbQuery( 'DELETE FROM Groups_Monitors WHERE GroupId=?', array($this->{'Id'}) );
457+- dbQuery( 'DELETE FROM Groups WHERE Id=?', array($this->{'Id'}) );
458++ dbQuery( 'DELETE FROM `Groups` WHERE Id=?', array($this->{'Id'}) );
459+ if ( isset($_COOKIE['zmGroup']) ) {
460+ if ( $this->{'Id'} == $_COOKIE['zmGroup'] ) {
461+ unset($_COOKIE['zmGroup']);
462+@@ -239,11 +239,11 @@
463+
464+ $MonitorIds = dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId'.$group_id_sql_part, 'MonitorId', $group_id);
465+
466+- $MonitorIds = array_merge($MonitorIds, dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM Groups WHERE ParentId'.$group_id_sql_part.')', 'MonitorId', $group_id));
467++ $MonitorIds = array_merge($MonitorIds, dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM `Groups` WHERE ParentId'.$group_id_sql_part.')', 'MonitorId', $group_id));
468+ } else {
469+ $MonitorIds = dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId=?', 'MonitorId', array($group_id));
470+
471+- $MonitorIds = array_merge($MonitorIds, dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM Groups WHERE ParentId = ?)', 'MonitorId', array($group_id)));
472++ $MonitorIds = array_merge($MonitorIds, dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM `Groups` WHERE ParentId = ?)', 'MonitorId', array($group_id)));
473+ }
474+ $groupSql = " find_in_set( M.Id, '".implode(',', $MonitorIds)."' )";
475+ }
476+--- a/web/skins/classic/views/control.php
477++++ b/web/skins/classic/views/control.php
478+@@ -25,13 +25,13 @@
479+
480+ $groupSql = '';
481+ if ( !empty($_REQUEST['group']) ) {
482+- $row = dbFetchOne( 'SELECT * FROM Groups WHERE Id = ?', NULL, array($_REQUEST['group']) );
483++ $row = dbFetchOne( 'SELECT * FROM `Groups` WHERE Id = ?', NULL, array($_REQUEST['group']) );
484+ $groupSql = " and find_in_set( Id, '".$row['MonitorIds']."' )";
485+ }
486+
487+ $mid = !empty($_REQUEST['mid']) ? validInt($_REQUEST['mid']) : 0;
488+
489+-$sql = "SELECT * FROM Monitors WHERE Function != 'None' AND Controllable = 1$groupSql ORDER BY Sequence";
490++$sql = "SELECT * FROM Monitors WHERE `Function` != 'None' AND Controllable = 1$groupSql ORDER BY Sequence";
491+ $mids = array();
492+ foreach( dbFetchAll( $sql ) as $row ) {
493+ if ( !visibleMonitor( $row['Id'] ) ) {
494diff --git a/debian/patches/mysql8_my_bool.patch b/debian/patches/mysql8_my_bool.patch
495new file mode 100644
496index 0000000..cee2469
497--- /dev/null
498+++ b/debian/patches/mysql8_my_bool.patch
499@@ -0,0 +1,43 @@
500+Description: Reintroduce my_bool to fix build with MySQL 8
501+Author: Andreas Hasenack <andreas@canonical.com>
502+Bug-Ubuntu: https://bugs.launchpad.net/bugs/1863026
503+Forwarded: no
504+Last-Update: 2020-02-12
505+---
506+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
507+diff --git a/src/zm_db.h b/src/zm_db.h
508+index c707ad2..9f3381f 100644
509+--- a/src/zm_db.h
510++++ b/src/zm_db.h
511+@@ -21,6 +21,7 @@
512+ #define ZM_DB_H
513+
514+ #include <mysql/mysql.h>
515++typedef bool my_bool;
516+ #include "zm_thread.h"
517+
518+ class zmDbRow {
519+diff --git a/src/zm_event.h b/src/zm_event.h
520+index 1e55ae5..c3225c0 100644
521+--- a/src/zm_event.h
522++++ b/src/zm_event.h
523+@@ -30,6 +30,7 @@
524+ #include <sys/stat.h>
525+ #include <sys/types.h>
526+ #include <mysql/mysql.h>
527++typedef bool my_bool;
528+
529+ #include <set>
530+ #include <map>
531+diff --git a/src/zm_logger.h b/src/zm_logger.h
532+index 8e2ab6c..c842a28 100644
533+--- a/src/zm_logger.h
534++++ b/src/zm_logger.h
535+@@ -29,6 +29,7 @@
536+ #include <sys/syscall.h>
537+ #endif // HAVE_SYS_SYSCALL_H
538+ #include <mysql/mysql.h>
539++typedef bool my_bool;
540+
541+ class Logger {
542+ public:
543diff --git a/debian/patches/series b/debian/patches/series
544index f16125a..c295979 100644
545--- a/debian/patches/series
546+++ b/debian/patches/series
547@@ -25,3 +25,7 @@
548 0009-Allow-generation-of-random-seeds-on-install-time-not.patch
549 0010-Use-mootools-shipped-by-debian-rather-than-the-zonem.patch
550 include_path.patch
551+mysql8_my_bool.patch
552+mysql8-password-deprecated.patch
553+mysql8-reserved-keywords.patch
554+mysql8-replace-password-call.patch
555diff --git a/debian/rules b/debian/rules
556index 98131b0..90031c5 100755
557--- a/debian/rules
558+++ b/debian/rules
559@@ -34,8 +34,9 @@ override_dh_clean:
560 dh_clean $(MANPAGES1)
561 $(RM) -r docs/_build docs/installationguide web/api/app/Plugin/Crud
562
563-build-indep:
564+override_dh_auto_build-indep:
565 $(MAKE) -C docs html
566+ dh_auto_build
567
568 MANPAGES1 = \
569 dbuild/scripts/zmupdate.pl.1 \

Subscribers

People subscribed via source and target branches

to all changes: