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_PERL_SEARCH_PATH
ZM_TARGET_DISTRO ZM_TARGET_DISTRO
ZM_CONFIG_DIR ZM_CONFIG_DIR
ZM_CONFIG_SUBDIR
ZM_SYSTEMD) ZM_SYSTEMD)
set(ZM_RUNDIR "/var/run/zm" CACHE PATH set(ZM_RUNDIR "/var/run/zm" CACHE PATH
@ -137,6 +138,8 @@ set(ZM_WEB_GROUP "" CACHE STRING
# Advanced # Advanced
set(ZM_CONFIG_DIR "/${CMAKE_INSTALL_SYSCONFDIR}" CACHE PATH set(ZM_CONFIG_DIR "/${CMAKE_INSTALL_SYSCONFDIR}" CACHE PATH
"Location of ZoneMinder configuration, default system config directory") "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 set(ZM_EXTRA_LIBS "" CACHE STRING
"A list of optional libraries, separated by semicolons, e.g. ssl;theora") "A list of optional libraries, separated by semicolons, e.g. ssl;theora")
set(ZM_MYSQL_ENGINE "InnoDB" CACHE STRING 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") "Set to ON to force building ZM with systemd support. default: OFF")
# Reassign some variables if a target distro has been specified # Reassign some variables if a target distro has been specified
if((ZM_TARGET_DISTRO STREQUAL "fc24") OR (ZM_TARGET_DISTRO STREQUAL "fc25")) 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_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")
set(ZM_RUNDIR "/var/run/zoneminder") set(ZM_RUNDIR "/var/run/zoneminder")
set(ZM_SOCKDIR "/var/lib/zoneminder/sock") set(ZM_SOCKDIR "/var/lib/zoneminder/sock")
set(ZM_TMPDIR "/var/lib/zoneminder/temp") set(ZM_TMPDIR "/var/lib/zoneminder/temp")
set(ZM_LOGDIR "/var/log/zoneminder") set(ZM_LOGDIR "/var/log/zoneminder")
set(ZM_CONFIG_DIR "/etc/zm") set(ZM_CONFIG_DIR "/etc/zm")
set(ZM_CONFIG_SUBDIR "/etc/zm/conf.d")
set(ZM_WEBDIR "/usr/share/zoneminder/www") set(ZM_WEBDIR "/usr/share/zoneminder/www")
set(ZM_CGIDIR "/usr/libexec/zoneminder/cgi-bin") set(ZM_CGIDIR "/usr/libexec/zoneminder/cgi-bin")
elseif(ZM_TARGET_DISTRO STREQUAL "OS13") elseif(ZM_TARGET_DISTRO STREQUAL "OS13")
@ -212,10 +200,11 @@ elseif(ZM_TARGET_DISTRO STREQUAL "FreeBSD")
set(ZM_WEB_USER "www") set(ZM_WEB_USER "www")
set(ZM_WEB_GROUP "www") set(ZM_WEB_GROUP "www")
set(ZM_CONFIG_DIR "/usr/local/etc/zm") 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_WEBDIR "/usr/local/share/zoneminder/www")
set(ZM_CGIDIR "/usr/local/libexec/zoneminder/cgi-bin") set(ZM_CGIDIR "/usr/local/libexec/zoneminder/cgi-bin")
set(ZM_PERL_MM_PARMS "INSTALLDIRS=site") 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 # Required for certain checks to work
set(CMAKE_EXTRA_INCLUDE_FILES set(CMAKE_EXTRA_INCLUDE_FILES
@ -791,6 +780,11 @@ else(ZM_PERL_SEARCH_PATH)
set(EXTRA_PERL_LIB "# Include from system perl paths only") set(EXTRA_PERL_LIB "# Include from system perl paths only")
endif(ZM_PERL_SEARCH_PATH) 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 # Generate files from the .in files
configure_file(zm.conf.in "${CMAKE_CURRENT_BINARY_DIR}/zm.conf" @ONLY) configure_file(zm.conf.in "${CMAKE_CURRENT_BINARY_DIR}/zm.conf" @ONLY)
configure_file(zoneminder-config.cmake "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) configure_file(zoneminder-config.cmake "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
@ -814,13 +808,11 @@ if(ZM_ONVIF)
endif(ZM_ONVIF) endif(ZM_ONVIF)
# Process distro subdirectories # Process distro subdirectories
if((ZM_TARGET_DISTRO STREQUAL "fc24") OR (ZM_TARGET_DISTRO STREQUAL "fc25")) if((ZM_TARGET_DISTRO MATCHES "^el") OR (ZM_TARGET_DISTRO MATCHES "^fc"))
add_subdirectory(distros/redhat)
elseif((ZM_TARGET_DISTRO STREQUAL "el6") OR (ZM_TARGET_DISTRO STREQUAL "el7"))
add_subdirectory(distros/redhat) add_subdirectory(distros/redhat)
elseif(ZM_TARGET_DISTRO STREQUAL "OS13") elseif(ZM_TARGET_DISTRO STREQUAL "OS13")
add_subdirectory(distros/opensuse) 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 # Print optional libraries detection status
message(STATUS "Optional libraries found:${optlibsfound}") message(STATUS "Optional libraries found:${optlibsfound}")
@ -837,8 +829,9 @@ else(zmconfgen_result EQUAL 0)
"ZoneMinder configuration generator failed. Exit code: ${zmconfgen_result}") "ZoneMinder configuration generator failed. Exit code: ${zmconfgen_result}")
endif(zmconfgen_result EQUAL 0) 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(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 # Uninstall target
configure_file( 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 FROM ubuntu:xenial
MAINTAINER Markos Vakondios <mvakondios@gmail.com> MAINTAINER Markos Vakondios <mvakondios@gmail.com>
# Resynchronize the package index files # Resynchronize the package index files
RUN apt-get update && \ RUN apt-get update \
DEBIAN_FRONTEND=noninteractive apt-get install -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
libpolkit-gobject-1-dev build-essential libmysqlclient-dev libssl-dev libbz2-dev libpcre3-dev \ apache2 \
libdbi-perl libarchive-zip-perl libdate-manip-perl libdevice-serialport-perl libmime-perl libpcre3 \ build-essential \
libwww-perl libdbd-mysql-perl libsys-mmap-perl yasm cmake libjpeg-turbo8-dev \ cmake \
libjpeg-turbo8 libtheora-dev libvorbis-dev libvpx-dev libx264-dev libmp4v2-dev libav-tools mysql-client \ dh-autoreconf \
apache2 php php-mysql libapache2-mod-php php-cli \ dpatch \
mysql-server libvlc-dev libvlc5 libvlccore-dev libvlccore8 vlc-data libcurl4-openssl-dev \ libapache2-mod-php \
libavformat-dev libswscale-dev libavutil-dev libavcodec-dev libavfilter-dev \ libarchive-zip-perl \
libavresample-dev libavdevice-dev libpostproc-dev libv4l-dev libtool libnetpbm10-dev \ libavcodec-dev \
libmime-lite-perl dh-autoreconf dpatch \ libavdevice-dev \
&& apt-get clean 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 # 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 # Change into the ZoneMinder directory
WORKDIR /ZoneMinder WORKDIR /ZoneMinder
@ -39,18 +91,20 @@ RUN ./zmlinkcontent.sh
# Adding the start script # Adding the start script
ADD utils/docker/start.sh /tmp/start.sh 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/ RUN chown -R www-data:www-data /usr/local/share/zoneminder/
# Adding apache virtual hosts file # Adding apache virtual hosts file
RUN cp misc/apache.conf /etc/apache2/sites-available/000-default.conf 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 http port
EXPOSE 80 EXPOSE 80
# Initial database and apache setup: VOLUME /var/lib/zoneminder/images /var/lib/zoneminder/events /var/lib/mysql /var/log/zm
RUN "/ZoneMinder/utils/docker/setup.sh"
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 ## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be 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 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 is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident. 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_CGIDIR=/usr/lib/zoneminder/cgi-bin \
-DZM_WEB_USER=www-data \ -DZM_WEB_USER=www-data \
-DZM_WEB_GROUP=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: override_dh_auto_install:
dh_auto_install --buildsystem=cmake 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 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: "/cgi-bin-zm/zms". This has been to done to avoid this bug:
https://bugzilla.redhat.com/show_bug.cgi?id=973067 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 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. in a broken system. You have been warned.
2. Due to the active state of the ZoneMinder project, we now recommend granting 4. This package uses the HTTPS protocol by default to access the web portal.
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.
Requests using HTTP will auto-redirect to HTTPS. See README.https for Requests using HTTP will auto-redirect to HTTPS. See README.https for
more information. more information.
4. This package ships with the new ZoneMinder API enabled.
New installs New installs
============ ============
@ -43,13 +46,17 @@ New installs
anything that suits your environment. anything that suits your environment.
3. If you have chosen to change the zoneminder database account credentials to 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. something other than zmuser/zmpass, you must now create a config file under
Change ZM_DB_USER and ZM_DB_PASS to the values you created in the previous /etc/zm/conf.d and set your credentials there. For example, create the file
step. /etc/zm/conf.d/zm-db-user.conf and add the following content to it:
This version of zoneminder no longer requires you to make a similar change ZM_DB_USER = {username of the sql account you want to use}
to the credentials in /usr/share/zoneminder/www/api/app/Config/database.php ZM_DB_PASS = {password of the sql account you want to use}
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 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 timezone. PHP will complain loudly if this is not set, or if it is set
@ -107,21 +114,11 @@ New installs
Upgrades Upgrades
======== ========
1. Verify /etc/zm/zm.conf. 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
If zm.conf was manually edited before running the upgrade, the installation config files, created under the conf.d folder. Do this now. See
may not overwrite it. In this case, it will create the file /etc/zm/conf.d/README for details. Once you recreate any custom config changes
/etc/zm/zm.conf.rpmnew. under the conf.d folder, they will remain in place indefinitely.
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.
2. Verify permissions of the zmuser account. 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 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. 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 "/cgi-bin-zm/zms". This has been to done match the configuration of
CentOS7/Fedora and simplify the build process. 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 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. 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. 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 Requests using HTTP will auto-redirect to HTTPS. See README.https for
more information. more information.
@ -59,9 +60,18 @@ New installs
The database account credentials, zmuser/zmpass, are arbitrary. Set them to The database account credentials, zmuser/zmpass, are arbitrary. Set them to
anything that suits your environment. anything that suits your environment.
3. If you have chosen to change the zoneminder mysql credentials to something 3. If you have chosen to change the zoneminder database account credentials to
other than zmuser/zmpass then you must now edit /etc/zm/zm.conf. Change something other than zmuser/zmpass, you must now create a config file under
ZM_DB_USER and ZM_DB_PASS to the values you created in the previous step. /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 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 timezone. PHP will complain loudly if this is not set, or if it is set
@ -110,17 +120,11 @@ New installs
Upgrades Upgrades
======== ========
1. Verify /etc/zm/zm.conf. 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
If zm.conf was manually edited before running the upgrade, the installation config files, created under the conf.d folder. Do this now. See
may not overwrite it. In this case, it will create the file /etc/zm/conf.d/README for details. Once you recreate any custom config changes
/etc/zm/zm.conf.rpmnew. under the conf.d folder, they will remain in place indefinitely.
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.
2. Verify permissions of the zmuser account. 2. Verify permissions of the zmuser account.

View File

@ -1,24 +1,27 @@
What's New 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: "/cgi-bin-zm/zms". This has been to done to avoid this bug:
https://bugzilla.redhat.com/show_bug.cgi?id=973067 https://bugzilla.redhat.com/show_bug.cgi?id=973067
IMPORTANT: You must manually verify the value of PATH_ZMS under Options. IMPORTANT: You must manually inspect the value for PATH_ZMS under Options
Make sure it is set to "/cgi-bin-zm/nph-zms". Failure to do so will result 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. in a broken system. You have been warned.
2. Due to the active state of the ZoneMinder project, we now recommend granting 4. This package uses the HTTPS protocol by default to access the web portal.
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.
Requests using HTTP will auto-redirect to HTTPS. See README.https for Requests using HTTP will auto-redirect to HTTPS. See README.https for
more information. more information.
4. This package ships with the new ZoneMinder API enabled.
New installs New installs
============ ============
@ -43,13 +46,17 @@ New installs
anything that suits your environment. anything that suits your environment.
3. If you have chosen to change the zoneminder database account credentials to 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. something other than zmuser/zmpass, you must now create a config file under
Change ZM_DB_USER and ZM_DB_PASS to the values you created in the previous /etc/zm/conf.d and set your credentials there. For example, create the file
step. /etc/zm/conf.d/zm-db-user.conf and add the following content to it:
This version of zoneminder no longer requires you to make a similar change ZM_DB_USER = {username of the sql account you want to use}
to the credentials in /usr/share/zoneminder/www/api/app/Config/database.php ZM_DB_PASS = {password of the sql account you want to use}
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 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 timezone. PHP will complain loudly if this is not set, or if it is set
@ -98,21 +105,11 @@ New installs
Upgrades Upgrades
======== ========
1. Verify /etc/zm/zm.conf. 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
If zm.conf was manually edited before running the upgrade, the installation config files, created under the conf.d folder. Do this now. See
may not overwrite it. In this case, it will create the file /etc/zm/conf.d/README for details. Once you recreate any custom config changes
/etc/zm/zm.conf.rpmnew. under the conf.d folder, they will remain in place indefinitely.
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.
2. Verify permissions of the zmuser account. 2. Verify permissions of the zmuser account.

View File

@ -280,7 +280,13 @@ rm -rf %{_docdir}/%{name}-%{version}
%files %files
%license COPYING %license COPYING
%doc AUTHORS README.md distros/redhat/readme/README.%{readme_suffix} distros/redhat/readme/README.https distros/redhat/jscalendar-doc %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) %attr(644,root,root) %{wwwconfdir}/zoneminder.conf
%config(noreplace) %{_sysconfdir}/logrotate.d/zoneminder %config(noreplace) %{_sysconfdir}/logrotate.d/zoneminder

View File

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

View File

@ -62,7 +62,9 @@ override_dh_auto_configure:
-DZM_CGIDIR=/usr/lib/cgi-bin \ -DZM_CGIDIR=/usr/lib/cgi-bin \
-DZM_WEB_USER=www-data \ -DZM_WEB_USER=www-data \
-DZM_WEB_GROUP=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: override_dh_auto_test:
# do not run tests... # do not run tests...

View File

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

View File

@ -3,7 +3,6 @@ usr/bin
usr/lib/zoneminder usr/lib/zoneminder
usr/share/polkit-1 usr/share/polkit-1
usr/share/zoneminder/db usr/share/zoneminder/db
usr/share/zoneminder/icons
usr/share/zoneminder/www usr/share/zoneminder/www
# libzoneminder-perl files: # 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_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 => "@ZM_CONFIG@"; # Path to the ZoneMinder config file
use constant ZM_CONFIG_SUBDIR => "@ZM_CONFIG_SUBDIR@"; # Path to the ZoneMinder config subfolder
use Carp; use Carp;
# Load the config from the database into the symbol table # Load the config from the database into the symbol table
BEGIN { BEGIN {
# Process name, value pairs from the main config file first
my $config_file = ZM_CONFIG; my $config_file = ZM_CONFIG;
open( my $CONFIG, "<", $config_file ) process_configfile($config_file);
or croak( "Can't open config file '$config_file': $!" );
foreach my $str ( <$CONFIG> ) { # Search for user created config files. If one or more are found then
next if ( $str =~ /^\s*$/ ); # update the Config hash with those values
next if ( $str =~ /^\s*#/ ); if ( -d ZM_CONFIG_SUBDIR ) {
my ( $name, $value ) = $str =~ /^\s*([^=\s]+)\s*=\s*(.*?)\s*$/; if ( -R ZM_CONFIG_SUBDIR ) {
if ( ! $name ) { foreach my $filename ( glob ZM_CONFIG_SUBDIR."/*.conf" ) {
print( STDERR "Warning, bad line in $config_file: $str\n" ); process_configfile($filename);
next; }
} # end if } else {
$name =~ tr/a-z/A-Z/; print( STDERR "WARNING: ZoneMinder configuration subfolder found but is not readable. Check folder permissions on ".ZM_CONFIG_SUBDIR.".\n" );
$Config{$name} = $value; }
} }
close( $CONFIG );
use DBI; use DBI;
my $socket; my $socket;
@ -126,6 +128,31 @@ BEGIN {
} }
$sth->finish(); $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 } # end BEGIN
sub loadConfigFromDB { 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. --help - Print usage information.
--user=<dbuser> - Alternate dB user with privileges to alter dB. --user=<dbuser> - Alternate dB user with privileges to alter dB.
--pass=<dbpass> - Password of alternate dB user with privileges to alter dB. --pass=<dbpass> - Password of alternate dB user with privileges to alter dB.
--version - Print version.
=cut =cut
use strict; use strict;
@ -149,8 +150,7 @@ if ($topreset) {
############### ###############
# Execute a pre-built sql select query # Execute a pre-built sql select query
sub selectQuery sub selectQuery {
{
my $dbh = shift; my $dbh = shift;
my $sql = shift; my $sql = shift;
my $monitorid = shift; my $monitorid = shift;
@ -167,8 +167,7 @@ sub selectQuery
} }
# Exectute a pre-built sql query # Exectute a pre-built sql query
sub runQuery sub runQuery {
{
my $dbh = shift; my $dbh = shift;
my $sql = shift; my $sql = shift;
my $sth = $dbh->prepare_cached( $sql ) my $sth = $dbh->prepare_cached( $sql )
@ -181,14 +180,13 @@ sub runQuery
} }
# Build and execute a sql insert query # Build and execute a sql insert query
sub insertQuery sub insertQuery {
{
my $dbh = shift; my $dbh = shift;
my $tablename = shift; my $tablename = shift;
my @data = @_; my @data = @_;
my $sql = "INSERT INTO $tablename VALUES (NULL," my $sql = "INSERT INTO $tablename VALUES (NULL,"
.(join ", ", ("?") x @data).")"; # Add "?" for each array element .(join ', ', ('?') x @data).')'; # Add "?" for each array element
my $sth = $dbh->prepare_cached( $sql ) my $sth = $dbh->prepare_cached( $sql )
or die( "Can't prepare '$sql': ".$dbh->errstr() ); or die( "Can't prepare '$sql': ".$dbh->errstr() );
@ -200,8 +198,7 @@ sub insertQuery
} }
# Build and execute a sql delete query # Build and execute a sql delete query
sub deleteQuery sub deleteQuery {
{
my $dbh = shift; my $dbh = shift;
my $sqltable = shift; my $sqltable = shift;
my $sqlname = shift; my $sqlname = shift;
@ -217,8 +214,7 @@ sub deleteQuery
} }
# Build and execute a sql select count query # Build and execute a sql select count query
sub checkExists sub checkExists {
{
my $dbh = shift; my $dbh = shift;
my $sqltable = shift; my $sqltable = shift;
my $sqlname = shift; my $sqlname = shift;
@ -241,8 +237,7 @@ sub checkExists
} }
# Import camera control & presets into the zoneminder dB # Import camera control & presets into the zoneminder dB
sub importsql sub importsql {
{
my @newcontrols; my @newcontrols;
my @overwritecontrols; my @overwritecontrols;
my @skippedcontrols; my @skippedcontrols;
@ -258,12 +253,12 @@ sub importsql
$sqlfile = $Config{ZM_PATH_DATA}.'/db/zm_create.sql'; $sqlfile = $Config{ZM_PATH_DATA}.'/db/zm_create.sql';
} }
open(my $SQLFILE,"<",$sqlfile) open(my $SQLFILE,'<',$sqlfile)
or die( "Can't Open file: $!\n" ); or die( "Can't Open file: $!\n" );
# Find and extract ptz control and monitor preset records # Find and extract ptz control and monitor preset records
while (<$SQLFILE>) { while (<$SQLFILE>) {
# Our regex replaces the primary key with NULL # Our regex replaces the primary key with NULL
if (s/^(INSERT INTO .*?Controls.*? VALUES \().*?(,')(.*?)(',.*)/$1NULL$2$3$4/i) { if (s/^(INSERT INTO .*?Controls.*? VALUES \().*?(,')(.*?)(',.*)/$1NULL$2$3$4/i) {
$controls{$3} = $_; $controls{$3} = $_;
} elsif (s/^(INSERT INTO .*?MonitorPresets.*? VALUES \().*?(,')(.*?)(',.*)/$1NULL$2$3$4/i) { } elsif (s/^(INSERT INTO .*?MonitorPresets.*? VALUES \().*?(,')(.*?)(',.*)/$1NULL$2$3$4/i) {
@ -276,115 +271,113 @@ sub importsql
die( "Error: No relevant data found in $sqlfile.\n" ); die( "Error: No relevant data found in $sqlfile.\n" );
} }
# Now that we've got what we were looking for, # Now that we've got what we were looking for,
# compare to what is already in the dB # compare to what is already in the dB
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
foreach (keys %controls) { foreach (keys %controls) {
if (!checkExists($dbh,"Controls",$_)) { if (!checkExists($dbh,'Controls',$_)) {
# No existing Control was found. Add new control to dB. # No existing Control was found. Add new control to dB.
runQuery($dbh,$controls{$_}); runQuery($dbh,$controls{$_});
push @newcontrols, $_; push @newcontrols, $_;
} elsif ($overwrite) { } elsif ($overwrite) {
# An existing Control was found and the overwrite flag is set. # An existing Control was found and the overwrite flag is set.
# Overwrite the control. # Overwrite the control.
deleteQuery($dbh,"Controls",$_); deleteQuery($dbh,'Controls',$_);
runQuery($dbh,$controls{$_}); runQuery($dbh,$controls{$_});
push @overwritecontrols, $_; push @overwritecontrols, $_;
} else { } else {
# An existing Control was found and the overwrite flag was not set. # An existing Control was found and the overwrite flag was not set.
# Do nothing. # Do nothing.
push @skippedcontrols, $_; push @skippedcontrols, $_;
} }
} }
foreach (keys %monitorpresets) { foreach (keys %monitorpresets) {
if (!checkExists($dbh,"MonitorPresets",$_)) { if (!checkExists($dbh,'MonitorPresets',$_)) {
# No existing MonitorPreset was found. Add new MonitorPreset to dB. # No existing MonitorPreset was found. Add new MonitorPreset to dB.
runQuery($dbh,$monitorpresets{$_}); runQuery($dbh,$monitorpresets{$_});
push @newpresets, $_; push @newpresets, $_;
} elsif ($overwrite) { } elsif ($overwrite) {
# An existing MonitorPreset was found and the overwrite flag is set. # An existing MonitorPreset was found and the overwrite flag is set.
# Overwrite the MonitorPreset. # Overwrite the MonitorPreset.
deleteQuery($dbh,"MonitorPresets",$_); deleteQuery($dbh,'MonitorPresets',$_);
runQuery($dbh,$monitorpresets{$_}); runQuery($dbh,$monitorpresets{$_});
push @overwritepresets, $_; push @overwritepresets, $_;
} else { } else {
# An existing MonitorPreset was found and the overwrite flag was # An existing MonitorPreset was found and the overwrite flag was
# not set. Do nothing. # not set. Do nothing.
push @skippedpresets, $_; push @skippedpresets, $_;
} }
} }
if (@newcontrols) { if (@newcontrols) {
print "Number of ptz camera controls added: " print 'Number of ptz camera controls added: '
.scalar(@newcontrols)."\n"; .scalar(@newcontrols)."\n";
} }
if (@overwritecontrols) { if (@overwritecontrols) {
print "Number of existing ptz camera controls overwritten: " print 'Number of existing ptz camera controls overwritten: '
.scalar(@overwritecontrols)."\n"; .scalar(@overwritecontrols)."\n";
} }
if (@skippedcontrols) { if (@skippedcontrols) {
print "Number of existing ptz camera controls skipped: " print 'Number of existing ptz camera controls skipped: '
.scalar(@skippedcontrols)."\n"; .scalar(@skippedcontrols)."\n";
} }
if (@newpresets) { if (@newpresets) {
print "Number of monitor presets added: " print 'Number of monitor presets added: '
.scalar(@newpresets)."\n"; .scalar(@newpresets)."\n";
} }
if (@overwritepresets) { if (@overwritepresets) {
print "Number of existing monitor presets overwritten: " print 'Number of existing monitor presets overwritten: '
.scalar(@overwritepresets)."\n"; .scalar(@overwritepresets)."\n";
} }
if (@skippedpresets) { if (@skippedpresets) {
print "Number of existing presets skipped: " print 'Number of existing presets skipped: '
.scalar(@skippedpresets)."\n"; .scalar(@skippedpresets)."\n";
} }
} }
# Export camera controls & presets from the zoneminder dB to STDOUT # Export camera controls & presets from the zoneminder dB to STDOUT
sub exportsql sub exportsql {
{
my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ ); my ( $host, $port ) = ( $Config{ZM_DB_HOST} =~ /^([^:]+)(?::(.+))?$/ );
my $command = "mysqldump -t --skip-opt --compact -h".$host; my $command = 'mysqldump -t --skip-opt --compact -h'.$host;
$command .= " -P".$port if defined($port); $command .= ' -P'.$port if defined($port);
if ( $dbUser ) { if ( $dbUser ) {
$command .= " -u".$dbUser; $command .= ' -u'.$dbUser;
if ( $dbPass ) { if ( $dbPass ) {
$command .= " -p".$dbPass; $command .= ' -p'.$dbPass;
} }
} }
if ($ARGV[0]) { if ($ARGV[0]) {
$command .= qq( --where="Name = '$ARGV[0]'"); $command .= qq( --where="Name = '$ARGV[0]'");
} }
$command .= " zm Controls MonitorPresets"; $command .= " zm Controls MonitorPresets";
my $output = qx($command); my $output = qx($command);
my $status = $? >> 8; my $status = $? >> 8;
if ( $status || logDebugging() ) { if ( $status || logDebugging() ) {
chomp( $output ); chomp( $output );
print( "Output: $output\n" ); print( "Output: $output\n" );
} }
if ( $status ) { if ( $status ) {
die( "Command '$command' exited with status: $status\n" ); die( "Command '$command' exited with status: $status\n" );
} else { } else {
# NULLify the primary keys before printing the output to STDOUT # NULLify the primary keys before printing the output to STDOUT
$output =~ s/VALUES \((.*?),'/VALUES \(NULL,'/ig; $output =~ s/VALUES \((.*?),'/VALUES \(NULL,'/ig;
print $output; print $output;
} }
} }
sub toPreset sub toPreset {
{
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
my $monitorid = $ARGV[0]; my $monitorid = $ARGV[0];
# Grap the following fields from the Monitors table # Grap the following fields from the Monitors table
my $sql = "SELECT my $sql = 'SELECT
Name, Name,
Type, Type,
Device, Device,
@ -406,15 +399,15 @@ sub toPreset
ControlAddress, ControlAddress,
DefaultRate, DefaultRate,
DefaultScale DefaultScale
FROM Monitors WHERE Id = ?"; FROM Monitors WHERE Id = ?';
my @data = selectQuery($dbh,$sql,$monitorid); my @data = selectQuery($dbh,$sql,$monitorid);
if (!@data) { if (!@data) {
die( "Error: Monitor Id $monitorid does not appear to exist in the database.\n" ); 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 # Attempt to search for and replace system specific values such as
# ip addresses, ports, usernames, etc. with generic placeholders # ip addresses, ports, usernames, etc. with generic placeholders
if (!$noregex) { if (!$noregex) {
foreach (@data) { foreach (@data) {
next if ! $_; next if ! $_;
@ -429,19 +422,21 @@ sub toPreset
} }
if (!checkExists($dbh,"MonitorPresets",$data[0])) { if (!checkExists($dbh,"MonitorPresets",$data[0])) {
# No existing Preset was found. Add new Preset to dB. # No existing Preset was found. Add new Preset to dB.
print "Adding new preset: $data[0]\n"; print "Adding new preset: $data[0]\n";
insertQuery($dbh,"MonitorPresets",@data); insertQuery($dbh,'MonitorPresets',@data);
} elsif ($overwrite) { } elsif ($overwrite) {
# An existing Control was found and the overwrite flag is set. # An existing Control was found and the overwrite flag is set.
# Overwrite the control. # Overwrite the control.
print "Existing preset $data[0] detected.\nOverwriting...\n"; print "Existing preset $data[0] detected.\nOverwriting...\n";
deleteQuery($dbh,"MonitorPresets",$data[0]); deleteQuery($dbh,'MonitorPresets',$data[0]);
insertQuery($dbh,"MonitorPresets",@data); insertQuery($dbh,'MonitorPresets',@data);
} else { } else {
# An existing Control was found and the overwrite flag was not set. # An existing Control was found and the overwrite flag was not set.
# Do nothing. # Do nothing.
print "Existing preset $data[0] detected and overwrite flag not set.\nSkipping...\n"; 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; die;
} }
# In future, should not be neccessary wrt StorageAreas
chdir( EVENT_PATH ); chdir( EVENT_PATH );
# SHould not be neccessary... but nice to get a local var. What if it fails?
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
if ( $filter_parm ) { if ( $filter_parm ) {
@ -149,7 +151,8 @@ if ( $filter_parm ) {
Info( "Scanning for events\n" ); Info( "Scanning for events\n" );
} }
if ( !$filter_parm ) { if ( ! $filter_parm ) {
Debug("Sleeping due to start delay: " . START_DELAY . ' seconds...' );
sleep( START_DELAY ); sleep( START_DELAY );
} }
@ -182,7 +185,7 @@ sub getFilters {
if ( $filter_name ) { if ( $filter_name ) {
$sql .= ' Name = ? and'; $sql .= ' Name = ? and';
} else { } else {
$sql .= ' Background = 1 and'; $sql .= ' Background = 1 AND';
} }
$sql .= '( AutoArchive = 1 $sql .= '( AutoArchive = 1
or AutoVideo = 1 or AutoVideo = 1

View File

@ -24,14 +24,80 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <dirent.h>
#include <glob.h>
#include "zm_utils.h" #include "zm_utils.h"
void zmLoadConfig() { 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; FILE *cfg;
char line[512]; char line[512];
if ( (cfg = fopen( ZM_CONFIG, "r")) == NULL ) { if ( (cfg = fopen( configFile, "r")) == NULL ) {
Fatal( "Can't open %s: %s", ZM_CONFIG, strerror(errno) ); Fatal( "Can't open %s: %s", configFile, strerror(errno) );
} }
while ( fgets( line, sizeof(line), cfg ) != NULL ) { while ( fgets( line, sizeof(line), cfg ) != NULL ) {
char *line_ptr = line; char *line_ptr = line;
@ -58,7 +124,7 @@ void zmLoadConfig() {
// Now look for the '=' in the middle of the line // Now look for the '=' in the middle of the line
temp_ptr = strchr( line_ptr, '=' ); temp_ptr = strchr( line_ptr, '=' );
if ( !temp_ptr ) { if ( !temp_ptr ) {
Warning( "Invalid data in %s: '%s'", ZM_CONFIG, line ); Warning( "Invalid data in %s: '%s'", configFile, line );
continue; continue;
} }
@ -99,38 +165,6 @@ void zmLoadConfig() {
} }
} // end foreach line of the config } // end foreach line of the config
fclose( cfg ); 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; StaticConfig staticConfig;

View File

@ -26,6 +26,7 @@
#include <string> #include <string>
#define ZM_CONFIG "@ZM_CONFIG@" // Path to config file #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_VERSION "@VERSION@" // ZoneMinder Version
#define ZM_HAS_V4L1 @ZM_HAS_V4L1@ #define ZM_HAS_V4L1 @ZM_HAS_V4L1@
@ -58,6 +59,8 @@
extern void zmLoadConfig(); extern void zmLoadConfig();
extern void process_configfile( char* configFile );
struct StaticConfig struct StaticConfig
{ {
std::string DB_HOST; 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 ) { bool EventStream::loadEventData( int event_id ) {
static char sql[ZM_SQL_MED_BUFSIZ]; 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 ) ) { if ( mysql_query( &dbconn, sql ) ) {
Error( "Can't run query: %s", mysql_error( &dbconn ) ); 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 ); 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; //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 ); Debug( 1, "Attempting to authenticate user from auth string '%s'", auth );
char sql[ZM_SQL_SML_BUFSIZ] = ""; 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 ) ) 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] ); 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 ) ) if ( !strcmp( auth, auth_md5 ) )
{ {
@ -246,5 +246,6 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
#else // HAVE_DECL_MD5 #else // HAVE_DECL_MD5
Error( "You need to build with gnutls or openssl installed to use hash based authentication" ); Error( "You need to build with gnutls or openssl installed to use hash based authentication" );
#endif // HAVE_DECL_MD5 #endif // HAVE_DECL_MD5
Debug(1, "No user found for auth_key %s", auth );
return( 0 ); return( 0 );
} }

View File

@ -379,8 +379,12 @@ bool VideoStore::setup_resampler() {
#ifdef HAVE_LIBAVRESAMPLE #ifdef HAVE_LIBAVRESAMPLE
static char error_buffer[256]; 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. // 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); 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 ); ret = avcodec_open2( audio_input_context, audio_input_codec, NULL );
if ( ret < 0 ) { if ( ret < 0 ) {
Error("Can't open input codec!"); Error("Can't open input codec!");
@ -451,11 +455,13 @@ bool VideoStore::setup_resampler() {
// Now copy them to the output stream // Now copy them to the output stream
audio_output_stream = avformat_new_stream( oc, audio_output_codec ); 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 ); ret = avcodec_parameters_from_context( audio_output_stream->codecpar, audio_output_context );
if ( ret < 0 ) { if ( ret < 0 ) {
Error( "Could not initialize stream parameteres"); Error( "Could not initialize stream parameteres");
return false; return false;
} }
#endif
AVDictionary *opts = NULL; AVDictionary *opts = NULL;
av_dict_set( &opts, "strict", "experimental", 0); av_dict_set( &opts, "strict", "experimental", 0);

View File

@ -46,7 +46,7 @@ private:
#ifdef HAVE_LIBAVRESAMPLE #ifdef HAVE_LIBAVRESAMPLE
AVAudioResampleContext* resample_context; AVAudioResampleContext* resample_context;
#endif #endif
uint8_t *converted_input_samples = NULL; uint8_t *converted_input_samples;
const char *filename; const char *filename;
const char *format; 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 ); 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; alarmed = false;
was_alarmed = false;
pixel_diff = 0; pixel_diff = 0;
alarm_pixels = 0; alarm_pixels = 0;
alarm_filter_pixels = 0; alarm_filter_pixels = 0;

View File

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

View File

@ -63,6 +63,8 @@ DATE=`date -R`
if [ "$TYPE" == "" ]; then if [ "$TYPE" == "" ]; then
echo "Defaulting to source build" echo "Defaulting to source build"
TYPE="source"; TYPE="source";
else
echo "Doing $TYPE build"
fi; fi;
if [ "$DISTRO" == "" ]; then if [ "$DISTRO" == "" ]; then
@ -81,6 +83,8 @@ if [ "$RELEASE" != "" ]; then
if [ "$GITHUB_FORK" != "" ] && [ "$GITHUB_FORK" != "ZoneMinder" ]; then if [ "$GITHUB_FORK" != "" ] && [ "$GITHUB_FORK" != "ZoneMinder" ]; then
echo "Releases cannot have a fork ($GITHUB_FORK).... exiting." echo "Releases cannot have a fork ($GITHUB_FORK).... exiting."
exit 0; exit 0;
else
GITHUB_FORK="ZoneMinder";
fi fi
BRANCH="release-$RELEASE" BRANCH="release-$RELEASE"
else else
@ -129,11 +133,7 @@ else
fi; fi;
cd "${GITHUB_FORK}_zoneminder_release" cd "${GITHUB_FORK}_zoneminder_release"
if [ $RELEASE ]; then
git checkout $RELEASE
else
git checkout $BRANCH git checkout $BRANCH
fi;
cd ../ cd ../
VERSION=`cat ${GITHUB_FORK}_zoneminder_release/version` VERSION=`cat ${GITHUB_FORK}_zoneminder_release/version`
@ -148,6 +148,11 @@ fi;
DIRECTORY="zoneminder_$VERSION"; DIRECTORY="zoneminder_$VERSION";
echo "Doing $TYPE release $DIRECTORY"; echo "Doing $TYPE release $DIRECTORY";
mv "${GITHUB_FORK}_zoneminder_release" "$DIRECTORY.orig"; 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"; cd "$DIRECTORY.orig";
git submodule init git submodule init
@ -185,6 +190,13 @@ zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
-- $AUTHOR $DATE -- $AUTHOR $DATE
EOF EOF
cat <<EOF > debian/NEWS
zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
* Release $VERSION
-- $AUTHOR $DATE
EOF
else else
cat <<EOF > debian/changelog cat <<EOF > debian/changelog
zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
@ -192,7 +204,13 @@ zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
* *
-- $AUTHOR $DATE -- $AUTHOR $DATE
EOF
cat <<EOF > debian/changelog
zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
*
-- $AUTHOR $DATE
EOF EOF
fi; fi;
@ -216,6 +234,7 @@ else
echo "Status: $?" echo "Status: $?"
DEBUILD="debuild -i -us -uc -b" DEBUILD="debuild -i -us -uc -b"
else else
# Source build, don't need build depends.
DEBUILD="debuild -S -sa" DEBUILD="debuild -S -sa"
fi; fi;
fi; fi;
@ -232,24 +251,32 @@ fi;
cd ../ cd ../
if [ "$INTERACTIVE" != "no" ]; then 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]" 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!" echo "Done!"
else 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 fi
if [ $TYPE == "binary" ]; then if [ $TYPE == "binary" ]; then
if [ "$INTERACTIVE" != "no" ]; then if [ "$INTERACTIVE" != "no" ]; then
echo "Not doing dput since it's a binary release. Do you want to install it? (Y/N)" read -p "Not doing dput since it's a binary release. Do you want to install it? (Y/N)"
read install if [[ $REPLY == [yY] ]]; then
if [ "$install" == "Y" ]; then
sudo dpkg -i $DIRECTORY*.deb sudo dpkg -i $DIRECTORY*.deb
else
echo $REPLY;
fi; fi;
if [ "$DISTRO" == "jessie" ]; then if [ "$DISTRO" == "jessie" ]; then
echo "Do you want to upload this binary to zmrepo? (y/N)" read -p "Do you want to upload this binary to zmrepo? (y/N)"
read install if [[ $REPLY == [yY] ]]; then
if [ "$install" == "Y" ]; then if [ "$RELEASE" != "" ]; then
scp "zoneminder_*-${VERSION}-${DISTRO}*" "zmrepo@zmrepo.connortechnology.com:debian/${BRANCH}/mini-dinstall/incoming/" 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; fi;
fi; fi;
@ -271,7 +298,7 @@ else
echo "Ready to dput $SC to $PPA ? Y/N..."; echo "Ready to dput $SC to $PPA ? Y/N...";
read dput read dput
fi fi
if [ "$dput" == "Y" -o "$dput" == "y" ]; then if [ "$dput" == [Yy] ]; then
dput $PPA $SC dput $PPA $SC
fi; fi;
fi; fi;

View File

@ -1,14 +1,24 @@
#!/bin/bash #!/bin/bash
# Start MySQL setup_mysql_first_time(){
# For Xenial the following won't start mysqld if [ "$(ls /var/lib/mysql)" ]; then
#/usr/bin/mysqld_safe & return
# Use this instead: fi
service mysql start
# Give MySQL time to wake up # Set MySQL in the volume
SECONDS_LEFT=120 rm -rf /var/lib/mysql/*
while true; do 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
# Give MySQL time to wake up
SECONDS_LEFT=120
while true; do
sleep 1 sleep 1
mysqladmin ping mysqladmin ping
if [ $? -eq 0 ];then if [ $? -eq 0 ];then
@ -22,25 +32,44 @@ while true; do
if [ $SECONDS_LEFT -eq 0 ];then if [ $SECONDS_LEFT -eq 0 ];then
return -1; return -1;
fi fi
done done
# Create the ZoneMinder database # Create the ZoneMinder database
mysql -u root < db/zm_create.sql mysql -u root < db/zm_create.sql
# Add the ZoneMinder DB user # 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';" mysql -u root -e "grant insert,select,update,delete,lock tables,alter on zm.* to 'zmuser'@'localhost' identified by 'zmpass';"
# Make ZM_LOGDIR # Shut down mysql cleanly:
mkdir /var/log/zm kill $(cat /var/run/mysqld/mysqld.pid)
sleep 5
}
# Activate CGI setup_mysql() {
a2enmod cgi # To configure MySQL if no container did it before
setup_mysql_first_time
# Activate modrewrite # Add configuration to avoid SQL error when adding monitor
a2enmod rewrite echo "sql_mode=NO_ENGINE_SUBSTITUTION" >> /etc/mysql/mysql.conf.d/mysqld.cnf
}
# Shut down mysql cleanly: setup_php() {
kill $(cat /var/run/mysqld/mysqld.pid) # Activate CGI
sleep 5 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 exit 0

View File

@ -35,7 +35,7 @@ done
service apache2 restart service apache2 restart
# Start ZoneMinder # Start ZoneMinder
/usr/local/bin/zmpkg.pl start /usr/local/bin/zmpkg.pl start && echo "Zone Minder started"
while : while :
do 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 echo
exit 1 exit 1
fi 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 # Check key variables before calling packpack
checkvars () { checkvars () {
if [ -z ${VERSION} ]; then
echo
echo "FATAL: VERSION variable was null. Cannot continue."
echo
exit 98
fi
if [ -z ${RELEASE} ]; then for var in $thedate $shorthash $versionfile $versionhash $numcommits; do
if [ -z ${var} ]; then
echo echo
echo "FATAL: RELEASE variable was null. Cannot Continue" 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 echo
exit 98 exit 98
fi fi
done
} }
# Steps common to all builds # Steps common to all builds
@ -131,15 +153,33 @@ installtrusty () {
fi fi
} }
# This sets the naming convention for the deb packages # This sets the naming convention for the rpm packages
setdebpkgver () { setrpmpkgname () {
# Set VERSION to x.xx.x+x e.g. 1.30.2+15 createvars
# the last x is number of commits since release
# Creates zoneminder packages in the format: zoneminder-{version}-{release} # Set VERSION to the contents of the version file e.g. 1.31.0
zmver=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\1/p') # Set RELEASE to 1.{number of commits}.{today's date}git{short hash of HEAD} e.g. 1.82.20170605gitg7ae0b4a
commitnum=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\2/p') export VERSION="$versionfile"
export VERSION="$zmver+$commitnum" export RELEASE="1.${numcommits}.${thedate}git${shorthash}"
checkvars
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}" export RELEASE="${DIST}"
checkvars 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 # This adds an entry to the debian changelog
setdebchangelog () { setdebchangelog () {
DATE=`date -R` DATE=`date -R`
@ -177,18 +227,7 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
if [ "${OS}" == "el" ] || [ "${OS}" == "fedora" ]; then if [ "${OS}" == "el" ] || [ "${OS}" == "fedora" ]; then
echo "Begin Redhat build..." echo "Begin Redhat build..."
# Set VERSION to x.xx.x e.g. 1.30.2 setrpmpkgname
# 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
ln -sfT distros/redhat rpm ln -sfT distros/redhat rpm
@ -213,14 +252,20 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
exit 1 exit 1
fi fi
setrpmchangelog
echo "Starting packpack..." 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 # Steps common to Debian based distros
elif [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ]; then elif [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ]; then
echo "Begin ${OS} ${DIST} build..." echo "Begin ${OS} ${DIST} build..."
setdebpkgver setdebpkgname
movecrud movecrud
if [ "${DIST}" == "trusty" ] || [ "${DIST}" == "precise" ]; then if [ "${DIST}" == "trusty" ] || [ "${DIST}" == "precise" ]; then
@ -234,7 +279,11 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
setdebchangelog setdebchangelog
echo "Starting packpack..." 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 if [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "trusty" ] && [ "${ARCH}" == "x86_64" ] && [ "${TRAVIS}" == "true" ]; then
installtrusty installtrusty
@ -246,7 +295,7 @@ elif [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "trusty" ] && [ "${ARCH}" == "x86
echo "Begin Ubuntu Trusty build..." echo "Begin Ubuntu Trusty build..."
commonprep commonprep
setdebpkgver setdebpkgname
movecrud movecrud
ln -sfT distros/ubuntu1204 debian ln -sfT distros/ubuntu1204 debian
@ -254,7 +303,11 @@ elif [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "trusty" ] && [ "${ARCH}" == "x86
setdebchangelog setdebchangelog
echo "Starting packpack..." 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 we are running inside Travis then attempt to install the deb we just built
if [ "${TRAVIS}" == "true" ]; then if [ "${TRAVIS}" == "true" ]; then

View File

@ -1,18 +1,19 @@
<?php <?php
if ( empty($_REQUEST['id']) && empty($_REQUEST['eids']) ) { if ( empty($_REQUEST['id']) && empty($_REQUEST['eids']) ) {
ajaxError( "No event id(s) supplied" ); ajaxError( 'No event id(s) supplied' );
} }
if ( canView( 'Events' ) ) { if ( canView( 'Events' ) ) {
switch ( $_REQUEST['action'] ) { switch ( $_REQUEST['action'] ) {
case 'video' : { case 'video' :
{
if ( empty($_REQUEST['videoFormat']) ) { if ( empty($_REQUEST['videoFormat']) ) {
ajaxError( "Video Generation Failure, no format given" ); ajaxError( 'Video Generation Failure, no format given' );
} elseif ( empty($_REQUEST['rate']) ) { } elseif ( empty($_REQUEST['rate']) ) {
ajaxError( "Video Generation Failure, no rate given" ); ajaxError( 'Video Generation Failure, no rate given' );
} elseif ( empty($_REQUEST['scale']) ) { } elseif ( empty($_REQUEST['scale']) ) {
ajaxError( "Video Generation Failure, no scale given" ); ajaxError( 'Video Generation Failure, no scale given' );
} else { } 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(); $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'] ) )) ) if ( !($event = dbFetchOne( $sql, NULL, array( $_REQUEST['id'] ) )) )
@ -33,11 +34,11 @@ if ( canView( 'Events' ) ) {
ajaxResponse(); ajaxResponse();
break; break;
} }
case "export" : case 'export' :
{ {
require_once( ZM_SKIN_PATH.'/includes/export_functions.php' ); 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. # 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(); session_start();
if ( !empty($_REQUEST['exportDetail']) ) if ( !empty($_REQUEST['exportDetail']) )
@ -71,7 +72,7 @@ if ( canView( 'Events' ) ) {
if ( $exportFile = exportEvents( $exportIds, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat ) ) if ( $exportFile = exportEvents( $exportIds, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc, $exportFormat ) )
ajaxResponse( array( 'exportFile'=>$exportFile ) ); ajaxResponse( array( 'exportFile'=>$exportFile ) );
else else
ajaxError( "Export Failed" ); ajaxError( 'Export Failed' );
break; break;
} }
} }
@ -97,7 +98,7 @@ if ( canEdit( 'Events' ) ) {
case 'archive' : case 'archive' :
case 'unarchive' : case 'unarchive' :
{ {
$archiveVal = ($_REQUEST['action'] == "archive")?1:0; $archiveVal = ($_REQUEST['action'] == 'archive')?1:0;
dbQuery( 'UPDATE Events SET Archived = ? WHERE Id = ?', array( $archiveVal, $_REQUEST['id']) ); dbQuery( 'UPDATE Events SET Archived = ? WHERE Id = ?', array( $archiveVal, $_REQUEST['id']) );
ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>false ) ); ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>false ) );
break; break;

View File

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

View File

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

View File

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

View File

@ -22,6 +22,7 @@
// This section contains options substituted by the zmconfig.pl utility, do not edit these directly // 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", "@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, and override any given in config file
define( "ZM_VERSION", "@VERSION@" ); // Version define( "ZM_VERSION", "@VERSION@" ); // Version
define( "ZM_DIR_TEMP", "@ZM_TMPDIR@" ); define( "ZM_DIR_TEMP", "@ZM_TMPDIR@" );
@ -37,18 +38,27 @@ if ( file_exists( $localConfigFile ) && filesize( $localConfigFile ) > 0 )
$configFile = $localConfigFile; $configFile = $localConfigFile;
} }
$cfg = fopen( $configFile, "r") or die("Could not open config file."); # Process name, value pairs from the main config file first
while ( !feof($cfg) ) $configvals = process_configfile($configFile);
{
$str = fgets( $cfg, 256 ); # Search for user created config files. If one or more are found then
if ( preg_match( '/^\s*$/', $str )) # update our config value array with those values
continue; $configSubFolder = ZM_CONFIG_SUBDIR;
elseif ( preg_match( '/^\s*#/', $str )) if ( is_dir($configSubFolder) ) {
continue; if ( is_readable($configSubFolder) ) {
elseif ( preg_match( '/^\s*([^=\s]+)\s*=\s*(.*?)\s*$/', $str, $matches )) foreach ( glob("$configSubFolder/*.conf") as $filename ) {
define( $matches[1], $matches[2] ); $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 // 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> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <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> <title><?php echo ZM_WEB_TITLE_PREFIX ?> - <?php echo validHtmlStr($title) ?></title>
<link rel="icon" type="image/ico" href="graphics/favicon.ico"/> <link rel="icon" type="image/ico" href="graphics/favicon.ico"/>
<link rel="shortcut icon" href="graphics/favicon.ico"/> <link rel="shortcut icon" href="graphics/favicon.ico"/>

View File

@ -33,7 +33,7 @@ $eventCounts = array(
'title' => translate('Hour'), 'title' => translate('Hour'),
'filter' => array( 'filter' => array(
'terms' => 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'), 'title' => translate('Day'),
'filter' => array( 'filter' => array(
'terms' => 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'), 'title' => translate('Week'),
'filter' => array( 'filter' => array(
'terms' => 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'), 'title' => translate('Month'),
'filter' => array( 'filter' => array(
'terms' => 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'), 'title' => translate('Archived'),
'filter' => array( 'filter' => array(
'terms' => 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"; $counts[] = 'count(if(1'.$filter['sql'].",1,NULL)) as EventCount$j";
$monitors[$i]['eventCounts'][$j]['filter'] = $filter; $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']) ); $counts = dbFetchOne( $sql, NULL, array($monitors[$i]['Id']) );
if ( $monitors[$i]['Function'] != 'None' ) { if ( $monitors[$i]['Function'] != 'None' ) {
$cycleCount++; $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="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> <div id="unarchiveEvent" class="hidden"><a href="#" onclick="unarchiveEvent()"><?php echo translate('Unarchive') ?></a></div>
<?php <?php
} // end if can edit Events
if ( $Event->DefaultVideo() ) { ?> if ( $Event->DefaultVideo() ) { ?>
<div id="downloadEventFile"><a href="<?php echo $Event->getStreamSrc()?>">Download MP4</a></div> <div id="downloadEventFile"><a href="<?php echo $Event->getStreamSrc()?>">Download MP4</a></div>
<?php <?php
} // end if Event->DefaultVideo } // 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> <div id="framesEvent"><a href="#" onclick="showEventFrames()"><?php echo translate('Frames') ?></a></div>
<?php <?php
@ -170,14 +169,14 @@ if ( $Event->DefaultVideo() ) {
<div id="imageFeed" <?php if ( $Event->DefaultVideo() ) { ?>class="hidden"<?php } ?> > <div id="imageFeed" <?php if ( $Event->DefaultVideo() ) { ?>class="hidden"<?php } ?> >
<?php <?php
if ( ZM_WEB_STREAM_METHOD == 'mpeg' && ZM_MPEG_LIVE_FORMAT ) { 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 ); outputVideoStream( "evtStream", $streamSrc, reScale( $Event->Width(), $scale ), reScale( $Event->Height(), $scale ), ZM_MPEG_LIVE_FORMAT );
} else { } 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() ) { 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 { } 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 } // end if stream method
?> ?>
@ -244,8 +243,7 @@ if ($Event->SaveJPEGs() & 3) { // frames or analysis
</div> </div>
</div> </div>
<?php <?php
} // end if SaveJPEGs() & 3 Analysis or Jpegs } // end if SaveJPEGs() & 3 Analysis or Jpegs
} // end if canView
} // end if Event exists } // end if Event exists
?> ?>
</div><!--page--> </div><!--page-->

View File

@ -628,8 +628,7 @@ function drawProgressBar() {
var cells = $('progressBar').getElements( 'div' ); var cells = $('progressBar').getElements( 'div' );
var cellWidth = parseInt( eventData.Width/$$(cells).length ); var cellWidth = parseInt( eventData.Width/$$(cells).length );
$$(cells).forEach( $$(cells).forEach(
function( cell, index ) function( cell, index ) {
{
if ( index == 0 ) if ( index == 0 )
$(cell).setStyles( { 'left': barWidth, 'width': cellWidth, 'borderLeft': 0 } ); $(cell).setStyles( { 'left': barWidth, 'width': cellWidth, 'borderLeft': 0 } );
else else
@ -662,7 +661,7 @@ function updateProgressBar() {
} // end if } // end if
} // end function } // end function
); );
$('progressBar').setStyle( 'width', barWidth ); //$('progressBar').setStyle( 'width', barWidth );
$('progressBar').removeClass( 'invisible' ); $('progressBar').removeClass( 'invisible' );
} // end if eventData && streamStatus } // end if eventData && streamStatus
} // end function updateProgressBar() } // end function updateProgressBar()

View File

@ -1,12 +1,15 @@
# ========================================================================== # ==========================================================================
# #
# ZoneMinder Base Configuration, $Date$, $Revision$ # ZoneMinder Base Configuration File
# #
# ========================================================================== # ==========================================================================
# #
# This file is generated by 'configure'. Care should be taken if manually # *** DO NOT EDIT THIS FILE ***
# editing this file as an changes may be overwritten by subsequent configuration # Changes made directly to this configuration file are no longer supported.
# or installations. # 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 # Path to installed data directory, used mostly for finding DB upgrade scripts
@ -47,9 +50,3 @@ ZM_DB_USER=@ZM_DB_USER@
# ZoneMinder database password # ZoneMinder database password
ZM_DB_PASS=@ZM_DB_PASS@ 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=