diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 610480e8e..7751de627 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,5 @@ + **Describe Your Environment** + **If the issue concerns a camera** + **Describe the bug** + **To Reproduce** + **Expected behavior** + **Debug Logs** ``` + ``` diff --git a/.gitignore b/.gitignore index 3167e62a6..152802d29 100644 --- a/.gitignore +++ b/.gitignore @@ -120,7 +120,7 @@ src/CMakeFiles/ src/cmake_install.cmake src/libzm.a src/nph-zms -src/zm_config.h +src/zm_config_data.h src/zm_config_defines.h src/zma src/zmc diff --git a/.travis.yml b/.travis.yml index 748b98f77..bc7b810de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,12 +37,9 @@ env: - SMPFLAGS=-j4 OS=el DIST=8 DOCKER_REPO=knnniggett/packpack - SMPFLAGS=-j4 OS=fedora DIST=31 DOCKER_REPO=knnniggett/packpack - SMPFLAGS=-j4 OS=fedora DIST=32 DOCKER_REPO=knnniggett/packpack - - SMPFLAGS=-j4 OS=ubuntu DIST=trusty DOCKER_REPO=iconzm/packpack - SMPFLAGS=-j4 OS=ubuntu DIST=xenial DOCKER_REPO=iconzm/packpack - SMPFLAGS=-j4 OS=ubuntu DIST=bionic DOCKER_REPO=iconzm/packpack - - SMPFLAGS=-j4 OS=ubuntu DIST=disco DOCKER_REPO=iconzm/packpack - SMPFLAGS=-j4 OS=ubuntu DIST=focal DOCKER_REPO=iconzm/packpack - - SMPFLAGS=-j4 OS=debian DIST=jessie DOCKER_REPO=iconzm/packpack - SMPFLAGS=-j4 OS=debian DIST=stretch DOCKER_REPO=iconzm/packpack - SMPFLAGS=-j4 OS=debian DIST=buster DOCKER_REPO=iconzm/packpack diff --git a/db/zm_update-1.35.6.sql b/db/zm_update-1.35.6.sql index eb0e59ddb..3512534be 100644 --- a/db/zm_update-1.35.6.sql +++ b/db/zm_update-1.35.6.sql @@ -1,2 +1,2 @@ -/* This was done in 1.31.0 but zm_create.sql.in wasn't updated to match */ +/* This was done in 1.31.0 but zm_create.sql.in wasn't updated to match. */ ALTER TABLE Monitors MODIFY LinkedMonitors varchar(255); diff --git a/distros/redhat/CMakeLists.txt b/distros/redhat/CMakeLists.txt index f1a1bc75b..45cafe57d 100644 --- a/distros/redhat/CMakeLists.txt +++ b/distros/redhat/CMakeLists.txt @@ -21,7 +21,7 @@ endif(ZM_TARGET_DISTRO MATCHES "^el") # Configure the common zoneminder files configure_file(common/zoneminder.logrotate.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.logrotate @ONLY) configure_file(common/zoneminder.service.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.service @ONLY) -file(MAKE_DIRECTORY sock swap zoneminder zoneminder-upload events temp) +file(MAKE_DIRECTORY sock swap zoneminder events temp) # Configure the Apache zoneminder files configure_file(httpd/zm-httpd.conf.in ${CMAKE_CURRENT_SOURCE_DIR}/zm-httpd.conf @ONLY) @@ -51,7 +51,6 @@ install(DIRECTORY sock swap DESTINATION /var/lib/zoneminder DIRECTORY_PERMISSION install(DIRECTORY zoneminder DESTINATION /var/log DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(DIRECTORY zoneminder DESTINATION /var/run DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(DIRECTORY zoneminder DESTINATION /var/cache DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) -install(DIRECTORY zoneminder-upload DESTINATION /var/spool DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(DIRECTORY events temp DESTINATION /var/lib/zoneminder DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # Install the Apache zoneminder files diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index 054f4b69f..9e876324e 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -28,7 +28,7 @@ %global _hardened_build 1 Name: zoneminder -Version: 1.35.5 +Version: 1.35.6 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons @@ -204,7 +204,6 @@ mv -f CakePHP-Enum-Behavior-%{ceb_version} ./web/api/app/Plugin/CakePHP-Enum-Beh # Change the following default values ./utils/zmeditconfigdata.sh ZM_OPT_CAMBOZOLA yes -./utils/zmeditconfigdata.sh ZM_UPLOAD_FTP_LOC_DIR %{_localstatedir}/spool/zoneminder-upload ./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes ./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no ./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no @@ -399,7 +398,6 @@ EOF %dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_sharedstatedir}/zoneminder/temp %dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/cache/zoneminder %dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/log/zoneminder -%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/spool/zoneminder-upload %files nginx %config(noreplace) %attr(640,root,nginx) %{_sysconfdir}/zm/zm.conf @@ -423,7 +421,6 @@ EOF %dir %attr(755,nginx,nginx) %{_sharedstatedir}/zoneminder/temp %dir %attr(755,nginx,nginx) %{_localstatedir}/cache/zoneminder %dir %attr(755,nginx,nginx) %{_localstatedir}/log/zoneminder -%dir %attr(755,nginx,nginx) %{_localstatedir}/spool/zoneminder-upload %changelog * Tue Feb 04 2020 Andrew Bauer - 1.34.2-1 diff --git a/distros/ubuntu1604/changelog b/distros/ubuntu1604/changelog index 616f75178..0fc2fda2e 100644 --- a/distros/ubuntu1604/changelog +++ b/distros/ubuntu1604/changelog @@ -1,3 +1,3 @@ -zoneminder (1.31.39~20180223.27-stretch-1) unstable; urgency=low - * - -- Isaac Connor Fri, 23 Feb 2018 14:15:59 -0500 +zoneminder (1.35.6~20200825.27-xenial) xenial; urgency=low + * + -- Isaac Connor Tue, 25 Aug 2020 09:28:18 -0400 diff --git a/distros/ubuntu2004/control b/distros/ubuntu2004/control index 3647dfab5..0a1f9e0de 100644 --- a/distros/ubuntu2004/control +++ b/distros/ubuntu2004/control @@ -3,7 +3,7 @@ Section: net Priority: optional Maintainer: Isaac Connor Uploaders: Isaac Connor -Build-Depends: debhelper, dh-systemd, sphinx-doc, dh-linktree, dh-systemd, dh-apache2 +Build-Depends: debhelper, dh-systemd, sphinx-doc, python3-sphinx, dh-linktree, dh-systemd, dh-apache2 ,cmake ,libx264-dev, libmp4v2-dev ,libavdevice-dev diff --git a/docs/installationguide/debian.rst b/docs/installationguide/debian.rst index 080b95d5b..d09423bd9 100644 --- a/docs/installationguide/debian.rst +++ b/docs/installationguide/debian.rst @@ -43,7 +43,7 @@ trigger their installation manually. :: - sudo apt install apache2 mysql-server + sudo apt install apache2 default-mysql-server **Step 4:** Add ZoneMinder's Package repository to your apt sources @@ -51,25 +51,29 @@ ZoneMinder's Debian packages are not included in Debian's official package repositories. To be able to install ZoneMinder with APT, you have to edit the list of apt sources and add ZoneMinder's repository. -:: - - sudo nano /etc/apt/sources.list - -Add the following to the bottom of the file +Add the following to the /etc/apt/sources.list.d/zoneminder.list file :: # ZoneMinder repository deb https://zmrepo.zoneminder.com/debian/release-1.34 buster/ -CTRL+o and to save -CTRL+x to exit +You can do this using: + +:: + echo "deb https://zmrepo.zoneminder.com/debian/release-1.34 buster/" | sudo tee /etc/apt/sources.list.d/zoneminder.list Because ZoneMinder's package repository provides a secure connection through HTTPS, apt must be enabled for HTTPS. :: sudo apt install apt-transport-https +Ensure you have gnupg installed before importing the apt key in the following step. +:: + + sudo apt install gnupg + + Finally, download the GPG key for ZoneMinder's repository: :: @@ -107,7 +111,7 @@ required apache modules. :: sudo a2enconf zoneminder - sudo a2enmod rewrite + sudo a2enmod rewrite # this is enabled by default sudo a2enmod cgi # this is done automatically when installing the package. Redo this command manually only for troubleshooting. @@ -116,12 +120,12 @@ required apache modules. Automated way: :: - sudo sed -i "s/;date.timezone =/date.timezone = $(sed 's/\//\\\//' /etc/timezone)/g" /etc/php/7.0/apache2/php.ini + sudo sed -i "s/;date.timezone =/date.timezone = $(sed 's/\//\\\//' /etc/timezone)/g" /etc/php/7.*/apache2/php.ini Manual way :: - sudo nano /etc/php/7.0/apache2/php.ini + sudo nano /etc/php/7.*/apache2/php.ini Search for [Date] (Ctrl + w then type Date and press Enter) and change date.timezone for your time zone. Don't forget to remove the ; from in front diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in index 10e4b4733..21f9a2d02 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in @@ -76,39 +76,42 @@ BEGIN { require ZoneMinder::Database; # Process name, value pairs from the main config file first - my $config_file = ZM_CONFIG; - process_configfile($config_file); + process_configfile(ZM_CONFIG); # Search for user created config files. If one or more are found then # update the Config hash with those values if ( ZM_CONFIG_SUBDIR and -d ZM_CONFIG_SUBDIR ) { if ( -R ZM_CONFIG_SUBDIR ) { - foreach my $filename ( glob ZM_CONFIG_SUBDIR.'/*.conf' ) { + foreach my $filename (glob ZM_CONFIG_SUBDIR.'/*.conf' ) { process_configfile($filename); } } else { - print( STDERR 'WARNING: ZoneMinder configuration subfolder found but is not readable. Check folder permissions on '.ZM_CONFIG_SUBDIR.".\n" ); + print(STDERR 'WARNING: ZoneMinder configuration subfolder found but is not readable. Check folder permissions on '.ZM_CONFIG_SUBDIR.".\n"); } } my $dbh = ZoneMinder::Database::zmDbConnect(); + die "Unable to connect to DB. ZM Cannot continue.\n" if !$dbh; + my $sql = 'SELECT Name,Value FROM Config'; my $sth = $dbh->prepare_cached($sql) or croak("Can't prepare '$sql': ".$dbh->errstr()); my $res = $sth->execute() or croak("Can't execute: ".$sth->errstr()); - while( my $config = $sth->fetchrow_hashref() ) { + while ( my $config = $sth->fetchrow_hashref() ) { + # If already defined skip it because we want the values in /etc/zm.conf to override the values in Config Table + next if exists $Config{$config->{Name}}; $Config{$config->{Name}} = $config->{Value}; } $sth->finish(); - if ( ! $Config{ZM_SERVER_ID} ) { + if ( !$Config{ZM_SERVER_ID} ) { $Config{ZM_SERVER_ID} = undef; - $sth = $dbh->prepare_cached( 'SELECT * FROM Servers WHERE Name=?' ); + $sth = $dbh->prepare_cached('SELECT * FROM Servers WHERE Name=?'); if ( $Config{ZM_SERVER_NAME} ) { - $res = $sth->execute( $Config{ZM_SERVER_NAME} ); + $res = $sth->execute($Config{ZM_SERVER_NAME}); my $result = $sth->fetchrow_hashref(); $Config{ZM_SERVER_ID} = $$result{Id}; } elsif ( $Config{ZM_SERVER_HOST} ) { - $res = $sth->execute( $Config{ZM_SERVER_HOST} ); + $res = $sth->execute($Config{ZM_SERVER_HOST}); my $result = $sth->fetchrow_hashref(); $Config{ZM_SERVER_ID} = $$result{Id}; } @@ -126,20 +129,20 @@ require ZoneMinder::Database; open( my $CONFIG, '<', $config_file ) or croak("Can't open config file '$config_file': $!"); foreach my $str ( <$CONFIG> ) { - next if ( $str =~ /^\s*$/ ); + next if ( $str =~ /^\s*$/ ); next if ( $str =~ /^\s*#/ ); my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*[\'"]*(.*?)[\'"]*\s*$/; if ( !$name ) { print(STDERR "Warning, bad line in $config_file: $str\n"); next; } # end if - $name =~ tr/a-z/A-Z/; + $name = uc $name; #if ( !$ZoneMinder::ConfigData::options_hash{$name} ) { - #print(STDERR "Warning, unknown config option name $name in $config_file\n"); -#} else { - #print(STDERR "Warning, known config option name $name in $config_file\n"); - #} - $Config{$name} = $value; + #print(STDERR "Warning, unknown config option name $name in $config_file\n"); + #} else { + #print(STDERR "Warning, known config option name $name in $config_file\n"); + #} + $Config{$name} = $value; } # end foreach config line close($CONFIG); } # end sub process_configfile @@ -147,11 +150,11 @@ require ZoneMinder::Database; } # end BEGIN sub loadConfigFromDB { - print( 'Loading config from DB' ); + print('Loading config from DB'); my $dbh = ZoneMinder::Database::zmDbConnect(); if ( !$dbh ) { - print( "Error: unable to load options from database: $DBI::errstr\n" ); - return( 0 ); + print("Error: unable to load options from database: $DBI::errstr\n"); + return(0); } my $sql = "select * from Config"; my $sth = $dbh->prepare_cached( $sql ) @@ -161,13 +164,13 @@ sub loadConfigFromDB { my $option_count = 0; while( my $config = $sth->fetchrow_hashref() ) { my ( $name, $value ) = ( $config->{Name}, $config->{Value} ); -#print( "Name = '$name'\n" ); + #print( "Name = '$name'\n" ); my $option = $options_hash{$name}; if ( !$option ) { warn( "No option '$name' found, removing.\n" ); next; } -#next if ( $option->{category} eq 'hidden' ); + #next if ( $option->{category} eq 'hidden' ); if ( defined($value) ) { if ( $option->{type} == $types{boolean} ) { $option->{value} = $value?'yes':'no'; @@ -204,8 +207,8 @@ sub saveConfigToDB { my $sth = $dbh->prepare_cached( $sql ) or croak( "Can't prepare '$sql': ".$dbh->errstr() ); foreach my $option ( @options ) { -#next if ( $option->{category} eq 'hidden' ); -#print( $option->{name}."\n" ) if ( !$option->{category} ); + #next if ( $option->{category} eq 'hidden' ); + #print( $option->{name}."\n" ) if ( !$option->{category} ); $option->{db_type} = $option->{type}->{db_type}; $option->{db_hint} = $option->{type}->{hint}; $option->{db_pattern} = $option->{type}->{pattern}; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in index 8310d8e1d..9b91ff4b9 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in @@ -582,26 +582,6 @@ our @options = ( type => $types{integer}, category => 'images', }, -# Deprecated, now stream quality - { - name => 'ZM_JPEG_IMAGE_QUALITY', - default => '70', - description => q`Set the JPEG quality setting for the streamed 'live' images (1-100)`, - help => q` - When viewing a 'live' stream for a monitor ZoneMinder will grab - an image from the buffer and encode it into JPEG format before - sending it. This option specifies what image quality should be - used to encode these images. A higher number means better - quality but less compression so will take longer to view over a - slow connection. By contrast a low number means quicker to view - images but at the price of lower quality images. This option - does not apply when viewing events or still images as these are - usually just read from disk and so will be encoded at the - quality specified by the previous options. - `, - type => $types{integer}, - category => 'hidden', - }, { name => 'ZM_JPEG_STREAM_QUALITY', default => '70', @@ -877,38 +857,6 @@ our @options = ( type => $types{integer}, category => 'config', }, -# Deprecated, really no longer necessary - { - name => 'ZM_OPT_REMOTE_CAMERAS', - default => 'no', - description => 'Are you going to use remote/networked cameras', - help => q` - ZoneMinder can work with both local cameras, ie. those attached - physically to your computer and remote or network cameras. If - you will be using networked cameras select this option. - `, - type => $types{boolean}, - category => 'hidden', - }, -# Deprecated, now set on a per monitor basis using the Method field - { - name => 'ZM_NETCAM_REGEXPS', - default => 'yes', - description => 'Use regular expression matching with network cameras', - help => q` - Traditionally ZoneMinder has used complex regular regular - expressions to handle the multitude of formats that network - cameras produce. In versions from 1.21.1 the default is to use - a simpler and faster built in pattern matching methodology. - This works well with most networks cameras but if you have - problems you can try the older, but more flexible, regular - expression based method by selecting this option. Note, to use - this method you must have libpcre installed on your system. - `, - requires => [ { name => 'ZM_OPT_REMOTE_CAMERAS', value => 'yes' } ], - type => $types{boolean}, - category => 'hidden', - }, { name => 'ZM_HTTP_VERSION', default => '1.0', @@ -1974,19 +1922,6 @@ our @options = ( }, category => 'upload', }, - { - name => 'ZM_UPLOAD_FTP_HOST', - default => '', - description => 'The remote server to upload to', - help => q` - You can use filters to instruct ZoneMinder to upload events to - a remote ftp server. This option indicates the name, or ip - address, of the server to use. - `, - requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ], - type => $types{hostname}, - category => 'hidden', - }, { name => 'ZM_UPLOAD_HOST', default => '', @@ -2015,19 +1950,6 @@ our @options = ( type => $types{integer}, category => 'upload', }, - { - name => 'ZM_UPLOAD_FTP_USER', - default => '', - description => 'Your ftp username', - help => q` - You can use filters to instruct ZoneMinder to upload events to - a remote ftp server. This option indicates the username that - ZoneMinder should use to log in for ftp transfer. - `, - requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ], - type => $types{alphanum}, - category => 'hidden', - }, { name => 'ZM_UPLOAD_USER', default => '', @@ -2041,19 +1963,6 @@ our @options = ( type => $types{alphanum}, category => 'upload', }, - { - name => 'ZM_UPLOAD_FTP_PASS', - default => '', - description => 'Your ftp password', - help => q` - You can use filters to instruct ZoneMinder to upload events to - a remote ftp server. This option indicates the password that - ZoneMinder should use to log in for ftp transfer. - `, - requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ], - type => $types{string}, - category => 'hidden', - }, { name => 'ZM_UPLOAD_PASS', default => '', @@ -2069,21 +1978,6 @@ our @options = ( type => $types{string}, category => 'upload', }, - { - name => 'ZM_UPLOAD_FTP_LOC_DIR', - default => '@ZM_TMPDIR@', - description => 'The local directory in which to create upload files', - help => q` - You can use filters to instruct ZoneMinder to upload events to - a remote ftp server. This option indicates the local directory - that ZoneMinder should use for temporary upload files. These - are files that are created from events, uploaded and then - deleted. - `, - requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ], - type => $types{abs_path}, - category => 'hidden', - }, { name => 'ZM_UPLOAD_LOC_DIR', default => '@ZM_TMPDIR@', @@ -2098,19 +1992,6 @@ our @options = ( type => $types{abs_path}, category => 'upload', }, - { - name => 'ZM_UPLOAD_FTP_REM_DIR', - default => '', - description => 'The remote directory to upload to', - help => q` - You can use filters to instruct ZoneMinder to upload events to - a remote ftp server. This option indicates the remote directory - that ZoneMinder should use to upload event files to. - `, - requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ], - type => $types{rel_path}, - category => 'hidden', - }, { name => 'ZM_UPLOAD_REM_DIR', default => '', @@ -2124,21 +2005,6 @@ our @options = ( type => $types{rel_path}, category => 'upload', }, - { - name => 'ZM_UPLOAD_FTP_TIMEOUT', - default => '120', - description => 'How long to allow the transfer to take for each file', - help => q` - You can use filters to instruct ZoneMinder to upload events to - a remote ftp server. This option indicates the maximum ftp - inactivity timeout (in seconds) that should be tolerated before - ZoneMinder determines that the transfer has failed and closes - down the connection. - `, - requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ], - type => $types{integer}, - category => 'hidden', - }, { name => 'ZM_UPLOAD_TIMEOUT', default => '120', @@ -2191,20 +2057,6 @@ our @options = ( type => $types{boolean}, category => 'upload', }, - { - name => 'ZM_UPLOAD_FTP_DEBUG', - default => 'no', - description => 'Switch ftp debugging on', - help => q` - You can use filters to instruct ZoneMinder to upload events to - a remote ftp server. If you are having (or expecting) troubles - with uploading events then setting this to 'yes' permits - additional information to be included in the zmfilter log file. - `, - requires => [ { name => 'ZM_OPT_UPLOAD', value => 'yes' } ], - type => $types{boolean}, - category => 'hidden', - }, { name => 'ZM_UPLOAD_DEBUG', default => 'no', @@ -2237,85 +2089,6 @@ our @options = ( type => $types{boolean}, category => 'mail', }, - { - name => 'ZM_EMAIL_ADDRESS', - default => '', - description => 'The email address to send matching event details to', - requires => [ { name => 'ZM_OPT_EMAIL', value => 'yes' } ], - help => q` - This option is used to define the email address that any events - that match the appropriate filters will be sent to. - `, - type => $types{email}, - category => 'hidden', - }, - { - name => 'ZM_EMAIL_TEXT', - default => 'subject = "ZoneMinder: Alarm - %MN%-%EI% (%ESM% - %ESA% %EFA%)" - body = " - Hello, - - An alarm has been detected on your installation of the ZoneMinder. - - The details are as follows :- - - Monitor : %MN% - Event Id : %EI% - Length : %EL% - Frames : %EF% (%EFA%) - Scores : t%EST% m%ESM% a%ESA% - - This alarm was matched by the %FN% filter and can be viewed at %EPS% - - ZoneMinder"', - description => 'The text of the email used to send matching event details', - requires => [ { name => 'ZM_OPT_EMAIL', value => 'yes' } ], - help => q` - This option is used to define the content of the email that is - sent for any events that match the appropriate filters. - `, - type => $types{text}, - category => 'hidden', - }, - { - name => 'ZM_EMAIL_SUBJECT', - default => 'ZoneMinder: Alarm - %MN%-%EI% (%ESM% - %ESA% %EFA%)', - description => 'The subject of the email used to send matching event details', - requires => [ { name => 'ZM_OPT_EMAIL', value => 'yes' } ], - help => q` - This option is used to define the subject of the email that is - sent for any events that match the appropriate filters. - `, - type => $types{string}, - category => 'hidden', - }, - { - name => 'ZM_EMAIL_BODY', - default => ' - Hello, - - An alarm has been detected on your installation of the ZoneMinder. - - The details are as follows :- - - Monitor : %MN% - Event Id : %EI% - Length : %EL% - Frames : %EF% (%EFA%) - Scores : t%EST% m%ESM% a%ESA% - - This alarm was matched by the %FN% filter and can be viewed at %EPS% - - ZoneMinder', - description => 'The body of the email used to send matching event details', - requires => [ { name => 'ZM_OPT_EMAIL', value => 'yes' } ], - help => q` - This option is used to define the content of the email that is - sent for any events that match the appropriate filters. - `, - type => $types{text}, - category => 'hidden', - }, { name => 'ZM_OPT_MESSAGE', default => 'no', @@ -2347,19 +2120,6 @@ our @options = ( type => $types{email}, category => 'mail', }, - { - name => 'ZM_MESSAGE_TEXT', - default => 'subject = "ZoneMinder: Alarm - %MN%-%EI%" - body = "ZM alarm detected - %EL% secs, %EF%/%EFA% frames, t%EST%/m%ESM%/a%ESA% score."', - description => 'The text of the message used to send matching event details', - requires => [ { name => 'ZM_OPT_MESSAGE', value => 'yes' } ], - help => q` - This option is used to define the content of the message that - is sent for any events that match the appropriate filters. - `, - type => $types{text}, - category => 'hidden', - }, { name => 'ZM_MESSAGE_SUBJECT', default => 'ZoneMinder: Alarm - %MN%-%EI%', @@ -2652,23 +2412,6 @@ our @options = ( category => 'config', }, # Deprecated, superseded by event close mode - { - name => 'ZM_FORCE_CLOSE_EVENTS', - default => 'no', - description => 'Close events at section ends.', - help => q` - When a monitor is running in a continuous recording mode - (Record or Mocord) events are usually closed after a fixed - period of time (the section length). However in Mocord mode it - is possible that motion detection may occur near the end of a - section and ordinarily this will prevent the event being closed - until the motion has ceased. Switching this option on will - force the event closed at the specified time regardless of any - motion activity. - `, - type => $types{boolean}, - category => 'hidden', - }, { name => 'ZM_WEIGHTED_ALARM_CENTRES', default => 'no', @@ -2876,34 +2619,6 @@ our @options = ( type => $types{hexadecimal}, category => 'system', }, -# Deprecated, really no longer necessary - { - name => 'ZM_WEB_REFRESH_METHOD', - default => 'javascript', - description => 'What method windows should use to refresh themselves', - help => q` - Many windows in ZoneMinder need to refresh themselves to keep - their information current. This option determines what method - they should use to do this. Choosing 'javascript' means that - each window will have a short JavaScript statement in with a - timer to prompt the refresh. This is the most compatible - method. Choosing 'http' means the refresh instruction is put in - the HTTP header. This is a cleaner method but refreshes are - interrupted or cancelled when a link in the window is clicked - meaning that the window will no longer refresh and this would - have to be done manually. - `, - type => { - db_type =>'string', - hint =>'javascript|http', - pattern =>qr|^([jh])|i, - format =>q( $1 =~ /^j/ - ? 'javascript' - : 'http' - ) - }, - category => 'hidden', - }, { name => 'ZM_WEB_EVENT_SORT_FIELD', default => 'DateTime', @@ -4043,7 +3758,6 @@ sub initialiseConfig { } else { $option->{value} = ''; } -#next if ( $option->{category} eq 'hidden' ); $option->{id} = $option_id++; } $configInitialised = 1; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm index 91b87e615..b48946d1f 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Filter.pm @@ -82,6 +82,13 @@ sub Execute { my $self = $_[0]; my $sql = $self->Sql(undef); + if ( $$self{PreSQLConditions} and @{$$self{PreSQLConditions}} ) { + foreach my $term ( @{$$self{PreSQLConditions}} ) { + if ( $$term{attr} eq 'DiskPercent' ) { + } + } + } + if ( $self->{HasDiskPercent} ) { my $disk_percent = getDiskPercent($$self{Storage} ? $$self{Storage}->Path() : ()); $sql =~ s/zmDiskPercent/$disk_percent/g; @@ -104,14 +111,27 @@ sub Execute { return; } my @results; - while ( my $event = $sth->fetchrow_hashref() ) { push @results, $event; } $sth->finish(); - Debug('Loaded ' . @results . " events for filter $_[0]{Name} using query ($sql)"); + Debug('Loaded ' . @results . ' events for filter '.$$self{Name}.' using query ('.$sql.')"'); + if ( $self->{PostSQLConditions} ) { + my @filtered_events; + foreach my $term ( @{$$self{PostSQLConditions}} ) { + if ( $$term{attr} eq 'ExistsInFileSystem' ) { + foreach my $row ( @results ) { + my $event = new ZoneMinder::Event($row); + if ( -e $event->Path() ) { + push @filtered_events, $row; + } + } + } + } # end foreach term + @results = @filtered_events; + } # end if has PostSQLConditions return @results; -} +} # end sub Execute sub Sql { my $self = shift; @@ -183,18 +203,22 @@ sub Sql { $self->{Sql} .= "weekday( E.EndTime )"; # + } elsif ( $term->{attr} eq 'ExistsInFileSystem' ) { + push @{$self->{PostSQLConditions}}, $term; } elsif ( $term->{attr} eq 'DiskSpace' ) { $self->{Sql} .= 'E.DiskSpace'; - $self->{HasDiskPercent} = !undef; } elsif ( $term->{attr} eq 'DiskPercent' ) { $self->{Sql} .= 'zmDiskPercent'; $self->{HasDiskPercent} = !undef; + $self->{HasPreCondition} = !undef; } elsif ( $term->{attr} eq 'DiskBlocks' ) { $self->{Sql} .= 'zmDiskBlocks'; $self->{HasDiskBlocks} = !undef; + $self->{HasPreCondition} = !undef; } elsif ( $term->{attr} eq 'SystemLoad' ) { $self->{Sql} .= 'zmSystemLoad'; $self->{HasSystemLoad} = !undef; + $self->{HasPreCondition} = !undef; } else { $self->{Sql} .= 'E.'.$term->{attr}; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dc623c29a..bf7bf0bc5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ # CMakeLists.txt for the ZoneMinder binaries # Create files from the .in files -configure_file(zm_config.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config.h" @ONLY) +configure_file(zm_config_data.h.in "${CMAKE_CURRENT_BINARY_DIR}/zm_config_data.h" @ONLY) # Group together all the source files that are used by all the binaries (zmc, zma, zmu, zms etc) set(ZM_BIN_SRC_FILES zm_box.cpp zm_buffer.cpp zm_camera.cpp zm_comms.cpp zm_config.cpp zm_coord.cpp zm_curl_camera.cpp zm.cpp zm_db.cpp zm_logger.cpp zm_event.cpp zm_frame.cpp zm_eventstream.cpp zm_exception.cpp zm_file_camera.cpp zm_ffmpeg_input.cpp zm_ffmpeg_camera.cpp zm_group.cpp zm_image.cpp zm_jpeg.cpp zm_libvlc_camera.cpp zm_libvnc_camera.cpp zm_local_camera.cpp zm_monitor.cpp zm_monitorstream.cpp zm_ffmpeg.cpp zm_mpeg.cpp zm_packet.cpp zm_packetqueue.cpp zm_poly.cpp zm_regexp.cpp zm_remote_camera.cpp zm_remote_camera_http.cpp zm_remote_camera_nvsocket.cpp zm_remote_camera_rtsp.cpp zm_rtp.cpp zm_rtp_ctrl.cpp zm_rtp_data.cpp zm_rtp_source.cpp zm_rtsp.cpp zm_rtsp_auth.cpp zm_sdp.cpp zm_signal.cpp zm_stream.cpp zm_swscale.cpp zm_thread.cpp zm_time.cpp zm_timer.cpp zm_user.cpp zm_utils.cpp zm_video.cpp zm_videostore.cpp zm_zone.cpp zm_storage.cpp zm_fifo.cpp zm_crypt.cpp) diff --git a/src/zm.cpp b/src/zm.cpp index e25ce45ce..e541b322f 100644 --- a/src/zm.cpp +++ b/src/zm.cpp @@ -20,4 +20,4 @@ #include "zm.h" /* This is our argv[0], we need it for backtrace */ -const char* self = 0; +const char* self = nullptr; diff --git a/src/zm_buffer.h b/src/zm_buffer.h index 8f47c7cbc..a4b373b6b 100644 --- a/src/zm_buffer.h +++ b/src/zm_buffer.h @@ -34,7 +34,7 @@ protected: unsigned char *mTail; public: - Buffer() : mStorage( 0 ), mAllocation( 0 ), mSize( 0 ), mHead( 0 ), mTail( 0 ) { + Buffer() : mStorage( nullptr ), mAllocation( 0 ), mSize( 0 ), mHead( nullptr ), mTail( nullptr ) { } explicit Buffer( unsigned int pSize ) : mAllocation( pSize ), mSize( 0 ) { mHead = mStorage = new unsigned char[mAllocation]; diff --git a/src/zm_camera.cpp b/src/zm_camera.cpp index 5cb558645..0b4b208a8 100644 --- a/src/zm_camera.cpp +++ b/src/zm_camera.cpp @@ -55,7 +55,7 @@ Camera::Camera( Debug(2, "New camera id: %d width: %d line size: %d height: %d colours: %d subpixelorder: %d capture: %d", monitor_id, width, linesize, height, colours, subpixelorder, capture); - monitor = NULL; + monitor = nullptr; } Camera::~Camera() { diff --git a/src/zm_comms.cpp b/src/zm_comms.cpp index 4744388af..b7231d4fd 100644 --- a/src/zm_comms.cpp +++ b/src/zm_comms.cpp @@ -142,13 +142,13 @@ SockAddr *SockAddr::newSockAddr( const struct sockaddr &addr, socklen_t len ) return( new SockAddrUnix( (const struct sockaddr_un *)&addr ) ); } Error( "Unable to create new SockAddr from addr family %d with size %d", addr.sa_family, len ); - return( 0 ); + return nullptr; } SockAddr *SockAddr::newSockAddr( const SockAddr *addr ) { if ( !addr ) - return( 0 ); + return nullptr; if ( addr->getDomain() == AF_INET ) { @@ -159,7 +159,7 @@ SockAddr *SockAddr::newSockAddr( const SockAddr *addr ) return( new SockAddrUnix( *(SockAddrUnix *)addr ) ); } Error( "Unable to create new SockAddr from addr family %d", addr->getDomain() ); - return( 0 ); + return nullptr; } SockAddrInet::SockAddrInet() : SockAddr( (struct sockaddr *)&mAddrIn ) @@ -170,14 +170,14 @@ bool SockAddrInet::resolve( const char *host, const char *serv, const char *prot { memset( &mAddrIn, 0, sizeof(mAddrIn) ); - struct hostent *hostent=0; + struct hostent *hostent=nullptr; if ( !(hostent = ::gethostbyname( host ) ) ) { Error( "gethostbyname( %s ), h_errno = %d", host, h_errno ); return( false ); } - struct servent *servent=0; + struct servent *servent=nullptr; if ( !(servent = ::getservbyname( serv, proto ) ) ) { Error( "getservbyname( %s ), errno = %d, error = %s", serv, errno, strerror(errno) ); @@ -195,7 +195,7 @@ bool SockAddrInet::resolve( const char *host, int port, const char *proto ) { memset( &mAddrIn, 0, sizeof(mAddrIn) ); - struct hostent *hostent=0; + struct hostent *hostent=nullptr; if ( !(hostent = ::gethostbyname( host ) ) ) { Error( "gethostbyname( %s ), h_errno = %d", host, h_errno ); @@ -212,7 +212,7 @@ bool SockAddrInet::resolve( const char *serv, const char *proto ) { memset( &mAddrIn, 0, sizeof(mAddrIn) ); - struct servent *servent=0; + struct servent *servent=nullptr; if ( !(servent = ::getservbyname( serv, proto ) ) ) { Error( "getservbyname( %s ), errno = %d, error = %s", serv, errno, strerror(errno) ); @@ -541,7 +541,7 @@ bool InetSocket::connect( const char *host, const char *serv ) * If socket(2) (or connect(2)) fails, we (close the socket * and) try the next address. */ - for (rp = result; rp != NULL; rp = rp->ai_next) { + for (rp = result; rp != nullptr; rp = rp->ai_next) { if (mSd != -1) { if (::connect(mSd, rp->ai_addr, rp->ai_addrlen) != -1) break; /* Success */ @@ -576,7 +576,7 @@ bool InetSocket::connect( const char *host, const char *serv ) freeaddrinfo(result); /* No longer needed */ - if (rp == NULL) { /* No address succeeded */ + if (rp == nullptr) { /* No address succeeded */ Error( "connect(), Could not connect" ); mAddressFamily = AF_UNSPEC; return( false ); @@ -607,9 +607,9 @@ bool InetSocket::bind( const char * host, const char * serv ) hints.ai_socktype = getType(); hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ hints.ai_protocol = 0; /* Any protocol */ - hints.ai_canonname = NULL; - hints.ai_addr = NULL; - hints.ai_next = NULL; + hints.ai_canonname = nullptr; + hints.ai_addr = nullptr; + hints.ai_next = nullptr; s = getaddrinfo(host, serv, &hints, &result); if (s != 0) { @@ -621,7 +621,7 @@ bool InetSocket::bind( const char * host, const char * serv ) * Try each address until we successfully bind(2). * If socket(2) (or bind(2)) fails, we (close the socket * and) try the next address. */ - for (rp = result; rp != NULL; rp = rp->ai_next) { + for (rp = result; rp != nullptr; rp = rp->ai_next) { memset(&buf, 0, sizeof(buf)); if (rp->ai_family == AF_INET) { inet_ntop(AF_INET, &((struct sockaddr_in *)rp->ai_addr)->sin_addr, buf, sizeof(buf)-1); @@ -645,7 +645,7 @@ bool InetSocket::bind( const char * host, const char * serv ) mSd = -1; } - if (rp == NULL) { /* No address succeeded */ + if (rp == nullptr) { /* No address succeeded */ Error( "bind(), Could not bind" ); return( false ); } @@ -657,7 +657,7 @@ bool InetSocket::bind( const char * host, const char * serv ) bool InetSocket::bind( const char * serv ) { - return bind( NULL, serv); + return bind( nullptr, serv); } bool InetSocket::bind( const char * host, int port ) @@ -673,7 +673,7 @@ bool InetSocket::bind( int port ) char serv[8]; snprintf(serv, sizeof(serv), "%d", port); - return bind( NULL, serv ); + return bind( nullptr, serv ); } bool TcpInetServer::listen() @@ -689,7 +689,7 @@ bool TcpInetServer::accept() bool TcpInetServer::accept( TcpInetSocket *&newSocket ) { int newSd = -1; - newSocket = 0; + newSocket = nullptr; if ( !Socket::accept( newSd ) ) return( false ); @@ -702,7 +702,7 @@ bool TcpInetServer::accept( TcpInetSocket *&newSocket ) bool TcpUnixServer::accept( TcpUnixSocket *&newSocket ) { int newSd = -1; - newSocket = 0; + newSocket = nullptr; if ( !Socket::accept( newSd ) ) return( false ); @@ -830,7 +830,7 @@ void Select::clearWriters() int Select::wait() { struct timeval tempTimeout = mTimeout; - struct timeval *selectTimeout = mHasTimeout?&tempTimeout:NULL; + struct timeval *selectTimeout = mHasTimeout?&tempTimeout:nullptr; fd_set rfds; fd_set wfds; @@ -845,7 +845,7 @@ int Select::wait() for ( CommsSet::iterator iter = mWriters.begin(); iter != mWriters.end(); ++iter ) FD_SET((*iter)->getWriteDesc(),&wfds); - int nFound = select( mMaxFd+1, &rfds, &wfds, NULL, selectTimeout ); + int nFound = select( mMaxFd+1, &rfds, &wfds, nullptr, selectTimeout ); if( nFound == 0 ) { Debug( 1, "Select timed out" ); diff --git a/src/zm_comms.h b/src/zm_comms.h index e93951a85..46face33c 100644 --- a/src/zm_comms.h +++ b/src/zm_comms.h @@ -416,8 +416,8 @@ public: } public: - virtual int sendto( const void *msg, int len, const SockAddr *addr=0 ) const { - ssize_t nBytes = ::sendto( mSd, msg, len, 0, addr?addr->getAddr():NULL, addr?addr->getAddrSize():0 ); + virtual int sendto( const void *msg, int len, const SockAddr *addr=nullptr ) const { + ssize_t nBytes = ::sendto( mSd, msg, len, 0, addr?addr->getAddr():nullptr, addr?addr->getAddrSize():0 ); if ( nBytes < 0 ) Debug( 1, "Sendto of %d bytes on sd %d failed: %s", len, mSd, strerror(errno) ); return( nBytes ); @@ -432,7 +432,7 @@ public: Debug( 1, "Recvfrom of %d bytes max on sd %d (with address) failed: %s", len, mSd, strerror(errno) ); } } else { - nBytes = ::recvfrom( mSd, msg, len, 0, NULL, 0 ); + nBytes = ::recvfrom( mSd, msg, len, 0, nullptr, 0 ); if ( nBytes < 0 ) Debug( 1, "Recvfrom of %d bytes max on sd %d (no address) failed: %s", len, mSd, strerror(errno) ); } diff --git a/src/zm_config.cpp b/src/zm_config.cpp index 2f5851803..015095472 100644 --- a/src/zm_config.cpp +++ b/src/zm_config.cpp @@ -36,8 +36,7 @@ void zmLoadConfig() { // Process name, value pairs from the main config file first - char configFile[PATH_MAX] = ZM_CONFIG; - process_configfile(configFile); + process_configfile(ZM_CONFIG); // Search for user created config files. If one or more are found then // update the Config hash with those values @@ -108,14 +107,14 @@ void zmLoadConfig() { snprintf(staticConfig.video_file_format, sizeof(staticConfig.video_file_format), "%%s/%%s"); } -void process_configfile(char* configFile) { +void process_configfile(char const *configFile) { FILE *cfg; char line[512]; - if ( (cfg = fopen(configFile, "r")) == NULL ) { + if ( (cfg = fopen(configFile, "r")) == nullptr ) { Fatal("Can't open %s: %s", configFile, strerror(errno)); return; } - while ( fgets(line, sizeof(line), cfg) != NULL ) { + while ( fgets(line, sizeof(line), cfg) != nullptr ) { char *line_ptr = line; // Trim off any cr/lf line endings @@ -260,16 +259,16 @@ ConfigItem::~ConfigItem() { void ConfigItem::ConvertValue() const { if ( !strcmp( type, "boolean" ) ) { cfg_type = CFG_BOOLEAN; - cfg_value.boolean_value = (bool)strtol(value, 0, 0); + cfg_value.boolean_value = (bool)strtol(value, nullptr, 0); } else if ( !strcmp(type, "integer") ) { cfg_type = CFG_INTEGER; - cfg_value.integer_value = strtol(value, 0, 10); + cfg_value.integer_value = strtol(value, nullptr, 10); } else if ( !strcmp(type, "hexadecimal") ) { cfg_type = CFG_INTEGER; - cfg_value.integer_value = strtol(value, 0, 16); + cfg_value.integer_value = strtol(value, nullptr, 16); } else if ( !strcmp(type, "decimal") ) { cfg_type = CFG_DECIMAL; - cfg_value.decimal_value = strtod(value, 0); + cfg_value.decimal_value = strtod(value, nullptr); } else { cfg_type = CFG_STRING; cfg_value.string_value = value; @@ -334,10 +333,10 @@ Config::~Config() { if ( items ) { for ( int i = 0; i < n_items; i++ ) { delete items[i]; - items[i] = NULL; + items[i] = nullptr; } delete[] items; - items = NULL; + items = nullptr; } } diff --git a/src/zm_config.h.in b/src/zm_config.h similarity index 91% rename from src/zm_config.h.in rename to src/zm_config.h index 9831677f0..d348f38e9 100644 --- a/src/zm_config.h.in +++ b/src/zm_config.h @@ -1,21 +1,21 @@ // // ZoneMinder Configuration, $Date$, $Revision$ // Copyright (C) 2001-2008 Philip Coombes -// +// // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. -// +// // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// +// #ifndef ZM_CONFIG_H #define ZM_CONFIG_H @@ -23,19 +23,13 @@ #if !defined(PATH_MAX) #define PATH_MAX 1024 #endif + #include "config.h" #include "zm_config_defines.h" +#include "zm_config_data.h" #include -#define ZM_CONFIG "@ZM_CONFIG@" // Path to config file -#define ZM_CONFIG_SUBDIR "@ZM_CONFIG_SUBDIR@" // Path to the ZoneMinder config subfolder -#define ZM_VERSION "@VERSION@" // ZoneMinder Version - -#define ZM_HAS_V4L1 @ZM_HAS_V4L1@ -#define ZM_HAS_V4L2 @ZM_HAS_V4L2@ -#define ZM_HAS_V4L @ZM_HAS_V4L@ - #ifdef HAVE_LIBAVFORMAT #define ZM_HAS_FFMPEG 1 #endif // HAVE_LIBAVFORMAT @@ -62,7 +56,7 @@ extern void zmLoadConfig(); -extern void process_configfile( char* configFile ); +extern void process_configfile(char const *configFile); struct StaticConfig { std::string DB_HOST; diff --git a/src/zm_config_data.h.in b/src/zm_config_data.h.in new file mode 100644 index 000000000..1209dcbf5 --- /dev/null +++ b/src/zm_config_data.h.in @@ -0,0 +1,31 @@ +// +// ZoneMinder Configuration, $Date$, $Revision$ +// Copyright (C) 2001-2008 Philip Coombes +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// + +#ifndef ZM_CONFIG_DATA_H +#define ZM_CONFIG_DATA_H + +#define ZM_CONFIG "@ZM_CONFIG@" // Path to config file +#define ZM_CONFIG_SUBDIR "@ZM_CONFIG_SUBDIR@" // Path to the ZoneMinder config subfolder +#define ZM_VERSION "@VERSION@" // ZoneMinder Version + +#define ZM_HAS_V4L1 @ZM_HAS_V4L1@ +#define ZM_HAS_V4L2 @ZM_HAS_V4L2@ +#define ZM_HAS_V4L @ZM_HAS_V4L@ + +#endif // ZM_CONFIG_DATA_H diff --git a/src/zm_curl_camera.cpp b/src/zm_curl_camera.cpp index 93b356c5e..421863101 100644 --- a/src/zm_curl_camera.cpp +++ b/src/zm_curl_camera.cpp @@ -106,26 +106,26 @@ void cURLCamera::Initialise() { Debug(2,"libcurl version: %s", (*curl_version_f)()); /* Create the shared data mutex */ - int nRet = pthread_mutex_init(&shareddata_mutex, NULL); + int nRet = pthread_mutex_init(&shareddata_mutex, nullptr); if(nRet != 0) { Error("Shared data mutex creation failed: %s",strerror(nRet)); return; } /* Create the data available condition variable */ - nRet = pthread_cond_init(&data_available_cond, NULL); + nRet = pthread_cond_init(&data_available_cond, nullptr); if(nRet != 0) { Error("Data available condition variable creation failed: %s",strerror(nRet)); return; } /* Create the request complete condition variable */ - nRet = pthread_cond_init(&request_complete_cond, NULL); + nRet = pthread_cond_init(&request_complete_cond, nullptr); if(nRet != 0) { Error("Request complete condition variable creation failed: %s",strerror(nRet)); return; } /* Create the thread */ - nRet = pthread_create(&thread, NULL, thread_func_dispatcher, this); + nRet = pthread_create(&thread, nullptr, thread_func_dispatcher, this); if(nRet != 0) { Error("Thread creation failed: %s",strerror(nRet)); return; @@ -137,7 +137,7 @@ void cURLCamera::Terminate() { bTerminate = true; /* Wait for thread termination */ - pthread_join(thread, NULL); + pthread_join(thread, nullptr); /* Destroy condition variables */ pthread_cond_destroy(&request_complete_cond); @@ -425,7 +425,7 @@ void* cURLCamera::thread_func() { double dSize; c = (*curl_easy_init_f)(); - if(c == NULL) { + if(c == nullptr) { dlclose(curl_lib); Error("Failed getting easy handle from libcurl"); tRet = -51; @@ -572,7 +572,7 @@ void* cURLCamera::thread_func() { /* Cleanup */ (*curl_easy_cleanup_f)(c); - c = NULL; + c = nullptr; return (void*)tRet; } diff --git a/src/zm_db.cpp b/src/zm_db.cpp index 35982ce50..37c3cd0f7 100644 --- a/src/zm_db.cpp +++ b/src/zm_db.cpp @@ -48,10 +48,10 @@ bool zmDbConnect() { staticConfig.DB_SSL_CLIENT_KEY.c_str(), staticConfig.DB_SSL_CLIENT_CERT.c_str(), staticConfig.DB_SSL_CA_CERT.c_str(), - NULL, NULL); + nullptr, nullptr); std::string::size_type colonIndex = staticConfig.DB_HOST.find(":"); if ( colonIndex == std::string::npos ) { - if ( !mysql_real_connect(&dbconn, staticConfig.DB_HOST.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, 0, NULL, 0) ) { + if ( !mysql_real_connect(&dbconn, staticConfig.DB_HOST.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), nullptr, 0, nullptr, 0) ) { Error( "Can't connect to server: %s", mysql_error(&dbconn)); return false; } @@ -59,12 +59,12 @@ bool zmDbConnect() { std::string dbHost = staticConfig.DB_HOST.substr( 0, colonIndex ); std::string dbPortOrSocket = staticConfig.DB_HOST.substr( colonIndex+1 ); if ( dbPortOrSocket[0] == '/' ) { - if ( !mysql_real_connect(&dbconn, NULL, staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, 0, dbPortOrSocket.c_str(), 0) ) { + if ( !mysql_real_connect(&dbconn, nullptr, staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), nullptr, 0, dbPortOrSocket.c_str(), 0) ) { Error("Can't connect to server: %s", mysql_error(&dbconn)); return false; } } else { - if ( !mysql_real_connect( &dbconn, dbHost.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, atoi(dbPortOrSocket.c_str()), NULL, 0 ) ) { + if ( !mysql_real_connect( &dbconn, dbHost.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), nullptr, atoi(dbPortOrSocket.c_str()), nullptr, 0 ) ) { Error( "Can't connect to server: %s", mysql_error( &dbconn ) ); return false; } @@ -94,20 +94,20 @@ void zmDbClose() { MYSQL_RES * zmDbFetch(const char * query) { if ( !zmDbConnected ) { Error("Not connected."); - return NULL; + return nullptr; } db_mutex.lock(); // Might have been disconnected while we waited for the lock if ( !zmDbConnected ) { db_mutex.unlock(); Error("Not connected."); - return NULL; + return nullptr; } if ( mysql_query(&dbconn, query) ) { db_mutex.unlock(); Error("Can't run query: %s", mysql_error(&dbconn)); - return NULL; + return nullptr; } Debug(4, "Success running query: %s", query); MYSQL_RES *result = mysql_store_result(&dbconn); @@ -124,7 +124,7 @@ zmDbRow *zmDbFetchOne(const char *query) { return row; } delete row; - return NULL; + return nullptr; } MYSQL_RES *zmDbRow::fetch(const char *query) { @@ -135,14 +135,14 @@ MYSQL_RES *zmDbRow::fetch(const char *query) { if ( n_rows != 1 ) { Error("Bogus number of lines return from query, %d returned for query %s.", n_rows, query); mysql_free_result(result_set); - result_set = NULL; + result_set = nullptr; return result_set; } row = mysql_fetch_row(result_set); if ( ! row ) { mysql_free_result(result_set); - result_set = NULL; + result_set = nullptr; Error("Error getting row from query %s. Error is %s", query, mysql_error(&dbconn)); } else { Debug(5, "Success"); @@ -153,6 +153,6 @@ MYSQL_RES *zmDbRow::fetch(const char *query) { zmDbRow::~zmDbRow() { if ( result_set ) { mysql_free_result(result_set); - result_set = NULL; + result_set = nullptr; } } diff --git a/src/zm_db.h b/src/zm_db.h index c707ad2b7..11fc9faaa 100644 --- a/src/zm_db.h +++ b/src/zm_db.h @@ -28,7 +28,7 @@ class zmDbRow { MYSQL_RES *result_set; MYSQL_ROW row; public: - zmDbRow() { result_set = NULL; row = NULL; }; + zmDbRow() { result_set = nullptr; row = nullptr; }; MYSQL_RES *fetch( const char *query ); zmDbRow( MYSQL_RES *, MYSQL_ROW *row ); ~zmDbRow(); diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 3dd89575a..76156c3a5 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -55,7 +55,7 @@ Event::Event( cause(p_cause), noteSetMap(p_noteSetMap), videoEvent(p_videoEvent), - videowriter(NULL) + videowriter(nullptr) { std::string notes; @@ -222,19 +222,19 @@ Event::Event( Error("ZoneMinder was not compiled with the X264 MP4 video writer, check dependencies (x264 and mp4v2)"); #endif - if ( videowriter != NULL ) { + if ( videowriter != nullptr ) { /* Open the video stream */ int nRet = videowriter->Open(); if ( nRet != 0 ) { Error("Failed opening video stream"); delete videowriter; - videowriter = NULL; + videowriter = nullptr; } } } } else { /* No video object */ - videowriter = NULL; + videowriter = nullptr; } } // Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string &p_cause, const StringSetMap &p_noteSetMap, bool p_videoEvent ) @@ -242,13 +242,13 @@ Event::~Event() { // We close the videowriter first, because if we finish the event, we might try to view the file, but we aren't done writing it yet. /* Close the video file */ - if ( videowriter != NULL ) { + if ( videowriter != nullptr ) { int nRet = videowriter->Close(); if ( nRet != 0 ) { Error("Failed closing video stream"); } delete videowriter; - videowriter = NULL; + videowriter = nullptr; } struct DeltaTimeval delta_time; @@ -347,7 +347,7 @@ bool Event::WriteFrameVideo( Image ts_image; /* Checking for invalid parameters */ - if ( videow == NULL ) { + if ( videow == nullptr ) { Error("NULL Video object"); return false; } @@ -509,7 +509,7 @@ void Event::AddFramesInternal(int n_frames, int start_frame, Image **images, str WriteFrameImage(images[i], *(timestamps[i]), snapshot_file.c_str()); } - if ( videowriter != NULL ) { + if ( videowriter != nullptr ) { WriteFrameVideo(images[i], *(timestamps[i]), videowriter); } @@ -646,7 +646,7 @@ void Event::AddFrame(Image *image, struct timeval timestamp, int score, Image *a } } // end if frame_type == ALARM - if ( videowriter != NULL ) { + if ( videowriter != nullptr ) { WriteFrameVideo(image, timestamp, videowriter); } diff --git a/src/zm_event.h b/src/zm_event.h index 03a07ed55..8c44af1f2 100644 --- a/src/zm_event.h +++ b/src/zm_event.h @@ -129,7 +129,7 @@ class Event { void updateNotes( const StringSetMap &stringSetMap ); void AddFrames( int n_frames, Image **images, struct timeval **timestamps ); - void AddFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL ); + void AddFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=nullptr ); private: void AddFramesInternal( int n_frames, int start_frame, Image **images, struct timeval **timestamps ); @@ -158,16 +158,16 @@ class Event { while ( pre_alarm_count > 0 ) { int i = pre_alarm_count - 1; delete pre_alarm_data[i].image; - pre_alarm_data[i].image = NULL; + pre_alarm_data[i].image = nullptr; if ( pre_alarm_data[i].alarm_frame ) { delete pre_alarm_data[i].alarm_frame; - pre_alarm_data[i].alarm_frame = NULL; + pre_alarm_data[i].alarm_frame = nullptr; } pre_alarm_count--; } pre_alarm_count = 0; } - static void AddPreAlarmFrame(Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL) { + static void AddPreAlarmFrame(Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=nullptr) { pre_alarm_data[pre_alarm_count].image = new Image(*image); pre_alarm_data[pre_alarm_count].timestamp = timestamp; pre_alarm_data[pre_alarm_count].score = score; diff --git a/src/zm_eventstream.cpp b/src/zm_eventstream.cpp index 62093af21..b9abf5e76 100644 --- a/src/zm_eventstream.cpp +++ b/src/zm_eventstream.cpp @@ -148,7 +148,7 @@ bool EventStream::loadEventData(uint64_t event_id) { event_data->monitor_id = atoi(dbrow[0]); event_data->storage_id = dbrow[1] ? atoi(dbrow[1]) : 0; - event_data->frame_count = dbrow[2] == NULL ? 0 : atoi(dbrow[2]); + event_data->frame_count = dbrow[2] == nullptr ? 0 : atoi(dbrow[2]); event_data->start_time = atoi(dbrow[3]); event_data->duration = dbrow[4] ? atof(dbrow[4]) : 0.0; strncpy(event_data->video_file, dbrow[5], sizeof(event_data->video_file)-1); @@ -160,8 +160,8 @@ bool EventStream::loadEventData(uint64_t event_id) { } else { event_data->scheme = Storage::SHALLOW; } - event_data->SaveJPEGs = dbrow[7] == NULL ? 0 : atoi(dbrow[7]); - event_data->Orientation = (Monitor::Orientation)(dbrow[8] == NULL ? 0 : atoi(dbrow[8])); + event_data->SaveJPEGs = dbrow[7] == nullptr ? 0 : atoi(dbrow[7]); + event_data->Orientation = (Monitor::Orientation)(dbrow[8] == nullptr ? 0 : atoi(dbrow[8])); mysql_free_result(result); if ( !monitor ) { @@ -303,7 +303,7 @@ bool EventStream::loadEventData(uint64_t event_id) { if ( 0 > ffmpeg_input->Open(filepath.c_str()) ) { Warning("Unable to open ffmpeg_input %s", filepath.c_str()); delete ffmpeg_input; - ffmpeg_input = NULL; + ffmpeg_input = nullptr; } } @@ -646,7 +646,6 @@ bool EventStream::sendFrame(int delta_us) { static char filepath[PATH_MAX]; static struct stat filestat; - FILE *fdj = NULL; // This needs to be abstracted. If we are saving jpgs, then load the capture file. // If we are only saving analysis frames, then send that. @@ -662,7 +661,6 @@ bool EventStream::sendFrame(int delta_us) { filepath[0] = 0; } } - } else if ( !ffmpeg_input ) { Fatal("JPEGS not saved. zms is not capable of streaming jpegs from mp4 yet"); return false; @@ -684,34 +682,22 @@ bool EventStream::sendFrame(int delta_us) { } else #endif // HAVE_LIBAVCODEC { - static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; + static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; int img_buffer_size = 0; uint8_t *img_buffer = temp_img_buffer; - bool send_raw = ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)) && filepath[0]; + bool send_raw = (type == STREAM_JPEG) && ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)) && filepath[0]; - fprintf(stdout, "--ZoneMinderFrame\r\n"); - - if ( (type != STREAM_JPEG) || (!filepath[0]) ) - send_raw = false; + fprintf(stdout, "--" BOUNDARY "\r\n"); if ( send_raw ) { - fdj = fopen(filepath, "rb"); - if ( !fdj ) { - Error("Can't open %s: %s", filepath, strerror(errno)); - return true; // returning false will cause us to terminate. - } -#if HAVE_SENDFILE - if ( fstat(fileno(fdj),&filestat) < 0 ) { - Error("Failed getting information about file %s: %s", filepath, strerror(errno)); + if ( !send_file(filepath) ) { + Error("Can't send %s: %s", filepath, strerror(errno)); return false; } -#else - img_buffer_size = fread(img_buffer, 1, sizeof(temp_img_buffer), fdj); -#endif } else { - Image *image = NULL; + Image *image = nullptr; if ( filepath[0] ) { image = new Image(filepath); @@ -765,92 +751,33 @@ bool EventStream::sendFrame(int delta_us) { switch ( type ) { case STREAM_JPEG : - if ( send_image->EncodeJpeg(img_buffer, &img_buffer_size) ) { - Debug(1, "encoded JPEG"); - } else { - // Failed - } + send_image->EncodeJpeg(img_buffer, &img_buffer_size); + fputs("Content-Type: image/jpeg\r\n", stdout); break; case STREAM_ZIP : -#if HAVE_ZLIB_H unsigned long zip_buffer_size; send_image->Zip(img_buffer, &zip_buffer_size); img_buffer_size = zip_buffer_size; + fputs("Content-Type: image/x-rgbz\r\n", stdout); break; -#else - Error("zlib is required for zipped images. Falling back to raw image"); - type = STREAM_RAW; -#endif // HAVE_ZLIB_H case STREAM_RAW : img_buffer = (uint8_t*)(send_image->Buffer()); img_buffer_size = send_image->Size(); + fputs("Content-Type: image/x-rgb\r\n", stdout); break; default: Fatal("Unexpected frame type %d", type); break; } + send_buffer(img_buffer, img_buffer_size); delete image; - image = NULL; - } // end if send_raw or not - - switch ( type ) { - case STREAM_JPEG : - fputs("Content-Type: image/jpeg\r\n", stdout); - break; - case STREAM_RAW : - fputs("Content-Type: image/x-rgb\r\n", stdout); - break; - case STREAM_ZIP : - fputs("Content-Type: image/x-rgbz\r\n", stdout); - break; - default : - Fatal("Unexpected frame type %d", type); - break; - } - - if ( send_raw ) { -#if HAVE_SENDFILE - if ( 0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size) ) { - fclose(fdj); /* Close the file handle */ - Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno)); - return false; - } - if ( zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size ) { - /* sendfile() failed, use standard way instead */ - img_buffer_size = fread(img_buffer, 1, sizeof(temp_img_buffer), fdj); - if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) { - fclose(fdj); /* Close the file handle */ - Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno)); - return false; - } - } -#else - if ( - (0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size) ) - || - ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) - ) { - fclose(fdj); /* Close the file handle */ - Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno)); - return false; - } -#endif - fclose(fdj); /* Close the file handle */ - } else { - Debug(3, "Content length: %d", img_buffer_size); - if ( - (0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size) ) - || - ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) ) { - if ( errno != EPIPE ) - Error("Unable to send stream frame: %s", strerror(errno)); - return false; - } + image = nullptr; } // end if send_raw or not - fputs("\r\n\r\n", stdout); - fflush(stdout); } // end if stream MPEG or other + + fputs("\r\n\r\n", stdout); + fflush(stdout); last_frame_sent = TV_2_FLOAT(now); return true; } // bool EventStream::sendFrame( int delta_us ) @@ -861,7 +788,7 @@ void EventStream::runStream() { checkInitialised(); if ( type == STREAM_JPEG ) - fputs("Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame\r\n\r\n", stdout); + fputs("Content-Type: multipart/x-mixed-replace;boundary=" BOUNDARY "\r\n\r\n", stdout); if ( !event_data ) { sendTextFrame("No event data found"); @@ -870,7 +797,7 @@ void EventStream::runStream() { Debug(3, "frame rate is: (%f)", (double)event_data->frame_count/event_data->duration); updateFrameRate((double)event_data->frame_count/event_data->duration); - gettimeofday(&start, NULL); + gettimeofday(&start, nullptr); uint64_t start_usec = start.tv_sec * 1000000 + start.tv_usec; uint64_t last_frame_offset = 0; @@ -878,7 +805,7 @@ void EventStream::runStream() { double time_to_event = 0; while ( !zm_terminate ) { - gettimeofday(&now, NULL); + gettimeofday(&now, nullptr); int delta_us = 0; send_frame = false; @@ -982,7 +909,7 @@ void EventStream::runStream() { // +/- 1? What if we are skipping frames? curr_frame_id += (replay_rate>0) ? frame_mod : -1*frame_mod; // sending the frame may have taken some time, so reload now - gettimeofday(&now, NULL); + gettimeofday(&now, nullptr); uint64_t now_usec = (now.tv_sec * 1000000 + now.tv_usec); // we incremented by replay_rate, so might have jumped past frame_count @@ -1079,7 +1006,65 @@ void EventStream::runStream() { #endif // HAVE_LIBAVCODEC closeComms(); -} // void EventStream::runStream() +} // end void EventStream::runStream() + +bool EventStream::send_file(const char * filepath) { + static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; + + int img_buffer_size = 0; + uint8_t *img_buffer = temp_img_buffer; + + FILE *fdj = NULL; + fdj = fopen(filepath, "rb"); + if ( !fdj ) { + Error("Can't open %s: %s", filepath, strerror(errno)); + return false; + } + bool size_sent = false; + +#if HAVE_SENDFILE + static struct stat filestat; + if ( fstat(fileno(fdj), &filestat) < 0 ) { + Error("Failed getting information about file %s: %s", filepath, strerror(errno)); + return false; + } + if ( 0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size) ) { + fclose(fdj); /* Close the file handle */ + Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno)); + return false; + } + size_sent = true; + + if ( zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size ) { + fclose(fdj); /* Close the file handle */ + return true; + } +#endif + img_buffer_size = fread(img_buffer, 1, sizeof(temp_img_buffer), fdj); + if ( !size_sent ) { + if ( 0 > fprintf(stdout, "Content-Length: %d\r\n\r\n", img_buffer_size) ) { + fclose(fdj); /* Close the file handle */ + Info("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno)); + return false; + } + } + if ( fwrite(img_buffer, img_buffer_size, 1, stdout) != 1 ) { + Error("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno)); + return false; + } + + fclose(fdj); /* Close the file handle */ + return true; +} // end bool EventStream::send_file(const char * filepath) + +bool EventStream::send_buffer(uint8_t* buffer, int size) { + fprintf(stdout, "Content-Length: %d\r\n\r\n", size); + if ( fwrite(buffer, size, 1, stdout) != 1 ) { + Error("Unable to send raw frame %u: %s", curr_frame_id, strerror(errno)); + return false; + } + return true; +} // end bool EventStream::send_buffer(uint8_t* buffer, int size) void EventStream::setStreamStart( uint64_t init_event_id, diff --git a/src/zm_eventstream.h b/src/zm_eventstream.h index c075892bc..023dd7a99 100644 --- a/src/zm_eventstream.h +++ b/src/zm_eventstream.h @@ -97,33 +97,33 @@ class EventStream : public StreamBase { curr_frame_id(0), curr_stream_time(0.0), send_frame(false), - event_data(0), - storage(NULL), - ffmpeg_input(NULL), + event_data(nullptr), + storage(nullptr), + ffmpeg_input(nullptr), // Used when loading frames from an mp4 - input_codec_context(0), - input_codec(0) + input_codec_context(nullptr), + input_codec(nullptr) {} ~EventStream() { if ( event_data ) { if ( event_data->frames ) { delete[] event_data->frames; - event_data->frames = NULL; + event_data->frames = nullptr; } delete event_data; - event_data = NULL; + event_data = nullptr; } if ( monitor ) { delete monitor; - monitor = NULL; + monitor = nullptr; } if ( storage ) { delete storage; - storage = NULL; + storage = nullptr; } if ( ffmpeg_input ) { delete ffmpeg_input; - ffmpeg_input = NULL; + ffmpeg_input = nullptr; } } void setStreamStart( uint64_t init_event_id, unsigned int init_frame_id ); @@ -134,6 +134,8 @@ class EventStream : public StreamBase { void runStream(); Image *getImage(); private: + bool send_file( const char *file_path ); + bool send_buffer( uint8_t * buffer, int size ); Storage *storage; FFmpeg_Input *ffmpeg_input; AVCodecContext *input_codec_context; diff --git a/src/zm_ffmpeg.cpp b/src/zm_ffmpeg.cpp index c668e2568..864b9e0a7 100644 --- a/src/zm_ffmpeg.cpp +++ b/src/zm_ffmpeg.cpp @@ -151,7 +151,7 @@ static int parse_key_value_pair(AVDictionary **pm, const char **buf, int flags) { char *key = av_get_token(buf, key_val_sep); - char *val = NULL; + char *val = nullptr; int ret; if (key && *key && strspn(*buf, key_val_sep)) { @@ -225,7 +225,7 @@ int hacked_up_context2_for_older_ffmpeg(AVFormatContext **avctx, AVOutputFormat AVFormatContext *s = avformat_alloc_context(); int ret = 0; - *avctx = NULL; + *avctx = nullptr; if (!s) { av_log(s, AV_LOG_ERROR, "Out of memory\n"); ret = AVERROR(ENOMEM); @@ -234,13 +234,13 @@ int hacked_up_context2_for_older_ffmpeg(AVFormatContext **avctx, AVOutputFormat if (!oformat) { if (format) { - oformat = av_guess_format(format, NULL, NULL); + oformat = av_guess_format(format, nullptr, nullptr); if (!oformat) { av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format); ret = AVERROR(EINVAL); } } else { - oformat = av_guess_format(NULL, filename, NULL); + oformat = av_guess_format(nullptr, filename, nullptr); if (!oformat) { ret = AVERROR(EINVAL); av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n", filename); @@ -267,7 +267,7 @@ int hacked_up_context2_for_older_ffmpeg(AVFormatContext **avctx, AVOutputFormat ret = AVERROR(ENOMEM); return ret; } - s->priv_data = NULL; + s->priv_data = nullptr; } #endif @@ -335,7 +335,7 @@ void zm_dump_stream_format(AVFormatContext *ic, int i, int index, int is_output) Debug(1, "Dumping stream index i(%d) index(%d)", i, index ); int flags = (is_output ? ic->oformat->flags : ic->iformat->flags); AVStream *st = ic->streams[i]; - AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); + AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", nullptr, 0); #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) AVCodecParameters *codec = st->codecpar; #else @@ -533,7 +533,7 @@ int zm_receive_packet(AVCodecContext *context, AVPacket &packet) { return 1; #else int got_packet = 0; - int ret = avcodec_encode_audio2(context, &packet, NULL, &got_packet); + int ret = avcodec_encode_audio2(context, &packet, nullptr, &got_packet); if ( ret < 0 ) { Error("Error encoding (%d) (%s)", ret, av_err2str(ret)); } @@ -719,7 +719,7 @@ int zm_resample_audio( Error("Flushing resampler not supported by AVRESAMPLE"); return 0; } - int ret = avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data, + int ret = avresample_convert(resample_ctx, nullptr, 0, 0, in_frame->data, 0, in_frame->nb_samples); if ( ret < 0 ) { Error("Could not resample frame (error '%s')", diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index a7a3bc259..6224c1f4f 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -133,32 +133,32 @@ FfmpegCamera::FfmpegCamera( Initialise(); } - mFormatContext = NULL; + mFormatContext = nullptr; mVideoStreamId = -1; mAudioStreamId = -1; - mVideoCodecContext = NULL; - mAudioCodecContext = NULL; - mVideoCodec = NULL; - mAudioCodec = NULL; - mRawFrame = NULL; - mFrame = NULL; + mVideoCodecContext = nullptr; + mAudioCodecContext = nullptr; + mVideoCodec = nullptr; + mAudioCodec = nullptr; + mRawFrame = nullptr; + mFrame = nullptr; frameCount = 0; mCanCapture = false; - videoStore = NULL; + videoStore = nullptr; have_video_keyframe = false; - packetqueue = NULL; + packetqueue = nullptr; error_count = 0; use_hwaccel = true; #if HAVE_LIBAVUTIL_HWCONTEXT_H - hwFrame = NULL; - hw_device_ctx = NULL; + hwFrame = nullptr; + hw_device_ctx = nullptr; #if LIBAVCODEC_VERSION_CHECK(57, 89, 0, 89, 0) hw_pix_fmt = AV_PIX_FMT_NONE; #endif #endif #if HAVE_LIBSWSCALE - mConvertContext = NULL; + mConvertContext = nullptr; #endif /* Has to be located inside the constructor so other components such as zma * will receive correct colours and subpixel order */ @@ -175,7 +175,7 @@ FfmpegCamera::FfmpegCamera( Panic("Unexpected colours: %d", colours); } - frame_buffer = NULL; + frame_buffer = nullptr; // sws_scale needs 32bit aligned width and an extra 16 bytes padding, so recalculate imagesize, which was width*height*bytes_per_pixel #if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) alignment = 32; @@ -351,10 +351,10 @@ int FfmpegCamera::OpenFfmpeg() { // Open the input, not necessarily a file #if !LIBAVFORMAT_VERSION_CHECK(53, 2, 0, 4, 0) - if ( av_open_input_file(&mFormatContext, mPath.c_str(), NULL, 0, NULL) != 0 ) + if ( av_open_input_file(&mFormatContext, mPath.c_str(), nullptr, 0, nullptr) != 0 ) #else // Handle options - AVDictionary *opts = 0; + AVDictionary *opts = nullptr; ret = av_dict_parse_string(&opts, Options().c_str(), "=", ",", 0); if ( ret < 0 ) { Warning("Could not parse ffmpeg input options '%s'", Options().c_str()); @@ -392,7 +392,7 @@ int FfmpegCamera::OpenFfmpeg() { mFormatContext->interrupt_callback.callback = FfmpegInterruptCallback; mFormatContext->interrupt_callback.opaque = this; - ret = avformat_open_input(&mFormatContext, mPath.c_str(), NULL, &opts); + ret = avformat_open_input(&mFormatContext, mPath.c_str(), nullptr, &opts); if ( ret != 0 ) #endif { @@ -403,15 +403,15 @@ int FfmpegCamera::OpenFfmpeg() { #else if ( mFormatContext ) { avformat_close_input(&mFormatContext); - mFormatContext = NULL; + mFormatContext = nullptr; } #endif av_dict_free(&opts); return -1; } - AVDictionaryEntry *e = NULL; - while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) { + AVDictionaryEntry *e = nullptr; + while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != nullptr ) { Warning("Option %s not recognized by ffmpeg", e->key); } av_dict_free(&opts); @@ -419,7 +419,7 @@ int FfmpegCamera::OpenFfmpeg() { #if !LIBAVFORMAT_VERSION_CHECK(53, 6, 0, 6, 0) ret = av_find_stream_info(mFormatContext); #else - ret = avformat_find_stream_info(mFormatContext, 0); + ret = avformat_find_stream_info(mFormatContext, nullptr); #endif if ( ret < 0 ) { Error("Unable to find stream info from %s due to: %s", @@ -474,7 +474,7 @@ int FfmpegCamera::OpenFfmpeg() { #endif if ( mVideoCodecContext->codec_id == AV_CODEC_ID_H264 ) { - if ( (mVideoCodec = avcodec_find_decoder_by_name("h264_mmal")) == NULL ) { + if ( (mVideoCodec = avcodec_find_decoder_by_name("h264_mmal")) == nullptr ) { Debug(1, "Failed to find decoder (h264_mmal)"); } else { Debug(1, "Success finding decoder (h264_mmal)"); @@ -540,7 +540,7 @@ int FfmpegCamera::OpenFfmpeg() { hw_pix_fmt, av_get_pix_fmt_name(hw_pix_fmt)); ret = av_hwdevice_ctx_create(&hw_device_ctx, type, - (hwaccel_device != "" ? hwaccel_device.c_str(): NULL), NULL, 0); + (hwaccel_device != "" ? hwaccel_device.c_str(): nullptr), nullptr, 0); if ( ret < 0 ) { Error("Failed to create hwaccel device. %s",av_make_error_string(ret).c_str()); hw_pix_fmt = AV_PIX_FMT_NONE; @@ -567,8 +567,8 @@ int FfmpegCamera::OpenFfmpeg() { #else ret = avcodec_open2(mVideoCodecContext, mVideoCodec, &opts); #endif - e = NULL; - while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) { + e = nullptr; + while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != nullptr ) { Warning("Option %s not recognized by ffmpeg", e->key); } if ( ret < 0 ) { @@ -587,7 +587,7 @@ int FfmpegCamera::OpenFfmpeg() { #else mFormatContext->streams[mAudioStreamId]->codec->codec_id #endif - )) == NULL ) { + )) == nullptr ) { Debug(1, "Can't find codec for audio stream from %s", mPath.c_str()); } else { #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) @@ -606,7 +606,7 @@ int FfmpegCamera::OpenFfmpeg() { #if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0) if ( avcodec_open(mAudioCodecContext, mAudioCodec) < 0 ) { #else - if ( avcodec_open2(mAudioCodecContext, mAudioCodec, 0) < 0 ) { + if ( avcodec_open2(mAudioCodecContext, mAudioCodec, nullptr) < 0 ) { #endif Error("Unable to open codec for audio stream from %s", mPath.c_str()); return -1; @@ -621,7 +621,7 @@ int FfmpegCamera::OpenFfmpeg() { // Allocate space for the converted video frame mFrame = zm_av_frame_alloc(); - if ( mRawFrame == NULL || mFrame == NULL ) { + if ( mRawFrame == nullptr || mFrame == nullptr ) { Error("Unable to allocate frame for %s", mPath.c_str()); return -1; } @@ -670,29 +670,29 @@ int FfmpegCamera::Close() { if ( mFrame ) { av_frame_free(&mFrame); - mFrame = NULL; + mFrame = nullptr; } if ( mRawFrame ) { av_frame_free(&mRawFrame); - mRawFrame = NULL; + mRawFrame = nullptr; } #if HAVE_LIBAVUTIL_HWCONTEXT_H if ( hwFrame ) { av_frame_free(&hwFrame); - hwFrame = NULL; + hwFrame = nullptr; } #endif #if HAVE_LIBSWSCALE if ( mConvertContext ) { sws_freeContext(mConvertContext); - mConvertContext = NULL; + mConvertContext = nullptr; } #endif if ( videoStore ) { delete videoStore; - videoStore = NULL; + videoStore = nullptr; } if ( mVideoCodecContext ) { @@ -700,14 +700,14 @@ int FfmpegCamera::Close() { #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) // avcodec_free_context(&mVideoCodecContext); #endif - mVideoCodecContext = NULL; // Freed by av_close_input_file + mVideoCodecContext = nullptr; // Freed by av_close_input_file } if ( mAudioCodecContext ) { avcodec_close(mAudioCodecContext); #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) avcodec_free_context(&mAudioCodecContext); #endif - mAudioCodecContext = NULL; // Freed by av_close_input_file + mAudioCodecContext = nullptr; // Freed by av_close_input_file } #if HAVE_LIBAVUTIL_HWCONTEXT_H @@ -722,12 +722,12 @@ int FfmpegCamera::Close() { #else avformat_close_input(&mFormatContext); #endif - mFormatContext = NULL; + mFormatContext = nullptr; } if ( packetqueue ) { delete packetqueue; - packetqueue = NULL; + packetqueue = nullptr; } return 0; @@ -823,7 +823,7 @@ int FfmpegCamera::CaptureAndRecord( } // end if video delete videoStore; - videoStore = NULL; + videoStore = nullptr; have_video_keyframe = false; monitor->SetVideoWriterEventId(0); @@ -839,7 +839,7 @@ int FfmpegCamera::CaptureAndRecord( Debug(3, "Record Audio on but no audio stream found"); videoStore = new VideoStore((const char *) event_file, "mp4", mFormatContext->streams[mVideoStreamId], - NULL, + nullptr, this->getMonitor()); } else { @@ -855,13 +855,13 @@ int FfmpegCamera::CaptureAndRecord( } videoStore = new VideoStore((const char *) event_file, "mp4", mFormatContext->streams[mVideoStreamId], - NULL, + nullptr, this->getMonitor()); } // end if record_audio if ( !videoStore->open() ) { delete videoStore; - videoStore = NULL; + videoStore = nullptr; } else { monitor->SetVideoWriterEventId(last_event_id); @@ -920,7 +920,7 @@ int FfmpegCamera::CaptureAndRecord( if ( videoStore ) { Debug(1, "Deleting videoStore instance"); delete videoStore; - videoStore = NULL; + videoStore = nullptr; have_video_keyframe = false; monitor->SetVideoWriterEventId(0); } @@ -1091,7 +1091,7 @@ int FfmpegCamera::transfer_to_image( /* Request a writeable buffer of the target image */ image_buffer = image.WriteBuffer(width, height, colours, subpixelorder); - if ( image_buffer == NULL ) { + if ( image_buffer == nullptr ) { Error("Failed requesting writeable buffer for the captured image."); return -1; } @@ -1128,9 +1128,9 @@ int FfmpegCamera::transfer_to_image( input_frame->height, (AVPixelFormat)input_frame->format, width, height, - imagePixFormat, SWS_BICUBIC, NULL, - NULL, NULL); - if ( mConvertContext == NULL ) { + imagePixFormat, SWS_BICUBIC, nullptr, + nullptr, nullptr); + if ( mConvertContext == nullptr ) { Error("Unable to create conversion context for %s from %s to %s", mPath.c_str(), av_get_pix_fmt_name((AVPixelFormat)input_frame->format), diff --git a/src/zm_ffmpeg_camera.h b/src/zm_ffmpeg_camera.h index dc24c9027..da815ab86 100644 --- a/src/zm_ffmpeg_camera.h +++ b/src/zm_ffmpeg_camera.h @@ -64,7 +64,7 @@ class FfmpegCamera : public Camera { AVFrame *hwFrame; // Will also be used to indicate if hwaccel is in use bool use_hwaccel; //will default to on if hwaccel specified, will get turned off if there is a failure #if HAVE_LIBAVUTIL_HWCONTEXT_H - AVBufferRef *hw_device_ctx = NULL; + AVBufferRef *hw_device_ctx = nullptr; #endif // Used to store the incoming packet, it will get copied when queued. diff --git a/src/zm_ffmpeg_input.cpp b/src/zm_ffmpeg_input.cpp index 06857a281..0ae6e634b 100644 --- a/src/zm_ffmpeg_input.cpp +++ b/src/zm_ffmpeg_input.cpp @@ -4,12 +4,12 @@ #include "zm_ffmpeg.h" FFmpeg_Input::FFmpeg_Input() { - input_format_context = NULL; + input_format_context = nullptr; video_stream_id = -1; audio_stream_id = -1; FFMPEGInit(); - streams = NULL; - frame = NULL; + streams = nullptr; + frame = nullptr; last_seek_request = -1; } @@ -17,14 +17,14 @@ FFmpeg_Input::~FFmpeg_Input() { if ( streams ) { for ( unsigned int i = 0; i < input_format_context->nb_streams; i += 1 ) { avcodec_close(streams[i].context); - streams[i].context = NULL; + streams[i].context = nullptr; } delete[] streams; - streams = NULL; + streams = nullptr; } if ( frame ) { av_frame_free(&frame); - frame = NULL; + frame = nullptr; } if ( input_format_context ) { #if !LIBAVFORMAT_VERSION_CHECK(53, 17, 0, 25, 0) @@ -32,7 +32,7 @@ FFmpeg_Input::~FFmpeg_Input() { #else avformat_close_input(&input_format_context); #endif - input_format_context = NULL; + input_format_context = nullptr; } } // end ~FFmpeg_Input() @@ -41,16 +41,16 @@ int FFmpeg_Input::Open(const char *filepath) { int error; /** Open the input file to read from it. */ - error = avformat_open_input(&input_format_context, filepath, NULL, NULL); + error = avformat_open_input(&input_format_context, filepath, nullptr, nullptr); if ( error < 0 ) { Error("Could not open input file '%s' (error '%s')\n", filepath, av_make_error_string(error).c_str() ); - input_format_context = NULL; + input_format_context = nullptr; return error; } /** Get information on the input file (number of streams etc.). */ - if ( (error = avformat_find_stream_info(input_format_context, NULL)) < 0 ) { + if ( (error = avformat_find_stream_info(input_format_context, nullptr)) < 0 ) { Error( "Could not open find stream info (error '%s')", av_make_error_string(error).c_str() @@ -84,7 +84,7 @@ int FFmpeg_Input::Open(const char *filepath) { streams[i].frame_count = 0; #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) - streams[i].context = avcodec_alloc_context3(NULL); + streams[i].context = avcodec_alloc_context3(nullptr); avcodec_parameters_to_context(streams[i].context, input_format_context->streams[i]->codecpar); #else streams[i].context = input_format_context->streams[i]->codec; @@ -98,7 +98,7 @@ int FFmpeg_Input::Open(const char *filepath) { Debug(1, "Using codec (%s) for stream %d", streams[i].codec->name, i); } - error = avcodec_open2(streams[i].context, streams[i].codec, NULL); + error = avcodec_open2(streams[i].context, streams[i].codec, nullptr); if ( error < 0 ) { Error("Could not open input codec (error '%s')", av_make_error_string(error).c_str()); @@ -106,7 +106,7 @@ int FFmpeg_Input::Open(const char *filepath) { avcodec_free_context(&streams[i].context); #endif avformat_close_input(&input_format_context); - input_format_context = NULL; + input_format_context = nullptr; return error; } } // end foreach stream @@ -134,11 +134,11 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id) { (ret == -110) ) { Info("av_read_frame returned %s.", av_make_error_string(ret).c_str()); - return NULL; + return nullptr; } Error("Unable to read packet from stream %d: error %d \"%s\".", packet.stream_index, ret, av_make_error_string(ret).c_str()); - return NULL; + return nullptr; } dumpPacket(input_format_context->streams[packet.stream_index], &packet, "Received packet"); @@ -175,7 +175,6 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id) { } // end while ! frameComplete return frame; - } // end AVFrame *FFmpeg_Input::get_frame AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) { @@ -193,7 +192,7 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) { ret = av_seek_frame(input_format_context, stream_id, seek_target, AVSEEK_FLAG_FRAME); if ( ret < 0 ) { Error("Unable to seek in stream"); - return NULL; + return nullptr; } // Have to grab a frame to update our current frame to know where we are get_frame(stream_id); @@ -201,7 +200,7 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) { if ( !frame ) { Warning("Unable to get frame."); - return NULL; + return nullptr; } if ( @@ -217,7 +216,7 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) { AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME ) < 0 ) ) { Error("Unable to seek in stream"); - return NULL; + return nullptr; } // Have to grab a frame to update our current frame to know where we are get_frame(stream_id); diff --git a/src/zm_fifo.cpp b/src/zm_fifo.cpp index 0c0f836bd..53025f597 100644 --- a/src/zm_fifo.cpp +++ b/src/zm_fifo.cpp @@ -30,13 +30,13 @@ #include "zm_fifo.h" #define RAW_BUFFER 512 static bool zm_fifodbg_inited = false; -FILE *zm_fifodbg_log_fd = 0; +FILE *zm_fifodbg_log_fd = nullptr; char zm_fifodbg_log[PATH_MAX] = ""; static bool zmFifoDbgOpen() { if ( zm_fifodbg_log_fd ) fclose(zm_fifodbg_log_fd); - zm_fifodbg_log_fd = NULL; + zm_fifodbg_log_fd = nullptr; signal(SIGPIPE, SIG_IGN); FifoStream::fifo_create_if_missing(zm_fifodbg_log); int fd = open(zm_fifodbg_log, O_WRONLY|O_NONBLOCK|O_TRUNC); @@ -48,7 +48,7 @@ static bool zmFifoDbgOpen() { return false; } zm_fifodbg_log_fd = fdopen(fd, "wb"); - if ( zm_fifodbg_log_fd == NULL ) { + if ( zm_fifodbg_log_fd == nullptr ) { close(fd); return false; } @@ -95,7 +95,7 @@ void zmFifoDbgOutput( int res = fwrite(dbg_string, dbg_ptr-dbg_string, 1, zm_fifodbg_log_fd); if ( res != 1 ) { fclose(zm_fifodbg_log_fd); - zm_fifodbg_log_fd = NULL; + zm_fifodbg_log_fd = nullptr; } else { fflush(zm_fifodbg_log_fd); } @@ -249,7 +249,7 @@ void FifoStream::runStream() { } while ( !zm_terminate ) { - gettimeofday(&now, NULL); + gettimeofday(&now, nullptr); checkCommandQueue(); if ( stream_type == MJPEG ) { if ( !sendMJEGFrames() ) diff --git a/src/zm_file_camera.cpp b/src/zm_file_camera.cpp index a7883c5d5..d94fce209 100644 --- a/src/zm_file_camera.cpp +++ b/src/zm_file_camera.cpp @@ -88,7 +88,7 @@ int FileCamera::PreCapture() { // This waits until 1 second has passed since it was modified. Effectively limiting fps to 60. // Which is kinda bogus. If we were writing to this jpg constantly faster than we are monitoring it here // we would never break out of this loop - while ( (time(0) - statbuf.st_mtime) < 1 ) { + while ( (time(nullptr) - statbuf.st_mtime) < 1 ) { usleep(100000); } return 0; diff --git a/src/zm_image.cpp b/src/zm_image.cpp index 1b8b33c8a..0a4cca08f 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -48,12 +48,12 @@ static short *g_v_table; static short *g_u_table; static short *b_u_table; -struct SwsContext *sws_convert_context = NULL; +struct SwsContext *sws_convert_context = nullptr; -jpeg_compress_struct *Image::writejpg_ccinfo[101] = { 0 }; -jpeg_compress_struct *Image::encodejpg_ccinfo[101] = { 0 }; -jpeg_decompress_struct *Image::readjpg_dcinfo = 0; -jpeg_decompress_struct *Image::decodejpg_dcinfo = 0; +jpeg_compress_struct *Image::writejpg_ccinfo[101] = { }; +jpeg_compress_struct *Image::encodejpg_ccinfo[101] = { }; +jpeg_decompress_struct *Image::readjpg_dcinfo = nullptr; +jpeg_decompress_struct *Image::decodejpg_dcinfo = nullptr; struct zm_error_mgr Image::jpg_err; /* Pointer to blend function. */ @@ -152,7 +152,7 @@ Image::Image(int p_width, int p_height, int p_colours, int p_subpixelorder, uint padding = p_padding; subpixelorder = p_subpixelorder; size = linesize*height + padding; - buffer = 0; + buffer = nullptr; holdbuffer = 0; if ( p_buffer ) { allocation = size; @@ -177,7 +177,7 @@ Image::Image(int p_width, int p_linesize, int p_height, int p_colours, int p_sub padding = p_padding; subpixelorder = p_subpixelorder; size = linesize*height + padding; - buffer = 0; + buffer = nullptr; holdbuffer = 0; if ( p_buffer ) { allocation = size; @@ -210,7 +210,7 @@ Image::Image(const AVFrame *frame) { size = avpicture_get_size(AV_PIX_FMT_RGBA, width, height); #endif - buffer = 0; + buffer = nullptr; holdbuffer = 0; AllocImgBuffer(size); @@ -229,9 +229,9 @@ Image::Image(const AVFrame *frame) { height, (AVPixelFormat)frame->format, width, height, - AV_PIX_FMT_RGBA, SWS_BICUBIC, NULL, - NULL, NULL); - if ( sws_convert_context == NULL ) + AV_PIX_FMT_RGBA, SWS_BICUBIC, nullptr, + nullptr, nullptr); + if ( sws_convert_context == nullptr ) Fatal("Unable to create conversion context"); if ( sws_scale(sws_convert_context, frame->data, frame->linesize, 0, frame->height, @@ -254,7 +254,7 @@ Image::Image(const Image &p_image) { colours = p_image.colours; subpixelorder = p_image.subpixelorder; size = p_image.size; // allocation is set in AllocImgBuffer - buffer = 0; + buffer = nullptr; holdbuffer = 0; AllocImgBuffer(size); (*fptr_imgbufcpy)(buffer, p_image.buffer, size); @@ -273,24 +273,24 @@ void Image::Deinitialise() { if ( readjpg_dcinfo ) { jpeg_destroy_decompress(readjpg_dcinfo); delete readjpg_dcinfo; - readjpg_dcinfo = NULL; + readjpg_dcinfo = nullptr; } if ( decodejpg_dcinfo ) { jpeg_destroy_decompress(decodejpg_dcinfo); delete decodejpg_dcinfo; - decodejpg_dcinfo = NULL; + decodejpg_dcinfo = nullptr; } for ( unsigned int quality=0; quality <= 100; quality += 1 ) { if ( writejpg_ccinfo[quality] ) { jpeg_destroy_compress(writejpg_ccinfo[quality]); delete writejpg_ccinfo[quality]; - writejpg_ccinfo[quality] = NULL; + writejpg_ccinfo[quality] = nullptr; } } // end foreach quality if ( sws_convert_context ) { sws_freeContext(sws_convert_context); - sws_convert_context = NULL; + sws_convert_context = nullptr; } } // end void Image::Deinitialise() @@ -501,25 +501,25 @@ uint8_t* Image::WriteBuffer( && p_colours != ZM_COLOUR_RGB32 ) { Error("WriteBuffer called with unexpected colours: %d", p_colours); - return NULL; + return nullptr; } if ( ! ( p_height > 0 && p_width > 0 ) ) { Error("WriteBuffer called with invalid width or height: %d %d", p_width, p_height); - return NULL; + return nullptr; } if ( p_width != width || p_height != height || p_colours != colours || p_subpixelorder != subpixelorder ) { unsigned int newsize = (p_width * p_height) * p_colours; - if ( buffer == NULL ) { + if ( buffer == nullptr ) { AllocImgBuffer(newsize); } else { if ( allocation < newsize ) { if ( holdbuffer ) { Error("Held buffer is undersized for requested buffer"); - return NULL; + return nullptr; } else { /* Replace buffer with a bigger one */ //DumpImgBuffer(); // Done in AllocImgBuffer too @@ -552,7 +552,7 @@ void Image::AssignDirect( const size_t buffer_size, const int p_buffertype) { - if ( new_buffer == NULL ) { + if ( new_buffer == nullptr ) { Error("Attempt to directly assign buffer from a NULL pointer"); return; } @@ -623,7 +623,7 @@ void Image::Assign( const size_t buffer_size) { unsigned int new_size = (p_width * p_height) * p_colours; - if ( new_buffer == NULL ) { + if ( new_buffer == nullptr ) { Error("Attempt to assign buffer from a NULL pointer"); return; } @@ -672,7 +672,7 @@ void Image::Assign( void Image::Assign(const Image &image) { unsigned int new_size = image.height * image.linesize; - if ( image.buffer == NULL ) { + if ( image.buffer == nullptr ) { Error("Attempt to assign image with an empty buffer"); return; } @@ -811,7 +811,7 @@ Image *Image::HighlightEdges( bool Image::ReadRaw(const char *filename) { FILE *infile; - if ( (infile = fopen(filename, "rb")) == NULL ) { + if ( (infile = fopen(filename, "rb")) == nullptr ) { Error("Can't open %s: %s", filename, strerror(errno)); return false; } @@ -842,7 +842,7 @@ bool Image::ReadRaw(const char *filename) { bool Image::WriteRaw(const char *filename) const { FILE *outfile; - if ( (outfile = fopen(filename, "wb")) == NULL ) { + if ( (outfile = fopen(filename, "wb")) == nullptr ) { Error("Can't open %s: %s", filename, strerror(errno)); return false; } @@ -871,7 +871,7 @@ bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int } FILE *infile; - if ( (infile = fopen(filename, "rb")) == NULL ) { + if ( (infile = fopen(filename, "rb")) == nullptr ) { Error("Can't open %s: %s", filename, strerror(errno)); return false; } @@ -895,7 +895,7 @@ bool Image::ReadJpeg(const char *filename, unsigned int p_colours, unsigned int /* Check if the image has at least one huffman table defined. If not, use the standard ones */ /* This is required for the MJPEG capture palette of USB devices */ - if ( cinfo->dc_huff_tbl_ptrs[0] == NULL ) { + if ( cinfo->dc_huff_tbl_ptrs[0] == nullptr ) { zm_use_std_huff_tables(cinfo); } @@ -960,7 +960,7 @@ cinfo->out_color_space = JCS_RGB; break; } // end switch p_colours - if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL ) { + if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == nullptr ) { Error("Failed requesting writeable buffer for reading JPEG image."); jpeg_abort_decompress(cinfo); fclose(infile); @@ -1011,7 +1011,7 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval int quality = quality_override ? quality_override : config.jpeg_file_quality; struct jpeg_compress_struct *cinfo = writejpg_ccinfo[quality]; - FILE *outfile = NULL; + FILE *outfile = nullptr; static int raw_fd = 0; raw_fd = 0; @@ -1028,7 +1028,7 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval jpg_err.pub.emit_message = zm_jpeg_emit_silence; if ( setjmp(jpg_err.setjmp_buffer) ) { jpeg_abort_compress(cinfo); - Debug(1, "Aborted a write mid-stream and %s and %d", (outfile == NULL) ? "closing file" : "file not opened", raw_fd); + Debug(1, "Aborted a write mid-stream and %s and %d", (outfile == nullptr) ? "closing file" : "file not opened", raw_fd); if ( raw_fd ) close(raw_fd); if ( outfile ) @@ -1038,7 +1038,7 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval } if ( !on_blocking_abort ) { - if ( (outfile = fopen(filename, "wb")) == NULL ) { + if ( (outfile = fopen(filename, "wb")) == nullptr ) { Error("Can't open %s for writing: %s", filename, strerror(errno)); return false; } @@ -1047,7 +1047,7 @@ bool Image::WriteJpeg(const char *filename, int quality_override, struct timeval if ( raw_fd < 0 ) return false; outfile = fdopen(raw_fd, "wb"); - if ( outfile == NULL ) { + if ( outfile == nullptr ) { close(raw_fd); return false; } @@ -1190,7 +1190,7 @@ bool Image::DecodeJpeg( /* Check if the image has at least one huffman table defined. If not, use the standard ones */ /* This is required for the MJPEG capture palette of USB devices */ - if ( cinfo->dc_huff_tbl_ptrs[0] == NULL ) { + if ( cinfo->dc_huff_tbl_ptrs[0] == nullptr ) { zm_use_std_huff_tables(cinfo); } @@ -1256,7 +1256,7 @@ cinfo->out_color_space = JCS_RGB; break; } // end switch - if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL ) { + if ( WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == nullptr ) { Error("Failed requesting writeable buffer for reading JPEG image."); jpeg_abort_decompress(cinfo); return false; @@ -1799,7 +1799,7 @@ void Image::Delta( const Image &image, Image* targetimage) const { uint8_t *pdiff = targetimage->WriteBuffer(width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE); - if ( pdiff == NULL ) { + if ( pdiff == nullptr ) { Panic("Failed requesting writeable buffer for storing the delta image"); } diff --git a/src/zm_image.h b/src/zm_image.h index 1b8f614b9..8f86c3e30 100644 --- a/src/zm_image.h +++ b/src/zm_image.h @@ -57,7 +57,7 @@ extern imgbufcpy_fptr_t fptr_imgbufcpy; /* Should be called from Image class functions */ inline static uint8_t* AllocBuffer(size_t p_bufsize) { uint8_t* buffer = (uint8_t*)zm_mallocaligned(64, p_bufsize); - if ( buffer == NULL ) + if ( buffer == nullptr ) Fatal("Memory allocation failed: %s", strerror(errno)); return buffer; @@ -122,7 +122,7 @@ protected: inline void DumpImgBuffer() { DumpBuffer(buffer, buffertype); - buffer = NULL; + buffer = nullptr; allocation = 0; } diff --git a/src/zm_jpeg.cpp b/src/zm_jpeg.cpp index 8e8899227..9865d4db4 100644 --- a/src/zm_jpeg.cpp +++ b/src/zm_jpeg.cpp @@ -192,7 +192,7 @@ void zm_jpeg_mem_dest (j_compress_ptr cinfo, JOCTET *outbuffer, int *outbuffer_s * manager serially with the same JPEG object, because their private object * sizes may be different. Caveat programmer. */ - if ( cinfo->dest == NULL ) + if ( cinfo->dest == nullptr ) { /* first time for this JPEG object? */ cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(mem_destination_mgr)); @@ -369,7 +369,7 @@ void zm_jpeg_mem_src( j_decompress_ptr cinfo, const JOCTET *inbuffer, int inbuff * This makes it unsafe to use this manager and a different source * manager serially with the same JPEG object. Caveat programmer. */ - if ( cinfo->src == NULL ) + if ( cinfo->src == nullptr ) { /* first time for this JPEG object? */ cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(mem_source_mgr)); @@ -396,7 +396,7 @@ void zm_jpeg_mem_src( j_decompress_ptr cinfo, const JOCTET *inbuffer, int inbuff src->inbuffer = (JOCTET *)inbuffer; src->inbuffer_size = inbuffer_size; src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ - src->pub.next_input_byte = NULL; /* until buffer loaded */ + src->pub.next_input_byte = nullptr; /* until buffer loaded */ } void zm_use_std_huff_tables( j_decompress_ptr cinfo ) { diff --git a/src/zm_libvlc_camera.cpp b/src/zm_libvlc_camera.cpp index 03fd00570..2ac76d198 100644 --- a/src/zm_libvlc_camera.cpp +++ b/src/zm_libvlc_camera.cpp @@ -72,7 +72,7 @@ void* LibvlcLockBuffer(void* opaque, void** planes) { data->prevBuffer = buffer; *planes = data->buffer; - return NULL; + return nullptr; } void LibvlcUnlockBuffer(void* opaque, void* picture, void *const *planes) { @@ -129,12 +129,12 @@ LibvlcCamera::LibvlcCamera( mMethod(p_method), mOptions(p_options) { - mLibvlcInstance = NULL; - mLibvlcMedia = NULL; - mLibvlcMediaPlayer = NULL; - mLibvlcData.buffer = NULL; - mLibvlcData.prevBuffer = NULL; - mOptArgV = NULL; + mLibvlcInstance = nullptr; + mLibvlcMedia = nullptr; + mLibvlcMediaPlayer = nullptr; + mLibvlcData.buffer = nullptr; + mLibvlcData.prevBuffer = nullptr; + mOptArgV = nullptr; /* Has to be located inside the constructor so other components such as zma will receive correct colours and subpixel order */ if ( colours == ZM_COLOUR_RGB32 ) { @@ -163,19 +163,19 @@ LibvlcCamera::~LibvlcCamera() { if ( capture ) { Terminate(); } - if ( mLibvlcMediaPlayer != NULL ) { + if ( mLibvlcMediaPlayer != nullptr ) { (*libvlc_media_player_release_f)(mLibvlcMediaPlayer); - mLibvlcMediaPlayer = NULL; + mLibvlcMediaPlayer = nullptr; } - if ( mLibvlcMedia != NULL ) { + if ( mLibvlcMedia != nullptr ) { (*libvlc_media_release_f)(mLibvlcMedia); - mLibvlcMedia = NULL; + mLibvlcMedia = nullptr; } - if ( mLibvlcInstance != NULL ) { + if ( mLibvlcInstance != nullptr ) { (*libvlc_release_f)(mLibvlcInstance); - mLibvlcInstance = NULL; + mLibvlcInstance = nullptr; } - if ( mOptArgV != NULL ) { + if ( mOptArgV != nullptr ) { delete[] mOptArgV; } } @@ -188,12 +188,12 @@ void LibvlcCamera::Terminate() { (*libvlc_media_player_stop_f)(mLibvlcMediaPlayer); if ( mLibvlcData.buffer ) { zm_freealigned(mLibvlcData.buffer); - mLibvlcData.buffer = NULL; + mLibvlcData.buffer = nullptr; } if ( mLibvlcData.prevBuffer ) { zm_freealigned(mLibvlcData.prevBuffer); - mLibvlcData.prevBuffer = NULL; + mLibvlcData.prevBuffer = nullptr; } } @@ -223,27 +223,27 @@ int LibvlcCamera::PrimeCapture() { } mLibvlcInstance = (*libvlc_new_f)(opVect.size(), (const char* const*)mOptArgV); - if ( mLibvlcInstance == NULL ) { + if ( mLibvlcInstance == nullptr ) { Error("Unable to create libvlc instance due to: %s", (*libvlc_errmsg_f)()); return -1; } - (*libvlc_log_set_f)(mLibvlcInstance, LibvlcCamera::log_callback, NULL); + (*libvlc_log_set_f)(mLibvlcInstance, LibvlcCamera::log_callback, nullptr); mLibvlcMedia = (*libvlc_media_new_location_f)(mLibvlcInstance, mPath.c_str()); - if ( mLibvlcMedia == NULL ) { + if ( mLibvlcMedia == nullptr ) { Error("Unable to open input %s due to: %s", mPath.c_str(), (*libvlc_errmsg_f)()); return -1; } mLibvlcMediaPlayer = (*libvlc_media_player_new_from_media_f)(mLibvlcMedia); - if ( mLibvlcMediaPlayer == NULL ) { + if ( mLibvlcMediaPlayer == nullptr ) { Error("Unable to create player for %s due to: %s", mPath.c_str(), (*libvlc_errmsg_f)()); return -1; } (*libvlc_video_set_format_f)(mLibvlcMediaPlayer, mTargetChroma.c_str(), width, height, width * mBpp); - (*libvlc_video_set_callbacks_f)(mLibvlcMediaPlayer, &LibvlcLockBuffer, &LibvlcUnlockBuffer, NULL, &mLibvlcData); + (*libvlc_video_set_callbacks_f)(mLibvlcMediaPlayer, &LibvlcLockBuffer, &LibvlcUnlockBuffer, nullptr, &mLibvlcData); mLibvlcData.bufferSize = width * height * mBpp; // Libvlc wants 32 byte alignment for images (should in theory do this for all image lines) diff --git a/src/zm_libvnc_camera.cpp b/src/zm_libvnc_camera.cpp index c88a1c3b2..594e143c1 100644 --- a/src/zm_libvnc_camera.cpp +++ b/src/zm_libvnc_camera.cpp @@ -50,7 +50,7 @@ static rfbCredential* GetCredentialsCallback(rfbClient* cl, int credentialType){ rfbCredential *c = (rfbCredential *)malloc(sizeof(rfbCredential)); if ( credentialType != rfbCredentialTypeUser ) { free(c); - return NULL; + return nullptr; } c->userCredential.password = strdup((const char *)(*rfbClientGetClientData_f)(cl, &TAG_1)); diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index de08c00d1..38c7dae0e 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -302,10 +302,10 @@ LocalCamera::V4L1Data LocalCamera::v4l1_data; #endif // ZM_HAS_V4L1 #if HAVE_LIBSWSCALE -AVFrame **LocalCamera::capturePictures = 0; +AVFrame **LocalCamera::capturePictures = nullptr; #endif // HAVE_LIBSWSCALE -LocalCamera *LocalCamera::last_camera = NULL; +LocalCamera *LocalCamera::last_camera = nullptr; LocalCamera::LocalCamera( int p_id, @@ -673,14 +673,14 @@ LocalCamera::LocalCamera( Fatal("Image size mismatch. Required: %d Available: %u", pSize, imagesize); } - imgConversionContext = sws_getContext(width, height, capturePixFormat, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL); + imgConversionContext = sws_getContext(width, height, capturePixFormat, width, height, imagePixFormat, SWS_BICUBIC, nullptr, nullptr, nullptr); if ( !imgConversionContext ) { Fatal("Unable to initialise image scaling context"); } } else { - tmpPicture = NULL; - imgConversionContext = NULL; + tmpPicture = nullptr; + imgConversionContext = nullptr; } #endif } // end LocalCamera::LocalCamera @@ -693,7 +693,7 @@ LocalCamera::~LocalCamera() { /* Clean up swscale stuff */ if ( capture && conversion_type == 1 ) { sws_freeContext(imgConversionContext); - imgConversionContext = NULL; + imgConversionContext = nullptr; av_frame_free(&tmpPicture); } @@ -898,7 +898,7 @@ void LocalCamera::Initialise() { Fatal("Unable to query video buffer: %s", strerror(errno)); v4l2_data.buffers[i].length = vid_buf.length; - v4l2_data.buffers[i].start = mmap(NULL, vid_buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, vid_fd, vid_buf.m.offset); + v4l2_data.buffers[i].start = mmap(nullptr, vid_buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, vid_fd, vid_buf.m.offset); if ( v4l2_data.buffers[i].start == MAP_FAILED ) Fatal("Can't map video buffer %u (%u bytes) to memory: %s(%d)", @@ -1991,7 +1991,7 @@ int LocalCamera::PrimeCapture() { if ( vidioctl(vid_fd, VIDIOC_QBUF, &vid_buf) < 0 ) Fatal("Failed to queue buffer %d: %s", frame, strerror(errno)); } - v4l2_data.bufptr = NULL; + v4l2_data.bufptr = nullptr; Debug(3, "Starting video stream"); //enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; @@ -2023,7 +2023,7 @@ int LocalCamera::PreCapture() { int LocalCamera::Capture(Image &image) { Debug(3, "Capturing"); - static uint8_t* buffer = NULL; + static uint8_t* buffer = nullptr; int buffer_bytesused = 0; int capture_frame = -1; @@ -2116,7 +2116,7 @@ int LocalCamera::Capture(Image &image) { /* Request a writeable buffer of the target image */ uint8_t* directbuffer = image.WriteBuffer(width, height, colours, subpixelorder); - if ( directbuffer == NULL ) { + if ( directbuffer == nullptr ) { Error("Failed requesting writeable buffer for the captured image."); return -1; } diff --git a/src/zm_logger.cpp b/src/zm_logger.cpp index 011a0166e..29361b5a9 100644 --- a/src/zm_logger.cpp +++ b/src/zm_logger.cpp @@ -38,7 +38,7 @@ #endif bool Logger::smInitialised = false; -Logger *Logger::smInstance = NULL; +Logger *Logger::smInstance = nullptr; Logger::StringMap Logger::smCodes; Logger::IntMap Logger::smSyslogPriorities; @@ -74,7 +74,7 @@ Logger::Logger() : mDbConnected(false), mLogPath(staticConfig.PATH_LOGS.c_str()), //mLogFile( mLogPath+"/"+mId+".log" ), - mLogFileFP(NULL), + mLogFileFP(nullptr), mHasTerminal(false), mFlush(false) { @@ -413,7 +413,7 @@ void Logger::logFile(const std::string &logFile) { void Logger::openFile() { if ( mLogFile.size() ) { - if ( (mLogFileFP = fopen(mLogFile.c_str(), "a")) == (FILE *)NULL ) { + if ( (mLogFileFP = fopen(mLogFile.c_str(), "a")) == nullptr ) { mFileLevel = NOLOG; Error("fopen() for %s, error = %s", mLogFile.c_str(), strerror(errno)); } @@ -426,10 +426,10 @@ void Logger::closeFile() { if ( mLogFileFP ) { fflush(mLogFileFP); if ( fclose(mLogFileFP) < 0 ) { - mLogFileFP = (FILE *)NULL; + mLogFileFP = nullptr; Error("fclose(), error = %s", strerror(errno)); } - mLogFileFP = (FILE *)NULL; + mLogFileFP = nullptr; } } @@ -464,7 +464,7 @@ void Logger::logPrint(bool hex, const char * const filepath, const int line, con if ( level < PANIC || level > DEBUG9 ) Panic("Invalid logger level %d", level); - gettimeofday(&timeVal, NULL); + gettimeofday(&timeVal, nullptr); #if 0 if ( logRuntime ) { @@ -604,7 +604,7 @@ void Logger::logPrint(bool hex, const char * const filepath, const int line, con void logInit(const char *name, const Logger::Options &options) { if ( Logger::smInstance ) { delete Logger::smInstance; - Logger::smInstance = NULL; + Logger::smInstance = nullptr; } Logger::smInstance = new Logger(); @@ -614,6 +614,6 @@ void logInit(const char *name, const Logger::Options &options) { void logTerm() { if ( Logger::smInstance ) { delete Logger::smInstance; - Logger::smInstance = NULL; + Logger::smInstance = nullptr; } } diff --git a/src/zm_mem_utils.h b/src/zm_mem_utils.h index 8d841d670..6ef1bdac5 100644 --- a/src/zm_mem_utils.h +++ b/src/zm_mem_utils.h @@ -27,15 +27,15 @@ inline void* zm_mallocaligned(unsigned int reqalignment, size_t reqsize) { uint8_t* retptr; #if HAVE_POSIX_MEMALIGN if ( posix_memalign((void**)&retptr,reqalignment,reqsize) != 0 ) - return NULL; + return nullptr; return retptr; #else uint8_t* alloc; retptr = (uint8_t*)malloc(reqsize+reqalignment+sizeof(void*)); - if ( retptr == NULL ) - return NULL; + if ( retptr == nullptr ) + return nullptr; alloc = retptr + sizeof(void*); @@ -60,7 +60,7 @@ inline void zm_freealigned(void* ptr) { inline char *mempbrk(const char *s, const char *accept, size_t limit) { if ( limit == 0 || !s || !accept || !*accept ) - return 0; + return nullptr; unsigned int i,j; size_t acc_len = strlen(accept); @@ -72,12 +72,12 @@ inline char *mempbrk(const char *s, const char *accept, size_t limit) { } } } - return 0; + return nullptr; } inline char *memstr(const char *s, const char *n, size_t limit) { if ( limit == 0 || !s || !n ) - return 0; + return nullptr; if ( !*n ) return (char *)s; @@ -97,7 +97,7 @@ inline char *memstr(const char *s, const char *n, size_t limit) { break; } } - return 0; + return nullptr; } inline size_t memspn(const char *s, const char *accept, size_t limit) { diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 9de1b57b2..de245f854 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -108,9 +108,9 @@ std::vector split(const std::string &s, char delim) { Monitor::MonitorLink::MonitorLink(unsigned int p_id, const char *p_name) : id(p_id), - shared_data(NULL), - trigger_data(NULL), - video_store_data(NULL) + shared_data(nullptr), + trigger_data(nullptr), + video_store_data(nullptr) { strncpy(name, p_name, sizeof(name)-1); @@ -121,7 +121,7 @@ Monitor::MonitorLink::MonitorLink(unsigned int p_id, const char *p_name) : shm_id = 0; #endif // ZM_MEM_MAPPED mem_size = 0; - mem_ptr = 0; + mem_ptr = nullptr; last_event = 0; last_state = IDLE; @@ -135,8 +135,8 @@ Monitor::MonitorLink::~MonitorLink() { } bool Monitor::MonitorLink::connect() { - if ( !last_connect_time || (time(0) - last_connect_time) > 60 ) { - last_connect_time = time(0); + if ( !last_connect_time || (time(nullptr) - last_connect_time) > 60 ) { + last_connect_time = time(nullptr); mem_size = sizeof(SharedData) + sizeof(TriggerData); @@ -172,7 +172,7 @@ bool Monitor::MonitorLink::connect() { return false; } - mem_ptr = (unsigned char *)mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0); + mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0); if ( mem_ptr == MAP_FAILED ) { Error("Can't map file %s (%d bytes) to memory: %s", mem_file, mem_size, strerror(errno)); disconnect(); @@ -247,7 +247,7 @@ bool Monitor::MonitorLink::disconnect() { #endif // ZM_MEM_MAPPED mem_size = 0; - mem_ptr = 0; + mem_ptr = nullptr; } return( true ); } @@ -368,10 +368,10 @@ Monitor::Monitor( camera( p_camera ), n_zones( p_n_zones ), zones( p_zones ), - timestamps( 0 ), - images( 0 ), - privacy_bitmask( NULL ), - event_delete_thread(NULL) + timestamps( nullptr ), + images( nullptr ), + privacy_bitmask( nullptr ), + event_delete_thread(nullptr) { if (analysis_fps > 0.0) { uint64_t usec = round(1000000*pre_event_count/analysis_fps); @@ -440,7 +440,7 @@ Monitor::Monitor( (image_buffer_count*sizeof(struct timeval)), image_buffer_count, camera->ImageSize(), (image_buffer_count*camera->ImageSize()), mem_size); - mem_ptr = NULL; + mem_ptr = nullptr; storage = new Storage(storage_id); Debug(1, "Storage path: %s", storage->Path()); @@ -516,7 +516,7 @@ Monitor::Monitor( videoRecording = ((GetOptVideoWriter() == H264PASSTHROUGH) && camera->SupportsNativeVideo()); n_linked_monitors = 0; - linked_monitors = 0; + linked_monitors = nullptr; if ( purpose == ANALYSIS ) { while( @@ -588,12 +588,12 @@ bool Monitor::connect() { Debug(3, "MMap file size is %ld", map_stat.st_size); #ifdef MAP_LOCKED - mem_ptr = (unsigned char *)mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0); + mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0); if ( mem_ptr == MAP_FAILED ) { if ( errno == EAGAIN ) { Debug(1, "Unable to map file %s (%d bytes) to locked memory, trying unlocked", mem_file, mem_size); #endif - mem_ptr = (unsigned char *)mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0); + mem_ptr = (unsigned char *)mmap(nullptr, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0); Debug(1, "Mapped file %s (%d bytes) to unlocked memory", mem_file, mem_size); #ifdef MAP_LOCKED } else { @@ -603,7 +603,7 @@ bool Monitor::connect() { #endif if ( mem_ptr == MAP_FAILED ) Fatal("Can't map file %s (%d bytes) to memory: %s(%d)", mem_file, mem_size, strerror(errno), errno); - if ( mem_ptr == NULL ) { + if ( mem_ptr == nullptr ) { Error("mmap gave a NULL address:"); } else { Debug(3, "mmapped to %p", mem_ptr); @@ -670,19 +670,19 @@ Monitor::~Monitor() { delete linked_monitors[i]; } delete[] linked_monitors; - linked_monitors = 0; + linked_monitors = nullptr; } if ( timestamps ) { delete[] timestamps; - timestamps = 0; + timestamps = nullptr; } if ( images ) { delete[] images; - images = 0; + images = nullptr; } if ( privacy_bitmask ) { delete[] privacy_bitmask; - privacy_bitmask = NULL; + privacy_bitmask = nullptr; } if ( mem_ptr ) { if ( event ) { @@ -693,7 +693,7 @@ Monitor::~Monitor() { if ( event_delete_thread ) { event_delete_thread->join(); delete event_delete_thread; - event_delete_thread = NULL; + event_delete_thread = nullptr; } } @@ -776,9 +776,9 @@ void Monitor::AddZones( int p_n_zones, Zone *p_zones[] ) { void Monitor::AddPrivacyBitmask( Zone *p_zones[] ) { if ( privacy_bitmask ) { delete[] privacy_bitmask; - privacy_bitmask = NULL; + privacy_bitmask = nullptr; } - Image *privacy_image = NULL; + Image *privacy_image = nullptr; for ( int i = 0; i < n_zones; i++ ) { if ( p_zones[i]->IsPrivacy() ) { @@ -1139,7 +1139,7 @@ void Monitor::DumpZoneImage(const char *zone_string) { } } - Image *zone_image = NULL; + Image *zone_image = nullptr; if ( ( (!staticConfig.SERVER_ID) || ( staticConfig.SERVER_ID == server_id ) ) && mem_ptr ) { Debug(3, "Trying to load from local zmc"); int index = shared_data->last_write_index; @@ -1158,7 +1158,7 @@ void Monitor::DumpZoneImage(const char *zone_string) { stream->setStreamStart(event_id, (unsigned int)1); zone_image = stream->getImage(); delete stream; - stream = NULL; + stream = nullptr; } else { Error("Unable to load an event for monitor %d", id); return; @@ -1294,7 +1294,7 @@ bool Monitor::Analyse() { } struct timeval now; - gettimeofday(&now, NULL); + gettimeofday(&now, nullptr); if ( image_count && fps_report_interval && !(image_count%fps_report_interval) ) { if ( now.tv_sec != last_fps_time ) { @@ -1700,9 +1700,9 @@ bool Monitor::Analyse() { } // end foreach zone if ( state == PREALARM ) { - Event::AddPreAlarmFrame(snap_image, *timestamp, score, (got_anal_image?&alarm_image:NULL)); + Event::AddPreAlarmFrame(snap_image, *timestamp, score, (got_anal_image?&alarm_image:nullptr)); } else { - event->AddFrame(snap_image, *timestamp, score, (got_anal_image?&alarm_image:NULL)); + event->AddFrame(snap_image, *timestamp, score, (got_anal_image?&alarm_image:nullptr)); } } else { // Not doing alarm frame storage @@ -1848,8 +1848,8 @@ void Monitor::Reload() { min_section_length = atoi(dbrow[index++]); frame_skip = atoi(dbrow[index++]); motion_frame_skip = atoi(dbrow[index++]); - analysis_fps = dbrow[index] ? strtod(dbrow[index], NULL) : 0; index++; - analysis_update_delay = strtoul(dbrow[index++], NULL, 0); + analysis_fps = dbrow[index] ? strtod(dbrow[index], nullptr) : 0; index++; + analysis_update_delay = strtoul(dbrow[index++], nullptr, 0); capture_max_fps = dbrow[index] ? atof(dbrow[index]) : 0.0; index++; capture_delay = ( capture_max_fps > 0.0 ) ? int(DT_PREC_3/capture_max_fps) : 0; @@ -1882,7 +1882,7 @@ void Monitor::ReloadZones() { delete zones[i]; } delete[] zones; - zones = 0; + zones = nullptr; n_zones = Zone::Load(this, zones); //DumpZoneImage(); } // end void Monitor::ReloadZones() @@ -1894,7 +1894,7 @@ void Monitor::ReloadLinkedMonitors(const char *p_linked_monitors) { delete linked_monitors[i]; } delete[] linked_monitors; - linked_monitors = 0; + linked_monitors = nullptr; } n_linked_monitors = 0; @@ -2082,8 +2082,8 @@ Monitor *Monitor::Load(MYSQL_ROW dbrow, bool load_zones, Purpose purpose) { int enabled = dbrow[col] ? atoi(dbrow[col]) : 0; col++; const char *linked_monitors = dbrow[col];col++; - double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; - unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); + double analysis_fps = dbrow[col] ? strtod(dbrow[col], nullptr) : 0; col++; + unsigned int analysis_update_delay = strtoul(dbrow[col++], nullptr, 0); double capture_max_fps = dbrow[col] ? atof(dbrow[col]) : 0.0; col++; double capture_delay = ( capture_max_fps > 0.0 ) ? int(DT_PREC_3/capture_max_fps) : 0; @@ -2161,9 +2161,9 @@ Monitor *Monitor::Load(MYSQL_ROW dbrow, bool load_zones, Purpose purpose) { int track_motion = atoi(dbrow[col]); col++; bool embed_exif = (*dbrow[col] != '0'); col++; int signal_check_points = dbrow[col] ? atoi(dbrow[col]) : 0;col++; - int signal_check_color = strtol(dbrow[col][0] == '#' ? dbrow[col]+1 : dbrow[col], 0, 16); col++; + int signal_check_color = strtol(dbrow[col][0] == '#' ? dbrow[col]+1 : dbrow[col], nullptr, 16); col++; - Camera *camera = 0; + Camera *camera = nullptr; if ( type == "Local" ) { #if ZM_HAS_V4L @@ -2412,7 +2412,7 @@ Monitor *Monitor::Load(unsigned int p_id, bool load_zones, Purpose purpose) { zmDbRow dbrow; if ( ! dbrow.fetch(sql.c_str()) ) { Error("Can't use query result: %s", mysql_error(&dbconn)); - return NULL; + return nullptr; } Monitor *monitor = Monitor::Load(dbrow.mysql_row(), load_zones, purpose); @@ -2521,7 +2521,7 @@ int Monitor::Capture() { if ( (index == shared_data->last_read_index) && (function > MONITOR) ) { Warning("Buffer overrun at index %d, image %d, slow down capture, speed up analysis or increase ring buffer size", index, image_count ); - time_t now = time(0); + time_t now = time(nullptr); double approxFps = double(image_buffer_count)/double(now-image_buffer[index].timestamp->tv_sec); time_t last_read_delta = now - shared_data->last_read_time; if ( last_read_delta > (image_buffer_count/approxFps) ) { @@ -2534,7 +2534,7 @@ int Monitor::Capture() { capture_image->MaskPrivacy(privacy_bitmask); // Might be able to remove this call, when we start passing around ZMPackets, which will already have a timestamp - gettimeofday(image_buffer[index].timestamp, NULL); + gettimeofday(image_buffer[index].timestamp, nullptr); if ( config.timestamp_on_capture ) { TimestampImage(capture_image, image_buffer[index].timestamp); } @@ -2642,23 +2642,23 @@ bool Monitor::closeEvent() { if ( function == RECORD || function == MOCORD ) { //FIXME Is this neccessary? ENdTime should be set in the destructor - gettimeofday(&(event->EndTime()), NULL); + gettimeofday(&(event->EndTime()), nullptr); } if ( event_delete_thread ) { event_delete_thread->join(); delete event_delete_thread; - event_delete_thread = NULL; + event_delete_thread = nullptr; } #if 0 event_delete_thread = new std::thread([](Event *event) { Event * e = event; - event = NULL; + event = nullptr; delete e; - e = NULL; + e = nullptr; }, event); #else delete event; - event = NULL; + event = nullptr; #endif video_store_data->recording = (struct timeval){0}; return true; diff --git a/src/zm_monitor.h b/src/zm_monitor.h index 345a85862..e020ba391 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -88,6 +88,7 @@ public: } Orientation; typedef enum { + UNKNOWN, IDLE, PREALARM, ALARM, @@ -425,7 +426,7 @@ public: bool connect(); inline int ShmValid() const { - return shared_data->valid; + return shared_data && shared_data->valid; } inline unsigned int Id() const { diff --git a/src/zm_monitorstream.cpp b/src/zm_monitorstream.cpp index 57bb09c56..71a7a66d2 100644 --- a/src/zm_monitorstream.cpp +++ b/src/zm_monitorstream.cpp @@ -251,20 +251,29 @@ void MonitorStream::processCommand(const CmdMsg *msg) { } status_data; status_data.id = monitor->Id(); - status_data.fps = monitor->GetFPS(); - status_data.state = monitor->shared_data->state; - if ( playback_buffer > 0 ) - status_data.buffer_level = (MOD_ADD( (temp_write_index-temp_read_index), 0, temp_image_buffer_count )*100)/temp_image_buffer_count; - else + if ( ! monitor->ShmValid() ) { + status_data.fps = 0.0; + status_data.state = Monitor::UNKNOWN; + //status_data.enabled = monitor->shared_data->active; + status_data.enabled = false; + status_data.forced = false; status_data.buffer_level = 0; + } else { + status_data.fps = monitor->GetFPS(); + status_data.state = monitor->shared_data->state; + //status_data.enabled = monitor->shared_data->active; + status_data.enabled = monitor->trigger_data->trigger_state!=Monitor::TRIGGER_OFF; + status_data.forced = monitor->trigger_data->trigger_state==Monitor::TRIGGER_ON; + if ( playback_buffer > 0 ) + status_data.buffer_level = (MOD_ADD( (temp_write_index-temp_read_index), 0, temp_image_buffer_count )*100)/temp_image_buffer_count; + else + status_data.buffer_level = 0; + } status_data.delayed = delayed; status_data.paused = paused; status_data.rate = replay_rate; - status_data.delay = TV_2_FLOAT( now ) - TV_2_FLOAT( last_frame_timestamp ); + status_data.delay = TV_2_FLOAT(now) - TV_2_FLOAT(last_frame_timestamp); status_data.zoom = zoom; - //status_data.enabled = monitor->shared_data->active; - status_data.enabled = monitor->trigger_data->trigger_state!=Monitor::TRIGGER_OFF; - status_data.forced = monitor->trigger_data->trigger_state==Monitor::TRIGGER_ON; Debug(2, "Buffer Level:%d, Delayed:%d, Paused:%d, Rate:%d, delay:%.3f, Zoom:%d, Enabled:%d Forced:%d", status_data.buffer_level, status_data.delayed, @@ -291,12 +300,13 @@ void MonitorStream::processCommand(const CmdMsg *msg) { // quit after sending a status, if this was a quit request if ( (MsgCommand)msg->msg_data[0]==CMD_QUIT ) { - Debug(2,"Quitting"); - exit(0); + zm_terminate = true; + Debug(2, "Quitting"); + return; } - Debug(2,"Updating framerate"); - updateFrameRate(monitor->GetFPS()); + //Debug(2,"Updating framerate"); + //updateFrameRate(monitor->GetFPS()); } // end void MonitorStream::processCommand(const CmdMsg *msg) bool MonitorStream::sendFrame(const char *filepath, struct timeval *timestamp) { @@ -315,7 +325,7 @@ bool MonitorStream::sendFrame(const char *filepath, struct timeval *timestamp) { int img_buffer_size = 0; static unsigned char img_buffer[ZM_MAX_IMAGE_SIZE]; - FILE *fdj = NULL; + FILE *fdj = nullptr; if ( (fdj = fopen(filepath, "r")) ) { img_buffer_size = fread(img_buffer, 1, sizeof(img_buffer), fdj); fclose(fdj); @@ -326,7 +336,7 @@ bool MonitorStream::sendFrame(const char *filepath, struct timeval *timestamp) { // Calculate how long it takes to actually send the frame struct timeval frameStartTime; - gettimeofday(&frameStartTime, NULL); + gettimeofday(&frameStartTime, nullptr); if ( (0 > fprintf(stdout, "Content-Length: %d\r\nX-Timestamp: %d.%06d\r\n\r\n", @@ -342,7 +352,7 @@ bool MonitorStream::sendFrame(const char *filepath, struct timeval *timestamp) { fflush(stdout); struct timeval frameEndTime; - gettimeofday(&frameEndTime, NULL); + gettimeofday(&frameEndTime, nullptr); int frameSendTime = tvDiffMsec(frameStartTime, frameEndTime); if ( frameSendTime > 1000/maxfps ) { @@ -386,9 +396,8 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) { // Calculate how long it takes to actually send the frame struct timeval frameStartTime; - gettimeofday(&frameStartTime, NULL); + gettimeofday(&frameStartTime, nullptr); - fputs("--ZoneMinderFrame\r\n", stdout); switch ( type ) { case STREAM_JPEG : send_image->EncodeJpeg(img_buffer, &img_buffer_size); @@ -430,7 +439,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) { fflush(stdout); struct timeval frameEndTime; - gettimeofday(&frameEndTime, NULL); + gettimeofday(&frameEndTime, nullptr); int frameSendTime = tvDiffMsec(frameStartTime, frameEndTime); if ( frameSendTime > 1000/maxfps ) { @@ -452,16 +461,23 @@ void MonitorStream::runStream() { openComms(); + if ( type == STREAM_JPEG ) + fputs("Content-Type: multipart/x-mixed-replace; boundary=" BOUNDARY "\r\n\r\n", stdout); + if ( !checkInitialised() ) { Error("Not initialized"); - return; + while ( !(loadMonitor(monitor_id) || zm_terminate) ) { + sendTextFrame("Not connected"); + if ( connkey ) + checkCommandQueue(); + sleep(1); + } + if ( zm_terminate ) + return; } updateFrameRate(monitor->GetFPS()); - if ( type == STREAM_JPEG ) - fputs("Content-Type: multipart/x-mixed-replace; boundary=" BOUNDARY "\r\n\r\n", stdout); - // point to end which is theoretically not a valid value because all indexes are % image_buffer_count unsigned int last_read_index = monitor->image_buffer_count; @@ -470,7 +486,7 @@ void MonitorStream::runStream() { frame_count = 0; - temp_image_buffer = 0; + temp_image_buffer = nullptr; temp_image_buffer_count = playback_buffer; temp_read_index = temp_image_buffer_count; temp_write_index = temp_image_buffer_count; @@ -479,7 +495,7 @@ void MonitorStream::runStream() { bool buffered_playback = false; // Last image and timestamp when paused, will be resent occasionally to prevent timeout - Image *paused_image = NULL; + Image *paused_image = nullptr; struct timeval paused_timestamp; if ( connkey && ( playback_buffer > 0 ) ) { @@ -487,8 +503,8 @@ void MonitorStream::runStream() { const int max_swap_len_suffix = 15; int swap_path_length = staticConfig.PATH_SWAP.length() + 1; // +1 for NULL terminator - int subfolder1_length = snprintf(NULL, 0, "/zmswap-m%d", monitor->Id()) + 1; - int subfolder2_length = snprintf(NULL, 0, "/zmswap-q%06d", connkey) + 1; + int subfolder1_length = snprintf(nullptr, 0, "/zmswap-m%d", monitor->Id()) + 1; + int subfolder2_length = snprintf(nullptr, 0, "/zmswap-q%06d", connkey) + 1; int total_swap_path_length = swap_path_length + subfolder1_length + subfolder2_length; if ( total_swap_path_length + max_swap_len_suffix > PATH_MAX ) { @@ -545,7 +561,7 @@ void MonitorStream::runStream() { break; } - gettimeofday(&now, NULL); + gettimeofday(&now, nullptr); bool was_paused = paused; if ( connkey ) { @@ -571,7 +587,7 @@ void MonitorStream::runStream() { } else if ( paused_image ) { Debug(1, "Clearing paused_image"); delete paused_image; - paused_image = NULL; + paused_image = nullptr; } if ( buffered_playback && delayed ) { diff --git a/src/zm_monitorstream.h b/src/zm_monitorstream.h index cb502efc3..24655b636 100644 --- a/src/zm_monitorstream.h +++ b/src/zm_monitorstream.h @@ -59,7 +59,7 @@ class MonitorStream : public StreamBase { public: MonitorStream() : - temp_image_buffer(NULL), temp_image_buffer_count(0), temp_read_index(0), temp_write_index(0), + temp_image_buffer(nullptr), temp_image_buffer_count(0), temp_read_index(0), temp_write_index(0), ttl(0), playback_buffer(0), delayed(false), frame_count(0) { } void setStreamBuffer(int p_playback_buffer) { diff --git a/src/zm_mpeg.cpp b/src/zm_mpeg.cpp index c6b1ebc7d..225cdaa5e 100644 --- a/src/zm_mpeg.cpp +++ b/src/zm_mpeg.cpp @@ -46,9 +46,9 @@ void VideoStream::Initialise( ) { void VideoStream::SetupFormat( ) { /* allocate the output media context */ - ofc = NULL; + ofc = nullptr; #if (LIBAVFORMAT_VERSION_CHECK(53, 2, 0, 2, 0) && (LIBAVFORMAT_VERSION_MICRO >= 100)) - avformat_alloc_output_context2(&ofc, NULL, format, filename); + avformat_alloc_output_context2(&ofc, nullptr, format, filename); #else AVFormatContext *s = avformat_alloc_context(); if ( !s ) { @@ -59,18 +59,18 @@ void VideoStream::SetupFormat( ) { AVOutputFormat *oformat; if ( format ) { #if LIBAVFORMAT_VERSION_CHECK(52, 45, 0, 45, 0) - oformat = av_guess_format(format, NULL, NULL); + oformat = av_guess_format(format, nullptr, nullptr); #else - oformat = guess_format(format, NULL, NULL); + oformat = guess_format(format, nullptr, nullptr); #endif if ( !oformat ) { Fatal("Requested output format '%s' is not a suitable output format", format); } } else { #if LIBAVFORMAT_VERSION_CHECK(52, 45, 0, 45, 0) - oformat = av_guess_format(NULL, filename, NULL); + oformat = av_guess_format(nullptr, filename, nullptr); #else - oformat = guess_format(NULL, filename, NULL); + oformat = guess_format(nullptr, filename, nullptr); #endif if ( !oformat ) { Fatal("Unable to find a suitable output format for '%s'", format); @@ -91,7 +91,7 @@ void VideoStream::SetupFormat( ) { #endif } else { Debug(1, "No allocating priv_data"); - s->priv_data = NULL; + s->priv_data = nullptr; } if ( filename ) { @@ -172,7 +172,7 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei /* add the video streams using the default format codecs and initialize the codecs */ - ost = NULL; + ost = nullptr; if ( codec_id != AV_CODEC_ID_NONE ) { codec = avcodec_find_encoder(codec_id); if ( !codec ) { @@ -204,7 +204,7 @@ void VideoStream::SetupCodec( int colours, int subpixelorder, int width, int hei #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) - codec_context = avcodec_alloc_context3(NULL); + codec_context = avcodec_alloc_context3(nullptr); //avcodec_parameters_to_context(codec_context, ost->codecpar); #else codec_context = ost->codec; @@ -296,7 +296,7 @@ bool VideoStream::OpenStream( ) { #if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0) if ( (ret = avcodec_open(codec_context, codec)) < 0 ) #else - if ( (ret = avcodec_open2(codec_context, codec, 0)) < 0 ) + if ( (ret = avcodec_open2(codec_context, codec, nullptr)) < 0 ) #endif { Error("Could not open codec. Error code %d \"%s\"", ret, av_err2str(ret)); @@ -338,7 +338,7 @@ bool VideoStream::OpenStream( ) { /* if the output format is not identical to the input format, then a temporary picture is needed too. It is then converted to the required output format */ - tmp_opicture = NULL; + tmp_opicture = nullptr; if ( codec_context->pix_fmt != pf ) { #if LIBAVCODEC_VERSION_CHECK(55, 28, 1, 45, 101) tmp_opicture = av_frame_alloc( ); @@ -374,7 +374,7 @@ bool VideoStream::OpenStream( ) { /* open the output file, if needed */ if ( !(of->flags & AVFMT_NOFILE) ) { #if LIBAVFORMAT_VERSION_CHECK(53, 15, 0, 21, 0) - ret = avio_open2( &ofc->pb, filename, AVIO_FLAG_WRITE, NULL, NULL ); + ret = avio_open2( &ofc->pb, filename, AVIO_FLAG_WRITE, nullptr, nullptr ); #elif LIBAVFORMAT_VERSION_CHECK(52, 102, 0, 102, 0) ret = avio_open( &ofc->pb, filename, AVIO_FLAG_WRITE ); #else @@ -391,7 +391,7 @@ bool VideoStream::OpenStream( ) { return false; } - video_outbuf = NULL; + video_outbuf = nullptr; #if LIBAVFORMAT_VERSION_CHECK(57, 0, 0, 0, 0) if (codec_context->codec_type == AVMEDIA_TYPE_VIDEO && codec_context->codec_id == AV_CODEC_ID_RAWVIDEO) { @@ -403,7 +403,7 @@ bool VideoStream::OpenStream( ) { // TODO: Make buffer dynamic. video_outbuf_size = 4000000; video_outbuf = (uint8_t *)malloc( video_outbuf_size ); - if ( video_outbuf == NULL ) { + if ( video_outbuf == nullptr ) { Fatal("Unable to malloc memory for outbuf"); } } @@ -417,7 +417,7 @@ bool VideoStream::OpenStream( ) { #if !LIBAVFORMAT_VERSION_CHECK(53, 2, 0, 4, 0) ret = av_write_header(ofc); #else - ret = avformat_write_header(ofc, NULL); + ret = avformat_write_header(ofc, nullptr); #endif if ( ret < 0 ) { @@ -430,16 +430,16 @@ bool VideoStream::OpenStream( ) { VideoStream::VideoStream( const char *in_filename, const char *in_format, int bitrate, double frame_rate, int colours, int subpixelorder, int width, int height ) : filename(in_filename), format(in_format), - opicture(NULL), - tmp_opicture(NULL), - video_outbuf(NULL), + opicture(nullptr), + tmp_opicture(nullptr), + video_outbuf(nullptr), video_outbuf_size(0), last_pts( -1 ), streaming_thread(0), do_streaming(true), add_timestamp(false), timestamp(0), - buffer_copy(NULL), + buffer_copy(nullptr), buffer_copy_lock(new pthread_mutex_t), buffer_copy_size(0), buffer_copy_used(0), @@ -454,15 +454,15 @@ VideoStream::VideoStream( const char *in_filename, const char *in_format, int bi codec_and_format = new char[length+1];; strcpy( codec_and_format, format ); format = codec_and_format; - codec_name = NULL; + codec_name = nullptr; char *f = strchr(codec_and_format, '/'); - if (f != NULL) { + if (f != nullptr) { *f = 0; codec_name = f+1; } } - codec_context = NULL; + codec_context = nullptr; SetupFormat( ); SetupCodec( colours, subpixelorder, width, height, bitrate, frame_rate ); SetParameters( ); @@ -474,7 +474,7 @@ VideoStream::VideoStream( const char *in_filename, const char *in_format, int bi packet_index = 0; // Initialize mutex used by streaming thread. - if ( pthread_mutex_init( buffer_copy_lock, NULL ) != 0 ) { + if ( pthread_mutex_init( buffer_copy_lock, nullptr ) != 0 ) { Fatal("pthread_mutex_init failed"); } @@ -494,7 +494,7 @@ VideoStream::~VideoStream( ) { pthread_join(streaming_thread, &thread_exit_code); } - if ( buffer_copy != NULL ) { + if ( buffer_copy != nullptr ) { av_free( buffer_copy ); } @@ -582,7 +582,7 @@ double VideoStream::EncodeFrame( const uint8_t *buffer, int buffer_size, bool _a Debug( 1, "Starting streaming thread" ); // Start a thread for streaming encoded video. - if (pthread_create( &streaming_thread, NULL, StreamingThreadCallback, (void*) this) != 0){ + if (pthread_create( &streaming_thread, nullptr, StreamingThreadCallback, (void*) this) != 0){ // Log a fatal error and exit the process. Fatal( "VideoStream failed to create streaming thread." ); } @@ -597,12 +597,12 @@ double VideoStream::ActuallyEncodeFrame( const uint8_t *buffer, int buffer_size, if ( codec_context->pix_fmt != pf ) { #ifdef HAVE_LIBSWSCALE - static struct SwsContext *img_convert_ctx = 0; + static struct SwsContext *img_convert_ctx = nullptr; #endif // HAVE_LIBSWSCALE memcpy( tmp_opicture->data[0], buffer, buffer_size ); #ifdef HAVE_LIBSWSCALE if ( !img_convert_ctx ) { - img_convert_ctx = sws_getCachedContext( NULL, codec_context->width, codec_context->height, pf, codec_context->width, codec_context->height, codec_context->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL ); + img_convert_ctx = sws_getCachedContext( nullptr, codec_context->width, codec_context->height, pf, codec_context->width, codec_context->height, codec_context->pix_fmt, SWS_BICUBIC, nullptr, nullptr, nullptr ); if ( !img_convert_ctx ) Panic( "Unable to initialise image scaling context" ); } @@ -659,7 +659,7 @@ double VideoStream::ActuallyEncodeFrame( const uint8_t *buffer, int buffer_size, #else int out_size = avcodec_encode_video( codec_context, video_outbuf, video_outbuf_size, opicture_ptr ); got_packet = out_size > 0 ? 1 : 0; - pkt->data = got_packet ? video_outbuf : NULL; + pkt->data = got_packet ? video_outbuf : nullptr; pkt->size = got_packet ? out_size : 0; #endif #endif @@ -705,7 +705,7 @@ void *VideoStream::StreamingThreadCallback(void *ctx){ Debug( 1, "StreamingThreadCallback started" ); - if (ctx == NULL) return NULL; + if (ctx == nullptr) return nullptr; VideoStream* videoStream = reinterpret_cast(ctx); @@ -765,7 +765,7 @@ void *VideoStream::StreamingThreadCallback(void *ctx){ frame_count++; } - return 0; + return nullptr; } #endif // HAVE_LIBAVCODEC diff --git a/src/zm_packet.cpp b/src/zm_packet.cpp index a04282d26..36407ba21 100644 --- a/src/zm_packet.cpp +++ b/src/zm_packet.cpp @@ -25,18 +25,18 @@ using namespace std; ZMPacket::ZMPacket( AVPacket *p ) { - frame = NULL; - image = NULL; + frame = nullptr; + image = nullptr; av_init_packet( &packet ); if ( zm_av_packet_ref( &packet, p ) < 0 ) { Error("error refing packet"); } - gettimeofday( ×tamp, NULL ); + gettimeofday( ×tamp, nullptr ); } ZMPacket::ZMPacket( AVPacket *p, struct timeval *t ) { - frame = NULL; - image = NULL; + frame = nullptr; + image = nullptr; av_init_packet( &packet ); if ( zm_av_packet_ref( &packet, p ) < 0 ) { Error("error refing packet"); diff --git a/src/zm_packetqueue.cpp b/src/zm_packetqueue.cpp index e3ffb8c9a..7dbe31bd7 100644 --- a/src/zm_packetqueue.cpp +++ b/src/zm_packetqueue.cpp @@ -32,7 +32,7 @@ zm_packetqueue::zm_packetqueue( int p_max_stream_id ) { zm_packetqueue::~zm_packetqueue() { clearQueue(); delete[] packet_counts; - packet_counts = NULL; + packet_counts = nullptr; } bool zm_packetqueue::queuePacket(ZMPacket* zm_packet) { @@ -116,7 +116,7 @@ bool zm_packetqueue::queuePacket(AVPacket* av_packet) { ZMPacket* zm_packetqueue::popPacket( ) { if ( pktQueue.empty() ) { - return NULL; + return nullptr; } ZMPacket *packet = pktQueue.front(); @@ -137,7 +137,7 @@ unsigned int zm_packetqueue::clearQueue(unsigned int frames_to_keep, int stream_ } std::list::reverse_iterator it; - ZMPacket *packet = NULL; + ZMPacket *packet = nullptr; for ( it = pktQueue.rbegin(); it != pktQueue.rend() && frames_to_keep; ++it ) { ZMPacket *zm_packet = *it; @@ -186,13 +186,13 @@ unsigned int zm_packetqueue::clearQueue(unsigned int frames_to_keep, int stream_ delete_count += 1; } - packet = NULL; // tidy up for valgrind + packet = nullptr; // tidy up for valgrind Debug(3, "Deleted %d packets, %d remaining", delete_count, pktQueue.size()); return delete_count; } // end unsigned int zm_packetqueue::clearQueue( unsigned int frames_to_keep, int stream_id ) void zm_packetqueue::clearQueue() { - ZMPacket *packet = NULL; + ZMPacket *packet = nullptr; int delete_count = 0; while ( !pktQueue.empty() ) { packet = pktQueue.front(); @@ -256,7 +256,7 @@ unsigned int zm_packetqueue::clearQueue(struct timeval *duration, int streamId) } unsigned int deleted_frames = 0; - ZMPacket *zm_packet = NULL; + ZMPacket *zm_packet = nullptr; while (distance(it, pktQueue.rend()) > 1) { zm_packet = pktQueue.front(); pktQueue.pop_front(); @@ -264,7 +264,7 @@ unsigned int zm_packetqueue::clearQueue(struct timeval *duration, int streamId) delete zm_packet; deleted_frames += 1; } - zm_packet = NULL; + zm_packet = nullptr; Debug(3, "Deleted %d frames", deleted_frames); return deleted_frames; @@ -366,7 +366,7 @@ void zm_packetqueue::clear_unwanted_packets( pktQueue.size() ); unsigned int deleted_frames = 0; - ZMPacket *packet = NULL; + ZMPacket *packet = nullptr; while ( distance(it, pktQueue.rend()) > 1 ) { //while ( pktQueue.rend() != it ) { packet = pktQueue.front(); @@ -375,7 +375,7 @@ void zm_packetqueue::clear_unwanted_packets( delete packet; deleted_frames += 1; } - packet = NULL; // tidy up for valgrind + packet = nullptr; // tidy up for valgrind zm_packet = pktQueue.front(); av_packet = &(zm_packet->packet); diff --git a/src/zm_poly.h b/src/zm_poly.h index be039ef3e..53eafcf84 100644 --- a/src/zm_poly.h +++ b/src/zm_poly.h @@ -61,7 +61,7 @@ protected: min_x = 0; max_x = 0; n_edges = 0; - edges = 0; + edges = nullptr; } ~Slice() { delete edges; @@ -83,7 +83,7 @@ protected: void calcCentre(); public: - inline Polygon() : n_coords(0), coords(0), area(0), edges(0), slices(0) { + inline Polygon() : n_coords(0), coords(nullptr), area(0), edges(nullptr), slices(nullptr) { } Polygon(int p_n_coords, const Coord *p_coords); Polygon(const Polygon &p_polygon); diff --git a/src/zm_regexp.cpp b/src/zm_regexp.cpp index 90c000028..fa3bc2de7 100644 --- a/src/zm_regexp.cpp +++ b/src/zm_regexp.cpp @@ -24,7 +24,7 @@ #if HAVE_LIBPCRE -RegExpr::RegExpr( const char *pattern, int flags, int p_max_matches ) : max_matches( p_max_matches ), match_buffers( 0 ), match_lengths( 0 ), match_valid( 0 ) +RegExpr::RegExpr( const char *pattern, int flags, int p_max_matches ) : max_matches( p_max_matches ), match_buffers( nullptr ), match_lengths( nullptr ), match_valid( nullptr ) { const char *errstr; int erroffset = 0; @@ -50,7 +50,7 @@ RegExpr::RegExpr( const char *pattern, int flags, int p_max_matches ) : max_matc match_valid = new bool[max_matches]; memset( match_valid, 0, sizeof(*match_valid)*max_matches ); } else { - match_vectors = NULL; + match_vectors = nullptr; } match_string = ""; n_matches = 0; diff --git a/src/zm_remote_camera.cpp b/src/zm_remote_camera.cpp index d80532d54..dce4daf5c 100644 --- a/src/zm_remote_camera.cpp +++ b/src/zm_remote_camera.cpp @@ -44,20 +44,20 @@ RemoteCamera::RemoteCamera( path( p_path ), hp( 0 ), mNeedAuth(false), - mAuthenticator(NULL) + mAuthenticator(nullptr) { if ( path[0] != '/' ) path = '/'+path; } RemoteCamera::~RemoteCamera() { - if ( hp != NULL ) { + if ( hp != nullptr ) { freeaddrinfo(hp); - hp = NULL; + hp = nullptr; } if ( mAuthenticator ) { delete mAuthenticator; - mAuthenticator = NULL; + mAuthenticator = nullptr; } } @@ -99,9 +99,9 @@ void RemoteCamera::Initialise() { if ( ret != 0 ) { Fatal( "Can't getaddrinfo(%s port %s): %s", host.c_str(), port.c_str(), gai_strerror(ret) ); } - struct addrinfo *p = NULL; + struct addrinfo *p = nullptr; int addr_count = 0; - for ( p = hp; p != NULL; p = p->ai_next ) { + for ( p = hp; p != nullptr; p = p->ai_next ) { addr_count++; } Debug(1, "%d addresses returned", addr_count); diff --git a/src/zm_remote_camera_http.cpp b/src/zm_remote_camera_http.cpp index 35ba5b58c..50c19cc44 100644 --- a/src/zm_remote_camera_http.cpp +++ b/src/zm_remote_camera_http.cpp @@ -36,11 +36,11 @@ #endif #if HAVE_LIBPCRE -static RegExpr *header_expr = 0; -static RegExpr *status_expr = 0; -static RegExpr *connection_expr = 0; -static RegExpr *content_length_expr = 0; -static RegExpr *content_type_expr = 0; +static RegExpr *header_expr = nullptr; +static RegExpr *status_expr = nullptr; +static RegExpr *connection_expr = nullptr; +static RegExpr *content_length_expr = nullptr; +static RegExpr *content_type_expr = nullptr; #endif RemoteCameraHttp::RemoteCameraHttp( @@ -140,9 +140,9 @@ void RemoteCameraHttp::Initialise() { } // end void RemoteCameraHttp::Initialise() int RemoteCameraHttp::Connect() { - struct addrinfo *p = NULL; + struct addrinfo *p = nullptr; - for ( p = hp; p != NULL; p = p->ai_next ) { + for ( p = hp; p != nullptr; p = p->ai_next ) { sd = socket( p->ai_family, p->ai_socktype, p->ai_protocol ); if ( sd < 0 ) { Warning("Can't create socket: %s", strerror(errno) ); @@ -165,7 +165,7 @@ int RemoteCameraHttp::Connect() { break; } - if ( p == NULL ) { + if ( p == nullptr ) { Error("Unable to connect to the remote camera, aborting"); return -1; } @@ -207,7 +207,7 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, unsigned int bytes_expected ) { struct timeval temp_timeout = timeout; - int n_found = select(sd+1, &rfds, NULL, NULL, &temp_timeout); + int n_found = select(sd+1, &rfds, nullptr, nullptr, &temp_timeout); if( n_found == 0 ) { Debug( 1, "Select timed out timeout was %d secs %d usecs", temp_timeout.tv_sec, temp_timeout.tv_usec ); int error = 0; @@ -293,10 +293,10 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, unsigned int bytes_expected ) { } int RemoteCameraHttp::GetData() { - time_t start_time = time(NULL); + time_t start_time = time(nullptr); int buffer_len = 0; while ( !( buffer_len = ReadData(buffer) ) ) { - if ( zm_terminate || ( start_time - time(NULL) < ZM_WATCH_MAX_DELAY )) + if ( zm_terminate || ( start_time - time(nullptr) < ZM_WATCH_MAX_DELAY )) return -1; Debug(4, "Timeout waiting for REGEXP HEADER"); usleep(100000); @@ -308,16 +308,16 @@ int RemoteCameraHttp::GetResponse() { int buffer_len; #if HAVE_LIBPCRE if ( method == REGEXP ) { - const char *header = 0; + const char *header = nullptr; int header_len = 0; - const char *http_version = 0; + const char *http_version = nullptr; int status_code = 0; - const char *status_mesg = 0; + const char *status_mesg = nullptr; const char *connection_type = ""; int content_length = 0; const char *content_type = ""; const char *content_boundary = ""; - const char *subheader = 0; + const char *subheader = nullptr; int subheader_len = 0; //int subcontent_length = 0; //const char *subcontent_type = ""; @@ -450,9 +450,9 @@ int RemoteCameraHttp::GetResponse() { } case SUBHEADER : { - static RegExpr *subheader_expr = 0; - static RegExpr *subcontent_length_expr = 0; - static RegExpr *subcontent_type_expr = 0; + static RegExpr *subheader_expr = nullptr; + static RegExpr *subcontent_length_expr = nullptr; + static RegExpr *subcontent_type_expr = nullptr; if ( !subheader_expr ) { @@ -641,11 +641,11 @@ int RemoteCameraHttp::GetResponse() { case HEADER : { n_headers = 0; - http_header = 0; - connection_header = 0; - content_length_header = 0; - content_type_header = 0; - authenticate_header = 0; + http_header = nullptr; + connection_header = nullptr; + content_length_header = nullptr; + content_type_header = nullptr; + authenticate_header = nullptr; http_version[0] = '\0'; status_code [0]= '\0'; @@ -665,7 +665,7 @@ int RemoteCameraHttp::GetResponse() { } bytes += buffer_len; - char *crlf = 0; + char *crlf = nullptr; char *header_ptr = (char *)buffer; int header_len = buffer.size(); bool all_headers = false; @@ -870,7 +870,7 @@ int RemoteCameraHttp::GetResponse() { } case SUBHEADERCONT : { - char *crlf = 0; + char *crlf = nullptr; char *subheader_ptr = (char *)buffer; int subheader_len = buffer.size(); bool all_headers = false; diff --git a/src/zm_remote_camera_rtsp.cpp b/src/zm_remote_camera_rtsp.cpp index b011c742d..98b0e3030 100644 --- a/src/zm_remote_camera_rtsp.cpp +++ b/src/zm_remote_camera_rtsp.cpp @@ -64,18 +64,18 @@ RemoteCameraRtsp::RemoteCameraRtsp( Initialise(); } - mFormatContext = NULL; + mFormatContext = nullptr; mVideoStreamId = -1; mAudioStreamId = -1; - mCodecContext = NULL; - mCodec = NULL; - mRawFrame = NULL; - mFrame = NULL; + mCodecContext = nullptr; + mCodec = nullptr; + mRawFrame = nullptr; + mFrame = nullptr; frameCount = 0; startTime=0; #if HAVE_LIBSWSCALE - mConvertContext = NULL; + mConvertContext = nullptr; #endif /* Has to be located inside the constructor so other components such as zma will receive correct colours and subpixel order */ if ( colours == ZM_COLOUR_RGB32 ) { @@ -99,13 +99,13 @@ RemoteCameraRtsp::~RemoteCameraRtsp() { #if HAVE_LIBSWSCALE if ( mConvertContext ) { sws_freeContext(mConvertContext); - mConvertContext = NULL; + mConvertContext = nullptr; } #endif if ( mCodecContext ) { avcodec_close(mCodecContext); - mCodecContext = NULL; // Freed by avformat_free_context in the destructor of RtspThread class + mCodecContext = nullptr; // Freed by avformat_free_context in the destructor of RtspThread class } if ( capture ) { @@ -144,7 +144,7 @@ int RemoteCameraRtsp::Disconnect() { rtspThread->stop(); rtspThread->join(); delete rtspThread; - rtspThread = 0; + rtspThread = nullptr; } return 0; } @@ -197,7 +197,7 @@ int RemoteCameraRtsp::PrimeCapture() { // Find the decoder for the video stream mCodec = avcodec_find_decoder(mCodecContext->codec_id); - if ( mCodec == NULL ) + if ( mCodec == nullptr ) Panic("Unable to locate codec %d decoder", mCodecContext->codec_id); // Open codec @@ -214,7 +214,7 @@ int RemoteCameraRtsp::PrimeCapture() { // Allocate space for the converted video frame mFrame = zm_av_frame_alloc(); - if ( mRawFrame == NULL || mFrame == NULL ) + if ( mRawFrame == nullptr || mFrame == nullptr ) Fatal("Unable to allocate frame(s)"); #if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) @@ -261,7 +261,7 @@ int RemoteCameraRtsp::Capture( Image &image ) { /* Request a writeable buffer of the target image */ directbuffer = image.WriteBuffer(width, height, colours, subpixelorder); - if ( directbuffer == NULL ) { + if ( directbuffer == nullptr ) { Error("Failed requesting writeable buffer for the captured image."); return -1; } @@ -343,12 +343,12 @@ int RemoteCameraRtsp::Capture( Image &image ) { #endif #if HAVE_LIBSWSCALE - if ( mConvertContext == NULL ) { + if ( mConvertContext == nullptr ) { mConvertContext = sws_getContext( mCodecContext->width, mCodecContext->height, mCodecContext->pix_fmt, - width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL); + width, height, imagePixFormat, SWS_BICUBIC, nullptr, nullptr, nullptr); - if ( mConvertContext == NULL ) + if ( mConvertContext == nullptr ) Fatal("Unable to create conversion context"); if ( diff --git a/src/zm_rtp_ctrl.cpp b/src/zm_rtp_ctrl.cpp index bc6725c5d..2ffc0c404 100644 --- a/src/zm_rtp_ctrl.cpp +++ b/src/zm_rtp_ctrl.cpp @@ -272,12 +272,12 @@ int RtpCtrlThread::run() { unsigned char buffer[ZM_NETWORK_BUFSIZ]; - time_t last_receive = time(NULL); + time_t last_receive = time(nullptr); bool timeout = false; // used as a flag that we had a timeout, and then sent an RR to see if we wake back up. Real timeout will happen when this is true. while ( !mStop && select.wait() >= 0 ) { - time_t now = time(NULL); + time_t now = time(nullptr); Select::CommsList readable = select.getReadable(); if ( readable.size() == 0 ) { if ( ! timeout ) { @@ -300,7 +300,7 @@ int RtpCtrlThread::run() { } } else { timeout = false; - last_receive = time(NULL); + last_receive = time(nullptr); } for ( Select::CommsList::iterator iter = readable.begin(); iter != readable.end(); ++iter ) { if ( UdpInetSocket *socket = dynamic_cast(*iter) ) { diff --git a/src/zm_rtsp.cpp b/src/zm_rtsp.cpp index 59d8ab171..53452bb94 100644 --- a/src/zm_rtsp.cpp +++ b/src/zm_rtsp.cpp @@ -198,14 +198,14 @@ RtspThread::~RtspThread() { #else av_free_format_context(mFormatContext); #endif - mFormatContext = NULL; + mFormatContext = nullptr; } if ( mSessDesc ) { delete mSessDesc; - mSessDesc = NULL; + mSessDesc = nullptr; } delete mAuthenticator; - mAuthenticator = NULL; + mAuthenticator = nullptr; } int RtspThread::run() { @@ -387,7 +387,7 @@ int RtspThread::run() { if ( !mAuth.empty() ) authUrl.insert( authUrl.find( "://" )+3, mAuth+"@" ); - if ( av_open_input_file( &mFormatContext, authUrl.c_str(), NULL, 0, NULL ) != 0 ) + if ( av_open_input_file( &mFormatContext, authUrl.c_str(), nullptr, 0, nullptr ) != 0 ) { Error( "Unable to open input '%s'", authUrl.c_str() ); return( -1 ); @@ -499,26 +499,26 @@ int RtspThread::run() { method = "RTP/UNICAST"; StringVector subparts = split( parts[i], "=" ); StringVector ports = split( subparts[1], "-" ); - remotePorts[0] = strtol( ports[0].c_str(), NULL, 10 ); - remotePorts[1] = strtol( ports[1].c_str(), NULL, 10 ); + remotePorts[0] = strtol( ports[0].c_str(), nullptr, 10 ); + remotePorts[1] = strtol( ports[1].c_str(), nullptr, 10 ); } else if ( startsWith( parts[i], "interleaved=" ) ) { method = "RTP/RTSP"; StringVector subparts = split( parts[i], "=" ); StringVector channels = split( subparts[1], "-" ); - remoteChannels[0] = strtol( channels[0].c_str(), NULL, 10 ); - remoteChannels[1] = strtol( channels[1].c_str(), NULL, 10 ); + remoteChannels[0] = strtol( channels[0].c_str(), nullptr, 10 ); + remoteChannels[1] = strtol( channels[1].c_str(), nullptr, 10 ); } else if ( startsWith( parts[i], "port=" ) ) { method = "RTP/MULTICAST"; StringVector subparts = split( parts[i], "=" ); StringVector ports = split( subparts[1], "-" ); - localPorts[0] = strtol( ports[0].c_str(), NULL, 10 ); - localPorts[1] = strtol( ports[1].c_str(), NULL, 10 ); + localPorts[0] = strtol( ports[0].c_str(), nullptr, 10 ); + localPorts[1] = strtol( ports[1].c_str(), nullptr, 10 ); } else if ( startsWith( parts[i], "destination=" ) ) { StringVector subparts = split( parts[i], "=" ); localHost = subparts[1]; } else if ( startsWith( parts[i], "ssrc=" ) ) { StringVector subparts = split( parts[i], "=" ); - ssrc = strtoll( subparts[1].c_str(), NULL, 16 ); + ssrc = strtoll( subparts[1].c_str(), nullptr, 16 ); } } @@ -568,10 +568,10 @@ int RtspThread::run() { for ( size_t j = 0; j < parts.size(); j++ ) { if ( startsWith( parts[j], "seq=" ) ) { StringVector subparts = split( parts[j], "=" ); - seq = strtol( subparts[1].c_str(), NULL, 10 ); + seq = strtol( subparts[1].c_str(), nullptr, 10 ); } else if ( startsWith( parts[j], "rtptime=" ) ) { StringVector subparts = split( parts[j], "=" ); - rtpTime = strtol( subparts[1].c_str(), NULL, 10 ); + rtpTime = strtol( subparts[1].c_str(), nullptr, 10 ); } } break; @@ -582,7 +582,7 @@ int RtspThread::run() { Debug( 2, "RTSP Seq is %d", seq ); Debug( 2, "RTSP Rtptime is %ld", rtpTime ); - time_t lastKeepalive = time(NULL); + time_t lastKeepalive = time(nullptr); time_t now; message = "GET_PARAMETER "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; @@ -598,7 +598,7 @@ int RtspThread::run() { rtpCtrlThread.start(); while( !mStop ) { - now = time(NULL); + now = time(nullptr); // Send a keepalive message if the server supports this feature and we are close to the timeout expiration Debug(5, "sendkeepalive %d, timeout %d, now: %d last: %d since: %d", sendKeepalive, timeout, now, lastKeepalive, (now-lastKeepalive) ); @@ -721,7 +721,7 @@ int RtspThread::run() { } // Send a keepalive message if the server supports this feature and we are close to the timeout expiration // FIXME: Is this really necessary when using tcp ? - now = time(NULL); + now = time(nullptr); // Send a keepalive message if the server supports this feature and we are close to the timeout expiration Debug(5, "sendkeepalive %d, timeout %d, now: %d last: %d since: %d", sendKeepalive, timeout, now, lastKeepalive, (now-lastKeepalive) ); if ( sendKeepalive && (timeout > 0) && ((now-lastKeepalive) > (timeout-5)) ) @@ -761,10 +761,10 @@ Debug(5, "sendkeepalive %d, timeout %d, now: %d last: %d since: %d", sendKeepali while ( !mStop ) { // Send a keepalive message if the server supports this feature and we are close to the timeout expiration - if ( sendKeepalive && (timeout > 0) && ((time(NULL)-lastKeepalive) > (timeout-5)) ) { + if ( sendKeepalive && (timeout > 0) && ((time(nullptr)-lastKeepalive) > (timeout-5)) ) { if ( !sendCommand( message ) ) return -1; - lastKeepalive = time(NULL); + lastKeepalive = time(nullptr); } usleep(100000); } diff --git a/src/zm_sdp.cpp b/src/zm_sdp.cpp index 15f6ad5e3..de48e169d 100644 --- a/src/zm_sdp.cpp +++ b/src/zm_sdp.cpp @@ -152,16 +152,16 @@ SessionDescriptor::MediaDescriptor::MediaDescriptor( mWidth( 0 ), mHeight( 0 ), mSprops( "" ), - mConnInfo( 0 ) + mConnInfo( nullptr ) { } SessionDescriptor::SessionDescriptor( const std::string &url, const std::string &sdp ) : mUrl( url ), - mConnInfo( 0 ), - mBandInfo( 0 ) + mConnInfo( nullptr ), + mBandInfo( nullptr ) { - MediaDescriptor *currMedia = 0; + MediaDescriptor *currMedia = nullptr; StringVector lines = split( sdp, "\r\n" ); for ( StringVector::const_iterator iter = lines.begin(); iter != lines.end(); ++iter ) { @@ -344,12 +344,12 @@ AVFormatContext *SessionDescriptor::generateFormatContext() const { #if !LIBAVFORMAT_VERSION_CHECK(53, 10, 0, 17, 0) AVStream *stream = av_new_stream(formatContext, i); #else - AVStream *stream = avformat_new_stream(formatContext, NULL); + AVStream *stream = avformat_new_stream(formatContext, nullptr); stream->id = i; #endif #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) - AVCodecContext *codec_context = avcodec_alloc_context3(NULL); + AVCodecContext *codec_context = avcodec_alloc_context3(nullptr); avcodec_parameters_to_context(codec_context, stream->codecpar); stream->codec = codec_context; #else @@ -434,7 +434,7 @@ AVFormatContext *SessionDescriptor::generateFormatContext() const { if ( codec_context->codec_id == AV_CODEC_ID_H264 && mediaDesc->getSprops().size()) { uint8_t start_sequence[]= { 0, 0, 1 }; codec_context->extradata_size= 0; - codec_context->extradata= NULL; + codec_context->extradata= nullptr; char pvalue[1024], *value = pvalue; strcpy(pvalue, mediaDesc->getSprops().c_str()); diff --git a/src/zm_sdp.h b/src/zm_sdp.h index ae7cd67a2..403c8a740 100644 --- a/src/zm_sdp.h +++ b/src/zm_sdp.h @@ -211,7 +211,7 @@ public: MediaDescriptor *getStream( int index ) { if ( index < 0 || (unsigned int)index >= mMediaList.size() ) - return( 0 ); + return nullptr; return( mMediaList[index] ); } diff --git a/src/zm_sendfile.h b/src/zm_sendfile.h index 2f892d693..d9a4ca05f 100644 --- a/src/zm_sendfile.h +++ b/src/zm_sendfile.h @@ -22,7 +22,7 @@ int zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) { #include int zm_sendfile(int out_fd, int in_fd, off_t *offset, off_t size) { int err; - err = sendfile(in_fd, out_fd, *offset, size, NULL, &size, 0); + err = sendfile(in_fd, out_fd, *offset, size, nullptr, &size, 0); if (err && errno != EAGAIN) return -errno; diff --git a/src/zm_signal.cpp b/src/zm_signal.cpp index e13bfdc9c..81012c07e 100644 --- a/src/zm_signal.cpp +++ b/src/zm_signal.cpp @@ -53,8 +53,8 @@ RETSIGTYPE zm_die_handler(int signal) #if (defined(__i386__) || defined(__x86_64__)) // Get more information if available #if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) - void *ip = 0; - void *cr2 = 0; + void *ip = nullptr; + void *cr2 = nullptr; if (info && context) { Debug(1, diff --git a/src/zm_stream.cpp b/src/zm_stream.cpp index 258e04d52..05236c3ba 100644 --- a/src/zm_stream.cpp +++ b/src/zm_stream.cpp @@ -33,13 +33,21 @@ StreamBase::~StreamBase() { #if HAVE_LIBAVCODEC if ( vid_stream ) { delete vid_stream; - vid_stream = NULL; + vid_stream = nullptr; } #endif closeComms(); + if ( monitor ) { + delete monitor; + monitor = NULL; + } } -bool StreamBase::loadMonitor(int monitor_id) { +bool StreamBase::loadMonitor(int p_monitor_id) { + monitor_id = p_monitor_id; + if ( monitor ) + delete monitor; + if ( !(monitor = Monitor::Load(monitor_id, false, Monitor::QUERY)) ) { Error("Unable to load monitor id %d for streaming", monitor_id); return false; @@ -59,7 +67,15 @@ bool StreamBase::loadMonitor(int monitor_id) { bool StreamBase::checkInitialised() { if ( !monitor ) { - Fatal("Cannot stream, not initialised"); + Error("Cannot stream, not initialised"); + return false; + } + if ( monitor->GetFunction() == Monitor::NONE ) { + Error("Monitor %d has function NONE. Will not be able to connect to it.", monitor_id); + return false; + } + if ( !monitor->ShmValid() ) { + Error("Monitor shm is not connected"); return false; } return true; @@ -248,7 +264,7 @@ bool StreamBase::sendTextFrame(const char *frame_text) { fprintf(stdout, "Content-type: %s\r\n\r\n", vid_stream->MimeType()); vid_stream->OpenStream(); } - /* double pts = */ vid_stream->EncodeFrame( image.Buffer(), image.Size() ); + /* double pts = */ vid_stream->EncodeFrame(image.Buffer(), image.Size()); } else #endif // HAVE_LIBAVCODEC { @@ -257,13 +273,13 @@ bool StreamBase::sendTextFrame(const char *frame_text) { image.EncodeJpeg(buffer, &n_bytes); - fputs("--ZoneMinderFrame\r\nContent-Type: image/jpeg\r\n", stdout); + fputs("--" BOUNDARY "\r\nContent-Type: image/jpeg\r\n", stdout); fprintf(stdout, "Content-Length: %d\r\n\r\n", n_bytes); if ( fwrite(buffer, n_bytes, 1, stdout) != 1 ) { Error("Unable to send stream text frame: %s", strerror(errno)); return false; } - fputs("\r\n\r\n",stdout); + fputs("\r\n\r\n", stdout); fflush(stdout); } last_frame_sent = TV_2_FLOAT(now); @@ -351,7 +367,7 @@ void StreamBase::openComms() { strncpy(rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path)); rem_addr.sun_family = AF_UNIX; - gettimeofday(&last_comm_update, NULL); + gettimeofday(&last_comm_update, nullptr); } // end if connKey > 0 Debug(3, "comms open at %s", loc_sock_path); } // end void StreamBase::openComms() diff --git a/src/zm_stream.h b/src/zm_stream.h index 6024d9823..d906b2de6 100644 --- a/src/zm_stream.h +++ b/src/zm_stream.h @@ -61,6 +61,7 @@ protected: typedef enum { CMD_NONE=0, CMD_PAUSE, CMD_PLAY, CMD_STOP, CMD_FASTFWD, CMD_SLOWFWD, CMD_SLOWREV, CMD_FASTREV, CMD_ZOOMIN, CMD_ZOOMOUT, CMD_PAN, CMD_SCALE, CMD_PREV, CMD_NEXT, CMD_SEEK, CMD_VARPLAY, CMD_GET_IMAGE, CMD_QUIT, CMD_QUERY=99 } MsgCommand; protected: + int monitor_id; Monitor *monitor; StreamType type; @@ -114,6 +115,7 @@ protected: public: StreamBase(): + monitor_id(0), monitor(0), type(DEFAULT_TYPE), format(""), @@ -157,6 +159,13 @@ public: void setStreamType(StreamType p_type) { type = p_type; +#if ! HAVE_ZLIB_H + if ( type == STREAM_ZIP ) { + Error("zlib is required for zipped images. Falling back to raw image"); + type = STREAM_RAW; + } +#endif + } void setStreamFormat(const char *p_format) { format = p_format; diff --git a/src/zm_swscale.cpp b/src/zm_swscale.cpp index 04c37ace7..7afb9521c 100644 --- a/src/zm_swscale.cpp +++ b/src/zm_swscale.cpp @@ -24,7 +24,7 @@ #include "zm_swscale.h" #if HAVE_LIBSWSCALE && HAVE_LIBAVUTIL -SWScale::SWScale() : gotdefaults(false), swscale_ctx(NULL), input_avframe(NULL), output_avframe(NULL) { +SWScale::SWScale() : gotdefaults(false), swscale_ctx(nullptr), input_avframe(nullptr), output_avframe(nullptr) { Debug(4,"SWScale object created"); } @@ -36,7 +36,7 @@ bool SWScale::init() { #else input_avframe = avcodec_alloc_frame(); #endif - if ( input_avframe == NULL ) { + if ( input_avframe == nullptr ) { Error("Failed allocating AVFrame for the input"); return false; } @@ -47,7 +47,7 @@ bool SWScale::init() { #else output_avframe = avcodec_alloc_frame(); #endif - if ( output_avframe == NULL ) { + if ( output_avframe == nullptr ) { Error("Failed allocating AVFrame for the output"); return false; } @@ -65,7 +65,7 @@ SWScale::~SWScale() { if ( swscale_ctx ) { sws_freeContext(swscale_ctx); - swscale_ctx = NULL; + swscale_ctx = nullptr; } Debug(4,"SWScale object destroyed"); @@ -86,7 +86,7 @@ int SWScale::SetDefaults(enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint8_t* out_buffer, const size_t out_buffer_size, enum _AVPIXELFORMAT in_pf, enum _AVPIXELFORMAT out_pf, unsigned int width, unsigned int height, unsigned int new_width, unsigned int new_height) { /* Parameter checking */ - if(in_buffer == NULL || out_buffer == NULL) { + if(in_buffer == nullptr || out_buffer == nullptr) { Error("NULL Input or output buffer"); return -1; } @@ -131,8 +131,8 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint } /* Get the context */ - swscale_ctx = sws_getCachedContext( swscale_ctx, width, height, in_pf, new_width, new_height, out_pf, SWS_FAST_BILINEAR, NULL, NULL, NULL ); - if(swscale_ctx == NULL) { + swscale_ctx = sws_getCachedContext( swscale_ctx, width, height, in_pf, new_width, new_height, out_pf, SWS_FAST_BILINEAR, nullptr, nullptr, nullptr ); + if(swscale_ctx == nullptr) { Error("Failed getting swscale context"); return -6; } diff --git a/src/zm_thread.cpp b/src/zm_thread.cpp index ac493a3fe..a4bbe763a 100644 --- a/src/zm_thread.cpp +++ b/src/zm_thread.cpp @@ -30,7 +30,7 @@ struct timespec getTimeout( int secs ) { struct timespec timeout; struct timeval temp_timeout; - gettimeofday(&temp_timeout, 0); + gettimeofday(&temp_timeout, nullptr); timeout.tv_sec = temp_timeout.tv_sec + secs; timeout.tv_nsec = temp_timeout.tv_usec*1000; return timeout; @@ -39,7 +39,7 @@ struct timespec getTimeout( int secs ) { struct timespec getTimeout( double secs ) { struct timespec timeout; struct timeval temp_timeout; - gettimeofday( &temp_timeout, 0 ); + gettimeofday( &temp_timeout, nullptr ); timeout.tv_sec = temp_timeout.tv_sec + int(secs); timeout.tv_nsec = temp_timeout.tv_usec += (long int)(1000000000.0*(secs-int(secs))); if ( timeout.tv_nsec > 1000000000 ) { @@ -50,7 +50,7 @@ struct timespec getTimeout( double secs ) { } Mutex::Mutex() { - if ( pthread_mutex_init(&mMutex, NULL) < 0 ) + if ( pthread_mutex_init(&mMutex, nullptr) < 0 ) Error("Unable to create pthread mutex: %s", strerror(errno)); } @@ -105,7 +105,7 @@ RecursiveMutex::RecursiveMutex() { } Condition::Condition( Mutex &mutex ) : mMutex( mutex ) { - if ( pthread_cond_init( &mCondition, NULL ) < 0 ) + if ( pthread_cond_init( &mCondition, nullptr ) < 0 ) throw ThreadException( stringtf( "Unable to create pthread condition: %s", strerror(errno) ) ); } diff --git a/src/zm_time.h b/src/zm_time.h index a9af32777..0f7dbc794 100644 --- a/src/zm_time.h +++ b/src/zm_time.h @@ -86,7 +86,7 @@ inline int tvDiffUsec( struct timeval first, struct timeval last ) inline int tvDiffUsec( struct timeval first ) { struct timeval now; - gettimeofday( &now, NULL ); + gettimeofday( &now, nullptr ); return( tvDiffUsec( first, now ) ); } @@ -98,7 +98,7 @@ inline int tvDiffMsec( struct timeval first, struct timeval last ) inline int tvDiffMsec( struct timeval first ) { struct timeval now; - gettimeofday( &now, NULL ); + gettimeofday( &now, nullptr ); return( tvDiffMsec( first, now ) ); } @@ -110,7 +110,7 @@ inline double tvDiffSec( struct timeval first, struct timeval last ) inline double tvDiffSec( struct timeval first ) { struct timeval now; - gettimeofday( &now, NULL ); + gettimeofday( &now, nullptr ); return( tvDiffSec( first, now ) ); } @@ -146,7 +146,7 @@ inline int tvEq( struct timeval t1, struct timeval t2 ) inline struct timeval tvNow( void ) { struct timeval t; - gettimeofday( &t, NULL ); + gettimeofday( &t, nullptr ); return( t ); } diff --git a/src/zm_user.cpp b/src/zm_user.cpp index 8457fd5b7..06b53abbe 100644 --- a/src/zm_user.cpp +++ b/src/zm_user.cpp @@ -116,7 +116,7 @@ User *zmLoadUser(const char *username, const char *password) { " FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1", safer_username); delete[] safer_username; - safer_username = NULL; + safer_username = nullptr; if ( mysql_query(&dbconn, sql) ) { Error("Can't run query: %s", mysql_error(&dbconn)); @@ -145,7 +145,7 @@ User *zmLoadUser(const char *username, const char *password) { mysql_free_result(result); Warning("Unable to authenticate user %s", username); - return NULL; + return nullptr; } // end User *zmLoadUser(const char *username, const char *password) User *zmLoadTokenUser(std::string jwt_token_str, bool use_remote_addr) { @@ -169,7 +169,7 @@ User *zmLoadTokenUser(std::string jwt_token_str, bool use_remote_addr) { Debug(1, "retrieved user '%s' from token", username.c_str()); if ( username == "" ) { - return NULL; + return nullptr; } char sql[ZM_SQL_MED_BUFSIZ] = ""; @@ -180,30 +180,30 @@ User *zmLoadTokenUser(std::string jwt_token_str, bool use_remote_addr) { if ( mysql_query(&dbconn, sql) ) { Error("Can't run query: %s", mysql_error(&dbconn)); - return NULL; + return nullptr; } MYSQL_RES *result = mysql_store_result(&dbconn); if ( !result ) { Error("Can't use query result: %s", mysql_error(&dbconn)); - return NULL; + return nullptr; } int n_users = mysql_num_rows(result); if ( n_users != 1 ) { mysql_free_result(result); Error("Unable to authenticate user '%s'", username.c_str()); - return NULL; + return nullptr; } MYSQL_ROW dbrow = mysql_fetch_row(result); User *user = new User(dbrow); - unsigned int stored_iat = strtoul(dbrow[10], NULL, 0); + unsigned int stored_iat = strtoul(dbrow[10], nullptr, 0); if ( stored_iat > iat ) { // admin revoked tokens mysql_free_result(result); Error("Token was revoked for '%s'", username.c_str()); - return NULL; + return nullptr; } Debug(1, "Authenticated user '%s' via token with last revoke time: %u", @@ -248,16 +248,16 @@ User *zmLoadAuthUser(const char *auth, bool use_remote_addr) { MYSQL_RES *result = mysql_store_result(&dbconn); if ( !result ) { Error("Can't use query result: %s", mysql_error(&dbconn)); - return NULL; + return nullptr; } int n_users = mysql_num_rows(result); if ( n_users < 1 ) { mysql_free_result(result); Warning("Unable to authenticate user"); - return NULL; + return nullptr; } - time_t now = time(0); + time_t now = time(nullptr); unsigned int hours = config.auth_hash_ttl; if ( ! hours ) { Warning("No value set for ZM_AUTH_HASH_TTL. Defaulting to 2."); @@ -323,7 +323,7 @@ User *zmLoadAuthUser(const char *auth, bool use_remote_addr) { Error("You need to build with gnutls or openssl to use hash based auth"); #endif // HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT Debug(1, "No user found for auth_key %s", auth); - return NULL; + return nullptr; } // end User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) // Function to check Username length diff --git a/src/zm_utils.cpp b/src/zm_utils.cpp index ecb220021..45a41e543 100644 --- a/src/zm_utils.cpp +++ b/src/zm_utils.cpp @@ -185,7 +185,7 @@ const std::string base64Encode(const std::string &inString) { } int split(const char* string, const char delim, std::vector& items) { - if ( string == NULL ) + if ( string == nullptr ) return -1; if ( string[0] == 0 ) @@ -206,7 +206,7 @@ int split(const char* string, const char delim, std::vector& items) } int pairsplit(const char* string, const char delim, std::string& name, std::string& value) { - if ( string == NULL ) + if ( string == nullptr ) return -1; if ( string[0] == 0 ) diff --git a/src/zm_video.cpp b/src/zm_video.cpp index 309c507c0..d97c75167 100644 --- a/src/zm_video.cpp +++ b/src/zm_video.cpp @@ -57,7 +57,7 @@ int VideoWriter::Reset(const char* new_path) { /* Common variables reset */ /* If there is a new path, use it */ - if ( new_path != NULL ) { + if ( new_path != nullptr ) { path = new_path; } @@ -116,7 +116,7 @@ X264MP4Writer::X264MP4Writer( } /* If supplied with user parameters to the encoder, copy them */ - if ( p_user_params != NULL ) { + if ( p_user_params != nullptr ) { user_params = *p_user_params; } @@ -144,7 +144,7 @@ X264MP4Writer::~X264MP4Writer() { int X264MP4Writer::Open() { /* Open the encoder */ x264enc = x264_encoder_open(&x264params); - if ( x264enc == NULL ) { + if ( x264enc == nullptr ) { Error("Failed opening x264 encoder"); return -1; } @@ -269,7 +269,7 @@ int X264MP4Writer::Encode( const size_t data_size, const unsigned int frame_time) { /* Parameter checking */ - if ( data == NULL ) { + if ( data == nullptr ) { Error("NULL buffer"); return -1; } @@ -418,7 +418,7 @@ int X264MP4Writer::x264encodeloop(bool bFlush) { int frame_size; if ( bFlush ) { - frame_size = x264_encoder_encode(x264enc, &nals, &i_nals, NULL, &x264picout); + frame_size = x264_encoder_encode(x264enc, &nals, &i_nals, nullptr, &x264picout); } else { frame_size = x264_encoder_encode(x264enc, &nals, &i_nals, &x264picin, &x264picout); } @@ -515,12 +515,12 @@ int ParseEncoderParameters( const char* str, std::vector* vec ) { - if ( vec == NULL ) { + if ( vec == nullptr ) { Error("NULL Encoder parameters vector pointer"); return -1; } - if ( str == NULL ) { + if ( str == nullptr ) { Error("NULL Encoder parameters string"); return -2; } diff --git a/src/zm_video.h b/src/zm_video.h index 46d7c3635..e185f82fc 100644 --- a/src/zm_video.h +++ b/src/zm_video.h @@ -81,7 +81,7 @@ public: virtual int Encode(const Image* img, const unsigned int frame_time) = 0; virtual int Open() = 0; virtual int Close() = 0; - virtual int Reset(const char* new_path = NULL); + virtual int Reset(const char* new_path = nullptr); const char* GetContainer() const { return container.c_str(); @@ -160,13 +160,13 @@ protected: public: - X264MP4Writer(const char* p_path, const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder, const std::vector* p_user_params = NULL); + X264MP4Writer(const char* p_path, const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder, const std::vector* p_user_params = nullptr); ~X264MP4Writer(); int Encode(const uint8_t* data, const size_t data_size, const unsigned int frame_time); int Encode(const Image* img, const unsigned int frame_time); int Open(); int Close(); - int Reset(const char* new_path = NULL); + int Reset(const char* new_path = nullptr); }; #endif // HAVE_LIBX264 && HAVE_LIBMP4V2 && HAVE_LIBAVUTIL && HAVE_LIBSWSCALE diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp index 19f1251e2..8892c6443 100644 --- a/src/zm_videostore.cpp +++ b/src/zm_videostore.cpp @@ -62,7 +62,7 @@ VideoStore::VideoStore( Info("Opening video storage stream %s format: %s", filename, format); - int ret = avformat_alloc_output_context2(&oc, NULL, NULL, filename); + int ret = avformat_alloc_output_context2(&oc, nullptr, nullptr, filename); if ( ret < 0 ) { Warning( "Could not create video storage stream %s as no out ctx" @@ -74,7 +74,7 @@ VideoStore::VideoStore( // Couldn't deduce format from filename, trying from format name if ( !oc ) { - avformat_alloc_output_context2(&oc, NULL, format, filename); + avformat_alloc_output_context2(&oc, nullptr, format, filename); if ( !oc ) { Error( "Could not create video storage stream %s as no out ctx" @@ -86,7 +86,7 @@ VideoStore::VideoStore( } } // end if ! oc - AVDictionary *pmetadata = NULL; + AVDictionary *pmetadata = nullptr; int dsr = av_dict_set(&pmetadata, "title", "Zoneminder Security Recording", 0); if ( dsr < 0 ) Warning("%s:%d: title set failed", __FILE__, __LINE__); @@ -104,7 +104,7 @@ VideoStore::VideoStore( #endif } - video_out_stream = avformat_new_stream(oc, NULL); + video_out_stream = avformat_new_stream(oc, nullptr); if ( !video_out_stream ) { Error("Unable to create video out stream"); return; @@ -231,11 +231,11 @@ VideoStore::VideoStore( video_out_codec->name, av_make_error_string(ret).c_str() ); - video_out_codec = NULL; + video_out_codec = nullptr; } - AVDictionaryEntry *e = NULL; - while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) { + AVDictionaryEntry *e = nullptr; + while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != nullptr ) { Warning("Encoder Option %s not recognized by ffmpeg codec", e->key); } ret = avcodec_parameters_from_context(video_out_stream->codecpar, video_out_ctx); @@ -275,16 +275,16 @@ VideoStore::VideoStore( } } - converted_in_samples = NULL; - audio_out_codec = NULL; - audio_in_codec = NULL; - audio_in_ctx = NULL; - audio_out_stream = NULL; - in_frame = NULL; - out_frame = NULL; + converted_in_samples = nullptr; + audio_out_codec = nullptr; + audio_in_codec = nullptr; + audio_in_ctx = nullptr; + audio_out_stream = nullptr; + in_frame = nullptr; + out_frame = nullptr; #if defined(HAVE_LIBSWRESAMPLE) || defined(HAVE_LIBAVRESAMPLE) - resample_ctx = NULL; - fifo = NULL; + resample_ctx = nullptr; + fifo = nullptr; #endif video_first_pts = 0; video_first_dts = 0; @@ -310,11 +310,11 @@ VideoStore::VideoStore( } #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) - audio_out_stream = avformat_new_stream(oc, NULL); + audio_out_stream = avformat_new_stream(oc, nullptr); audio_out_ctx = avcodec_alloc_context3(audio_out_codec); if ( !audio_out_ctx ) { Error("could not allocate codec ctx for AAC"); - audio_out_stream = NULL; + audio_out_stream = nullptr; return; } #else @@ -329,7 +329,7 @@ VideoStore::VideoStore( } else { Debug(2, "Got AAC"); - audio_out_stream = avformat_new_stream(oc, NULL); + audio_out_stream = avformat_new_stream(oc, nullptr); if ( !audio_out_stream ) { Error("Could not allocate new stream"); return; @@ -366,7 +366,7 @@ VideoStore::VideoStore( if ( ret < 0 ) { Error("Unable to copy audio ctx %s", av_make_error_string(ret).c_str()); - audio_out_stream = NULL; + audio_out_stream = nullptr; return; } // end if audio_out_ctx->codec_tag = 0; @@ -403,7 +403,7 @@ bool VideoStore::open() { int ret; /* open the out file, if needed */ if ( !(out_format->flags & AVFMT_NOFILE) ) { - ret = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE, NULL, NULL); + ret = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE, nullptr, nullptr); if ( ret < 0 ) { Error("Could not open out file '%s': %s", filename, av_make_error_string(ret).c_str()); @@ -414,7 +414,7 @@ bool VideoStore::open() { zm_dump_stream_format(oc, 0, 0, 1); if ( audio_out_stream ) zm_dump_stream_format(oc, 1, 0, 1); - AVDictionary *opts = NULL; + AVDictionary *opts = nullptr; std::string option_string = monitor->GetOptEncoderParams(); ret = av_dict_parse_string(&opts, option_string.c_str(), "=", ",\n", 0); @@ -422,7 +422,7 @@ bool VideoStore::open() { Warning("Could not parse ffmpeg output options '%s'", option_string.c_str()); } - const AVDictionaryEntry *movflags_entry = av_dict_get(opts, "movflags", NULL, AV_DICT_MATCH_CASE); + const AVDictionaryEntry *movflags_entry = av_dict_get(opts, "movflags", nullptr, AV_DICT_MATCH_CASE); if ( !movflags_entry ) { Debug(1, "setting movflags to frag_keyframe+empty_moov"); // av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0); @@ -435,14 +435,14 @@ bool VideoStore::open() { } if ( (ret = avformat_write_header(oc, &opts)) < 0 ) { Warning("Unable to set movflags trying with defaults."); - ret = avformat_write_header(oc, NULL); + ret = avformat_write_header(oc, nullptr); } else if ( av_dict_count(opts) != 0 ) { Info("some options not used, turn on debugging for a list."); - AVDictionaryEntry *e = NULL; - while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != NULL ) { + AVDictionaryEntry *e = nullptr; + while ( (e = av_dict_get(opts, "", e, AV_DICT_IGNORE_SUFFIX)) != nullptr ) { Debug(1, "Encoder Option %s=>%s", e->key, e->value); if ( !e->value ) { - av_dict_set(&opts, e->key, NULL, 0); + av_dict_set(&opts, e->key, nullptr, 0); } } } @@ -468,7 +468,7 @@ VideoStore::~VideoStore() { // whatever we get. Failures are not fatal. AVPacket pkt; // Without these we seg fault I don't know why. - pkt.data = NULL; + pkt.data = nullptr; pkt.size = 0; av_init_packet(&pkt); @@ -477,7 +477,7 @@ VideoStore::~VideoStore() { * At the end of the file, we pass the remaining samples to * the encoder. */ while ( zm_resample_get_delay(resample_ctx, audio_out_ctx->sample_rate) ) { - zm_resample_audio(resample_ctx, NULL, out_frame); + zm_resample_audio(resample_ctx, nullptr, out_frame); if ( zm_add_samples_to_fifo(fifo, out_frame) ) { // Should probably set the frame size to what is reported FIXME @@ -518,7 +518,7 @@ VideoStore::~VideoStore() { #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) // Put encoder into flushing mode - avcodec_send_frame(audio_out_ctx, NULL); + avcodec_send_frame(audio_out_ctx, nullptr); #endif while (1) { @@ -537,7 +537,7 @@ VideoStore::~VideoStore() { // Flush Queues Debug(1, "Flushing interleaved queues"); - av_interleaved_write_frame(oc, NULL); + av_interleaved_write_frame(oc, nullptr); Debug(1, "Writing trailer"); /* Write the trailer before close */ @@ -552,7 +552,7 @@ VideoStore::~VideoStore() { /* Close the out file. */ Debug(2, "Closing"); if ( int rc = avio_close(oc->pb) ) { - oc->pb = NULL; + oc->pb = nullptr; Error("Error closing avio %s", av_err2str(rc)); } } else { @@ -570,24 +570,24 @@ VideoStore::~VideoStore() { // We allocate and copy in newer ffmpeg, so need to free it //avcodec_free_context(&video_in_ctx); #endif - video_in_ctx = NULL; + video_in_ctx = nullptr; if ( video_out_codec ) { avcodec_close(video_out_ctx); Debug(4, "Success closing video_out_ctx"); - video_out_codec = NULL; + video_out_codec = nullptr; } // end if video_out_codec #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) avcodec_free_context(&video_out_ctx); #endif - video_out_ctx = NULL; + video_out_ctx = nullptr; } // end if video_out_stream if ( audio_out_stream ) { if ( audio_in_codec ) { avcodec_close(audio_in_ctx); Debug(4, "Success closing audio_in_ctx"); - audio_in_codec = NULL; + audio_in_codec = nullptr; } // end if audio_in_codec #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) @@ -595,7 +595,7 @@ VideoStore::~VideoStore() { avcodec_free_context(&audio_in_ctx); #endif Debug(4, "Success freeing audio_in_ctx"); - audio_in_ctx = NULL; + audio_in_ctx = nullptr; if ( audio_out_ctx ) { avcodec_close(audio_out_ctx); @@ -604,13 +604,13 @@ VideoStore::~VideoStore() { avcodec_free_context(&audio_out_ctx); #endif } - audio_out_ctx = NULL; + audio_out_ctx = nullptr; #if defined(HAVE_LIBAVRESAMPLE) || defined(HAVE_LIBSWRESAMPLE) if ( resample_ctx ) { if ( fifo ) { av_audio_fifo_free(fifo); - fifo = NULL; + fifo = nullptr; } #if defined(HAVE_LIBSWRESAMPLE) swr_free(&resample_ctx); @@ -623,15 +623,15 @@ VideoStore::~VideoStore() { } if ( in_frame ) { av_frame_free(&in_frame); - in_frame = NULL; + in_frame = nullptr; } if ( out_frame ) { av_frame_free(&out_frame); - out_frame = NULL; + out_frame = nullptr; } if ( converted_in_samples ) { av_free(converted_in_samples); - converted_in_samples = NULL; + converted_in_samples = nullptr; } #endif } // end if audio_out_stream @@ -690,7 +690,7 @@ bool VideoStore::setup_resampler() { #endif // if the codec is already open, nothing is done. - if ( (ret = avcodec_open2(audio_in_ctx, audio_in_codec, NULL)) < 0 ) { + if ( (ret = avcodec_open2(audio_in_ctx, audio_in_codec, nullptr)) < 0 ) { Error("Can't open audio in codec!"); return false; } @@ -747,7 +747,7 @@ bool VideoStore::setup_resampler() { audio_out_ctx->time_base = (AVRational){1, audio_out_ctx->sample_rate}; - AVDictionary *opts = NULL; + AVDictionary *opts = nullptr; if ( (ret = av_dict_set(&opts, "strict", "experimental", 0)) < 0 ) { Error("Couldn't set experimental"); } @@ -756,9 +756,9 @@ bool VideoStore::setup_resampler() { if ( ret < 0 ) { Error("could not open codec (%d) (%s)", ret, av_make_error_string(ret).c_str()); - audio_out_codec = NULL; - audio_out_ctx = NULL; - audio_out_stream = NULL; + audio_out_codec = nullptr; + audio_out_ctx = nullptr; + audio_out_stream = nullptr; return false; } zm_dump_codec(audio_out_ctx); @@ -814,14 +814,14 @@ bool VideoStore::setup_resampler() { return false; } #if defined(HAVE_LIBSWRESAMPLE) - resample_ctx = swr_alloc_set_opts(NULL, + resample_ctx = swr_alloc_set_opts(nullptr, audio_out_ctx->channel_layout, audio_out_ctx->sample_fmt, audio_out_ctx->sample_rate, audio_in_ctx->channel_layout, audio_in_ctx->sample_fmt, audio_in_ctx->sample_rate, - 0, NULL); + 0, nullptr); if ( !resample_ctx ) { Error("Could not allocate resample context"); av_frame_free(&in_frame); @@ -885,7 +885,7 @@ bool VideoStore::setup_resampler() { // The codec gives us the frame size, in samples, we calculate the size of the // samples buffer in bytes unsigned int audioSampleBuffer_size = av_samples_get_buffer_size( - NULL, audio_out_ctx->channels, + nullptr, audio_out_ctx->channels, audio_out_ctx->frame_size, audio_out_ctx->sample_fmt, 0); converted_in_samples = reinterpret_cast(av_malloc(audioSampleBuffer_size)); @@ -1013,7 +1013,7 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) { if ( zm_resample_get_delay(resample_ctx, out_frame->sample_rate) < out_frame->nb_samples) break; // This will send a null frame, emptying out the resample buffer - input_frame = NULL; + input_frame = nullptr; } // end while there is data in the resampler } else { diff --git a/src/zm_zone.cpp b/src/zm_zone.cpp index ee7a5c829..9bb8d26e5 100644 --- a/src/zm_zone.cpp +++ b/src/zm_zone.cpp @@ -83,7 +83,7 @@ void Zone::Setup( alarm_blobs = 0; min_blob_size = 0; max_blob_size = 0; - image = 0; + image = nullptr; score = 0; overload_count = 0; @@ -136,7 +136,7 @@ void Zone::RecordStats(const Event *event) { db_mutex.lock(); snprintf(sql, sizeof(sql), "INSERT INTO Stats SET MonitorId=%d, ZoneId=%d, EventId=%" PRIu64 ", FrameId=%d, PixelDiff=%d, AlarmPixels=%d, FilterPixels=%d, BlobPixels=%d, Blobs=%d, MinBlobSize=%d, MaxBlobSize=%d, MinX=%d, MinY=%d, MaxX=%d, MaxY=%d, Score=%d", - monitor->Id(), id, event->Id(), event->Frames()+1, pixel_diff, alarm_pixels, alarm_filter_pixels, alarm_blob_pixels, alarm_blobs, min_blob_size, max_blob_size, alarm_box.LoX(), alarm_box.LoY(), alarm_box.HiX(), alarm_box.HiY(), score + monitor->Id(), id, event->Id(), event->Frames(), pixel_diff, alarm_pixels, alarm_filter_pixels, alarm_blob_pixels, alarm_blobs, min_blob_size, max_blob_size, alarm_box.LoX(), alarm_box.LoY(), alarm_box.HiX(), alarm_box.HiY(), score ); if ( mysql_query(&dbconn, sql) ) { Error("Can't insert event stats: %s", mysql_error(&dbconn)); diff --git a/src/zma.cpp b/src/zma.cpp index a0cb048bf..edaf9c722 100644 --- a/src/zma.cpp +++ b/src/zma.cpp @@ -70,15 +70,15 @@ void Usage() { int main( int argc, char *argv[] ) { self = argv[0]; - srand(getpid() * time(0)); + srand(getpid() * time(nullptr)); int id = -1; static struct option long_options[] = { - {"monitor", 1, 0, 'm'}, - {"help", 0, 0, 'h'}, - {"version", 0, 0, 'v'}, - {0, 0, 0, 0} + {"monitor", 1, nullptr, 'm'}, + {"help", 0, nullptr, 'h'}, + {"version", 0, nullptr, 'v'}, + {nullptr, 0, nullptr, 0} }; while (1) { @@ -146,15 +146,15 @@ int main( int argc, char *argv[] ) { unsigned int analysis_update_delay = monitor->GetAnalysisUpdateDelay(); time_t last_analysis_update_time, cur_time; monitor->UpdateAdaptiveSkip(); - last_analysis_update_time = time(0); + last_analysis_update_time = time(nullptr); while( (!zm_terminate) && monitor->ShmValid() ) { // Process the next image - sigprocmask(SIG_BLOCK, &block_set, 0); + sigprocmask(SIG_BLOCK, &block_set, nullptr); // Some periodic updates are required for variable capturing framerate if ( analysis_update_delay ) { - cur_time = time(0); + cur_time = time(nullptr); if ( (unsigned int)( cur_time - last_analysis_update_time ) > analysis_update_delay ) { analysis_rate = monitor->GetAnalysisRate(); monitor->UpdateAdaptiveSkip(); @@ -174,7 +174,7 @@ int main( int argc, char *argv[] ) { logInit(log_id_string); zm_reload = false; } - sigprocmask(SIG_UNBLOCK, &block_set, 0); + sigprocmask(SIG_UNBLOCK, &block_set, nullptr); } // end while ! zm_terminate delete monitor; } else { diff --git a/src/zmc.cpp b/src/zmc.cpp index 22132e668..8376c91ba 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -90,7 +90,7 @@ void Usage() { int main(int argc, char *argv[]) { self = argv[0]; - srand(getpid() * time(0)); + srand(getpid() * time(nullptr)); const char *device = ""; const char *protocol = ""; @@ -101,16 +101,16 @@ int main(int argc, char *argv[]) { int monitor_id = -1; static struct option long_options[] = { - {"device", 1, 0, 'd'}, - {"protocol", 1, 0, 'r'}, - {"host", 1, 0, 'H'}, - {"port", 1, 0, 'P'}, - {"path", 1, 0, 'p'}, - {"file", 1, 0, 'f'}, - {"monitor", 1, 0, 'm'}, - {"help", 0, 0, 'h'}, - {"version", 0, 0, 'v'}, - {0, 0, 0, 0} + {"device", 1, nullptr, 'd'}, + {"protocol", 1, nullptr, 'r'}, + {"host", 1, nullptr, 'H'}, + {"port", 1, nullptr, 'P'}, + {"path", 1, nullptr, 'p'}, + {"file", 1, nullptr, 'f'}, + {"monitor", 1, nullptr, 'm'}, + {"help", 0, nullptr, 'h'}, + {"version", 0, nullptr, 'v'}, + {nullptr, 0, nullptr, 0} }; while (1) { @@ -193,7 +193,7 @@ int main(int argc, char *argv[]) { hwcaps_detect(); - Monitor **monitors = 0; + Monitor **monitors = nullptr; int n_monitors = 0; #if ZM_HAS_V4L if ( device[0] ) { @@ -240,7 +240,7 @@ int main(int argc, char *argv[]) { result = 0; static char sql[ZM_SQL_SML_BUFSIZ]; for ( int i = 0; i < n_monitors; i++ ) { - time_t now = (time_t)time(NULL); + time_t now = (time_t)time(nullptr); monitors[i]->setStartupTime(now); snprintf(sql, sizeof(sql), @@ -287,7 +287,7 @@ int main(int argc, char *argv[]) { for ( int i = 0; i < n_monitors; i++ ) { long min_delay = MAXINT; - gettimeofday(&now, NULL); + gettimeofday(&now, nullptr); for ( int j = 0; j < n_monitors; j++ ) { if ( last_capture_times[j].tv_sec ) { DELTA_TIMEVAL(delta_time, now, last_capture_times[j], DT_PREC_3); @@ -329,14 +329,14 @@ int main(int argc, char *argv[]) { } if ( next_delays[i] > 0 ) { - gettimeofday(&now, NULL); + gettimeofday(&now, nullptr); DELTA_TIMEVAL(delta_time, now, last_capture_times[i], DT_PREC_3); long sleep_time = next_delays[i]-delta_time.delta; if ( sleep_time > 0 ) { usleep(sleep_time*(DT_MAXGRAN/DT_PREC_3)); } } - gettimeofday(&(last_capture_times[i]), NULL); + gettimeofday(&(last_capture_times[i]), nullptr); } // end if next_delay <= min_delay || next_delays[i] <= 0 ) } // end foreach n_monitors diff --git a/src/zms.cpp b/src/zms.cpp index ad7076e7a..9b661c564 100644 --- a/src/zms.cpp +++ b/src/zms.cpp @@ -50,10 +50,10 @@ bool ValidateAccess(User *user, int mon_id) { return allowed; } -int main(int argc, const char *argv[]) { +int main(int argc, const char *argv[], char **envp) { self = argv[0]; - srand(getpid() * time(0)); + srand(getpid() * time(nullptr)); enum { ZMS_UNKNOWN, ZMS_MONITOR, ZMS_EVENT, ZMS_FIFO } source = ZMS_UNKNOWN; enum { ZMS_JPEG, ZMS_MPEG, ZMS_RAW, ZMS_ZIP, ZMS_SINGLE } mode = ZMS_JPEG; @@ -89,6 +89,10 @@ int main(int argc, const char *argv[]) { zmLoadConfig(); char log_id_string[32] = "zms"; logInit(log_id_string); + for (char **env = envp; *env != 0; env++) { + char *thisEnv = *env; + Debug(1, "env: %s", thisEnv); + } const char *query = getenv("QUERY_STRING"); if ( query ) { @@ -101,12 +105,12 @@ int main(int argc, const char *argv[]) { int parm_no = 0; while ( (parm_no < 16) && (parms[parm_no] = strtok(q_ptr, "&")) ) { parm_no++; - q_ptr = NULL; + q_ptr = nullptr; } for ( int p = 0; p < parm_no; p++ ) { char *name = strtok(parms[p], "="); - char const *value = strtok(NULL, "="); + char const *value = strtok(nullptr, "="); if ( !value ) value = ""; if ( !strcmp(name, "source") ) { @@ -127,10 +131,10 @@ int main(int argc, const char *argv[]) { } else if ( !strcmp(name, "time") ) { event_time = atoi(value); } else if ( !strcmp(name, "event") ) { - event_id = strtoull(value, NULL, 10); + event_id = strtoull(value, nullptr, 10); source = ZMS_EVENT; } else if ( !strcmp(name, "frame") ) { - frame_id = strtoull(value, NULL, 10); + frame_id = strtoull(value, nullptr, 10); source = ZMS_EVENT; } else if ( !strcmp(name, "scale") ) { scale = atoi(value); @@ -184,7 +188,7 @@ int main(int argc, const char *argv[]) { logInit(log_id_string); if ( config.opt_use_auth ) { - User *user = NULL; + User *user = nullptr; if ( jwt_token_str != "" ) { // user = zmLoadTokenUser(jwt_token_str, config.auth_hash_ips); @@ -204,34 +208,36 @@ int main(int argc, const char *argv[]) { } if ( !user ) { fputs("HTTP/1.0 403 Forbidden\r\n\r\n", stdout); - Error("Unable to authenticate user"); + + const char *referer = getenv("HTTP_REFERER"); + Error("Unable to authenticate user from %s", referer); logTerm(); zmDbClose(); return 0; } if ( !ValidateAccess(user, monitor_id) ) { delete user; - user = NULL; + user = nullptr; fputs("HTTP/1.0 403 Forbidden\r\n\r\n", stdout); logTerm(); zmDbClose(); return 0; } delete user; - user = NULL; + user = nullptr; } // end if config.opt_use_auth hwcaps_detect(); zmSetDefaultTermHandler(); zmSetDefaultDieHandler(); - setbuf(stdout, 0); + setbuf(stdout, nullptr); if ( nph ) { fputs("HTTP/1.0 200 OK\r\n", stdout); } fprintf(stdout, "Server: ZoneMinder Video Server/%s\r\n", ZM_VERSION); - time_t now = time(0); + time_t now = time(nullptr); char date_string[64]; strftime(date_string, sizeof(date_string)-1, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now)); @@ -253,14 +259,7 @@ int main(int argc, const char *argv[]) { stream.setStreamTTL(ttl); stream.setStreamQueue(connkey); stream.setStreamBuffer(playback_buffer); - if ( !stream.setStreamStart(monitor_id) ) { - Error("Unable to connect to zmc process for monitor %d", monitor_id); - fprintf(stderr, "Unable to connect to zmc process. " - " Please ensure that it is running."); - logTerm(); - zmDbClose(); - return -1; - } + stream.setStreamStart(monitor_id); if ( mode == ZMS_JPEG ) { stream.setStreamType(MonitorStream::STREAM_JPEG); diff --git a/src/zmu.cpp b/src/zmu.cpp index 412bc816c..bdc467812 100644 --- a/src/zmu.cpp +++ b/src/zmu.cpp @@ -211,45 +211,45 @@ int main(int argc, char *argv[]) { self = argv[0]; - srand(getpid() * time(0)); + srand(getpid() * time(nullptr)); static struct option long_options[] = { - {"device", 2, 0, 'd'}, - {"monitor", 1, 0, 'm'}, - {"verbose", 0, 0, 'v'}, - {"image", 2, 0, 'i'}, - {"scale", 1, 0, 'S'}, - {"timestamp", 2, 0, 't'}, - {"state", 0, 0, 's'}, - {"brightness", 2, 0, 'B'}, - {"contrast", 2, 0, 'C'}, - {"hue", 2, 0, 'H'}, - {"contrast", 2, 0, 'O'}, - {"read_index", 0, 0, 'R'}, - {"write_index", 0, 0, 'W'}, - {"event", 0, 0, 'e'}, - {"fps", 0, 0, 'f'}, - {"zones", 2, 0, 'z'}, - {"alarm", 0, 0, 'a'}, - {"noalarm", 0, 0, 'n'}, - {"cancel", 0, 0, 'c'}, - {"reload", 0, 0, 'L'}, - {"enable", 0, 0, 'E'}, - {"disable", 0, 0, 'D'}, - {"suspend", 0, 0, 'u'}, - {"resume", 0, 0, 'r'}, - {"query", 0, 0, 'q'}, - {"username", 1, 0, 'U'}, - {"password", 1, 0, 'P'}, - {"auth", 1, 0, 'A'}, - {"token", 1, 0, 'T'}, - {"version", 1, 0, 'V'}, - {"help", 0, 0, 'h'}, - {"list", 0, 0, 'l'}, - {0, 0, 0, 0} + {"device", 2, nullptr, 'd'}, + {"monitor", 1, nullptr, 'm'}, + {"verbose", 0, nullptr, 'v'}, + {"image", 2, nullptr, 'i'}, + {"scale", 1, nullptr, 'S'}, + {"timestamp", 2, nullptr, 't'}, + {"state", 0, nullptr, 's'}, + {"brightness", 2, nullptr, 'B'}, + {"contrast", 2, nullptr, 'C'}, + {"hue", 2, nullptr, 'H'}, + {"contrast", 2, nullptr, 'O'}, + {"read_index", 0, nullptr, 'R'}, + {"write_index", 0, nullptr, 'W'}, + {"event", 0, nullptr, 'e'}, + {"fps", 0, nullptr, 'f'}, + {"zones", 2, nullptr, 'z'}, + {"alarm", 0, nullptr, 'a'}, + {"noalarm", 0, nullptr, 'n'}, + {"cancel", 0, nullptr, 'c'}, + {"reload", 0, nullptr, 'L'}, + {"enable", 0, nullptr, 'E'}, + {"disable", 0, nullptr, 'D'}, + {"suspend", 0, nullptr, 'u'}, + {"resume", 0, nullptr, 'r'}, + {"query", 0, nullptr, 'q'}, + {"username", 1, nullptr, 'U'}, + {"password", 1, nullptr, 'P'}, + {"auth", 1, nullptr, 'A'}, + {"token", 1, nullptr, 'T'}, + {"version", 1, nullptr, 'V'}, + {"help", 0, nullptr, 'h'}, + {"list", 0, nullptr, 'l'}, + {nullptr, 0, nullptr, 0} }; - const char *device = 0; + const char *device = nullptr; int mon_id = 0; bool verbose = false; int function = ZMU_BOGUS; @@ -260,10 +260,10 @@ int main(int argc, char *argv[]) { int contrast = -1; int hue = -1; int colour = -1; - char *zoneString = 0; - char *username = 0; - char *password = 0; - char *auth = 0; + char *zoneString = nullptr; + char *username = nullptr; + char *password = nullptr; + char *auth = nullptr; std::string jwt_token_str = ""; #if ZM_HAS_V4L #if ZM_HAS_V4L2 @@ -487,7 +487,7 @@ int main(int argc, char *argv[]) { if ( !monitor->connect() ) { Error("Can't connect to capture daemon: %d %s", monitor->Id(), monitor->Name()); delete monitor; - monitor = NULL; + monitor = nullptr; exit_zmu(-1); } @@ -701,7 +701,7 @@ int main(int argc, char *argv[]) { Usage(); } delete monitor; - monitor = NULL; + monitor = nullptr; } else { // non monitor functions if ( function & ZMU_QUERY ) { #if ZM_HAS_V4L diff --git a/utils/do_debian_package.sh b/utils/do_debian_package.sh index f366fda47..f95cc6523 100755 --- a/utils/do_debian_package.sh +++ b/utils/do_debian_package.sh @@ -80,7 +80,7 @@ fi; if [ "$DISTROS" == "" ]; then if [ "$RELEASE" != "" ]; then - DISTROS="xenial,bionic,eoan,focal" + DISTROS="xenial,bionic,focal" else DISTROS=`lsb_release -a 2>/dev/null | grep Codename | awk '{print $2}'`; fi; diff --git a/utils/packpack/startpackpack.sh b/utils/packpack/startpackpack.sh index 6a51e2995..1e9f6557f 100755 --- a/utils/packpack/startpackpack.sh +++ b/utils/packpack/startpackpack.sh @@ -1,4 +1,7 @@ #!/bin/bash + +set -o pipefail + # packpack setup file for the ZoneMinder project # Written by Andrew Bauer @@ -250,6 +253,13 @@ execpackpack () { else packpack/packpack $parms fi + + if [ $? -ne 0 ]; then + echo + echo "ERROR: An error occurred while executing packpack." + echo + exit 1 + fi } # Check for connectivity with the deploy target host @@ -337,10 +347,10 @@ elif [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ] || [ "${OS}" == "raspbia setdebpkgname movecrud - if [ "${DIST}" == "trusty" ] || [ "${DIST}" == "precise" ]; then - ln -sfT distros/ubuntu1204 debian - elif [ "${DIST}" == "wheezy" ]; then - ln -sfT distros/debian debian + if [ "${DIST}" == "focal" ] || [ "${DIST}" == "buster" ]; then + ln -sfT distros/ubuntu2004 debian + elif [ "${DIST}" == "beowulf" ]; then + ln -sfT distros/beowulf debian else ln -sfT distros/ubuntu1604 debian fi diff --git a/utils/travis/bootstrap-zm.sh b/utils/travis/bootstrap-zm.sh deleted file mode 100644 index 397a8f90e..000000000 --- a/utils/travis/bootstrap-zm.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -x - -set -e -set -o pipefail -set -x - -with_timestamps() { - while read -r line; do - echo -e "$(date +%T)\t$line"; - done -} - - -bootstrap_zm() { - - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then libtoolize --force; fi - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then aclocal; fi - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then autoheader; fi - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then automake --force-missing --add-missing; fi - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then autoconf; fi - - mysql -uroot -e "CREATE DATABASE IF NOT EXISTS zm" - mysql -uroot -e "GRANT ALL ON zm.* TO 'zmuser'@'localhost' IDENTIFIED BY 'zmpass'"; - mysql -uroot -e "FLUSH PRIVILEGES" - mysql -uzmuser -pzmpass < ${TRAVIS_BUILD_DIR}/db/zm_create.sql - -} - -bootstrap_zm | with_timestamps diff --git a/utils/travis/build-zm.sh b/utils/travis/build-zm.sh deleted file mode 100644 index 2d758f61b..000000000 --- a/utils/travis/build-zm.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -set -e -set -o pipefail - -with_timestamps() { - while read -r line; do - echo -e "$(date +%T)\t$line"; - done -} - -cd $TRAVIS_BUILD_DIR - -build_zm() { - - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then - ./configure --prefix=/usr --with-libarch=lib/$DEB_HOST_GNU_TYPE --host=$DEB_HOST_GNU_TYPE --build=$DEB_BUILD_GNU_TYPE --with-mysql=/usr --with-ffmpeg=/usr --with-webdir=/usr/share/zoneminder/www --with-cgidir=/usr/libexec/zoneminder/cgi-bin --with-webuser=www-data --with-webgroup=www-data --enable-crashtrace=yes --disable-debug --enable-mmap=yes ZM_SSL_LIB=openssl - fi - - if [ "$ZM_BUILDMETHOD" = "cmake" ]; then - cmake -DCMAKE_INSTALL_PREFIX="/usr" - fi - - make - sudo make install - - if [ "$ZM_BUILDMETHOD" = "cmake" ]; then - sudo ./zmlinkcontent.sh - fi - -} - -build_zm | with_timestamps diff --git a/utils/travis/install-deps.sh b/utils/travis/install-deps.sh deleted file mode 100644 index d7981cb5a..000000000 --- a/utils/travis/install-deps.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -set -e -set -o pipefail - -with_timestamps() { - while read -r line; do - echo -e "$(date +%T)\t$line"; - done -} - - -install_deps() { - - sudo apt-get update -qq - sudo apt-get install -y -qq zlib1g-dev apache2 mysql-server php5 php5-mysql build-essential libmysqlclient-dev libssl-dev libbz2-dev libpcre3-dev libdbi-perl libarchive-zip-perl libdate-manip-perl libdevice-serialport-perl libmime-perl libwww-perl libdbd-mysql-perl libsys-mmap-perl yasm automake autoconf cmake libjpeg-turbo8-dev apache2-mpm-prefork libapache2-mod-php5 php5-cli libtheora-dev libvorbis-dev libvpx-dev libx264-dev 2>&1 > /dev/null - -} - -install_deps | with_timestamps diff --git a/utils/travis/install-ffmpeg.sh b/utils/travis/install-ffmpeg.sh deleted file mode 100644 index c2a2e9733..000000000 --- a/utils/travis/install-ffmpeg.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -set -e - - -git clone --depth=10 --branch=master git://source.ffmpeg.org/ffmpeg.git -cd ffmpeg -./configure --enable-shared --enable-swscale --enable-gpl --enable-libx264 --enable-libvpx --enable-libvorbis --enable-libtheora -make -j `grep processor /proc/cpuinfo|wc -l` -sudo make install -sudo make install-libs diff --git a/utils/travis/run-tests.sh b/utils/travis/run-tests.sh deleted file mode 100644 index c3bb392d9..000000000 --- a/utils/travis/run-tests.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -set -e -set -o pipefail - -with_timestamps() { - while read -r line; do - echo -e "$(date +%T)\t$line"; - done -} - -run_tests() { - mysql -uzmuser -pzmpass zm < ../../db/test.monitor.sql - sudo zmu -l - sudo zmc -m1 & - sudo zma -m1 & - sudo zmu -l - sudo grep ERR /var/log/syslog - sudo zmpkg.pl start - sudo zmfilter.pl -f purgewhenfull -} - -run_tests | with_timestamps diff --git a/version b/version index 00bedd170..21cbe96c2 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.35.5 +1.35.6 diff --git a/web/ajax/events.php b/web/ajax/events.php new file mode 100644 index 000000000..7b852c559 --- /dev/null +++ b/web/ajax/events.php @@ -0,0 +1,41 @@ +Id() ) { + $message[] = array($eid=>'Event not found.'); + } else if ( $event->Archived() ) { + $message[] = array($eid=>'Event is archived, cannot delete it.'); + } else { + $event->delete(); + } + break; + } // end switch action + } // end foreach + ajaxResponse($message); +} // end if canEdit('Events') + +ajaxError('Unrecognised action '.$_REQUEST['action'].' or insufficient permissions for user '.$user['Username']); +?> diff --git a/web/css/bootstrap-table-page-jump-to.min.css b/web/css/bootstrap-table-page-jump-to.min.css new file mode 100644 index 000000000..0c8e7d527 --- /dev/null +++ b/web/css/bootstrap-table-page-jump-to.min.css @@ -0,0 +1,10 @@ +/** + * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) + * + * @version v1.17.1 + * @homepage https://bootstrap-table.com + * @author wenzhixin (http://wenzhixin.net.cn/) + * @license MIT + */ + +.bootstrap-table.bootstrap3 .fixed-table-pagination>.pagination .page-jump-to,.bootstrap-table.bootstrap3 .fixed-table-pagination>.pagination ul.pagination{display:inline}.bootstrap-table .fixed-table-pagination>.pagination .page-jump-to input{width:70px;margin-left:5px;text-align:center;float:left} \ No newline at end of file diff --git a/web/includes/Event.php b/web/includes/Event.php index 2f9fa4d20..23f806354 100644 --- a/web/includes/Event.php +++ b/web/includes/Event.php @@ -50,6 +50,9 @@ class Event extends ZM_Object { public static function clear_cache() { return ZM_Object::_clear_cache(get_class()); } + public function remove_from_cache() { + return ZM_Object::_remove_from_cache(get_class(), $this); + } public function Storage( $new = null ) { if ( $new ) { @@ -58,8 +61,10 @@ class Event extends ZM_Object { if ( ! ( property_exists($this, 'Storage') and $this->{'Storage'} ) ) { if ( isset($this->{'StorageId'}) and $this->{'StorageId'} ) $this->{'Storage'} = Storage::find_one(array('Id'=>$this->{'StorageId'})); - if ( ! ( property_exists($this, 'Storage') and $this->{'Storage'} ) ) + if ( ! ( property_exists($this, 'Storage') and $this->{'Storage'} ) ) { $this->{'Storage'} = new Storage(NULL); + $this->{'Storage'}->Scheme($this->{'Scheme'}); + } } return $this->{'Storage'}; } @@ -130,6 +135,10 @@ class Event extends ZM_Object { Error('Event delete on event with empty Id'); return; } + if ( $this->{'Archived'} ) { + Error('Cannot delete an Archived event.'); + return; + } if ( ZM_OPT_FAST_DELETE ) { dbQuery('DELETE FROM Events WHERE Id = ?', array($this->{'Id'})); return; diff --git a/web/includes/Filter.php b/web/includes/Filter.php index ce9d11cd4..4405a7688 100644 --- a/web/includes/Filter.php +++ b/web/includes/Filter.php @@ -30,9 +30,104 @@ class Filter extends ZM_Object { 'Query_json' => '', ); + protected $_querystring; + protected $_sql; + protected $_hidden_fields; + public $_pre_sql_conditions; + public $_post_sql_conditions; + protected $_Terms; + + public function sql() { + if ( ! isset($this->_sql) ) { + foreach ( $this->FilterTerms() as $term ) { + #if ( ! ($term->is_pre_sql() or $term->is_post_sql()) ) { + $this->_sql .= $term->sql(); + #} else { + #$this->_sql .= '1'; + #} + } # end foreach term + } + return $this->_sql; + } + + public function querystring() { + if ( ! isset($this->_querystring) ) { + foreach ( $this->FilterTerms() as $term ) { + $this->_querystring .= $term->querystring(); + } # end foreach term + } + return $this->_querystring; + } + + public function hidden_fields() { + if ( ! isset($this->_hidden_fields) ) { + foreach ( $this->FilterTerms() as $term ) { + $this->_hidden_fields .= $term->hidden_fields(); + } # end foreach term + } + return $this->_hidden_fields; + } + + public function pre_sql_conditions() { + if ( ! isset($this->_pre_sql_conditions) ) { + $this->_pre_sql_conditions = array(); + foreach ( $this->FilterTerms() as $term ) { + if ( $term->is_pre_sql() ) + $this->_pre_sql_conditions[] = $term; + } # end foreach term + } + return $this->_pre_sql_conditions; + } + + public function post_sql_conditions() { + + if ( ! isset($this->_post_sql_conditions) ) { + $this->_post_sql_conditions = array(); + foreach ( $this->FilterTerms() as $term ) { + if ( $term->is_post_sql() ) + $this->_post_sql_conditions[] = $term; + } # end foreach term + } + return $this->_post_sql_conditions; + } + + public function FilterTerms() { + if ( ! isset($this->Terms) ) { + $this->Terms = array(); + $_terms = $this->terms(); + for ( $i = 0; $i < count($_terms); $i++ ) { + $term = new FilterTerm($this, $_terms[$i], $i); + $this->Terms[] = $term; + } # end foreach term + } + return $this->Terms; + } + + public static function parse($new_filter, $querySep='&') { + $filter = new Filter(); + $filter->Query($new_filter['Query']); + return $filter; + } + + # If no storage areas are specified in the terms, then return all + public function get_StorageAreas() { + $storage_ids = array(); + foreach ( $this->Terms as $term ) { + if ( $term->attr == 'StorageId' ) { + # TODO handle other operators like != + $storage_ids[] = $term->value; + } + } + if ( count($storage_ids) ) { + return Storage::find(array('Id'=>$storage_ids)); + } else { + return Storage::find(); + } + } # end function get_StorageAreas + public function Query_json() { if ( func_num_args( ) ) { - $this->{'Query_json'} = func_get_arg(0);; + $this->{'Query_json'} = func_get_arg(0); $this->{'Query'} = jsonDecode($this->{'Query_json'}); } return $this->{'Query_json'}; @@ -40,7 +135,7 @@ class Filter extends ZM_Object { public function Query() { if ( func_num_args( ) ) { - $this->{'Query'} = func_get_arg(0);; + $this->{'Query'} = func_get_arg(0); $this->{'Query_json'} = jsonEncode($this->{'Query'}); } if ( !property_exists($this, 'Query') ) { @@ -183,6 +278,37 @@ class Filter extends ZM_Object { return $status; } + public function test_pre_sql_conditions() { + if ( !count($this->pre_sql_conditions()) ) { + return true; + } # end if pre_sql_conditions + + $failed = false; + foreach ( $this->pre_sql_conditions() as $term ) { + if ( !$term->test() ) { + $failed = true; + break; + } + } + return $failed; + } + + public function test_post_sql_conditions($event) { + if ( !count($this->post_sql_conditions()) ) { + return true; + } # end if pre_sql_conditions + + $failed = true; + foreach ( $this->post_sql_conditions() as $term ) { + if ( !$term->test($event) ) { + $failed = false; + break; + } + } + return $failed; + } + + } # end class Filter ?> diff --git a/web/includes/FilterTerm.php b/web/includes/FilterTerm.php new file mode 100644 index 000000000..1e3af259e --- /dev/null +++ b/web/includes/FilterTerm.php @@ -0,0 +1,414 @@ + translate('ConjAnd'), + 'or' => translate('ConjOr') + ); + } + return $validConjunctionTypes; +} + +class FilterTerm { + public $filter; + public $index; + public $attr; + public $op; + public $val; + public $values; + public $cnj; + public $obr; + public $cbr; + + + public function __construct($filter = null, $term = NULL, $index=0) { + $this->filter = $filter; + $validConjunctionTypes = getFilterQueryConjunctionTypes(); + + $this->index = $index; + $this->attr = $term['attr']; + $this->op = $term['op']; + $this->val = $term['val']; + if ( isset($term['cnj']) ) { + if ( array_key_exists($term['cnj'], $validConjunctionTypes) ) { + $this->cnj = $term['cnj']; + } else { + Warning('Invalid cnj ' . $term['cnj'].' in '.print_r($term, true)); + } + } + + if ( isset($term['obr']) ) { + if ( (string)(int)$term['obr'] == $term['obr'] ) { + $this->obr = $term['obr']; + } else { + Warning('Invalid obr ' . $term['obr'] . ' in ' . print_r($term, true)); + } + } + if ( isset($term['cbr']) ) { + if ( (string)(int)$term['cbr'] == $term['cbr'] ) { + $this->obr = $term['cbr']; + } else { + Warning('Invalid cbr ' . $term['cbr'] . ' in ' . print_r($term, true)); + } + } + } # end function __construct + + # Returns an array of values. AS term->value can be a list, we will break it apart, remove quotes etc + public function sql_values() { + $values = array(); + if ( !isset($this->val) ) { + Logger::Warning("No value in term "); + return $values; + } + + foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $this->val)) as $value ) { + + switch ( $this->attr ) { + + case 'AlarmedZoneId': + $value = '(SELECT * FROM Stats WHERE EventId=E.Id AND ZoneId='.$value.')'; + break; + case 'ExistsInFileSystem': + $value = ''; + break; + case 'MonitorName': + case 'Name': + case 'Cause': + case 'Notes': + if ( $this->op == 'LIKE' || $this->op == 'NOT LIKE' ) { + $value = '%'.$value.'%'; + } + $value = dbEscape($value); + break; + case 'MonitorServerId': + case 'FilterServerId': + case 'StorageServerId': + case 'ServerId': + if ( $value == 'ZM_SERVER_ID' ) { + $value = ZM_SERVER_ID; + } else if ( $value == 'NULL' ) { + + } else { + $value = dbEscape($value); + } + break; + case 'StorageId': + if ( $value != 'NULL' ) { + $value = dbEscape($value); + } + break; + case 'DateTime': + case 'StartDateTime': + case 'EndDateTime': + if ( $value != 'NULL' ) + $value = '\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\''; + break; + case 'Date': + case 'StartDate': + case 'EndDate': + if ( $value == 'CURDATE()' or $value == 'NOW()' ) { + $value = 'to_days('.$value.')'; + } else if ( $value != 'NULL' ) { + $value = 'to_days(\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')'; + } + break; + case 'Time': + case 'StartTime': + case 'EndTime': + if ( $value != 'NULL' ) + $value = 'extract(hour_second from \''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')'; + break; + default : + if ( $value == 'Odd' ) { + $value = 1; + } else if ( $value == 'Even' ) { + $value = 0; + } else if ( $value != 'NULL' ) + $value = dbEscape($value); + break; + } + $values[] = $value; + } // end foreach value + return $values; + } # end function sql_values + + public function sql_operator() { + if ( $this->attr == 'AlarmZoneId' ) { + return ' EXISTS '; + } + if ( $this->attr == 'ExistsInFileSystem' ) { + return ''; + } + + + switch ( $this->op ) { + case '=' : + case '!=' : + case '>=' : + case '>' : + case '<' : + case '<=' : + case 'LIKE' : + case 'NOT LIKE': + return ' '.$this->op.' '; + case '=~' : + return ' regexp '; + case '!~' : + return ' not regexp '; + case '=[]' : + case 'IN' : + return ' IN '; + case '![]' : + return ' NOT IN '; + case 'EXISTS' : + return ' EXISTS '; + case 'IS' : + # Odd will be replaced with 1 + # Even will be replaced with 0 + if ( $this->val == 'Odd' or $this->val == 'Even' ) { + return ' % 2 = '; + } else { + return ' IS '; + } + case 'IS NOT' : + if ( $this->val == 'Odd' or $this->val == 'Even' ) { + return ' % 2 = '; + } + return ' IS NOT '; + default: + ZM\Warning('Invalid operator in filter: ' . print_r($this->op, true)); + } // end switch op + } # end public function sql_operator + + /* Some terms don't have related SQL */ + public function sql() { + + $sql = ''; + if ( isset($this->cnj) ) { + $sql .= ' '.$this->cnj.' '; + } + if ( isset($this->obr) ) { + $sql .= ' '.str_repeat('(', $this->obr).' '; + } + + switch ( $this->attr ) { + case 'ExistsInFileSystem': + $sql .= 'TRUE /*'.$this->attr.'*/'; + break; + case 'MonitorName': + $sql .= 'M.Name'; + break; + case 'ServerId': + case 'MonitorServerId': + $sql .= 'M.ServerId'; + break; + case 'StorageServerId': + $sql .= 'S.ServerId'; + break; + case 'FilterServerId': + $sql .= ZM_SERVER_ID; + break; + # Unspecified start or end, so assume start, this is to support legacy filters + case 'DateTime': + $sql .= 'E.StartTime'; + break; + case 'Date': + $sql .= 'to_days(E.StartTime)'; + break; + case 'Time': + $sql .= 'extract(hour_second FROM E.StartTime)'; + break; + case 'Weekday': + $sql .= 'weekday(E.StartTime)'; + break; + # Starting Time + case 'StartDateTime': + $sql .= 'E.StartTime'; + break; + case 'FramesEventId': + $sql .= 'F.EventId'; + break; + case 'StartDate': + $sql .= 'to_days(E.StartTime)'; + break; + case 'StartTime': + $sql .= 'extract(hour_second FROM E.StartTime)'; + break; + case 'StartWeekday': + $sql .= 'weekday(E.StartTime)'; + break; + # Ending Time + case 'EndDateTime': + $sql .= 'E.EndTime'; + break; + case 'EndDate': + $sql .= 'to_days(E.EndTime)'; + break; + case 'EndTime': + $sql .= 'extract(hour_second FROM E.EndTime)'; + break; + case 'EndWeekday': + $sql .= 'weekday(E.EndTime)'; + break; + case 'Id': + case 'Name': + case 'DiskSpace': + case 'MonitorId': + case 'StorageId': + case 'SecondaryStorageId': + case 'Length': + case 'Frames': + case 'AlarmFrames': + case 'TotScore': + case 'AvgScore': + case 'MaxScore': + case 'Cause': + case 'Notes': + case 'StateId': + case 'Archived': + $sql .= 'E.'.$this->attr; + } + $sql .= $this->sql_operator(); + $values = $this->sql_values(); + if ( (count($values) > 1) or ($this->op == 'IN') or ($this->op == 'NOT IN') ) { + $sql .= '('.join(',', $values).')'; + } else { + $sql .= $values[0]; + } + + if ( isset($this->cbr) ) { + $sql .= ' '.str_repeat(')', $this->cbr).' '; + } + return $sql; + } # end public function sql + + public function querystring($querySep='&') { + # We don't validate the term parameters here + $query = ''; + if ( $this->cnj ) + $query .= $querySep.urlencode('filter[Query][terms]['.$this->index.'][cnj]').'='.$this->cnj; + if ( $this->obr ) + $query .= $querySep.urlencode('filter[Query][terms]['.$this->index.'][obr]').'='.$this->obr; + + $query .= $querySep.urlencode('filter[Query][terms]['.$this->index.'][attr]').'='.urlencode($this->attr); + $query .= $querySep.urlencode('filter[Query][terms]['.$this->index.'][op]').'='.urlencode($this->op); + $query .= $querySep.urlencode('filter[Query][terms]['.$this->index.'][val]').'='.urlencode($this->val); + if ( $this->cbr ) + $query .= $querySep.urlencode('filter[Query][terms]['.$this->index.'][cbr]').'='.$this->cbr; + return $query; + } # end public function querystring + + public function hidden_fields() { + $html =''; + if ( $this->cnj ) + $html .= ''.PHP_EOL; + + if ( $this->obr ) + $html .= ''.PHP_EOL; + + # attr should have been already validation, so shouldn't need htmlspecialchars + $html .= ''.PHP_EOL; + $html .= ''.PHP_EOL; + $html .= ''.PHP_EOL; + if ( $this->cbr ) + $html .= ''.PHP_EOL; + + return $html; + } # end public function hiddens_fields + + public function test($event=null) { + if ( !isset($event) ) { + # Is a Pre Condition + Logger::Debug("Testing " . $this->attr); + if ( $this->attr == 'DiskPercent' ) { + # The logic on this is really ugly. We are going to treat it as an OR + foreach ( $this->filter->get_StorageAreas() as $storage ) { + $string_to_eval = 'return $storage->disk_usage_percent() '.$this->op.' '.$this->val.';'; + try { + $ret = eval($string_to_eval); + Logger::Debug("Evalled $string_to_eval = $ret"); + if ( $ret ) + return true; + } catch ( Throwable $t ) { + Error('Failed evaluating '.$string_to_eval); + return false; + } + } # end foreach Storage Area + } else if ( $this->attr == 'SystemLoad' ) { + $string_to_eval = 'return getLoad() '.$this->op.' '.$this->val.';'; + try { + $ret = eval($string_to_eval); + Logger::Debug("Evaled $string_to_eval = $ret"); + if ( $ret ) + return true; + } catch ( Throwable $t ) { + Error('Failed evaluating '.$string_to_eval); + return false; + } + } else { + Error('testing unsupported pre term ' . $this->attr); + } + } else { + # Is a Post Condition + if ( $this->attr == 'ExistsInFileSystem' ) { + if ( + ($this->op == 'IS' and $this->val == 'True') + or + ($this->op == 'IS NOT' and $this->val == 'False') + ) { + return file_exists($event->Path()); + } else { + return !file_exists($event->Path()); + } + } else if ( $this->attr == 'DiskPercent' ) { + $string_to_eval = 'return $event->Storage()->disk_usage_percent() '.$this->op.' '.$this->val.';'; + try { + $ret = eval($string_to_eval); + Logger::Debug("Evalled $string_to_eval = $ret"); + if ( $ret ) + return true; + } catch ( Throwable $t ) { + Error('Failed evaluating '.$string_to_eval); + return false; + } + } else if ( $this->attr == 'DiskBlocks' ) { + $string_to_eval = 'return $event->Storage()->disk_usage_blocks() '.$this->op.' '.$this->val.';'; + try { + $ret = eval($string_to_eval); + Logger::Debug("Evalled $string_to_eval = $ret"); + if ( $ret ) + return true; + } catch ( Throwable $t ) { + Error('Failed evaluating '.$string_to_eval); + return false; + } + } else { + Error('testing unsupported post term ' . $this->attr); + } + } + return false; + } + + public function is_pre_sql() { + if ( $this->attr == 'DiskPercent' ) { + return true; + } + return false; + } + + public function is_post_sql() { + if ( $this->attr == 'ExistsInFileSystem' ) { + return true; + } else if ( $this->attr == 'DiskPercent' ) { + return true; + } + return false; + } + +} # end class FilterTerm + +?> diff --git a/web/includes/Group_Monitor.php b/web/includes/Group_Monitor.php new file mode 100644 index 000000000..a015c5e60 --- /dev/null +++ b/web/includes/Group_Monitor.php @@ -0,0 +1,20 @@ + null, + 'GroupId' => null, + 'MonitorId' => null, + ); + + public static function find( $parameters = array(), $options = array() ) { + return ZM_Object::_find(get_class(), $parameters, $options); + } + + public static function find_one( $parameters = array(), $options = array() ) { + return ZM_Object::_find_one(get_class(), $parameters, $options); + } +} # end class Group_Monitor +?> diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index d9c6df4c1..02911aa73 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -5,6 +5,23 @@ require_once('Server.php'); require_once('Object.php'); require_once('Control.php'); require_once('Storage.php'); +require_once('Group.php'); + +$FunctionTypes = null; + +function getMonitorFunctionTypes() { + if ( !isset($FunctionTypes ) ) { + $FunctionTypes = array( + 'None' => translate('FnNone'), + 'Monitor' => translate('FnMonitor'), + 'Modect' => translate('FnModect'), + 'Record' => translate('FnRecord'), + 'Mocord' => translate('FnMocord'), + 'Nodect' => translate('FnNodect') + ); + } + return $FunctionTypes; +} class Monitor extends ZM_Object { protected static $table = 'Monitors'; @@ -133,7 +150,7 @@ class Monitor extends ZM_Object { public function Server() { if ( !property_exists($this, 'Server') ) { - if ( $this->ServerId() ) + if ( $this->ServerId() ) $this->{'Server'} = Server::find_one(array('Id'=>$this->{'ServerId'})); if ( !property_exists($this, 'Server') ) { $this->{'Server'} = new Server(); @@ -199,17 +216,25 @@ class Monitor extends ZM_Object { $args['user'] = $_SESSION['username']; } } - if ( ( (!isset($args['mode'])) or ( $args['mode'] != 'single' ) ) && !empty($GLOBALS['connkey']) ) { - $args['connkey'] = $GLOBALS['connkey']; + if ( (!isset($args['mode'])) or ( $args['mode'] != 'single' ) ) { + $args['connkey'] = $this->connKey(); } if ( ZM_RAND_STREAM ) { $args['rand'] = time(); } - foreach ( array('scale') as $int_arg ) { - if ( isset($args[$int_arg]) and (!is_numeric($args[$int_arg]) or !$args[$int_arg] ) ) { - unset($args[$int_arg]); + + # zms doesn't support width & height, so if no scale is set, default it + if ( ! isset($args['scale']) ) { + if ( isset($args['width']) and intval($args['width']) ) { + $args['scale'] = intval((100*intval($args['width']))/$this->ViewWidth()); + } else if ( isset($args['height']) and intval($args['height']) ) { + $args['scale'] = intval((100*intval($args['height']))/$this->ViewHeight()); } } + if ( isset($args['width']) ) + unset($args['width']); + if ( isset($args['height']) ) + unset($args['height']); $streamSrc .= '?'.http_build_query($args, '', $querySep); @@ -307,7 +332,7 @@ class Monitor extends ZM_Object { $context = stream_context_create(); try { $result = file_get_contents($url, false, $context); - if ( $result === FALSE ) { /* Handle error */ + if ( $result === FALSE ) { /* Handle error */ Error("Error restarting zmc using $url"); } } catch ( Exception $e ) { @@ -326,7 +351,7 @@ class Monitor extends ZM_Object { if ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) { if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) { - if ( ZM_OPT_CONTROL && $this->Controllable() && $this->TrackMotion() && + if ( ZM_OPT_CONTROL && $this->Controllable() && $this->TrackMotion() && ( $this->{'Function'} == 'Modect' || $this->{'Function'} == 'Mocord' ) ) { daemonControl('stop', 'zmtrack.pl', '-m '.$this->{'Id'}); } @@ -339,7 +364,7 @@ class Monitor extends ZM_Object { daemonControl('stop', 'zma', '-m '.$this->{'Id'}); } daemonControl('start', 'zma', '-m '.$this->{'Id'}); - if ( ZM_OPT_CONTROL && $this->Controllable() && $this->TrackMotion() && + if ( ZM_OPT_CONTROL && $this->Controllable() && $this->TrackMotion() && ( $this->{'Function'} == 'Modect' || $this->{'Function'} == 'Mocord' ) ) { daemonControl('start', 'zmtrack.pl', '-m '.$this->{'Id'}); } @@ -438,8 +463,8 @@ class Monitor extends ZM_Object { $this->{'Storage'} = $new; } if ( ! ( property_exists($this, 'Storage') and $this->{'Storage'} ) ) { - $this->{'Storage'} = isset($this->{'StorageId'}) ? - Storage::find_one(array('Id'=>$this->{'StorageId'})) : + $this->{'Storage'} = isset($this->{'StorageId'}) ? + Storage::find_one(array('Id'=>$this->{'StorageId'})) : new Storage(NULL); if ( ! $this->{'Storage'} ) $this->{'Storage'} = new Storage(NULL); @@ -480,7 +505,7 @@ class Monitor extends ZM_Object { if ( isset($url_parts['port']) and ( $url_parts['port'] == '80' or $url_parts['port'] == '554' ) ) unset($url_parts['port']); $source = unparse_url($url_parts); - } else { # Don't filter anything + } else { # Don't filter anything $source = $this->{'Path'}; } } @@ -582,5 +607,26 @@ class Monitor extends ZM_Object { return true; } // end function sendControlCommand($mid, $command) + function Groups($new='') { + if ( $new != '' ) + $this->Groups = $new; + if ( !property_exists($this, 'Groups') ) { + $this->Groups = Group::find(array('Id'=>$this->GroupIds())); + } + return $this->Groups; + } + function connKey($new='') { + if ( $new ) + $this->connKey = $new; + if ( !isset($this->connKey) ) { + if ( !empty($GLOBALS['connkey']) ) { + $this->connKey = $GLOBALS['connkey']; + } else { + $this->connKey = generateConnKey(); + } + } + return $this->connKey; + } + } // end class Monitor ?> diff --git a/web/includes/Object.php b/web/includes/Object.php index f49497276..75477c08a 100644 --- a/web/includes/Object.php +++ b/web/includes/Object.php @@ -141,10 +141,15 @@ class ZM_Object { global $object_cache; $object_cache[$class] = array(); } + public function _remove_from_cache($class, $object) { + global $object_cache; + unset($object_cache[$class][$object->Id()]); + Logger::Debug("Unsset $class " . $object->Id() . " " . count($object_cache[$class])); + } - public static function Objects_Indexed_By_Id($class) { + public static function Objects_Indexed_By_Id($class, $params=null) { $results = array(); - foreach ( ZM_Object::_find($class, null, array('order'=>'lower(Name)')) as $Object ) { + foreach ( ZM_Object::_find($class, $params, array('order'=>'lower(Name)')) as $Object ) { $results[$Object->Id()] = $Object; } return $results; diff --git a/web/includes/Server.php b/web/includes/Server.php index d49a4e914..bf3dfeb51 100644 --- a/web/includes/Server.php +++ b/web/includes/Server.php @@ -106,7 +106,6 @@ class Server extends ZM_Object { if ( $this->Protocol() == 'https' and $port == 443 ) { } else if ( $this->Protocol() == 'http' and $port == 80 ) { } else { - Logger::Debug("Adding port $port for " . $this->Protocol()); $url .= ':'.$port; } return $url; diff --git a/web/includes/Storage.php b/web/includes/Storage.php index 099b98f4d..2c243d913 100644 --- a/web/includes/Storage.php +++ b/web/includes/Storage.php @@ -69,6 +69,14 @@ class Storage extends ZM_Object { return $this->{'EventCount'}; } + public function disk_used_blocks() { + $df = shell_exec('df '.escapeshellarg($this->Path())); + $space = -1; + if ( preg_match('/\s(\d+)\s+\d+\s+\d+%/ms', $df, $matches) ) + $space = $matches[1]; + return $space; + } + public function disk_usage_percent() { $path = $this->Path(); if ( ! $path ) { @@ -106,7 +114,7 @@ class Storage extends ZM_Object { public function disk_used_space() { # This isn't a function like this in php, so we have to add up the space used in each event. if ( ( !property_exists($this, 'disk_used_space')) or !$this->{'disk_used_space'} ) { - if ( $this->{'Type'} == 's3fs' ) { + if ( $this->Type() == 's3fs' ) { $this->{'disk_used_space'} = $this->event_disk_space(); } else { $path = $this->Path(); @@ -123,7 +131,7 @@ class Storage extends ZM_Object { public function event_disk_space() { # This isn't a function like this in php, so we have to add up the space used in each event. - if ( (! property_exists($this, 'DiskSpace')) or (!$this->{'DiskSpace'}) ) { + if ( (! property_exists($this, 'DiskSpace')) or (!isset($this->{'DiskSpace'})) ) { $used = dbFetchOne('SELECT SUM(DiskSpace) AS DiskSpace FROM Events WHERE StorageId=? AND DiskSpace IS NOT NULL', 'DiskSpace', array($this->Id())); do { diff --git a/web/includes/actions/events.php b/web/includes/actions/events.php index abea69b60..41a693ccc 100644 --- a/web/includes/actions/events.php +++ b/web/includes/actions/events.php @@ -31,14 +31,18 @@ if ( !canEdit('Events') ) { if ( $action == 'archive' ) { $dbConn->beginTransaction(); - foreach( getAffectedIds('eids') as $markEid ) { + $eids = getAffectedIds('eids'); + ZM\Logger::Debug("E IDS" . print_r($eids, true)); + foreach ( $eids as $markEid ) { dbQuery('UPDATE Events SET Archived=? WHERE Id=?', array(1, $markEid)); } $dbConn->commit(); $refreshParent = true; } else if ( $action == 'unarchive' ) { $dbConn->beginTransaction(); - foreach( getAffectedIds('eids') as $markEid ) { + $eids = getAffectedIds('eids'); + ZM\Logger::Debug("E IDS" . print_r($eids, true)); + foreach ( $eids as $markEid ) { dbQuery('UPDATE Events SET Archived=? WHERE Id=?', array(0, $markEid)); } $dbConn->commit(); @@ -48,5 +52,7 @@ if ( $action == 'archive' ) { deleteEvent($markEid); } $refreshParent = true; +} else { + ZM\Warning("Unsupported action $action in events"); } ?> diff --git a/web/includes/actions/filter.php b/web/includes/actions/filter.php index a2e272025..2725c70fc 100644 --- a/web/includes/actions/filter.php +++ b/web/includes/actions/filter.php @@ -95,6 +95,7 @@ if ( isset($_REQUEST['object']) and ( $_REQUEST['object'] == 'filter' ) ) { } else if ( $filter->Background() ) { $filter->control('start'); } + $redirect = '?view=filter&Id='.$filter->Id(); } else if ( $action == 'control' ) { if ( $_REQUEST['command'] == 'start' diff --git a/web/includes/actions/function.php b/web/includes/actions/function.php index 00e4e21f7..adf85de38 100644 --- a/web/includes/actions/function.php +++ b/web/includes/actions/function.php @@ -31,20 +31,21 @@ if ( !canEdit('Monitors', $mid) ) { } if ( $action == 'function' ) { - $monitor = dbFetchOne('SELECT * FROM Monitors WHERE Id=?', NULL, array($mid)); + $monitor = new ZM\Monitor($mid); + if ( !$monitor ) { + ZM\Error("Monitor not found with Id=$mid"); + return; + } $newFunction = validStr($_REQUEST['newFunction']); # Because we use a checkbox, it won't get passed in the request. So not being in _REQUEST means 0 $newEnabled = ( !isset($_REQUEST['newEnabled']) or $_REQUEST['newEnabled'] != '1' ) ? '0' : '1'; - $oldFunction = $monitor['Function']; - $oldEnabled = $monitor['Enabled']; + $oldFunction = $monitor->Function(); + $oldEnabled = $monitor->Enabled(); if ( $newFunction != $oldFunction || $newEnabled != $oldEnabled ) { - dbQuery('UPDATE Monitors SET `Function`=?, `Enabled`=? WHERE `Id`=?', - array($newFunction, $newEnabled, $mid)); + $monitor->save(array('Function'=>$newFunction, 'Enabled'=>$newEnabled)); - $monitor['Function'] = $newFunction; - $monitor['Enabled'] = $newEnabled; - if ( daemonCheck() && ($monitor['Type'] != 'WebSite') ) { + if ( daemonCheck() && ($monitor->Type() != 'WebSite') ) { zmaControl($monitor, 'stop'); zmcControl($monitor, ($newFunction != 'None') ? 'restart' : 'stop'); if ( $newFunction != 'None' && $newFunction != 'NoDect' ) diff --git a/web/includes/actions/logout.php b/web/includes/actions/logout.php index aecdb7683..999d7d772 100644 --- a/web/includes/actions/logout.php +++ b/web/includes/actions/logout.php @@ -21,9 +21,10 @@ if ( $action == 'logout' ) { userLogout(); - $refreshParent = true; - $view = 'none'; - $closePopup = true; + $view = 'login'; ZM\Logger::Debug("User: " . print_r($user,true)); +} elseif ( $action == 'config' ) { + $redirect = '?view=user&uid='.$user['Id']; } + ?> diff --git a/web/includes/actions/monitor.php b/web/includes/actions/monitor.php index 78b64e13c..fe8581f54 100644 --- a/web/includes/actions/monitor.php +++ b/web/includes/actions/monitor.php @@ -272,9 +272,8 @@ if ( $action == 'monitor' ) { } // really should thump zmwatch and maybe zmtrigger too. //daemonControl( 'restart', 'zmwatch.pl' ); - $refreshParent = true; } // end if restart - $view = 'none'; + $view = 'console'; } else { ZM\Warning("Unknown action $action in Monitor"); } // end if action == Delete diff --git a/web/includes/auth.php b/web/includes/auth.php index c3a34405d..e49f5876b 100644 --- a/web/includes/auth.php +++ b/web/includes/auth.php @@ -260,6 +260,22 @@ function userFromSession() { return $user; } +function get_auth_relay() { + if ( ZM_OPT_USE_AUTH ) { + if ( ZM_AUTH_RELAY == 'hashed' ) { + return 'auth='.generateAuthHash(ZM_AUTH_HASH_IPS); + } else if ( ZM_AUTH_RELAY == 'plain' ) { + // password probably needs to be escaped + return 'username='.$_SESSION['username'].'&password='.urlencode($_SESSION['password']); + } else if ( ZM_AUTH_RELAY == 'none' ) { + return 'username='.$_SESSION['username']; + } else { + ZM\Error('Unknown value for ZM_AUTH_RELAY ' . ZM_AUTH_RELAY); + } + } + return ''; +} // end function get_auth_relay + if ( ZM_OPT_USE_AUTH ) { if ( !empty($_REQUEST['token']) ) { // we only need to get the username here diff --git a/web/includes/config.php.in b/web/includes/config.php.in index 7052a061a..65dbcdbd9 100644 --- a/web/includes/config.php.in +++ b/web/includes/config.php.in @@ -31,7 +31,7 @@ global $configvals; $configFile = ZM_CONFIG; $localConfigFile = basename($configFile); -if ( file_exists( $localConfigFile ) && filesize( $localConfigFile ) > 0 ) { +if ( file_exists($localConfigFile) && filesize($localConfigFile) > 0 ) { if ( php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR']) ) print("Warning, overriding installed $localConfigFile file with local copy\n"); else @@ -47,15 +47,15 @@ $configvals = process_configfile($configFile); $configSubFolder = ZM_CONFIG_SUBDIR; if ( is_dir($configSubFolder) ) { if ( is_readable($configSubFolder) ) { - foreach ( glob("$configSubFolder/*.conf") as $filename ) { + foreach ( glob($configSubFolder.'/*.conf') as $filename ) { //error_log("processing $filename"); $configvals = array_replace($configvals, process_configfile($filename)); } } else { - error_log("WARNING: ZoneMinder configuration subfolder found but is not readable. Check folder permissions on $configSubFolder."); + error_log('WARNING: ZoneMinder configuration subfolder found but is not readable. Check folder permissions on '.$configSubFolder); } } else { - error_log("WARNING: ZoneMinder configuration subfolder found but is not a directory. Check $configSubFolder."); + error_log('WARNING: ZoneMinder configuration subfolder found but is not a directory. Check '.$configSubFolder); } # Now that our array our finalized, define each key => value @@ -67,73 +67,73 @@ foreach ( $configvals as $key => $value ) { // // This section is options normally derived from other options or configuration // -define( 'ZMU_PATH', ZM_PATH_BIN.'/zmu' ); // Local path to the ZoneMinder Utility +define('ZMU_PATH', ZM_PATH_BIN.'/zmu'); // Local path to the ZoneMinder Utility // // If setup supports Video 4 Linux v2 and/or v1 // -define( 'ZM_HAS_V4L2', '@ZM_HAS_V4L2@' ); // V4L2 support enabled -define( 'ZM_HAS_V4L1', '@ZM_HAS_V4L1@' ); // V4L1 support enabled -define( 'ZM_HAS_V4L', '@ZM_HAS_V4L@' ); // V4L support enabled +define('ZM_HAS_V4L2', '@ZM_HAS_V4L2@'); // V4L2 support enabled +define('ZM_HAS_V4L1', '@ZM_HAS_V4L1@'); // V4L1 support enabled +define('ZM_HAS_V4L', '@ZM_HAS_V4L@'); // V4L support enabled // // If ONVIF support has been built in // -define( 'ZM_HAS_ONVIF', '@ZM_HAS_ONVIF@' ); // ONVIF support enabled +define('ZM_HAS_ONVIF', '@ZM_HAS_ONVIF@'); // ONVIF support enabled // // If PCRE dev libraries are installed // -define( 'ZM_PCRE', '@ZM_PCRE@' ); // PCRE support enabled +define('ZM_PCRE', '@ZM_PCRE@'); // PCRE support enabled // // Alarm states // -define( 'STATE_IDLE', 0 ); -define( 'STATE_PREALARM', 1 ); -define( 'STATE_ALARM', 2 ); -define( 'STATE_ALERT', 3 ); -define( 'STATE_TAPE', 4 ); +define('STATE_IDLE', 0); +define('STATE_PREALARM', 1); +define('STATE_ALARM', 2); +define('STATE_ALERT', 3); +define('STATE_TAPE', 4); // // DVR Control Commands // -define( 'MSG_CMD', 1 ); -define( 'MSG_DATA_WATCH', 2 ); -define( 'MSG_DATA_EVENT', 3 ); +define('MSG_CMD', 1); +define('MSG_DATA_WATCH', 2); +define('MSG_DATA_EVENT', 3); -define( 'CMD_NONE', 0 ); -define( 'CMD_PAUSE', 1 ); -define( 'CMD_PLAY', 2 ); -define( 'CMD_STOP', 3 ); -define( 'CMD_FASTFWD', 4 ); -define( 'CMD_SLOWFWD', 5 ); -define( 'CMD_SLOWREV', 6 ); -define( 'CMD_FASTREV', 7 ); -define( 'CMD_ZOOMIN', 8 ); -define( 'CMD_ZOOMOUT', 9 ); -define( 'CMD_PAN', 10 ); -define( 'CMD_SCALE', 11 ); -define( 'CMD_PREV', 12 ); -define( 'CMD_NEXT', 13 ); -define( 'CMD_SEEK', 14 ); -define( 'CMD_VARPLAY', 15 ); -define( 'CMD_QUIT', 17 ); -define( 'CMD_QUERY', 99 ); +define('CMD_NONE', 0); +define('CMD_PAUSE', 1); +define('CMD_PLAY', 2); +define('CMD_STOP', 3); +define('CMD_FASTFWD', 4); +define('CMD_SLOWFWD', 5); +define('CMD_SLOWREV', 6); +define('CMD_FASTREV', 7); +define('CMD_ZOOMIN', 8); +define('CMD_ZOOMOUT', 9); +define('CMD_PAN', 10); +define('CMD_SCALE', 11); +define('CMD_PREV', 12); +define('CMD_NEXT', 13); +define('CMD_SEEK', 14 ); +define('CMD_VARPLAY', 15); +define('CMD_QUIT', 17); +define('CMD_QUERY', 99); // // These are miscellaneous options you won't normally need to change // -define( 'MAX_EVENTS', 10 ); // The maximum number of events to show in the monitor event listing -define( 'RATE_BASE', 100 ); // The additional scaling factor used to help get fractional rates in integer format -define( 'SCALE_BASE', 100 ); // The additional scaling factor used to help get fractional scales in integer format +define('MAX_EVENTS', 10); // The maximum number of events to show in the monitor event listing +define('RATE_BASE', 100); // The additional scaling factor used to help get fractional rates in integer format +define('SCALE_BASE', 100); // The additional scaling factor used to help get fractional scales in integer format // // Date and time formats, not to be modified by language files // -define( 'STRF_FMT_DATETIME_DB', '%Y-%m-%d %H:%M:%S' ); // Strftime format for database queries, don't change -define( 'MYSQL_FMT_DATETIME_SHORT', '%y/%m/%d %H:%i:%S' ); // MySQL date_format shorter format for dates with time +define('STRF_FMT_DATETIME_DB', '%Y-%m-%d %H:%M:%S'); // Strftime format for database queries, don't change +define('MYSQL_FMT_DATETIME_SHORT', '%y/%m/%d %H:%i:%S'); // MySQL date_format shorter format for dates with time require_once('database.php'); require_once('logger.php'); @@ -166,10 +166,18 @@ function loadConfig( $defineConsts=true ) { if ( !$result ) echo mysql_error(); while( $row = dbFetchNext($result) ) { - if ( $defineConsts ) - define($row['Name'], $row['Value']); $config[$row['Name']] = $row; + + if ( $defineConsts ) { + # Values in conf.d files override db so check if already defined and update value + if ( ! defined($row['Name']) ) { + define($row['Name'], $row['Value']); + } else { + $config[$row['Name']]['Value'] = constant($row['Name']); + } + } } + return $config; } # end function loadConfig // For Human-readability, use ZM_SERVER_HOST or ZM_SERVER_NAME in zm.conf, and convert it here to a ZM_SERVER_ID @@ -197,15 +205,15 @@ if ( defined('ZM_TIMEZONE') and ZM_TIMEZONE ) ini_set('date.timezone', ZM_TIMEZONE); function process_configfile($configFile) { - if ( is_readable( $configFile ) ) { + if ( is_readable($configFile) ) { $configvals = array(); - $cfg = fopen($configFile, 'r') or ZM\Error("Could not open config file: $configFile."); + $cfg = fopen($configFile, 'r') or ZM\Error('Could not open config file: '.$configFile); while ( !feof($cfg) ) { $str = fgets($cfg, 256); if ( preg_match('/^\s*(#.*)?$/', $str) ) { continue; - } else if ( preg_match( '/^\s*([^=\s]+)\s*=\s*[\'"]*(.*?)[\'"]*\s*$/', $str, $matches )) { + } else if ( preg_match('/^\s*([^=\s]+)\s*=\s*[\'"]*(.*?)[\'"]*\s*$/', $str, $matches) ) { $configvals[$matches[1]] = $matches[2]; } else { ZM\Error("Malformed line in config $configFile\n$str"); @@ -214,7 +222,7 @@ function process_configfile($configFile) { fclose($cfg); return $configvals; } else { - error_log("WARNING: ZoneMinder configuration file found but is not readable. Check file permissions on $configFile."); + error_log('WARNING: ZoneMinder configuration file found but is not readable. Check file permissions on '.$configFile); return false; } } diff --git a/web/includes/csrf/csrf-magic.php b/web/includes/csrf/csrf-magic.php index d96165eb9..edb04002a 100644 --- a/web/includes/csrf/csrf-magic.php +++ b/web/includes/csrf/csrf-magic.php @@ -389,7 +389,7 @@ function csrf_conf($key, $val) { */ function csrf_start() { if ($GLOBALS['csrf']['auto-session'] && !session_id()) { - session_start(); + zm_session_start(); } } diff --git a/web/includes/database.php b/web/includes/database.php index 7404d085e..4298b4ce8 100644 --- a/web/includes/database.php +++ b/web/includes/database.php @@ -153,10 +153,7 @@ function dbQuery($sql, $params=NULL) { } } if ( defined('ZM_DB_DEBUG') ) { - if ( $params ) - ZM\Logger::Debug("SQL: $sql " . implode(',',$params) . ' rows: '.$result->rowCount()); - else - ZM\Logger::Debug("SQL: $sql: rows:" . $result->rowCount()); + ZM\Logger::Debug('SQL: '.$sql.' '.($params?implode(',',$params):'').' rows: '.$result->rowCount()); } } catch(PDOException $e) { ZM\Error("SQL-ERR '".$e->getMessage()."', statement was '".$sql."' params:" . ($params?implode(',',$params):'')); diff --git a/web/includes/functions.php b/web/includes/functions.php index e50fd23c2..4e361025a 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -17,6 +17,9 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // +// +require_once('Filter.php'); +require_once('FilterTerm.php'); // Compatibility functions if ( version_compare(phpversion(), '4.3.0', '<') ) { @@ -175,7 +178,7 @@ function getVideoStreamHTML($id, $src, $width, $height, $format, $title='') { $mimeType = 'video/3gpp'; break; default : - $mimeType = "video/$format"; + $mimeType = 'video/'.$format; break; } } @@ -333,7 +336,7 @@ function getWebSiteUrl($id, $src, $width, $height, $title='') { if ( array_key_exists('X-Frame-Options', $header) ) { $header = $header['X-Frame-Options']; if ( stripos($header, 'sameorigin') === 0 ) - ZM\Warning("Web site $src has X-Frame-Options set to sameorigin. An X-Frame-Options browser plugin is required to display this site."); + ZM\Warning('Web site '.$src.' has X-Frame-Options set to sameorigin. An X-Frame-Options browser plugin is required to display this site.'); } } return ''; @@ -391,7 +394,7 @@ function getEventDefaultVideoPath($event) { } function deletePath( $path ) { - ZM\Logger::Debug("Deleting $path"); + ZM\Logger::Debug('Deleting '.$path); if ( is_dir($path) ) { system(escapeshellcmd('rm -rf '.$path)); } else if ( file_exists($path) ) { @@ -409,17 +412,15 @@ function deleteEvent($event) { if ( gettype($event) != 'array' ) { # $event could be an eid, so turn it into an event hash $event = new ZM\Event($event); - } else { -ZM\Logger::Debug("Event type: " . gettype($event)); } - global $user; - if ( $event->Archived() ) { ZM\Info('Cannot delete Archived event.'); return; } # end if Archived + global $user; + if ( $user['Events'] == 'Edit' ) { $event->delete(); } # CAN EDIT @@ -493,13 +494,13 @@ function htmlSelect($name, $contents, $values, $behaviours=false) { } } - return "'; + return ''; } -function htmlOptions($contents, $values) { +function htmlOptions($options, $values) { $options_html = ''; - - foreach ( $contents as $value=>$option ) { + $has_selected = false; + foreach ( $options as $value=>$option ) { $disabled = 0; $text = ''; if ( is_array($option) ) { @@ -517,15 +518,21 @@ function htmlOptions($contents, $values) { } else { $text = $option; } - $selected = is_array($values) ? in_array($value, $values) : !strcmp($value, $values); + $selected = is_array($values) ? in_array($value, $values) : (!strcmp($value, $values)); + if ( !$has_selected ) + $has_selected = $selected; + $options_html .= ' '; + } # end foreach options + if ( $values and ! $has_selected ) { + ZM\Warning('Specified value '.$values.' not in contents: '.print_r($options, true)); } return $options_html; -} +} # end function htmlOptions function truncText($text, $length, $deslash=1) { return preg_replace('/^(.{'.$length.',}?)\b.*$/', '\\1…', ($deslash?stripslashes($text):$text)); @@ -607,7 +614,7 @@ function getFormChanges($values, $newValues, $types=false, $columns=false) { $imageData = getimagesize( $newValues[$key]['tmp_name'] ); $changes[$key.'Width'] = $key.'Width = '.$imageData[0]; $changes[$key.'Height'] = $key.'Height = '.$imageData[1]; - $changes[$key.'Type'] = $key."Type = '".$newValues[$key]['type']."'"; + $changes[$key.'Type'] = $key.'Type = \''.$newValues[$key]['type'].'\''; $changes[$key.'Size'] = $key.'Size = '.$newValues[$key]['size']; ob_start(); readfile( $newValues[$key]['tmp_name'] ); @@ -620,7 +627,7 @@ function getFormChanges($values, $newValues, $types=false, $columns=false) { case 'document' : if ( is_array( $newValues[$key] ) ) { $imageData = getimagesize( $newValues[$key]['tmp_name'] ); - $changes[$key.'Type'] = $key."Type = '".$newValues[$key]['type']."'"; + $changes[$key.'Type'] = $key.'Type = \''.$newValues[$key]['type'].'\''; $changes[$key.'Size'] = $key.'Size = '.$newValues[$key]['size']; ob_start(); readfile( $newValues[$key]['tmp_name'] ); @@ -635,7 +642,7 @@ function getFormChanges($values, $newValues, $types=false, $columns=false) { $changes[$key.'Size'] = $key.'Size = '.dbEscape($newValues[$key]['size']); ob_start(); readfile( $newValues[$key]['tmp_name'] ); - $changes[$key] = $key." = '".dbEscape( ob_get_contents() )."'"; + $changes[$key] = $key.' = \''.dbEscape( ob_get_contents() ).'\''; ob_end_clean(); break; case 'raw' : @@ -646,9 +653,9 @@ function getFormChanges($values, $newValues, $types=false, $columns=false) { case 'toggle' : if ( (!isset($values[$key])) or $values[$key] != $value ) { if ( empty($value) ) { - $changes[$key] = "$key = 0"; + $changes[$key] = $key.' = 0'; } else { - $changes[$key] = "$key = 1"; + $changes[$key] = $key.' = 1'; //$changes[$key] = $key . ' = '.dbEscape(trim($value)); } } @@ -675,10 +682,10 @@ function getFormChanges($values, $newValues, $types=false, $columns=false) { if ( !empty($types[$key]) ) { if ( $types[$key] == 'toggle' ) { if ( !isset($newValues[$key]) && !empty($value) ) { - $changes[$key] = "$key = 0"; + $changes[$key] = "`$key` = 0"; } } else if ( $types[$key] == 'set' ) { - $changes[$key] = "$key = ''"; + $changes[$key] = "`$key` = ''"; } } } @@ -810,7 +817,7 @@ function daemonControl($command, $daemon=false, $args=false) { } $string = escapeshellcmd($string); #$string .= ' 2>/dev/null >&- <&- >/dev/null'; - ZM\Logger::Debug("daemonControl $string"); + ZM\Logger::Debug('daemonControl '.$string); exec($string); } @@ -846,7 +853,6 @@ function daemonStatus($daemon, $args=false) { if ( $args ) { if ( is_array($args) ) { $string .= join(' ', $args); -ZM\Warning("daemonStatus args: $string"); } else { $string .= ' ' . $args; } @@ -867,7 +873,7 @@ function zmaStatus($monitor) { if ( is_array($monitor) ) { $monitor = $monitor['Id']; } - return daemonStatus('zma', "-m $monitor"); + return daemonStatus('zma', '-m '.$monitor); } function daemonCheck($daemon=false, $args=false) { @@ -895,7 +901,7 @@ function zmaCheck($monitor) { if ( is_array($monitor) ) { $monitor = $monitor['Id']; } - return daemonCheck('zma', "-m $monitor"); + return daemonCheck('zma', '-m '.$monitor); } function getImageSrc($event, $frame, $scale=SCALE_BASE, $captureOnly=false, $overwrite=false) { @@ -1087,288 +1093,24 @@ function parseSort($saveToSession=false, $querySep='&') { } } -function getFilterQueryConjunctionTypes() { - return array( - 'and' => translate('ConjAnd'), - 'or' => translate('ConjOr') - ); -} - +# Historically this function has just modified the passed in filter array. +# This would normally be $_REQUEST['filter']; We don't like modifying +# request parameters. For now we will keep this behaviour, but note that we +# now return the resulting array and other code should by modified to use that. +# +# Please note that I will be removing the savetosession code as well. function parseFilter(&$filter, $saveToSession=false, $querySep='&') { - $filter['query'] = ''; - $filter['sql'] = ''; - $filter['fields'] = ''; - $validQueryConjunctionTypes = getFilterQueryConjunctionTypes(); - $StorageArea = NULL; + $Filter = ZM\Filter::parse($filter, $querySep); - # It is not possible to pass an empty array in the url, so we have to deal with there not being a terms field. - $terms = (isset($filter['Query']) and isset($filter['Query']['terms']) and is_array($filter['Query']['terms'])) ? $filter['Query']['terms'] : array(); + $filter['sql'] = $Filter->sql(); + $filter['querystring'] = $Filter->querystring(); + $filter['hidden_fields'] = $Filter->hidden_fields(); + $filter['pre_sql_conditions'] = $Filter->pre_sql_conditions(); + $filter['post_sql_conditions'] = $Filter->post_sql_conditions(); - if ( count($terms) ) { - for ( $i = 0; $i < count($terms); $i++ ) { - - $term = $terms[$i]; - - if ( isset($term['cnj']) && array_key_exists($term['cnj'], $validQueryConjunctionTypes) ) { - $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cnj]").'='.urlencode($term['cnj']); - $filter['sql'] .= ' '.$term['cnj'].' '; - $filter['fields'] .= "\n"; - } - if ( isset($term['obr']) && (string)(int)$term['obr'] == $term['obr'] ) { - $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][obr]").'='.urlencode($term['obr']); - $filter['sql'] .= ' '.str_repeat('(', $term['obr']).' '; - $filter['fields'] .= "\n"; - } - if ( isset($term['attr']) ) { - $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][attr]").'='.urlencode($term['attr']); - $filter['fields'] .= "\n"; - switch ( $term['attr'] ) { - case 'AlarmedZoneId': - $term['op'] = 'EXISTS'; - break; - case 'MonitorName': - $filter['sql'] .= 'M.Name'; - break; - case 'ServerId': - case 'MonitorServerId': - $filter['sql'] .= 'M.ServerId'; - break; - case 'StorageServerId': - $filter['sql'] .= 'S.ServerId'; - break; - case 'FilterServerId': - $filter['sql'] .= ZM_SERVER_ID; - break; -# Unspecified start or end, so assume start, this is to support legacy filters - case 'DateTime': - $filter['sql'] .= 'E.StartTime'; - break; - case 'Date': - $filter['sql'] .= 'to_days(E.StartTime)'; - break; - case 'Time': - $filter['sql'] .= 'extract(hour_second FROM E.StartTime)'; - break; - case 'Weekday': - $filter['sql'] .= 'weekday(E.StartTime)'; - break; -# Starting Time - case 'StartDateTime': - $filter['sql'] .= 'E.StartTime'; - break; - case 'FramesEventId': - $filter['sql'] .= 'F.EventId'; - break; - case 'StartDate': - $filter['sql'] .= 'to_days(E.StartTime)'; - break; - case 'StartTime': - $filter['sql'] .= 'extract(hour_second FROM E.StartTime)'; - break; - case 'StartWeekday': - $filter['sql'] .= 'weekday(E.StartTime)'; - break; -# Ending Time - case 'EndDateTime': - $filter['sql'] .= 'E.EndTime'; - break; - case 'EndDate': - $filter['sql'] .= 'to_days(E.EndTime)'; - break; - case 'EndTime': - $filter['sql'] .= 'extract(hour_second FROM E.EndTime)'; - break; - case 'EndWeekday': - $filter['sql'] .= 'weekday(E.EndTime)'; - break; - case 'Id': - case 'Name': - case 'DiskSpace': - case 'MonitorId': - case 'StorageId': - case 'SecondaryStorageId': - case 'Length': - case 'Frames': - case 'AlarmFrames': - case 'TotScore': - case 'AvgScore': - case 'MaxScore': - case 'Cause': - case 'Notes': - case 'StateId': - case 'Archived': - $filter['sql'] .= 'E.'.$term['attr']; - break; - case 'DiskPercent': - // Need to specify a storage area, so need to look through other terms looking for a storage area, else we default to ZM_EVENTS_PATH - if ( ! $StorageArea ) { - for ( $j = 0; $j < count($terms); $j++ ) { - if ( - isset($terms[$j]['attr']) - and - ($terms[$j]['attr'] == 'StorageId') - and - isset($terms[$j]['val']) - ) { - $StorageArea = ZM\Storage::find_one(array('Id'=>$terms[$j]['val'])); - break; - } - } // end foreach remaining term - if ( ! $StorageArea ) $StorageArea = new ZM\Storage(); - } // end no StorageArea found yet - - $filter['sql'] .= getDiskPercent($StorageArea->Path()); - break; - case 'DiskBlocks': - // Need to specify a storage area, so need to look through other terms looking for a storage area, else we default to ZM_EVENTS_PATH - if ( ! $StorageArea ) { - for ( $j = $i; $j < count($terms); $j++ ) { - if ( - isset($terms[$j]['attr']) - and - ($terms[$j]['attr'] == 'StorageId') - and - isset($terms[$j]['val']) - ) { - $StorageArea = ZM\Storage::find_one(array('Id'=>$terms[$j]['val'])); - } - } // end foreach remaining term - } // end no StorageArea found yet - $filter['sql'] .= getDiskBlocks( $StorageArea ); - break; - case 'SystemLoad': - $filter['sql'] .= getLoad(); - break; - } - $valueList = array(); - if ( !isset($term['val']) ) $term['val'] = ''; - foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $term['val'])) as $value ) { - switch ( $term['attr'] ) { - - case 'AlarmedZoneId': - $value = '(SELECT * FROM Stats WHERE EventId=E.Id AND ZoneId='.$value.')'; - break; - case 'MonitorName': - case 'Name': - case 'Cause': - case 'Notes': - if ( $term['op'] == 'LIKE' || $term['op'] == 'NOT LIKE' ) { - $value = '%'.$value.'%'; - } - $value = dbEscape($value); - break; - case 'MonitorServerId': - case 'FilterServerId': - case 'StorageServerId': - case 'ServerId': - if ( $value == 'ZM_SERVER_ID' ) { - $value = ZM_SERVER_ID; - } else if ( $value == 'NULL' ) { - - } else { - $value = dbEscape($value); - } - break; - case 'StorageId': - $StorageArea = ZM\Storage::find_one(array('Id'=>$value)); - if ( $value != 'NULL' ) - $value = dbEscape($value); - break; - case 'DateTime': - case 'StartDateTime': - case 'EndDateTime': - if ( $value != 'NULL' ) - $value = '\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\''; - break; - case 'Date': - case 'StartDate': - case 'EndDate': - if ( $value == 'CURDATE()' or $value == 'NOW()' ) { - $value = 'to_days('.$value.')'; - } else if ( $value != 'NULL' ) { - $value = 'to_days(\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')'; - } - break; - case 'Time': - case 'StartTime': - case 'EndTime': - if ( $value != 'NULL' ) - $value = 'extract(hour_second from \''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')'; - break; - default : - if ( $value != 'NULL' ) - $value = dbEscape($value); - break; - } - $valueList[] = $value; - } // end foreach value - - switch ( $term['op'] ) { - case '=' : - case '!=' : - case '>=' : - case '>' : - case '<' : - case '<=' : - case 'LIKE' : - case 'NOT LIKE': - $filter['sql'] .= ' '.$term['op'].' '. $value; - break; - case '=~' : - $filter['sql'] .= ' regexp '.$value; - break; - case '!~' : - $filter['sql'] .= ' not regexp '.$value; - break; - case '=[]' : - case 'IN' : - $filter['sql'] .= ' IN ('.join(',', $valueList).')'; - break; - case '![]' : - $filter['sql'] .= ' not in ('.join(',', $valueList).')'; - break; - case 'EXISTS' : - $filter['sql'] .= ' EXISTS ' .$value; - break; - case 'IS' : - if ( $value == 'Odd' ) { - $filter['sql'] .= ' % 2 = 1'; - } else if ( $value == 'Even' ) { - $filter['sql'] .= ' % 2 = 0'; - } else { - $filter['sql'] .= " IS $value"; - } - break; - case 'IS NOT' : - $filter['sql'] .= " IS NOT $value"; - break; - default: - ZM\Warning('Invalid operator in filter: ' . print_r($term['op'], true)); - } // end switch op - - $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][op]").'='.urlencode($term['op']); - $filter['fields'] .= "\n"; - if ( isset($term['val']) ) { - $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][val]").'='.urlencode($term['val']); - $filter['fields'] .= "\n"; - } - } // end if isset($term['attr']) - if ( isset($term['cbr']) && (string)(int)$term['cbr'] == $term['cbr'] ) { - $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cbr]").'='.urlencode($term['cbr']); - $filter['sql'] .= ' '.str_repeat(')', $term['cbr']); - $filter['fields'] .= "\n"; - } - } // end foreach term - if ( $filter['sql'] ) - $filter['sql'] = ' AND ( '.$filter['sql'].' )'; - if ( $saveToSession ) { - $_SESSION['filter'] = $filter; - } - } else { - $filter['query'] = $querySep; - #.urlencode('filter[Query][terms]=[]'); - } // end if terms + if ( $filter['sql'] ) + $filter['sql'] = ' AND ( '.$filter['sql'].' )'; #if ( 0 ) { #// ICON I feel like these should be here, but not yet @@ -1376,10 +1118,8 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') { #$filter['sql'] .= ' ORDER BY ' . $filter['Query']['sort_field'] . ( #( $filter['Query']['sort_asc'] ? ' ASC' : ' DESC' ) ); #} - #if ( $filter['Query']['limit'] ) { - #$filter['sql'] .= ' LIMIT ' . validInt($filter['Query']['limit']); - #} #} + return $filter; } // end function parseFilter(&$filter, $saveToSession=false, $querySep='&') // Please note that the filter is passed in by copy, so you need to use the return value from this function. @@ -1489,12 +1229,14 @@ function sortHeader($field, $querySep='&') { )); } -function sortTag( $field ) { - if ( $_REQUEST['sort_field'] == $field ) - if ( $_REQUEST['sort_asc'] ) - return '(^)'; - else - return '(v)'; +function sortTag($field) { + if ( isset($_REQUEST['sort_field']) ) { + if ( $_REQUEST['sort_field'] == $field ) + if ( $_REQUEST['sort_asc'] ) + return '(^)'; + else + return '(v)'; + } return false; } @@ -1520,9 +1262,8 @@ function getDiskPercent($path = ZM_DIR_EVENTS) { return $space; } -function getDiskBlocks() { - if ( !$StorageArea ) $StorageArea = new ZM\Storage(); - $df = shell_exec('df '.escapeshellarg($StorageArea->Path())); +function getDiskBlocks($path = ZM_DIR_EVENTS) { + $df = shell_exec('df '.escapeshellarg($path)); $space = -1; if ( preg_match('/\s(\d+)\s+\d+\s+\d+%/ms', $df, $matches) ) $space = $matches[1]; @@ -1542,20 +1283,20 @@ function systemStats() { if ( $normalized_load <= 0.75 ) { $htmlLoad = $load; } else if ( $normalized_load <= 0.9 ) { - $htmlLoad = "$load"; + $htmlLoad = ''.$load.''; } else if ( $normalized_load <= 1.1 ) { - $htmlLoad = "$load"; + $htmlLoad = ''.$load.''; } else { - $htmlLoad = "$load"; + $htmlLoad = ''.$load.''; } # Colorize the disk space stat if ( $diskPercent < 98 ) { $htmlDiskPercent = $diskPercent.'%'; } else if ( $diskPercent <= 99 ) { - $htmlDiskPercent = "$diskPercent%"; + $htmlDiskPercent = ''.$diskPercent.'%'; } else { - $htmlDiskPercent = "$diskPercent%"; + $htmlDiskPercent = ''.$diskPercent.'%'; } # Colorize the PATH_MAP (usually /dev/shm) stat @@ -1563,15 +1304,15 @@ function systemStats() { if ( disk_free_space(ZM_PATH_MAP) > 209715200 ) { # have to always have at least 200MiB free $htmlPathMapPercent = $pathMapPercent.'%'; } else { - $htmlPathMapPercent = "$pathMapPercent%"; + $htmlPathMapPercent = ''.$pathMapPercent.'%'; } } else if ( $pathMapPercent < 100 ) { - $htmlPathMapPercent = "$pathMapPercent%"; + $htmlPathMapPercent = ''.$pathMapPercent.'%'; } else { - $htmlPathMapPercent = "$pathMapPercent%"; + $htmlPathMapPercent = ''.$pathMapPercent.'%'; } - $htmlString = translate('Load').": $htmlLoad - ".translate('Disk').": $htmlDiskPercent - ".ZM_PATH_MAP.": $htmlPathMapPercent"; + $htmlString = translate('Load').': '.$htmlLoad.' - '.translate('Disk').': '.$htmlDiskPercent.' - '.ZM_PATH_MAP.': '.$htmlPathMapPercent; return $htmlString; } @@ -1754,12 +1495,11 @@ function getPolyCentre($points, $area=0) { $area = getPolyArea($points); for ( $i = 0, $j = count($points)-1; $i < count($points); $j = $i++ ) { $ct = ($points[$i]['x'] * $points[$j]['y']) - ($points[$j]['x'] * $points[$i]['y']); - $cx += ($points[$i]['x'] + $points[$j]['x']) * ct; - $cy += ($points[$i]['y'] + $points[$j]['y']) * ct; + $cx += ($points[$i]['x'] + $points[$j]['x']) * $ct; + $cy += ($points[$i]['y'] + $points[$j]['y']) * $ct; } $cx = intval(round(abs($cx/(6.0*$area)))); $cy = intval(round(abs($cy/(6.0*$area)))); - printf( "X:%cx, Y:$cy
" ); return array('x'=>$cx, 'y'=>$cy); } @@ -1907,12 +1647,12 @@ function coordsToPoints($coords) { if ( preg_match('/(\d+),(\d+)/', $matches[1][$i], $cmatches) ) { $points[] = array('x'=>$cmatches[1], 'y'=>$cmatches[2]); } else { - echo("Bogus coordinates '".$matches[$i]."'"); + echo('Bogus coordinates ('.$matches[$i].')'); return false; } } } else { - echo("Bogus coordinate string '$coords'"); + echo('Bogus coordinate string '.$coords); return false; } return $points; @@ -1992,7 +1732,7 @@ function initX10Status() { if ( @socket_connect($socket, $sock_file) ) { $command = 'status'; if ( !socket_write($socket, $command) ) { - ZM\Fatal("Can't write to control socket: ".socket_strerror(socket_last_error($socket))); + ZM\Fatal('Can\'t write to control socket: '.socket_strerror(socket_last_error($socket))); } socket_shutdown($socket, 1); $x10Output = ''; @@ -2028,7 +1768,7 @@ function getDeviceStatusX10($key) { function setDeviceStatusX10($key, $status) { $socket = socket_create(AF_UNIX, SOCK_STREAM, 0); if ( $socket < 0 ) { - ZM\Fatal( 'socket_create() failed: '.socket_strerror($socket) ); + ZM\Fatal('socket_create() failed: '.socket_strerror($socket)); } $sock_file = ZM_PATH_SOCKS.'/zmx10.sock'; if ( @socket_connect($socket, $sock_file) ) { @@ -2247,7 +1987,7 @@ function cache_bust($file) { if ( file_exists(ZM_DIR_CACHE.'/'.$cacheFile) or symlink(ZM_PATH_WEB.'/'.$file, ZM_DIR_CACHE.'/'.$cacheFile) ) { return 'cache/'.$cacheFile; } else { - ZM\Warning("Failed linking $file to $cacheFile"); + ZM\Warning('Failed linking '.$file.' to '.$cacheFile); } return $file; } @@ -2314,27 +2054,50 @@ function validHtmlStr($input) { return htmlspecialchars($input, ENT_QUOTES); } +/* options['width'] is the desired view width not necessarily the image width requested. + * It can be % in which case we us it to set the scale + * It can be px in which case we can use it to calculate the scale + * Same width height. If both are set we should calculate the smaller resulting scale + */ function getStreamHTML($monitor, $options = array()) { - if ( isset($options['scale']) ) { - if ( $options['scale'] != 'auto' && $options['scale'] != '0' and $options['scale'] != '' ) { - ZM\Logger::Debug("Setting dimensions from scale:".$options['scale']); + if ( isset($options['scale']) and $options['scale'] != '' ) { + if ( $options['scale'] != 'auto' && $options['scale'] != '0' ) { + #ZM\Warning('Setting dimensions from scale:'.$options['scale']); $options['width'] = reScale($monitor->ViewWidth(), $options['scale']).'px'; $options['height'] = reScale($monitor->ViewHeight(), $options['scale']).'px'; - } else { + } else if ( ! ( isset($options['width']) or isset($options['height']) ) ) { $options['width'] = '100%'; $options['height'] = 'auto'; } } else { + $options['scale'] = 100; # scale is empty or 100 # There may be a fixed width applied though, in which case we need to leave the height empty if ( ! ( isset($options['width']) and $options['width'] ) ) { - $options['width'] = $monitor->ViewWidth().'px'; - if ( ! ( isset($options['height']) and $options['height'] ) ) { - $options['height'] = $monitor->ViewHeight().'px'; + # Havn't specified width. If we specified height, then we should + # use a width that keeps the aspect ratio, otherwise no scaling, + # no dimensions, so assume the dimensions of the Monitor + + if ( ! (isset($options['height']) and $options['height']) ) { + # If we havn't specified any scale or dimensions, then we must be using CSS to scale it in a dynamic way. Can't make any assumptions. + #$options['width'] = $monitor->ViewWidth().'px'; + #$options['height'] = $monitor->ViewHeight().'px'; + } + } else { + #ZM\Warning("Have width ".$options['width']); + if ( preg_match('/^(\d+)px$/', $options['width'], $matches) ) { + $scale = intval(100*$matches[1]/$monitor->ViewWidth()); + #ZM\Warning("Scale is $scale"); + if ( $scale < $options['scale'] ) + $options['scale'] = $scale; + } else if ( preg_match('/^(\d+)%$/', $options['width'], $matches) ) { + $scale = intval($matches[1]); + if ( $scale < $options['scale'] ) + $options['scale'] = $scale; + } else { + Warning('Invalid value for width: '.$options['width']); } - } else if ( ! isset($options['height']) ) { - $options['height'] = ''; } } if ( ! isset($options['mode'] ) ) { @@ -2439,10 +2202,10 @@ function check_timezone() { ZM\Error("ZoneMinder is not configured properly: php's date.timezone $php_tzoffset does not match the system timezone $sys_tzoffset! Please check Options->System->Timezone."); if ( $sys_tzoffset != $mysql_tzoffset ) - ZM\Error("ZoneMinder is not configured properly: mysql's timezone does not match the system timezone! Event lists will display incorrect times."); + ZM\Error('ZoneMinder is not configured properly: mysql\'s timezone does not match the system timezone! Event lists will display incorrect times.'); if (!ini_get('date.timezone') || !date_default_timezone_set(ini_get('date.timezone'))) - ZM\Error("ZoneMinder is not configured properly: php's date.timezone is not set to a valid timezone. Please check Options->System->Timezone"); + ZM\Error('ZoneMinder is not configured properly: php\'s date.timezone is not set to a valid timezone. Please check Options->System->Timezone'); } @@ -2502,12 +2265,12 @@ function do_post_request($url, $data, $optional_headers = null) { $ctx = stream_context_create($params); $fp = @fopen($url, 'rb', false, $ctx); if ( !$fp ) { - throw new Exception("Problem with $url, " + throw new Exception('Problem with '.$url.', ' .print_r(error_get_last(),true)); } $response = @stream_get_contents($fp); if ( $response === false ) { - throw new Exception("Problem reading data from $url, data: ".print_r($params,true) + throw new Exception('Problem reading data from '.$url.', data: '.print_r($params,true) .print_r(error_get_last(),true)); } return $response; @@ -2527,7 +2290,7 @@ if ( !function_exists('sem_get') ) { } if ( !function_exists('ftok') ) { - function ftok($filename = "", $proj = "") { + function ftok($filename = '', $proj = '') { if ( empty($filename) || !file_exists($filename) ) { return -1; } else { @@ -2564,10 +2327,9 @@ function format_duration($time, $separator=':') { function array_recursive_diff($aArray1, $aArray2) { $aReturn = array(); if ( ! (is_array($aArray1) and is_array($aArray2) ) ) { - $backTrace = debug_backtrace(); - ZM\Warning("Bad arrays passed 1:" . print_r($aArray1,true) . "\n2: " . print_r($aArray2,true)."\n from: ".print_r($backTrace,true)); - return; - + $backTrace = debug_backtrace(); + ZM\Warning('Bad arrays passed 1:' . print_r($aArray1,true) . PHP_EOL.'2: '.print_r($aArray2,true).PHP_EOL.' from: '.print_r($backTrace,true)); + return; } foreach ( $aArray1 as $mKey => $mValue ) { @@ -2650,12 +2412,12 @@ function html_radio($name, $values, $selected=null, $options=array(), $attrs=arr function random_colour() { return '#'. - str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT). - str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT). - str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT); + str_pad( dechex( mt_rand(0, 255) ), 2, '0', STR_PAD_LEFT). + str_pad( dechex( mt_rand(0, 255) ), 2, '0', STR_PAD_LEFT). + str_pad( dechex( mt_rand(0, 255) ), 2, '0', STR_PAD_LEFT); } -function zm_random_bytes($length = 32){ +function zm_random_bytes($length = 32) { if ( !isset($length) || intval($length) <= 8 ) { $length = 32; } diff --git a/web/index.php b/web/index.php index 286dc8474..3d6f24fc7 100644 --- a/web/index.php +++ b/web/index.php @@ -53,7 +53,7 @@ require_once('includes/Group.php'); require_once('includes/Monitor.php'); // Useful debugging lines for mobile devices -if ( ZM\Logger::fetch()->debugOn() ) { +if ( 0 and ZM\Logger::fetch()->debugOn() ) { ob_start(); phpinfo(INFO_VARIABLES); ZM\Logger::Debug(ob_get_contents()); @@ -222,11 +222,11 @@ ZM\Logger::Debug("View: $view Request: $request Action: $action User: " . ( isse if ( ZM_ENABLE_CSRF_MAGIC && ( $action != 'login' ) && - ( $view != 'view_video' ) && - ( $view != 'image' ) && + ( $view != 'view_video' ) && // only video no html + ( $view != 'image' ) && // view=image doesn't return html, just image data. ( $request != 'control' ) && - ( $view != 'frames' ) && - ( $view != 'archive' ) + //( $view != 'frames' ) && // big html can overflow ob + ( $view != 'archive' ) // returns data ) { require_once('includes/csrf/csrf-magic.php'); #ZM\Logger::Debug("Calling csrf_check with the following values: \$request = \"$request\", \$view = \"$view\", \$action = \"$action\""); @@ -266,7 +266,6 @@ if ( ZM_OPT_USE_AUTH and (!isset($user)) and ($view != 'login') and ($view != 'n $request = null; } -CSPHeaders($view, $cspNonce); if ( $redirect ) { ZM\Logger::Debug("Redirecting to $redirect"); @@ -284,6 +283,7 @@ if ( $request ) { } if ( $includeFiles = getSkinIncludes('views/'.$view.'.php', true, true) ) { + ob_start(); foreach ( $includeFiles as $includeFile ) { if ( !file_exists($includeFile) ) ZM\Fatal("View '$view' does not exist"); @@ -297,6 +297,9 @@ if ( $includeFiles = getSkinIncludes('views/'.$view.'.php', true, true) ) { foreach ( getSkinIncludes('views/login.php', true, true) as $includeFile ) require_once $includeFile; } + + CSPHeaders($view, $cspNonce); + ob_end_flush(); } // If the view is missing or the view still returned error with the user logged in, // then it is not recoverable. diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js new file mode 100644 index 000000000..24996344a --- /dev/null +++ b/web/js/MonitorStream.js @@ -0,0 +1,271 @@ + +function MonitorStream(monitorData) { + this.id = monitorData.id; + this.connKey = monitorData.connKey; + this.url = monitorData.url; + this.width = monitorData.width; + this.height = monitorData.height; + this.status = null; + this.alarmState = STATE_IDLE; + this.lastAlarmState = STATE_IDLE; + this.streamCmdParms = 'view=request&request=stream&connkey='+this.connKey; + if ( auth_hash ) { + this.streamCmdParms += '&auth='+auth_hash; + } else if ( auth_relay ) { + this.streamCmdParms += '&'+auth_relay; + } + this.streamCmdTimer = null; + this.type = monitorData.type; + this.refresh = monitorData.refresh; + this.start = function(delay) { + // Step 1 make sure we are streaming instead of a static image + var stream = $j('#liveStream'+this.id)[0]; + if ( ! stream ) { + console.log('No live stream'); + return; + } + src = stream.src.replace(/mode=single/i, 'mode=jpeg'); + if ( -1 == src.search('connkey') ) { + src += '&connkey='+this.connKey; + } + if ( stream.src != src ) { + console.log("Setting to streaming"); + stream.src = ''; + stream.src = src; + } + + if ( this.streamCmdQuery ) { + this.streamCmdTimer = this.streamCmdQuery.delay(delay, this); + } else { + console.log("No streamCmdQuery"); + } + + console.log("queueing for " + this.id + " " + this.connKey + " timeout is: " + AJAX_TIMEOUT); + requestQueue.addRequest("cmdReq"+this.id, this.streamCmdReq); + }; + this.stop = function() { + if ( 0 ) { + var stream = $j('#liveStream'+this.id)[0]; + if ( ! stream ) { + console.log('No live stream'); + return; + } + src = stream.src.replace(/mode=jpeg/i, 'mode=single'); + if ( stream.src != src ) { + console.log("Setting to stopped"); + stream.src = ''; + stream.src = src; + } + } + this.streamCmdReq.send(this.streamCmdParms+"&command="+CMD_STOP); + }; + this.pause = function() { + this.streamCmdReq.send(this.streamCmdParms+"&command="+CMD_PAUSE); + }; + this.play = function() { + this.streamCmdReq.send(this.streamCmdParms+"&command="+CMD_PLAY); + }; + + this.eventHandler = function(event) { + console.log(event); + }; + + this.onclick = function(evt) { + var el = evt.currentTarget; + var tag = 'watch'; + var id = el.getAttribute("data-monitor-id"); + var width = el.getAttribute("data-width"); + var height = el.getAttribute("data-height"); + var url = '?view=watch&mid='+id; + var name = 'zmWatch'+id; + evt.preventDefault(); + createPopup(url, name, tag, width, height); + }; + + this.setup_onclick = function() { + var el = document.getElementById('imageFeed'+this.id); + if ( el ) el.addEventListener('click', this.onclick, false); + }; + this.disable_onclick = function() { + document.getElementById('imageFeed'+this.id).removeEventListener('click', this.onclick ); + }; + + this.setStateClass = function(element, stateClass) { + if ( !element ) { + return; + } + if ( !element.hasClass( stateClass ) ) { + if ( stateClass != 'alarm' ) { + element.removeClass('alarm'); + } + if ( stateClass != 'alert' ) { + element.removeClass('alert'); + } + if ( stateClass != 'idle' ) { + element.removeClass('idle'); + } + element.addClass(stateClass); + } + }; + + this.onError = function(text, error) { + console.log('onerror: ' + text + ' error:'+error); + // Requeue, but want to wait a while. + var streamCmdTimeout = 10*statusRefreshTimeout; + this.streamCmdTimer = this.streamCmdQuery.delay(streamCmdTimeout, this); + }; + this.onFailure = function(xhr) { + console.log('onFailure: ' + this.connKey); + console.log(xhr); + if ( ! requestQueue.hasNext('cmdReq'+this.id) ) { + console.log('Not requeuing because there is one already'); + requestQueue.addRequest('cmdReq'+this.id, this.streamCmdReq); + } + if ( 0 ) { + // Requeue, but want to wait a while. + if ( this.streamCmdTimer ) { + this.streamCmdTimer = clearTimeout( this.streamCmdTimer ); + } + var streamCmdTimeout = 1000*statusRefreshTimeout; + this.streamCmdTimer = this.streamCmdQuery.delay(streamCmdTimeout, this, true); + requestQueue.resume(); + } + console.log('done failure'); + }; + + this.getStreamCmdResponse = function(respObj, respText) { + if ( this.streamCmdTimer ) { + this.streamCmdTimer = clearTimeout(this.streamCmdTimer); + } + + var stream = $j('#liveStream'+this.id)[0]; + if ( ! stream ) { + console.log('No live stream'); + return; + } + + if ( respObj.result == 'Ok' ) { + if ( respObj.status ) { + this.status = respObj.status; + this.alarmState = this.status.state; + + var stateClass = ''; + if ( this.alarmState == STATE_ALARM ) { + stateClass = 'alarm'; + } else if ( this.alarmState == STATE_ALERT ) { + stateClass = 'alert'; + } else { + stateClass = 'idle'; + } + + if ( ( + (typeof COMPACT_MONTAGE === 'undefined') || + !COMPACT_MONTAGE) && + (this.type != 'WebSite') + ) { + fpsValue = $('fpsValue'+this.id); + if ( fpsValue ) { + fpsValue.set('text', this.status.fps); + } + stateValue = $('stateValue'+this.id); + if ( stateValue ) { + stateValue.set('text', stateStrings[this.alarmState]); + } + + monitorState = $('monitorState'+this.id); + if ( monitorState ) { + this.setStateClass(monitorState, stateClass); + } + } + + this.setStateClass($('monitor'+this.id), stateClass); + + /*Stream could be an applet so can't use moo tools*/ + //stream.parentNode().className = stateClass; + + var isAlarmed = ( this.alarmState == STATE_ALARM || this.alarmState == STATE_ALERT ); + var wasAlarmed = ( this.lastAlarmState == STATE_ALARM || this.lastAlarmState == STATE_ALERT ); + + var newAlarm = ( isAlarmed && !wasAlarmed ); + var oldAlarm = ( !isAlarmed && wasAlarmed ); + + if ( newAlarm ) { + if ( false && SOUND_ON_ALARM ) { + // Enable the alarm sound + $('alarmSound').removeClass('hidden'); + } + if ( (typeof POPUP_ON_ALARM !== 'undefined') && POPUP_ON_ALARM ) { + windowToFront(); + } + } + if ( false && SOUND_ON_ALARM ) { + if ( oldAlarm ) { + // Disable alarm sound + $('alarmSound').addClass('hidden'); + } + } + if ( this.status.auth ) { + if ( this.status.auth != auth_hash ) { + // Try to reload the image stream. + if ( stream ) { + stream.src = stream.src.replace(/auth=\w+/i, 'auth='+this.status.auth); + } + console.log("Changed auth from " + auth_hash + " to " + this.status.auth); + auth_hash = this.status.auth; + } + } // end if have a new auth hash + } // end if has state + } else { + console.error(respObj.message); + // Try to reload the image stream. + if ( stream ) { + if ( stream.src ) { + console.log('Reloading stream: ' + stream.src); + src = stream.src.replace(/rand=\d+/i, 'rand='+Math.floor((Math.random() * 1000000) )); + if ( src != stream.src ) { + stream.src = src; + } else { + console.log("Failed to update rand on stream src"); + } + } else { + } + } else { + console.log('No stream to reload?'); + } + } // end if Ok or not + + var streamCmdTimeout = statusRefreshTimeout; + // The idea here is if we are alarmed, do updates faster. + // However, there is a timeout in the php side which isn't getting modified, + // so this may cause a problem. Also the server may only be able to update so fast. + //if ( this.alarmState == STATE_ALARM || this.alarmState == STATE_ALERT ) { + //streamCmdTimeout = streamCmdTimeout/5; + //} + this.streamCmdTimer = this.streamCmdQuery.delay(streamCmdTimeout, this); + this.lastAlarmState = this.alarmState; + }; + + this.streamCmdQuery = function(resent) { + if ( resent ) { + console.log(this.connKey+': timeout: Resending'); + this.streamCmdReq.cancel(); + } + //console.log("Starting CmdQuery for " + this.connKey ); + if ( this.type != 'WebSite' ) { + this.streamCmdReq.send(this.streamCmdParms+'&command='+CMD_QUERY); + } + }; + + if ( this.type != 'WebSite' ) { + this.streamCmdReq = new Request.JSON( { + url: this.url, + method: 'get', + timeout: AJAX_TIMEOUT, + onSuccess: this.getStreamCmdResponse.bind(this), + onTimeout: this.streamCmdQuery.bind(this, true), + onError: this.onError.bind(this), + onFailure: this.onFailure.bind(this), + link: 'cancel' + } ); + } +} // end function MonitorStream diff --git a/web/lang/en_gb.php b/web/lang/en_gb.php index b3de1729d..fb730d86a 100644 --- a/web/lang/en_gb.php +++ b/web/lang/en_gb.php @@ -343,6 +343,7 @@ $SLANG = array( 'Export' => 'Export', 'DownloadVideo' => 'Download Video', 'GenerateDownload' => 'Generate Download', + 'ExistsInFileSystem' => 'Exists In File System', 'ExportFailed' => 'Export Failed', 'ExportFormat' => 'Export File Format', 'ExportFormatTar' => 'Tar', diff --git a/web/skins/classic/css/base/skin.css b/web/skins/classic/css/base/skin.css index 370038e61..baff90992 100644 --- a/web/skins/classic/css/base/skin.css +++ b/web/skins/classic/css/base/skin.css @@ -476,6 +476,15 @@ th.table-th-sort-rev span.table-th-sort-span { color: white; font-weight: 300; } +#header:after { + content: "."; + display: block; + height: 0; + font-size: 0; + clear: both; + visibility: hidden; +} + #header h2 { left: 0; @@ -724,7 +733,11 @@ li.search-choice { #dropdown_storage+div, #dropdown_reminder+div, #dropdown_bandwidth+div { -background-color:#485460; + background-color:#485460; +} + +#framesTable td:hover { + cursor: pointer; } .zoom { @@ -738,3 +751,18 @@ background-color:#485460; transform: scale(5); /* (arbitray zoom value - Note if the zoom is too large, it will go outside of the viewport) */ } +.zoom-right { + padding: 0px; + transition: transform .2s; /* Animation */ + margin: 0 auto; +} + +.zoom-right:hover { + transform-origin: 0% 50%; + transform: scale(5); /* (arbitray zoom value - Note if the zoom is too large, it will go outside of the viewport) */ +} + +a.flip { + float: right; + margin-right: -20px; +} diff --git a/web/skins/classic/css/base/views/zone.css b/web/skins/classic/css/base/views/zone.css index 4e9d8d479..626600eb2 100644 --- a/web/skins/classic/css/base/views/zone.css +++ b/web/skins/classic/css/base/views/zone.css @@ -38,7 +38,10 @@ } #imagePanel { + float: left; position: relative; + width: 50%; + min-width: 647px; /* extra 6 px for padding */ } /* NB: The size of the imageFrame determines the area within which the markers @@ -47,7 +50,23 @@ * the extreme edges of the imageFrame. */ #imageFrame { position: relative; - padding: 0 3px 3px 0; /* Compensate for negative margins in the markers just below. */ + padding: 3px 4px 4px 3px; +} +#imageFrame svg { + box-sizing: border-box; + position:absolute; + top: 3px; + left: 3px; + right: 3px; + background: none; + } +#imageFrame img { + width: 100%; + display: block; +} +#imageFrame img.alarm , +#imageFrame img.alert { + padding: 1px; } #imageFrame div { @@ -153,3 +172,18 @@ input[name="newZone[MaxAlarmPixels]"] { input.ZonePoint { width: 75px; } +svg { + overflow: visible; +} +svg circle { + fill: green; + overflow: visible; +} +#monitorState { + display: inline; + float: left; +} +#StreamControlButtons { + display: inline; + float: right; +} diff --git a/web/skins/classic/css/base/views/zones.css b/web/skins/classic/css/base/views/zones.css index f65dcdf33..125a558ec 100644 --- a/web/skins/classic/css/base/views/zones.css +++ b/web/skins/classic/css/base/views/zones.css @@ -19,19 +19,36 @@ fill: #0000FF; } -#zones, .ZonesImage { +.zones, .ZonesImage { + position: relative; + width: 50%; + min-width: 500px; float: left; } -#zones { - width: 500px; -} .ZonesImage img { -top:0; -left:0; -position: relative; + top:0; + left:0; + position: relative; +} +.ZonesImage svg { + width: 100%; + position:absolute; + top: 0; + left: 0; + right: 0; + background: none; } #content { -width: 100%; +width: 97%; position: relative; } + +.Monitor:after { + content: "."; + display: block; + height: 0; + font-size: 0; + clear: both; + visibility: hidden; +} diff --git a/web/skins/classic/css/dark/skin.css b/web/skins/classic/css/dark/skin.css index 13bfa125e..b1a1506b3 100644 --- a/web/skins/classic/css/dark/skin.css +++ b/web/skins/classic/css/dark/skin.css @@ -528,12 +528,18 @@ input[type=submit]:disabled, margin-left: 0; } +.table { + width: 100%; + margin-bottom: 1rem; + color: #eeeeee; +} + .table-striped > tbody > tr:nth-of-type(2n+1) { background-color: #333333; } -.table-hover>tbody>tr:hover { - background-color: #444444; +.table-hover > tbody > tr:hover { + background-color: orange; } .nav-pills>li.active>a, .nav-pills>li.active>a:focus, .nav-pills>li.active>a:hover { diff --git a/web/skins/classic/includes/functions.php b/web/skins/classic/includes/functions.php index 2c420c4e8..20892f22e 100644 --- a/web/skins/classic/includes/functions.php +++ b/web/skins/classic/includes/functions.php @@ -25,6 +25,7 @@ function xhtmlHeaders($file, $title) { global $skin; global $view; global $cspNonce; + global $basename; # This idea is that we always include the classic css files, # and then any different skin only needs to contain things that are different. @@ -32,15 +33,11 @@ function xhtmlHeaders($file, $title) { $skinCssPhpFile = getSkinFile('css/'.$css.'/skin.css.php'); - $skinJsPhpFile = getSkinFile('js/skin.js.php'); - $cssJsFile = getSkinFile('js/'.$css.'.js'); $basename = basename($file, '.php'); $baseViewCssPhpFile = getSkinFile('/css/base/views/'.$basename.'.css.php'); $viewCssPhpFile = getSkinFile('/css/'.$css.'/views/'.$basename.'.css.php'); - $viewJsFile = getSkinFile('views/js/'.$basename.'.js'); - $viewJsPhpFile = getSkinFile('views/js/'.$basename.'.js.php'); function output_link_if_exists($files) { global $skin; @@ -88,6 +85,7 @@ echo output_cache_busted_stylesheet_links(array( 'css/font-awesome.min.css', 'css/bootstrap.min.css', 'css/bootstrap-table.min.css', + 'css/bootstrap-table-page-jump-to.min.css', )); echo output_link_if_exists(array( @@ -113,7 +111,7 @@ if ( $css != 'base' ) echo output_link_if_exists(array('/css/'.$css.'/views/control.css')); } ?> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - '; echo ''; } @@ -344,7 +260,7 @@ function getNormalNavBarHTML($running, $user, $bandwidth_options, $view, $filter // // A new, slimmer navigation bar, permanently collapsed into a dropdown // -function getCollapsedNavBarHTML($running, $user, $bandwidth_options, $view, $filterQuery, $sortQuery, $limitQuery) { +function getCollapsedNavBarHTML($running, $user, $bandwidth_options, $view, $skin) { $status = runtimeStatus($running); @@ -390,7 +306,7 @@ function getCollapsedNavBarHTML($running, $user, $bandwidth_options, $view, $fil
@@ -413,7 +329,7 @@ function getCollapsedNavBarHTML($running, $user, $bandwidth_options, $view, $fil echo getLogHTML(); echo getDevicesHTML(); echo getGroupsHTML($view); - echo getFilterHTML($view,$filterQuery,$sortQuery,$limitQuery); + echo getFilterHTML($view); echo getCycleHTML($view); echo getMontageHTML($view); echo getMontageReviewHTML($view); @@ -467,6 +383,7 @@ function getStorageHTML() { $result=''; $func = function($S) { + ZM\Logger::Debug("disk_usage for " . $S->Name()); $class = ''; if ( $S->disk_usage_percent() > 98 ) { $class = 'text-danger'; @@ -702,11 +619,11 @@ function getGroupsHTML($view) { } // Returns the html representing the Filter menu item -function getFilterHTML($view, $filterQuery, $sortQuery, $limitQuery) { +function getFilterHTML($view) { $result = ''; $class = $view == 'filter' ? ' selected' : ''; - $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; return $result; } @@ -785,14 +702,15 @@ function getHeaderFlipHTML() { } // Returns the html representing the logged in user name and avatar -function getAcctCircleHTML($user=null) { +function getAcctCircleHTML($skin, $user=null) { + // Include Logout modal + include("skins/$skin/views/logout.php"); $result = ''; if ( ZM_OPT_USE_AUTH and $user ) { $result .= ''.PHP_EOL; } @@ -838,13 +756,86 @@ function runtimeStatus($running=null) { } function xhtmlFooter() { + global $css; global $cspNonce; global $view; global $skin; + global $basename; if ( canEdit('System') ) { include("skins/$skin/views/state.php"); } + $skinJsPhpFile = getSkinFile('js/skin.js.php'); + $cssJsFile = getSkinFile('js/'.$css.'.js'); + $viewJsFile = getSkinFile('views/js/'.$basename.'.js'); + $viewJsPhpFile = getSkinFile('views/js/'.$basename.'.js.php'); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/skins/classic/js/base.js b/web/skins/classic/js/base.js index d70cd3b6a..a3a99f773 100644 --- a/web/skins/classic/js/base.js +++ b/web/skins/classic/js/base.js @@ -41,7 +41,7 @@ var popupSizes = { 'export': {'width': 500, 'height': 640}, 'filter': {'width': 900, 'height': 700}, 'frame': {'addWidth': 32, 'minWidth': 384, 'addHeight': 200}, - 'frames': {'addWidth': 600, 'addHeight': 600}, + 'frames': {'addWidth': 800, 'addHeight': 600}, 'function': {'width': 350, 'height': 260}, 'group': {'width': 760, 'height': 600}, 'groups': {'width': 540, 'height': 420}, @@ -59,7 +59,7 @@ var popupSizes = { 'options': {'width': 1000, 'height': 660}, 'preset': {'width': 300, 'height': 220}, 'server': {'width': 600, 'height': 405}, - 'settings': {'width': 220, 'height': 235}, + 'settings': {'width': 250, 'height': 335}, 'shutdown': {'width': 400, 'height': 400}, 'state': {'width': 400, 'height': 170}, 'stats': {'width': 840, 'height': 200}, diff --git a/web/skins/classic/js/bootstrap-table-export.min.js b/web/skins/classic/js/bootstrap-table-export.min.js new file mode 100644 index 000000000..44d05ba4c --- /dev/null +++ b/web/skins/classic/js/bootstrap-table-export.min.js @@ -0,0 +1,10 @@ +/** + * bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation) + * + * @version v1.17.1 + * @homepage https://bootstrap-table.com + * @author wenzhixin (http://wenzhixin.net.cn/) + * @license MIT + */ + +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],e):e((t=t||self).jQuery)}(this,(function(t){"use strict";t=t&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t;var e="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function n(t,e){return t(e={exports:{}},e.exports),e.exports}var r=function(t){return t&&t.Math==Math&&t},o=r("object"==typeof globalThis&&globalThis)||r("object"==typeof window&&window)||r("object"==typeof self&&self)||r("object"==typeof e&&e)||Function("return this")(),i=function(t){try{return!!t()}catch(t){return!0}},a=!i((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})),c={}.propertyIsEnumerable,u=Object.getOwnPropertyDescriptor,l={f:u&&!c.call({1:2},1)?function(t){var e=u(this,t);return!!e&&e.enumerable}:c},s=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},f={}.toString,p=function(t){return f.call(t).slice(8,-1)},d="".split,h=i((function(){return!Object("z").propertyIsEnumerable(0)}))?function(t){return"String"==p(t)?d.call(t,""):Object(t)}:Object,g=function(t){if(null==t)throw TypeError("Can't call method on "+t);return t},y=function(t){return h(g(t))},v=function(t){return"object"==typeof t?null!==t:"function"==typeof t},b=function(t,e){if(!v(t))return t;var n,r;if(e&&"function"==typeof(n=t.toString)&&!v(r=n.call(t)))return r;if("function"==typeof(n=t.valueOf)&&!v(r=n.call(t)))return r;if(!e&&"function"==typeof(n=t.toString)&&!v(r=n.call(t)))return r;throw TypeError("Can't convert object to primitive value")},x={}.hasOwnProperty,m=function(t,e){return x.call(t,e)},S=o.document,w=v(S)&&v(S.createElement),O=function(t){return w?S.createElement(t):{}},E=!a&&!i((function(){return 7!=Object.defineProperty(O("div"),"a",{get:function(){return 7}}).a})),T=Object.getOwnPropertyDescriptor,j={f:a?T:function(t,e){if(t=y(t),e=b(e,!0),E)try{return T(t,e)}catch(t){}if(m(t,e))return s(!l.f.call(t,e),t[e])}},P=function(t){if(!v(t))throw TypeError(String(t)+" is not an object");return t},A=Object.defineProperty,I={f:a?A:function(t,e,n){if(P(t),e=b(e,!0),P(n),E)try{return A(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported");return"value"in n&&(t[e]=n.value),t}},_=a?function(t,e,n){return I.f(t,e,s(1,n))}:function(t,e,n){return t[e]=n,t},R=function(t,e){try{_(o,t,e)}catch(n){o[t]=e}return e},C=o["__core-js_shared__"]||R("__core-js_shared__",{}),L=Function.toString;"function"!=typeof C.inspectSource&&(C.inspectSource=function(t){return L.call(t)});var k,M,$,D=C.inspectSource,N=o.WeakMap,F="function"==typeof N&&/native code/.test(D(N)),B=n((function(t){(t.exports=function(t,e){return C[t]||(C[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.6.0",mode:"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})})),G=0,V=Math.random(),H=function(t){return"Symbol("+String(void 0===t?"":t)+")_"+(++G+V).toString(36)},q=B("keys"),z=function(t){return q[t]||(q[t]=H(t))},U={},W=o.WeakMap;if(F){var K=new W,Y=K.get,X=K.has,J=K.set;k=function(t,e){return J.call(K,t,e),e},M=function(t){return Y.call(K,t)||{}},$=function(t){return X.call(K,t)}}else{var Q=z("state");U[Q]=!0,k=function(t,e){return _(t,Q,e),e},M=function(t){return m(t,Q)?t[Q]:{}},$=function(t){return m(t,Q)}}var Z,tt={set:k,get:M,has:$,enforce:function(t){return $(t)?M(t):k(t,{})},getterFor:function(t){return function(e){var n;if(!v(e)||(n=M(e)).type!==t)throw TypeError("Incompatible receiver, "+t+" required");return n}}},et=n((function(t){var e=tt.get,n=tt.enforce,r=String(String).split("String");(t.exports=function(t,e,i,a){var c=!!a&&!!a.unsafe,u=!!a&&!!a.enumerable,l=!!a&&!!a.noTargetGet;"function"==typeof i&&("string"!=typeof e||m(i,"name")||_(i,"name",e),n(i).source=r.join("string"==typeof e?e:"")),t!==o?(c?!l&&t[e]&&(u=!0):delete t[e],u?t[e]=i:_(t,e,i)):u?t[e]=i:R(e,i)})(Function.prototype,"toString",(function(){return"function"==typeof this&&e(this).source||D(this)}))})),nt=o,rt=function(t){return"function"==typeof t?t:void 0},ot=function(t,e){return arguments.length<2?rt(nt[t])||rt(o[t]):nt[t]&&nt[t][e]||o[t]&&o[t][e]},it=Math.ceil,at=Math.floor,ct=function(t){return isNaN(t=+t)?0:(t>0?at:it)(t)},ut=Math.min,lt=function(t){return t>0?ut(ct(t),9007199254740991):0},st=Math.max,ft=Math.min,pt=function(t,e){var n=ct(t);return n<0?st(n+e,0):ft(n,e)},dt=function(t){return function(e,n,r){var o,i=y(e),a=lt(i.length),c=pt(r,a);if(t&&n!=n){for(;a>c;)if((o=i[c++])!=o)return!0}else for(;a>c;c++)if((t||c in i)&&i[c]===n)return t||c||0;return!t&&-1}},ht={includes:dt(!0),indexOf:dt(!1)}.indexOf,gt=function(t,e){var n,r=y(t),o=0,i=[];for(n in r)!m(U,n)&&m(r,n)&&i.push(n);for(;e.length>o;)m(r,n=e[o++])&&(~ht(i,n)||i.push(n));return i},yt=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],vt=yt.concat("length","prototype"),bt={f:Object.getOwnPropertyNames||function(t){return gt(t,vt)}},xt={f:Object.getOwnPropertySymbols},mt=ot("Reflect","ownKeys")||function(t){var e=bt.f(P(t)),n=xt.f;return n?e.concat(n(t)):e},St=function(t,e){for(var n=mt(e),r=I.f,o=j.f,i=0;ii;)I.f(t,n=r[i++],e[n]);return t},Dt=ot("document","documentElement"),Nt=z("IE_PROTO"),Ft=function(){},Bt=function(t){return" - - + + + @@ -459,7 +472,7 @@ if ( ZM_OPT_MESSAGE ) {
- + diff --git a/web/skins/classic/views/frame.php b/web/skins/classic/views/frame.php index c40b393d7..dc9ef9c4f 100644 --- a/web/skins/classic/views/frame.php +++ b/web/skins/classic/views/frame.php @@ -85,22 +85,26 @@ $focusWindow = true; xhtmlHeaders(__FILE__, translate('Frame').' - '.$Event->Id().' - '.$Frame->FrameId()); ?> -
-
-
- - - - +
+ + + + -
-
- +
+
+
+
@@ -80,7 +81,6 @@ xhtmlHeaders(__FILE__, translate('SystemLog'));
- @@ -97,10 +97,8 @@ xhtmlHeaders(__FILE__, translate('SystemLog'));
-
-
-
- + +
@@ -134,5 +132,4 @@ xhtmlHeaders(__FILE__, translate('SystemLog'));
- - + diff --git a/web/skins/classic/views/login.php b/web/skins/classic/views/login.php index 296a54887..e08bf91bc 100644 --- a/web/skins/classic/views/login.php +++ b/web/skins/classic/views/login.php @@ -36,5 +36,4 @@ if ( - - + diff --git a/web/skins/classic/views/logout.php b/web/skins/classic/views/logout.php index d68bd2b82..86e07605a 100644 --- a/web/skins/classic/views/logout.php +++ b/web/skins/classic/views/logout.php @@ -17,32 +17,28 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // - -$focusWindow = true; - -xhtmlHeaders(__FILE__, translate('Logout') ); +global $CLANG; ?> - -
- -
-
- - +
diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index aa54fa926..9cd29da2f 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -379,37 +379,17 @@ $codecs = array( 'MJPEG' => translate('MJPEG'), ); +$controls = ZM\Control::find(null, array('order'=>'lower(Name)')); + xhtmlHeaders(__FILE__, translate('Monitor').' - '.validHtmlStr($monitor->Name())); getBodyTopHTML(); +echo getNavBarHTML(); ?> -
- -
-
    +
    + +
    + + +
    + +
    +
    + + +
    + +

    - Name()) ?>Id() ) { ?> (Id()?>)

    + +
    + Configuration cloned from Monitor: +
    + +
    + + + +
    + +
    + + +
    @@ -614,15 +620,15 @@ switch ( $tab ) { { ?> - + - + - + 'None','auto'=>'Auto'); foreach ( ZM\Server::find(NULL, array('order'=>'lower(Name)')) as $Server ) { @@ -633,11 +639,11 @@ switch ( $tab ) { - + Type()); ?> - + - + Enabled() ? ' checked="checked"' : '' ?>/> Type() != 'WebSite' ) { ?> -  () +  () - + - + Type() != 'Local' && $monitor->Type() != 'File' && $monitor->Type() != 'NVSocket' ) { ?> -  () +  () CAUTION: See the help text -  () +  () CAUTION: See the help text @@ -707,11 +713,11 @@ switch ( $tab ) { } else { ?> - + - + - + RefBlendPerc()); ?> - + AlarmRefBlendPerc()); ?> - - + + - + - + - + - + - + Type() == 'Local' ) { ?> - + Method(), array('onchange'=>'submitTab', 'data-tab-name'=>$tab) ); ?> @@ -793,36 +799,36 @@ switch ( $tab ) { if ( ZM_HAS_V4L1 && $monitor->Method() == 'v4l1' ) { ?> - + Channel()); ?> - + Format()); ?> - + Palette()); ?> - + Channel()); ?> - + Format()); ?> - + Palette()); ?> - + V4LMultiBuffer() == '1' ? 'checked="checked"' : '' ) ?>/> V4LMultiBuffer() == '0' ? 'checked="checked"' : '' ) ?>/> @@ -831,7 +837,7 @@ switch ( $tab ) { - + Type() == 'VNC' ) { ?> - + - + - + - + Type() == 'Remote' ) { ?> - + Protocol(), "updateMethods( this );if(this.value=='rtsp'){\$('RTSPDescribe').setStyle('display','table-row');}else{\$('RTSPDescribe').hide();}" ); ?> - + Protocol() || $monitor->Protocol() == 'http' ) { @@ -875,24 +881,24 @@ include('_monitor_source_nvsocket.php'); ?> - + Type() == 'File' ) { ?> - + Type() == 'cURL' ) { ?> - - - + + + Type() == 'WebSite' ) { ?> - + @@ -900,29 +906,29 @@ include('_monitor_source_nvsocket.php'); - () + () - + Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) { ?> - + - ) Method()) ?> -  (Type()), 'zmOptionHelp', 'optionhelp', '?' ) ?>) +  (Type()), 'zmOptionHelp', 'optionhelp', '?' ) ?>) Type() == 'Ffmpeg' ) { ?> - + () - + () @@ -946,11 +952,11 @@ include('_monitor_source_nvsocket.php'); if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) { ?> - + Colours()) ?> - () + () @@ -981,11 +987,11 @@ include('_monitor_source_nvsocket.php'); - + - + Orientation());?> Type() == 'Local' ) { ?> - + Deinterlacing())?> Type() != 'WebSite' ) { ?> - + Deinterlacing())?> Type() == 'Remote' ) { ?> Protocol()!= 'rtsp' ) { echo ' style="display:none;"'; } ?>> -  () +  () RTSPDescribe() ) { ?> checked="checked"/> - + 'Default'); @@ -1030,7 +1036,7 @@ include('_monitor_source_nvsocket.php'); - + - + 'Disabled', @@ -1060,12 +1066,12 @@ include('_monitor_source_nvsocket.php'); ?> -  () +  () - + Type() == 'Ffmpeg' ) { ?> RecordAudio() ) { ?> checked="checked"/> @@ -1080,19 +1086,19 @@ include('_monitor_source_nvsocket.php'); { ?> - + - + - + - + LabelSize()) ?> - + - + - + - + - + - + - + Controllable() ) { ?> checked="checked"/> - - ControlId()); -if ( canEdit('Control') ) { - echo ' '.makePopupLink('?view=controlcaps', 'zmControlCaps', 'controlcaps', translate('Edit')); -} -?> + + +translate('None')); + foreach ( $controls as $control ) { + $controlTypes[$control->Id()] = $control->Name(); + } + + echo htmlSelect('newMonitor[ControlId]', $controlTypes, $monitor->ControlId()); + if ( canEdit('Control') ) { + echo ' '.makePopupLink('?view=controlcaps', 'zmControlCaps', 'controlcaps', translate('Edit')); + } +?> + - + - + - + - + TrackMotion() ) { ?> checked="checked"/> - + - + translate('None'), @@ -1174,7 +1188,7 @@ if ( canEdit('Control') ) { echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnLocation()); ?> - + ReturnL case 'x10' : { ?> - - - + + + ReturnL { ?> - + - + - + - + - + - + - + - + DefaultRate()); ?> - + DefaultScale()); ?> - + DefaultCodec()); ?> - + - +      - +      @@ -1272,7 +1286,7 @@ echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnL -  () +  () Exif() ) { ?> checked="checked"/> ReturnL ?> -
    +
    - +
    - - +
    +
    + diff --git a/web/skins/classic/views/monitorpreset.php b/web/skins/classic/views/monitorpreset.php index ef5a6ac01..72419a599 100644 --- a/web/skins/classic/views/monitorpreset.php +++ b/web/skins/classic/views/monitorpreset.php @@ -57,5 +57,4 @@ xhtmlHeaders(__FILE__, translate('MonitorPreset') );
- - + diff --git a/web/skins/classic/views/monitorprobe.php b/web/skins/classic/views/monitorprobe.php index a76c67810..0b7098351 100644 --- a/web/skins/classic/views/monitorprobe.php +++ b/web/skins/classic/views/monitorprobe.php @@ -344,5 +344,4 @@ xhtmlHeaders(__FILE__, translate('MonitorProbe') );
- - + diff --git a/web/skins/classic/views/montage.php b/web/skins/classic/views/montage.php index dfcba186e..1c62fddf4 100644 --- a/web/skins/classic/views/montage.php +++ b/web/skins/classic/views/montage.php @@ -49,13 +49,6 @@ $heights = array( '1080' => '1080px', ); -$scale = '100'; # actual - -if ( isset($_REQUEST['scale']) ) { - $scale = validInt($_REQUEST['scale']); -} else if ( isset($_COOKIE['zmMontageScale']) ) { - $scale = validInt($_COOKIE['zmMontageScale']); -} $layouts = ZM\MontageLayout::find(NULL, array('order'=>"lower('Name')")); $layoutsById = array(); @@ -96,8 +89,9 @@ if ( isset($_COOKIE['zmMontageWidth']) ) { $_SESSION['zmMontageWidth'] = $options['width'] = validInt($_COOKIE['zmMontageWidth']); #} elseif ( isset($_SESSION['zmMontageWidth']) and $_SESSION['zmMontageWidth'] ) { #$options['width'] = $_SESSION['zmMontageWidth']; -} else +} else { $options['width'] = 0; +} if ( isset($_COOKIE['zmMontageHeight']) ) { $_SESSION['zmMontageHeight'] = $options['height'] = validInt($_COOKIE['zmMontageHeight']); @@ -107,8 +101,14 @@ if ( isset($_COOKIE['zmMontageHeight']) ) { $options['height'] = 0; } -#if ( $scale ) - $options['scale'] = $scale; +$scale = '100'; # actual + +if ( isset($_REQUEST['scale']) ) { + $scale = validInt($_REQUEST['scale']); +} else if ( isset($_COOKIE['zmMontageScale']) ) { + $scale = validInt($_COOKIE['zmMontageScale']); +} +$options['scale'] = $scale; session_write_close(); @@ -118,7 +118,7 @@ $filterbar = ob_get_contents(); ob_end_clean(); $monitors = array(); -foreach( $displayMonitors as &$row ) { +foreach ( $displayMonitors as &$row ) { if ( $row['Function'] == 'None' ) continue; @@ -127,7 +127,6 @@ foreach( $displayMonitors as &$row ) { if ( ZM_OPT_CONTROL && $row['ControlId'] && $row['Controllable'] ) $showControl = true; - $row['connKey'] = generateConnKey(); if ( ! isset($widths[$row['Width']]) ) { $widths[$row['Width']] = $row['Width'].'px'; } @@ -142,9 +141,14 @@ xhtmlHeaders(__FILE__, translate('Montage'));
-
- - + diff --git a/web/skins/classic/views/shutdown.php b/web/skins/classic/views/shutdown.php index 1fbe838c1..25d5d3d34 100644 --- a/web/skins/classic/views/shutdown.php +++ b/web/skins/classic/views/shutdown.php @@ -76,5 +76,4 @@ xhtmlHeaders(__FILE__, translate('Shutdown').' '.translate('Restart')); ?>
- - + diff --git a/web/skins/classic/views/stats.php b/web/skins/classic/views/stats.php index 6ad8edc1c..f6373151c 100644 --- a/web/skins/classic/views/stats.php +++ b/web/skins/classic/views/stats.php @@ -27,83 +27,24 @@ if ( !canView( 'Events' ) ) $eid = validInt($_REQUEST['eid']); $fid = validInt($_REQUEST['fid']); -$sql = 'SELECT S.*,E.*,Z.Name AS ZoneName,Z.Units,Z.Area,M.Name AS MonitorName FROM Stats AS S LEFT JOIN Events AS E ON S.EventId = E.Id LEFT JOIN Zones AS Z ON S.ZoneId = Z.Id LEFT JOIN Monitors AS M ON E.MonitorId = M.Id WHERE S.EventId = ? AND S.FrameId = ? ORDER BY S.ZoneId'; -$stats = dbFetchAll( $sql, NULL, array( $eid, $fid ) ); - $focusWindow = true; xhtmlHeaders(__FILE__, translate('Stats')." - ".$eid." - ".$fid ); ?> +
-
- - + diff --git a/web/skins/classic/views/storage.php b/web/skins/classic/views/storage.php index e1642b142..b25d12a21 100644 --- a/web/skins/classic/views/storage.php +++ b/web/skins/classic/views/storage.php @@ -111,5 +111,4 @@ xhtmlHeaders(__FILE__, translate('Storage').' - '.$newStorage->Name()); - - + diff --git a/web/skins/classic/views/timeline.php b/web/skins/classic/views/timeline.php index d97713cd7..98361907c 100644 --- a/web/skins/classic/views/timeline.php +++ b/web/skins/classic/views/timeline.php @@ -673,18 +673,17 @@ $focusWindow = true; xhtmlHeaders(__FILE__, translate('Timeline')); ?> -
-