Merge branch 'master' into osx-port

This commit is contained in:
Isaac Connor 2017-06-12 14:21:12 -04:00
commit b59e870fd4
44 changed files with 1748 additions and 1410 deletions

View File

@ -104,6 +104,7 @@ mark_as_advanced(
ZM_PERL_SEARCH_PATH
ZM_TARGET_DISTRO
ZM_CONFIG_DIR
ZM_CONFIG_SUBDIR
ZM_SYSTEMD)
set(ZM_RUNDIR "/var/run/zm" CACHE PATH
@ -137,6 +138,8 @@ set(ZM_WEB_GROUP "" CACHE STRING
# Advanced
set(ZM_CONFIG_DIR "/${CMAKE_INSTALL_SYSCONFDIR}" CACHE PATH
"Location of ZoneMinder configuration, default system config directory")
set(ZM_CONFIG_SUBDIR "${ZM_CONFIG_DIR}/conf.d" CACHE PATH
"Location of ZoneMinder configuration subfolder, default: ZM_CONFIG_DIR/conf.d")
set(ZM_EXTRA_LIBS "" CACHE STRING
"A list of optional libraries, separated by semicolons, e.g. ssl;theora")
set(ZM_MYSQL_ENGINE "InnoDB" CACHE STRING
@ -171,28 +174,13 @@ set(ZM_SYSTEMD "OFF" CACHE BOOL
"Set to ON to force building ZM with systemd support. default: OFF")
# Reassign some variables if a target distro has been specified
if((ZM_TARGET_DISTRO STREQUAL "fc24") OR (ZM_TARGET_DISTRO STREQUAL "fc25"))
set(ZM_RUNDIR "/var/run/zoneminder")
set(ZM_SOCKDIR "/var/lib/zoneminder/sock")
set(ZM_TMPDIR "/var/lib/zoneminder/temp")
set(ZM_LOGDIR "/var/log/zoneminder")
set(ZM_CONFIG_DIR "/etc/zm")
set(ZM_WEBDIR "/usr/share/zoneminder/www")
set(ZM_CGIDIR "/usr/libexec/zoneminder/cgi-bin")
elseif(ZM_TARGET_DISTRO STREQUAL "el6")
set(ZM_RUNDIR "/var/run/zoneminder")
set(ZM_SOCKDIR "/var/lib/zoneminder/sock")
set(ZM_TMPDIR "/var/lib/zoneminder/temp")
set(ZM_LOGDIR "/var/log/zoneminder")
set(ZM_CONFIG_DIR "/etc/zm")
set(ZM_WEBDIR "/usr/share/zoneminder/www")
set(ZM_CGIDIR "/usr/libexec/zoneminder/cgi-bin")
elseif(ZM_TARGET_DISTRO STREQUAL "el7")
if((ZM_TARGET_DISTRO MATCHES "^el") OR (ZM_TARGET_DISTRO MATCHES "^fc"))
set(ZM_RUNDIR "/var/run/zoneminder")
set(ZM_SOCKDIR "/var/lib/zoneminder/sock")
set(ZM_TMPDIR "/var/lib/zoneminder/temp")
set(ZM_LOGDIR "/var/log/zoneminder")
set(ZM_CONFIG_DIR "/etc/zm")
set(ZM_CONFIG_SUBDIR "/etc/zm/conf.d")
set(ZM_WEBDIR "/usr/share/zoneminder/www")
set(ZM_CGIDIR "/usr/libexec/zoneminder/cgi-bin")
elseif(ZM_TARGET_DISTRO STREQUAL "OS13")
@ -212,10 +200,11 @@ elseif(ZM_TARGET_DISTRO STREQUAL "FreeBSD")
set(ZM_WEB_USER "www")
set(ZM_WEB_GROUP "www")
set(ZM_CONFIG_DIR "/usr/local/etc/zm")
set(ZM_CONFIG_SUBDIR "/usr/local/etc/zm/conf.d")
set(ZM_WEBDIR "/usr/local/share/zoneminder/www")
set(ZM_CGIDIR "/usr/local/libexec/zoneminder/cgi-bin")
set(ZM_PERL_MM_PARMS "INSTALLDIRS=site")
endif((ZM_TARGET_DISTRO STREQUAL "fc24") OR (ZM_TARGET_DISTRO STREQUAL "fc25"))
endif((ZM_TARGET_DISTRO MATCHES "^el") OR (ZM_TARGET_DISTRO MATCHES "^fc"))
# Required for certain checks to work
set(CMAKE_EXTRA_INCLUDE_FILES
@ -791,6 +780,11 @@ else(ZM_PERL_SEARCH_PATH)
set(EXTRA_PERL_LIB "# Include from system perl paths only")
endif(ZM_PERL_SEARCH_PATH)
# If this is an out-of-source build, copy the files we need to the binary directory
if(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR))
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/conf.d" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/conf.d")
endif(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR))
# Generate files from the .in files
configure_file(zm.conf.in "${CMAKE_CURRENT_BINARY_DIR}/zm.conf" @ONLY)
configure_file(zoneminder-config.cmake "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
@ -814,13 +808,11 @@ if(ZM_ONVIF)
endif(ZM_ONVIF)
# Process distro subdirectories
if((ZM_TARGET_DISTRO STREQUAL "fc24") OR (ZM_TARGET_DISTRO STREQUAL "fc25"))
add_subdirectory(distros/redhat)
elseif((ZM_TARGET_DISTRO STREQUAL "el6") OR (ZM_TARGET_DISTRO STREQUAL "el7"))
if((ZM_TARGET_DISTRO MATCHES "^el") OR (ZM_TARGET_DISTRO MATCHES "^fc"))
add_subdirectory(distros/redhat)
elseif(ZM_TARGET_DISTRO STREQUAL "OS13")
add_subdirectory(distros/opensuse)
endif((ZM_TARGET_DISTRO STREQUAL "fc24") OR (ZM_TARGET_DISTRO STREQUAL "fc25"))
endif((ZM_TARGET_DISTRO MATCHES "^el") OR (ZM_TARGET_DISTRO MATCHES "^fc"))
# Print optional libraries detection status
message(STATUS "Optional libraries found:${optlibsfound}")
@ -837,8 +829,9 @@ else(zmconfgen_result EQUAL 0)
"ZoneMinder configuration generator failed. Exit code: ${zmconfgen_result}")
endif(zmconfgen_result EQUAL 0)
# Install zm.conf
# Install zm.conf and conf.d subfolder
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zm.conf" DESTINATION "${ZM_CONFIG_DIR}")
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/conf.d/" DESTINATION "${ZM_CONFIG_SUBDIR}")
# Uninstall target
configure_file(

View File

@ -1,24 +1,76 @@
# ZoneMinder
# ZoneMinder, you need the GIT repository code and submodules (git submodule update --init --recursive)
FROM ubuntu:xenial
MAINTAINER Markos Vakondios <mvakondios@gmail.com>
# Resynchronize the package index files
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y \
libpolkit-gobject-1-dev build-essential libmysqlclient-dev libssl-dev libbz2-dev libpcre3-dev \
libdbi-perl libarchive-zip-perl libdate-manip-perl libdevice-serialport-perl libmime-perl libpcre3 \
libwww-perl libdbd-mysql-perl libsys-mmap-perl yasm cmake libjpeg-turbo8-dev \
libjpeg-turbo8 libtheora-dev libvorbis-dev libvpx-dev libx264-dev libmp4v2-dev libav-tools mysql-client \
apache2 php php-mysql libapache2-mod-php php-cli \
mysql-server libvlc-dev libvlc5 libvlccore-dev libvlccore8 vlc-data libcurl4-openssl-dev \
libavformat-dev libswscale-dev libavutil-dev libavcodec-dev libavfilter-dev \
libavresample-dev libavdevice-dev libpostproc-dev libv4l-dev libtool libnetpbm10-dev \
libmime-lite-perl dh-autoreconf dpatch \
&& apt-get clean
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
apache2 \
build-essential \
cmake \
dh-autoreconf \
dpatch \
libapache2-mod-php \
libarchive-zip-perl \
libavcodec-dev \
libavdevice-dev \
libavfilter-dev \
libavformat-dev \
libavresample-dev \
libav-tools \
libavutil-dev \
libbz2-dev \
libcurl4-openssl-dev \
libdate-manip-perl \
libdbd-mysql-perl \
libdbi-perl \
libdevice-serialport-perl \
libjpeg-turbo8 \
libjpeg-turbo8-dev \
libmime-lite-perl \
libmime-perl \
libmp4v2-dev \
libmysqlclient-dev \
libnetpbm10-dev \
libpcre3 \
libpcre3-dev \
libpolkit-gobject-1-dev \
libpostproc-dev \
libssl-dev \
libswscale-dev \
libsys-mmap-perl \
libtheora-dev \
libtool \
libv4l-dev \
libvlc5 \
libvlccore8 \
libvlccore-dev \
libvlc-dev \
libvorbis-dev \
libvpx-dev \
libwww-perl \
libx264-dev \
mysql-client \
mysql-server \
php \
php-cli \
php-mysql \
vlc-data \
yasm \
&& rm -rf /var/lib/apt/lists/*
# Copy local code into our container
ADD . /ZoneMinder
ADD cmake /ZoneMinder/cmake/
ADD db /ZoneMinder/db/
ADD misc /ZoneMinder/misc/
ADD onvif /ZoneMinder/onvif/
ADD scripts /ZoneMinder/scripts/
ADD src /ZoneMinder/src/
ADD umutils /ZoneMinder/umutils/
ADD web /ZoneMinder/web/
ADD cmakecacheimport.sh CMakeLists.txt version zm.conf.in zmconfgen.pl.in zmlinkcontent.sh.in zoneminder-config.cmake /ZoneMinder/
ADD conf.d /ZoneMinder/conf.d
# Change into the ZoneMinder directory
WORKDIR /ZoneMinder
@ -39,18 +91,20 @@ RUN ./zmlinkcontent.sh
# Adding the start script
ADD utils/docker/start.sh /tmp/start.sh
# give files in /usr/local/share/zoneminder/
# Settings rights for /usr/local/share/zoneminder/
RUN chown -R www-data:www-data /usr/local/share/zoneminder/
# Adding apache virtual hosts file
RUN cp misc/apache.conf /etc/apache2/sites-available/000-default.conf
ADD utils/docker/phpdate.ini /etc/php5/apache2/conf.d/25-phpdate.ini
# Expose http port
EXPOSE 80
# Initial database and apache setup:
RUN "/ZoneMinder/utils/docker/setup.sh"
VOLUME /var/lib/zoneminder/images /var/lib/zoneminder/events /var/lib/mysql /var/log/zm
CMD ["/ZoneMinder/utils/docker/start.sh"]
# To speed up configuration testing, we put it here
ADD utils/docker /ZoneMinder/utils/docker/
CMD /ZoneMinder/utils/docker/setup.sh && /ZoneMinder/utils/docker/start.sh >/var/log/start.log 2>&1 & /bin/bash
# Run example docker run -it -p 1080:80 -e PHP_TIMEZONE='Europe/Paris' -v /disk/zoneminder/events:/var/lib/zoneminder/events -v /disk/zoneminder/images:/var/lib/zoneminder/images -v /disk/zoneminder/mysql:/var/lib/mysql -v /disk/zoneminder/logs:/var/log/zm --name zoneminder zoneminder/zoneminder

View File

@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
reported by contacting the project team at abuse@zoneminder.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.

19
conf.d/README Normal file
View File

@ -0,0 +1,19 @@
conf.d/README
Any changes to ZoneMinder's configuration should be made here in this folder,
rather than directly editing the default zm.conf file.
ZoneMinder will process each file in this folder with a ".conf" extension.
Each "Var = Value" pair, in each config file, will be loaded into ZoneMinder's
running configuration, overriding any variables with the same name found in the
default zm.conf file.
After creating a custom config file, don't forget to set the proper file and
owner permission on it. For example, this is typically what you should do after
saving the config file to disk:
sudo chown root:apache *.conf
sudo chmod 640 *.conf
Substitute "apache" with the name of the web server user account on your system.

View File

@ -0,0 +1,7 @@
# Do NOT set ZM_SERVER_HOST if you are not using Multi-Server
# You have been warned
#
# The name specified here must have a corresponding entry
# in the Servers tab under Options
ZM_SERVER_HOST=

View File

@ -22,7 +22,8 @@ override_dh_auto_configure:
-DZM_CGIDIR=/usr/lib/zoneminder/cgi-bin \
-DZM_WEB_USER=www-data \
-DZM_WEB_GROUP=www-data \
-DCMAKE_INSTALL_SYSCONFDIR=etc/zm
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
-DZM_CONFIG_DIR="/etc/zm"
override_dh_auto_install:
dh_auto_install --buildsystem=cmake

View File

@ -1 +1 @@
../redhat/redalert.wav
../redhat/misc/redalert.wav

View File

@ -1,7 +1,16 @@
What's New
==========
1. The Apache ScriptAlias has been changed from "/cgi-bin/zm/zms" to
1. ZoneMinder now uses a conf.d subfolder to process custom changes to
variables found in zm.conf. Changes to zm.conf will be overwritten
during an upgrade. Instead, create a file with a ".conf" extension under
the conf.d folder and make your changes there.
2. ZoneMinder now supports recording directly to video container! This feature
is new and should be treated as experimental. Refer to the documentation
regarding how to use this feature.
3. The Apache ScriptAlias has been changed from "/cgi-bin/zm/zms" to
"/cgi-bin-zm/zms". This has been to done to avoid this bug:
https://bugzilla.redhat.com/show_bug.cgi?id=973067
@ -9,16 +18,10 @@ What's New
and verify it is set to "/cgi-bin-zm/nph-zms". Failure to do so will result
in a broken system. You have been warned.
2. Due to the active state of the ZoneMinder project, we now recommend granting
ALL permission to the ZoneMinder mysql account. This change must be done
manually before ZoneMinder will run. See the installation steps below.
3. This package uses the HTTPS protocol by default to access the web portal.
4. This package uses the HTTPS protocol by default to access the web portal.
Requests using HTTP will auto-redirect to HTTPS. See README.https for
more information.
4. This package ships with the new ZoneMinder API enabled.
New installs
============
@ -43,13 +46,17 @@ New installs
anything that suits your environment.
3. If you have chosen to change the zoneminder database account credentials to
something other than zmuser/zmpass, you must now edit /etc/zm/zm.conf.
Change ZM_DB_USER and ZM_DB_PASS to the values you created in the previous
step.
something other than zmuser/zmpass, you must now create a config file under
/etc/zm/conf.d and set your credentials there. For example, create the file
/etc/zm/conf.d/zm-db-user.conf and add the following content to it:
ZM_DB_USER = {username of the sql account you want to use}
ZM_DB_PASS = {password of the sql account you want to use}
This version of zoneminder no longer requires you to make a similar change
to the credentials in /usr/share/zoneminder/www/api/app/Config/database.php
This now happens dynamically. Do *not* make any changes to this file.
Once the file has been saved, set proper file & ownership permissions on it:
sudo chown root:apache *.conf
sudo chmod 640 *.conf
4. Edit /etc/php.ini, uncomment the date.timezone line, and add your local
timezone. PHP will complain loudly if this is not set, or if it is set
@ -107,21 +114,11 @@ New installs
Upgrades
========
1. Verify /etc/zm/zm.conf.
If zm.conf was manually edited before running the upgrade, the installation
may not overwrite it. In this case, it will create the file
/etc/zm/zm.conf.rpmnew.
For example, this will happen if you are using database account credentials
other than zmuser/zmpass.
Compare /etc/zm/zm.conf to /etc/zm/zm.conf.rpmnew. Verify that zm.conf
contains any new config settings that may be in zm.conf.rpmnew.
This version of zoneminder no longer requires you to make a similar change
to the credentials in /usr/share/zoneminder/www/api/app/Config/database.php
This now happens dynamically. Do *not* make any changes to this file.
1. Conf.d folder support has been added to ZoneMinder 1.31.0. Any custom
changes previously made to zm.conf must now be made in one or more custom
config files, created under the conf.d folder. Do this now. See
/etc/zm/conf.d/README for details. Once you recreate any custom config changes
under the conf.d folder, they will remain in place indefinitely.
2. Verify permissions of the zmuser account.

View File

@ -11,7 +11,16 @@ What's New
replacing core packages, such as php, will not be supported by us. You are
on your own should you choose to go down that path.
2. The Apache ScriptAlias has been changed from "/cgi-bin/zm/zms" to
2. ZoneMinder now uses a conf.d subfolder to process custom changes to
variables found in zm.conf. Changes to zm.conf will be overwritten
during an upgrade. Instead, create a file with a ".conf" extension under
th2 conf.d folder and make your changes there.
3. ZoneMinder now supports recording directly to video container! This feature
is new and should be treated as experimental. Refer to the documentation
regarding how to use this feature.
4. The Apache ScriptAlias has been changed from "/cgi-bin/zm/zms" to
"/cgi-bin-zm/zms". This has been to done match the configuration of
CentOS7/Fedora and simplify the build process.
@ -19,14 +28,6 @@ What's New
Make sure it is set to "/cgi-bin-zm/nph-zms". Failure to do so will result
in a broken system. You have been warned.
3. The ZoneMinder configuration file, zm.conf, has been moved to /etc/zm/.
This has been to done match the configuration of CentOS7/Fedora and
simplify the build process.
4. Due to the active state of the ZoneMinder project, we now recommend granting
ALL permission to the ZoneMinder mysql account. This change must be done
manually before ZoneMinder will run. See the installation steps below.
5. This package uses the HTTPS protocol by default to access the web portal.
Requests using HTTP will auto-redirect to HTTPS. See README.https for
more information.
@ -59,9 +60,18 @@ New installs
The database account credentials, zmuser/zmpass, are arbitrary. Set them to
anything that suits your environment.
3. If you have chosen to change the zoneminder mysql credentials to something
other than zmuser/zmpass then you must now edit /etc/zm/zm.conf. Change
ZM_DB_USER and ZM_DB_PASS to the values you created in the previous step.
3. If you have chosen to change the zoneminder database account credentials to
something other than zmuser/zmpass, you must now create a config file under
/etc/zm/conf.d and set your credentials there. For example, create the file
/etc/zm/conf.d/zm-db-user.conf and add the following content to it:
ZM_DB_USER = {username of the sql account you want to use}
ZM_DB_PASS = {password of the sql account you want to use}
Once the file has been saved, set proper file & ownership permissions on it:
sudo chown root:apache *.conf
sudo chmod 640 *.conf
4. Edit /etc/php.ini, uncomment the date.timezone line, and add your local
timezone. PHP will complain loudly if this is not set, or if it is set
@ -110,17 +120,11 @@ New installs
Upgrades
========
1. Verify /etc/zm/zm.conf.
If zm.conf was manually edited before running the upgrade, the installation
may not overwrite it. In this case, it will create the file
/etc/zm/zm.conf.rpmnew.
For example, this will happen if you are using database account credentials
other than zmuser/zmpass.
Compare /etc/zm/zm.conf to /etc/zm/zm.conf.rpmnew. Verify that zm.conf
contains any new config settings that may be in zm.conf.rpmnew.
1. Conf.d folder support has been added to ZoneMinder 1.31.0. Any custom
changes previously made to zm.conf must now be made in one or more custom
config files, created under the conf.d folder. Do this now. See
/etc/zm/conf.d/README for details. Once you recreate any custom config changes
under the conf.d folder, they will remain in place indefinitely.
2. Verify permissions of the zmuser account.

View File

@ -1,23 +1,26 @@
What's New
==========
1. The Apache ScriptAlias has been changed from "/cgi-bin/zm/zms" to
1. ZoneMinder now uses a conf.d subfolder to process custom changes to
variables found in zm.conf. Changes to zm.conf will be overwritten
during an upgrade. Instead, create a file with a ".conf" extension under
the conf.d folder and make your changes there.
2. ZoneMinder now supports recording directly to video container! This feature
is new and should be treated as experimental. Refer to the documentation
regarding how to use this feature.
3. The Apache ScriptAlias has been changed from "/cgi-bin/zm/zms" to
"/cgi-bin-zm/zms". This has been to done to avoid this bug:
https://bugzilla.redhat.com/show_bug.cgi?id=973067
IMPORTANT: You must manually verify the value of PATH_ZMS under Options.
Make sure it is set to "/cgi-bin-zm/nph-zms". Failure to do so will result
IMPORTANT: You must manually inspect the value for PATH_ZMS under Options
and verify it is set to "/cgi-bin-zm/nph-zms". Failure to do so will result
in a broken system. You have been warned.
2. Due to the active state of the ZoneMinder project, we now recommend granting
ALL permission to the ZoneMinder mysql account. This change must be done
manually before ZoneMinder will run. See the installation steps below.
3. This package uses the HTTPS protocol by default to access the web portal.
4. This package uses the HTTPS protocol by default to access the web portal.
Requests using HTTP will auto-redirect to HTTPS. See README.https for
more information.
4. This package ships with the new ZoneMinder API enabled.
New installs
============
@ -43,13 +46,17 @@ New installs
anything that suits your environment.
3. If you have chosen to change the zoneminder database account credentials to
something other than zmuser/zmpass, you must now edit /etc/zm/zm.conf.
Change ZM_DB_USER and ZM_DB_PASS to the values you created in the previous
step.
something other than zmuser/zmpass, you must now create a config file under
/etc/zm/conf.d and set your credentials there. For example, create the file
/etc/zm/conf.d/zm-db-user.conf and add the following content to it:
ZM_DB_USER = {username of the sql account you want to use}
ZM_DB_PASS = {password of the sql account you want to use}
This version of zoneminder no longer requires you to make a similar change
to the credentials in /usr/share/zoneminder/www/api/app/Config/database.php
This now happens dynamically. Do *not* make any changes to this file.
Once the file has been saved, set proper file & ownership permissions on it:
sudo chown root:apache *.conf
sudo chmod 640 *.conf
4. Edit /etc/php.ini, uncomment the date.timezone line, and add your local
timezone. PHP will complain loudly if this is not set, or if it is set
@ -98,21 +105,11 @@ New installs
Upgrades
========
1. Verify /etc/zm/zm.conf.
If zm.conf was manually edited before running the upgrade, the installation
may not overwrite it. In this case, it will create the file
/etc/zm/zm.conf.rpmnew.
For example, this will happen if you are using database account credentials
other than zmuser/zmpass.
Compare /etc/zm/zm.conf to /etc/zm/zm.conf.rpmnew. Verify that zm.conf
contains any new config settings that may be in zm.conf.rpmnew.
This version of zoneminder no longer requires you to make a similar change
to the credentials in /usr/share/zoneminder/www/api/app/Config/database.php
This now happens dynamically. Do *not* make any changes to this file.
1. Conf.d folder support has been added to ZoneMinder 1.31.0. Any custom
changes previously made to zm.conf must now be made in one or more custom
config files, created under the conf.d folder. Do this now. See
/etc/zm/conf.d/README for details. Once you recreate any custom config changes
under the conf.d folder, they will remain in place indefinitely.
2. Verify permissions of the zmuser account.

View File

@ -280,7 +280,13 @@ rm -rf %{_docdir}/%{name}-%{version}
%files
%license COPYING
%doc AUTHORS README.md distros/redhat/readme/README.%{readme_suffix} distros/redhat/readme/README.https distros/redhat/jscalendar-doc
%config(noreplace) %attr(640,root,%{zmgid_final}) %{_sysconfdir}/zm/zm.conf
%dir %{_sysconfdir}/zm
%dir %{_sysconfdir}/zm/conf.d
%{_sysconfdir}/zm/conf.d/README
# Always overwrite zm.conf now that ZoneMinder supports conf.d folder
%attr(640,root,%{zmgid_final}) %{_sysconfdir}/zm/zm.conf
%config(noreplace) %attr(640,root,%{zmgid_final}) %{_sysconfdir}/zm/conf.d/*.conf
%config(noreplace) %attr(644,root,root) %{wwwconfdir}/zoneminder.conf
%config(noreplace) %{_sysconfdir}/logrotate.d/zoneminder

View File

@ -20,6 +20,7 @@ override_dh_auto_configure:
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DZM_CONFIG_DIR="/etc/zm" \
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
-DZM_RUNDIR="/var/run/zm" \
-DZM_SOCKDIR="/var/run/zm" \
-DZM_TMPDIR="/tmp/zm" \

View File

@ -62,7 +62,9 @@ override_dh_auto_configure:
-DZM_CGIDIR=/usr/lib/cgi-bin \
-DZM_WEB_USER=www-data \
-DZM_WEB_GROUP=www-data \
-DCMAKE_INSTALL_SYSCONFDIR=etc/zm
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
-DZM_CONFIG_DIR="/etc/zm"
override_dh_auto_test:
# do not run tests...

View File

@ -20,6 +20,7 @@ override_dh_auto_configure:
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DZM_CONFIG_DIR="/etc/zm" \
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
-DZM_RUNDIR="/var/run/zm" \
-DZM_SOCKDIR="/var/run/zm" \
-DZM_TMPDIR="/tmp/zm" \

View File

@ -3,7 +3,6 @@ usr/bin
usr/lib/zoneminder
usr/share/polkit-1
usr/share/zoneminder/db
usr/share/zoneminder/icons
usr/share/zoneminder/www
# libzoneminder-perl files:

View File

@ -1,2 +0,0 @@
?package(zoneminder):needs="x11" section="Applications/Video" title="ZoneMinder" command="/usr/bin/x-www-browser http://localhost/zm" icon="/usr/share/zoneminder/icons/16x16/icon.xpm"

View File

@ -65,26 +65,28 @@ our $VERSION = $ZoneMinder::Base::VERSION;
use constant ZM_PID => "@ZM_PID@"; # Path to the ZoneMinder run pid file
use constant ZM_CONFIG => "@ZM_CONFIG@"; # Path to the ZoneMinder config file
use constant ZM_CONFIG_SUBDIR => "@ZM_CONFIG_SUBDIR@"; # Path to the ZoneMinder config subfolder
use Carp;
# Load the config from the database into the symbol table
BEGIN {
# Process name, value pairs from the main config file first
my $config_file = ZM_CONFIG;
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*#/ );
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/;
$Config{$name} = $value;
process_configfile($config_file);
# Search for user created config files. If one or more are found then
# update the Config hash with those values
if ( -d ZM_CONFIG_SUBDIR ) {
if ( -R ZM_CONFIG_SUBDIR ) {
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" );
}
}
close( $CONFIG );
use DBI;
my $socket;
@ -126,6 +128,31 @@ BEGIN {
}
$sth->finish();
}
# This subroutine must be inside the BEGIN block
sub process_configfile {
my $config_file = shift;
if ( -R $config_file ) {
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*#/ );
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/;
$Config{$name} = $value;
}
close( $CONFIG );
} else {
print( STDERR "WARNING: ZoneMinder configuration file found but is not readable. Check file permissions on $config_file\n" );
}
}
} # end BEGIN
sub loadConfigFromDB {

View File

@ -55,6 +55,7 @@ a sql file, which can then be easily imported to another zoneminder system.
--help - Print usage information.
--user=<dbuser> - Alternate dB user with privileges to alter dB.
--pass=<dbpass> - Password of alternate dB user with privileges to alter dB.
--version - Print version.
=cut
use strict;
@ -105,43 +106,43 @@ $Config{ZM_DB_USER} = $dbUser;
$Config{ZM_DB_PASS} = $dbPass;
if ( $version ) {
print( ZoneMinder::Base::ZM_VERSION . "\n");
exit(0);
print( ZoneMinder::Base::ZM_VERSION . "\n");
exit(0);
}
# Check to make sure commandline params make sense
if ( ((!$help) && ($import + $export + $topreset) != 1 )) {
print( STDERR qq/Please give only one of the following: "import", "export", or "topreset".\n/ );
pod2usage(-exitstatus => -1);
print( STDERR qq/Please give only one of the following: "import", "export", or "topreset".\n/ );
pod2usage(-exitstatus => -1);
}
if ( ($export)&&($overwrite) ) {
print( "Warning: Overwrite parameter ignored during an export.\n");
print( "Warning: Overwrite parameter ignored during an export.\n");
}
if ( ($noregex)&&(!$topreset) ) {
print( qq/Warning: Noregex parameter only applies when "topreset" parameter is also set. Ignoring.\n/);
print( qq/Warning: Noregex parameter only applies when "topreset" parameter is also set. Ignoring.\n/);
}
if ( ($topreset)&&($ARGV[0] !~ /\d\d*/) ) {
print( STDERR qq/Parameter "topreset" requires a valid monitor ID.\n/ );
pod2usage(-exitstatus => -1);
print( STDERR qq/Parameter "topreset" requires a valid monitor ID.\n/ );
pod2usage(-exitstatus => -1);
}
# Call the appropriate subroutine based on the params given on the commandline
if ($help) {
pod2usage(-exitstatus => -1);
pod2usage(-exitstatus => -1);
}
if ($export) {
exportsql();
exportsql();
}
if ($import) {
importsql();
importsql();
}
if ($topreset) {
toPreset();
toPreset();
}
###############
@ -149,299 +150,293 @@ if ($topreset) {
###############
# Execute a pre-built sql select query
sub selectQuery
{
my $dbh = shift;
my $sql = shift;
my $monitorid = shift;
sub selectQuery {
my $dbh = shift;
my $sql = shift;
my $monitorid = shift;
my $sth = $dbh->prepare_cached( $sql )
or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute($monitorid)
or die( "Can't execute: ".$sth->errstr() );
my $sth = $dbh->prepare_cached( $sql )
or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute($monitorid)
or die( "Can't execute: ".$sth->errstr() );
my @data = $sth->fetchrow_array();
$sth->finish();
my @data = $sth->fetchrow_array();
$sth->finish();
return @data;
return @data;
}
# Exectute a pre-built sql query
sub runQuery
{
my $dbh = shift;
my $sql = shift;
my $sth = $dbh->prepare_cached( $sql )
or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute()
or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
sub runQuery {
my $dbh = shift;
my $sql = shift;
my $sth = $dbh->prepare_cached( $sql )
or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute()
or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
return $res;
return $res;
}
# Build and execute a sql insert query
sub insertQuery
{
my $dbh = shift;
my $tablename = shift;
my @data = @_;
sub insertQuery {
my $dbh = shift;
my $tablename = shift;
my @data = @_;
my $sql = "INSERT INTO $tablename VALUES (NULL,"
.(join ", ", ("?") x @data).")"; # Add "?" for each array element
my $sql = "INSERT INTO $tablename VALUES (NULL,"
.(join ', ', ('?') x @data).')'; # Add "?" for each array element
my $sth = $dbh->prepare_cached( $sql )
or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute(@data)
or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute(@data)
or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
return $res;
return $res;
}
# Build and execute a sql delete query
sub deleteQuery
{
my $dbh = shift;
my $sqltable = shift;
my $sqlname = shift;
sub deleteQuery {
my $dbh = shift;
my $sqltable = shift;
my $sqlname = shift;
my $sql = "DELETE FROM $sqltable WHERE Name = ?";
my $sth = $dbh->prepare_cached( $sql )
or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute($sqlname)
or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
my $sql = "DELETE FROM $sqltable WHERE Name = ?";
my $sth = $dbh->prepare_cached( $sql )
or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute($sqlname)
or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
return $res;
return $res;
}
# Build and execute a sql select count query
sub checkExists
{
my $dbh = shift;
my $sqltable = shift;
my $sqlname = shift;
my $result = 0;
sub checkExists {
my $dbh = shift;
my $sqltable = shift;
my $sqlname = shift;
my $result = 0;
my $sql = "SELECT count(*) FROM $sqltable WHERE Name = ?";
my $sth = $dbh->prepare_cached( $sql )
or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute($sqlname)
or die( "Can't execute: ".$sth->errstr() );
my $sql = "SELECT count(*) FROM $sqltable WHERE Name = ?";
my $sth = $dbh->prepare_cached( $sql )
or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute($sqlname)
or die( "Can't execute: ".$sth->errstr() );
my $rows = $sth->fetchrow_arrayref();
$sth->finish();
my $rows = $sth->fetchrow_arrayref();
$sth->finish();
if ($rows->[0] > 0) {
$result = 1;
}
if ($rows->[0] > 0) {
$result = 1;
}
return $result;
return $result;
}
# Import camera control & presets into the zoneminder dB
sub importsql
{
my @newcontrols;
my @overwritecontrols;
my @skippedcontrols;
my @newpresets;
my @overwritepresets;
my @skippedpresets;
my %controls;
my %monitorpresets;
sub importsql {
my @newcontrols;
my @overwritecontrols;
my @skippedcontrols;
my @newpresets;
my @overwritepresets;
my @skippedpresets;
my %controls;
my %monitorpresets;
if ($ARGV[0]) {
$sqlfile = $ARGV[0];
if ($ARGV[0]) {
$sqlfile = $ARGV[0];
} else {
$sqlfile = $Config{ZM_PATH_DATA}.'/db/zm_create.sql';
}
open(my $SQLFILE,'<',$sqlfile)
or die( "Can't Open file: $!\n" );
# Find and extract ptz control and monitor preset records
while (<$SQLFILE>) {
# Our regex replaces the primary key with NULL
if (s/^(INSERT INTO .*?Controls.*? VALUES \().*?(,')(.*?)(',.*)/$1NULL$2$3$4/i) {
$controls{$3} = $_;
} elsif (s/^(INSERT INTO .*?MonitorPresets.*? VALUES \().*?(,')(.*?)(',.*)/$1NULL$2$3$4/i) {
$monitorpresets{$3} = $_;
}
}
close $SQLFILE;
if ( ! (%controls || %monitorpresets) ) {
die( "Error: No relevant data found in $sqlfile.\n" );
}
# Now that we've got what we were looking for,
# compare to what is already in the dB
my $dbh = zmDbConnect();
foreach (keys %controls) {
if (!checkExists($dbh,'Controls',$_)) {
# No existing Control was found. Add new control to dB.
runQuery($dbh,$controls{$_});
push @newcontrols, $_;
} elsif ($overwrite) {
# An existing Control was found and the overwrite flag is set.
# Overwrite the control.
deleteQuery($dbh,'Controls',$_);
runQuery($dbh,$controls{$_});
push @overwritecontrols, $_;
} else {
$sqlfile = $Config{ZM_PATH_DATA}.'/db/zm_create.sql';
}
# An existing Control was found and the overwrite flag was not set.
# Do nothing.
push @skippedcontrols, $_;
}
}
open(my $SQLFILE,"<",$sqlfile)
or die( "Can't Open file: $!\n" );
foreach (keys %monitorpresets) {
if (!checkExists($dbh,'MonitorPresets',$_)) {
# No existing MonitorPreset was found. Add new MonitorPreset to dB.
runQuery($dbh,$monitorpresets{$_});
push @newpresets, $_;
} elsif ($overwrite) {
# An existing MonitorPreset was found and the overwrite flag is set.
# Overwrite the MonitorPreset.
deleteQuery($dbh,'MonitorPresets',$_);
runQuery($dbh,$monitorpresets{$_});
push @overwritepresets, $_;
} else {
# An existing MonitorPreset was found and the overwrite flag was
# not set. Do nothing.
push @skippedpresets, $_;
}
}
# Find and extract ptz control and monitor preset records
while (<$SQLFILE>) {
# Our regex replaces the primary key with NULL
if (s/^(INSERT INTO .*?Controls.*? VALUES \().*?(,')(.*?)(',.*)/$1NULL$2$3$4/i) {
$controls{$3} = $_;
} elsif (s/^(INSERT INTO .*?MonitorPresets.*? VALUES \().*?(,')(.*?)(',.*)/$1NULL$2$3$4/i) {
$monitorpresets{$3} = $_;
}
}
close $SQLFILE;
if (@newcontrols) {
print 'Number of ptz camera controls added: '
.scalar(@newcontrols)."\n";
}
if (@overwritecontrols) {
print 'Number of existing ptz camera controls overwritten: '
.scalar(@overwritecontrols)."\n";
}
if (@skippedcontrols) {
print 'Number of existing ptz camera controls skipped: '
.scalar(@skippedcontrols)."\n";
}
if ( ! (%controls || %monitorpresets) ) {
die( "Error: No relevant data found in $sqlfile.\n" );
}
# Now that we've got what we were looking for,
# compare to what is already in the dB
my $dbh = zmDbConnect();
foreach (keys %controls) {
if (!checkExists($dbh,"Controls",$_)) {
# No existing Control was found. Add new control to dB.
runQuery($dbh,$controls{$_});
push @newcontrols, $_;
} elsif ($overwrite) {
# An existing Control was found and the overwrite flag is set.
# Overwrite the control.
deleteQuery($dbh,"Controls",$_);
runQuery($dbh,$controls{$_});
push @overwritecontrols, $_;
} else {
# An existing Control was found and the overwrite flag was not set.
# Do nothing.
push @skippedcontrols, $_;
}
}
foreach (keys %monitorpresets) {
if (!checkExists($dbh,"MonitorPresets",$_)) {
# No existing MonitorPreset was found. Add new MonitorPreset to dB.
runQuery($dbh,$monitorpresets{$_});
push @newpresets, $_;
} elsif ($overwrite) {
# An existing MonitorPreset was found and the overwrite flag is set.
# Overwrite the MonitorPreset.
deleteQuery($dbh,"MonitorPresets",$_);
runQuery($dbh,$monitorpresets{$_});
push @overwritepresets, $_;
} else {
# An existing MonitorPreset was found and the overwrite flag was
# not set. Do nothing.
push @skippedpresets, $_;
}
}
if (@newcontrols) {
print "Number of ptz camera controls added: "
.scalar(@newcontrols)."\n";
}
if (@overwritecontrols) {
print "Number of existing ptz camera controls overwritten: "
.scalar(@overwritecontrols)."\n";
}
if (@skippedcontrols) {
print "Number of existing ptz camera controls skipped: "
.scalar(@skippedcontrols)."\n";
}
if (@newpresets) {
print "Number of monitor presets added: "
.scalar(@newpresets)."\n";
}
if (@overwritepresets) {
print "Number of existing monitor presets overwritten: "
.scalar(@overwritepresets)."\n";
}
if (@skippedpresets) {
print "Number of existing presets skipped: "
.scalar(@skippedpresets)."\n";
}
if (@newpresets) {
print 'Number of monitor presets added: '
.scalar(@newpresets)."\n";
}
if (@overwritepresets) {
print 'Number of existing monitor presets overwritten: '
.scalar(@overwritepresets)."\n";
}
if (@skippedpresets) {
print 'Number of existing presets skipped: '
.scalar(@skippedpresets)."\n";
}
}
# Export camera controls & presets from the zoneminder dB to STDOUT
sub exportsql
{
sub exportsql {
my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
my $command = "mysqldump -t --skip-opt --compact -h".$host;
$command .= " -P".$port if defined($port);
if ( $dbUser ) {
$command .= " -u".$dbUser;
my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
my $command = 'mysqldump -t --skip-opt --compact -h'.$host;
$command .= ' -P'.$port if defined($port);
if ( $dbUser ) {
$command .= ' -u'.$dbUser;
if ( $dbPass ) {
$command .= " -p".$dbPass;
}
$command .= ' -p'.$dbPass;
}
}
if ($ARGV[0]) {
if ($ARGV[0]) {
$command .= qq( --where="Name = '$ARGV[0]'");
}
}
$command .= " zm Controls MonitorPresets";
$command .= " zm Controls MonitorPresets";
my $output = qx($command);
my $status = $? >> 8;
if ( $status || logDebugging() ) {
my $output = qx($command);
my $status = $? >> 8;
if ( $status || logDebugging() ) {
chomp( $output );
print( "Output: $output\n" );
}
if ( $status ) {
}
if ( $status ) {
die( "Command '$command' exited with status: $status\n" );
} else {
# NULLify the primary keys before printing the output to STDOUT
} else {
# NULLify the primary keys before printing the output to STDOUT
$output =~ s/VALUES \((.*?),'/VALUES \(NULL,'/ig;
print $output;
}
}
}
sub toPreset
{
my $dbh = zmDbConnect();
my $monitorid = $ARGV[0];
sub toPreset {
my $dbh = zmDbConnect();
my $monitorid = $ARGV[0];
# Grap the following fields from the Monitors table
my $sql = "SELECT
Name,
Type,
Device,
Channel,
Format,
Protocol,
Method,
Host,
Port,
Path,
SubPath,
Width,
Height,
Palette,
MaxFPS,
Controllable,
ControlId,
ControlDevice,
ControlAddress,
DefaultRate,
DefaultScale
FROM Monitors WHERE Id = ?";
my @data = selectQuery($dbh,$sql,$monitorid);
# Grap the following fields from the Monitors table
my $sql = 'SELECT
Name,
Type,
Device,
Channel,
Format,
Protocol,
Method,
Host,
Port,
Path,
SubPath,
Width,
Height,
Palette,
MaxFPS,
Controllable,
ControlId,
ControlDevice,
ControlAddress,
DefaultRate,
DefaultScale
FROM Monitors WHERE Id = ?';
my @data = selectQuery($dbh,$sql,$monitorid);
if (!@data) {
die( "Error: Monitor Id $monitorid does not appear to exist in the database.\n" );
if (!@data) {
die( "Error: Monitor Id $monitorid does not appear to exist in the database.\n" );
}
# Attempt to search for and replace system specific values such as
# ip addresses, ports, usernames, etc. with generic placeholders
if (!$noregex) {
foreach (@data) {
next if ! $_;
s/\b(?:\d{1,3}\.){3}\d{1,3}\b/<ip-address>/; # ip address
s/<ip-address>:(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)$/<ip-address>:<port>/; # tcpip port
s/\/\/.*:.*@/\/\/<username>:<pwd>@/; # user & pwd preceding an ip address
s/(&|\?)(user|username)=\w\w*(&|\?)/$1$2=<username>$3/i; # username embedded in url
s/(&|\?)(pwd|password)=\w\w*(&|\?)/$1$2=<pwd>$3/i; # password embedded in url
s/\w\w*:\w\w*/<username>:<pwd>/; # user & pwd in their own field
s/\/dev\/video\d\d*/\/dev\/video<?>/; # local video devices
}
}
# Attempt to search for and replace system specific values such as
# ip addresses, ports, usernames, etc. with generic placeholders
if (!$noregex) {
foreach (@data) {
next if ! $_;
s/\b(?:\d{1,3}\.){3}\d{1,3}\b/<ip-address>/; # ip address
s/<ip-address>:(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)$/<ip-address>:<port>/; # tcpip port
s/\/\/.*:.*@/\/\/<username>:<pwd>@/; # user & pwd preceding an ip address
s/(&|\?)(user|username)=\w\w*(&|\?)/$1$2=<username>$3/i; # username embedded in url
s/(&|\?)(pwd|password)=\w\w*(&|\?)/$1$2=<pwd>$3/i; # password embedded in url
s/\w\w*:\w\w*/<username>:<pwd>/; # user & pwd in their own field
s/\/dev\/video\d\d*/\/dev\/video<?>/; # local video devices
}
}
if (!checkExists($dbh,"MonitorPresets",$data[0])) {
# No existing Preset was found. Add new Preset to dB.
print "Adding new preset: $data[0]\n";
insertQuery($dbh,"MonitorPresets",@data);
} elsif ($overwrite) {
# An existing Control was found and the overwrite flag is set.
# Overwrite the control.
print "Existing preset $data[0] detected.\nOverwriting...\n";
deleteQuery($dbh,"MonitorPresets",$data[0]);
insertQuery($dbh,"MonitorPresets",@data);
} else {
# An existing Control was found and the overwrite flag was not set.
# Do nothing.
print "Existing preset $data[0] detected and overwrite flag not set.\nSkipping...\n";
}
if (!checkExists($dbh,"MonitorPresets",$data[0])) {
# No existing Preset was found. Add new Preset to dB.
print "Adding new preset: $data[0]\n";
insertQuery($dbh,'MonitorPresets',@data);
} elsif ($overwrite) {
# An existing Control was found and the overwrite flag is set.
# Overwrite the control.
print "Existing preset $data[0] detected.\nOverwriting...\n";
deleteQuery($dbh,'MonitorPresets',$data[0]);
insertQuery($dbh,'MonitorPresets',@data);
} else {
# An existing Control was found and the overwrite flag was not set.
# Do nothing.
print "Existing preset $data[0] detected and overwrite flag not set.\nSkipping...\n";
}
}
1;
__END__

View File

@ -139,8 +139,10 @@ if ( ! EVENT_PATH ) {
die;
}
# In future, should not be neccessary wrt StorageAreas
chdir( EVENT_PATH );
# SHould not be neccessary... but nice to get a local var. What if it fails?
my $dbh = zmDbConnect();
if ( $filter_parm ) {
@ -149,7 +151,8 @@ if ( $filter_parm ) {
Info( "Scanning for events\n" );
}
if ( !$filter_parm ) {
if ( ! $filter_parm ) {
Debug("Sleeping due to start delay: " . START_DELAY . ' seconds...' );
sleep( START_DELAY );
}
@ -182,7 +185,7 @@ sub getFilters {
if ( $filter_name ) {
$sql .= ' Name = ? and';
} else {
$sql .= ' Background = 1 and';
$sql .= ' Background = 1 AND';
}
$sql .= '( AutoArchive = 1
or AutoVideo = 1

View File

@ -24,14 +24,80 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <glob.h>
#include "zm_utils.h"
void zmLoadConfig() {
// Process name, value pairs from the main config file first
char configFile[PATH_MAX] = ZM_CONFIG;
process_configfile(configFile);
// Search for user created config files. If one or more are found then
// update the Config hash with those values
DIR* configSubFolder = opendir(ZM_CONFIG_SUBDIR);
if ( configSubFolder ) { // subfolder exists and is readable
char glob_pattern[PATH_MAX] = "";
snprintf( glob_pattern, sizeof(glob_pattern), "%s/*.conf", ZM_CONFIG_SUBDIR );
glob_t pglob;
int glob_status = glob( glob_pattern, 0, 0, &pglob );
if ( glob_status != 0 ) {
if ( glob_status < 0 ) {
Error( "Can't glob '%s': %s", glob_pattern, strerror(errno) );
} else {
Debug( 1, "Can't glob '%s': %d", glob_pattern, glob_status );
}
} else {
for ( unsigned int i = 0; i < pglob.gl_pathc; i++ ) {
process_configfile(pglob.gl_pathv[i]);
}
closedir(configSubFolder);
}
globfree( &pglob );
}
zmDbConnect();
config.Load();
config.Assign();
// Populate the server config entries
if ( ! staticConfig.SERVER_ID ) {
if ( ! staticConfig.SERVER_NAME.empty() ) {
Debug( 1, "Fetching ZM_SERVER_ID For Name = %s", staticConfig.SERVER_NAME.c_str() );
std::string sql = stringtf("SELECT Id FROM Servers WHERE Name='%s'", staticConfig.SERVER_NAME.c_str() );
if ( MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() ) ) {
staticConfig.SERVER_ID = atoi(dbrow[0]);
} else {
Fatal("Can't get ServerId for Server %s", staticConfig.SERVER_NAME.c_str() );
}
} // end if has SERVER_NAME
} else if ( staticConfig.SERVER_NAME.empty() ) {
Debug( 1, "Fetching ZM_SERVER_NAME For Id = %d", staticConfig.SERVER_ID );
std::string sql = stringtf("SELECT Name FROM Servers WHERE Id='%d'", staticConfig.SERVER_ID );
if ( MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() ) ) {
staticConfig.SERVER_NAME = std::string(dbrow[0]);
} else {
Fatal("Can't get ServerName for Server ID %d", staticConfig.SERVER_ID );
}
if ( staticConfig.SERVER_ID ) {
Debug( 3, "Multi-server configuration detected. Server is %d.", staticConfig.SERVER_ID );
} else {
Debug( 3, "Single server configuration assumed because no Server ID or Name was specified." );
}
}
}
void process_configfile( char* configFile) {
FILE *cfg;
char line[512];
if ( (cfg = fopen( ZM_CONFIG, "r")) == NULL ) {
Fatal( "Can't open %s: %s", ZM_CONFIG, strerror(errno) );
if ( (cfg = fopen( configFile, "r")) == NULL ) {
Fatal( "Can't open %s: %s", configFile, strerror(errno) );
}
while ( fgets( line, sizeof(line), cfg ) != NULL ) {
char *line_ptr = line;
@ -58,7 +124,7 @@ void zmLoadConfig() {
// Now look for the '=' in the middle of the line
temp_ptr = strchr( line_ptr, '=' );
if ( !temp_ptr ) {
Warning( "Invalid data in %s: '%s'", ZM_CONFIG, line );
Warning( "Invalid data in %s: '%s'", configFile, line );
continue;
}
@ -99,38 +165,6 @@ void zmLoadConfig() {
}
} // end foreach line of the config
fclose( cfg );
zmDbConnect();
config.Load();
config.Assign();
// Populate the server config entries
if ( ! staticConfig.SERVER_ID ) {
if ( ! staticConfig.SERVER_NAME.empty() ) {
Debug( 1, "Fetching ZM_SERVER_ID For Name = %s", staticConfig.SERVER_NAME.c_str() );
std::string sql = stringtf("SELECT Id FROM Servers WHERE Name='%s'", staticConfig.SERVER_NAME.c_str() );
if ( MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() ) ) {
staticConfig.SERVER_ID = atoi(dbrow[0]);
} else {
Fatal("Can't get ServerId for Server %s", staticConfig.SERVER_NAME.c_str() );
}
} // end if has SERVER_NAME
} else if ( staticConfig.SERVER_NAME.empty() ) {
Debug( 1, "Fetching ZM_SERVER_NAME For Id = %d", staticConfig.SERVER_ID );
std::string sql = stringtf("SELECT Name FROM Servers WHERE Id='%d'", staticConfig.SERVER_ID );
if ( MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() ) ) {
staticConfig.SERVER_NAME = std::string(dbrow[0]);
} else {
Fatal("Can't get ServerName for Server ID %d", staticConfig.SERVER_ID );
}
if ( staticConfig.SERVER_ID ) {
Debug( 3, "Multi-server configuration detected. Server is %d.", staticConfig.SERVER_ID );
} else {
Debug( 3, "Single server configuration assumed because no Server ID or Name was specified." );
}
}
}
StaticConfig staticConfig;

View File

@ -26,6 +26,7 @@
#include <string>
#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@
@ -58,6 +59,8 @@
extern void zmLoadConfig();
extern void process_configfile( char* configFile );
struct StaticConfig
{
std::string DB_HOST;

View File

@ -643,7 +643,7 @@ bool EventStream::loadInitialEventData( int init_event_id, unsigned int init_fra
bool EventStream::loadEventData( int event_id ) {
static char sql[ZM_SQL_MED_BUFSIZ];
snprintf( sql, sizeof(sql), "select MonitorId, Frames, unix_timestamp( StartTime ) as StartTimestamp, (SELECT max(Delta)-min(Delta) FROM Frames WHERE EventId=Events.Id) as Duration, DefaultVideo from Events Id = %d", event_id );
snprintf( sql, sizeof(sql), "SELECT MonitorId, Frames, unix_timestamp( StartTime ) AS StartTimestamp, (SELECT max(Delta)-min(Delta) FROM Frames WHERE EventId=Events.Id) AS Duration, DefaultVideo FROM Events WHERE Id = %d", event_id );
if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) );

View File

@ -212,7 +212,12 @@ void Logger::initialise( const std::string &id, const Options &options ) {
level( tempLevel );
mFlush = (envPtr = getenv( "LOG_FLUSH")) ? atoi( envPtr ) : false;
mFlush = false;
if (envPtr = getenv( "LOG_FLUSH")) {
mFlush = atoi( envPtr );
} else if ( config.log_debug ) {
mFlush = true;
}
//mRuntime = (envPtr = getenv( "LOG_RUNTIME")) ? atoi( envPtr ) : false;
{

View File

@ -171,7 +171,7 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
Debug( 1, "Attempting to authenticate user from auth string '%s'", auth );
char sql[ZM_SQL_SML_BUFSIZ] = "";
snprintf( sql, sizeof(sql), "select Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Enabled = 1" );
snprintf( sql, sizeof(sql), "SELECT Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds FROM Users WHERE Enabled = 1" );
if ( mysql_query( &dbconn, sql ) )
{
@ -232,7 +232,7 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
{
sprintf( &auth_md5[2*j], "%02x", md5sum[j] );
}
Debug( 1, "Checking auth_key '%s' -> auth_md5 '%s'", auth_key, auth_md5 );
Debug( 1, "Checking auth_key '%s' -> auth_md5 '%s' == '%s'", auth_key, auth_md5, auth );
if ( !strcmp( auth, auth_md5 ) )
{
@ -246,5 +246,6 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
#else // HAVE_DECL_MD5
Error( "You need to build with gnutls or openssl installed to use hash based authentication" );
#endif // HAVE_DECL_MD5
Debug(1, "No user found for auth_key %s", auth );
return( 0 );
}

View File

@ -379,8 +379,12 @@ bool VideoStore::setup_resampler() {
#ifdef HAVE_LIBAVRESAMPLE
static char error_buffer[256];
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
// Newer ffmpeg wants to keep everything separate... so have to lookup our own decoder, can't reuse the one from the camera.
AVCodec *audio_input_codec = avcodec_find_decoder(audio_input_stream->codecpar->codec_id);
#else
AVCodec *audio_input_codec = avcodec_find_decoder(audio_input_context->codec_id);
#endif
ret = avcodec_open2( audio_input_context, audio_input_codec, NULL );
if ( ret < 0 ) {
Error("Can't open input codec!");
@ -451,11 +455,13 @@ bool VideoStore::setup_resampler() {
// Now copy them to the output stream
audio_output_stream = avformat_new_stream( oc, audio_output_codec );
#if LIBAVCODEC_VERSION_CHECK(57, 0, 0, 0, 0)
ret = avcodec_parameters_from_context( audio_output_stream->codecpar, audio_output_context );
if ( ret < 0 ) {
Error( "Could not initialize stream parameteres");
return false;
}
#endif
AVDictionary *opts = NULL;
av_dict_set( &opts, "strict", "experimental", 0);

View File

@ -46,7 +46,7 @@ private:
#ifdef HAVE_LIBAVRESAMPLE
AVAudioResampleContext* resample_context;
#endif
uint8_t *converted_input_samples = NULL;
uint8_t *converted_input_samples;
const char *filename;
const char *format;

View File

@ -71,6 +71,7 @@ void Zone::Setup(
Debug( 1, "Initialised zone %d/%s - %d - %dx%d - Rgb:%06x, CM:%d, MnAT:%d, MxAT:%d, MnAP:%d, MxAP:%d, FB:%dx%d, MnFP:%d, MxFP:%d, MnBS:%d, MxBS:%d, MnB:%d, MxB:%d, OF: %d, AF: %d", id, label, type, polygon.Width(), polygon.Height(), alarm_rgb, check_method, min_pixel_threshold, max_pixel_threshold, min_alarm_pixels, max_alarm_pixels, filter_box.X(), filter_box.Y(), min_filter_pixels, max_filter_pixels, min_blob_pixels, max_blob_pixels, min_blobs, max_blobs, overload_frames, extend_alarm_frames );
alarmed = false;
was_alarmed = false;
pixel_diff = 0;
alarm_pixels = 0;
alarm_filter_pixels = 0;

View File

@ -77,6 +77,7 @@ protected:
// Outputs/Statistics
bool alarmed;
bool was_alarmed;
int pixel_diff;
unsigned int alarm_pixels;
int alarm_filter_pixels;
@ -131,14 +132,16 @@ public:
inline const Image *AlarmImage() const { return( image ); }
inline const Polygon &GetPolygon() const { return( polygon ); }
inline bool Alarmed() const { return( alarmed ); }
inline void SetAlarm() { alarmed = true; }
inline void ClearAlarm() { alarmed = false; }
inline bool WasAlarmed() const { return( was_alarmed ); }
inline void SetAlarm() { was_alarmed = alarmed; alarmed = true; }
inline void ClearAlarm() { was_alarmed = alarmed; alarmed = false; }
inline Coord GetAlarmCentre() const { return( alarm_centre ); }
inline unsigned int Score() const { return( score ); }
inline void ResetStats()
{
alarmed = false;
was_alarmed = false;
pixel_diff = 0;
alarm_pixels = 0;
alarm_filter_pixels = 0;
@ -170,7 +173,6 @@ public:
inline const Image *getPgImage() const { return( pg_image ); }
inline const Range *getRanges() const { return( ranges ); }
};
#endif // ZM_ZONE_H

View File

@ -63,6 +63,8 @@ DATE=`date -R`
if [ "$TYPE" == "" ]; then
echo "Defaulting to source build"
TYPE="source";
else
echo "Doing $TYPE build"
fi;
if [ "$DISTRO" == "" ]; then
@ -81,6 +83,8 @@ if [ "$RELEASE" != "" ]; then
if [ "$GITHUB_FORK" != "" ] && [ "$GITHUB_FORK" != "ZoneMinder" ]; then
echo "Releases cannot have a fork ($GITHUB_FORK).... exiting."
exit 0;
else
GITHUB_FORK="ZoneMinder";
fi
BRANCH="release-$RELEASE"
else
@ -118,10 +122,10 @@ if [ ! -d "${GITHUB_FORK}_zoneminder_release" ]; then
git pull
cd ../
echo "git clone ${GITHUB_FORK}_ZoneMinder.git ${GITHUB_FORK}_zoneminder_release"
git clone "${GITHUB_FORK}_ZoneMinder.git" "${GITHUB_FORK}_zoneminder_release"
git clone "${GITHUB_FORK}_ZoneMinder.git" "${GITHUB_FORK}_zoneminder_release"
else
echo "git clone https://github.com/$GITHUB_FORK/ZoneMinder.git ${GITHUB_FORK}_zoneminder_release"
git clone "https://github.com/$GITHUB_FORK/ZoneMinder.git" "${GITHUB_FORK}_zoneminder_release"
git clone "https://github.com/$GITHUB_FORK/ZoneMinder.git" "${GITHUB_FORK}_zoneminder_release"
fi
else
echo "release dir already exists. Please remove it."
@ -129,17 +133,13 @@ else
fi;
cd "${GITHUB_FORK}_zoneminder_release"
if [ $RELEASE ]; then
git checkout $RELEASE
else
git checkout $BRANCH
fi;
cd ../
VERSION=`cat ${GITHUB_FORK}_zoneminder_release/version`
if [ $VERSION == "" ]; then
exit 1;
exit 1;
fi;
if [ "$SNAPSHOT" != "stable" ] && [ "$SNAPSHOT" != "" ]; then
VERSION="$VERSION~$SNAPSHOT";
@ -148,12 +148,17 @@ fi;
DIRECTORY="zoneminder_$VERSION";
echo "Doing $TYPE release $DIRECTORY";
mv "${GITHUB_FORK}_zoneminder_release" "$DIRECTORY.orig";
if [ $? -ne 0 ]; then
echo "Error status code is: $?"
echo "Setting up build dir failed.";
exit $?;
fi;
cd "$DIRECTORY.orig";
git submodule init
git submodule update --init --recursive
if [ "$DISTRO" == "trusty" ] || [ "$DISTRO" == "precise" ]; then
mv distros/ubuntu1204 debian
mv distros/ubuntu1204 debian
else
if [ "$DISTRO" == "wheezy" ]; then
mv distros/debian debian
@ -185,6 +190,13 @@ zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
-- $AUTHOR $DATE
EOF
cat <<EOF > debian/NEWS
zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
* Release $VERSION
-- $AUTHOR $DATE
EOF
else
cat <<EOF > debian/changelog
zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
@ -192,7 +204,13 @@ zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
*
-- $AUTHOR $DATE
EOF
cat <<EOF > debian/changelog
zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
*
-- $AUTHOR $DATE
EOF
fi;
@ -207,7 +225,7 @@ if [ $TYPE == "binary" ]; then
sudo apt-get install devscripts equivs
sudo mk-build-deps -ir ./debian/control
echo "Status: $?"
DEBUILD=debuild
DEBUILD=debuild
else
if [ $TYPE == "local" ]; then
# Auto-install all ZoneMinder's depedencies using the Debian control file
@ -216,6 +234,7 @@ else
echo "Status: $?"
DEBUILD="debuild -i -us -uc -b"
else
# Source build, don't need build depends.
DEBUILD="debuild -S -sa"
fi;
fi;
@ -232,48 +251,56 @@ fi;
cd ../
if [ "$INTERACTIVE" != "no" ]; then
read -p "Do you want to keep the checked out version of Zoneminder (incase you want to modify it later) [y/N]"
[[ $REPLY == [yY] ]] && { mv $DIRECTORY zoneminder_release; echo "The checked out copy is preserved in zoneminder_release"; } || { rm -fr $DIRECTORY; echo "The checked out copy has been deleted"; }
[[ $REPLY == [yY] ]] && { mv "$DIRECTORY.orig" zoneminder_release; echo "The checked out copy is preserved in zoneminder_release"; } || { rm -fr "$DIRECTORY.orig"; echo "The checked out copy has been deleted"; }
echo "Done!"
else
rm -fr $DIRECTORY; echo "The checked out copy has been deleted";
rm -fr "$DIRECTORY.orig"; echo "The checked out copy has been deleted";
fi
if [ $TYPE == "binary" ]; then
if [ "$INTERACTIVE" != "no" ]; then
echo "Not doing dput since it's a binary release. Do you want to install it? (Y/N)"
read install
if [ "$install" == "Y" ]; then
read -p "Not doing dput since it's a binary release. Do you want to install it? (Y/N)"
if [[ $REPLY == [yY] ]]; then
sudo dpkg -i $DIRECTORY*.deb
else
echo $REPLY;
fi;
if [ "$DISTRO" == "jessie" ]; then
echo "Do you want to upload this binary to zmrepo? (y/N)"
read install
if [ "$install" == "Y" ]; then
scp "zoneminder_*-${VERSION}-${DISTRO}*" "zmrepo@zmrepo.connortechnology.com:debian/${BRANCH}/mini-dinstall/incoming/"
read -p "Do you want to upload this binary to zmrepo? (y/N)"
if [[ $REPLY == [yY] ]]; then
if [ "$RELEASE" != "" ]; then
scp "zoneminder_${VERSION}-${DISTRO}*" "zmrepo@zmrepo.connortechnology.com:debian/stable/mini-dinstall/incoming/"
else
if [ "$BRANCH" == "" ]; then
scp "zoneminder_${VERSION}-${DISTRO}*" "zmrepo@zmrepo.connortechnology.com:debian/master/mini-dinstall/incoming/"
else
scp "$DIRECTORY-${DISTRO}*" "zmrepo@zmrepo.connortechnology.com:debian/${BRANCH}/mini-dinstall/incoming/"
fi;
fi;
fi;
fi;
fi;
else
SC="zoneminder_${VERSION}-${DISTRO}${PACKAGE_VERSION}_source.changes";
PPA="";
if [ "$RELEASE" != "" ]; then
PPA="ppa:iconnor/zoneminder";
else
if [ "$BRANCH" == "" ]; then
PPA="ppa:iconnor/zoneminder-master";
else
PPA="ppa:iconnor/zoneminder-$BRANCH";
fi;
fi;
PPA="";
if [ "$RELEASE" != "" ]; then
PPA="ppa:iconnor/zoneminder";
else
if [ "$BRANCH" == "" ]; then
PPA="ppa:iconnor/zoneminder-master";
else
PPA="ppa:iconnor/zoneminder-$BRANCH";
fi;
fi;
dput="Y";
if [ "$INTERACTIVE" != "no" ]; then
echo "Ready to dput $SC to $PPA ? Y/N...";
read dput
fi
if [ "$dput" == "Y" -o "$dput" == "y" ]; then
dput $PPA $SC
fi;
if [ "$dput" == [Yy] ]; then
dput $PPA $SC
fi;
fi;

View File

@ -1,46 +1,75 @@
#!/bin/bash
# Start MySQL
# For Xenial the following won't start mysqld
#/usr/bin/mysqld_safe &
# Use this instead:
service mysql start
# Give MySQL time to wake up
SECONDS_LEFT=120
while true; do
sleep 1
mysqladmin ping
if [ $? -eq 0 ];then
break; # Success
setup_mysql_first_time(){
if [ "$(ls /var/lib/mysql)" ]; then
return
fi
let SECONDS_LEFT=SECONDS_LEFT-1
# If we have waited >120 seconds, give up
# ZM should never have a database that large!
# if $COUNTER -lt 120
if [ $SECONDS_LEFT -eq 0 ];then
return -1;
fi
done
# Set MySQL in the volume
rm -rf /var/lib/mysql/*
chown -R mysql:mysql /var/lib/mysql
mysqld --initialize-insecure
# Start MySQL
# For Xenial the following won't start mysqld
#/usr/bin/mysqld_safe &
# Use this instead:
service mysql start
# Create the ZoneMinder database
mysql -u root < db/zm_create.sql
# Give MySQL time to wake up
SECONDS_LEFT=120
while true; do
sleep 1
mysqladmin ping
if [ $? -eq 0 ];then
break; # Success
fi
let SECONDS_LEFT=SECONDS_LEFT-1
# Add the ZoneMinder DB user
mysql -u root -e "grant insert,select,update,delete,lock tables,alter on zm.* to 'zmuser'@'localhost' identified by 'zmpass';"
# If we have waited >120 seconds, give up
# ZM should never have a database that large!
# if $COUNTER -lt 120
if [ $SECONDS_LEFT -eq 0 ];then
return -1;
fi
done
# Make ZM_LOGDIR
mkdir /var/log/zm
# Create the ZoneMinder database
mysql -u root < db/zm_create.sql
# Activate CGI
a2enmod cgi
# Add the ZoneMinder DB user
mysql -u root -e "grant insert,select,update,delete,lock tables,alter on zm.* to 'zmuser'@'localhost' identified by 'zmpass';"
# Shut down mysql cleanly:
kill $(cat /var/run/mysqld/mysqld.pid)
sleep 5
}
# Activate modrewrite
a2enmod rewrite
setup_mysql() {
# To configure MySQL if no container did it before
setup_mysql_first_time
# Add configuration to avoid SQL error when adding monitor
echo "sql_mode=NO_ENGINE_SUBSTITUTION" >> /etc/mysql/mysql.conf.d/mysqld.cnf
}
# Shut down mysql cleanly:
kill $(cat /var/run/mysqld/mysqld.pid)
sleep 5
setup_php() {
# Activate CGI
a2enmod cgi
# Activate modrewrite
a2enmod rewrite
# Setting timezone
sed -i "s#;date.timezone =#date.timezone = $PHP_TIMEZONE#" /etc/php/7.0/apache2/php.ini
# Settings rights for volume
chown -R www-data:www-data /var/lib/zoneminder/events
chown -R www-data:www-data /var/lib/zoneminder/images
}
setup_mysql
setup_php
exit 0

View File

@ -35,7 +35,7 @@ done
service apache2 restart
# Start ZoneMinder
/usr/local/bin/zmpkg.pl start
/usr/local/bin/zmpkg.pl start && echo "Zone Minder started"
while :
do

9
utils/packpack/heartbeat.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
# A script to provide background noise so Travis doesn't kill us due to inactivity
# written by Andrew Bauer
while true; do
echo "$(date) - Please don't kill us Mr. Travis, we are still running!"
sleep 30s
done

View File

@ -36,24 +36,46 @@ checksanity () {
echo
exit 1
fi
}
# Create key variables used to assemble the package name
createvars () {
# We need today's date in year/month/day format
thedate=$(date +%Y%m%d)
# We need the (short) commit hash of the latest commit (rpm packaging only)
shorthash=$(git describe --long --always | awk -F - '{print $3}')
# Grab the ZoneMinder version from the contents of the version file
versionfile=$(cat version)
# git the latest (short) commit hash of the version file
versionhash=$(git log -n1 --pretty=format:%h version)
# Number of commits since the version file was last changed
numcommits=$(git rev-list ${versionhash}..HEAD --count)
}
# Check key variables before calling packpack
checkvars () {
if [ -z ${VERSION} ]; then
echo
echo "FATAL: VERSION variable was null. Cannot continue."
echo
exit 98
fi
if [ -z ${RELEASE} ]; then
echo
echo "FATAL: RELEASE variable was null. Cannot Continue"
echo
exit 98
fi
for var in $thedate $shorthash $versionfile $versionhash $numcommits; do
if [ -z ${var} ]; then
echo
echo "FATAL: This script was unable to determine one or more key variables. Cannot continue."
echo
echo "VARIABLE DUMP"
echo "-------------"
echo
echo "thedate: ${thedate}"
echo "shorthash: ${shorthash}"
echo "versionfile: ${versionfile}"
echo "versionhash: ${versionhash}"
echo "numcommits: ${numcommits}"
echo
exit 98
fi
done
}
# Steps common to all builds
@ -131,15 +153,33 @@ installtrusty () {
fi
}
# This sets the naming convention for the deb packages
setdebpkgver () {
# This sets the naming convention for the rpm packages
setrpmpkgname () {
createvars
# Set VERSION to the contents of the version file e.g. 1.31.0
# Set RELEASE to 1.{number of commits}.{today's date}git{short hash of HEAD} e.g. 1.82.20170605gitg7ae0b4a
export VERSION="$versionfile"
export RELEASE="1.${numcommits}.${thedate}git${shorthash}"
checkvars
# Set VERSION to x.xx.x+x e.g. 1.30.2+15
# the last x is number of commits since release
# Creates zoneminder packages in the format: zoneminder-{version}-{release}
zmver=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\1/p')
commitnum=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\2/p')
export VERSION="$zmver+$commitnum"
echo
echo "Packpack VERSION has been set to: ${VERSION}"
echo "Packpack RELEASE has been set to: ${RELEASE}"
echo
}
# This sets the naming convention for the deb packages
setdebpkgname () {
createvars
# Set VERSION to {zm version}~{today's date}.{number of commits} e.g. 1.31.0~20170605.82
# Set RELEASE to the packpack DIST variable e.g. Trusty
export VERSION="${versionfile}~${thedate}.${numcommits}"
export RELEASE="${DIST}"
checkvars
@ -151,6 +191,16 @@ setdebpkgver () {
}
# This adds an entry to the rpm specfile changelog
setrpmchangelog () {
export CHANGELOG_NAME="Andrew Bauer"
export CHANGELOG_EMAIL="zonexpertconsulting@outlook.com"
export CHANGELOG_TEXT="Automated, development snapshot of git ${shorthash}"
}
# This adds an entry to the debian changelog
setdebchangelog () {
DATE=`date -R`
@ -177,18 +227,7 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
if [ "${OS}" == "el" ] || [ "${OS}" == "fedora" ]; then
echo "Begin Redhat build..."
# Set VERSION to x.xx.x e.g. 1.30.2
# Set RELEASE to x where x is number of commits since release
# Creates zoneminder packages in the format: zoneminder-{version}-{release}
export VERSION=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\1/p')
export RELEASE=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\2/p')
checkvars
echo
echo "Packpack VERSION has been set to: ${VERSION}"
echo "Packpack RELEASE has been set to: ${RELEASE}"
echo
setrpmpkgname
ln -sfT distros/redhat rpm
@ -213,14 +252,20 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
exit 1
fi
setrpmchangelog
echo "Starting packpack..."
packpack/packpack -f utils/packpack/redhat_package.mk redhat_package
utils/packpack/heartbeat.sh &
mypid=$!
packpack/packpack -f utils/packpack/redhat_package.mk redhat_package > buildlog.txt 2>&1
kill $mypid
tail -n 1000 buildlog.txt
# Steps common to Debian based distros
elif [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ]; then
echo "Begin ${OS} ${DIST} build..."
setdebpkgver
setdebpkgname
movecrud
if [ "${DIST}" == "trusty" ] || [ "${DIST}" == "precise" ]; then
@ -234,8 +279,12 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
setdebchangelog
echo "Starting packpack..."
packpack/packpack
utils/packpack/heartbeat.sh &
mypid=$!
packpack/packpack > buildlog.txt 2>&1
kill $mypid
tail -n 1000 buildlog.txt
if [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "trusty" ] && [ "${ARCH}" == "x86_64" ] && [ "${TRAVIS}" == "true" ]; then
installtrusty
fi
@ -246,7 +295,7 @@ elif [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "trusty" ] && [ "${ARCH}" == "x86
echo "Begin Ubuntu Trusty build..."
commonprep
setdebpkgver
setdebpkgname
movecrud
ln -sfT distros/ubuntu1204 debian
@ -254,7 +303,11 @@ elif [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "trusty" ] && [ "${ARCH}" == "x86
setdebchangelog
echo "Starting packpack..."
packpack/packpack
utils/packpack/heartbeat.sh &
mypid=$!
packpack/packpack > buildlog.txt 2>&1
kill $mypid
tail -n 1000 buildlog.txt
# If we are running inside Travis then attempt to install the deb we just built
if [ "${TRAVIS}" == "true" ]; then

View File

@ -1,119 +1,120 @@
<?php
if ( empty($_REQUEST['id']) && empty($_REQUEST['eids']) ) {
ajaxError( "No event id(s) supplied" );
ajaxError( 'No event id(s) supplied' );
}
if ( canView( 'Events' ) ) {
switch ( $_REQUEST['action'] ) {
case 'video' : {
if ( empty($_REQUEST['videoFormat']) ) {
ajaxError( "Video Generation Failure, no format given" );
} elseif ( empty($_REQUEST['rate']) ) {
ajaxError( "Video Generation Failure, no rate given" );
} elseif ( empty($_REQUEST['scale']) ) {
ajaxError( "Video Generation Failure, no scale given" );
} else {
$sql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultRate,M.DefaultScale FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE E.Id = ?'.monitorLimitSql();
if ( !($event = dbFetchOne( $sql, NULL, array( $_REQUEST['id'] ) )) )
ajaxError( "Video Generation Failure, can't load event" );
else
if ( $videoFile = createVideo( $event, $_REQUEST['videoFormat'], $_REQUEST['rate'], $_REQUEST['scale'], !empty($_REQUEST['overwrite']) ) )
ajaxResponse( array( 'response'=>$videoFile ) );
else
ajaxError( "Video Generation Failed" );
}
$ok = true;
break;
switch ( $_REQUEST['action'] ) {
case 'video' :
{
if ( empty($_REQUEST['videoFormat']) ) {
ajaxError( 'Video Generation Failure, no format given' );
} elseif ( empty($_REQUEST['rate']) ) {
ajaxError( 'Video Generation Failure, no rate given' );
} elseif ( empty($_REQUEST['scale']) ) {
ajaxError( 'Video Generation Failure, no scale given' );
} else {
$sql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultRate,M.DefaultScale FROM Events AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE E.Id = ?'.monitorLimitSql();
if ( !($event = dbFetchOne( $sql, NULL, array( $_REQUEST['id'] ) )) )
ajaxError( "Video Generation Failure, can't load event" );
else
if ( $videoFile = createVideo( $event, $_REQUEST['videoFormat'], $_REQUEST['rate'], $_REQUEST['scale'], !empty($_REQUEST['overwrite']) ) )
ajaxResponse( array( 'response'=>$videoFile ) );
else
ajaxError( "Video Generation Failed" );
}
case 'deleteVideo' :
{
unlink( $videoFiles[$_REQUEST['id']] );
unset( $videoFiles[$_REQUEST['id']] );
ajaxResponse();
break;
}
case "export" :
{
require_once( ZM_SKIN_PATH.'/includes/export_functions.php' );
$ok = true;
break;
}
case 'deleteVideo' :
{
unlink( $videoFiles[$_REQUEST['id']] );
unset( $videoFiles[$_REQUEST['id']] );
ajaxResponse();
break;
}
case 'export' :
{
require_once( ZM_SKIN_PATH.'/includes/export_functions.php' );
# We use session vars in here, so we need to restart the session because we stopped it in index.php to improve concurrency.
session_start();
# We use session vars in here, so we need to restart the session because we stopped it in index.php to improve concurrency.
session_start();
if ( !empty($_REQUEST['exportDetail']) )
$exportDetail = $_SESSION['export']['detail'] = $_REQUEST['exportDetail'];
else
$exportDetail = false;
if ( !empty($_REQUEST['exportFrames']) )
$exportFrames = $_SESSION['export']['frames'] = $_REQUEST['exportFrames'];
else
$exportFrames = false;
if ( !empty($_REQUEST['exportImages']) )
$exportImages = $_SESSION['export']['images'] = $_REQUEST['exportImages'];
else
$exportImages = false;
if ( !empty($_REQUEST['exportVideo']) )
$exportVideo = $_SESSION['export']['video'] = $_REQUEST['exportVideo'];
else
$exportVideo = false;
if ( !empty($_REQUEST['exportMisc']) )
$exportMisc = $_SESSION['export']['misc'] = $_REQUEST['exportMisc'];
else
$exportMisc = false;
if ( !empty($_REQUEST['exportFormat']) )
$exportFormat = $_SESSION['export']['format'] = $_REQUEST['exportFormat'];
else
$exportFormat = '';
if ( !empty($_REQUEST['exportDetail']) )
$exportDetail = $_SESSION['export']['detail'] = $_REQUEST['exportDetail'];
else
$exportDetail = false;
if ( !empty($_REQUEST['exportFrames']) )
$exportFrames = $_SESSION['export']['frames'] = $_REQUEST['exportFrames'];
else
$exportFrames = false;
if ( !empty($_REQUEST['exportImages']) )
$exportImages = $_SESSION['export']['images'] = $_REQUEST['exportImages'];
else
$exportImages = false;
if ( !empty($_REQUEST['exportVideo']) )
$exportVideo = $_SESSION['export']['video'] = $_REQUEST['exportVideo'];
else
$exportVideo = false;
if ( !empty($_REQUEST['exportMisc']) )
$exportMisc = $_SESSION['export']['misc'] = $_REQUEST['exportMisc'];
else
$exportMisc = false;
if ( !empty($_REQUEST['exportFormat']) )
$exportFormat = $_SESSION['export']['format'] = $_REQUEST['exportFormat'];
else
$exportFormat = '';
session_write_close();
session_write_close();
$exportIds = !empty($_REQUEST['eids'])?$_REQUEST['eids']:$_REQUEST['id'];
if ( $exportFile = exportEvents( $exportIds, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat ) )
ajaxResponse( array( 'exportFile'=>$exportFile ) );
else
ajaxError( "Export Failed" );
break;
}
}
$exportIds = !empty($_REQUEST['eids'])?$_REQUEST['eids']:$_REQUEST['id'];
if ( $exportFile = exportEvents( $exportIds, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat ) )
ajaxResponse( array( 'exportFile'=>$exportFile ) );
else
ajaxError( 'Export Failed' );
break;
}
}
}
if ( canEdit( 'Events' ) ) {
switch ( $_REQUEST['action'] ) {
case 'rename' :
{
if ( !empty($_REQUEST['eventName']) )
dbQuery( 'UPDATE Events SET Name = ? WHERE Id = ?', array( $_REQUEST['eventName'], $_REQUEST['id'] ) );
else
ajaxError( "No new event name supplied" );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>true ) );
break;
switch ( $_REQUEST['action'] ) {
case 'rename' :
{
if ( !empty($_REQUEST['eventName']) )
dbQuery( 'UPDATE Events SET Name = ? WHERE Id = ?', array( $_REQUEST['eventName'], $_REQUEST['id'] ) );
else
ajaxError( "No new event name supplied" );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>true ) );
break;
}
case 'eventdetail' :
{
dbQuery( 'UPDATE Events SET Cause = ?, Notes = ? WHERE Id = ?', array( $_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $_REQUEST['id'] ) );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>true ) );
break;
}
case 'archive' :
case 'unarchive' :
{
$archiveVal = ($_REQUEST['action'] == 'archive')?1:0;
dbQuery( 'UPDATE Events SET Archived = ? WHERE Id = ?', array( $archiveVal, $_REQUEST['id']) );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>false ) );
break;
}
case 'delete' :
{
$Event = new Event( $_REQUEST['id'] );
if ( ! $Event->Id() ) {
ajaxResponse( array( 'refreshEvent'=>false, 'refreshParent'=>true, 'message'=> 'Event not found.' ) );
} else {
$Event->delete();
ajaxResponse( array( 'refreshEvent'=>false, 'refreshParent'=>true ) );
}
case 'eventdetail' :
{
dbQuery( 'UPDATE Events SET Cause = ?, Notes = ? WHERE Id = ?', array( $_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $_REQUEST['id'] ) );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>true ) );
break;
}
case 'archive' :
case 'unarchive' :
{
$archiveVal = ($_REQUEST['action'] == "archive")?1:0;
dbQuery( 'UPDATE Events SET Archived = ? WHERE Id = ?', array( $archiveVal, $_REQUEST['id']) );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>false ) );
break;
}
case 'delete' :
{
$Event = new Event( $_REQUEST['id'] );
if ( ! $Event->Id() ) {
ajaxResponse( array( 'refreshEvent'=>false, 'refreshParent'=>true, 'message'=> 'Event not found.' ) );
} else {
$Event->delete();
ajaxResponse( array( 'refreshEvent'=>false, 'refreshParent'=>true ) );
}
break;
}
}
break;
}
}
}
ajaxError( 'Unrecognised action or insufficient permissions' );

View File

@ -100,12 +100,12 @@ App::uses('CakeLog', 'Log');
CakeLog::config('debug', array(
'engine' => 'File',
'types' => array('notice', 'info', 'debug'),
'file' => '@ZM_LOGDIR@/cake_debug',
'file' => 'cake_debug',
));
CakeLog::config('error', array(
'engine' => 'File',
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
'file' => '@ZM_LOGDIR@/cake_error',
'file' => 'cake_error',
));
CakeLog::config('custom_path', array(
'engine' => 'File',

View File

@ -137,28 +137,27 @@ class Event {
$streamSrc = ZM_BASE_URL.ZM_PATH_ZMS;
$args[] = 'source=event&event='.$this->{'Id'};
$args['source'] = 'event';
$args['event'] = $this->{'Id'};
if ( ZM_OPT_USE_AUTH ) {
if ( ZM_AUTH_RELAY == 'hashed' ) {
$args[] = 'auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
$args['auth'] = generateAuthHash( ZM_AUTH_HASH_IPS );
} elseif ( ZM_AUTH_RELAY == 'plain' ) {
$args[] = 'user='.$_SESSION['username'];
$args[] = 'pass='.$_SESSION['password'];
$args['user'] = $_SESSION['username'];
$args['pass'] = $_SESSION['password'];
} elseif ( ZM_AUTH_RELAY == "none" ) {
$args[] = 'user='.$_SESSION['username'];
$args['user'] = $_SESSION['username'];
}
}
if ( !in_array( 'mode=single', $args ) && !empty($GLOBALS['connkey']) ) {
$args[] = 'connkey='.$GLOBALS['connkey'];
if ( ( (!isset($args['mode'])) or ( $args['mode'] != 'single' ) ) && !empty($GLOBALS['connkey']) ) {
$args['connkey'] = $GLOBALS['connkey'];
}
if ( ZM_RAND_STREAM ) {
$args[] = 'rand='.time();
$args['rand'] = time();
}
if ( count($args) ) {
$streamSrc .= '?'.join( $querySep, $args );
}
$streamSrc .= '?'.http_build_query( $args,'', $querySep );
return( $streamSrc );
} // end function getStreamSrc

View File

@ -198,9 +198,7 @@ private $control_fields = array(
$args['rand'] = time();
}
if ( count($args) ) {
$streamSrc .= '?'.http_build_query( $args,'', $querySep );
}
$streamSrc .= '?'.http_build_query( $args,'', $querySep );
return( $streamSrc );
} // end function getStreamSrc

View File

@ -22,6 +22,7 @@
// This section contains options substituted by the zmconfig.pl utility, do not edit these directly
//
define( "ZM_CONFIG", "@ZM_CONFIG@" ); // Path to config file
define( "ZM_CONFIG_SUBDIR", "@ZM_CONFIG_SUBDIR@" ); // Path to config subfolder
// Define, and override any given in config file
define( "ZM_VERSION", "@VERSION@" ); // Version
define( "ZM_DIR_TEMP", "@ZM_TMPDIR@" );
@ -36,19 +37,28 @@ if ( file_exists( $localConfigFile ) && filesize( $localConfigFile ) > 0 )
error_log( "Warning, overriding installed $localConfigFile file with local copy" );
$configFile = $localConfigFile;
}
$cfg = fopen( $configFile, "r") or die("Could not open config file.");
while ( !feof($cfg) )
{
$str = fgets( $cfg, 256 );
if ( preg_match( '/^\s*$/', $str ))
continue;
elseif ( preg_match( '/^\s*#/', $str ))
continue;
elseif ( preg_match( '/^\s*([^=\s]+)\s*=\s*(.*?)\s*$/', $str, $matches ))
define( $matches[1], $matches[2] );
# Process name, value pairs from the main config file first
$configvals = process_configfile($configFile);
# Search for user created config files. If one or more are found then
# update our config value array with those values
$configSubFolder = ZM_CONFIG_SUBDIR;
if ( is_dir($configSubFolder) ) {
if ( is_readable($configSubFolder) ) {
foreach ( glob("$configSubFolder/*.conf") as $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." );
}
}
# Now that our array our finalized, define each key => value
# pair in the array as a constant
foreach( $configvals as $key => $value) {
define( $key, $value );
}
fclose( $cfg );
//
// This section is options normally derived from other options or configuration
@ -189,5 +199,27 @@ if ( ! defined('ZM_SERVER_ID') ) {
}
}
function process_configfile($configFile) {
if ( is_readable( $configFile ) ) {
$configvals = array();
$cfg = fopen( $configFile, "r") or die("Could not open config file.");
while ( !feof($cfg) )
{
$str = fgets( $cfg, 256 );
if ( preg_match( '/^\s*$/', $str ))
continue;
elseif ( preg_match( '/^\s*#/', $str ))
continue;
elseif ( preg_match( '/^\s*([^=\s]+)\s*=\s*(.*?)\s*$/', $str, $matches ))
$configvals[$matches[1]] = $matches[2];
}
fclose( $cfg );
return( $configvals );
} else {
error_log( "WARNING: ZoneMinder configuration file found but is not readable. Check file permissions on $configFile." );
return( false );
}
}
?>

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,6 @@ function xhtmlHeaders( $file, $title ) {
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<title><?php echo ZM_WEB_TITLE_PREFIX ?> - <?php echo validHtmlStr($title) ?></title>
<link rel="icon" type="image/ico" href="graphics/favicon.ico"/>
<link rel="shortcut icon" href="graphics/favicon.ico"/>

View File

@ -33,7 +33,7 @@ $eventCounts = array(
'title' => translate('Hour'),
'filter' => array(
'terms' => array(
array( 'attr' => "DateTime", 'op' => ">=", 'val' => "-1 hour" ),
array( 'attr' => 'DateTime', 'op' => '>=', 'val' => '-1 hour' ),
)
),
),
@ -41,7 +41,7 @@ $eventCounts = array(
'title' => translate('Day'),
'filter' => array(
'terms' => array(
array( 'attr' => "DateTime", 'op' => ">=", 'val' => "-1 day" ),
array( 'attr' => "DateTime", 'op' => '>=', 'val' => '-1 day' ),
)
),
),
@ -49,7 +49,7 @@ $eventCounts = array(
'title' => translate('Week'),
'filter' => array(
'terms' => array(
array( 'attr' => "DateTime", 'op' => ">=", 'val' => "-7 day" ),
array( 'attr' => "DateTime", 'op' => '>=', 'val' => '-7 day' ),
)
),
),
@ -57,7 +57,7 @@ $eventCounts = array(
'title' => translate('Month'),
'filter' => array(
'terms' => array(
array( 'attr' => "DateTime", 'op' => ">=", 'val' => "-1 month" ),
array( 'attr' => "DateTime", 'op' => '>=', 'val' => '-1 month' ),
)
),
),
@ -65,7 +65,7 @@ $eventCounts = array(
'title' => translate('Archived'),
'filter' => array(
'terms' => array(
array( 'attr' => "Archived", 'op' => "=", 'val' => "1" ),
array( 'attr' => "Archived", 'op' => '=', 'val' => '1' ),
)
),
),
@ -115,7 +115,7 @@ for ( $i = 0; $i < count($monitors); $i++ ) {
$counts[] = 'count(if(1'.$filter['sql'].",1,NULL)) as EventCount$j";
$monitors[$i]['eventCounts'][$j]['filter'] = $filter;
}
$sql = 'select '.join($counts,", ").' from Events as E where MonitorId = ?';
$sql = 'SELECT '.join($counts,', ').' FROM Events AS E WHERE MonitorId = ?';
$counts = dbFetchOne( $sql, NULL, array($monitors[$i]['Id']) );
if ( $monitors[$i]['Function'] != 'None' ) {
$cycleCount++;

View File

@ -128,12 +128,11 @@ if ( canEdit( 'Events' ) ) {
<div id="archiveEvent" class="hidden"><a href="#" onclick="archiveEvent()"><?php echo translate('Archive') ?></a></div>
<div id="unarchiveEvent" class="hidden"><a href="#" onclick="unarchiveEvent()"><?php echo translate('Unarchive') ?></a></div>
<?php
} // end if can edit Events
if ( $Event->DefaultVideo() ) { ?>
<div id="downloadEventFile"><a href="<?php echo $Event->getStreamSrc()?>">Download MP4</a></div>
<?php
} // end if Event->DefaultVideo
} // end if can edit Events
if ( canView( 'Events' ) ) {
?>
<div id="framesEvent"><a href="#" onclick="showEventFrames()"><?php echo translate('Frames') ?></a></div>
<?php
@ -170,14 +169,14 @@ if ( $Event->DefaultVideo() ) {
<div id="imageFeed" <?php if ( $Event->DefaultVideo() ) { ?>class="hidden"<?php } ?> >
<?php
if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) {
$streamSrc = getStreamSrc( array( "source=event", "mode=mpeg", "event=".$eid, "frame=".$fid, "scale=".$scale, "rate=".$rate, "bitrate=".ZM_WEB_VIDEO_BITRATE, "maxfps=".ZM_WEB_VIDEO_MAXFPS, "format=".ZM_MPEG_REPLAY_FORMAT, "replay=".$replayMode ) );
$streamSrc = $Event->getStreamSrc( array( 'mode'=>'mpeg', 'scale'=>$scale, 'rate'=>$rate, 'bitrate'=>ZM_WEB_VIDEO_BITRATE, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'format'=>ZM_MPEG_REPLAY_FORMAT, 'replay'=>$replayMode ) );
outputVideoStream( "evtStream", $streamSrc, reScale( $Event->Width(), $scale ), reScale( $Event->Height(), $scale ), ZM_MPEG_LIVE_FORMAT );
} else {
$streamSrc = getStreamSrc( array( "source=event", "mode=jpeg", "event=".$eid, "frame=".$fid, "scale=".$scale, "rate=".$rate, "maxfps=".ZM_WEB_VIDEO_MAXFPS, "replay=".$replayMode) );
$streamSrc = $Event->getStreamSrc( array( 'mode'=>'jpeg', 'frame'=>$fid, 'scale'=>$scale, 'rate'=>$rate, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>$replayMode) );
if ( canStreamNative() ) {
outputImageStream( "evtStream", $streamSrc, reScale( $Event->Width(), $scale ), reScale( $Event->Height(), $scale ), validHtmlStr($Event->Name()) );
outputImageStream( 'evtStream', $streamSrc, reScale( $Event->Width(), $scale ), reScale( $Event->Height(), $scale ), validHtmlStr($Event->Name()) );
} else {
outputHelperStream( "evtStream", $streamSrc, reScale( $Event->Width(), $scale ), reScale( $Event->Height(), $scale ) );
outputHelperStream( 'evtStream', $streamSrc, reScale( $Event->Width(), $scale ), reScale( $Event->Height(), $scale ) );
}
} // end if stream method
?>
@ -244,8 +243,7 @@ if ($Event->SaveJPEGs() & 3) { // frames or analysis
</div>
</div>
<?php
} // end if SaveJPEGs() & 3 Analysis or Jpegs
} // end if canView
} // end if SaveJPEGs() & 3 Analysis or Jpegs
} // end if Event exists
?>
</div><!--page-->

View File

@ -628,17 +628,16 @@ function drawProgressBar() {
var cells = $('progressBar').getElements( 'div' );
var cellWidth = parseInt( eventData.Width/$$(cells).length );
$$(cells).forEach(
function( cell, index )
{
function( cell, index ) {
if ( index == 0 )
$(cell).setStyles( { 'left': barWidth, 'width': cellWidth, 'borderLeft': 0 } );
$(cell).setStyles( { 'left': barWidth, 'width': cellWidth, 'borderLeft': 0 } );
else
$(cell).setStyles( { 'left': barWidth, 'width': cellWidth } );
var offset = parseInt((index*eventData.Length)/$$(cells).length);
$(cell).setProperty( 'title', '+'+secsToTime(offset)+'s' );
$(cell).removeEvent( 'click' );
$(cell).addEvent( 'click', function() { streamSeek( offset ); } );
barWidth += $(cell).getCoordinates().width;
$(cell).setStyles( { 'left': barWidth, 'width': cellWidth } );
var offset = parseInt((index*eventData.Length)/$$(cells).length);
$(cell).setProperty( 'title', '+'+secsToTime(offset)+'s' );
$(cell).removeEvent( 'click' );
$(cell).addEvent( 'click', function() { streamSeek( offset ); } );
barWidth += $(cell).getCoordinates().width;
}
);
$('progressBar').setStyle( 'width', barWidth );
@ -662,7 +661,7 @@ function updateProgressBar() {
} // end if
} // end function
);
$('progressBar').setStyle( 'width', barWidth );
//$('progressBar').setStyle( 'width', barWidth );
$('progressBar').removeClass( 'invisible' );
} // end if eventData && streamStatus
} // end function updateProgressBar()

View File

@ -1,13 +1,16 @@
# ==========================================================================
#
# ZoneMinder Base Configuration, $Date$, $Revision$
# ZoneMinder Base Configuration File
#
# ==========================================================================
#
# This file is generated by 'configure'. Care should be taken if manually
# editing this file as an changes may be overwritten by subsequent configuration
# or installations.
# *** DO NOT EDIT THIS FILE ***
# Changes made directly to this configuration file are no longer supported.
# They will be overwritten during an upgrade.
#
# Instead, create a custom configuration file, with an extention of ".conf"
# under the @ZM_CONFIG_SUBDIR@ subfolder containing your desired modifications.
#
# Path to installed data directory, used mostly for finding DB upgrade scripts
ZM_PATH_DATA=@PKGDATADIR@
@ -47,9 +50,3 @@ ZM_DB_USER=@ZM_DB_USER@
# ZoneMinder database password
ZM_DB_PASS=@ZM_DB_PASS@
# Do NOT set ZM_SERVER_HOST if you are not using Multi-Server
# You have been warned
#
# The name specified here must have a corresponding entry
# in the Servers tab under Options
ZM_SERVER_HOST=