git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@3459 e3e1d417-86f3-4887-817a-d78f3d33393f

This commit is contained in:
stan 2011-06-21 09:19:10 +00:00
parent 96249db582
commit 6ff385e407
167 changed files with 16737 additions and 10502 deletions

View File

@ -18,6 +18,9 @@
*/ */
#undef HAVE_ALLOCA_H #undef HAVE_ALLOCA_H
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the declaration of `backtrace', and to 0 if you /* Define to 1 if you have the declaration of `backtrace', and to 0 if you
don't. */ don't. */
#undef HAVE_DECL_BACKTRACE #undef HAVE_DECL_BACKTRACE
@ -32,6 +35,9 @@
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT #undef HAVE_DOPRNT
/* Define to 1 if you have the <execinfo.h> header file. */
#undef HAVE_EXECINFO_H
/* Define to 1 if you have the <fcntl.h> header file. */ /* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H #undef HAVE_FCNTL_H
@ -62,9 +68,18 @@
/* Define to 1 if you have the `gettimeofday' function. */ /* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY #undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the <glob.h> header file. */
#undef HAVE_GLOB_H
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H #undef HAVE_INTTYPES_H
/* Define to 1 if you have the `ioctl' function. */
#undef HAVE_IOCTL
/* Define to 1 if you have the `ioctlsocket' function. */
#undef HAVE_IOCTLSOCKET
/* Define to 1 if you have the <jpeglib.h> header file. */ /* Define to 1 if you have the <jpeglib.h> header file. */
#undef HAVE_JPEGLIB_H #undef HAVE_JPEGLIB_H
@ -177,15 +192,24 @@
/* Define to 1 if you have the <pcre/pcre.h> header file. */ /* Define to 1 if you have the <pcre/pcre.h> header file. */
#undef HAVE_PCRE_PCRE_H #undef HAVE_PCRE_PCRE_H
/* Define to 1 if you have the <pthread.h> header file. */
#undef HAVE_PTHREAD_H
/* Define to 1 if you have the `putenv' function. */ /* Define to 1 if you have the `putenv' function. */
#undef HAVE_PUTENV #undef HAVE_PUTENV
/* Define to 1 if you have the `select' function. */ /* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT #undef HAVE_SELECT
/* Define to 1 if you have the `sigaction' function. */
#undef HAVE_SIGACTION
/* Define to 1 if the system has the type `siginfo_t'. */ /* Define to 1 if the system has the type `siginfo_t'. */
#undef HAVE_SIGINFO_T #undef HAVE_SIGINFO_T
/* Define to 1 if you have the `sleep' function. */
#undef HAVE_SLEEP
/* Define to 1 if you have the `socket' function. */ /* Define to 1 if you have the `socket' function. */
#undef HAVE_SOCKET #undef HAVE_SOCKET
@ -256,6 +280,12 @@
/* Define to 1 if `eip' is a member of `struct sigcontext'. */ /* Define to 1 if `eip' is a member of `struct sigcontext'. */
#undef HAVE_STRUCT_SIGCONTEXT_EIP #undef HAVE_STRUCT_SIGCONTEXT_EIP
/* Define to 1 if you have the `syscall' function. */
#undef HAVE_SYSCALL
/* Define to 1 if you have the <syscall.h> header file. */
#undef HAVE_SYSCALL_H
/* Define to 1 if you have the <syslog.h> header file. */ /* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H #undef HAVE_SYSLOG_H
@ -289,12 +319,18 @@
/* Define to 1 if you have the <sys/types.h> header file. */ /* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H #undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H
/* Define to 1 if the system has the type `ucontext_t'. */ /* Define to 1 if the system has the type `ucontext_t'. */
#undef HAVE_UCONTEXT_T #undef HAVE_UCONTEXT_T
/* Define to 1 if you have the <unistd.h> header file. */ /* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H #undef HAVE_UNISTD_H
/* Define to 1 if you have the `usleep' function. */
#undef HAVE_USLEEP
/* Define to 1 if you have the <values.h> header file. */ /* Define to 1 if you have the <values.h> header file. */
#undef HAVE_VALUES_H #undef HAVE_VALUES_H

85
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for zm 1.24.4. # Generated by GNU Autoconf 2.65 for zm 1.25.0.
# #
# Report bugs to <support@zoneminder.com>. # Report bugs to <support@zoneminder.com>.
# #
@ -552,8 +552,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='zm' PACKAGE_NAME='zm'
PACKAGE_TARNAME='ZoneMinder' PACKAGE_TARNAME='ZoneMinder'
PACKAGE_VERSION='1.24.4' PACKAGE_VERSION='1.25.0'
PACKAGE_STRING='zm 1.24.4' PACKAGE_STRING='zm 1.25.0'
PACKAGE_BUGREPORT='support@zoneminder.com' PACKAGE_BUGREPORT='support@zoneminder.com'
PACKAGE_URL='http://www.zoneminder.com/downloads.html' PACKAGE_URL='http://www.zoneminder.com/downloads.html'
@ -1309,7 +1309,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures zm 1.24.4 to adapt to many kinds of systems. \`configure' configures zm 1.25.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1375,7 +1375,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of zm 1.24.4:";; short | recursive ) echo "Configuration of zm 1.25.0:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1491,7 +1491,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
zm configure 1.24.4 zm configure 1.25.0
generated by GNU Autoconf 2.65 generated by GNU Autoconf 2.65
Copyright (C) 2009 Free Software Foundation, Inc. Copyright (C) 2009 Free Software Foundation, Inc.
@ -2050,7 +2050,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by zm $as_me 1.24.4, which was It was created by zm $as_me 1.25.0, which was
generated by GNU Autoconf 2.65. Invocation command line was generated by GNU Autoconf 2.65. Invocation command line was
$ $0 $@ $ $0 $@
@ -2861,7 +2861,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='ZoneMinder' PACKAGE='ZoneMinder'
VERSION='1.24.4' VERSION='1.25.0'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -6257,6 +6257,19 @@ _ACEOF
fi fi
done done
for ac_func in syscall sleep usleep ioctl ioctlsocket sigaction
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
eval as_val=\$$as_ac_var
if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
# Other programs # Other programs
# Extract the first word of "ffmpeg", so it can be a program name with args. # Extract the first word of "ffmpeg", so it can be a program name with args.
@ -7588,7 +7601,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
fi fi
for ac_header in fcntl.h limits.h memory.h netdb.h netinet/in.h stddef.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h values.h for ac_header in fcntl.h limits.h memory.h stddef.h stdlib.h string.h strings.h sys/param.h sys/time.h syslog.h unistd.h values.h
do : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@ -7602,6 +7615,56 @@ fi
done done
for ac_header in netdb.h netinet/in.h arpa/inet.h sys/ioctl.h sys/socket.h sys/un.h glob.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
eval as_val=\$$as_ac_Header
if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
done
for ac_header in execinfo.h
do :
ac_fn_cxx_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default"
if test "x$ac_cv_header_execinfo_h" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_EXECINFO_H 1
_ACEOF
fi
done
for ac_header in syscall.h
do :
ac_fn_cxx_check_header_mongrel "$LINENO" "syscall.h" "ac_cv_header_syscall_h" "$ac_includes_default"
if test "x$ac_cv_header_syscall_h" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_SYSCALL_H 1
_ACEOF
fi
done
for ac_header in pthread.h
do :
ac_fn_cxx_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
if test "x$ac_cv_header_pthread_h" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_PTHREAD_H 1
_ACEOF
fi
done
for ac_header in linux/videodev.h for ac_header in linux/videodev.h
do : do :
ac_fn_cxx_check_header_mongrel "$LINENO" "linux/videodev.h" "ac_cv_header_linux_videodev_h" "$ac_includes_default" ac_fn_cxx_check_header_mongrel "$LINENO" "linux/videodev.h" "ac_cv_header_linux_videodev_h" "$ac_includes_default"
@ -9904,7 +9967,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by zm $as_me 1.24.4, which was This file was extended by zm $as_me 1.25.0, which was
generated by GNU Autoconf 2.65. Invocation command line was generated by GNU Autoconf 2.65. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -9971,7 +10034,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
zm config.status 1.24.4 zm config.status 1.25.0
configured by $0, generated by GNU Autoconf 2.65, configured by $0, generated by GNU Autoconf 2.65,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -1,5 +1,5 @@
AC_PREREQ(2.59) AC_PREREQ(2.59)
AC_INIT(zm,1.24.4,support@zoneminder.com,ZoneMinder,http://www.zoneminder.com/downloads.html) AC_INIT(zm,1.25.0,support@zoneminder.com,ZoneMinder,http://www.zoneminder.com/downloads.html)
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR(src/zm.h) AC_CONFIG_SRCDIR(src/zm.h)
AM_CONFIG_HEADER(config.h) AM_CONFIG_HEADER(config.h)
@ -247,6 +247,7 @@ AC_FUNC_STRFTIME
AC_FUNC_STRTOD AC_FUNC_STRTOD
AC_FUNC_VPRINTF AC_FUNC_VPRINTF
AC_CHECK_FUNCS([gethostbyname gethostname gettimeofday memmove memset mkdir munmap putenv select socket sqrt strcasecmp strchr strcspn strerror strncasecmp strrchr strsignal strspn strstr strtol strtoull]) AC_CHECK_FUNCS([gethostbyname gethostname gettimeofday memmove memset mkdir munmap putenv select socket sqrt strcasecmp strchr strcspn strerror strncasecmp strrchr strsignal strspn strstr strtol strtoull])
AC_CHECK_FUNCS([syscall sleep usleep ioctl ioctlsocket sigaction])
# Other programs # Other programs
AC_CHECK_PROG(OPT_FFMPEG,ffmpeg,yes,no) AC_CHECK_PROG(OPT_FFMPEG,ffmpeg,yes,no)
@ -285,7 +286,11 @@ AC_CHECK_LIB(z,compress,,)
# Checks for header files. # Checks for header files.
AC_FUNC_ALLOCA AC_FUNC_ALLOCA
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([fcntl.h limits.h memory.h netdb.h netinet/in.h stddef.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h values.h]) AC_CHECK_HEADERS([fcntl.h limits.h memory.h stddef.h stdlib.h string.h strings.h sys/param.h sys/time.h syslog.h unistd.h values.h])
AC_CHECK_HEADERS([netdb.h netinet/in.h arpa/inet.h sys/ioctl.h sys/socket.h sys/un.h glob.h])
AC_CHECK_HEADERS(execinfo.h,,,)
AC_CHECK_HEADERS(syscall.h,,,)
AC_CHECK_HEADERS(pthread.h,,,)
AC_CHECK_HEADERS(linux/videodev.h,AC_SUBST(ZM_HAS_V4L1,1),AC_SUBST(ZM_HAS_V4L1,0),) AC_CHECK_HEADERS(linux/videodev.h,AC_SUBST(ZM_HAS_V4L1,1),AC_SUBST(ZM_HAS_V4L1,0),)
AC_CHECK_HEADERS(linux/videodev2.h,AC_SUBST(ZM_HAS_V4L2,1),AC_SUBST(ZM_HAS_V4L2,0),) AC_CHECK_HEADERS(linux/videodev2.h,AC_SUBST(ZM_HAS_V4L2,1),AC_SUBST(ZM_HAS_V4L2,0),)
if test "$ZM_HAS_V4L1" == "1" || test "$ZM_HAS_V4L2" == "1"; then if test "$ZM_HAS_V4L1" == "1" || test "$ZM_HAS_V4L2" == "1"; then

View File

@ -40,4 +40,5 @@ EXTRA_DIST = \
zm_update-1.24.0.sql \ zm_update-1.24.0.sql \
zm_update-1.24.1.sql \ zm_update-1.24.1.sql \
zm_update-1.24.2.sql \ zm_update-1.24.2.sql \
zm_update-1.24.3.sql zm_update-1.24.3.sql \
zm_update-1.24.4.sql

View File

@ -222,7 +222,8 @@ EXTRA_DIST = \
zm_update-1.24.0.sql \ zm_update-1.24.0.sql \
zm_update-1.24.1.sql \ zm_update-1.24.1.sql \
zm_update-1.24.2.sql \ zm_update-1.24.2.sql \
zm_update-1.24.3.sql zm_update-1.24.3.sql \
zm_update-1.24.4.sql
all: all-am all: all-am

View File

@ -259,6 +259,21 @@ CREATE TABLE `Groups` (
PRIMARY KEY (`Id`) PRIMARY KEY (`Id`)
) ENGINE=@ZM_MYSQL_ENGINE@; ) ENGINE=@ZM_MYSQL_ENGINE@;
--
-- Table structure for table `Logs`
--
CREATE TABLE `Logs` (
`TimeKey` decimal(16,6) NOT NULL,
`Component` varchar(32) NOT NULL,
`Pid` smallint(6) DEFAULT NULL,
`Level` tinyint(3) NOT NULL,
`Code` char(3) NOT NULL,
`Message` varchar(255) NOT NULL,
`File` varchar(255) DEFAULT NULL,
`Line` smallint(5) unsigned DEFAULT NULL,
KEY `TimeKey` (`TimeKey`)
) ENGINE=@ZM_MYSQL_ENGINE@;
-- --
-- Table structure for table `MonitorPresets` -- Table structure for table `MonitorPresets`
-- --

30
db/zm_update-1.24.4.sql Normal file
View File

@ -0,0 +1,30 @@
--
-- This updates a 1.24.4 database to the next version
--
--
-- Create Logs table
-- TODO - defaults to MyISAM as not easy to import selected engine
--
CREATE TABLE `Logs` (
`TimeKey` decimal(16,6) NOT NULL,
`Component` varchar(32) NOT NULL,
`Pid` smallint(6) DEFAULT NULL,
`Level` tinyint(3) NOT NULL,
`Code` char(3) NOT NULL,
`Message` varchar(255) NOT NULL,
`File` varchar(255) DEFAULT NULL,
`Line` smallint(5) unsigned DEFAULT NULL,
KEY `TimeKey` (`TimeKey`)
) ENGINE=MyISAM;
--
-- These are optional, but we might as well do it now
--
optimize table Frames;
optimize table Events;
optimize table Filters;
optimize table Zones;
optimize table Monitors;
optimize table Stats;

View File

@ -44,7 +44,7 @@ EXTRA_DIST = \
ZoneMinder/lib/ZoneMinder.pm \ ZoneMinder/lib/ZoneMinder.pm \
ZoneMinder/lib/ZoneMinder/Base.pm.in \ ZoneMinder/lib/ZoneMinder/Base.pm.in \
ZoneMinder/lib/ZoneMinder/Config.pm.in \ ZoneMinder/lib/ZoneMinder/Config.pm.in \
ZoneMinder/lib/ZoneMinder/Debug.pm \ ZoneMinder/lib/ZoneMinder/Logger.pm \
ZoneMinder/lib/ZoneMinder/General.pm \ ZoneMinder/lib/ZoneMinder/General.pm \
ZoneMinder/lib/ZoneMinder/Database.pm \ ZoneMinder/lib/ZoneMinder/Database.pm \
ZoneMinder/lib/ZoneMinder/Memory.pm.in \ ZoneMinder/lib/ZoneMinder/Memory.pm.in \

View File

@ -294,7 +294,7 @@ EXTRA_DIST = \
ZoneMinder/lib/ZoneMinder.pm \ ZoneMinder/lib/ZoneMinder.pm \
ZoneMinder/lib/ZoneMinder/Base.pm.in \ ZoneMinder/lib/ZoneMinder/Base.pm.in \
ZoneMinder/lib/ZoneMinder/Config.pm.in \ ZoneMinder/lib/ZoneMinder/Config.pm.in \
ZoneMinder/lib/ZoneMinder/Debug.pm \ ZoneMinder/lib/ZoneMinder/Logger.pm \
ZoneMinder/lib/ZoneMinder/General.pm \ ZoneMinder/lib/ZoneMinder/General.pm \
ZoneMinder/lib/ZoneMinder/Database.pm \ ZoneMinder/lib/ZoneMinder/Database.pm \
ZoneMinder/lib/ZoneMinder/Memory.pm.in \ ZoneMinder/lib/ZoneMinder/Memory.pm.in \

View File

@ -10,9 +10,9 @@ WriteMakefile(
'lib/ZoneMinder.pm' => '$(INST_LIBDIR)/ZoneMinder.pm', 'lib/ZoneMinder.pm' => '$(INST_LIBDIR)/ZoneMinder.pm',
'lib/ZoneMinder/Base.pm' => '$(INST_LIBDIR)/ZoneMinder/Base.pm', 'lib/ZoneMinder/Base.pm' => '$(INST_LIBDIR)/ZoneMinder/Base.pm',
'lib/ZoneMinder/Config.pm' => '$(INST_LIBDIR)/ZoneMinder/Config.pm', 'lib/ZoneMinder/Config.pm' => '$(INST_LIBDIR)/ZoneMinder/Config.pm',
'lib/ZoneMinder/Debug.pm' => '$(INST_LIBDIR)/ZoneMinder/Debug.pm',
'lib/ZoneMinder/General.pm' => '$(INST_LIBDIR)/ZoneMinder/General.pm', 'lib/ZoneMinder/General.pm' => '$(INST_LIBDIR)/ZoneMinder/General.pm',
'lib/ZoneMinder/Database.pm' => '$(INST_LIBDIR)/ZoneMinder/Database.pm', 'lib/ZoneMinder/Database.pm' => '$(INST_LIBDIR)/ZoneMinder/Database.pm',
'lib/ZoneMinder/Logger.pm' => '$(INST_LIBDIR)/ZoneMinder/Logger.pm',
'lib/ZoneMinder/Memory.pm' => '$(INST_LIBDIR)/ZoneMinder/Memory.pm', 'lib/ZoneMinder/Memory.pm' => '$(INST_LIBDIR)/ZoneMinder/Memory.pm',
'lib/ZoneMinder/Memory/Shared.pm' => '$(INST_LIBDIR)/ZoneMinder/Memory/Shared.pm', 'lib/ZoneMinder/Memory/Shared.pm' => '$(INST_LIBDIR)/ZoneMinder/Memory/Shared.pm',
'lib/ZoneMinder/Memory/Mapped.pm' => '$(INST_LIBDIR)/ZoneMinder/Memory/Mapped.pm', 'lib/ZoneMinder/Memory/Mapped.pm' => '$(INST_LIBDIR)/ZoneMinder/Memory/Mapped.pm',

View File

@ -31,12 +31,12 @@ use warnings;
require Exporter; require Exporter;
use ZoneMinder::Base qw(:all); use ZoneMinder::Base qw(:all);
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::General qw(:all); use ZoneMinder::General qw(:all);
use ZoneMinder::Database qw(:all); use ZoneMinder::Database qw(:all);
use ZoneMinder::Memory qw(:all); use ZoneMinder::Memory qw(:all);
our @ISA = qw(Exporter ZoneMinder::Base ZoneMinder::Config ZoneMinder::Debug ZoneMinder::General ZoneMinder::Database ZoneMinder::Memory); our @ISA = qw(Exporter ZoneMinder::Base ZoneMinder::Config ZoneMinder::Logger ZoneMinder::General ZoneMinder::Database ZoneMinder::Memory);
# Items to export into callers namespace by default. Note: do not export # Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead. # names by default without a very good reason. Use EXPORT_OK instead.
@ -53,7 +53,7 @@ our %EXPORT_TAGS = (
@ZoneMinder::Config::EXPORT_OK @ZoneMinder::Config::EXPORT_OK
], ],
'debug' => [ 'debug' => [
@ZoneMinder::Debug::EXPORT_OK @ZoneMinder::Logger::EXPORT_OK
], ],
'general' => [ 'general' => [
@ZoneMinder::General::EXPORT_OK @ZoneMinder::General::EXPORT_OK
@ -87,7 +87,7 @@ ZoneMinder - Container module for common ZoneMinder modules
=head1 DESCRIPTION =head1 DESCRIPTION
This module is a convenience container module that uses the This module is a convenience container module that uses the
ZoneMinder::Base, ZoneMinder::Common, ZoneMinder::Debug, ZoneMinder::Base, ZoneMinder::Common, ZoneMinder::Logger,
ZoneMinder::Database and ZoneMinder::Memory modules. It also ZoneMinder::Database and ZoneMinder::Memory modules. It also
exports by default all symbols provided by the 'all' tag of exports by default all symbols provided by the 'all' tag of
each of the modules. each of the modules.
@ -96,7 +96,7 @@ Thus 'use'ing this module is equivalent to the following
use ZoneMinder::Base qw(:all); use ZoneMinder::Base qw(:all);
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::Database qw(:all); use ZoneMinder::Database qw(:all);
use ZoneMinder::Memory qw(:all); use ZoneMinder::Memory qw(:all);
@ -109,7 +109,7 @@ modules.
=head1 SEE ALSO =head1 SEE ALSO
ZoneMinder::Base, ZoneMinder::Common, ZoneMinder::Debug, ZoneMinder::Base, ZoneMinder::Common, ZoneMinder::Logger,
ZoneMinder::Database, ZoneMinder::Memory ZoneMinder::Database, ZoneMinder::Memory
http://www.zoneminder.com http://www.zoneminder.com

View File

@ -458,13 +458,144 @@ our @options =
type => $types{string}, type => $types{string},
category => "images", category => "images",
}, },
{
name => "ZM_LOG_LEVEL_SYSLOG",
default => "0",
description => "Save logging output to the system log",
help => "ZoneMinder logging is now more more integrated between components and allows you to specify the destination for logging output and the individual levels for each. This option lets you control the level of logging output that goes to the system log. ZoneMinder binaries have always logged to the system log but now scripts and web logging is also included. To preserve the previous behaviour you should ensure this value is set to Info or Warning. This option controls the maximum level of logging that will be written, so Info includes Warnings and Errors etc. To disable entirely, set this option to None. You should use caution when setting this option to Debug as it can affect severely affect system performance. If you want debug you will also need to set a level and component below",
type => { db_type=>"integer", hint=>"None=-5|Panic=-4|Fatal=-3|Error=-2|Warning=-1|Info=0|Debug=1", pattern=>qr|^(\d+)$|, format=>q( $1 ) },
category => "logging",
},
{
name => "ZM_LOG_LEVEL_FILE",
default => "-5",
description => "Save logging output to component files",
help => "ZoneMinder logging is now more more integrated between components and allows you to specify the destination for logging output and the individual levels for each. This option lets you control the level of logging output that goes to individual log files written by specific components. This is how logging worked previously and although useful for tracking down issues in specific components it also resulted in many disparate log files. To preserve this behaviour you should ensure this value is set to Info or Warning. This option controls the maximum level of logging that will be written, so Info includes Warnings and Errors etc. To disable entirely, set this option to None. You should use caution when setting this option to Debug as it can affect severely affect system performance though file output has less impact than the other options. If you want debug you will also need to set a level and component below",
type => { db_type=>"integer", hint=>"None=-5|Panic=-4|Fatal=-3|Error=-2|Warning=-1|Info=0|Debug=1", pattern=>qr|^(\d+)$|, format=>q( $1 ) },
category => "logging",
},
{
name => "ZM_LOG_LEVEL_WEBLOG",
default => "-5",
description => "Save logging output to the weblog",
help => "ZoneMinder logging is now more more integrated between components and allows you to specify the destination for logging output and the individual levels for each. This option lets you control the level of logging output from the web interface that goes to the httpd error log. Note that only web logging from PHP and JavaScript files is included and so this option is really only useful for investigating specific issues with those components. This option controls the maximum level of logging that will be written, so Info includes Warnings and Errors etc. To disable entirely, set this option to None. You should use caution when setting this option to Debug as it can affect severely affect system performance. If you want debug you will also need to set a level and component below",
type => { db_type=>"integer", hint=>"None=-5|Panic=-4|Fatal=-3|Error=-2|Warning=-1|Info=0|Debug=1", pattern=>qr|^(\d+)$|, format=>q( $1 ) },
category => "logging",
},
{
name => "ZM_LOG_LEVEL_DATABASE",
default => "0",
description => "Save logging output to the database",
help => "ZoneMinder logging is now more more integrated between components and allows you to specify the destination for logging output and the individual levels for each. This option lets you control the level of logging output that is written to the database. This is a new option which can make viewing logging output easier and more intuitive and also makes it easier to get an overall impression of how the system is performing. If you have a large or very busy system then it is possible that use of this option may slow your system down if the table becomes very large. Ensure you use the LOG_DATABASE_LIMIT option to keep the table to a manageable size. This option controls the maximum level of logging that will be written, so Info includes Warnings and Errors etc. To disable entirely, set this option to None. You should use caution when setting this option to Debug as it can affect severely affect system performance. If you want debug you will also need to set a level and component below",
type => { db_type=>"integer", hint=>"None=-5|Panic=-4|Fatal=-3|Error=-2|Warning=-1|Info=0|Debug=1", pattern=>qr|^(\d+)$|, format=>q( $1 ) },
category => "logging",
},
{
name => "ZM_LOG_DATABASE_LIMIT",
default => "7 day",
description => "Maximum number of log entries to retain",
help => "If you are using database logging then it is possible to quickly build up a large number of entries in the Logs table. This option allows you to specify how many of these entries are kept. If you set this option to a number greater than zero then that number is used to determine the maximum number of rows, less than or equal to zero indicates no limit and is not recommended. You can also set this value to time values such as '<n> day' which will limit the log entries to those newer than that time. You can specify 'hour', 'day', 'week', 'month' and 'year', note that the values should be singular (no 's' at the end). The Logs table is pruned periodically so it is possible for more than the expected number of rows to be present briefly in the meantime.",
type => $types{string},
category => "logging",
},
{
name => "ZM_LOG_DEBUG",
default => "no",
description => "Switch debugging on",
help => "ZoneMinder components usually support debug logging available to help with diagnosing problems. Binary components have several levels of debug whereas more other components have only one. Normally this is disabled to minimise performance penalties and avoid filling logs too quickly. This option lets you switch on other options that allow you to configure additional debug information to be output. Components will pick up this instruction when they are restarted.",
type => $types{boolean},
category => "logging",
},
{
name => "ZM_LOG_DEBUG_TARGET",
default => "",
description => "What components should have extra debug enabled",
help => "There are three scopes of debug available. Leaving this option blank means that all components will use extra debug (not recommended). Setting this option to '_<component>', e.g. _zmc, will limit extra debug to that component only. Setting this option to '_<component>_<identity>', e.g. '_zmc_m1' will limit extra debug to that instance of the component only. This is ordinarily what you probably want to do. To debug scripts use their names without the .pl extension, e.g. '_zmvideo' and to debug issues with the web interface use '_web'. You can specify multiple targets by separating them with '|' characters.",
requires => [ { name => "ZM_LOG_DEBUG", value => "yes" } ],
type => $types{string},
category => "logging",
},
{
name => "ZM_LOG_DEBUG_LEVEL",
default => 1,
description => "What level of extra debug should be enabled",
help => "There are 9 levels of debug available, with higher numbers being more debug and level 0 being no debug. However not all levels are used by all components. Also if there is debug at a high level it is usually likely to be output at such a volume that it may obstruct normal operation. For this reason you should set the level carefully and cautiously until the degree of debug you wish to see is present. Scripts and the web interface only have one level so this is an on/off type option for them.",
requires => [ { name => "ZM_LOG_DEBUG", value => "yes" } ],
type => { db_type=>"integer", hint=>"1|2|3|4|5|6|7|8|9", pattern=>qr|^(\d+)$|, format=>q( $1 ) },
category => "logging",
},
{
name => "ZM_LOG_DEBUG_FILE",
default => "@ZM_TMPDIR@/zm_debug.log+",
description => "Where extra debug is output to",
help => "This option allows you to specify a different target for debug output. All components have a default log file which will norally be in /tmp or /var/log and this is where debug will be written to if this value is empty. Adding a path here will temporarily redirect debug, and other logging output, to this file. This option is a simple filename and you are debugging several components then they will all try and write to the same file with undesirable consequences. Appending a '+' to the filename will cause the file to be created with a '.<pid>' suffix containing your process id. In this way debug from each run of a component is kept separate. This is the recommended setting as it will also prevent subsequent runs from overwriting the same log. You should ensure that permissions are set up to allow writing to the file and directory specified here.",
requires => [ { name => "ZM_LOG_DEBUG", value => "yes" } ],
type => $types{string},
category => "logging",
},
{
name => "ZM_LOG_CHECK_PERIOD",
default => "900",
description => "Time period used when calculating overall system health",
help => "When ZoneMinder is logging events to the database it can retrospectively examine the number of warnings and errors that have occurred to calculate an overall state of system health. This option allows you to indicate what period of historical events are used in this calculation. This value is expressed in seconds and is ignored if LOG_LEVEL_DATABASE is set to None.",
type => $types{integer},
category => "logging",
},
{
name => "ZM_LOG_ALERT_WAR_COUNT",
default => "1",
description => "Number of warnings indicating system alert state",
help => "When ZoneMinder is logging events to the database it can retrospectively examine the number of warnings and errors that have occurred to calculate an overall state of system health. This option allows you to specify how many warnings must have occurred within the defined time period to generate an overall system alert state. A value of zero means warnings are not considered. This value is ignored if LOG_LEVEL_DATABASE is set to None.",
type => $types{integer},
category => "logging",
},
{
name => "ZM_LOG_ALERT_ERR_COUNT",
default => "1",
description => "Number of errors indicating system alert state",
help => "When ZoneMinder is logging events to the database it can retrospectively examine the number of warnings and errors that have occurred to calculate an overall state of system health. This option allows you to specify how many errors must have occurred within the defined time period to generate an overall system alert state. A value of zero means errors are not considered. This value is ignored if LOG_LEVEL_DATABASE is set to None.",
type => $types{integer},
category => "logging",
},
{
name => "ZM_LOG_ALERT_FAT_COUNT",
default => "0",
description => "Number of fatal error indicating system alert state",
help => "When ZoneMinder is logging events to the database it can retrospectively examine the number of warnings and errors that have occurred to calculate an overall state of system health. This option allows you to specify how many fatal errors (including panics) must have occurred within the defined time period to generate an overall system alert state. A value of zero means fatal errors are not considered. This value is ignored if LOG_LEVEL_DATABASE is set to None.",
type => $types{integer},
category => "logging",
},
{
name => "ZM_LOG_ALARM_WAR_COUNT",
default => "100",
description => "Number of warnings indicating system alarm state",
help => "When ZoneMinder is logging events to the database it can retrospectively examine the number of warnings and errors that have occurred to calculate an overall state of system health. This option allows you to specify how many warnings must have occurred within the defined time period to generate an overall system alarm state. A value of zero means warnings are not considered. This value is ignored if LOG_LEVEL_DATABASE is set to None.",
type => $types{integer},
category => "logging",
},
{
name => "ZM_LOG_ALARM_ERR_COUNT",
default => "10",
description => "Number of errors indicating system alarm state",
help => "When ZoneMinder is logging events to the database it can retrospectively examine the number of warnings and errors that have occurred to calculate an overall state of system health. This option allows you to specify how many errors must have occurred within the defined time period to generate an overall system alarm state. A value of zero means errors are not considered. This value is ignored if LOG_LEVEL_DATABASE is set to None.",
type => $types{integer},
category => "logging",
},
{
name => "ZM_LOG_ALARM_FAT_COUNT",
default => "1",
description => "Number of fatal error indicating system alarm state",
help => "When ZoneMinder is logging events to the database it can retrospectively examine the number of warnings and errors that have occurred to calculate an overall state of system health. This option allows you to specify how many fatal errors (including panics) must have occurred within the defined time period to generate an overall system alarm state. A value of zero means fatal errors are not considered. This value is ignored if LOG_LEVEL_DATABASE is set to None.",
type => $types{integer},
category => "logging",
},
{ {
name => "ZM_RECORD_EVENT_STATS", name => "ZM_RECORD_EVENT_STATS",
default => "yes", default => "yes",
description => "Record event statistical information, switch off if too slow", description => "Record event statistical information, switch off if too slow",
help => "This version of ZoneMinder records detailed information about events in the Stats table. This can help in profiling what the optimum settings are for Zones though this is tricky at present. However in future releases this will be done more easily and intuitively, especially with a large sample of events. The default option of 'yes' allows this information to be collected now in readiness for this but if you are concerned about performance you can switch this off in which case no Stats information will be saved.", help => "This version of ZoneMinder records detailed information about events in the Stats table. This can help in profiling what the optimum settings are for Zones though this is tricky at present. However in future releases this will be done more easily and intuitively, especially with a large sample of events. The default option of 'yes' allows this information to be collected now in readiness for this but if you are concerned about performance you can switch this off in which case no Stats information will be saved.",
type => $types{boolean}, type => $types{boolean},
category => "debug", category => "logging",
}, },
{ {
name => "ZM_RECORD_DIAG_IMAGES", name => "ZM_RECORD_DIAG_IMAGES",
@ -472,42 +603,7 @@ our @options =
description => "Record intermediate alarm diagnostic images, can be very slow", description => "Record intermediate alarm diagnostic images, can be very slow",
help => "In addition to recording event statistics you can also record the intermediate diagnostic images that display the results of the various checks and processing that occur when trying to determine if an alarm event has taken place. There are several of these images generated for each frame and zone for each alarm or alert frame so this can have a massive impact on performance. Only switch this setting on for debug or analysis purposes and remember to switch it off again once no longer required.", help => "In addition to recording event statistics you can also record the intermediate diagnostic images that display the results of the various checks and processing that occur when trying to determine if an alarm event has taken place. There are several of these images generated for each frame and zone for each alarm or alert frame so this can have a massive impact on performance. Only switch this setting on for debug or analysis purposes and remember to switch it off again once no longer required.",
type => $types{boolean}, type => $types{boolean},
category => "debug", category => "logging",
},
{
name => "ZM_EXTRA_DEBUG",
default => "no",
description => "Switch additional debugging on",
help => "ZoneMinder binary components usually have several levels of debug information they can output. Normally this is set to a fairly low level to avoid filling logs too quickly. This options lets you switch on other options that allow you to configure additional debug information to be output. Components will pick up this instruction when they are restarted.",
type => $types{boolean},
category => "debug",
},
{
name => "ZM_EXTRA_DEBUG_TARGET",
default => "",
description => "What components should have extra debug enabled",
help => "There are three scopes of debug available. Leaving this option blank means that all components will use extra debug (not recommended). Setting this option to '_<component>', e.g. _zmc, will limit extra debug to that component only. Setting this option to '_<component>_<identity>', e.g. '_zmc_m1' will limit extra debug to that instance of the component only. This is ordinarily what you probably want to do.",
requires => [ { name => "ZM_EXTRA_DEBUG", value => "yes" } ],
type => $types{string},
category => "debug",
},
{
name => "ZM_EXTRA_DEBUG_LEVEL",
default => 0,
description => "What level of extra debug should be enabled",
help => "There are 9 levels of debug available, with higher numbers being more debug and level 0 being no debug. However not all levels are used by all components. Also if there is debug at a high level it is usually likely to be output at such a volume that it may obstruct normal operation. For this reason you should set the level carefully and cautiously until the degree of debug you wish to see is present.",
requires => [ { name => "ZM_EXTRA_DEBUG", value => "yes" } ],
type => { db_type=>"integer", hint=>"0|1|2|3|4|5|6|7|8|9", pattern=>qr|^(\d+)$|, format=>q( $1 ) },
category => "debug",
},
{
name => "ZM_EXTRA_DEBUG_LOG",
default => "@ZM_TMPDIR@/zm_debug.log+",
description => "Where extra debug is output to",
help => "Depending on your system configuration you may find that only errors, warning and informational messages are logged to your system log. This option allows you to specify an additional target for these messages and debug. This also has the advantage of partitioning debug for the component you are tracing, from messages from other components. Be warned however that if this is a simple filename and you are debugging several components then they will all try and write to the same file with undesirable consequences. Appending a '+' to the filename will cause the file to be created with a '.<pid>' suffix containing your process id. In this way debug from each run of a component is kept separate. This is the recommended setting as it will also prevent subsequent runs from overwriting the same log.",
requires => [ { name => "ZM_EXTRA_DEBUG", value => "yes" } ],
type => $types{string},
category => "debug",
}, },
{ {
name => "ZM_DUMP_CORES", name => "ZM_DUMP_CORES",
@ -515,7 +611,7 @@ our @options =
description => "Create core files on unexpected process failure.", description => "Create core files on unexpected process failure.",
help => "When an unrecoverable error occurs in a ZoneMinder binary process is has traditionally been trapped and the details written to logs to aid in remote analysis. However in some cases it is easier to diagnose the error if a core file, which is a memory dump of the process at the time of the error, is created. This can be interactively analysed in the debugger and may reveal more or better information than that available from the logs. This option is recommended for advanced users only otherwise leave at the default. Note using this option to trigger core files will mean that there will be no indication in the binary logs that a process has died, they will just stop, however the zmdc log will still contain an entry. Also note that you may have to explicitly enable core file creation on your system via the 'ulimit -c' command or other means otherwise no file will be created regardless of the value of this option.", help => "When an unrecoverable error occurs in a ZoneMinder binary process is has traditionally been trapped and the details written to logs to aid in remote analysis. However in some cases it is easier to diagnose the error if a core file, which is a memory dump of the process at the time of the error, is created. This can be interactively analysed in the debugger and may reveal more or better information than that available from the logs. This option is recommended for advanced users only otherwise leave at the default. Note using this option to trigger core files will mean that there will be no indication in the binary logs that a process has died, they will just stop, however the zmdc log will still contain an entry. Also note that you may have to explicitly enable core file creation on your system via the 'ulimit -c' command or other means otherwise no file will be created regardless of the value of this option.",
type => $types{boolean}, type => $types{boolean},
category => "debug", category => "logging",
}, },
{ {
name => "ZM_PATH_MAP", name => "ZM_PATH_MAP",

View File

@ -38,7 +38,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::Database qw(:all); use ZoneMinder::Database qw(:all);
our $AUTOLOAD; our $AUTOLOAD;

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep ); use Time::HiRes qw( usleep );

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep ); use Time::HiRes qw( usleep );

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep ); use Time::HiRes qw( usleep );

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use Time::HiRes qw( usleep ); use Time::HiRes qw( usleep );
@ -102,7 +102,7 @@ sub close
sub printMsg sub printMsg
{ {
if ( zmDbgLevel() > 0 ) if ( logDebugging() )
{ {
my $self = shift; my $self = shift;
my $msg = shift; my $msg = shift;

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use Time::HiRes qw( usleep ); use Time::HiRes qw( usleep );
@ -103,7 +103,7 @@ sub close
sub printMsg sub printMsg
{ {
if ( zmDbgLevel() > 0 ) if ( logDebugging() )
{ {
my $self = shift; my $self = shift;
my $msg = shift; my $msg = shift;

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use Time::HiRes qw( usleep ); use Time::HiRes qw( usleep );
@ -103,7 +103,7 @@ sub close
sub printMsg sub printMsg
{ {
if ( zmDbgLevel() > 0 ) if ( logDebugging() )
{ {
my $self = shift; my $self = shift;
my $msg = shift; my $msg = shift;

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep ); use Time::HiRes qw( usleep );

View File

@ -63,7 +63,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use Carp; use Carp;
@ -89,6 +89,7 @@ sub zmDbConnect( ;$ )
{ {
$dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS );
} }
$dbh->trace( 0 );
} }
return( $dbh ); return( $dbh );
} }

View File

@ -1,474 +0,0 @@
# ==========================================================================
#
# ZoneMinder Debug Module, $Date$, $Revision$
# Copyright (C) 2001-2008 Philip Coombes
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the debug definitions and functions used by the rest
# of the ZoneMinder scripts
#
package ZoneMinder::Debug;
use 5.006;
use strict;
use warnings;
require Exporter;
require ZoneMinder::Base;
our @ISA = qw(Exporter ZoneMinder::Base);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
# This allows declaration use ZoneMinder ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = (
'constants' => [ qw(
DBG_DEBUG
DBG_INFO
DBG_WARNING
DBG_ERROR
DBG_FATAL
DBG_NOSYSLOG
) ],
'functions' => [ qw(
zmDbgInit
zmDbgTerm
zmDbgReinit
zmDbgSetSignal
zmDbgClearSignal
zmDbgId
zmDbgLevel
zmDbgCarp
zmDbgDebugOn
Debug
Info
Warning
Error
Fatal
Panic
) ]
);
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
our $VERSION = $ZoneMinder::Base::VERSION;
# ==========================================================================
#
# Debug Facilities
#
# ==========================================================================
use ZoneMinder::Config qw(:all);
use Carp;
use POSIX;
use IO::Handle;
use Time::HiRes qw/gettimeofday/;
use Sys::Syslog qw(:DEFAULT setlogsock);
use constant DBG_DEBUG => 1;
use constant DBG_INFO => 0;
use constant DBG_WARNING => -1;
use constant DBG_ERROR => -2;
use constant DBG_FATAL => -3;
use constant DBG_NOSYSLOG => -4;
our $dbg_initialised = undef;
our $dbg_id = "zmundef";
our $dbg_level = DBG_INFO;
our $dbg_carp = 0;
our $dbg_to_log = 1;
our $dbg_to_term = 0;
our $dbg_to_syslog = DBG_INFO;
our $dbg_log_file = "";
our $_dbg_has_term = 0;
our %dbg_codes = (
1 => "DBG",
0 => "INF",
-1 => "WAR",
-2 => "ERR",
-3 => "FAT",
);
our %dbg_priorities = (
1 => "debug",
0 => "info",
-1 => "warning",
-2 => "err",
-3 => "err",
);
sub zmDbgInit
{
my $id = shift;
my %options = @_;
if ( $dbg_initialised )
{
_dbgCloseLog();
_dbgCloseSyslog();
}
$dbg_id = $id if ( $id );
$dbg_level = $options{level} if ( defined($options{level}) );
$dbg_level = $options{carp} if ( defined($options{carp}) );
$dbg_to_log = $options{to_log} if ( defined($options{to_log}) );
$dbg_to_term = $options{to_term} if ( defined($options{to_term}) );
$dbg_to_syslog = $options{to_syslog} if ( defined($options{to_syslog}) );
_dbgOpenSyslog();
_dbgOpenLog();
$_dbg_has_term = -t STDERR;
$dbg_initialised = !undef;
}
sub zmDbgTerm
{
if ( $dbg_initialised )
{
_dbgCloseLog();
_dbgCloseSyslog();
}
$dbg_initialised = undef;
}
sub zmDbgReinit
{
my $saved_errno = $!;
if ( $dbg_initialised )
{
_dbgCloseLog();
#_dbgCloseSyslog();
#_dbgOpenSyslog();
_dbgOpenLog();
}
zmDbgSetSignal();
$! = $saved_errno;
}
sub zmDbgSetSignal
{
$SIG{HUP} = \&zmDbgReinit;
}
sub zmDbgClearSignal
{
$SIG{HUP} = 'DEFAULT';
}
sub zmDbgId
{
$dbg_id = $_[0] if ( @_ );
return( $dbg_id );
}
sub zmDbgLevel
{
$dbg_level = $_[0] if ( @_ );
return( $dbg_level );
}
sub zmDbgCarp
{
$dbg_carp = $_[0] if ( @_ );
return( $dbg_carp );
}
sub zmDbgToTerm
{
$dbg_to_term = $_[0] if ( @_ );
return( $dbg_to_term );
}
sub zmDbgToLog
{
if ( @_ )
{
if ( $dbg_to_log != $_[0] )
{
_dbgCloseLog();
$dbg_to_log = $_[0];
_dbgOpenLog();
}
}
return( $dbg_to_log );
}
sub zmDbgToSyslog
{
if ( @_ )
{
if ( $dbg_to_syslog != $_[0] )
{
_dbgCloseSyslog();
$dbg_to_syslog = $_[0];
_dbgOpenSyslog();
}
}
return( $dbg_to_syslog );
}
sub zmDbgDebugOk
{
return ( $dbg_level >= DBG_DEBUG );
}
sub _dbgOpenSyslog
{
if ( $dbg_to_syslog > DBG_NOSYSLOG )
{
#setlogsock( "stream", "/tmp/xxx.log" );
openlog( $dbg_id, "pid,ndelay", "local1" )
}
}
sub _dbgCloseSyslog
{
if ( $dbg_to_syslog > DBG_NOSYSLOG )
{
closelog();
}
}
sub _dbgOpenLog
{
if ( $dbg_to_log )
{
$dbg_log_file = ZM_PATH_LOGS."/".$dbg_id.".log";
if ( open( LOG, ">>".$dbg_log_file ) )
{
LOG->autoflush();
my $web_uid = (getpwnam( ZM_WEB_USER ))[2];
my $web_gid = (getgrnam( ZM_WEB_GROUP ))[2];
if ( $> == 0 )
{
chown( $web_uid, $web_gid, $dbg_log_file ) or croak( "Can't change permissions on log file: $!" )
}
}
else
{
warn( "Can't open log file '$dbg_log_file': $!" );
$dbg_to_log = 0;
}
}
}
sub _dbgCloseLog
{
if ( $dbg_to_log )
{
close( LOG );
}
}
sub _dbgPrint
{
my $level = shift;
my $string = shift;
my $carp = shift;
if ( $level <= $dbg_level )
{
if ( !$dbg_initialised )
{
zmDbgInit( $dbg_id );
}
$string =~ s/[\r\n]+$//g;
my $code = $dbg_codes{$level};
my ($seconds, $microseconds) = gettimeofday();
my $message = sprintf( "%s.%06d %s[%d].%s [%s]", strftime( "%x %H:%M:%S", localtime( $seconds ) ), $microseconds, $dbg_id, $$, $code, $string );
if ( $dbg_carp || $carp )
{
$message = Carp::shortmess( $message );
}
else
{
$message = $message."\n";
}
print( STDERR $message ) if ( $dbg_to_term == 1 || ($dbg_to_term == 2 && $_dbg_has_term) );
print( LOG $message ) if ( $dbg_to_log );
syslog( $dbg_priorities{$level}, $code." [%s]", $string ) if ( $level <= $dbg_to_syslog );
}
}
sub Debug
{
_dbgPrint( DBG_DEBUG, @_ );
}
sub Info
{
_dbgPrint( DBG_INFO, @_ );
}
sub Warning
{
_dbgPrint( DBG_WARNING, @_ );
}
sub Error
{
_dbgPrint( DBG_ERROR, @_ );
}
sub Fatal
{
_dbgPrint( DBG_FATAL, @_ );
confess( $_[0] );
}
sub Panic
{
Fatal( @_ );
}
1;
__END__
=head1 NAME
ZoneMinder::Debug - ZoneMinder Debug module
=head1 SYNOPSIS
use ZoneMinder::Debug;
use ZoneMinder::Debug qw(:all);
zmDbgInit( "myproc", DBG_DEBUG );
Debug( "This is what is happening" );
Info( "Something interesting is happening" );
Warning( "Something might be going wrong." );
Error( "Something has gone wrong!!" );
Fatal( "Something has gone badly wrong, gotta stop!!" );
=head1 DESCRIPTION
The ZoneMinder:Debug module contains the common debug and error reporting routines used by the ZoneMinder scripts.
To use debug in your scripts you need to include this module, and call zmDbgInit. Thereafter you can sprinkle Debug or Error calls etc throughout the code safe in the knowledge that they will be reported to your error log, and possibly the syslogger, in a meaningful and consistent format.
Debug is discussed in terms of levels where 1 and above (currently only 1 for scripts) is considered debug, 0 is considered as informational, -1 is a warning, -2 is an error and -3 is a fatal error or panic. Where levels are mentioned below as thresholds the value given and anything with a lower level (ie. more serious) will be included.
=head1 METHODS
=over 4
=item zmDbgInit ( $id, %options );
Initialises the debug and prepares the logging for forthcoming operations. If not called explicitly it will be called by the first debug call in your script, but with default (and probably meaningless) options. The only compulsory arguments are $id which must be a string that will identify debug coming from this script in mixed logs. Other options may be provided as below,
Option Default Description
--------- --------- -----------
level DBG_INFO The initial debug level which defines which statements are output and which are ignored
carp 0 Whether to use the Carp::shortmess format in debug statements to identify where the debug was emitted from
to_log 1 Whether to write debug to a log file of the format of <id>.log in the standard log directory
to_term 0 Whether to write debug to terminal standard error, 0 is no, 1 is yes, 2 is write only if terminal
to_syslog DBG_INFO At what level debug is written to syslog. To disable entirely set this to DBG_NOSYSLOG
=item zmDbgTerm ();
Used to end the debug session and close any logs etc. Not usually necessary.
=item $id = zmDbgId ( [$id] );
=item $level = zmDbgLevel ( [$level] );
=item $carp = zmDbgId ( [$carp] );
=item $to_log = zmDbgToLog ( [$to_log] );
=item $to_term = zmDbgToTerm ( [$to_term] );
=item $to_syslog = zmDbgToSyslog ( [$to_syslog] );
These methods can be used to get and set the current settings as defined in zmDbgInit.
=item Debug( $string );
This method will output a debug message if the current debug level permits it, otherwise does nothing. This message will be tagged with the DBG string in the logs.
=item Info( $string );
This method will output an informational message if the current debug level permits it, otherwise does nothing. This message will be tagged with the INF string in the logs.
=item Warning( $string );
This method will output a warning message if the current debug level permits it, otherwise does nothing. This message will be tagged with the WAR string in the logs.
=item Error( $string );
This method will output an error message if the current debug level permits it, otherwise does nothing. This message will be tagged with the ERR string in the logs.
=item Fatal( $string );
This method will output a fatal error message and then die if the current debug level permits it, otherwise does nothing. This message will be tagged with the FAT string in the logs.
=item Panic( $string );
Synonym for Fatal.
=head2 EXPORT
None by default.
The :constants tag will export the debug constants which define the various levels of debug
The :variables tag will export variables containing the current debug id and level
The :functions tag will export the debug functions. This or :all is what you would normally use.
The :all tag will export all above symbols.
=head1 SEE ALSO
Carp
Sys::Syslog
The ZoneMinder README file Troubleshooting section for an extended discussion on the use and configuration of syslog with ZoneMinder.
http://www.zoneminder.com
=head1 AUTHOR
Philip Coombes, E<lt>philip.coombes@zoneminder.comE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2001-2008 Philip Coombes
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.3 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@ -67,7 +67,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use POSIX; use POSIX;
@ -77,7 +77,7 @@ sub executeShellCommand( $ )
my $command = shift; my $command = shift;
my $output = qx( $command ); my $output = qx( $command );
my $status = $? >> 8; my $status = $? >> 8;
if ( $status || zmDbgLevel() > 0 ) if ( $status || logDebugging() )
{ {
Debug( "Command: $command\n" ); Debug( "Command: $command\n" );
chomp( $output ); chomp( $output );
@ -177,7 +177,7 @@ sub runCommand( $ )
my $output = qx($command); my $output = qx($command);
my $status = $? >> 8; my $status = $? >> 8;
chomp( $output ); chomp( $output );
if ( $status || zmDbgLevel() > 0 ) if ( $status || logDebugging() )
{ {
if ( $status ) if ( $status )
{ {

View File

@ -0,0 +1,852 @@
# ==========================================================================
#
# ZoneMinder Logger Module, $Date$, $Revision$
# Copyright (C) 2001-2008 Philip Coombes
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the debug definitions and functions used by the rest
# of the ZoneMinder scripts
#
package ZoneMinder::Logger;
use 5.006;
use strict;
use warnings;
require Exporter;
require ZoneMinder::Base;
our @ISA = qw(Exporter ZoneMinder::Base);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
# This allows declaration use ZoneMinder ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = (
'constants' => [ qw(
DEBUG
INFO
WARNING
ERROR
FATAL
PANIC
NOLOG
) ],
'functions' => [ qw(
logInit
logReinit
logTerm
logSetSignal
logClearSignal
logDebugging
logLevel
logTermLevel
logDatabaseLevel
logFileLevel
logSyslogLevel
Mark
Dump
Debug
Info
Warning
Error
Fatal
Panic
) ]
);
push( @{$EXPORT_TAGS{all}}, @{$EXPORT_TAGS{$_}} ) foreach keys %EXPORT_TAGS;
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw();
our $VERSION = $ZoneMinder::Base::VERSION;
# ==========================================================================
#
# Logger Facilities
#
# ==========================================================================
use ZoneMinder::Config qw(:all);
use DBI;
use Carp;
use POSIX;
use IO::Handle;
use Data::Dumper;
use Time::HiRes qw/gettimeofday/;
use Sys::Syslog;
use constant {
DEBUG => 1,
INFO => 0,
WARNING => -1,
ERROR => -2,
FATAL => -3,
PANIC => -4,
NOLOG => -5
};
our %codes = (
&DEBUG => "DBG",
&INFO => "INF",
&WARNING => "WAR",
&ERROR => "ERR",
&FATAL => "FAT",
&PANIC => "PNC",
&NOLOG => "OFF"
);
our %priorities = (
&DEBUG => "debug",
&INFO => "info",
&WARNING => "warning",
&ERROR => "err",
&FATAL => "err",
&PANIC => "err"
);
our $logger;
sub new
{
my $class = shift;
my $this = {};
$this->{initialised} = undef;
#$this->{id} = "zmundef";
( $this->{id} ) = $0 =~ m|^(?:.*/)?([^/]+?)(?:\.[^/.]+)?$|;
$this->{idRoot} = $this->{id};
$this->{idArgs} = "";
$this->{level} = INFO;
$this->{termLevel} = NOLOG;
$this->{databaseLevel} = NOLOG;
$this->{fileLevel} = NOLOG;
$this->{syslogLevel} = NOLOG;
$this->{effectiveLevel} = INFO;
$this->{autoFlush} = 1;
$this->{hasTerm} = -t STDERR;
( $this->{fileName} = $0 ) =~ s|^.*/||;
$this->{logPath} = ZM_PATH_LOGS;
$this->{logFile} = $this->{logPath}."/".$this->{id}.".log";
$this->{trace} = 0;
bless( $this, $class );
return $this;
}
sub BEGIN
{
# Fake the config variables that are used in case they are not defined yet
# Only really necessary to support upgrade from previous version
if ( !eval('defined(ZM_LOG_DEBUG)') )
{
no strict 'subs';
no strict 'refs';
my %dbgConfig = (
ZM_LOG_LEVEL_DATABASE => 0,
ZM_LOG_LEVEL_FILE => 0,
ZM_LOG_LEVEL_SYSLOG => 0,
ZM_LOG_DEBUG => 0,
ZM_LOG_DEBUG_TARGET => "",
ZM_LOG_DEBUG_LEVEL => 1,
ZM_LOG_DEBUG_FILE => ""
);
while ( my ( $name, $value ) = each( %dbgConfig ) )
{
*{$name} = sub { $value };
}
use strict 'subs';
use strict 'refs';
}
}
sub DESTROY
{
my $this = shift;
$this->terminate();
}
sub initialise( @ )
{
my $this = shift;
my %options = @_;
$this->{id} = $options{id} if ( defined($options{id}) );
$this->{logPath} = $options{logPath} if ( defined($options{logPath}) );
my $tempLogFile;
$tempLogFile = $this->{logPath}."/".$this->{id}.".log";
$tempLogFile = $options{logFile} if ( defined($options{logFile}) );
if ( my $logFile = $this->getTargettedEnv('LOG_FILE') )
{
$tempLogFile = $logFile;
}
my $tempLevel = INFO;
my $tempTermLevel = $this->{termLevel};
my $tempDatabaseLevel = $this->{databaseLevel};
my $tempFileLevel = $this->{fileLevel};
my $tempSyslogLevel = $this->{syslogLevel};
$tempTermLevel = $options{termLevel} if ( defined($options{termLevel}) );
if ( defined($options{databaseLevel}) )
{
$tempDatabaseLevel = $options{databaseLevel};
}
else
{
$tempDatabaseLevel = ZM_LOG_LEVEL_DATABASE;
}
if ( defined($options{fileLevel}) )
{
$tempFileLevel = $options{fileLevel};
}
else
{
$tempFileLevel = ZM_LOG_LEVEL_FILE;
}
if ( defined($options{syslogLevel}) )
{
$tempSyslogLevel = $options{syslogLevel};
}
else
{
$tempSyslogLevel = ZM_LOG_LEVEL_SYSLOG;
}
if ( defined($ENV{'LOG_PRINT'}) )
{
$tempTermLevel = $ENV{'LOG_PRINT'}? DEBUG : NOLOG;
}
my $level;
$tempLevel = $level if ( $level = $this->getTargettedEnv('LOG_LEVEL') );
$tempTermLevel = $level if ( $level = $this->getTargettedEnv('LOG_LEVEL_TERM') );
$tempDatabaseLevel = $level if ( $level = $this->getTargettedEnv('LOG_LEVEL_DATABASE') );
$tempFileLevel = $level if ( $level = $this->getTargettedEnv('LOG_LEVEL_FILE') );
$tempSyslogLevel = $level if ( $level = $this->getTargettedEnv('LOG_LEVEL_SYSLOG') );
if ( ZM_LOG_DEBUG )
{
foreach my $target ( split( /\|/, ZM_LOG_DEBUG_TARGET ) )
{
if ( $target eq $this->{id} || $target eq "_".$this->{id} || $target eq $this->{idRoot} || $target eq "_".$this->{idRoot} || $target eq "" )
{
if ( ZM_LOG_DEBUG_LEVEL > NOLOG )
{
$tempLevel = $this->limit( ZM_LOG_DEBUG_LEVEL );
if ( ZM_LOG_DEBUG_FILE ne "" )
{
$tempLogFile = ZM_LOG_DEBUG_FILE;
$tempFileLevel = $tempLevel;
}
}
}
}
}
$this->logFile( $tempLogFile );
$this->termLevel( $tempTermLevel );
$this->databaseLevel( $tempDatabaseLevel );
$this->fileLevel( $tempFileLevel );
$this->syslogLevel( $tempSyslogLevel );
$this->level( $tempLevel );
$this->{trace} = $options{trace} if ( defined($options{trace}) );
$this->{autoFlush} = $ENV{'LOG_FLUSH'}?1:0 if ( defined($ENV{'LOG_FLUSH'}) );
$this->{initialised} = !undef;
Debug( "LogOpts: level=".$codes{$this->{level}}."/".$codes{$this->{effectiveLevel}}.", screen=".$codes{$this->{termLevel}}.", database=".$codes{$this->{databaseLevel}}.", logfile=".$codes{$this->{fileLevel}}."->".$this->{logFile}.", syslog=".$codes{$this->{syslogLevel}} );
}
sub terminate()
{
my $this = shift;
return unless ( $this->{initialised} );
$this->syslogLevel( NOLOG );
$this->fileLevel( NOLOG );
$this->databaseLevel( NOLOG );
$this->termLevel( NOLOG );
}
sub reinitialise()
{
my $this = shift;
return unless ( $this->{initialised} );
# Bit of a nasty hack to reopen connections to log files and the DB
my $syslogLevel = $this->syslogLevel();
$this->syslogLevel( NOLOG );
my $logfileLevel = $this->fileLevel();
$this->fileLevel( NOLOG );
my $databaseLevel = $this->databaseLevel();
$this->databaseLevel( NOLOG );
my $screenLevel = $this->termLevel();
$this->termLevel( NOLOG );
$this->syslogLevel( $syslogLevel ) if ( $syslogLevel > NOLOG );
$this->fileLevel( $logfileLevel ) if ( $logfileLevel > NOLOG );
$this->databaseLevel( $databaseLevel ) if ( $databaseLevel > NOLOG );
$this->databaseLevel( $databaseLevel ) if ( $databaseLevel > NOLOG );
}
sub limit( $ )
{
my $this = shift;
my $level = shift;
return( DEBUG ) if ( $level > DEBUG );
return( NOLOG ) if ( $level < NOLOG );
return( $level );
}
sub getTargettedEnv( $ )
{
my $this = shift;
my $name = shift;
my $envName = $name."_".$this->{id};
my $value = $ENV{$envName} if ( defined($ENV{$envName}) );
if ( !defined($value) && $this->{id} ne $this->{idRoot} )
{
$envName = $name."_".$this->{idRoot};
$value = $ENV{$envName} if ( defined($ENV{$envName}) );
}
if ( !defined($value) )
{
$value = $ENV{$name} if ( defined($ENV{$name}) );
}
return( $value );
}
sub fetch()
{
if ( !$logger )
{
$logger = ZoneMinder::Logger->new();
$logger->initialise( undef, 'syslogLevel'=>INFO, 'fileLevel'=>INFO );
}
return( $logger );
}
sub id( ;$ )
{
my $this = shift;
my $id = shift;
if ( defined($id) && $this->{id} ne $id )
{
# Remove whitespace
$id =~ s/\S//g;
# Replace non-alphanum with underscore
$id =~ s/[^a-zA-Z_]/_/g;
if ( $this->{id} ne $id )
{
$this->{id} = $this->{idRoot} = $id;
if ( $id =~ /^([^_]+)_(.+)$/ )
{
$this->{idRoot} = $1;
$this->{idArgs} = $2;
}
}
}
return( $this->{id} );
}
sub level( ;$ )
{
my $this = shift;
my $level = shift;
if ( defined($level) )
{
$this->{level} = $this->limit( $level );
$this->{effectiveLevel} = NOLOG;
$this->{effectiveLevel} = $this->{termLevel} if ( $this->{termLevel} > $this->{effectiveLevel} );
$this->{effectiveLevel} = $this->{databaseLevel} if ( $this->{databaseLevel} > $this->{effectiveLevel} );
$this->{effectiveLevel} = $this->{fileLevel} if ( $this->{fileLevel} > $this->{effectiveLevel} );
$this->{effectiveLevel} = $this->{syslogLevel} if ( $this->{syslogLevel} > $this->{level} );
$this->{effectiveLevel} = $this->{level} if ( $this->{effectiveLevel} > $this->{level} );
}
return( $this->{level} );
}
sub debugOn()
{
my $this = shift;
return( $this->{effectiveLevel} >= DEBUG );
}
sub trace( ;$ )
{
my $this = shift;
$this->{trace} = $_[0] if ( @_ );
return( $this->{trace} );
}
sub termLevel( ;$ )
{
my $this = shift;
my $termLevel = shift;
if ( defined($termLevel) )
{
$termLevel = NOLOG if ( !$this->{hasTerm} );
$termLevel = $this->limit( $termLevel );
if ( $this->{termLevel} != $termLevel )
{
$this->{termLevel} = $termLevel;
}
}
return( $this->{termLevel} );
}
sub databaseLevel( ;$ )
{
my $this = shift;
my $databaseLevel = shift;
if ( defined($databaseLevel) )
{
$databaseLevel = $this->limit( $databaseLevel );
if ( $this->{databaseLevel} != $databaseLevel )
{
if ( $databaseLevel > NOLOG && $this->{databaseLevel} <= NOLOG )
{
if ( !$this->{dbh} )
{
my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ );
if ( defined($port) )
{
$this->{dbh} = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".$host.";port=".$port, ZM_DB_USER, ZM_DB_PASS );
}
else
{
$this->{dbh} = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS );
}
if ( !$this->{dbh} )
{
$databaseLevel = NOLOG;
Error( "Unable to write log entries to DB, can't connect to database '".ZM_DB_NAME."' on host '".ZM_DB_HOST."'" );
}
else
{
$this->{dbh}->trace( 0 );
}
}
}
elsif ( $databaseLevel <= NOLOG && $this->{databaseLevel} > NOLOG )
{
if ( $this->{dbh} )
{
$this->{dbh}->disconnect();
undef($this->{dbh});
}
}
$this->{databaseLevel} = $databaseLevel;
}
}
return( $this->{databaseLevel} );
}
sub fileLevel( ;$ )
{
my $this = shift;
my $fileLevel = shift;
if ( defined($fileLevel) )
{
$fileLevel = $this->limit($fileLevel);
if ( $this->{fileLevel} != $fileLevel )
{
$this->closeFile() if ( $this->{fileLevel} > NOLOG );
$this->{fileLevel} = $fileLevel;
$this->openFile() if ( $this->{fileLevel} > NOLOG );
}
}
return( $this->{fileLevel} );
}
sub syslogLevel( ;$ )
{
my $this = shift;
my $syslogLevel = shift;
if ( defined($syslogLevel) )
{
$syslogLevel = $this->limit($syslogLevel);
if ( $this->{syslogLevel} != $syslogLevel )
{
$this->closeSyslog() if ( $syslogLevel <= NOLOG && $this->{syslogLevel} > NOLOG );
$this->openSyslog() if ( $syslogLevel > NOLOG && $this->{syslogLevel} <= NOLOG );
$this->{syslogLevel} = $syslogLevel;
}
}
return( $this->{syslogLevel} );
}
sub openSyslog()
{
my $this = shift;
openlog( $this->{id}, "pid", "local1" );
}
sub closeSyslog()
{
my $this = shift;
#closelog();
}
sub logFile( $ )
{
my $this = shift;
my $logFile = shift;
if ( $logFile =~ /^(.+)\+$/ )
{
$this->{logFile} = $1.'.'.$$;
}
else
{
$this->{logFile} = $logFile;
}
}
sub openFile()
{
my $this = shift;
if ( open( LOGFILE, ">>".$this->{logFile} ) )
{
LOGFILE->autoflush() if ( $this->{autoFlush} );
my $webUid = (getpwnam( ZM_WEB_USER ))[2];
my $webGid = (getgrnam( ZM_WEB_GROUP ))[2];
if ( $> == 0 )
{
chown( $webUid, $webGid, $this->{logFile} ) or Fatal( "Can't change permissions on log file '".$this->{logFile}."': $!" )
}
}
else
{
$this->fileLevel( NOLOG );
Error( "Can't open log file '".$this->{logFile}."': $!" );
}
}
sub closeFile()
{
my $this = shift;
close( LOGFILE ) if ( fileno(LOGFILE) );
}
sub logPrint( $;$ )
{
my $this = shift;
my $level = shift;
my $string = shift;
if ( $level <= $this->{effectiveLevel} )
{
$string =~ s/[\r\n]+$//g;
my $code = $codes{$level};
my ($seconds, $microseconds) = gettimeofday();
my $message = sprintf( "%s.%06d %s[%d].%s [%s]", strftime( "%x %H:%M:%S", localtime( $seconds ) ), $microseconds, $this->{id}, $$, $code, $string );
if ( $this->{trace} )
{
$message = Carp::shortmess( $message );
}
else
{
$message = $message."\n";
}
syslog( $priorities{$level}, $code." [%s]", $string ) if ( $level <= $this->{syslogLevel} );
print( LOGFILE $message ) if ( $level <= $this->{fileLevel} );
if ( $level <= $this->{databaseLevel} )
{
my $sql = "insert into Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) values ( ?, ?, ?, ?, ?, ?, ?, NULL )";
$this->{sth} = $this->{dbh}->prepare_cached( $sql );
if ( !$this->{sth} )
{
$this->{databaseLevel} = NOLOG;
Fatal( "Can't prepare log entry '$sql': ".$this->{dbh}->errstr() );
}
my $res = $this->{sth}->execute( $seconds+($microseconds/1000000.0), $this->{id}, $$, $level, $code, $string, $this->{fileName} );
if ( !$res )
{
$this->{databaseLevel} = NOLOG;
Fatal( "Can't execute log entry '$sql': ".$this->{sth}->errstr() );
}
}
print( STDERR $message ) if ( $level <= $this->{termLevel} );
}
}
sub logInit( ;@ )
{
my %options = @_ ? @_ : ();
$logger = ZoneMinder::Logger->new() if ( !$logger );
$logger->initialise( %options );
}
sub logReinit()
{
fetch()->reinitialise();
}
sub logTerm
{
return unless ( $logger );
$logger->terminate();
$logger = undef;
}
sub logHupHandler()
{
my $savedErrno = $!;
return unless( $logger );
fetch()->reinitialise();
logSetSignal();
$! = $savedErrno;
}
sub logSetSignal()
{
$SIG{HUP} = \&logHupHandler;
}
sub logClearSignal()
{
$SIG{HUP} = 'DEFAULT';
}
sub logLevel( ;$ )
{
return( fetch()->level( @_ ) );
}
sub logDebugging()
{
return( fetch()->debugOn() );
}
sub logTermLevel( ;$ )
{
return( fetch()->termLevel( @_ ) );
}
sub logDatabaseLevel( ;$ )
{
return( fetch()->databaseLevel( @_ ) );
}
sub logFileLevel( ;$ )
{
return( fetch()->fileLevel( @_ ) );
}
sub logSyslogLevel( ;$ )
{
return( fetch()->syslogLevel( @_ ) );
}
sub Mark( ;$$ )
{
my $level = shift;
$level = DEBUG unless( defined($level) );
my $tag = "Mark";
fetch()->logPrint( $level, $tag );
}
sub Dump( \$;$ )
{
my $var = shift;
my $label = shift;
$label = "VAR" unless( defined($label) );
fetch()->logPrint( DEBUG, Data::Dumper->Dump( [ $var ], [ $label ] ) );
}
sub Debug( @ )
{
fetch()->logPrint( DEBUG, @_ );
}
sub Info( @ )
{
fetch()->logPrint( INFO, @_ );
}
sub Warning( @ )
{
fetch()->logPrint( WARNING, @_ );
}
sub Error( @ )
{
fetch()->logPrint( ERROR, @_ );
}
sub Fatal( @ )
{
fetch()->logPrint( FATAL, @_ );
exit( -1 );
}
sub Panic( @ )
{
fetch()->logPrint( PANIC, @_ );
confess( $_[0] );
}
1;
__END__
=head1 NAME
ZoneMinder::Logger - ZoneMinder Logger module
=head1 SYNOPSIS
use ZoneMinder::Logger;
use ZoneMinder::Logger qw(:all);
logInit( "myproc", DEBUG );
Debug( "This is what is happening" );
Info( "Something interesting is happening" );
Warning( "Something might be going wrong." );
Error( "Something has gone wrong!!" );
Fatal( "Something has gone badly wrong, gotta stop!!" );
Panic( "Something fundamental has gone wrong, die with stack trace );
=head1 DESCRIPTION
The ZoneMinder:Logger module contains the common debug and error reporting routines used by the ZoneMinder scripts.
To use debug in your scripts you need to include this module, and call logInit. Thereafter you can sprinkle Debug or Error calls etc throughout the code safe in the knowledge that they will be reported to your error log, and possibly the syslogger, in a meaningful and consistent format.
Debug is discussed in terms of levels where 1 and above (currently only 1 for scripts) is considered debug, 0 is considered as informational, -1 is a warning, -2 is an error and -3 is a fatal error or panic. Where levels are mentioned below as thresholds the value given and anything with a lower level (ie. more serious) will be included.
=head1 METHODS
=over 4
=item logInit ( $id, %options );
Initialises the debug and prepares the logging for forthcoming operations. If not called explicitly it will be called by the first debug call in your script, but with default (and probably meaningless) options. The only compulsory arguments are $id which must be a string that will identify debug coming from this script in mixed logs. Other options may be provided as below,
Option Default Description
--------- --------- -----------
level INFO The initial debug level which defines which statements are output and which are ignored
trace 0 Whether to use the Carp::shortmess format in debug statements to identify where the debug was emitted from
termLevel NOLOG At what level debug is written to terminal standard error, 0 is no, 1 is yes, 2 is write only if terminal
databaseLevel INFO At what level debug is written to the Log table in the database;
fileLevel NOLOG At what level debug is written to a log file of the format of <id>.log in the standard log directory.
syslogLevel INFO At what level debug is written to syslog.
To disable any of these action entirely set to NOLOG
=item logTerm ();
Used to end the debug session and close any logs etc. Not usually necessary.
=item $id = logId ( [$id] );
=item $level = logLevel ( [$level] );
=item $trace = logTrace ( [$trace] );
=item $level = logLevel ( [$level] );
=item $termLevel = logTermLevel ( [$termLevel] );
=item $databaseLevel = logDatabaseLevel ( [$databaseLevel] );
=item $fileLevel = logFileLevel ( [$fileLevel] );
=item $syslogLevel = logSyslogLevel ( [$syslogLevel] );
These methods can be used to get and set the current settings as defined in logInit.
=item Debug( $string );
This method will output a debug message if the current debug level permits it, otherwise does nothing. This message will be tagged with the DBG string in the logs.
=item Info( $string );
This method will output an informational message if the current debug level permits it, otherwise does nothing. This message will be tagged with the INF string in the logs.
=item Warning( $string );
This method will output a warning message if the current debug level permits it, otherwise does nothing. This message will be tagged with the WAR string in the logs.
=item Error( $string );
This method will output an error message if the current debug level permits it, otherwise does nothing. This message will be tagged with the ERR string in the logs.
=item Fatal( $string );
This method will output a fatal error message and then die if the current debug level permits it, otherwise does nothing. This message will be tagged with the FAT string in the logs.
=item Panic( $string );
This method will output a panic error message and then die with a stack trace if the current debug level permits it, otherwise does nothing. This message will be tagged with the PNC string in the logs.
=head2 EXPORT
None by default.
The :constants tag will export the debug constants which define the various levels of debug
The :variables tag will export variables containing the current debug id and level
The :functions tag will export the debug functions. This or :all is what you would normally use.
The :all tag will export all above symbols.
=head1 SEE ALSO
Carp
Sys::Syslog
The ZoneMinder README file Troubleshooting section for an extended discussion on the use and configuration of syslog with ZoneMinder.
http://www.zoneminder.com
=head1 AUTHOR
Philip Coombes, E<lt>philip.coombes@zoneminder.comE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2001-2008 Philip Coombes
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.3 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@ -95,7 +95,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use constant STATE_IDLE => 0; use constant STATE_IDLE => 0;
use constant STATE_PREALARM => 1; use constant STATE_PREALARM => 1;

View File

@ -64,7 +64,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use Sys::Mmap; use Sys::Mmap;

View File

@ -65,7 +65,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# ========================================================================== # ==========================================================================
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
sub zmMemKey( $ ) sub zmMemKey( $ )
{ {

View File

@ -38,7 +38,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use Carp; use Carp;

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use Carp; use Carp;
use Fcntl; use Fcntl;

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use POSIX; use POSIX;
sub new sub new

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use Carp; use Carp;
use Socket; use Socket;

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use Device::SerialPort; use Device::SerialPort;
sub new sub new

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
sub new sub new
{ {

View File

@ -41,7 +41,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use Carp; use Carp;
use Socket; use Socket;

View File

@ -38,7 +38,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use Carp; use Carp;

View File

@ -40,7 +40,7 @@ our $VERSION = $ZoneMinder::Base::VERSION;
# #
# ========================================================================== # ==========================================================================
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
sub new sub new
{ {

View File

@ -43,9 +43,6 @@ use constant MAX_AGED_DIRS => 10; # Number of event dirs to check age on
use constant RECOVER_TAG => "(r)"; # Tag to append to event name when recovered use constant RECOVER_TAG => "(r)"; # Tag to append to event name when recovered
use constant RECOVER_TEXT => "Recovered."; # Text to append to event notes when recovered use constant RECOVER_TEXT => "Recovered."; # Text to append to event notes when recovered
use constant DBG_ID => "zmaudit"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
# ========================================================================== # ==========================================================================
# #
# You shouldn't need to change anything from here downwards # You shouldn't need to change anything from here downwards
@ -75,32 +72,32 @@ my $continuous = 0;
sub usage sub usage
{ {
print( " print( "
Usage: zmaudit.pl [-r,-report|-i,-interactive] Usage: zmaudit.pl [-r,-report|-i,-interactive]
Parameters are :- Parameters are :-
-r, --report - Just report don't actually do anything -r, --report - Just report don't actually do anything
-i, --interactive - Ask before applying any changes -i, --interactive - Ask before applying any changes
-c, --continuous - Run continuously -c, --continuous - Run continuously
"); ");
exit( -1 ); exit( -1 );
} }
sub aud_print( $ ); sub aud_print( $ );
sub confirm( ;$$ ); sub confirm( ;$$ );
sub deleteSwapImage(); sub deleteSwapImage();
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
zmDbgSetSignal(); logSetSignal();
if ( !GetOptions( 'report'=>\$report, 'interactive'=>\$interactive, 'continuous'=>\$continuous ) ) if ( !GetOptions( 'report'=>\$report, 'interactive'=>\$interactive, 'continuous'=>\$continuous ) )
{ {
usage(); usage();
} }
if ( ($report + $interactive + $continuous) > 1 ) if ( ($report + $interactive + $continuous) > 1 )
{ {
print( STDERR "Error, only option may be specified\n" ); print( STDERR "Error, only option may be specified\n" );
usage(); usage();
} }
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
@ -116,40 +113,40 @@ my $loop = 1;
my $cleaned = 0; my $cleaned = 0;
MAIN: while( $loop ) MAIN: while( $loop )
{ {
my $db_monitors; my $db_monitors;
my $monitorSelectSql = "select Id from Monitors order by Id"; my $monitorSelectSql = "select Id from Monitors order by Id";
my $monitorSelectSth = $dbh->prepare_cached( $monitorSelectSql ) or Fatal( "Can't prepare '$monitorSelectSql': ".$dbh->errstr() ); my $monitorSelectSth = $dbh->prepare_cached( $monitorSelectSql ) or Fatal( "Can't prepare '$monitorSelectSql': ".$dbh->errstr() );
my $eventSelectSql = "select Id, (unix_timestamp() - unix_timestamp(StartTime)) as Age from Events where MonitorId = ? order by Id"; my $eventSelectSql = "select Id, (unix_timestamp() - unix_timestamp(StartTime)) as Age from Events where MonitorId = ? order by Id";
my $eventSelectSth = $dbh->prepare_cached( $eventSelectSql ) or Fatal( "Can't prepare '$eventSelectSql': ".$dbh->errstr() ); my $eventSelectSth = $dbh->prepare_cached( $eventSelectSql ) or Fatal( "Can't prepare '$eventSelectSql': ".$dbh->errstr() );
my $res = $monitorSelectSth->execute() or Fatal( "Can't execute: ".$monitorSelectSth->errstr() ); my $res = $monitorSelectSth->execute() or Fatal( "Can't execute: ".$monitorSelectSth->errstr() );
while( my $monitor = $monitorSelectSth->fetchrow_hashref() ) while( my $monitor = $monitorSelectSth->fetchrow_hashref() )
{ {
Debug( "Found database monitor '$monitor->{Id}'" ); Debug( "Found database monitor '$monitor->{Id}'" );
my $db_events = $db_monitors->{$monitor->{Id}} = {}; my $db_events = $db_monitors->{$monitor->{Id}} = {};
my $res = $eventSelectSth->execute( $monitor->{Id} ) or Fatal( "Can't execute: ".$eventSelectSth->errstr() ); my $res = $eventSelectSth->execute( $monitor->{Id} ) or Fatal( "Can't execute: ".$eventSelectSth->errstr() );
while ( my $event = $eventSelectSth->fetchrow_hashref() ) while ( my $event = $eventSelectSth->fetchrow_hashref() )
{ {
$db_events->{$event->{Id}} = $event->{Age}; $db_events->{$event->{Id}} = $event->{Age};
} }
Debug( "Got ".int(keys(%$db_events))." events\n" ); Debug( "Got ".int(keys(%$db_events))." events\n" );
$eventSelectSth->finish(); $eventSelectSth->finish();
} }
$monitorSelectSth->finish(); $monitorSelectSth->finish();
my $fs_monitors; my $fs_monitors;
foreach my $monitor ( <[0-9]*> ) foreach my $monitor ( <[0-9]*> )
{ {
Debug( "Found filesystem monitor '$monitor'" ); Debug( "Found filesystem monitor '$monitor'" );
my $fs_events = $fs_monitors->{$monitor} = {}; my $fs_events = $fs_monitors->{$monitor} = {};
( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ ); # De-taint ( my $monitor_dir ) = ( $monitor =~ /^(.*)$/ ); # De-taint
if ( ZM_USE_DEEP_STORAGE ) if ( ZM_USE_DEEP_STORAGE )
{ {
foreach my $day_dir ( <$monitor_dir/*/*/*> ) foreach my $day_dir ( <$monitor_dir/*/*/*> )
{ {
Debug( "Checking $day_dir" ); Debug( "Checking $day_dir" );
( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint ( $day_dir ) = ( $day_dir =~ /^(.*)$/ ); # De-taint
chdir( $day_dir ); chdir( $day_dir );
opendir( DIR, "." ) or Fatal( "Can't open directory '$day_dir': $!" ); opendir( DIR, "." ) or Fatal( "Can't open directory '$day_dir': $!" );
my @event_links = sort { $b <=> $a } grep { -l $_ } readdir( DIR ); my @event_links = sort { $b <=> $a } grep { -l $_ } readdir( DIR );
@ -169,7 +166,7 @@ MAIN: while( $loop )
$fs_events->{$event} = (time() - ($^T - ((-M $event_path) * 24*60*60))); $fs_events->{$event} = (time() - ($^T - ((-M $event_path) * 24*60*60)));
} }
} }
chdir( EVENT_PATH ); chdir( EVENT_PATH );
} }
} }
else else
@ -190,54 +187,54 @@ MAIN: while( $loop )
$fs_events->{$event} = (time() - ($^T - ((-M $event) * 24*60*60))); $fs_events->{$event} = (time() - ($^T - ((-M $event) * 24*60*60)));
} }
} }
chdir( EVENT_PATH ); chdir( EVENT_PATH );
} }
Debug( "Got ".int(keys(%$fs_events))." events\n" ); Debug( "Got ".int(keys(%$fs_events))." events\n" );
} }
$cleaned = 0; $cleaned = 0;
while ( my ( $fs_monitor, $fs_events ) = each(%$fs_monitors) ) while ( my ( $fs_monitor, $fs_events ) = each(%$fs_monitors) )
{ {
if ( my $db_events = $db_monitors->{$fs_monitor} ) if ( my $db_events = $db_monitors->{$fs_monitor} )
{ {
if ( $fs_events ) if ( $fs_events )
{ {
while ( my ( $fs_event, $age ) = each(%$fs_events ) ) while ( my ( $fs_event, $age ) = each(%$fs_events ) )
{ {
if ( !defined($db_events->{$fs_event}) && ($age < 0 || ($age > MIN_AGE)) ) if ( !defined($db_events->{$fs_event}) && ($age < 0 || ($age > MIN_AGE)) )
{ {
aud_print( "Filesystem event '$fs_monitor/$fs_event' does not exist in database" ); aud_print( "Filesystem event '$fs_monitor/$fs_event' does not exist in database" );
if ( confirm() ) if ( confirm() )
{ {
deleteEventFiles( $fs_event, $fs_monitor ); deleteEventFiles( $fs_event, $fs_monitor );
$cleaned = 1; $cleaned = 1;
} }
} }
} }
} }
} }
else else
{ {
aud_print( "Filesystem monitor '$fs_monitor' does not exist in database" ); aud_print( "Filesystem monitor '$fs_monitor' does not exist in database" );
if ( confirm() ) if ( confirm() )
{ {
my $command = "rm -rf $fs_monitor"; my $command = "rm -rf $fs_monitor";
executeShellCommand( $command ); executeShellCommand( $command );
$cleaned = 1; $cleaned = 1;
} }
} }
} }
my $monitor_links; my $monitor_links;
foreach my $link ( <*> ) foreach my $link ( <*> )
{ {
next if ( !-l $link ); next if ( !-l $link );
next if ( -e $link ); next if ( -e $link );
aud_print( "Filesystem monitor link '$link' does not point to valid monitor directory" ); aud_print( "Filesystem monitor link '$link' does not point to valid monitor directory" );
if ( confirm() ) if ( confirm() )
{ {
( $link ) = ( $link =~ /^(.*)$/ ); # De-taint ( $link ) = ( $link =~ /^(.*)$/ ); # De-taint
my $command = "rm $link"; my $command = "rm $link";
executeShellCommand( $command ); executeShellCommand( $command );
$cleaned = 1; $cleaned = 1;
@ -246,204 +243,233 @@ MAIN: while( $loop )
redo MAIN if ( $cleaned ); redo MAIN if ( $cleaned );
$cleaned = 0; $cleaned = 0;
my $deleteMonitorSql = "delete from Monitors where Id = ?"; my $deleteMonitorSql = "delete from Monitors where Id = ?";
my $deleteMonitorSth = $dbh->prepare_cached( $deleteMonitorSql ) or Fatal( "Can't prepare '$deleteMonitorSql': ".$dbh->errstr() ); my $deleteMonitorSth = $dbh->prepare_cached( $deleteMonitorSql ) or Fatal( "Can't prepare '$deleteMonitorSql': ".$dbh->errstr() );
my $deleteEventSql = "delete from Events where Id = ?"; my $deleteEventSql = "delete from Events where Id = ?";
my $deleteEventSth = $dbh->prepare_cached( $deleteEventSql ) or Fatal( "Can't prepare '$deleteEventSql': ".$dbh->errstr() ); my $deleteEventSth = $dbh->prepare_cached( $deleteEventSql ) or Fatal( "Can't prepare '$deleteEventSql': ".$dbh->errstr() );
my $deleteFramesSql = "delete from Frames where EventId = ?"; my $deleteFramesSql = "delete from Frames where EventId = ?";
my $deleteFramesSth = $dbh->prepare_cached( $deleteFramesSql ) or Fatal( "Can't prepare '$deleteFramesSql': ".$dbh->errstr() ); my $deleteFramesSth = $dbh->prepare_cached( $deleteFramesSql ) or Fatal( "Can't prepare '$deleteFramesSql': ".$dbh->errstr() );
my $deleteStatsSql = "delete from Stats where EventId = ?"; my $deleteStatsSql = "delete from Stats where EventId = ?";
my $deleteStatsSth = $dbh->prepare_cached( $deleteStatsSql ) or Fatal( "Can't prepare '$deleteStatsSql': ".$dbh->errstr() ); my $deleteStatsSth = $dbh->prepare_cached( $deleteStatsSql ) or Fatal( "Can't prepare '$deleteStatsSql': ".$dbh->errstr() );
while ( my ( $db_monitor, $db_events ) = each(%$db_monitors) ) while ( my ( $db_monitor, $db_events ) = each(%$db_monitors) )
{ {
if ( my $fs_events = $fs_monitors->{$db_monitor} ) if ( my $fs_events = $fs_monitors->{$db_monitor} )
{ {
if ( $db_events ) if ( $db_events )
{ {
while ( my ( $db_event, $age ) = each(%$db_events ) ) while ( my ( $db_event, $age ) = each(%$db_events ) )
{ {
if ( !defined($fs_events->{$db_event}) && ($age > MIN_AGE) ) if ( !defined($fs_events->{$db_event}) && ($age > MIN_AGE) )
{ {
aud_print( "Database event '$db_monitor/$db_event' does not exist in filesystem" ); aud_print( "Database event '$db_monitor/$db_event' does not exist in filesystem" );
if ( confirm() ) if ( confirm() )
{ {
my $res = $deleteEventSth->execute( $db_event ) or Fatal( "Can't execute: ".$deleteEventSth->errstr() ); my $res = $deleteEventSth->execute( $db_event ) or Fatal( "Can't execute: ".$deleteEventSth->errstr() );
$res = $deleteFramesSth->execute( $db_event ) or Fatal( "Can't execute: ".$deleteFramesSth->errstr() ); $res = $deleteFramesSth->execute( $db_event ) or Fatal( "Can't execute: ".$deleteFramesSth->errstr() );
$res = $deleteStatsSth->execute( $db_event ) or Fatal( "Can't execute: ".$deleteStatsSth->errstr() ); $res = $deleteStatsSth->execute( $db_event ) or Fatal( "Can't execute: ".$deleteStatsSth->errstr() );
$cleaned = 1; $cleaned = 1;
} }
} }
} }
} }
} }
else else
{ {
#aud_print( "Database monitor '$db_monitor' does not exist in filesystem" ); #aud_print( "Database monitor '$db_monitor' does not exist in filesystem" );
#if ( confirm() ) #if ( confirm() )
#{ #{
# We don't actually do this in case it's new # We don't actually do this in case it's new
#my $res = $deleteMonitorSth->execute( $db_monitor ) or Fatal( "Can't execute: ".$deleteMonitorSth->errstr() ); #my $res = $deleteMonitorSth->execute( $db_monitor ) or Fatal( "Can't execute: ".$deleteMonitorSth->errstr() );
#$cleaned = 1; #$cleaned = 1;
#} #}
} }
} }
redo MAIN if ( $cleaned ); redo MAIN if ( $cleaned );
# Remove orphaned events (with no monitor) # Remove orphaned events (with no monitor)
$cleaned = 0; $cleaned = 0;
my $selectOrphanedEventsSql = "select Events.Id, Events.Name from Events left join Monitors on (Events.MonitorId = Monitors.Id) where isnull(Monitors.Id)"; my $selectOrphanedEventsSql = "select Events.Id, Events.Name from Events left join Monitors on (Events.MonitorId = Monitors.Id) where isnull(Monitors.Id)";
my $selectOrphanedEventsSth = $dbh->prepare_cached( $selectOrphanedEventsSql ) or Fatal( "Can't prepare '$selectOrphanedEventsSql': ".$dbh->errstr() ); my $selectOrphanedEventsSth = $dbh->prepare_cached( $selectOrphanedEventsSql ) or Fatal( "Can't prepare '$selectOrphanedEventsSql': ".$dbh->errstr() );
$res = $selectOrphanedEventsSth->execute() or Fatal( "Can't execute: ".$selectOrphanedEventsSth->errstr() ); $res = $selectOrphanedEventsSth->execute() or Fatal( "Can't execute: ".$selectOrphanedEventsSth->errstr() );
while( my $event = $selectOrphanedEventsSth->fetchrow_hashref() ) while( my $event = $selectOrphanedEventsSth->fetchrow_hashref() )
{ {
aud_print( "Found orphaned event with no monitor '$event->{Id}'" ); aud_print( "Found orphaned event with no monitor '$event->{Id}'" );
if ( confirm() ) if ( confirm() )
{ {
$res = $deleteEventSth->execute( $event->{Id} ) or Fatal( "Can't execute: ".$deleteEventSth->errstr() ); $res = $deleteEventSth->execute( $event->{Id} ) or Fatal( "Can't execute: ".$deleteEventSth->errstr() );
$cleaned = 1; $cleaned = 1;
} }
} }
$selectOrphanedEventsSth->finish(); $selectOrphanedEventsSth->finish();
redo MAIN if ( $cleaned ); redo MAIN if ( $cleaned );
# Remove empty events (with no frames) # Remove empty events (with no frames)
$cleaned = 0; $cleaned = 0;
my $selectEmptyEventsSql = "select * from Events as E left join Frames as F on (E.Id = F.EventId) where isnull(F.EventId) and now() - interval ".MIN_AGE." second > E.StartTime"; my $selectEmptyEventsSql = "select * from Events as E left join Frames as F on (E.Id = F.EventId) where isnull(F.EventId) and now() - interval ".MIN_AGE." second > E.StartTime";
my $selectEmptyEventsSth = $dbh->prepare_cached( $selectEmptyEventsSql ) or Fatal( "Can't prepare '$selectEmptyEventsSql': ".$dbh->errstr() ); my $selectEmptyEventsSth = $dbh->prepare_cached( $selectEmptyEventsSql ) or Fatal( "Can't prepare '$selectEmptyEventsSql': ".$dbh->errstr() );
$res = $selectEmptyEventsSth->execute() or Fatal( "Can't execute: ".$selectEmptyEventsSth->errstr() ); $res = $selectEmptyEventsSth->execute() or Fatal( "Can't execute: ".$selectEmptyEventsSth->errstr() );
while( my $event = $selectEmptyEventsSth->fetchrow_hashref() ) while( my $event = $selectEmptyEventsSth->fetchrow_hashref() )
{ {
aud_print( "Found empty event with no frame records '$event->{Id}'" ); aud_print( "Found empty event with no frame records '$event->{Id}'" );
if ( confirm() ) if ( confirm() )
{ {
$res = $deleteEventSth->execute( $event->{Id} ) or Fatal( "Can't execute: ".$deleteEventSth->errstr() ); $res = $deleteEventSth->execute( $event->{Id} ) or Fatal( "Can't execute: ".$deleteEventSth->errstr() );
$cleaned = 1; $cleaned = 1;
} }
} }
$selectEmptyEventsSth->finish(); $selectEmptyEventsSth->finish();
redo MAIN if ( $cleaned ); redo MAIN if ( $cleaned );
# Remove orphaned frame records # Remove orphaned frame records
$cleaned = 0; $cleaned = 0;
my $selectOrphanedFramesSql = "select distinct EventId from Frames where EventId not in (select Id from Events)"; my $selectOrphanedFramesSql = "select distinct EventId from Frames where EventId not in (select Id from Events)";
my $selectOrphanedFramesSth = $dbh->prepare_cached( $selectOrphanedFramesSql ) or Fatal( "Can't prepare '$selectOrphanedFramesSql': ".$dbh->errstr() ); my $selectOrphanedFramesSth = $dbh->prepare_cached( $selectOrphanedFramesSql ) or Fatal( "Can't prepare '$selectOrphanedFramesSql': ".$dbh->errstr() );
$res = $selectOrphanedFramesSth->execute() or Fatal( "Can't execute: ".$selectOrphanedFramesSth->errstr() ); $res = $selectOrphanedFramesSth->execute() or Fatal( "Can't execute: ".$selectOrphanedFramesSth->errstr() );
while( my $frame = $selectOrphanedFramesSth->fetchrow_hashref() ) while( my $frame = $selectOrphanedFramesSth->fetchrow_hashref() )
{ {
aud_print( "Found orphaned frame records for event '$frame->{EventId}'" ); aud_print( "Found orphaned frame records for event '$frame->{EventId}'" );
if ( confirm() ) if ( confirm() )
{ {
$res = $deleteFramesSth->execute( $frame->{EventId} ) or Fatal( "Can't execute: ".$deleteFramesSth->errstr() ); $res = $deleteFramesSth->execute( $frame->{EventId} ) or Fatal( "Can't execute: ".$deleteFramesSth->errstr() );
$cleaned = 1; $cleaned = 1;
} }
} }
$selectOrphanedFramesSth->finish(); $selectOrphanedFramesSth->finish();
redo MAIN if ( $cleaned ); redo MAIN if ( $cleaned );
# Remove orphaned stats records # Remove orphaned stats records
$cleaned = 0; $cleaned = 0;
my $selectOrphanedStatsSql = "select distinct EventId from Stats where EventId not in (select Id from Events)"; my $selectOrphanedStatsSql = "select distinct EventId from Stats where EventId not in (select Id from Events)";
my $selectOrphanedStatsSth = $dbh->prepare_cached( $selectOrphanedStatsSql ) or Fatal( "Can't prepare '$selectOrphanedStatsSql': ".$dbh->errstr() ); my $selectOrphanedStatsSth = $dbh->prepare_cached( $selectOrphanedStatsSql ) or Fatal( "Can't prepare '$selectOrphanedStatsSql': ".$dbh->errstr() );
$res = $selectOrphanedStatsSth->execute() or Fatal( "Can't execute: ".$selectOrphanedStatsSth->errstr() ); $res = $selectOrphanedStatsSth->execute() or Fatal( "Can't execute: ".$selectOrphanedStatsSth->errstr() );
while( my $stat = $selectOrphanedStatsSth->fetchrow_hashref() ) while( my $stat = $selectOrphanedStatsSth->fetchrow_hashref() )
{ {
aud_print( "Found orphaned statistic records for event '$stat->{EventId}'" ); aud_print( "Found orphaned statistic records for event '$stat->{EventId}'" );
if ( confirm() ) if ( confirm() )
{ {
$res = $deleteStatsSth->execute( $stat->{EventId} ) or Fatal( "Can't execute: ".$deleteStatsSth->errstr() ); $res = $deleteStatsSth->execute( $stat->{EventId} ) or Fatal( "Can't execute: ".$deleteStatsSth->errstr() );
$cleaned = 1; $cleaned = 1;
} }
} }
$selectOrphanedStatsSth->finish(); $selectOrphanedStatsSth->finish();
redo MAIN if ( $cleaned ); redo MAIN if ( $cleaned );
# New audit to close any events that were left open for longer than MIN_AGE seconds # New audit to close any events that were left open for longer than MIN_AGE seconds
my $selectUnclosedEventsSql = "select E.Id, max(F.TimeStamp) as EndTime, unix_timestamp(max(F.TimeStamp)) - unix_timestamp(E.StartTime) as Length, max(F.FrameId) as Frames, count(if(F.Score>0,1,NULL)) as AlarmFrames, sum(F.Score) as TotScore, max(F.Score) as MaxScore, M.EventPrefix as Prefix from Events as E left join Monitors as M on E.MonitorId = M.Id inner join Frames as F on E.Id = F.EventId where isnull(E.Frames) or isnull(E.EndTime) group by E.Id having EndTime < (now() - interval ".MIN_AGE." second)"; my $selectUnclosedEventsSql = "select E.Id, max(F.TimeStamp) as EndTime, unix_timestamp(max(F.TimeStamp)) - unix_timestamp(E.StartTime) as Length, max(F.FrameId) as Frames, count(if(F.Score>0,1,NULL)) as AlarmFrames, sum(F.Score) as TotScore, max(F.Score) as MaxScore, M.EventPrefix as Prefix from Events as E left join Monitors as M on E.MonitorId = M.Id inner join Frames as F on E.Id = F.EventId where isnull(E.Frames) or isnull(E.EndTime) group by E.Id having EndTime < (now() - interval ".MIN_AGE." second)";
my $selectUnclosedEventsSth = $dbh->prepare_cached( $selectUnclosedEventsSql ) or Fatal( "Can't prepare '$selectUnclosedEventsSql': ".$dbh->errstr() ); my $selectUnclosedEventsSth = $dbh->prepare_cached( $selectUnclosedEventsSql ) or Fatal( "Can't prepare '$selectUnclosedEventsSql': ".$dbh->errstr() );
my $updateUnclosedEventsSql = "update Events set Name = ?, EndTime = ?, Length = ?, Frames = ?, AlarmFrames = ?, TotScore = ?, AvgScore = ?, MaxScore = ?, Notes = concat_ws( ' ', Notes, ? ) where Id = ?"; my $updateUnclosedEventsSql = "update Events set Name = ?, EndTime = ?, Length = ?, Frames = ?, AlarmFrames = ?, TotScore = ?, AvgScore = ?, MaxScore = ?, Notes = concat_ws( ' ', Notes, ? ) where Id = ?";
my $updateUnclosedEventsSth = $dbh->prepare_cached( $updateUnclosedEventsSql ) or Fatal( "Can't prepare '$updateUnclosedEventsSql': ".$dbh->errstr() ); my $updateUnclosedEventsSth = $dbh->prepare_cached( $updateUnclosedEventsSql ) or Fatal( "Can't prepare '$updateUnclosedEventsSql': ".$dbh->errstr() );
$res = $selectUnclosedEventsSth->execute() or Fatal( "Can't execute: ".$selectUnclosedEventsSth->errstr() ); $res = $selectUnclosedEventsSth->execute() or Fatal( "Can't execute: ".$selectUnclosedEventsSth->errstr() );
while( my $event = $selectUnclosedEventsSth->fetchrow_hashref() ) while( my $event = $selectUnclosedEventsSth->fetchrow_hashref() )
{ {
aud_print( "Found open event '$event->{Id}'" ); aud_print( "Found open event '$event->{Id}'" );
if ( confirm( 'close', 'closing' ) ) if ( confirm( 'close', 'closing' ) )
{ {
$res = $updateUnclosedEventsSth->execute( sprintf( "%s%d%s", $event->{Prefix}, $event->{Id}, RECOVER_TAG ), $event->{EndTime}, $event->{Length}, $event->{Frames}, $event->{AlarmFrames}, $event->{TotScore}, $event->{AlarmFrames}?int($event->{TotScore}/$event->{AlarmFrames}):0, $event->{MaxScore}, RECOVER_TEXT, $event->{Id} ) or Fatal( "Can't execute: ".$updateUnclosedEventsSth->errstr() ); $res = $updateUnclosedEventsSth->execute( sprintf( "%s%d%s", $event->{Prefix}, $event->{Id}, RECOVER_TAG ), $event->{EndTime}, $event->{Length}, $event->{Frames}, $event->{AlarmFrames}, $event->{TotScore}, $event->{AlarmFrames}?int($event->{TotScore}/$event->{AlarmFrames}):0, $event->{MaxScore}, RECOVER_TEXT, $event->{Id} ) or Fatal( "Can't execute: ".$updateUnclosedEventsSth->errstr() );
} }
} }
$selectUnclosedEventsSth->finish(); $selectUnclosedEventsSth->finish();
# Now delete any old image files # Now delete any old image files
if ( my @old_files = grep { -M > $max_image_age } <$image_path/*.{jpg,gif,wbmp}> ) if ( my @old_files = grep { -M > $max_image_age } <$image_path/*.{jpg,gif,wbmp}> )
{ {
aud_print( "Deleting ".int(@old_files)." old images\n" ); aud_print( "Deleting ".int(@old_files)." old images\n" );
my $untainted_old_files = join( ";", @old_files ); my $untainted_old_files = join( ";", @old_files );
( $untainted_old_files ) = ( $untainted_old_files =~ /^(.*)$/ ); ( $untainted_old_files ) = ( $untainted_old_files =~ /^(.*)$/ );
unlink( split( ";", $untainted_old_files ) ); unlink( split( ";", $untainted_old_files ) );
} }
# Now delete any old swap files # Now delete any old swap files
( my $swap_image_root ) = ( $swap_image_path =~ /^(.*)$/ ); # De-taint ( my $swap_image_root ) = ( $swap_image_path =~ /^(.*)$/ ); # De-taint
File::Find::find( { wanted=>\&deleteSwapImage, untaint=>1 }, $swap_image_root ); File::Find::find( { wanted=>\&deleteSwapImage, untaint=>1 }, $swap_image_root );
# Prune the Logs table if required
if ( ZM_LOG_DATABASE_LIMIT )
{
if ( ZM_LOG_DATABASE_LIMIT =~ /^\d+$/ )
{
# Number of rows
my $selectLogRowCountSql = "select count(*) as Rows from Logs";
my $selectLogRowCountSth = $dbh->prepare_cached( $selectLogRowCountSql ) or Fatal( "Can't prepare '$selectLogRowCountSql': ".$dbh->errstr() );
$res = $selectLogRowCountSth->execute() or Fatal( "Can't execute: ".$selectLogRowCountSth->errstr() );
my $row = $selectLogRowCountSth->fetchrow_hashref();
my $logRows = $row->{Rows};
$selectLogRowCountSth->finish();
if ( $logRows > ZM_LOG_DATABASE_LIMIT )
{
my $deleteLogByRowsSql = "delete from Logs order by TimeKey asc limit ?";
my $deleteLogByRowsSth = $dbh->prepare_cached( $deleteLogByRowsSql ) or Fatal( "Can't prepare '$deleteLogByRowsSql': ".$dbh->errstr() );
$res = $deleteLogByRowsSth->execute( $logRows - ZM_LOG_DATABASE_LIMIT ) or Fatal( "Can't execute: ".$deleteLogByRowsSth->errstr() );
aud_print( "Deleted ".$deleteLogByRowsSth->rows()." log table entries by count\n" ) if ( $deleteLogByRowsSth->rows() );
}
}
else
{
# Time of record
my $deleteLogByTimeSql = "delete from Logs where TimeKey < unix_timestamp(now() - interval ".ZM_LOG_DATABASE_LIMIT.")";
my $deleteLogByTimeSth = $dbh->prepare_cached( $deleteLogByTimeSql ) or Fatal( "Can't prepare '$deleteLogByTimeSql': ".$dbh->errstr() );
$res = $deleteLogByTimeSth->execute() or Fatal( "Can't execute: ".$deleteLogByTimeSth->errstr() );
aud_print( "Deleted ".$deleteLogByTimeSth->rows()." log table entries by time\n" ) if ( $deleteLogByTimeSth->rows() );
}
}
$loop = $continuous; $loop = $continuous;
sleep( ZM_AUDIT_CHECK_INTERVAL ) if ( $continuous ); sleep( ZM_AUDIT_CHECK_INTERVAL ) if ( $continuous );
}; };
exit( 0 ); exit( 0 );
sub aud_print( $ ) sub aud_print( $ )
{ {
my $string = shift; my $string = shift;
if ( !$continuous ) if ( !$continuous )
{ {
print( $string ); print( $string );
} }
else else
{ {
Info( $string ); Info( $string );
} }
} }
sub confirm( ;$$ ) sub confirm( ;$$ )
{ {
my $prompt = shift || "delete"; my $prompt = shift || "delete";
my $action = shift || "deleting"; my $action = shift || "deleting";
my $yesno = 0; my $yesno = 0;
if ( $report ) if ( $report )
{ {
print( "\n" ); print( "\n" );
} }
elsif ( $interactive ) elsif ( $interactive )
{ {
print( ", $prompt y/n: " ); print( ", $prompt y/n: " );
my $char = <>; my $char = <>;
chomp( $char ); chomp( $char );
if ( $char eq 'q' ) if ( $char eq 'q' )
{ {
exit( 0 ); exit( 0 );
} }
if ( !$char ) if ( !$char )
{ {
$char = 'y'; $char = 'y';
} }
$yesno = ( $char =~ /[yY]/ ); $yesno = ( $char =~ /[yY]/ );
} }
else else
{ {
if ( !$continuous ) if ( !$continuous )
{ {
print( ", $action\n" ); print( ", $action\n" );
} }
else else
{ {
Info( $action ); Info( $action );
} }
$yesno = 1; $yesno = 1;
} }
return( $yesno ); return( $yesno );
} }
sub deleteSwapImage() sub deleteSwapImage()

View File

@ -27,17 +27,6 @@
# #
use strict; use strict;
# ==========================================================================
#
# These are the elements you can edit to suit your installation
#
# ==========================================================================
use constant DBG_ID => "zmcontrol"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
# ==========================================================================
@EXTRA_PERL_LIB@ @EXTRA_PERL_LIB@
use ZoneMinder; use ZoneMinder;
use Getopt::Long; use Getopt::Long;
@ -63,7 +52,7 @@ Usage: zmcontrol.pl --id <monitor_id> --command=<command> <various options>
exit( -1 ); exit( -1 );
} }
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
my $arg_string = join( " ", @ARGV ); my $arg_string = join( " ", @ARGV );
@ -124,7 +113,7 @@ if ( !$server_up )
my $output = qx($command); my $output = qx($command);
my $status = $? >> 8; my $status = $? >> 8;
if ( $status || DBG_LEVEL > 0 ) if ( $status || logDebugging() )
{ {
chomp( $output ); chomp( $output );
Debug( "Output: $output\n" ); Debug( "Output: $output\n" );
@ -142,7 +131,7 @@ if ( !$server_up )
if ( my $cpid = fork() ) if ( my $cpid = fork() )
{ {
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
# Parent process just sleep and fall through # Parent process just sleep and fall through
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or die( "Can't open socket: $!" ); socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or die( "Can't open socket: $!" );
@ -161,7 +150,7 @@ if ( !$server_up )
setpgrp(); setpgrp();
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
Info( "Control server $id/$protocol starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() ) ); Info( "Control server $id/$protocol starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() ) );

View File

@ -36,9 +36,6 @@ use bytes;
# #
# ========================================================================== # ==========================================================================
use constant DBG_ID => "zmdc"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
use constant MAX_CONNECT_DELAY => 10; use constant MAX_CONNECT_DELAY => 10;
# ========================================================================== # ==========================================================================
@ -63,16 +60,16 @@ $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
my @daemons = ( my @daemons = (
'zmc', 'zmc',
'zma', 'zma',
'zmf', 'zmf',
'zmfilter.pl', 'zmfilter.pl',
'zmaudit.pl', 'zmaudit.pl',
'zmtrigger.pl', 'zmtrigger.pl',
'zmx10.pl', 'zmx10.pl',
'zmwatch.pl', 'zmwatch.pl',
'zmupdate.pl', 'zmupdate.pl',
'zmtrack.pl' 'zmtrack.pl'
); );
sub Usage sub Usage
@ -105,30 +102,30 @@ my @args;
my $daemon_patt = '('.join( '|', @daemons ).')'; my $daemon_patt = '('.join( '|', @daemons ).')';
if ( $needs_daemon ) if ( $needs_daemon )
{ {
if ( $daemon =~ /^${daemon_patt}$/ ) if ( $daemon =~ /^${daemon_patt}$/ )
{ {
$daemon = $1; $daemon = $1;
} }
else else
{ {
print( STDERR "Invalid daemon '$daemon' specified" ); print( STDERR "Invalid daemon '$daemon' specified" );
Usage(); Usage();
} }
} }
foreach my $arg ( @ARGV ) foreach my $arg ( @ARGV )
{ {
# Detaint arguments, if they look ok # Detaint arguments, if they look ok
#if ( $arg =~ /^(-{0,2}[\w]+)/ ) #if ( $arg =~ /^(-{0,2}[\w]+)/ )
if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ ) if ( $arg =~ /^(-{0,2}[\w\/?&=.-]+)$/ )
{ {
push( @args, $1 ); push( @args, $1 );
} }
else else
{ {
print( STDERR "Bogus argument '$arg' found" ); print( STDERR "Bogus argument '$arg' found" );
exit( -1 ); exit( -1 );
} }
} }
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" ); socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
@ -137,56 +134,56 @@ my $saddr = sockaddr_un( SOCK_FILE );
my $server_up = connect( CLIENT, $saddr ); my $server_up = connect( CLIENT, $saddr );
if ( !$server_up ) if ( !$server_up )
{ {
if ( $command eq "logrot" ) if ( $command eq "logrot" )
{ {
exit(); exit();
} }
if ( $command eq "check" ) if ( $command eq "check" )
{ {
print( "stopped\n" ); print( "stopped\n" );
exit(); exit();
} }
elsif ( $command ne "startup" ) elsif ( $command ne "startup" )
{ {
print( "Unable to connect to server\n" ); print( "Unable to connect to server\n" );
exit( -1 ); exit( -1 );
} }
# The server isn't there # The server isn't there
print( "Starting server\n" ); print( "Starting server\n" );
close( CLIENT ); close( CLIENT );
if ( my $cpid = fork() ) if ( my $cpid = fork() )
{ {
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
# Parent process just sleep and fall through # Parent process just sleep and fall through
socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" ); socket( CLIENT, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
my $attempts = 0; my $attempts = 0;
while (!connect( CLIENT, $saddr )) while (!connect( CLIENT, $saddr ))
{ {
$attempts++; $attempts++;
Fatal( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY); Fatal( "Can't connect: $!" ) if ($attempts > MAX_CONNECT_DELAY);
sleep(1); sleep(1);
} }
} }
elsif ( defined($cpid) ) elsif ( defined($cpid) )
{ {
ZMServer::run(); ZMServer::run();
} }
else else
{ {
Fatal( "Can't fork: $!" ); Fatal( "Can't fork: $!" );
} }
} }
if ( $command eq "check" && !$daemon ) if ( $command eq "check" && !$daemon )
{ {
print( "running\n" ); print( "running\n" );
exit(); exit();
} }
elsif ( $command eq "startup" ) elsif ( $command eq "startup" )
{ {
# Our work here is done # Our work here is done
exit() if ( !$server_up ); exit() if ( !$server_up );
} }
# The server is there, connect to it # The server is there, connect to it
#print( "Writing commands\n" ); #print( "Writing commands\n" );
@ -198,8 +195,8 @@ print( CLIENT $message );
shutdown( CLIENT, 1 ); shutdown( CLIENT, 1 );
while ( my $line = <CLIENT> ) while ( my $line = <CLIENT> )
{ {
chomp( $line ); chomp( $line );
print( "$line\n" ); print( "$line\n" );
} }
# And we're done! # And we're done!
close( CLIENT ); close( CLIENT );
@ -232,9 +229,9 @@ sub run
setpgrp(); setpgrp();
zmDbgInit( main::DBG_ID, level=>main::DBG_LEVEL ); logInit();
dPrint( DBG_INFO, "Server starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" ); dPrint( ZoneMinder::Logger::INFO, "Server starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
if ( open( PID, ">".ZM_PID ) ) if ( open( PID, ">".ZM_PID ) )
{ {
@ -293,7 +290,7 @@ sub run
elsif ( $command eq 'startup' ) elsif ( $command eq 'startup' )
{ {
# Do nothing, this is all we're here for # Do nothing, this is all we're here for
dPrint( DBG_WARNING, "Already running, ignoring command '$command'\n" ); dPrint( ZoneMinder::Logger::WARNING, "Already running, ignoring command '$command'\n" );
} }
elsif ( $command eq 'shutdown' ) elsif ( $command eq 'shutdown' )
{ {
@ -320,7 +317,7 @@ sub run
} }
else else
{ {
dPrint( DBG_ERROR, "Invalid command '$command'\n" ); dPrint( ZoneMinder::Logger::ERROR, "Invalid command '$command'\n" );
} }
close( CLIENT ); close( CLIENT );
} }
@ -353,7 +350,7 @@ sub run
restartPending(); restartPending();
} }
} }
dPrint( DBG_INFO, "Server exiting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" ); dPrint( ZoneMinder::Logger::INFO, "Server exiting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
unlink( main::SOCK_FILE ); unlink( main::SOCK_FILE );
unlink( ZM_PID ); unlink( ZM_PID );
exit(); exit();
@ -369,28 +366,28 @@ sub cPrint
sub dPrint sub dPrint
{ {
my $dbg_level = shift; my $logLevel = shift;
if ( fileno(CLIENT) ) if ( fileno(CLIENT) )
{ {
print CLIENT @_ print CLIENT @_
} }
if ( $dbg_level == DBG_DEBUG ) if ( $logLevel == ZoneMinder::Logger::DEBUG )
{ {
Debug( @_ ); Debug( @_ );
} }
elsif ( $dbg_level == DBG_INFO ) elsif ( $logLevel == ZoneMinder::Logger::INFO )
{ {
Info( @_ ); Info( @_ );
} }
elsif ( $dbg_level == DBG_WARNING ) elsif ( $logLevel == ZoneMinder::Logger::WARNING )
{ {
Warning( @_ ); Warning( @_ );
} }
elsif ( $dbg_level == DBG_ERROR ) elsif ( $logLevel == ZoneMinder::Logger::ERROR )
{ {
Error( @_ ); Error( @_ );
} }
elsif ( $dbg_level == DBG_FATAL ) elsif ( $logLevel == ZoneMinder::Logger::FATAL )
{ {
Fatal( @_ ); Fatal( @_ );
} }
@ -412,38 +409,31 @@ sub start
} }
elsif ( $process->{pid} && $pid_hash{$process->{pid}} ) elsif ( $process->{pid} && $pid_hash{$process->{pid}} )
{ {
dPrint( DBG_INFO, "'$process->{command}' already running at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}\n" ); dPrint( ZoneMinder::Logger::INFO, "'$process->{command}' already running at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}\n" );
return(); return();
} }
my $sigset = POSIX::SigSet->new;
my $blockset = POSIX::SigSet->new( SIGCHLD );
sigprocmask( SIG_BLOCK, $blockset, $sigset ) or Fatal( "Can't block SIGCHLD: $!" );
if ( my $cpid = fork() ) if ( my $cpid = fork() )
{ {
my $sigset = POSIX::SigSet->new; logReinit();
my $blockset = POSIX::SigSet->new( SIGCHLD );
sigprocmask( SIG_BLOCK, $blockset, $sigset ) or Fatal( "Can't block SIGCHLD: $!" );
$process->{pid} = $cpid; $process->{pid} = $cpid;
$process->{started} = time(); $process->{started} = time();
delete( $process->{pending} ); delete( $process->{pending} );
dPrint( DBG_INFO, "'$command' starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}\n" ); dPrint( ZoneMinder::Logger::INFO, "'$command' starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}\n" );
$cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process; $cmd_hash{$process->{command}} = $pid_hash{$cpid} = $process;
sigprocmask( SIG_SETMASK, $sigset ) or Fatal( "Can't restore SIGCHLD: $!" ); sigprocmask( SIG_SETMASK, $sigset ) or Fatal( "Can't restore SIGCHLD: $!" );
} }
elsif ( defined($cpid ) ) elsif ( defined($cpid ) )
{ {
my $fd = 0; logReinit();
while( $fd < POSIX::sysconf( &POSIX::_SC_OPEN_MAX ) )
{
POSIX::close( $fd++ );
}
# Child process dPrint( ZoneMinder::Logger::INFO, "'".join( ' ', ( $daemon, @args ) )."' started at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
$SIG{CHLD} = 'DEFAULT';
$SIG{INT} = 'DEFAULT';
$SIG{TERM} = 'DEFAULT';
$SIG{ABRT} = 'DEFAULT';
dPrint( DBG_INFO, "'".join( ' ', ( $daemon, @args ) )."' started at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
if ( $daemon =~ /^${daemon_patt}$/ ) if ( $daemon =~ /^${daemon_patt}$/ )
{ {
@ -468,6 +458,20 @@ sub start
} }
} }
logTerm();
my $fd = 0;
while( $fd < POSIX::sysconf( &POSIX::_SC_OPEN_MAX ) )
{
POSIX::close( $fd++ );
}
# Child process
$SIG{CHLD} = 'DEFAULT';
$SIG{INT} = 'DEFAULT';
$SIG{TERM} = 'DEFAULT';
$SIG{ABRT} = 'DEFAULT';
exec( $daemon, @good_args ) or Fatal( "Can't exec: $!" ); exec( $daemon, @good_args ) or Fatal( "Can't exec: $!" );
} }
else else
@ -487,24 +491,24 @@ sub _stop
my $process = $cmd_hash{$command}; my $process = $cmd_hash{$command};
if ( !$process ) if ( !$process )
{ {
dPrint( DBG_WARNING, "Can't find process with command of '$command'\n" ); dPrint( ZoneMinder::Logger::WARNING, "Can't find process with command of '$command'\n" );
return(); return();
} }
elsif ( $process->{pending} ) elsif ( $process->{pending} )
{ {
delete( $cmd_hash{$command} ); delete( $cmd_hash{$command} );
dPrint( DBG_INFO, "Command '$command' removed from pending list at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" ); dPrint( ZoneMinder::Logger::INFO, "Command '$command' removed from pending list at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
return(); return();
} }
my $cpid = $process->{pid}; my $cpid = $process->{pid};
if ( !$pid_hash{$cpid} ) if ( !$pid_hash{$cpid} )
{ {
dPrint( DBG_ERROR, "No process with command of '$command' is running\n" ); dPrint( ZoneMinder::Logger::ERROR, "No process with command of '$command' is running\n" );
return(); return();
} }
dPrint( DBG_INFO, "'$daemon ".join( ' ', @args )."' stopping at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" ); dPrint( ZoneMinder::Logger::INFO, "'$daemon ".join( ' ', @args )."' stopping at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
$process->{keepalive} = !$final; $process->{keepalive} = !$final;
kill( 'TERM', $cpid ); kill( 'TERM', $cpid );
delete( $cmd_hash{$command} ); delete( $cmd_hash{$command} );
@ -568,7 +572,7 @@ sub reload
sub logrot sub logrot
{ {
zmDbgReinit(); logReinit();
foreach my $process ( values( %pid_hash ) ) foreach my $process ( values( %pid_hash ) )
{ {
if ( $process->{pid} && $process->{command} =~ /^zm.*\.pl/ ) if ( $process->{pid} && $process->{command} =~ /^zm.*\.pl/ )
@ -590,7 +594,7 @@ sub reaper
if ( !$process ) if ( !$process )
{ {
dPrint( DBG_INFO, "Can't find child with pid of '$cpid'\n" ); dPrint( ZoneMinder::Logger::INFO, "Can't find child with pid of '$cpid'\n" );
next; next;
} }
@ -673,7 +677,7 @@ sub restartPending
{ {
if ( $process->{pending} && $process->{pending} <= time() ) if ( $process->{pending} && $process->{pending} <= time() )
{ {
dPrint( DBG_INFO, "Starting pending process, $process->{command}\n" ); dPrint( ZoneMinder::Logger::INFO, "Starting pending process, $process->{command}\n" );
start( $process->{daemon}, @{$process->{args}} ); start( $process->{daemon}, @{$process->{args}} );
} }
} }
@ -686,7 +690,7 @@ sub shutdownAll
stop( $process->{daemon}, @{$process->{args}} ); stop( $process->{daemon}, @{$process->{args}} );
} }
killAll( 5 ); killAll( 5 );
dPrint( DBG_INFO, "Server shutdown at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" ); dPrint( ZoneMinder::Logger::INFO, "Server shutdown at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
unlink( main::SOCK_FILE ); unlink( main::SOCK_FILE );
unlink( ZM_PID ); unlink( ZM_PID );
close( CLIENT ); close( CLIENT );
@ -736,24 +740,24 @@ sub status
my $process = $cmd_hash{$command}; my $process = $cmd_hash{$command};
if ( !$process ) if ( !$process )
{ {
dPrint( DBG_DEBUG, "'$command' not running\n" ); dPrint( ZoneMinder::Logger::DEBUG, "'$command' not running\n" );
return(); return();
} }
if ( $process->{pending} ) if ( $process->{pending} )
{ {
dPrint( DBG_DEBUG, "'$process->{command}' pending at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{pending}) )."\n" ); dPrint( ZoneMinder::Logger::DEBUG, "'$process->{command}' pending at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{pending}) )."\n" );
} }
else else
{ {
my $cpid = $process->{pid}; my $cpid = $process->{pid};
if ( !$pid_hash{$cpid} ) if ( !$pid_hash{$cpid} )
{ {
dPrint( DBG_DEBUG, "'$command' not running\n" ); dPrint( ZoneMinder::Logger::DEBUG, "'$command' not running\n" );
return(); return();
} }
} }
dPrint( DBG_DEBUG, "'$process->{command}' running since ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}" ); dPrint( ZoneMinder::Logger::DEBUG, "'$process->{command}' running since ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}" );
} }
else else
{ {
@ -762,13 +766,13 @@ sub status
my $out_str = "'$process->{command}' running since ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}"; my $out_str = "'$process->{command}' running since ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{started}) ).", pid = $process->{pid}";
$out_str .= ", valid" if ( kill( 0, $process->{pid} ) ); $out_str .= ", valid" if ( kill( 0, $process->{pid} ) );
$out_str .= "\n"; $out_str .= "\n";
dPrint( DBG_DEBUG, $out_str ); dPrint( ZoneMinder::Logger::DEBUG, $out_str );
} }
foreach my $process ( values( %cmd_hash ) ) foreach my $process ( values( %cmd_hash ) )
{ {
if ( $process->{pending} ) if ( $process->{pending} )
{ {
dPrint( DBG_DEBUG, "'$process->{command}' pending at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{pending}) )."\n" ); dPrint( ZoneMinder::Logger::DEBUG, "'$process->{command}' pending at ".strftime( '%y/%m/%d %H:%M:%S', localtime( $process->{pending}) )."\n" );
} }
} }
} }
@ -776,19 +780,19 @@ sub status
sub killAll sub killAll
{ {
my $delay = shift; my $delay = shift;
sleep( $delay ); sleep( $delay );
foreach my $daemon ( @daemons ) foreach my $daemon ( @daemons )
{ {
my $cmd = "killall --quiet --signal TERM $daemon"; my $cmd = "killall --quiet --signal TERM $daemon";
Debug( $cmd ); Debug( $cmd );
qx( $cmd ); qx( $cmd );
} }
sleep( $delay ); sleep( $delay );
foreach my $daemon ( @daemons ) foreach my $daemon ( @daemons )
{ {
my $cmd = "killall --quiet --signal KILL $daemon"; my $cmd = "killall --quiet --signal KILL $daemon";
Debug( $cmd ); Debug( $cmd );
qx( $cmd ); qx( $cmd );
} }
} }

View File

@ -34,9 +34,6 @@ use bytes;
# #
# ========================================================================== # ==========================================================================
use constant DBG_ID => "zmfilter"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
use constant START_DELAY => 5; # How long to wait before starting use constant START_DELAY => 5; # How long to wait before starting
# ========================================================================== # ==========================================================================
@ -56,8 +53,8 @@ use Data::Dumper;
use constant EVENT_PATH => (ZM_DIR_EVENTS=~m|/|)?ZM_DIR_EVENTS:(ZM_PATH_WEB.'/'.ZM_DIR_EVENTS); use constant EVENT_PATH => (ZM_DIR_EVENTS=~m|/|)?ZM_DIR_EVENTS:(ZM_PATH_WEB.'/'.ZM_DIR_EVENTS);
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
zmDbgSetSignal(); logSetSignal();
if ( ZM_OPT_UPLOAD ) if ( ZM_OPT_UPLOAD )
{ {
@ -678,7 +675,7 @@ sub generateVideo
my $output = qx($command); my $output = qx($command);
chomp( $output ); chomp( $output );
my $status = $? >> 8; my $status = $? >> 8;
if ( $status || DBG_LEVEL > 0 ) if ( $status || logDebugging() )
{ {
Debug( "Output: $output\n" ); Debug( "Output: $output\n" );
} }
@ -1119,7 +1116,7 @@ sub executeCommand
Info( "Executing '$command'\n" ); Info( "Executing '$command'\n" );
my $output = qx($command); my $output = qx($command);
my $status = $? >> 8; my $status = $? >> 8;
if ( $status || DBG_LEVEL > 0 ) if ( $status || logDebugging() )
{ {
chomp( $output ); chomp( $output );
Debug( "Output: $output\n" ); Debug( "Output: $output\n" );

View File

@ -27,15 +27,6 @@
use strict; use strict;
use bytes; use bytes;
# ==========================================================================
#
# These are the elements you can edit to suit your installation
#
# ==========================================================================
use constant DBG_ID => "zmpkg"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
# ========================================================================== # ==========================================================================
# #
# Don't change anything below here # Don't change anything below here
@ -53,7 +44,7 @@ $ENV{PATH} = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
my $command = $ARGV[0]; my $command = $ARGV[0];

View File

@ -33,9 +33,6 @@ use bytes;
# #
# ========================================================================== # ==========================================================================
use constant DBG_ID => "zmtrack"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
use constant SLEEP_TIME => 10000; # In microseconds use constant SLEEP_TIME => 10000; # In microseconds
# ========================================================================== # ==========================================================================
@ -74,8 +71,8 @@ if ( !GetOptions( 'monitor=s'=>\$mid ) )
Usage(); Usage();
} }
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
zmDbgSetSignal(); logSetSignal();
my ( $detaint_mid ) = $mid =~ /^(\d+)$/; my ( $detaint_mid ) = $mid =~ /^(\d+)$/;
$mid = $detaint_mid; $mid = $detaint_mid;
@ -190,7 +187,7 @@ while( 1 )
} }
else else
{ {
if ( DBG_LEVEL > 0 && $alarmed ) if ( logDebugging() && $alarmed )
{ {
print( "Left alarm state\n" ); print( "Left alarm state\n" );
$alarmed = undef; $alarmed = undef;

View File

@ -34,9 +34,6 @@ use bytes;
# #
# ========================================================================== # ==========================================================================
use constant DBG_ID => "zmtrigger"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
use constant MAX_CONNECT_DELAY => 10; use constant MAX_CONNECT_DELAY => 10;
use constant MONITOR_RELOAD_INTERVAL => 300; use constant MONITOR_RELOAD_INTERVAL => 300;
use constant SELECT_TIMEOUT => 0.25; use constant SELECT_TIMEOUT => 0.25;
@ -78,8 +75,8 @@ $ENV{PATH} = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
zmDbgSetSignal(); logSetSignal();
Info( "Trigger daemon starting\n" ); Info( "Trigger daemon starting\n" );

View File

@ -34,9 +34,6 @@ use bytes;
# #
# ========================================================================== # ==========================================================================
use constant DBG_ID => "zmupdate"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
use constant CHECK_INTERVAL => (1*24*60*60); # Interval between version checks use constant CHECK_INTERVAL => (1*24*60*60); # Interval between version checks
# ========================================================================== # ==========================================================================
@ -48,7 +45,7 @@ use constant CHECK_INTERVAL => (1*24*60*60); # Interval between version checks
@EXTRA_PERL_LIB@ @EXTRA_PERL_LIB@
use ZoneMinder::Base qw(:all); use ZoneMinder::Base qw(:all);
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use ZoneMinder::Debug qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::General qw(:all); use ZoneMinder::General qw(:all);
use ZoneMinder::Database qw(:all); use ZoneMinder::Database qw(:all);
use ZoneMinder::ConfigAdmin qw( :functions ); use ZoneMinder::ConfigAdmin qw( :functions );
@ -68,19 +65,19 @@ delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
my $web_uid = (getpwnam( ZM_WEB_USER ))[2]; my $web_uid = (getpwnam( ZM_WEB_USER ))[2];
my $use_log = (($> == 0) || ($> == $web_uid)); my $use_log = (($> == 0) || ($> == $web_uid));
zmDbgInit( DBG_ID, level=>DBG_LEVEL, to_log=>$use_log ); logInit( toFile=>$use_log?DEBUG:NOLOG );
zmDbgSetSignal(); logSetSignal();
my $interactive = 1; my $interactive = 1;
my $check = 0; my $check = 0;
my $freshen = 0; my $freshen = 0;
my $rename = 0; my $rename = 0;
my $zone_fix = 0; my $zoneFix = 0;
my $migrate_events = 0; my $migrateEvents = 0;
my $version = ''; my $version = '';
my $db_user = ZM_DB_USER; my $dbUser = ZM_DB_USER;
my $db_pass = ZM_DB_PASS; my $dbPass = ZM_DB_PASS;
my $update_dir = ''; my $updateDir = '';
sub Usage sub Usage
{ {
print( " print( "
@ -96,12 +93,12 @@ Parameters are :-
exit( -1 ); exit( -1 );
} }
if ( !GetOptions( 'check'=>\$check, 'freshen'=>\$freshen, 'rename'=>\$rename, 'zone-fix'=>\$zone_fix, 'migrate-events'=>\$migrate_events, 'version=s'=>\$version, 'interactive!'=>\$interactive, 'user:s'=>\$db_user, 'pass:s'=>\$db_pass, 'dir:s'=>\$update_dir ) ) if ( !GetOptions( 'check'=>\$check, 'freshen'=>\$freshen, 'rename'=>\$rename, 'zone-fix'=>\$zoneFix, 'migrate-events'=>\$migrateEvents, 'version=s'=>\$version, 'interactive!'=>\$interactive, 'user:s'=>\$dbUser, 'pass:s'=>\$dbPass, 'dir:s'=>\$updateDir ) )
{ {
Usage(); Usage();
} }
if ( ! ($check || $freshen || $rename || $zone_fix || $migrate_events || $version) ) if ( ! ($check || $freshen || $rename || $zoneFix || $migrateEvents || $version) )
{ {
if ( ZM_DYN_DB_VERSION ) if ( ZM_DYN_DB_VERSION )
{ {
@ -114,7 +111,7 @@ if ( ! ($check || $freshen || $rename || $zone_fix || $migrate_events || $versio
} }
} }
if ( ($check + $freshen + $rename + $zone_fix + $migrate_events + ($version?1:0)) > 1 ) if ( ($check + $freshen + $rename + $zoneFix + $migrateEvents + ($version?1:0)) > 1 )
{ {
print( STDERR "Please give only one option\n" ); print( STDERR "Please give only one option\n" );
Usage(); Usage();
@ -126,25 +123,27 @@ if ( $check && ZM_CHECK_FOR_UPDATES )
my $dbh = zmDbConnect(); my $dbh = zmDbConnect();
my $curr_version = ZM_DYN_CURR_VERSION; my $currVersion = ZM_DYN_CURR_VERSION;
my $last_version = ZM_DYN_LAST_VERSION; my $lastVersion = ZM_DYN_LAST_VERSION;
my $last_check = ZM_DYN_LAST_CHECK; my $lastCheck = ZM_DYN_LAST_CHECK;
if ( !$curr_version ) if ( !$currVersion )
{ {
$curr_version = ZM_VERSION; $currVersion = ZM_VERSION;
my $sql = "update Config set Value = ? where Name = 'ZM_DYN_CURR_VERSION'"; my $sql = "update Config set Value = ? where Name = 'ZM_DYN_CURR_VERSION'";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( "$curr_version" ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( "$currVersion" ) or die( "Can't execute: ".$sth->errstr() );
} }
zmDbDisconnect(); zmDbDisconnect();
while( 1 ) while( 1 )
{ {
my $now = time(); my $now = time();
if ( !$last_version || !$last_check || (($now-$last_check) > CHECK_INTERVAL) ) if ( !$lastVersion || !$lastCheck || (($now-$lastCheck) > CHECK_INTERVAL) )
{ {
$dbh = zmDbConnect();
Info( "Checking for updates\n" ); Info( "Checking for updates\n" );
use LWP::UserAgent; use LWP::UserAgent;
@ -164,28 +163,25 @@ if ( $check && ZM_CHECK_FOR_UPDATES )
if ( $res->is_success ) if ( $res->is_success )
{ {
$last_version = $res->content; $lastVersion = $res->content;
chomp($last_version); chomp($lastVersion);
$last_check = $now; $lastCheck = $now;
Info( "Got version: '".$last_version."'\n" ); Info( "Got version: '".$lastVersion."'\n" );
$dbh = zmDbConnect();
my $lv_sql = "update Config set Value = ? where Name = 'ZM_DYN_LAST_VERSION'"; my $lv_sql = "update Config set Value = ? where Name = 'ZM_DYN_LAST_VERSION'";
my $lv_sth = $dbh->prepare_cached( $lv_sql ) or die( "Can't prepare '$lv_sql': ".$dbh->errstr() ); my $lv_sth = $dbh->prepare_cached( $lv_sql ) or die( "Can't prepare '$lv_sql': ".$dbh->errstr() );
my $lv_res = $lv_sth->execute( $last_version ) or die( "Can't execute: ".$lv_sth->errstr() ); my $lv_res = $lv_sth->execute( $lastVersion ) or die( "Can't execute: ".$lv_sth->errstr() );
my $lc_sql = "update Config set Value = ? where Name = 'ZM_DYN_LAST_CHECK'"; my $lc_sql = "update Config set Value = ? where Name = 'ZM_DYN_LAST_CHECK'";
my $lc_sth = $dbh->prepare_cached( $lc_sql ) or die( "Can't prepare '$lc_sql': ".$dbh->errstr() ); my $lc_sth = $dbh->prepare_cached( $lc_sql ) or die( "Can't prepare '$lc_sql': ".$dbh->errstr() );
my $lc_res = $lc_sth->execute( $last_check ) or die( "Can't execute: ".$lc_sth->errstr() ); my $lc_res = $lc_sth->execute( $lastCheck ) or die( "Can't execute: ".$lc_sth->errstr() );
zmDbDisconnect();
} }
else else
{ {
Error( "Error check failed: '".$res->status_line()."'\n" ); Error( "Error check failed: '".$res->status_line()."'\n" );
} }
zmDbDisconnect();
} }
sleep( 3600 ); sleep( 3600 );
} }
@ -211,15 +207,15 @@ if ( $rename )
{ {
return; return;
} }
my $new_file = "$2-$1$3"; my $newFile = "$2-$1$3";
print( "Renaming '$file' to '$new_file'\n" ); print( "Renaming '$file' to '$newFile'\n" );
rename( $file, $new_file ) or warn( "Can't rename '$file' to '$new_file'" ); rename( $file, $newFile ) or warn( "Can't rename '$file' to '$newFile'" );
} }
File::Find::find( \&renameImage, '.' ); File::Find::find( \&renameImage, '.' );
} }
if ( $zone_fix ) if ( $zoneFix )
{ {
require DBI; require DBI;
@ -254,7 +250,7 @@ if ( $zone_fix )
) or die( "Can't execute: ".$sth->errstr() ); ) or die( "Can't execute: ".$sth->errstr() );
} }
} }
if ( $migrate_events ) if ( $migrateEvents )
{ {
my $webUid = (getpwnam( ZM_WEB_USER ))[2]; my $webUid = (getpwnam( ZM_WEB_USER ))[2];
my $webGid = (getgrnam( ZM_WEB_USER ))[2]; my $webGid = (getgrnam( ZM_WEB_USER ))[2];
@ -372,21 +368,21 @@ if ( $version )
my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ ); my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ );
my $command = "mysqldump -h".$host; my $command = "mysqldump -h".$host;
$command .= " -P".$port if defined($port); $command .= " -P".$port if defined($port);
if ( $db_user ) if ( $dbUser )
{ {
$command .= " -u".$db_user; $command .= " -u".$dbUser;
if ( $db_pass ) if ( $dbPass )
{ {
$command .= " -p".$db_pass; $command .= " -p".$dbPass;
} }
} }
my $backup = "@ZM_TMPDIR@/".ZM_DB_NAME."-".$version.".dump"; my $backup = "@ZM_TMPDIR@/".ZM_DB_NAME."-".$version.".dump";
$command .= " --add-drop-table --databases ".ZM_DB_NAME." > ".$backup; $command .= " --add-drop-table --databases ".ZM_DB_NAME." > ".$backup;
print( "Creating backup to $backup. This may take several minutes.\n" ); print( "Creating backup to $backup. This may take several minutes.\n" );
print( "Executing '$command'\n" ) if ( DBG_LEVEL > 0 ); print( "Executing '$command'\n" ) if ( logDebugging() );
my $output = qx($command); my $output = qx($command);
my $status = $? >> 8; my $status = $? >> 8;
if ( $status || DBG_LEVEL > 0 ) if ( $status || logDebugging() )
{ {
chomp( $output ); chomp( $output );
print( "Output: $output\n" ); print( "Output: $output\n" );
@ -413,18 +409,18 @@ if ( $version )
my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ ); my ( $host, $port ) = ( ZM_DB_HOST =~ /^([^:]+)(?::(.+))?$/ );
my $command = "mysql -h".$host; my $command = "mysql -h".$host;
$command .= " -P".$port if defined($port); $command .= " -P".$port if defined($port);
if ( $db_user ) if ( $dbUser )
{ {
$command .= " -u".$db_user; $command .= " -u".$dbUser;
if ( $db_pass ) if ( $dbPass )
{ {
$command .= " -p".$db_pass; $command .= " -p".$dbPass;
} }
} }
$command .= " ".ZM_DB_NAME." < "; $command .= " ".ZM_DB_NAME." < ";
if ( $update_dir ) if ( $updateDir )
{ {
$command -= $update_dir; $command -= $updateDir;
} }
else else
{ {
@ -432,10 +428,10 @@ if ( $version )
} }
$command .= "/zm_update-".$version.".sql"; $command .= "/zm_update-".$version.".sql";
print( "Executing '$command'\n" ) if ( DBG_LEVEL > 0 ); print( "Executing '$command'\n" ) if ( logDebugging() );
my $output = qx($command); my $output = qx($command);
my $status = $? >> 8; my $status = $? >> 8;
if ( $status || DBG_LEVEL > 0 ) if ( $status || logDebugging() )
{ {
chomp( $output ); chomp( $output );
print( "Output: $output\n" ); print( "Output: $output\n" );
@ -603,8 +599,8 @@ if ( $version )
{ {
if ( $filter->{Query} =~ /op\d=&/ ) if ( $filter->{Query} =~ /op\d=&/ )
{ {
( my $new_query = $filter->{Query} ) =~ s/(op\d=)&/$1=&/g; ( my $newQuery = $filter->{Query} ) =~ s/(op\d=)&/$1=&/g;
$res = $sth->execute( $new_query, $filter->{Name} ) or die( "Can't execute: ".$sth->errstr() ); $res = $sth->execute( $newQuery, $filter->{Name} ) or die( "Can't execute: ".$sth->errstr() );
} }
} }
} }
@ -643,14 +639,14 @@ if ( $version )
} }
else else
{ {
my $lo_x = ($zone->{LoX} * ($zone->{Width}-1) ) / 100; my $loX = ($zone->{LoX} * ($zone->{Width}-1) ) / 100;
my $hi_x = ($zone->{HiX} * ($zone->{Width}-1) ) / 100; my $hiX = ($zone->{HiX} * ($zone->{Width}-1) ) / 100;
my $lo_y = ($zone->{LoY} * ($zone->{Height}-1) ) / 100; my $loY = ($zone->{LoY} * ($zone->{Height}-1) ) / 100;
my $hi_y = ($zone->{HiY} * ($zone->{Height}-1) ) / 100; my $hiY = ($zone->{HiY} * ($zone->{Height}-1) ) / 100;
my $area = (($hi_x-$lo_x)+1)*(($hi_y-$lo_y)+1); my $area = (($hiX-$loX)+1)*(($hiY-$loY)+1);
my $sql = "update Zones set NumCoords = 4, Coords = concat( round(?),',',round(?),' ',round(?),',',round(?),' ',round(?),',',round(?),' ',round(?),',',round(?) ), Area = round(?), MinAlarmPixels = round(?), MaxAlarmPixels = round(?), MinFilterPixels = round(?), MaxFilterPixels = round(?), MinBlobPixels = round(?), MaxBlobPixels = round(?) where Id = ?"; my $sql = "update Zones set NumCoords = 4, Coords = concat( round(?),',',round(?),' ',round(?),',',round(?),' ',round(?),',',round(?),' ',round(?),',',round(?) ), Area = round(?), MinAlarmPixels = round(?), MaxAlarmPixels = round(?), MinFilterPixels = round(?), MaxFilterPixels = round(?), MinBlobPixels = round(?), MaxBlobPixels = round(?) where Id = ?";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $lo_x, $lo_y, $hi_x, $lo_y, $hi_x, $hi_y, $lo_x, $hi_y, $area, ($zone->{MinAlarmPixels}*$area)/100, ($zone->{MaxAlarmPixels}*$area)/100, ($zone->{MinFilterPixels}*$area)/100, ($zone->{MaxFilterPixels}*$area)/100, ($zone->{MinBlobPixels}*$area)/100, ($zone->{MaxBlobPixels}*$area)/100, $zone->{Id} ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $loX, $loY, $hiX, $loY, $hiX, $hiY, $loX, $hiY, $area, ($zone->{MinAlarmPixels}*$area)/100, ($zone->{MaxAlarmPixels}*$area)/100, ($zone->{MinFilterPixels}*$area)/100, ($zone->{MaxFilterPixels}*$area)/100, ($zone->{MinBlobPixels}*$area)/100, ($zone->{MaxBlobPixels}*$area)/100, $zone->{Id} ) or die( "Can't execute: ".$sth->errstr() );
} }
} }
} }
@ -780,16 +776,16 @@ if ( $version )
my $sql = "select * from Filters"; my $sql = "select * from Filters";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); 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() ); my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
my @db_filters; my @dbFilters;
while( my $db_filter = $sth->fetchrow_hashref() ) while( my $dbFilter = $sth->fetchrow_hashref() )
{ {
push( @db_filters, $db_filter ); push( @dbFilters, $dbFilter );
} }
$sth->finish(); $sth->finish();
foreach my $db_filter ( @db_filters ) foreach my $dbFilter ( @dbFilters )
{ {
my %filter_terms; my %filter_terms;
foreach my $filter_parm ( split( '&', $db_filter->{Query} ) ) foreach my $filter_parm ( split( '&', $dbFilter->{Query} ) )
{ {
my( $key, $value ) = split( '=', $filter_parm, 2 ); my( $key, $value ) = split( '=', $filter_parm, 2 );
if ( $key ) if ( $key )
@ -820,33 +816,33 @@ if ( $version )
$filter->{sort_asc} = $filter_terms{sort_asc} if ( $filter_terms{sort_asc} ); $filter->{sort_asc} = $filter_terms{sort_asc} if ( $filter_terms{sort_asc} );
$filter->{limit} = $filter_terms{limit} if ( $filter_terms{limit} ); $filter->{limit} = $filter_terms{limit} if ( $filter_terms{limit} );
my $new_query = 'a:'.int(keys(%$filter)).':{s:5:"terms";a:'.int(@{$filter->{terms}}).':{'; my $newQuery = 'a:'.int(keys(%$filter)).':{s:5:"terms";a:'.int(@{$filter->{terms}}).':{';
my $i = 0; my $i = 0;
foreach my $term ( @{$filter->{terms}} ) foreach my $term ( @{$filter->{terms}} )
{ {
$new_query .= 'i:'.$i.';a:'.int(keys(%$term)).':{'; $newQuery .= 'i:'.$i.';a:'.int(keys(%$term)).':{';
while ( my ( $key, $val ) = each( %$term ) ) while ( my ( $key, $val ) = each( %$term ) )
{ {
$new_query .= 's:'.length($key).':"'.$key.'";'; $newQuery .= 's:'.length($key).':"'.$key.'";';
$new_query .= 's:'.length($val).':"'.$val.'";'; $newQuery .= 's:'.length($val).':"'.$val.'";';
} }
$new_query .= '}'; $newQuery .= '}';
$i++; $i++;
} }
$new_query .= '}'; $newQuery .= '}';
foreach my $field ( "sort_field", "sort_asc", "limit" ) foreach my $field ( "sort_field", "sort_asc", "limit" )
{ {
if ( defined($filter->{$field}) ) if ( defined($filter->{$field}) )
{ {
$new_query .= 's:'.length($field).':"'.$field.'";'; $newQuery .= 's:'.length($field).':"'.$field.'";';
$new_query .= 's:'.length($filter->{$field}).':"'.$filter->{$field}.'";'; $newQuery .= 's:'.length($filter->{$field}).':"'.$filter->{$field}.'";';
} }
} }
$new_query .= '}'; $newQuery .= '}';
my $sql = "update Filters set Query = ? where Name = ?"; my $sql = "update Filters set Query = ? where Name = ?";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( $new_query, $db_filter->{Name} ) or die( "Can't execute: ".$sth->errstr() ); my $res = $sth->execute( $newQuery, $dbFilter->{Name} ) or die( "Can't execute: ".$sth->errstr() );
} }
} }
@ -951,6 +947,12 @@ if ( $version )
} }
$cascade = !undef; $cascade = !undef;
} }
if ( $cascade || $version eq "1.24.4" )
{
# Patch the database
patchDB( $dbh, "1.24.4" );
$cascade = !undef;
}
if ( $cascade ) if ( $cascade )
{ {
my $installed_version = ZM_VERSION; my $installed_version = ZM_VERSION;

View File

@ -27,15 +27,6 @@
use strict; use strict;
use bytes; use bytes;
# ==========================================================================
#
# These are the elements you can edit to suit your installation
#
# ==========================================================================
use constant DBG_ID => "zmvideo"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
# ========================================================================== # ==========================================================================
# #
# You shouldn't need to change anything from here downwards # You shouldn't need to change anything from here downwards
@ -55,7 +46,7 @@ $ENV{PATH} = '/bin:/usr/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
my $event_id; my $event_id;
my $format = 'mpg'; my $format = 'mpg';

View File

@ -34,9 +34,6 @@ use bytes;
# #
# ========================================================================== # ==========================================================================
use constant DBG_ID => "zmwatch"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
use constant START_DELAY => 30; # To give everything else time to start use constant START_DELAY => 30; # To give everything else time to start
# ========================================================================== # ==========================================================================
@ -65,8 +62,8 @@ Usage: zmwatch.pl
exit( -1 ); exit( -1 );
} }
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
zmDbgSetSignal(); logSetSignal();
Info( "Watchdog starting\n" ); Info( "Watchdog starting\n" );
Info( "Watchdog pausing for ".START_DELAY." seconds\n" ); Info( "Watchdog pausing for ".START_DELAY." seconds\n" );

View File

@ -33,9 +33,6 @@ use bytes;
# #
# ========================================================================== # ==========================================================================
use constant DBG_ID => "zmx10"; # Tag that appears in debug to identify source
use constant DBG_LEVEL => 0; # 0 is errors, warnings and info only, > 0 for debug
use constant CAUSE_STRING => "X10"; # What gets written as the cause of any events use constant CAUSE_STRING => "X10"; # What gets written as the cause of any events
# ========================================================================== # ==========================================================================
@ -70,8 +67,8 @@ Parameters are :-
exit( -1 ); exit( -1 );
} }
zmDbgInit( DBG_ID, level=>DBG_LEVEL ); logInit();
zmDbgSetSignal(); logSetSignal();
my $command; my $command;
my $unit_code; my $unit_code;
@ -206,7 +203,7 @@ sub runServer
{ {
if ( $unit_code < 1 || $unit_code > 16 ) if ( $unit_code < 1 || $unit_code > 16 )
{ {
dPrint( DBG_ERROR, "Invalid unit code '$unit_code'\n" ); dPrint( ZoneMinder::Logger::ERROR, "Invalid unit code '$unit_code'\n" );
next; next;
} }
@ -238,14 +235,14 @@ sub runServer
{ {
if ( $device ) if ( $device )
{ {
dPrint( DBG_DEBUG, $unit_code." ".$device->{status}."\n" ); dPrint( ZoneMinder::Logger::DEBUG, $unit_code." ".$device->{status}."\n" );
} }
else else
{ {
foreach my $unit_code ( sort( keys(%device_hash) ) ) foreach my $unit_code ( sort( keys(%device_hash) ) )
{ {
my $device = $device_hash{$unit_code}; my $device = $device_hash{$unit_code};
dPrint( DBG_DEBUG, $unit_code." ".$device->{status}."\n" ); dPrint( ZoneMinder::Logger::DEBUG, $unit_code." ".$device->{status}."\n" );
} }
} }
} }
@ -255,19 +252,19 @@ sub runServer
} }
else else
{ {
dPrint( DBG_ERROR, "Invalid command '$command'\n" ); dPrint( ZoneMinder::Logger::ERROR, "Invalid command '$command'\n" );
} }
if ( defined($result) ) if ( defined($result) )
{ {
if ( 1 || $result ) if ( 1 || $result )
{ {
$device->{status} = uc($command); $device->{status} = uc($command);
dPrint( DBG_DEBUG, $device->{appliance}->address()." $command, ok\n" ); dPrint( ZoneMinder::Logger::DEBUG, $device->{appliance}->address()." $command, ok\n" );
#x10listen( new X10::Event( sprintf("%s %s", $device->{appliance}->address, uc($command) ) ) ); #x10listen( new X10::Event( sprintf("%s %s", $device->{appliance}->address, uc($command) ) ) );
} }
else else
{ {
dPrint( DBG_ERROR, $device->{appliance}->address()." $command, failed\n" ); dPrint( ZoneMinder::Logger::ERROR, $device->{appliance}->address()." $command, failed\n" );
} }
} }
close( CLIENT ); close( CLIENT );
@ -623,23 +620,23 @@ sub dPrint
{ {
print CLIENT @_ print CLIENT @_
} }
if ( $dbg_level == DBG_DEBUG ) if ( $dbg_level == ZoneMinder::Logger::DEBUG )
{ {
Debug( @_ ); Debug( @_ );
} }
elsif ( $dbg_level == DBG_INFO ) elsif ( $dbg_level == ZoneMinder::Logger::INFO )
{ {
Info( @_ ); Info( @_ );
} }
elsif ( $dbg_level == DBG_WARNING ) elsif ( $dbg_level == ZoneMinder::Logger::WARNING )
{ {
Warning( @_ ); Warning( @_ );
} }
elsif ( $dbg_level == DBG_ERROR ) elsif ( $dbg_level == ZoneMinder::Logger::ERROR )
{ {
Error( @_ ); Error( @_ );
} }
elsif ( $dbg_level == DBG_FATAL ) elsif ( $dbg_level == ZoneMinder::Logger::FATAL )
{ {
Fatal( @_ ); Fatal( @_ );
} }

View File

@ -29,13 +29,13 @@ zm_SOURCES = \
zm_coord.cpp \ zm_coord.cpp \
zm.cpp \ zm.cpp \
zm_db.cpp \ zm_db.cpp \
zm_debug.c \ zm_logger.cpp \
zm_event.cpp \ zm_event.cpp \
zm_exception.cpp \ zm_exception.cpp \
zm_file_camera.cpp \ zm_file_camera.cpp \
zm_ffmpeg_camera.cpp \ zm_ffmpeg_camera.cpp \
zm_image.cpp \ zm_image.cpp \
zm_jpeg.c \ zm_jpeg.cpp \
zm_local_camera.cpp \ zm_local_camera.cpp \
zm_monitor.cpp \ zm_monitor.cpp \
zm_ffmpeg.cpp \ zm_ffmpeg.cpp \
@ -66,7 +66,7 @@ zms_SOURCES = zms.cpp $(zm_SOURCES)
zmu_SOURCES = zmu.cpp $(zm_SOURCES) zmu_SOURCES = zmu.cpp $(zm_SOURCES)
zmf_SOURCES = zmf.cpp $(zm_SOURCES) zmf_SOURCES = zmf.cpp $(zm_SOURCES)
zmstreamer_SOURCES = zmstreamer.cpp $(zm_SOURCES) zmstreamer_SOURCES = zmstreamer.cpp $(zm_SOURCES)
zmfix_SOURCES = zmfix.cpp zm_config.cpp zm_regexp.cpp zm_debug.c zm_db.cpp zm.cpp zmfix_SOURCES = zmfix.cpp zm_config.cpp zm_regexp.cpp zm_logger.cpp zm_utils.cpp zm_db.cpp zm.cpp
noinst_HEADERS = \ noinst_HEADERS = \
jinclude.h \ jinclude.h \
@ -78,7 +78,7 @@ noinst_HEADERS = \
zm_config.h \ zm_config.h \
zm_coord.h \ zm_coord.h \
zm_db.h \ zm_db.h \
zm_debug.h \ zm_logger.h \
zm_event.h \ zm_event.h \
zm_exception.h \ zm_exception.h \
zmf.h \ zmf.h \

View File

@ -52,7 +52,7 @@ PROGRAMS = $(bin_PROGRAMS)
am__objects_1 = zm_box.$(OBJEXT) zm_buffer.$(OBJEXT) \ am__objects_1 = zm_box.$(OBJEXT) zm_buffer.$(OBJEXT) \
zm_camera.$(OBJEXT) zm_comms.$(OBJEXT) zm_config.$(OBJEXT) \ zm_camera.$(OBJEXT) zm_comms.$(OBJEXT) zm_config.$(OBJEXT) \
zm_coord.$(OBJEXT) zm.$(OBJEXT) zm_db.$(OBJEXT) \ zm_coord.$(OBJEXT) zm.$(OBJEXT) zm_db.$(OBJEXT) \
zm_debug.$(OBJEXT) zm_event.$(OBJEXT) zm_exception.$(OBJEXT) \ zm_logger.$(OBJEXT) zm_event.$(OBJEXT) zm_exception.$(OBJEXT) \
zm_file_camera.$(OBJEXT) zm_ffmpeg_camera.$(OBJEXT) \ zm_file_camera.$(OBJEXT) zm_ffmpeg_camera.$(OBJEXT) \
zm_image.$(OBJEXT) zm_jpeg.$(OBJEXT) zm_local_camera.$(OBJEXT) \ zm_image.$(OBJEXT) zm_jpeg.$(OBJEXT) zm_local_camera.$(OBJEXT) \
zm_monitor.$(OBJEXT) zm_ffmpeg.$(OBJEXT) zm_mpeg.$(OBJEXT) \ zm_monitor.$(OBJEXT) zm_ffmpeg.$(OBJEXT) zm_mpeg.$(OBJEXT) \
@ -74,8 +74,8 @@ am_zmf_OBJECTS = zmf.$(OBJEXT) $(am__objects_1)
zmf_OBJECTS = $(am_zmf_OBJECTS) zmf_OBJECTS = $(am_zmf_OBJECTS)
zmf_LDADD = $(LDADD) zmf_LDADD = $(LDADD)
am_zmfix_OBJECTS = zmfix.$(OBJEXT) zm_config.$(OBJEXT) \ am_zmfix_OBJECTS = zmfix.$(OBJEXT) zm_config.$(OBJEXT) \
zm_regexp.$(OBJEXT) zm_debug.$(OBJEXT) zm_db.$(OBJEXT) \ zm_regexp.$(OBJEXT) zm_logger.$(OBJEXT) zm_utils.$(OBJEXT) \
zm.$(OBJEXT) zm_db.$(OBJEXT) zm.$(OBJEXT)
zmfix_OBJECTS = $(am_zmfix_OBJECTS) zmfix_OBJECTS = $(am_zmfix_OBJECTS)
zmfix_LDADD = $(LDADD) zmfix_LDADD = $(LDADD)
am_zms_OBJECTS = zms.$(OBJEXT) $(am__objects_1) am_zms_OBJECTS = zms.$(OBJEXT) $(am__objects_1)
@ -91,10 +91,6 @@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles am__depfiles_maybe = depfiles
am__mv = mv -f am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX) CXXLD = $(CXX)
@ -264,13 +260,13 @@ zm_SOURCES = \
zm_coord.cpp \ zm_coord.cpp \
zm.cpp \ zm.cpp \
zm_db.cpp \ zm_db.cpp \
zm_debug.c \ zm_logger.cpp \
zm_event.cpp \ zm_event.cpp \
zm_exception.cpp \ zm_exception.cpp \
zm_file_camera.cpp \ zm_file_camera.cpp \
zm_ffmpeg_camera.cpp \ zm_ffmpeg_camera.cpp \
zm_image.cpp \ zm_image.cpp \
zm_jpeg.c \ zm_jpeg.cpp \
zm_local_camera.cpp \ zm_local_camera.cpp \
zm_monitor.cpp \ zm_monitor.cpp \
zm_ffmpeg.cpp \ zm_ffmpeg.cpp \
@ -301,7 +297,7 @@ zms_SOURCES = zms.cpp $(zm_SOURCES)
zmu_SOURCES = zmu.cpp $(zm_SOURCES) zmu_SOURCES = zmu.cpp $(zm_SOURCES)
zmf_SOURCES = zmf.cpp $(zm_SOURCES) zmf_SOURCES = zmf.cpp $(zm_SOURCES)
zmstreamer_SOURCES = zmstreamer.cpp $(zm_SOURCES) zmstreamer_SOURCES = zmstreamer.cpp $(zm_SOURCES)
zmfix_SOURCES = zmfix.cpp zm_config.cpp zm_regexp.cpp zm_debug.c zm_db.cpp zm.cpp zmfix_SOURCES = zmfix.cpp zm_config.cpp zm_regexp.cpp zm_logger.cpp zm_utils.cpp zm_db.cpp zm.cpp
noinst_HEADERS = \ noinst_HEADERS = \
jinclude.h \ jinclude.h \
zm_box.h \ zm_box.h \
@ -312,7 +308,7 @@ noinst_HEADERS = \
zm_config.h \ zm_config.h \
zm_coord.h \ zm_coord.h \
zm_db.h \ zm_db.h \
zm_debug.h \ zm_logger.h \
zm_event.h \ zm_event.h \
zm_exception.h \ zm_exception.h \
zmf.h \ zmf.h \
@ -356,7 +352,7 @@ EXTRA_DIST = \
all: all-am all: all-am
.SUFFIXES: .SUFFIXES:
.SUFFIXES: .c .cpp .o .obj .SUFFIXES: .cpp .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \ @for dep in $?; do \
case '$(am__configure_deps)' in \ case '$(am__configure_deps)' in \
@ -462,7 +458,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_config.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_config.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_coord.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_coord.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_db.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_db.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_debug.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_event.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_event.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_exception.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_exception.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_ffmpeg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_ffmpeg.Po@am__quote@
@ -471,6 +466,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_image.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_image.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_jpeg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_jpeg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_local_camera.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_local_camera.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_logger.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_monitor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_mpeg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_mpeg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_poly.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zm_poly.Po@am__quote@
@ -500,20 +496,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zmstreamer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zmstreamer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zmu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zmu.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.cpp.o: .cpp.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po

View File

@ -20,12 +20,8 @@
#ifndef ZM_H #ifndef ZM_H
#define ZM_H #define ZM_H
extern "C"
{
#include "zm_debug.h"
}
#include "zm_config.h" #include "zm_config.h"
#include "zm_logger.h"
extern "C" extern "C"
{ {

View File

@ -19,7 +19,7 @@
#include "zm_comms.h" #include "zm_comms.h"
#include "zm_debug.h" #include "zm_logger.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>

View File

@ -17,13 +17,14 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// //
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "zm.h" #include "zm.h"
#include "zm_db.h" #include "zm_db.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void zmLoadConfig() void zmLoadConfig()
{ {
FILE *cfg; FILE *cfg;
@ -31,7 +32,7 @@ void zmLoadConfig()
char *val; char *val;
if ( (cfg = fopen( ZM_CONFIG, "r")) == NULL ) if ( (cfg = fopen( ZM_CONFIG, "r")) == NULL )
{ {
Fatal("Can't open %s: %s", ZM_CONFIG, strerror(errno) ); Fatal( "Can't open %s: %s", ZM_CONFIG, strerror(errno) );
} }
while ( fgets( line, sizeof(line), cfg ) != NULL ) while ( fgets( line, sizeof(line), cfg ) != NULL )
{ {
@ -270,26 +271,6 @@ void Config::Load()
void Config::Assign() void Config::Assign()
{ {
ZM_CFG_ASSIGN_LIST ZM_CFG_ASSIGN_LIST
if ( extra_debug )
{
static char extra_level_env[PATH_MAX] = "";
static char extra_log_env[PATH_MAX] = "";
snprintf( extra_level_env, sizeof(extra_level_env), "ZM_DBG_LEVEL%s=%d", extra_debug_target, extra_debug_level );
if ( putenv( extra_level_env ) < 0 )
{
Error("Can't putenv %s: %s", extra_level_env, strerror(errno) );
}
snprintf( extra_log_env, sizeof(extra_log_env), "ZM_DBG_LOG%s=%s", extra_debug_target, extra_debug_log );
if ( putenv( extra_log_env ) < 0 )
{
Error("Can't putenv %s: %s", extra_log_env, strerror(errno) );
}
zmDbgReinit( extra_debug_target );
}
} }
const ConfigItem &Config::Item( int id ) const ConfigItem &Config::Item( int id )

View File

@ -17,6 +17,9 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// //
#ifndef ZM_CONFIG_H
#define ZM_CONFIG_H
#include "config.h" #include "config.h"
#include "zm_config_defines.h" #include "zm_config_defines.h"
@ -128,3 +131,5 @@ public:
}; };
extern Config config; extern Config config;
#endif // ZM_CONFIG_H

View File

@ -45,162 +45,174 @@
#define ZM_FFMPEG_INPUT_OPTIONS 41 #define ZM_FFMPEG_INPUT_OPTIONS 41
#define ZM_FFMPEG_OUTPUT_OPTIONS 42 #define ZM_FFMPEG_OUTPUT_OPTIONS 42
#define ZM_FFMPEG_FORMATS 43 #define ZM_FFMPEG_FORMATS 43
#define ZM_RECORD_EVENT_STATS 44 #define ZM_LOG_LEVEL_SYSLOG 44
#define ZM_RECORD_DIAG_IMAGES 45 #define ZM_LOG_LEVEL_FILE 45
#define ZM_EXTRA_DEBUG 46 #define ZM_LOG_LEVEL_WEBLOG 46
#define ZM_EXTRA_DEBUG_TARGET 47 #define ZM_LOG_LEVEL_DATABASE 47
#define ZM_EXTRA_DEBUG_LEVEL 48 #define ZM_LOG_DATABASE_LIMIT 48
#define ZM_EXTRA_DEBUG_LOG 49 #define ZM_LOG_DEBUG 49
#define ZM_DUMP_CORES 50 #define ZM_LOG_DEBUG_TARGET 50
#define ZM_PATH_MAP 51 #define ZM_LOG_DEBUG_LEVEL 51
#define ZM_PATH_SOCKS 52 #define ZM_LOG_DEBUG_FILE 52
#define ZM_PATH_LOGS 53 #define ZM_LOG_CHECK_PERIOD 53
#define ZM_PATH_SWAP 54 #define ZM_LOG_ALERT_WAR_COUNT 54
#define ZM_WEB_TITLE_PREFIX 55 #define ZM_LOG_ALERT_ERR_COUNT 55
#define ZM_WEB_RESIZE_CONSOLE 56 #define ZM_LOG_ALERT_FAT_COUNT 56
#define ZM_WEB_POPUP_ON_ALARM 57 #define ZM_LOG_ALARM_WAR_COUNT 57
#define ZM_OPT_X10 58 #define ZM_LOG_ALARM_ERR_COUNT 58
#define ZM_X10_DEVICE 59 #define ZM_LOG_ALARM_FAT_COUNT 59
#define ZM_X10_HOUSE_CODE 60 #define ZM_RECORD_EVENT_STATS 60
#define ZM_X10_DB_RELOAD_INTERVAL 61 #define ZM_RECORD_DIAG_IMAGES 61
#define ZM_WEB_SOUND_ON_ALARM 62 #define ZM_DUMP_CORES 62
#define ZM_WEB_ALARM_SOUND 63 #define ZM_PATH_MAP 63
#define ZM_WEB_COMPACT_MONTAGE 64 #define ZM_PATH_SOCKS 64
#define ZM_OPT_FAST_DELETE 65 #define ZM_PATH_LOGS 65
#define ZM_STRICT_VIDEO_CONFIG 66 #define ZM_PATH_SWAP 66
#define ZM_V4L2_CAPTURE_FIELDS 67 #define ZM_WEB_TITLE_PREFIX 67
#define ZM_SIGNAL_CHECK_POINTS 68 #define ZM_WEB_RESIZE_CONSOLE 68
#define ZM_V4L_MULTI_BUFFER 69 #define ZM_WEB_POPUP_ON_ALARM 69
#define ZM_CAPTURES_PER_FRAME 70 #define ZM_OPT_X10 70
#define ZM_FILTER_RELOAD_DELAY 71 #define ZM_X10_DEVICE 71
#define ZM_FILTER_EXECUTE_INTERVAL 72 #define ZM_X10_HOUSE_CODE 72
#define ZM_OPT_UPLOAD 73 #define ZM_X10_DB_RELOAD_INTERVAL 73
#define ZM_UPLOAD_ARCH_FORMAT 74 #define ZM_WEB_SOUND_ON_ALARM 74
#define ZM_UPLOAD_ARCH_COMPRESS 75 #define ZM_WEB_ALARM_SOUND 75
#define ZM_UPLOAD_ARCH_ANALYSE 76 #define ZM_WEB_COMPACT_MONTAGE 76
#define ZM_UPLOAD_FTP_HOST 77 #define ZM_OPT_FAST_DELETE 77
#define ZM_UPLOAD_FTP_USER 78 #define ZM_STRICT_VIDEO_CONFIG 78
#define ZM_UPLOAD_FTP_PASS 79 #define ZM_V4L2_CAPTURE_FIELDS 79
#define ZM_UPLOAD_FTP_LOC_DIR 80 #define ZM_SIGNAL_CHECK_POINTS 80
#define ZM_UPLOAD_FTP_REM_DIR 81 #define ZM_V4L_MULTI_BUFFER 81
#define ZM_UPLOAD_FTP_TIMEOUT 82 #define ZM_CAPTURES_PER_FRAME 82
#define ZM_UPLOAD_FTP_PASSIVE 83 #define ZM_FILTER_RELOAD_DELAY 83
#define ZM_UPLOAD_FTP_DEBUG 84 #define ZM_FILTER_EXECUTE_INTERVAL 84
#define ZM_OPT_EMAIL 85 #define ZM_OPT_UPLOAD 85
#define ZM_EMAIL_ADDRESS 86 #define ZM_UPLOAD_ARCH_FORMAT 86
#define ZM_EMAIL_TEXT 87 #define ZM_UPLOAD_ARCH_COMPRESS 87
#define ZM_EMAIL_SUBJECT 88 #define ZM_UPLOAD_ARCH_ANALYSE 88
#define ZM_EMAIL_BODY 89 #define ZM_UPLOAD_FTP_HOST 89
#define ZM_OPT_MESSAGE 90 #define ZM_UPLOAD_FTP_USER 90
#define ZM_MESSAGE_ADDRESS 91 #define ZM_UPLOAD_FTP_PASS 91
#define ZM_MESSAGE_TEXT 92 #define ZM_UPLOAD_FTP_LOC_DIR 92
#define ZM_MESSAGE_SUBJECT 93 #define ZM_UPLOAD_FTP_REM_DIR 93
#define ZM_MESSAGE_BODY 94 #define ZM_UPLOAD_FTP_TIMEOUT 94
#define ZM_NEW_MAIL_MODULES 95 #define ZM_UPLOAD_FTP_PASSIVE 95
#define ZM_EMAIL_HOST 96 #define ZM_UPLOAD_FTP_DEBUG 96
#define ZM_FROM_EMAIL 97 #define ZM_OPT_EMAIL 97
#define ZM_URL 98 #define ZM_EMAIL_ADDRESS 98
#define ZM_MAX_RESTART_DELAY 99 #define ZM_EMAIL_TEXT 99
#define ZM_WATCH_CHECK_INTERVAL 100 #define ZM_EMAIL_SUBJECT 100
#define ZM_WATCH_MAX_DELAY 101 #define ZM_EMAIL_BODY 101
#define ZM_RUN_AUDIT 102 #define ZM_OPT_MESSAGE 102
#define ZM_AUDIT_CHECK_INTERVAL 103 #define ZM_MESSAGE_ADDRESS 103
#define ZM_FORCED_ALARM_SCORE 104 #define ZM_MESSAGE_TEXT 104
#define ZM_BULK_FRAME_INTERVAL 105 #define ZM_MESSAGE_SUBJECT 105
#define ZM_EVENT_CLOSE_MODE 106 #define ZM_MESSAGE_BODY 106
#define ZM_FORCE_CLOSE_EVENTS 107 #define ZM_NEW_MAIL_MODULES 107
#define ZM_CREATE_ANALYSIS_IMAGES 108 #define ZM_EMAIL_HOST 108
#define ZM_WEIGHTED_ALARM_CENTRES 109 #define ZM_FROM_EMAIL 109
#define ZM_EVENT_IMAGE_DIGITS 110 #define ZM_URL 110
#define ZM_DEFAULT_ASPECT_RATIO 111 #define ZM_MAX_RESTART_DELAY 111
#define ZM_USER_SELF_EDIT 112 #define ZM_WATCH_CHECK_INTERVAL 112
#define ZM_OPT_FRAME_SERVER 113 #define ZM_WATCH_MAX_DELAY 113
#define ZM_FRAME_SOCKET_SIZE 114 #define ZM_RUN_AUDIT 114
#define ZM_OPT_CONTROL 115 #define ZM_AUDIT_CHECK_INTERVAL 115
#define ZM_OPT_TRIGGERS 116 #define ZM_FORCED_ALARM_SCORE 116
#define ZM_CHECK_FOR_UPDATES 117 #define ZM_BULK_FRAME_INTERVAL 117
#define ZM_UPDATE_CHECK_PROXY 118 #define ZM_EVENT_CLOSE_MODE 118
#define ZM_SHM_KEY 119 #define ZM_FORCE_CLOSE_EVENTS 119
#define ZM_WEB_REFRESH_METHOD 120 #define ZM_CREATE_ANALYSIS_IMAGES 120
#define ZM_WEB_EVENT_SORT_FIELD 121 #define ZM_WEIGHTED_ALARM_CENTRES 121
#define ZM_WEB_EVENT_SORT_ORDER 122 #define ZM_EVENT_IMAGE_DIGITS 122
#define ZM_WEB_EVENTS_PER_PAGE 123 #define ZM_DEFAULT_ASPECT_RATIO 123
#define ZM_WEB_LIST_THUMBS 124 #define ZM_USER_SELF_EDIT 124
#define ZM_WEB_LIST_THUMB_WIDTH 125 #define ZM_OPT_FRAME_SERVER 125
#define ZM_WEB_LIST_THUMB_HEIGHT 126 #define ZM_FRAME_SOCKET_SIZE 126
#define ZM_WEB_USE_OBJECT_TAGS 127 #define ZM_OPT_CONTROL 127
#define ZM_WEB_H_REFRESH_MAIN 128 #define ZM_OPT_TRIGGERS 128
#define ZM_WEB_H_REFRESH_CYCLE 129 #define ZM_CHECK_FOR_UPDATES 129
#define ZM_WEB_H_REFRESH_IMAGE 130 #define ZM_UPDATE_CHECK_PROXY 130
#define ZM_WEB_H_REFRESH_STATUS 131 #define ZM_SHM_KEY 131
#define ZM_WEB_H_REFRESH_EVENTS 132 #define ZM_WEB_REFRESH_METHOD 132
#define ZM_WEB_H_CAN_STREAM 133 #define ZM_WEB_EVENT_SORT_FIELD 133
#define ZM_WEB_H_STREAM_METHOD 134 #define ZM_WEB_EVENT_SORT_ORDER 134
#define ZM_WEB_H_DEFAULT_SCALE 135 #define ZM_WEB_EVENTS_PER_PAGE 135
#define ZM_WEB_H_DEFAULT_RATE 136 #define ZM_WEB_LIST_THUMBS 136
#define ZM_WEB_H_VIDEO_BITRATE 137 #define ZM_WEB_LIST_THUMB_WIDTH 137
#define ZM_WEB_H_VIDEO_MAXFPS 138 #define ZM_WEB_LIST_THUMB_HEIGHT 138
#define ZM_WEB_H_SCALE_THUMBS 139 #define ZM_WEB_USE_OBJECT_TAGS 139
#define ZM_WEB_H_EVENTS_VIEW 140 #define ZM_WEB_H_REFRESH_MAIN 140
#define ZM_WEB_H_SHOW_PROGRESS 141 #define ZM_WEB_H_REFRESH_CYCLE 141
#define ZM_WEB_H_AJAX_TIMEOUT 142 #define ZM_WEB_H_REFRESH_IMAGE 142
#define ZM_WEB_M_REFRESH_MAIN 143 #define ZM_WEB_H_REFRESH_STATUS 143
#define ZM_WEB_M_REFRESH_CYCLE 144 #define ZM_WEB_H_REFRESH_EVENTS 144
#define ZM_WEB_M_REFRESH_IMAGE 145 #define ZM_WEB_H_CAN_STREAM 145
#define ZM_WEB_M_REFRESH_STATUS 146 #define ZM_WEB_H_STREAM_METHOD 146
#define ZM_WEB_M_REFRESH_EVENTS 147 #define ZM_WEB_H_DEFAULT_SCALE 147
#define ZM_WEB_M_CAN_STREAM 148 #define ZM_WEB_H_DEFAULT_RATE 148
#define ZM_WEB_M_STREAM_METHOD 149 #define ZM_WEB_H_VIDEO_BITRATE 149
#define ZM_WEB_M_DEFAULT_SCALE 150 #define ZM_WEB_H_VIDEO_MAXFPS 150
#define ZM_WEB_M_DEFAULT_RATE 151 #define ZM_WEB_H_SCALE_THUMBS 151
#define ZM_WEB_M_VIDEO_BITRATE 152 #define ZM_WEB_H_EVENTS_VIEW 152
#define ZM_WEB_M_VIDEO_MAXFPS 153 #define ZM_WEB_H_SHOW_PROGRESS 153
#define ZM_WEB_M_SCALE_THUMBS 154 #define ZM_WEB_H_AJAX_TIMEOUT 154
#define ZM_WEB_M_EVENTS_VIEW 155 #define ZM_WEB_M_REFRESH_MAIN 155
#define ZM_WEB_M_SHOW_PROGRESS 156 #define ZM_WEB_M_REFRESH_CYCLE 156
#define ZM_WEB_M_AJAX_TIMEOUT 157 #define ZM_WEB_M_REFRESH_IMAGE 157
#define ZM_WEB_L_REFRESH_MAIN 158 #define ZM_WEB_M_REFRESH_STATUS 158
#define ZM_WEB_L_REFRESH_CYCLE 159 #define ZM_WEB_M_REFRESH_EVENTS 159
#define ZM_WEB_L_REFRESH_IMAGE 160 #define ZM_WEB_M_CAN_STREAM 160
#define ZM_WEB_L_REFRESH_STATUS 161 #define ZM_WEB_M_STREAM_METHOD 161
#define ZM_WEB_L_REFRESH_EVENTS 162 #define ZM_WEB_M_DEFAULT_SCALE 162
#define ZM_WEB_L_CAN_STREAM 163 #define ZM_WEB_M_DEFAULT_RATE 163
#define ZM_WEB_L_STREAM_METHOD 164 #define ZM_WEB_M_VIDEO_BITRATE 164
#define ZM_WEB_L_DEFAULT_SCALE 165 #define ZM_WEB_M_VIDEO_MAXFPS 165
#define ZM_WEB_L_DEFAULT_RATE 166 #define ZM_WEB_M_SCALE_THUMBS 166
#define ZM_WEB_L_VIDEO_BITRATE 167 #define ZM_WEB_M_EVENTS_VIEW 167
#define ZM_WEB_L_VIDEO_MAXFPS 168 #define ZM_WEB_M_SHOW_PROGRESS 168
#define ZM_WEB_L_SCALE_THUMBS 169 #define ZM_WEB_M_AJAX_TIMEOUT 169
#define ZM_WEB_L_EVENTS_VIEW 170 #define ZM_WEB_L_REFRESH_MAIN 170
#define ZM_WEB_L_SHOW_PROGRESS 171 #define ZM_WEB_L_REFRESH_CYCLE 171
#define ZM_WEB_L_AJAX_TIMEOUT 172 #define ZM_WEB_L_REFRESH_IMAGE 172
#define ZM_WEB_P_CAN_STREAM 173 #define ZM_WEB_L_REFRESH_STATUS 173
#define ZM_WEB_P_STREAM_METHOD 174 #define ZM_WEB_L_REFRESH_EVENTS 174
#define ZM_WEB_P_DEFAULT_SCALE 175 #define ZM_WEB_L_CAN_STREAM 175
#define ZM_WEB_P_DEFAULT_RATE 176 #define ZM_WEB_L_STREAM_METHOD 176
#define ZM_WEB_P_VIDEO_BITRATE 177 #define ZM_WEB_L_DEFAULT_SCALE 177
#define ZM_WEB_P_VIDEO_MAXFPS 178 #define ZM_WEB_L_DEFAULT_RATE 178
#define ZM_WEB_P_SCALE_THUMBS 179 #define ZM_WEB_L_VIDEO_BITRATE 179
#define ZM_WEB_P_AJAX_TIMEOUT 180 #define ZM_WEB_L_VIDEO_MAXFPS 180
#define ZM_DYN_LAST_VERSION 181 #define ZM_WEB_L_SCALE_THUMBS 181
#define ZM_DYN_CURR_VERSION 182 #define ZM_WEB_L_EVENTS_VIEW 182
#define ZM_DYN_DB_VERSION 183 #define ZM_WEB_L_SHOW_PROGRESS 183
#define ZM_DYN_LAST_CHECK 184 #define ZM_WEB_L_AJAX_TIMEOUT 184
#define ZM_DYN_NEXT_REMINDER 185 #define ZM_WEB_P_CAN_STREAM 185
#define ZM_DYN_DONATE_REMINDER_TIME 186 #define ZM_WEB_P_STREAM_METHOD 186
#define ZM_DYN_SHOW_DONATE_REMINDER 187 #define ZM_WEB_P_DEFAULT_SCALE 187
#define ZM_EYEZM_DEBUG 188 #define ZM_WEB_P_DEFAULT_RATE 188
#define ZM_EYEZM_LOG_TO_FILE 189 #define ZM_WEB_P_VIDEO_BITRATE 189
#define ZM_EYEZM_LOG_FILE 190 #define ZM_WEB_P_VIDEO_MAXFPS 190
#define ZM_EYEZM_EVENT_VCODEC 191 #define ZM_WEB_P_SCALE_THUMBS 191
#define ZM_EYEZM_FEED_VCODEC 192 #define ZM_WEB_P_AJAX_TIMEOUT 192
#define ZM_EYEZM_H264_DEFAULT_BR 193 #define ZM_DYN_LAST_VERSION 193
#define ZM_EYEZM_H264_DEFAULT_EVBR 194 #define ZM_DYN_CURR_VERSION 194
#define ZM_EYEZM_H264_TIMEOUT 195 #define ZM_DYN_DB_VERSION 195
#define ZM_EYEZM_SEG_DURATION 196 #define ZM_DYN_LAST_CHECK 196
#define ZM_DYN_NEXT_REMINDER 197
#define ZM_DYN_DONATE_REMINDER_TIME 198
#define ZM_DYN_SHOW_DONATE_REMINDER 199
#define ZM_EYEZM_DEBUG 200
#define ZM_EYEZM_LOG_TO_FILE 201
#define ZM_EYEZM_LOG_FILE 202
#define ZM_EYEZM_EVENT_VCODEC 203
#define ZM_EYEZM_FEED_VCODEC 204
#define ZM_EYEZM_H264_DEFAULT_BR 205
#define ZM_EYEZM_H264_DEFAULT_EVBR 206
#define ZM_EYEZM_H264_TIMEOUT 207
#define ZM_EYEZM_SEG_DURATION 208
#define ZM_MAX_CFG_ID 196 #define ZM_MAX_CFG_ID 208
#define ZM_CFG_DECLARE_LIST \ #define ZM_CFG_DECLARE_LIST \
const char *lang_default;\ const char *lang_default;\
@ -247,12 +259,24 @@
const char *ffmpeg_input_options;\ const char *ffmpeg_input_options;\
const char *ffmpeg_output_options;\ const char *ffmpeg_output_options;\
const char *ffmpeg_formats;\ const char *ffmpeg_formats;\
int log_level_syslog;\
int log_level_file;\
int log_level_weblog;\
int log_level_database;\
const char *log_database_limit;\
bool log_debug;\
const char *log_debug_target;\
int log_debug_level;\
const char *log_debug_file;\
int log_check_period;\
int log_alert_war_count;\
int log_alert_err_count;\
int log_alert_fat_count;\
int log_alarm_war_count;\
int log_alarm_err_count;\
int log_alarm_fat_count;\
bool record_event_stats;\ bool record_event_stats;\
bool record_diag_images;\ bool record_diag_images;\
bool extra_debug;\
const char *extra_debug_target;\
int extra_debug_level;\
const char *extra_debug_log;\
bool dump_cores;\ bool dump_cores;\
const char *path_map;\ const char *path_map;\
const char *path_socks;\ const char *path_socks;\
@ -447,12 +471,24 @@
ffmpeg_input_options = (const char *)config.Item( ZM_FFMPEG_INPUT_OPTIONS );\ ffmpeg_input_options = (const char *)config.Item( ZM_FFMPEG_INPUT_OPTIONS );\
ffmpeg_output_options = (const char *)config.Item( ZM_FFMPEG_OUTPUT_OPTIONS );\ ffmpeg_output_options = (const char *)config.Item( ZM_FFMPEG_OUTPUT_OPTIONS );\
ffmpeg_formats = (const char *)config.Item( ZM_FFMPEG_FORMATS );\ ffmpeg_formats = (const char *)config.Item( ZM_FFMPEG_FORMATS );\
log_level_syslog = (int)config.Item( ZM_LOG_LEVEL_SYSLOG );\
log_level_file = (int)config.Item( ZM_LOG_LEVEL_FILE );\
log_level_weblog = (int)config.Item( ZM_LOG_LEVEL_WEBLOG );\
log_level_database = (int)config.Item( ZM_LOG_LEVEL_DATABASE );\
log_database_limit = (const char *)config.Item( ZM_LOG_DATABASE_LIMIT );\
log_debug = (bool)config.Item( ZM_LOG_DEBUG );\
log_debug_target = (const char *)config.Item( ZM_LOG_DEBUG_TARGET );\
log_debug_level = (int)config.Item( ZM_LOG_DEBUG_LEVEL );\
log_debug_file = (const char *)config.Item( ZM_LOG_DEBUG_FILE );\
log_check_period = (int)config.Item( ZM_LOG_CHECK_PERIOD );\
log_alert_war_count = (int)config.Item( ZM_LOG_ALERT_WAR_COUNT );\
log_alert_err_count = (int)config.Item( ZM_LOG_ALERT_ERR_COUNT );\
log_alert_fat_count = (int)config.Item( ZM_LOG_ALERT_FAT_COUNT );\
log_alarm_war_count = (int)config.Item( ZM_LOG_ALARM_WAR_COUNT );\
log_alarm_err_count = (int)config.Item( ZM_LOG_ALARM_ERR_COUNT );\
log_alarm_fat_count = (int)config.Item( ZM_LOG_ALARM_FAT_COUNT );\
record_event_stats = (bool)config.Item( ZM_RECORD_EVENT_STATS );\ record_event_stats = (bool)config.Item( ZM_RECORD_EVENT_STATS );\
record_diag_images = (bool)config.Item( ZM_RECORD_DIAG_IMAGES );\ record_diag_images = (bool)config.Item( ZM_RECORD_DIAG_IMAGES );\
extra_debug = (bool)config.Item( ZM_EXTRA_DEBUG );\
extra_debug_target = (const char *)config.Item( ZM_EXTRA_DEBUG_TARGET );\
extra_debug_level = (int)config.Item( ZM_EXTRA_DEBUG_LEVEL );\
extra_debug_log = (const char *)config.Item( ZM_EXTRA_DEBUG_LOG );\
dump_cores = (bool)config.Item( ZM_DUMP_CORES );\ dump_cores = (bool)config.Item( ZM_DUMP_CORES );\
path_map = (const char *)config.Item( ZM_PATH_MAP );\ path_map = (const char *)config.Item( ZM_PATH_MAP );\
path_socks = (const char *)config.Item( ZM_PATH_SOCKS );\ path_socks = (const char *)config.Item( ZM_PATH_SOCKS );\

View File

@ -25,6 +25,8 @@
MYSQL dbconn; MYSQL dbconn;
int zmDbConnected = false;
void zmDbConnect() void zmDbConnect()
{ {
if ( !mysql_init( &dbconn ) ) if ( !mysql_init( &dbconn ) )
@ -56,5 +58,6 @@ void zmDbConnect()
Error( "Can't select database: %s", mysql_error( &dbconn ) ); Error( "Can't select database: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) ); exit( mysql_errno( &dbconn ) );
} }
zmDbConnected = true;
} }

View File

@ -22,10 +22,16 @@
#include <mysql/mysql.h> #include <mysql/mysql.h>
#include "zm.h" #ifdef __cplusplus
extern "C" {
#endif
extern MYSQL dbconn; extern MYSQL dbconn;
extern int zmDbConnected;
void zmDbConnect(); void zmDbConnect();
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // ZM_DB_H #endif // ZM_DB_H

View File

@ -1,470 +0,0 @@
/*
* ZoneMinder Debug Implementation, $Date$, $Revision$
* Copyright (C) 2001-2008 Philip Coombes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <syslog.h>
#include <signal.h>
#include <stdarg.h>
#include <errno.h>
#include "zm_debug.h"
int zmDbgLevel = 0;
static char dbgSyslog[64];
static char dbgName[64];
static char dbgId[64];
static char dbgLog[PATH_MAX] = "";
static FILE *dbgLogFP = (FILE *)NULL;
static int dbgPrint = FALSE;
static int dbgFlush = FALSE;
static int dbgRuntime = FALSE;
static int dbgAddLogId = FALSE;
static struct timeval dbgStart;
static int dbgRunning = FALSE;
const char *zmDbgName()
{
return( dbgName );
}
void zmUsrHandler( int sig )
{
if( sig == SIGUSR1)
{
if ( zmDbgLevel < 9 )
{
zmDbgLevel++;
}
}
else if ( sig == SIGUSR2 )
{
if( zmDbgLevel > -3 )
{
zmDbgLevel--;
}
}
Info( "Debug Level Changed to %d", zmDbgLevel );
}
int zmGetDebugEnv()
{
char envName[128];
char *envPtr = 0;
envPtr = getenv( "ZM_DBG_PRINT" );
if ( envPtr == (char *)NULL )
{
dbgPrint = FALSE;
}
else
{
dbgPrint = atoi( envPtr );
}
envPtr = getenv( "ZM_DBG_FLUSH" );
if ( envPtr == (char *)NULL )
{
dbgFlush = FALSE;
}
else
{
dbgFlush = atoi( envPtr );
}
envPtr = getenv( "ZM_DBG_RUNTIME" );
if ( envPtr == (char *)NULL )
{
dbgRuntime = FALSE;
}
else
{
dbgRuntime = atoi( envPtr );
}
envPtr = NULL;
sprintf( envName, "ZM_DBG_LEVEL_%s_%s", dbgName, dbgId );
envPtr = getenv(envName);
if ( envPtr == (char *)NULL )
{
sprintf( envName, "ZM_DBG_LEVEL_%s", dbgName );
envPtr = getenv(envName);
if ( envPtr == (char *)NULL )
{
sprintf( envName, "ZM_DBG_LEVEL" );
envPtr = getenv(envName);
}
}
if ( envPtr != (char *)NULL )
{
zmDbgLevel = atoi(envPtr);
}
envPtr = NULL;
sprintf( envName, "ZM_DBG_LOG_%s_%s", dbgName, dbgId );
envPtr = getenv(envName);
if ( envPtr == (char *)NULL )
{
sprintf( envName, "ZM_DBG_LOG_%s", dbgName );
envPtr = getenv(envName);
if ( envPtr == (char *)NULL )
{
sprintf( envName, "ZM_DBG_LOG" );
envPtr = getenv(envName);
}
}
if ( envPtr != (char *)NULL )
{
/* If we do not want to add a pid to the debug logs
* which is the default, and original method
*/
if ( envPtr[strlen(envPtr)-1] == '+' )
{
/* remove the + character from the string */
envPtr[strlen(envPtr)-1] = '\0';
dbgAddLogId = TRUE;
}
if ( dbgAddLogId == FALSE )
{
strncpy( dbgLog, envPtr, sizeof(dbgLog) );
}
else
{
snprintf( dbgLog, sizeof(dbgLog), "%s.%05d", envPtr, getpid() );
}
}
return( 0 );
}
int zmDebugPrepareLog()
{
FILE *tempLogFP = NULL;
if ( dbgLogFP )
{
fflush( dbgLogFP );
if ( fclose(dbgLogFP) == -1 )
{
Error( "fclose(), error = %s",strerror(errno) );
return( -1 );
}
dbgLogFP = (FILE *)NULL;
}
if ( ( dbgAddLogId == FALSE && dbgLog[0] ) && ( dbgLog[strlen(dbgLog)-1] == '~' ) )
{
dbgLog[strlen(dbgLog)-1] = '\0';
if ( (tempLogFP = fopen(dbgLog, "r")) != NULL )
{
char oldLogPath[256];
sprintf( oldLogPath, "%s.old", dbgLog );
rename( dbgLog, oldLogPath );
fclose( tempLogFP );
}
}
if( dbgLog[0] && (dbgLogFP = fopen(dbgLog,"w")) == (FILE *)NULL )
{
Error( "fopen() for %s, error = %s", dbgLog, strerror(errno) );
return( -1 );
}
return( 0 );
}
int zmDebugInitialise( const char *name, const char *id, int level )
{
int status;
gettimeofday( &dbgStart, NULL );
strncpy( dbgName, name, sizeof(dbgName) );
strncpy( dbgId, id, sizeof(dbgId) );
zmDbgLevel = level;
/* Now set up the syslog stuff */
if ( dbgId[0] )
snprintf( dbgSyslog, sizeof(dbgSyslog), "%s_%s", dbgName, dbgId );
else
strncpy( dbgSyslog, dbgName, sizeof(dbgSyslog) );
(void) openlog( dbgSyslog, LOG_PID|LOG_NDELAY, LOG_LOCAL1 );
dbgLogFP = (FILE *)NULL;
if( (status = zmGetDebugEnv() ) < 0)
{
Error( "Debug Environment Error, status = %d", status );
return( -1 );
}
zmDebugPrepareLog();
Info( "Debug Level = %d, Debug Log = %s", zmDbgLevel, dbgLog[0]?dbgLog:"<none>" );
{
struct sigaction action;
memset( &action, 0, sizeof(action) );
action.sa_handler = zmUsrHandler;
action.sa_flags = SA_RESTART;
if ( sigaction( SIGUSR1, &action, 0 ) < 0 )
{
Error( "sigaction(), error = %s", strerror(errno) );
return( -1 );
}
if ( sigaction( SIGUSR2, &action, 0 ) < 0)
{
Error( "sigaction(), error = %s", strerror(errno) );
return( -1 );
}
}
dbgRunning = TRUE;
return( 0 );
}
int zmDbgInit( const char *name, const char *id, int level )
{
return( zmDebugInitialise( name, id, level ) );
}
int zmDebugReinitialise( const char *target )
{
int status;
int reinit = FALSE;
char buffer[64];
if ( target )
{
snprintf( buffer, sizeof(buffer), "_%s_%s", dbgName, dbgId );
if ( strcmp( target, buffer ) == 0 )
{
reinit = TRUE;
}
else
{
snprintf( buffer, sizeof(buffer), "_%s", dbgName );
if ( strcmp( target, buffer ) == 0 )
{
reinit = TRUE;
}
else
{
if ( strcmp( target, "" ) == 0 )
{
reinit = TRUE;
}
}
}
}
if ( reinit )
{
if ( (status = zmGetDebugEnv() ) < 0 )
{
Error( "Debug Environment Error, status = %d", status );
return( -1 );
}
zmDebugPrepareLog();
Info( "New Debug Level = %d, New Debug Log = %s", zmDbgLevel, dbgLog[0]?dbgLog:"<none>" );
}
return( 0 );
}
int zmDbgReinit( const char *target )
{
return( zmDebugReinitialise( target ) );
}
int zmDebugTerminate()
{
Debug( 1, "Terminating Debug" );
fflush( dbgLogFP );
if ( fclose(dbgLogFP) == -1 )
{
Error( "fclose(), error = %s", strerror(errno) );
return( -1 );
}
dbgLogFP = (FILE *)NULL;
(void) closelog();
dbgRunning = FALSE;
return( 0 );
}
int zmDbgTerm()
{
return( zmDebugTerminate() );
}
void zmDbgSubtractTime( struct timeval * const tp1, struct timeval * const tp2 )
{
tp1->tv_sec -= tp2->tv_sec;
if ( tp1->tv_usec <= tp2->tv_usec )
{
tp1->tv_sec--;
tp1->tv_usec = 1000000 - (tp2->tv_usec - tp1->tv_usec);
}
else
{
tp1->tv_usec = tp1->tv_usec - tp2->tv_usec;
}
}
void zmDbgOutput( int hex, const char * const file, const int line, const int level, const char *fstring, ... )
{
char classString[4];
char timeString[64];
char dbgString[8192];
va_list argPtr;
int logCode;
struct timeval timeVal;
switch ( level )
{
case ZM_DBG_INF:
strncpy( classString, "INF", sizeof(classString) );
break;
case ZM_DBG_WAR:
strncpy( classString, "WAR", sizeof(classString) );
break;
case ZM_DBG_ERR:
strncpy( classString, "ERR", sizeof(classString) );
break;
case ZM_DBG_FAT:
strncpy( classString, "FAT", sizeof(classString) );
break;
case ZM_DBG_PNC:
strncpy( classString, "PNC", sizeof(classString) );
break;
default:
if ( level > 0 && level <= 9 )
{
snprintf( classString, sizeof(classString), "DB%d", level );
}
else
{
Error( "Unknown Error Level %d", level );
}
break;
}
gettimeofday( &timeVal, NULL );
if ( dbgRuntime )
{
zmDbgSubtractTime( &timeVal, &dbgStart );
snprintf( timeString, sizeof(timeString), "%ld.%03ld", timeVal.tv_sec, timeVal.tv_usec/1000 );
}
else
{
char *timePtr = timeString;
timePtr += strftime( timePtr, sizeof(timeString), "%x %H:%M:%S", localtime(&timeVal.tv_sec) );
snprintf( timePtr, sizeof(timeString)-(timePtr-timeString), ".%06ld", timeVal.tv_usec );
}
char *dbgPtr = dbgString;
dbgPtr += snprintf( dbgPtr, sizeof(dbgString), "%s %s[%ld].%s-%s/%d [",
timeString,
dbgSyslog,
syscall(224),
classString,
file,
line
);
char *dbgLogStart = dbgPtr;
va_start( argPtr, fstring );
if ( hex )
{
unsigned char *data = va_arg( argPtr, unsigned char * );
int len = va_arg( argPtr, int );
int i;
dbgPtr += snprintf( dbgPtr, sizeof(dbgString)-(dbgPtr-dbgString), "%d:", len );
for ( i = 0; i < len; i++ )
{
dbgPtr += snprintf( dbgPtr, sizeof(dbgString)-(dbgPtr-dbgString), " %02x", data[i] );
}
}
else
{
dbgPtr += vsnprintf( dbgPtr, sizeof(dbgString)-(dbgPtr-dbgString), fstring, argPtr );
}
va_end(argPtr);
char *dbg_log_end = dbgPtr;
strncpy( dbgPtr, "]\n", sizeof(dbgString)-(dbgPtr-dbgString) );
if ( dbgPrint )
{
printf( "%s", dbgString );
fflush( stdout );
}
if ( dbgLogFP != (FILE *)NULL )
{
fprintf( dbgLogFP, "%s", dbgString );
if ( dbgFlush )
{
fflush( dbgLogFP );
}
}
/* For Info, Warning, Errors etc we want to log them */
if ( level <= ZM_DBG_SYSLOG )
{
switch( level )
{
case ZM_DBG_INF:
logCode = LOG_INFO;
break;
case ZM_DBG_WAR:
logCode = LOG_WARNING;
break;
case ZM_DBG_ERR:
case ZM_DBG_FAT:
case ZM_DBG_PNC:
logCode = LOG_ERR;
break;
default:
logCode = LOG_DEBUG;
break;
}
//logCode |= LOG_DAEMON;
*dbg_log_end = '\0';
syslog( logCode, "%s [%s]", classString, dbgLogStart );
}
if ( level <= ZM_DBG_FAT )
{
if ( level <= ZM_DBG_PNC )
abort();
exit( -1 );
}
}

View File

@ -1,118 +0,0 @@
/*
* ZoneMinder Debug Interface, $Date$, $Revision$
* Copyright (C) 2001-2008 Philip Coombes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef ZM_DEBUG_H
#define ZM_DEBUG_H
#include <sys/types.h>
#include <limits.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* Leave 0 and below for debug */
#define ZM_DBG_INF 0
#define ZM_DBG_WAR -1
#define ZM_DBG_ERR -2
#define ZM_DBG_FAT -3
#define ZM_DBG_PNC -4
/* Define the level at which messages go through syslog */
#define ZM_DBG_SYSLOG ZM_DBG_INF
#define zmDbgPrintf(level,params...) {\
if (level <= zmDbgLevel)\
zmDbgOutput( 0, __FILE__, __LINE__, level, ##params );\
}
#define zmDbgHexdump(level,data,len) {\
if (level <= zmDbgLevel)\
zmDbgOutput( 1, __FILE__, __LINE__, level, "%p (%d)", data, len );\
}
/* Turn off debug here */
#ifndef ZM_DBG_OFF
#define Debug(level,params...) zmDbgPrintf(level,##params)
#define Hexdump(level,data,len) zmDbgHexdump(level,data,len)
#else
#define Debug(level,params...)
#define Hexdump(level,data,len)
#endif
#define Info(params...) zmDbgPrintf(ZM_DBG_INF,##params)
#define Warning(params...) zmDbgPrintf(ZM_DBG_WAR,##params)
#define Error(params...) zmDbgPrintf(ZM_DBG_ERR,##params)
#define Fatal(params...) zmDbgPrintf(ZM_DBG_FAT,##params)
#define Panic(params...) zmDbgPrintf(ZM_DBG_PNC,##params)
#define Mark() Info("Mark/%s/%d",__FILE__,__LINE__)
#define Log() Info("Log")
#ifdef __GNUC__
#define Enter(level) zmDbgPrintf(level,("Entering %s",__PRETTY_FUNCTION__))
#define Exit(level) zmDbgPrintf(level,("Exiting %s",__PRETTY_FUNCTION__))
#else
#if 0
#define Enter(level) zmDbgPrintf(level,("Entering <unknown>"))
#define Exit(level) zmDbgPrintf(level,("Exiting <unknown>"))
#endif
#define Enter(level)
#define Exit(level)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* function declarations */
const char *zmDbgName();
void zmUsrHandler( int sig );
int zmGetDebugEnv( void );
int zmDebugPrepareLog( void );
int zmDebugInitialise( const char *name, const char *id, int level );
int zmDebugReinitialise( const char *target );
int zmDebugTerminate( void );
void zmDbgSubtractTime( struct timeval * const tp1, struct timeval * const tp2 );
#if defined(__STDC__) || defined(__cplusplus)
int zmDbgInit( const char *name, const char *id, int level );
int zmDbgReinit( const char *target );
int zmDbgTerm(void);
void zmDbgOutput( int hex, const char * const file, const int line, const int level, const char *fstring, ... ) __attribute__ ((format(printf, 5, 6)));
#else
int zmDbgInit();
int zmDbgReinit();
int zmDbgTerm();
void zmDbgOutput();
#endif
extern int zmDbgLevel;
#ifndef _STDIO_INCLUDED
#include <stdio.h>
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // ZM_DEBUG_H

View File

@ -74,7 +74,7 @@ void FfmpegCamera::Initialise()
mBuffer.size( max_size ); mBuffer.size( max_size );
if ( zmDbgLevel > ZM_DBG_INF ) if ( logDebugging() )
av_log_set_level( AV_LOG_DEBUG ); av_log_set_level( AV_LOG_DEBUG );
else else
av_log_set_level( AV_LOG_QUIET ); av_log_set_level( AV_LOG_QUIET );

View File

@ -24,6 +24,8 @@
#include "zm_buffer.h" #include "zm_buffer.h"
#include "zm_regexp.h" #include "zm_regexp.h"
#include <sys/param.h>
// //
// Class representing 'file' cameras, i.e. those which are // Class representing 'file' cameras, i.e. those which are
// accessed over a network connection. // accessed over a network connection.

View File

@ -1365,7 +1365,7 @@ void Image::Fill( Rgb colour, int density, const Polygon &polygon )
qsort( global_edges, n_global_edges, sizeof(*global_edges), Edge::CompareYX ); qsort( global_edges, n_global_edges, sizeof(*global_edges), Edge::CompareYX );
#ifndef ZM_DBG_OFF #ifndef ZM_DBG_OFF
if ( zmDbgLevel >= 9 ) if ( logLevel() >= Logger::DEBUG9 )
{ {
for ( int i = 0; i < n_global_edges; i++ ) for ( int i = 0; i < n_global_edges; i++ )
{ {
@ -1400,7 +1400,7 @@ void Image::Fill( Rgb colour, int density, const Polygon &polygon )
} }
qsort( active_edges, n_active_edges, sizeof(*active_edges), Edge::CompareX ); qsort( active_edges, n_active_edges, sizeof(*active_edges), Edge::CompareX );
#ifndef ZM_DBG_OFF #ifndef ZM_DBG_OFF
if ( zmDbgLevel >= 9 ) if ( logLevel() >= Logger::DEBUG9 )
{ {
for ( int i = 0; i < n_active_edges; i++ ) for ( int i = 0; i < n_active_edges; i++ )
{ {

View File

@ -17,12 +17,14 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "zm_jpeg.h"
#include "zm_logger.h"
#include <unistd.h> #include <unistd.h>
#include "zm_jpeg.h"
#include "zm_debug.h"
/* Overridden error handlers, mostly for decompression */ /* Overridden error handlers, mostly for decompression */
extern "C"
{
#define MAX_JPEG_ERRS 25 #define MAX_JPEG_ERRS 25
@ -389,3 +391,5 @@ void zm_jpeg_mem_src( j_decompress_ptr cinfo, const JOCTET *inbuffer, int inbuff
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
src->pub.next_input_byte = NULL; /* until buffer loaded */ src->pub.next_input_byte = NULL; /* until buffer loaded */
} }
}

View File

@ -23,6 +23,12 @@
#include "jpeglib.h" #include "jpeglib.h"
#include "jerror.h" #include "jerror.h"
// Stop complaints about deuplicate definitions
#undef HAVE_STDLIB_H
#undef HAVE_STDDEF_H
extern "C"
{
/* Stuff for overriden error handlers */ /* Stuff for overriden error handlers */
struct zm_error_mgr struct zm_error_mgr
{ {
@ -38,3 +44,4 @@ void zm_jpeg_emit_message( j_common_ptr cinfo, int msg_level );
// Prototypes for memory compress/decompression object */ // Prototypes for memory compress/decompression object */
void zm_jpeg_mem_src(j_decompress_ptr cinfo, const JOCTET *inbuffer, int inbuffer_size ); void zm_jpeg_mem_src(j_decompress_ptr cinfo, const JOCTET *inbuffer, int inbuffer_size );
void zm_jpeg_mem_dest(j_compress_ptr cinfo, JOCTET *outbuffer, int *outbuffer_size ); void zm_jpeg_mem_dest(j_compress_ptr cinfo, JOCTET *outbuffer, int *outbuffer_size );
}

View File

@ -337,7 +337,7 @@ LocalCamera::~LocalCamera()
void LocalCamera::Initialise() void LocalCamera::Initialise()
{ {
#if HAVE_LIBSWSCALE #if HAVE_LIBSWSCALE
if ( zmDbgLevel > ZM_DBG_INF ) if ( logDebugging() )
av_log_set_level( AV_LOG_DEBUG ); av_log_set_level( AV_LOG_DEBUG );
else else
av_log_set_level( AV_LOG_QUIET ); av_log_set_level( AV_LOG_QUIET );

569
src/zm_logger.cpp Normal file
View File

@ -0,0 +1,569 @@
/*
* ZoneMinder Logger Implementation, $Date$, $Revision$
* Copyright (C) 2001-2008 Philip Coombes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "zm_logger.h"
#include "zm_config.h"
#include "zm_utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <syslog.h>
#ifdef HAVE_SYSCALL_H
#include <syscall.h>
#endif // HAVE_SYSCALL_H
#include <signal.h>
#include <stdarg.h>
#include <errno.h>
bool Logger::smInitialised = false;
Logger *Logger::smInstance = 0;
Logger::StringMap Logger::smCodes;
Logger::IntMap Logger::smSyslogPriorities;
static void subtractTime( struct timeval * const tp1, struct timeval * const tp2 )
{
tp1->tv_sec -= tp2->tv_sec;
if ( tp1->tv_usec <= tp2->tv_usec )
{
tp1->tv_sec--;
tp1->tv_usec = 1000000 - (tp2->tv_usec - tp1->tv_usec);
}
else
{
tp1->tv_usec = tp1->tv_usec - tp2->tv_usec;
}
}
void Logger::usrHandler( int sig )
{
Logger *logger = fetch();
if ( sig == SIGUSR1 )
logger->level( logger->level()+1 );
else if ( sig == SIGUSR2 )
logger->level( logger->level()-1 );
Info( "Logger - Level changed to %d", logger->level() );
}
Logger::Logger() :
mLevel( INFO ),
mTermLevel( NOLOG ),
mDatabaseLevel( NOLOG ),
mFileLevel( NOLOG ),
mSyslogLevel( NOLOG ),
mEffectiveLevel( NOLOG ),
//mLogPath( config.path_logs ),
//mLogFile( mLogPath+"/"+mId+".log" ),
mLogFileFP( NULL ),
mHasTerm( false ),
mFlush( false )
{
if ( smInstance )
{
Panic( "Attempt to create second instance of Logger class" );
}
if ( !smInitialised )
{
smCodes[INFO] = "INF";
smCodes[WARNING] = "WAR";
smCodes[ERROR] = "ERR";
smCodes[FATAL] = "FAT";
smCodes[PANIC] = "PNC";
smCodes[NOLOG] = "OFF";
smSyslogPriorities[INFO] = LOG_INFO;
smSyslogPriorities[WARNING] = LOG_WARNING;
smSyslogPriorities[ERROR] = LOG_ERR;
smSyslogPriorities[FATAL] = LOG_ERR;
smSyslogPriorities[PANIC] = LOG_ERR;
char code[4] = "";
for ( int i = DEBUG1; i <= DEBUG9; i++ )
{
snprintf( code, sizeof(code), "DB%d", i );
smCodes[i] = code;
smSyslogPriorities[i] = LOG_DEBUG;
}
smInitialised = true;
}
if ( fileno(stderr) && isatty(fileno(stderr)) )
mHasTerm = true;
}
Logger::~Logger()
{
terminate();
}
void Logger::initialise( const std::string &id, const Options &options )
{
char *envPtr;
if ( !id.empty() )
this->id( id );
std::string tempLogFile;
if ( options.mLogPath.size() )
{
mLogPath = options.mLogPath;
tempLogFile = mLogPath+"/"+mId+".log";
}
if ( options.mLogFile.size() )
tempLogFile = options.mLogFile;
else
tempLogFile = mLogPath+"/"+mId+".log";
if ( (envPtr = getTargettedEnv( "LOG_FILE" )) )
tempLogFile = envPtr;
Level tempLevel = INFO;
Level tempTermLevel = mTermLevel;
Level tempDatabaseLevel = mDatabaseLevel;
Level tempFileLevel = mFileLevel;
Level tempSyslogLevel = mSyslogLevel;
if ( options.mTermLevel != NOOPT )
tempTermLevel = options.mTermLevel;
if ( options.mDatabaseLevel != NOOPT )
tempDatabaseLevel = options.mDatabaseLevel;
else
tempDatabaseLevel = config.log_level_database >= DEBUG1 ? DEBUG9 : config.log_level_database;
if ( options.mFileLevel != NOOPT )
tempFileLevel = options.mFileLevel;
else
tempFileLevel = config.log_level_file >= DEBUG1 ? DEBUG9 : config.log_level_file;
if ( options.mSyslogLevel != NOOPT )
tempSyslogLevel = options.mSyslogLevel;
else
tempSyslogLevel = config.log_level_syslog >= DEBUG1 ? DEBUG9 : config.log_level_syslog;
// Legacy
if ( (envPtr = getenv( "LOG_PRINT" )) )
tempTermLevel = atoi(envPtr) ? DEBUG9 : NOLOG;
if ( (envPtr = getTargettedEnv( "LOG_LEVEL" )) )
tempLevel = atoi(envPtr);
if ( (envPtr = getTargettedEnv( "LOG_LEVEL_TERM" )) )
tempTermLevel = atoi(envPtr);
if ( (envPtr = getTargettedEnv( "LOG_LEVEL_DATABASE" )) )
tempDatabaseLevel = atoi(envPtr);
if ( (envPtr = getTargettedEnv( "LOG_LEVEL_FILE" )) )
tempFileLevel = atoi(envPtr);
if ( (envPtr = getTargettedEnv( "LOG_LEVEL_SYSLOG" )) )
tempSyslogLevel = atoi(envPtr);
if ( config.log_debug )
{
StringVector targets = split( config.log_debug_target, "|" );
for ( int i = 0; i < targets.size(); i++ )
{
const std::string &target = targets[i];
if ( target == mId || target == "_"+mId || target == "_"+mIdRoot || target == "_"+mIdRoot || target == "" )
{
if ( config.log_debug_level > NOLOG )
{
tempLevel = config.log_debug_level;
if ( config.log_debug_file[0] )
{
tempLogFile = config.log_debug_file;
tempFileLevel = tempLevel;
}
}
}
}
}
logFile( tempLogFile );
termLevel( tempTermLevel );
databaseLevel( tempDatabaseLevel );
fileLevel( tempFileLevel );
syslogLevel( tempSyslogLevel );
level( tempLevel );
mFlush = (envPtr = getenv( "LOG_FLUSH")) ? atoi( envPtr ) : false;
//mRuntime = (envPtr = getenv( "LOG_RUNTIME")) ? atoi( envPtr ) : false;
{
struct sigaction action;
memset( &action, 0, sizeof(action) );
action.sa_handler = usrHandler;
action.sa_flags = SA_RESTART;
if ( sigaction( SIGUSR1, &action, 0 ) < 0 )
{
Fatal( "sigaction(), error = %s", strerror(errno) );
}
if ( sigaction( SIGUSR2, &action, 0 ) < 0)
{
Fatal( "sigaction(), error = %s", strerror(errno) );
}
}
mInitialised = true;
Debug( 1, "LogOpts: level=%s/%s, screen=%s, database=%s, logfile=%s->%s, syslog=%s", smCodes[mLevel].c_str(), smCodes[mEffectiveLevel].c_str(), smCodes[mTermLevel].c_str(), smCodes[mDatabaseLevel].c_str(), smCodes[mFileLevel].c_str(), mLogFile.c_str(), smCodes[mSyslogLevel].c_str() );
}
void Logger::terminate()
{
Info( "Terminating Logger" );
if ( mFileLevel > NOLOG )
closeFile();
if ( mSyslogLevel > NOLOG )
closeSyslog();
}
bool Logger::boolEnv( const std::string &name, bool defaultValue )
{
const char *envPtr = getenv( name.c_str() );
return( envPtr ? atoi( envPtr ) : defaultValue );
}
int Logger::intEnv( const std::string &name, bool defaultValue )
{
const char *envPtr = getenv( name.c_str() );
return( envPtr ? atoi( envPtr ) : defaultValue );
}
std::string Logger::strEnv( const std::string &name, const std::string defaultValue )
{
const char *envPtr = getenv( name.c_str() );
return( envPtr ? envPtr : defaultValue );
}
char *Logger::getTargettedEnv( const std::string &name )
{
char *envPtr = NULL;
std::string envName;
envName = name+"_"+mId;
envPtr = getenv( envName.c_str() );
if ( !envPtr && mId != mIdRoot )
{
envName = name+"_"+mIdRoot;
envPtr = getenv( envName.c_str() );
}
if ( !envPtr )
envPtr = getenv( name.c_str() );
return( envPtr );
}
const std::string &Logger::id( const std::string &id )
{
std::string tempId = id;
size_t pos;
// Remove whitespace
while ( (pos = tempId.find_first_of( " \t" )) != std::string::npos )
{
tempId.replace( pos, 1, "" );
}
// Replace non-alphanum with underscore
while ( (pos = tempId.find_first_not_of( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" )) != std::string::npos )
{
tempId.replace( pos, 1, "_" );
}
if ( mId != tempId )
{
mId = tempId;
pos = mId.find( '_' );
if ( pos != std::string::npos )
{
mIdRoot = mId.substr( 0, pos );
if ( ++pos < mId.size() )
mIdArgs = mId.substr( pos );
}
}
return( mId );
}
Logger::Level Logger::level( Logger::Level level )
{
if ( level > NOOPT )
{
level = limit(level);
if ( mLevel != level )
mLevel = level;
mEffectiveLevel = NOLOG;
if ( mTermLevel > mEffectiveLevel )
mEffectiveLevel = mTermLevel;
if ( mDatabaseLevel > mEffectiveLevel )
mEffectiveLevel = mDatabaseLevel;
if ( mFileLevel > mEffectiveLevel )
mEffectiveLevel = mFileLevel;
if ( mSyslogLevel > mEffectiveLevel )
mEffectiveLevel = mSyslogLevel;
if ( mEffectiveLevel > mLevel)
mEffectiveLevel = mLevel;
}
return( mLevel );
}
Logger::Level Logger::termLevel( Logger::Level termLevel )
{
if ( termLevel > NOOPT )
{
if ( !mHasTerm )
termLevel = NOLOG;
termLevel = limit(termLevel);
if ( mTermLevel != termLevel )
mTermLevel = termLevel;
}
return( mTermLevel );
}
Logger::Level Logger::databaseLevel( Logger::Level databaseLevel )
{
if ( databaseLevel > NOOPT )
{
databaseLevel = limit(databaseLevel);
if ( mDatabaseLevel != databaseLevel )
{
if ( databaseLevel > NOLOG && mDatabaseLevel <= NOLOG )
{
if ( zmDbConnected )
zmDbConnect();
}
mDatabaseLevel = databaseLevel;
}
}
return( mDatabaseLevel );
}
Logger::Level Logger::fileLevel( Logger::Level fileLevel )
{
if ( fileLevel > NOOPT )
{
fileLevel = limit(fileLevel);
if ( mFileLevel != fileLevel )
{
if ( mFileLevel > NOLOG )
closeFile();
mFileLevel = fileLevel;
if ( mFileLevel > NOLOG )
openFile();
}
}
return( mFileLevel );
}
Logger::Level Logger::syslogLevel( Logger::Level syslogLevel )
{
if ( syslogLevel > NOOPT )
{
syslogLevel = limit(syslogLevel);
if ( mSyslogLevel != syslogLevel )
{
if ( mSyslogLevel > NOLOG )
closeSyslog();
mSyslogLevel = syslogLevel;
if ( mSyslogLevel > NOLOG )
openSyslog();
}
}
return( mSyslogLevel );
}
void Logger::logFile( const std::string &logFile )
{
bool addLogPid = false;
std::string tempLogFile = logFile;
if ( tempLogFile[tempLogFile.length()-1] == '+' )
{
tempLogFile.resize(tempLogFile.length()-1);
addLogPid = true;
}
if ( addLogPid )
mLogFile = stringtf( "%s.%05d", tempLogFile.c_str(), getpid() );
else
mLogFile = tempLogFile;
}
void Logger::openFile()
{
if ( mLogFile.size() && (mLogFileFP = fopen( mLogFile.c_str() ,"w" )) == (FILE *)NULL )
{
mFileLevel = NOLOG;
Fatal( "fopen() for %s, error = %s", mLogFile.c_str(), strerror(errno) );
}
}
void Logger::closeFile()
{
if ( mLogFileFP )
{
fflush( mLogFileFP );
if ( fclose( mLogFileFP ) < 0 )
{
Fatal( "fclose(), error = %s",strerror(errno) );
}
mLogFileFP = (FILE *)NULL;
}
}
void Logger::openSyslog()
{
(void) openlog( mId.c_str(), LOG_PID|LOG_NDELAY, LOG_LOCAL1 );
}
void Logger::closeSyslog()
{
(void) closelog();
}
void Logger::logPrint( bool hex, const char * const file, const int line, const int level, const char *fstring, ... )
{
if ( level <= mEffectiveLevel )
{
char classString[4];
char timeString[64];
char logString[8192];
va_list argPtr;
struct timeval timeVal;
if ( level < PANIC || level > DEBUG9 )
Panic( "Invalid logger level %d", level );
strncpy( classString, smCodes[level].c_str(), sizeof(classString) );
gettimeofday( &timeVal, NULL );
#if 0
if ( logRuntime )
{
static struct timeval logStart;
subtractTime( &timeVal, &logStart );
snprintf( timeString, sizeof(timeString), "%ld.%03ld", timeVal.tv_sec, timeVal.tv_usec/1000 );
}
else
{
#endif
char *timePtr = timeString;
timePtr += strftime( timePtr, sizeof(timeString), "%x %H:%M:%S", localtime(&timeVal.tv_sec) );
snprintf( timePtr, sizeof(timeString)-(timePtr-timeString), ".%06ld", timeVal.tv_usec );
#if 0
}
#endif
pid_t tid;
#ifdef HAVE_SYSCALL
if ( (tid = syscall(SYS_gettid)) < 0 ) // Thread/Process id
#endif // HAVE_SYSCALL
tid = getpid(); // Process id
char *logPtr = logString;
logPtr += snprintf( logPtr, sizeof(logString), "%s %s[%d].%s-%s/%d [",
timeString,
mId.c_str(),
tid,
classString,
file,
line
);
char *syslogStart = logPtr;
va_start( argPtr, fstring );
if ( hex )
{
unsigned char *data = va_arg( argPtr, unsigned char * );
int len = va_arg( argPtr, int );
int i;
logPtr += snprintf( logPtr, sizeof(logString)-(logPtr-logString), "%d:", len );
for ( i = 0; i < len; i++ )
{
logPtr += snprintf( logPtr, sizeof(logString)-(logPtr-logString), " %02x", data[i] );
}
}
else
{
logPtr += vsnprintf( logPtr, sizeof(logString)-(logPtr-logString), fstring, argPtr );
}
va_end(argPtr);
char *syslogEnd = logPtr;
strncpy( logPtr, "]\n", sizeof(logString)-(logPtr-logString) );
if ( level <= mTermLevel )
{
printf( "%s", logString );
fflush( stdout );
}
if ( level <= mFileLevel )
{
fprintf( mLogFileFP, "%s", logString );
if ( mFlush )
fflush( mLogFileFP );
}
*syslogEnd = '\0';
if ( level <= mDatabaseLevel )
{
char sql[ZM_SQL_MED_BUFSIZ];
char escapedString[(strlen(syslogStart)*2)+1];
mysql_real_escape_string( &dbconn, escapedString, syslogStart, strlen(syslogStart) );
snprintf( sql, sizeof(sql), "insert into Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) values ( %ld.%06ld, '%s', %d, %d, '%s', '%s', '%s', %d )", timeVal.tv_sec, timeVal.tv_usec, mId.c_str(), tid, level, classString, escapedString, file, line );
if ( mysql_query( &dbconn, sql ) )
{
databaseLevel( NOLOG );
Fatal( "Can't insert log entry: %s", mysql_error( &dbconn ) );
exit( mysql_errno( &dbconn ) );
}
}
if ( level <= mSyslogLevel )
{
int priority = smSyslogPriorities[level];
//priority |= LOG_DAEMON;
syslog( priority, "%s [%s]", classString, syslogStart );
}
if ( level <= FATAL )
{
if ( level <= PANIC )
abort();
exit( -1 );
}
}
}
void logInit( const char *name, const Logger::Options &options )
{
if ( !Logger::smInstance )
Logger::smInstance = new Logger();
Logger::Options tempOptions = options;
tempOptions.mLogPath = config.path_logs;
Logger::smInstance->initialise( name, tempOptions );
}
void logTerm()
{
Logger::fetch()->terminate();
}

237
src/zm_logger.h Normal file
View File

@ -0,0 +1,237 @@
/*
* ZoneMinder Logger Interface, $Date$, $Revision$
* Copyright (C) 2001-2008 Philip Coombes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef ZM_LOGGER_H
#define ZM_LOGGER_H
#include "zm_db.h"
#include <string>
#include <map>
class Logger
{
public:
enum {
NOOPT=-6,
NOLOG,
PANIC,
FATAL,
ERROR,
WARNING,
INFO,
DEBUG1,
DEBUG2,
DEBUG3,
DEBUG4,
DEBUG5,
DEBUG6,
DEBUG7,
DEBUG8,
DEBUG9
};
typedef int Level;
typedef std::map<Level,std::string> StringMap;
typedef std::map<Level,int> IntMap;
class Options
{
public:
int mTermLevel;
int mDatabaseLevel;
int mFileLevel;
int mSyslogLevel;
std::string mLogPath;
std::string mLogFile;
public:
Options( Level termLevel=NOOPT, Level databaseLevel=NOOPT, Level fileLevel=NOOPT, Level syslogLevel=NOOPT, const std::string &logPath=".", const std::string &logFile="" ) :
mTermLevel( termLevel ),
mDatabaseLevel( databaseLevel ),
mFileLevel( fileLevel ),
mSyslogLevel( syslogLevel ),
mLogPath( logPath ),
mLogFile( logFile )
{
}
};
private:
static bool smInitialised;
static Logger *smInstance;
static StringMap smCodes;
static IntMap smSyslogPriorities;
private:
bool mInitialised;
std::string mId;
std::string mIdRoot;
std::string mIdArgs;
Level mLevel; // Level that is currently in operation
Level mTermLevel; // Maximum level output via terminal
Level mDatabaseLevel; // Maximum level output via database
Level mFileLevel; // Maximum level output via file
Level mSyslogLevel; // Maximum level output via syslog
Level mEffectiveLevel; // Level optimised to take account of maxima
std::string mLogPath;
std::string mLogFile;
FILE *mLogFileFP;
bool mHasTerm;
bool mFlush;
private:
static void usrHandler( int sig );
public:
friend void logInit( const char *name, const Options &options );
static Logger *fetch()
{
if ( !smInstance )
{
smInstance = new Logger();
Options options;
smInstance->initialise( "undef", options );
}
return( smInstance );
}
private:
Logger();
~Logger();
public:
void initialise( const std::string &id, const Options &options );
void terminate();
private:
int limit( int level )
{
if ( level > DEBUG9 )
return( DEBUG9 );
if ( level < NOLOG )
return( NOLOG );
return( level );
}
bool boolEnv( const std::string &name, bool defaultValue=false );
int intEnv( const std::string &name, bool defaultValue=0 );
std::string strEnv( const std::string &name, const std::string defaultValue="" );
char *getTargettedEnv( const std::string &name );
void loadEnv();
public:
const std::string &id() const
{
return( mId );
}
const std::string &id( const std::string &id );
Level level() const
{
return( mLevel );
}
Level level( Level=NOOPT );
bool debugOn()
{
return( mEffectiveLevel >= DEBUG1 );
}
Level termLevel( Level=NOOPT );
Level databaseLevel( Level=NOOPT );
Level fileLevel( Level=NOOPT );
Level syslogLevel( Level=NOOPT );
private:
void logFile( const std::string &logFile );
void openFile();
void closeFile();
void openSyslog();
void closeSyslog();
public:
void logPrint( bool hex, const char * const file, const int line, const int level, const char *fstring, ... );
};
void logInit( const char *name, const Logger::Options &options=Logger::Options() );
void logTerm();
inline const std::string &logId()
{
return( Logger::fetch()->id() );
}
inline Logger::Level logLevel()
{
return( Logger::fetch()->level() );
}
inline void logCapLevel( Logger::Level level )
{
Logger::fetch()->level( level );
}
inline Logger::Level logDebugging()
{
return( Logger::fetch()->debugOn() );
}
#define logPrintf(logLevel,params...) {\
if ( logLevel <= Logger::fetch()->level() )\
Logger::fetch()->logPrint( false, __FILE__, __LINE__, logLevel, ##params );\
}
#define logHexdump(logLevel,data,len) {\
if ( logLevel <= Logger::fetch()->level() )\
Logger::fetch()->logPrint( true, __FILE__, __LINE__, logLevel, "%p (%d)", data, len );\
}
/* Debug compiled out */
#ifndef DBG_OFF
#define Debug(level,params...) logPrintf(level,##params)
#define Hexdump(level,data,len) logHexdump(level,data,len)
#else
#define Debug(level,params...)
#define Hexdump(level,data,len)
#endif
/* Standard debug calls */
#define Info(params...) logPrintf(Logger::INFO,##params)
#define Warning(params...) logPrintf(Logger::WARNING,##params)
#define Error(params...) logPrintf(Logger::ERROR,##params)
#define Fatal(params...) logPrintf(Logger::FATAL,##params)
#define Panic(params...) logPrintf(Logger::PANIC,##params)
#define Mark() Info("Mark/%s/%d",__FILE__,__LINE__)
#define Log() Info("Log")
#ifdef __GNUC__
#define Enter(level) logPrintf(level,("Entering %s",__PRETTY_FUNCTION__))
#define Exit(level) logPrintf(level,("Exiting %s",__PRETTY_FUNCTION__))
#else
#define Enter(level)
#define Exit(level)
#endif
#endif // ZM_LOGGER_H

View File

@ -65,7 +65,7 @@ void RemoteCameraRtsp::Initialise()
buffer.size( max_size ); buffer.size( max_size );
if ( zmDbgLevel > ZM_DBG_INF ) if ( logDebugging() )
av_log_set_level( AV_LOG_DEBUG ); av_log_set_level( AV_LOG_DEBUG );
else else
av_log_set_level( AV_LOG_QUIET ); av_log_set_level( AV_LOG_QUIET );
@ -222,7 +222,7 @@ int RemoteCameraRtsp::Capture( Image &image )
return( 0 ); return( 0 );
} }
Error( "Error while decoding frame %d", frameCount ); Error( "Error while decoding frame %d", frameCount );
Hexdump( ZM_DBG_ERR, buffer.head(), buffer.size()>256?256:buffer.size() ); Hexdump( Logger::ERROR, buffer.head(), buffer.size()>256?256:buffer.size() );
buffer.clear(); buffer.clear();
continue; continue;
//return( -1 ); //return( -1 );

View File

@ -83,7 +83,7 @@ bool RtspThread::recvResponse( std::string &response )
{ {
Error( "Response parse failure, %zd bytes follow", response.size() ); Error( "Response parse failure, %zd bytes follow", response.size() );
if ( response.size() ) if ( response.size() )
Hexdump( ZM_DBG_ERR, response.data(), min(response.size(),16) ); Hexdump( Logger::ERROR, response.data(), min(response.size(),16) );
} }
return( false ); return( false );
} }
@ -257,7 +257,7 @@ int RtspThread::run()
{ {
Error( "Response parse failure, %zd bytes follow", response.size() ); Error( "Response parse failure, %zd bytes follow", response.size() );
if ( response.size() ) if ( response.size() )
Hexdump( ZM_DBG_ERR, response.data(), min(response.size(),16) ); Hexdump( Logger::ERROR, response.data(), min(response.size(),16) );
} }
return( -1 ); return( -1 );
} }

View File

@ -17,12 +17,13 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// //
#include <string.h>
#include <stdlib.h>
#include "zm.h" #include "zm.h"
#include "zm_signal.h" #include "zm_signal.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
bool zm_reload = false; bool zm_reload = false;
RETSIGTYPE zm_hup_handler( int signal ) RETSIGTYPE zm_hup_handler( int signal )
@ -114,7 +115,7 @@ RETSIGTYPE zm_die_handler( int signal )
} }
else else
{ {
cmd_ptr += snprintf( cmd_ptr, sizeof(cmd)-(cmd_ptr-cmd), "/path/to/%s", zmDbgName() ); cmd_ptr += snprintf( cmd_ptr, sizeof(cmd)-(cmd_ptr-cmd), "/path/to/%s", logId().c_str() );
} }
// skip first stack frame (points here) // skip first stack frame (points here)
for ( int i=1; i < trace_size; i++ ) for ( int i=1; i < trace_size; i++ )

View File

@ -19,7 +19,7 @@
#include "zm_thread.h" #include "zm_thread.h"
#include "zm_debug.h" #include "zm_logger.h"
#include "zm_utils.h" #include "zm_utils.h"
#include <string.h> #include <string.h>

View File

@ -19,7 +19,7 @@
#include "zm_timer.h" #include "zm_timer.h"
#include "zm_debug.h" #include "zm_logger.h"
int Timer::TimerThread::mNextTimerId = 0; int Timer::TimerThread::mNextTimerId = 0;

View File

@ -17,16 +17,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include "zm.h" #include "zm.h"
#include "zm_db.h" #include "zm_db.h"
#include "zm_user.h" #include "zm_user.h"
#include <stdio.h>
User::User() User::User()
{ {
username[0] = password[0] = 0; username[0] = password[0] = 0;

View File

@ -17,7 +17,7 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// //
//#include "zm_debug.h" //#include "zm_logger.h"
#include "zm_utils.h" #include "zm_utils.h"
#include <stdio.h> #include <stdio.h>

View File

@ -87,13 +87,13 @@ int main( int argc, char *argv[] )
exit( 0 ); exit( 0 );
} }
char dbg_id_string[16]; char log_id_string[16];
snprintf( dbg_id_string, sizeof(dbg_id_string), "m%d", id ); snprintf( log_id_string, sizeof(log_id_string), "zma_m%d", id );
zmDbgInit( "zma", dbg_id_string, 0 );
zmLoadConfig(); zmLoadConfig();
logInit( log_id_string );
Monitor *monitor = Monitor::Load( id, true, Monitor::ANALYSIS ); Monitor *monitor = Monitor::Load( id, true, Monitor::ANALYSIS );
if ( monitor ) if ( monitor )

View File

@ -128,30 +128,30 @@ int main( int argc, char *argv[] )
exit( 0 ); exit( 0 );
} }
char dbg_id_string[16]; char log_id_string[32] = "";
if ( device[0] ) if ( device[0] )
{ {
const char *slash_ptr = strrchr( device, '/' ); const char *slash_ptr = strrchr( device, '/' );
snprintf( dbg_id_string, sizeof(dbg_id_string), "d%s", slash_ptr?slash_ptr+1:device ); snprintf( log_id_string, sizeof(log_id_string), "zmc_d%s", slash_ptr?slash_ptr+1:device );
} }
else if ( host[0] ) else if ( host[0] )
{ {
snprintf( dbg_id_string, sizeof(dbg_id_string), "h%s", host ); snprintf( log_id_string, sizeof(log_id_string), "zmc_h%s", host );
} }
else if ( file[0] ) else if ( file[0] )
{ {
const char *slash_ptr = strrchr( file, '/' ); const char *slash_ptr = strrchr( file, '/' );
snprintf( dbg_id_string, sizeof(dbg_id_string), "f%s", slash_ptr?slash_ptr+1:file ); snprintf( log_id_string, sizeof(log_id_string), "zmc_f%s", slash_ptr?slash_ptr+1:file );
} }
else else
{ {
snprintf( dbg_id_string, sizeof(dbg_id_string), "m%d", monitor_id ); snprintf( log_id_string, sizeof(log_id_string), "zmc_m%d", monitor_id );
} }
zmDbgInit( "zmc", dbg_id_string, 0 );
zmLoadConfig(); zmLoadConfig();
logInit( log_id_string );
Monitor **monitors = 0; Monitor **monitors = 0;
int n_monitors = 0; int n_monitors = 0;
#if ZM_HAS_V4L #if ZM_HAS_V4L

View File

@ -155,13 +155,13 @@ int main( int argc, char *argv[] )
exit( 0 ); exit( 0 );
} }
char dbg_id_string[16]; char log_id_string[16];
snprintf( dbg_id_string, sizeof(dbg_id_string), "m%d", id ); snprintf( log_id_string, sizeof(log_id_string), "m%d", id );
zmDbgInit( "zmf", dbg_id_string, 0 );
zmLoadConfig(); zmLoadConfig();
logInit( "zmf" );
Monitor *monitor = Monitor::Load( id, false, Monitor::QUERY ); Monitor *monitor = Monitor::Load( id, false, Monitor::QUERY );
if ( !monitor ) if ( !monitor )

View File

@ -132,10 +132,11 @@ bool fixDevice( const char *device_path )
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
zmDbgInit( "zmfix", "", -1 );
zmLoadConfig(); zmLoadConfig();
logInit( "zmfix" );
logCapLevel( Logger::ERROR );
// Only do registered devices // Only do registered devices
static char sql[ZM_SQL_SML_BUFSIZ]; static char sql[ZM_SQL_SML_BUFSIZ];
snprintf( sql, sizeof(sql), "select distinct Device from Monitors where not isnull(Device) and Type = 'Local'" ); snprintf( sql, sizeof(sql), "select distinct Device from Monitors where not isnull(Device) and Type = 'Local'" );

View File

@ -85,10 +85,10 @@ int main( int argc, const char *argv[] )
nph = true; nph = true;
} }
zmDbgInit( "zms", "", 0 );
zmLoadConfig(); zmLoadConfig();
logInit( "zms" );
zmSetDefaultTermHandler(); zmSetDefaultTermHandler();
zmSetDefaultDieHandler(); zmSetDefaultDieHandler();

View File

@ -140,12 +140,12 @@ int main(int argc, char** argv) {
setenv("ZM_DBG_PRINT", "1", 1); setenv("ZM_DBG_PRINT", "1", 1);
printf("Done.\n"); printf("Done.\n");
} }
zmDbgInit("zmstreamer", "", 0);
// Loading ZM configurations // Loading ZM configurations
printf("Loading ZoneMinder configurations..."); printf("Loading ZoneMinder configurations...");
zmLoadConfig(); zmLoadConfig();
printf("Done.\n"); printf("Done.\n");
logInit("zmstreamer");
// Setting stream parameters // Setting stream parameters
MonitorStream stream; MonitorStream stream;

View File

@ -349,10 +349,10 @@ int main( int argc, char *argv[] )
} }
//printf( "Monitor %d, Function %d\n", mon_id, function ); //printf( "Monitor %d, Function %d\n", mon_id, function );
zmDbgInit( "zmu", "", -1 );
zmLoadConfig(); zmLoadConfig();
logInit( "zmu" );
zmSetDefaultTermHandler(); zmSetDefaultTermHandler();
zmSetDefaultDieHandler(); zmSetDefaultDieHandler();

View File

@ -6,6 +6,7 @@ dist_web_DATA = \
alarm.php \ alarm.php \
control.php \ control.php \
event.php \ event.php \
log.php \
status.php \ status.php \
stream.php \ stream.php \
zone.php zone.php

View File

@ -211,6 +211,7 @@ dist_web_DATA = \
alarm.php \ alarm.php \
control.php \ control.php \
event.php \ event.php \
log.php \
status.php \ status.php \
stream.php \ stream.php \
zone.php zone.php

357
web/ajax/log.php Normal file
View File

@ -0,0 +1,357 @@
<?php
switch ( $_REQUEST['task'] )
{
case 'create' :
{
if ( !canEdit( 'System' ) )
ajaxError( 'Insufficient permissions to create new log entry' );
logInit( array( 'id' => "web_js" ) );
$string = $_REQUEST['message'];
$file = preg_replace( '/\w+:\/\/\w+\//', '', $_REQUEST['file'] );
if ( !empty( $_REQUEST['line'] ) )
$line = $_REQUEST['line'];
else
$line = NULL;
$levels = array_flip(Logger::$codes);
if ( !isset($levels[$_REQUEST['level']]) )
Panic( "Unexpected logger level '".$_REQUEST['level']."'" );
$level = $levels[$_REQUEST['level']];
Logger::fetch()->logPrint( $level, $string, $file, $line );
ajaxResponse();
break;
}
case 'query' :
{
if ( !canView( 'System' ) )
ajaxError( 'Insufficient permissions to view log entries' );
$minTime = isset($_REQUEST['minTime'])?$_REQUEST['minTime']:NULL;
$maxTime = isset($_REQUEST['maxTime'])?$_REQUEST['maxTime']:NULL;
$limit = isset($_REQUEST['limit'])?$_REQUEST['limit']:1000;
$filter = isset($_REQUEST['filter'])?$_REQUEST['filter']:array();
$sortField = isset($_REQUEST['sortField'])?$_REQUEST['sortField']:'TimeKey';
$sortOrder = isset($_REQUEST['sortOrder'])?$_REQUEST['sortOrder']:'desc';
$filterFields = array( 'Component', 'Pid', 'Level', 'File', 'Line' );
//$filterSql = $filter?' where
$countSql = "select count(*) as Total from Logs";
$total = dbFetchOne( $countSql, 'Total' );
$sql = "select * from Logs";
$where = array();
if ( $minTime )
$where[] = "TimeKey > ".dbEscape($minTime);
elseif ( $maxTime )
$where[] = "TimeKey < ".dbEscape($maxTime);
foreach ( $filter as $field=>$value )
if ( $field == 'Level' )
$where[] = dbEscape($field)." <= ".dbEscape($value);
else
$where[] = dbEscape($field)." = '".dbEscape($value)."'";
if ( count($where) )
$sql.= " where ".join( " and ", $where );
$sql .= " order by ".dbEscape($sortField)." ".dbEscape($sortOrder)." limit ".dbEscape($limit);
$logs = array();
foreach ( dbFetchAll( $sql ) as $log )
{
$log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] );
$logs[] = $log;
}
$options = array();
$where = array();
foreach( $filter as $field=>$value )
$where[] = "$field = '".dbEscape($value)."'";
foreach( $filterFields as $field )
{
$sql = "select distinct $field from Logs where not isnull($field)";
if ( count($where) )
$sql.= " and ".join( " and ", $where );
$sql.= " order by $field asc";
if ( $field == 'Level' )
{
foreach( dbFetchAll( $sql, $field ) as $value )
if ( $value <= Logger::INFO )
$options[$field][$value] = Logger::$codes[$value];
else
$options[$field][$value] = "DB".$value;
}
else
{
foreach( dbFetchAll( $sql, $field ) as $value )
if ( $value != '' )
$options[$field][] = $value;
}
}
if ( count($filter) )
{
$sql = "select count(*) as Available from Logs where ".join( " and ", $where );
$available = dbFetchOne( $sql, 'Available' );
}
ajaxResponse( array(
'updated' => preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG ),
'total' => $total,
'available' => isset($available)?$available:$total,
'logs' => $logs,
'state' => logState(),
'options' => $options
) );
break;
}
case 'export' :
{
if ( !canView( 'System' ) )
ajaxError( 'Insufficient permissions to export logs' );
$minTime = isset($_REQUEST['minTime'])?$_REQUEST['minTime']:NULL;
$maxTime = isset($_REQUEST['maxTime'])?$_REQUEST['maxTime']:NULL;
if ( !is_null($minTime) && !is_null($maxTime) && $minTime > $maxTime )
{
$tempTime = $minTime;
$minTime = $maxTime;
$maxTime = $tempTime;
}
//$limit = isset($_REQUEST['limit'])?$_REQUEST['limit']:1000;
$filter = isset($_REQUEST['filter'])?$_REQUEST['filter']:array();
$sortField = isset($_REQUEST['sortField'])?$_REQUEST['sortField']:'TimeKey';
$sortOrder = isset($_REQUEST['sortOrder'])?$_REQUEST['sortOrder']:'asc';
$sql = "select * from Logs";
$where = array();
if ( $minTime )
{
preg_match( '/(.+)(\.\d+)/', $minTime, $matches );
$minTime = strtotime($matches[1]).$matches[2];
$where[] = "TimeKey >= ".$minTime;
}
if ( $maxTime )
{
preg_match( '/(.+)(\.\d+)/', $maxTime, $matches );
$maxTime = strtotime($matches[1]).$matches[2];
$where[] = "TimeKey <= ".$maxTime;
}
foreach ( $filter as $field=>$value )
if ( $value != '' )
if ( $field == 'Level' )
$where[] = dbEscape($field)." <= ".dbEscape($value);
else
$where[] = dbEscape($field)." = '".dbEscape($value)."'";
if ( count($where) )
$sql.= " where ".join( " and ", $where );
$sql .= " order by ".dbEscape($sortField)." ".dbEscape($sortOrder);
//$sql .= " limit ".dbEscape($limit);
$format = isset($_REQUEST['format'])?$_REQUEST['format']:'text';
switch( $format )
{
case 'text' :
$exportExt = "txt";
break;
case 'tsv' :
$exportExt = "tsv";
break;
case 'html' :
$exportExt = "html";
break;
case 'xml' :
$exportExt = "xml";
break;
default :
Fatal( "Unrecognised log export format '$format'" );
}
$exportKey = substr(md5(rand()),0,8);
$exportFile = "zm-log.$exportExt";
$exportPath = "temp/zm-log-$exportKey.$exportExt";
if ( !($exportFP = fopen( $exportPath, "w" )) )
Fatal( "Unable to open log export file $exportFile" );
$logs = array();
foreach ( dbFetchAll( $sql ) as $log )
{
$log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] );
$logs[] = $log;
}
switch( $format )
{
case 'text' :
{
foreach ( $logs as $log )
{
if ( $log['Line'] )
fprintf( $exportFP, "%s %s[%d].%s-%s/%d [%s]\n", $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['File'], $log['Line'], $log['Message'] );
else
fprintf( $exportFP, "%s %s[%d].%s-%s [%s]\n", $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['File'], $log['Message'] );
}
break;
}
case 'tsv' :
{
fprintf( $exportFP, $SLANG['DateTime']."\t".$SLANG['Component']."\t".$SLANG['Pid']."\t".$SLANG['Level']."\t".$SLANG['Message']."\t".$SLANG['File']."\t".$SLANG['Line']."\n" );
foreach ( $logs as $log )
{
fprintf( $exportFP, "%s\t%s\t%d\t%s\t%s\t%s\t%s\n", $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['Message'], $log['File'], $log['Line'] );
}
break;
}
case 'html' :
{
fwrite( $exportFP,
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>'.$SLANG['ZoneMinderLog'].'</title>
<style type="text/css">
body, h3, p, table, td {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
table {
border-collapse: collapse;
width: 100%;
}
th {
font-weight: bold;
}
th, td {
border: 1px solid #888888;
padding: 1px 2px;
}
tr.log-fat td {
background-color:#ffcccc;
font-weight: bold;
font-style: italics;
}
tr.log-err td {
background-color:#ffcccc;
}
tr.log-war td {
background-color: #ffe4b5;
}
tr.log-dbg td {
font-style: italics;
}
</style>
</head>
<body>
<h3>'.$SLANG['ZoneMinderLog'].'</h3>
<p>'.htmlspecialchars(preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG )).'</p>
<p>'.count($logs).' '.$SLANG['Logs'].'</p>
<table>
<tbody>
<tr><th>'.$SLANG['DateTime'].'</th><th>'.$SLANG['Component'].'</th><th>'.$SLANG['Pid'].'</th><th>'.$SLANG['Level'].'</th><th>'.$SLANG['Message'].'</th><th>'.$SLANG['File'].'</th><th>'.$SLANG['Line'].'</th></tr>
' );
foreach ( $logs as $log )
{
$classLevel = $log['Level'];
if ( $classLevel < Logger::FATAL )
$classLevel = Logger::FATAL;
elseif ( $classLevel > Logger::DEBUG )
$classLevel = Logger::DEBUG;
$logClass = 'log-'.strtolower(Logger::$codes[$classLevel]);
fprintf( $exportFP, " <tr class=\"%s\"><td>%s</td><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $logClass, $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], $log['Message'], $log['File'], $log['Line'] );
}
fwrite( $exportFP,
' </tbody>
</table>
</body>
</html>' );
break;
}
case 'xml' :
{
fwrite( $exportFP,
'<?xml version="1.0" encoding="utf-8"?>
<logexport title="'.$SLANG['ZoneMinderLog'].'" date="'.htmlspecialchars(preg_match( '/%/', DATE_FMT_CONSOLE_LONG )?strftime( DATE_FMT_CONSOLE_LONG ):date( DATE_FMT_CONSOLE_LONG )).'">
<selector>'.$_POST['selector'].'</selector>' );
foreach ( $filter as $field=>$value )
if ( $value != '' )
fwrite( $exportFP,
' <filter>
<'.strtolower($field).'>'.htmlspecialchars($value).'</'.strtolower($field).'>
</filter>' );
fwrite( $exportFP,
' <columns>
<column field="datetime">'.$SLANG['DateTime'].'</column><column field="component">'.$SLANG['Component'].'</column><column field="pid">'.$SLANG['Pid'].'</column><column field="level">'.$SLANG['Level'].'</column><column field="message">'.$SLANG['Message'].'</column><column field="file">'.$SLANG['File'].'</column><column field="line">'.$SLANG['Line'].'</column>
</columns>
<logs count="'.count($logs).'">
' );
foreach ( $logs as $log )
{
fprintf( $exportFP,
" <log>
<datetime>%s</datetime>
<component>%s</component>
<pid>%d</pid>
<level>%s</level>
<message><![CDATA[%s]]></message>
<file>%s</file>
<line>%d</line>
</log>\n", $log['DateTime'], $log['Component'], $log['Pid'], $log['Code'], utf8_decode( $log['Message'] ), $log['File'], $log['Line'] );
}
fwrite( $exportFP,
' </logs>
</logexport>' );
break;
}
$exportExt = "xml";
break;
}
fclose( $exportFP );
ajaxResponse( array(
'key' => $exportKey,
'format' => $format,
) );
break;
}
case 'download' :
{
if ( !canView( 'System' ) )
ajaxError( 'Insufficient permissions to download logs' );
if ( empty($_REQUEST['key']) )
Fatal( "No log export key given" );
$exportKey = $_REQUEST['key'];
if ( empty($_REQUEST['format']) )
Fatal( "No log export format given" );
$format = $_REQUEST['format'];
switch( $format )
{
case 'text' :
$exportExt = "txt";
break;
case 'tsv' :
$exportExt = "tsv";
break;
case 'html' :
$exportExt = "html";
break;
case 'xml' :
$exportExt = "xml";
break;
default :
Fatal( "Unrecognised log export format '$format'" );
}
$exportFile = "zm-log.$exportExt";
$exportPath = "temp/zm-log-$exportKey.$exportExt";
header( "Pragma: public" );
header( "Expires: 0" );
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
header( "Cache-Control: private", false ); // required by certain browsers
header( "Content-Description: File Transfer" );
header( 'Content-Disposition: attachment; filename="'.$exportFile.'"' );
header( "Content-Transfer-Encoding: binary" );
header( "Content-Type: application/force-download" );
header( "Content-Length: ".filesize($exportPath) );
readfile( $exportPath );
exit( 0 );
break;
}
}
ajaxError( 'Unrecognised action or insufficient permissions' );
?>

View File

@ -21,23 +21,23 @@ if ( !@socket_bind( $socket, $locSockFile ) )
switch ( $_REQUEST['command'] ) switch ( $_REQUEST['command'] )
{ {
case CMD_VARPLAY : case CMD_VARPLAY :
//error_log( "Varplaying to ".$_REQUEST['rate'] ); Debug( "Varplaying to ".$_REQUEST['rate'] );
$msg = pack( "lcn", MSG_CMD, $_REQUEST['command'], $_REQUEST['rate']+32768 ); $msg = pack( "lcn", MSG_CMD, $_REQUEST['command'], $_REQUEST['rate']+32768 );
break; break;
case CMD_ZOOMIN : case CMD_ZOOMIN :
//error_log( "Zooming to ".$_REQUEST['x'].",".$_REQUEST['y'] ); Debug( "Zooming to ".$_REQUEST['x'].",".$_REQUEST['y'] );
$msg = pack( "lcnn", MSG_CMD, $_REQUEST['command'], $_REQUEST['x'], $_REQUEST['y'] ); $msg = pack( "lcnn", MSG_CMD, $_REQUEST['command'], $_REQUEST['x'], $_REQUEST['y'] );
break; break;
case CMD_PAN : case CMD_PAN :
//error_log( "Panning to ".$_REQUEST['x'].",".$_REQUEST['y'] ); Debug( "Panning to ".$_REQUEST['x'].",".$_REQUEST['y'] );
$msg = pack( "lcnn", MSG_CMD, $_REQUEST['command'], $_REQUEST['x'], $_REQUEST['y'] ); $msg = pack( "lcnn", MSG_CMD, $_REQUEST['command'], $_REQUEST['x'], $_REQUEST['y'] );
break; break;
case CMD_SCALE : case CMD_SCALE :
//error_log( "Scaling to ".$_REQUEST['scale'] ); Debug( "Scaling to ".$_REQUEST['scale'] );
$msg = pack( "lcn", MSG_CMD, $_REQUEST['command'], $_REQUEST['scale'] ); $msg = pack( "lcn", MSG_CMD, $_REQUEST['command'], $_REQUEST['scale'] );
break; break;
case CMD_SEEK : case CMD_SEEK :
//error_log( "Seeking to ".$_REQUEST['offset'] ); Debug( "Seeking to ".$_REQUEST['offset'] );
$msg = pack( "lcN", MSG_CMD, $_REQUEST['command'], $_REQUEST['offset'] ); $msg = pack( "lcN", MSG_CMD, $_REQUEST['command'], $_REQUEST['offset'] );
break; break;
default : default :

View File

@ -3,4 +3,6 @@ AUTOMAKE_OPTIONS = gnu
webdir = @WEB_PREFIX@/css webdir = @WEB_PREFIX@/css
dist_web_DATA = \ dist_web_DATA = \
reset.css reset.css \
spinner.css \
overlay.css

View File

@ -208,7 +208,9 @@ top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = gnu AUTOMAKE_OPTIONS = gnu
webdir = @WEB_PREFIX@/css webdir = @WEB_PREFIX@/css
dist_web_DATA = \ dist_web_DATA = \
reset.css reset.css \
spinner.css \
overlay.css
all: all-am all: all-am

49
web/css/overlay.css Normal file
View File

@ -0,0 +1,49 @@
.overlayMask {
position: absolute;
opacity: 0.6;
filter: alpha(opacity=60);
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=60);
z-index: 999;
background: #aaaaaa;
}
.overlay {
display: none;
position: absolute;
background-color: #f0f0f0;
border: 2px solid #555555;
-moz-border-radius: 4px;
z-index: 1000;
overflow: hidden;
}
.overlayHeader {
float: left;
background-color: #dddddd;
width: 100%;
border-bottom: 1px solid #666666;
color: black;
}
.overlayTitle {
float: left;
padding: 10px 6px;
font-weight: bold;
width: auto;
}
.overlayToolbar {
float: right;
font-weight: bold;
padding: 6px 4px;
width: auto;
}
.overlayBody {
float: left;
width: 100%;
}
.overlayContent {
padding: 4px 4px 6px;
}

19
web/css/spinner.css Normal file
View File

@ -0,0 +1,19 @@
.spinner {
position: absolute;
opacity: 0.9;
filter: alpha(opacity=90);
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=90);
z-index: 1001;
background: #fff;
}
.spinner-msg {
text-align: center;
font-weight: bold;
}
.spinner-img {
background: url(/graphics/spinner.gif) no-repeat;
width: 24px;
height: 24px;
margin: 0 auto;
}

View File

@ -4,4 +4,5 @@ webdir = @WEB_PREFIX@/graphics
dist_web_DATA = \ dist_web_DATA = \
favicon.ico \ favicon.ico \
spinner.gif \
transparent.gif transparent.gif

View File

@ -209,6 +209,7 @@ AUTOMAKE_OPTIONS = gnu
webdir = @WEB_PREFIX@/graphics webdir = @WEB_PREFIX@/graphics
dist_web_DATA = \ dist_web_DATA = \
favicon.ico \ favicon.ico \
spinner.gif \
transparent.gif transparent.gif
all: all-am all: all-am

BIN
web/graphics/spinner.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -8,4 +8,5 @@ dist_web_DATA = \
database.php \ database.php \
functions.php \ functions.php \
control_functions.php \ control_functions.php \
lang.php lang.php \
logger.php

View File

@ -213,7 +213,8 @@ dist_web_DATA = \
database.php \ database.php \
functions.php \ functions.php \
control_functions.php \ control_functions.php \
lang.php lang.php \
logger.php
all: all-am all: all-am

View File

@ -181,7 +181,7 @@ if ( !empty($action) )
$socket = socket_create( AF_UNIX, SOCK_STREAM, 0 ); $socket = socket_create( AF_UNIX, SOCK_STREAM, 0 );
if ( $socket < 0 ) if ( $socket < 0 )
{ {
die( "socket_create() failed: ".socket_strerror($socket) ); Fatal( "socket_create() failed: ".socket_strerror($socket) );
} }
$sockFile = ZM_PATH_SOCKS.'/zmcontrol-'.$monitor['Id'].'.sock'; $sockFile = ZM_PATH_SOCKS.'/zmcontrol-'.$monitor['Id'].'.sock';
if ( @socket_connect( $socket, $sockFile ) ) if ( @socket_connect( $socket, $sockFile ) )
@ -197,7 +197,7 @@ if ( !empty($action) )
$optionString = jsonEncode( $options ); $optionString = jsonEncode( $options );
if ( !socket_write( $socket, $optionString ) ) if ( !socket_write( $socket, $optionString ) )
{ {
die( "Can't write to control socket: ".socket_strerror(socket_last_error($socket)) ); Fatal( "Can't write to control socket: ".socket_strerror(socket_last_error($socket)) );
} }
socket_close( $socket ); socket_close( $socket );
} }
@ -754,7 +754,7 @@ if ( !empty($action) )
case "web" : case "web" :
case "tools" : case "tools" :
break; break;
case "debug" : case "logging" :
case "network" : case "network" :
case "mail" : case "mail" :
case "ftp" : case "ftp" :

View File

@ -23,7 +23,18 @@
// //
define( "ZM_CONFIG", "@ZM_CONFIG@" ); // Path to config file define( "ZM_CONFIG", "@ZM_CONFIG@" ); // Path to config file
$cfg = fopen( ZM_CONFIG, "r") or die("Could not open config file."); $configFile = ZM_CONFIG;
$localConfigFile = basename($configFile);
if ( file_exists( $localConfigFile ) && filesize( $localConfigFile ) > 0 )
{
if ( php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR']) )
print( "Warning, overriding installed $localConfigFile file with local copy\n" );
else
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) ) while ( !feof($cfg) )
{ {
$str = fgets( $cfg, 256 ); $str = fgets( $cfg, 256 );

View File

@ -69,16 +69,13 @@ function dbLog( $sql, $update=false )
global $dbLogLevel; global $dbLogLevel;
$noExecute = $update && ($dbLogLevel >= DB_LOG_DEBUG); $noExecute = $update && ($dbLogLevel >= DB_LOG_DEBUG);
if ( $dbLogLevel > DB_LOG_OFF ) if ( $dbLogLevel > DB_LOG_OFF )
error_log( "SQL-LOG: $sql".($noExecute?" (not executed)":"") ); Debug( "SQL-LOG: $sql".($noExecute?" (not executed)":"") );
return( $noExecute ); return( $noExecute );
} }
function dbError( $sql ) function dbError( $sql )
{ {
$err_ref = sprintf( "%X", rand( 0x100000, 0xffffff ) ); Fatal( "SQL-ERR '".mysql_error()."', statement was '".$sql."'" );
error_log( "SQL-ERROR($err_ref): ".$sql );
error_log( "SQL-ERROR($err_ref): ".mysql_error() );
die( "An error has occurred and this operation cannot continue.<br/>For full details check your web logs for the code '$err_ref'" );
} }
function dbEscape( $string ) function dbEscape( $string )
@ -249,7 +246,7 @@ function getTableDescription( $table, $asString=1 )
//$desc['minLength'] = -128; //$desc['minLength'] = -128;
break; break;
default : default :
error_log( "Unexpected text qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'" ); Error( "Unexpected text qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'" );
break; break;
} }
} }
@ -286,7 +283,7 @@ function getTableDescription( $table, $asString=1 )
//$desc['maxValue'] = 127; //$desc['maxValue'] = 127;
break; break;
default : default :
error_log( "Unexpected integer qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'" ); Error( "Unexpected integer qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'" );
break; break;
} }
if ( !empty($matches[1]) ) if ( !empty($matches[1]) )
@ -329,7 +326,7 @@ function getTableDescription( $table, $asString=1 )
} }
else else
{ {
error_log( "Can't parse database type '".$row['Type']."' found for field '".$row['Field']."' in table '".$table."'" ); Error( "Can't parse database type '".$row['Type']."' found for field '".$row['Field']."' in table '".$table."'" );
} }
if ( $asString ) if ( $asString )

View File

@ -103,7 +103,7 @@ function getAuthUser( $auth )
$remoteAddr = $_SERVER['REMOTE_ADDR']; $remoteAddr = $_SERVER['REMOTE_ADDR'];
if ( !$remoteAddr ) if ( !$remoteAddr )
{ {
error_log( "Can't determine remote address for authentication, using empty string" ); Error( "Can't determine remote address for authentication, using empty string" );
$remoteAddr = ""; $remoteAddr = "";
} }
} }
@ -125,7 +125,7 @@ function getAuthUser( $auth )
} }
} }
} }
error_log( "Unable to authenticate user from auth hash '$auth'" ); Error( "Unable to authenticate user from auth hash '$auth'" );
return( false ); return( false );
} }
@ -611,7 +611,7 @@ function buildSelect( $name, $contents, $behaviours=false )
$value = $_REQUEST[$arr]; $value = $_REQUEST[$arr];
if ( !preg_match_all( "/\[\s*['\"]?(\w+)[\"']?\s*\]/", $matches[2], $matches ) ) if ( !preg_match_all( "/\[\s*['\"]?(\w+)[\"']?\s*\]/", $matches[2], $matches ) )
{ {
die( "Can't parse selector '$name'" ); Fatal( "Can't parse selector '$name'" );
} }
for ( $i = 0; $i < count($matches[1]); $i++ ) for ( $i = 0; $i < count($matches[1]); $i++ )
{ {
@ -1158,7 +1158,7 @@ function getImageSrc( $event, $frame, $scale=SCALE_BASE, $captureOnly=false, $ov
imagecopyresampled( $thumbImage, $image, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imageWidth, $imageHeight ); imagecopyresampled( $thumbImage, $image, 0, 0, 0, 0, $thumbWidth, $thumbHeight, $imageWidth, $imageHeight );
if ( !imagejpeg( $thumbImage, $thumbFile ) ) if ( !imagejpeg( $thumbImage, $thumbFile ) )
error_log( "Can't create thumbnail '$thumbPath'" ); Error( "Can't create thumbnail '$thumbPath'" );
} }
} }
@ -1214,7 +1214,7 @@ function createListThumbnail( $event, $overwrite=false )
} }
else else
{ {
die( "No thumbnail width or height specified, please check in Options->Web" ); Fatal( "No thumbnail width or height specified, please check in Options->Web" );
} }
$imageData = getImageSrc( $event, $frame, $scale, false, $overwrite ); $imageData = getImageSrc( $event, $frame, $scale, false, $overwrite );
@ -1601,6 +1601,7 @@ function sortTag( $field )
return( "(v)" ); return( "(v)" );
return( false ); return( false );
} }
function getLoad() function getLoad()
{ {
$uptime = shell_exec( 'uptime' ); $uptime = shell_exec( 'uptime' );
@ -2075,7 +2076,7 @@ function initX10Status()
$socket = socket_create( AF_UNIX, SOCK_STREAM, 0 ); $socket = socket_create( AF_UNIX, SOCK_STREAM, 0 );
if ( $socket < 0 ) if ( $socket < 0 )
{ {
die( "socket_create() failed: ".socket_strerror($socket) ); Fatal( "socket_create() failed: ".socket_strerror($socket) );
} }
$sock_file = ZM_PATH_SOCKS.'/zmx10.sock'; $sock_file = ZM_PATH_SOCKS.'/zmx10.sock';
if ( @socket_connect( $socket, $sock_file ) ) if ( @socket_connect( $socket, $sock_file ) )
@ -2083,7 +2084,7 @@ function initX10Status()
$command = "status"; $command = "status";
if ( !socket_write( $socket, $command ) ) if ( !socket_write( $socket, $command ) )
{ {
die( "Can't write to control socket: ".socket_strerror(socket_last_error($socket)) ); Fatal( "Can't write to control socket: ".socket_strerror(socket_last_error($socket)) );
} }
socket_shutdown( $socket, 1 ); socket_shutdown( $socket, 1 );
$x10Output = ""; $x10Output = "";
@ -2127,7 +2128,7 @@ function setDeviceStatusX10( $key, $status )
$socket = socket_create( AF_UNIX, SOCK_STREAM, 0 ); $socket = socket_create( AF_UNIX, SOCK_STREAM, 0 );
if ( $socket < 0 ) if ( $socket < 0 )
{ {
die( "socket_create() failed: ".socket_strerror($socket) ); Fatal( "socket_create() failed: ".socket_strerror($socket) );
} }
$sock_file = ZM_PATH_SOCKS.'/zmx10.sock'; $sock_file = ZM_PATH_SOCKS.'/zmx10.sock';
if ( @socket_connect( $socket, $sock_file ) ) if ( @socket_connect( $socket, $sock_file ) )
@ -2135,7 +2136,7 @@ function setDeviceStatusX10( $key, $status )
$command = "$status;$key"; $command = "$status;$key";
if ( !socket_write( $socket, $command ) ) if ( !socket_write( $socket, $command ) )
{ {
die( "Can't write to control socket: ".socket_strerror(socket_last_error($socket)) ); Fatal( "Can't write to control socket: ".socket_strerror(socket_last_error($socket)) );
} }
socket_shutdown( $socket, 1 ); socket_shutdown( $socket, 1 );
$x10Response = socket_read( $socket, 256 ); $x10Response = socket_read( $socket, 256 );
@ -2155,6 +2156,41 @@ function setDeviceStatusX10( $key, $status )
return( $status ); return( $status );
} }
function logState()
{
$state = 'ok';
$levelCounts = array(
Logger::FATAL => array( ZM_LOG_ALERT_FAT_COUNT, ZM_LOG_ALARM_FAT_COUNT ),
Logger::ERROR => array( ZM_LOG_ALERT_ERR_COUNT, ZM_LOG_ALARM_ERR_COUNT ),
Logger::WARNING => array( ZM_LOG_ALERT_WAR_COUNT, ZM_LOG_ALARM_WAR_COUNT ),
);
$sql = "select Level, count(Level) as LevelCount from Logs where Level < ".Logger::INFO." and from_unixtime(TimeKey) + interval ".ZM_LOG_CHECK_PERIOD." second > now() group by Level order by Level asc";
$counts = dbFetchAll( $sql );
foreach ( $counts as $count )
{
if ( $count['Level'] <= Logger::PANIC )
$count['Level'] = Logger::FATAL;
if ( !($levelCount = $levelCounts[$count['Level']]) )
{
Error( "Unexpected Log level ".$count['Level'] );
next;
}
if ( $levelCount[1] && $count['LevelCount'] >= $levelCount[1] )
{
$state = 'alarm';
break;
}
elseif ( $levelCount[0] && $count['LevelCount'] >= $levelCount[0] )
{
$state = 'alert';
}
}
return( $state );
}
function isVector ( &$array ) function isVector ( &$array )
{ {
$next_key = 0; $next_key = 0;
@ -2173,15 +2209,15 @@ function checkJsonError()
switch( json_last_error() ) switch( json_last_error() )
{ {
case JSON_ERROR_DEPTH : case JSON_ERROR_DEPTH :
die( "Unable to decode JSON string '$value', maximum stack depth exceeded" ); Fatal( "Unable to decode JSON string '$value', maximum stack depth exceeded" );
case JSON_ERROR_CTRL_CHAR : case JSON_ERROR_CTRL_CHAR :
die( "Unable to decode JSON string '$value', unexpected control character found" ); Fatal( "Unable to decode JSON string '$value', unexpected control character found" );
case JSON_ERROR_STATE_MISMATCH : case JSON_ERROR_STATE_MISMATCH :
die( "Unable to decode JSON string '$value', invalid or malformed JSON" ); Fatal( "Unable to decode JSON string '$value', invalid or malformed JSON" );
case JSON_ERROR_SYNTAX : case JSON_ERROR_SYNTAX :
die( "Unable to decode JSON string '$value', syntax error" ); Fatal( "Unable to decode JSON string '$value', syntax error" );
default : default :
die( "Unable to decode JSON string '$value', unexpected error ".json_last_error() ); Fatal( "Unable to decode JSON string '$value', unexpected error ".json_last_error() );
case JSON_ERROR_NONE: case JSON_ERROR_NONE:
break; break;
} }
@ -2280,9 +2316,7 @@ define( 'HTTP_STATUS_FORBIDDEN', 403 );
function ajaxError( $message, $code=HTTP_STATUS_OK ) function ajaxError( $message, $code=HTTP_STATUS_OK )
{ {
error_log( $message ); Error( $message );
if ( function_exists( 'debug_backtrace' ) )
error_log( var_export( debug_backtrace(), true ) );
if ( function_exists( 'ajaxCleanup' ) ) if ( function_exists( 'ajaxCleanup' ) )
ajaxCleanup(); ajaxCleanup();
if ( $code == HTTP_STATUS_OK ) if ( $code == HTTP_STATUS_OK )
@ -2304,7 +2338,6 @@ function ajaxResponse( $result=false )
$response = array_merge( $response, $result ); $response = array_merge( $response, $result );
elseif ( !empty($result) ) elseif ( !empty($result) )
$response['message'] = $result; $response['message'] = $result;
//error_log( var_export( $response, true ) );
header( "Content-type: text/plain" ); header( "Content-type: text/plain" );
exit( jsonEncode( $response ) ); exit( jsonEncode( $response ) );
} }

594
web/includes/logger.php Normal file
View File

@ -0,0 +1,594 @@
<?php
require_once( 'config.php' );
class Logger
{
private static $instance;
const DEBUG = 1;
const INFO = 0;
const WARNING = -1;
const ERROR = -2;
const FATAL = -3;
const PANIC = -4;
const NOLOG = -5; // Special artificial level to prevent logging
private $initialised = false;
private $id = "web";
private $idRoot = "web";
private $idArgs = "";
private $useErrorLog = true;
private $level = self::INFO;
private $termLevel = self::NOLOG;
private $databaseLevel = self::NOLOG;
private $fileLevel = self::NOLOG;
private $weblogLevel = self::NOLOG;
private $syslogLevel = self::NOLOG;
private $effectiveLevel = self::NOLOG;
private $hasTerm = false;
private $logPath = ZM_PATH_LOGS;
private $logFile = "";
private $logFd = NULL;
public static $codes = array(
self::DEBUG => "DBG",
self::INFO => "INF",
self::WARNING => "WAR",
self::ERROR => "ERR",
self::FATAL => "FAT",
self::PANIC => "PNC",
self::NOLOG => "OFF",
);
private static $syslogPriorities = array(
self::DEBUG => LOG_DEBUG,
self::INFO => LOG_INFO,
self::WARNING => LOG_WARNING,
self::ERROR => LOG_ERR,
self::FATAL => LOG_ERR,
self::PANIC => LOG_ERR,
);
private static $phpErrorLevels = array(
self::DEBUG => E_USER_NOTICE,
self::INFO => E_USER_NOTICE,
self::WARNING => E_USER_WARNING,
self::ERROR => E_USER_WARNING,
self::FATAL => E_USER_ERROR,
self::PANIC => E_USER_ERROR,
);
private function __construct()
{
$this->hasTerm = (php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR']));
$this->logFile = $this->logPath."/".$this->id.".log";
}
public function __destruct()
{
$this->terminate();
}
public function initialise( $options=array() )
{
if ( !empty($options['id']) )
$this->id = $options['id'];
//if ( isset($options['useErrorLog']) )
//$this->useErrorLog = $options['useErrorLog'];
if ( isset($options['logPath']) )
{
$this->logPath = $options['logPath'];
$tempLogFile = $this->logPath."/".$this->id.".log";
}
if ( isset($options['logFile']) )
$tempLogFile = $options['logFile'];
else
$tempLogFile = $this->logPath."/".$this->id.".log";
if ( !is_null($logFile = $this->getTargettedEnv('LOG_FILE')) )
$tempLogFile = $logFile;
$tempLevel = self::INFO;
$tempTermLevel = $this->termLevel;
$tempDatabaseLevel = $this->databaseLevel;
$tempFileLevel = $this->fileLevel;
$tempSyslogLevel = $this->syslogLevel;
$tempWeblogLevel = $this->weblogLevel;
if ( isset($options['termLevel']) )
$tempTermLevel = $options['termLevel'];
if ( isset($options['databaseLevel']) )
$tempDatabaseLevel = $options['databaseLevel'];
else
$tempDatabaseLevel = ZM_LOG_LEVEL_DATABASE;
if ( isset($options['fileLevel']) )
$tempFileLevel = $options['fileLevel'];
else
$tempFileLevel = ZM_LOG_LEVEL_FILE;
if ( isset($options['weblogLevel']) )
$tempWeblogLevel = $options['weblogLevel'];
else
$tempWeblogLevel = ZM_LOG_LEVEL_WEBLOG;
if ( isset($options['syslogLevel']) )
$tempSyslogLevel = $options['syslogLevel'];
else
$tempSyslogLevel = ZM_LOG_LEVEL_SYSLOG;
if ( isset($_ENV['LOG_PRINT']) )
$tempTermLevel = $_ENV['LOG_PRINT']? self::DEBUG : self::NOLOG;
if ( !is_null($level = $this->getTargettedEnv('LOG_LEVEL')) )
$tempLevel = $level;
if ( !is_null($level = $this->getTargettedEnv('LOG_LEVEL_TERM')) )
$tempTermLevel = $level;
if ( !is_null($level = $this->getTargettedEnv('LOG_LEVEL_DATABASE')) )
$tempDatabaseLevel = $level;
if ( !is_null($level = $this->getTargettedEnv('LOG_LEVEL_FILE')) )
$tempFileLevel = $level;
if ( !is_null($level = $this->getTargettedEnv('LOG_LEVEL_SYSLOG')) )
$tempSyslogLevel = $level;
if ( !is_null($level = $this->getTargettedEnv('LOG_LEVEL_WEBLOG')) )
$tempWeblogLevel = $level;
if ( ZM_LOG_DEBUG )
{
foreach ( explode( '|', ZM_LOG_DEBUG_TARGET ) as $target )
{
if ( $target == $this->id || $target == "_".$this->id || $target == $this->idRoot || $target == "_".$this->idRoot || $target == "" )
{
if ( ZM_LOG_DEBUG_LEVEL > self::NOLOG )
{
$tempLevel = $this->limit( ZM_LOG_DEBUG_LEVEL );
if ( ZM_LOG_DEBUG_FILE != "" )
{
$tempLogFile = ZM_LOG_DEBUG_FILE;
$tempFileLevel = $tempLevel;
}
}
}
}
}
$this->logFile( $tempLogFile );
$this->termLevel( $tempTermLevel );
$this->databaseLevel( $tempDatabaseLevel );
$this->fileLevel( $tempFileLevel );
$this->syslogLevel( $tempSyslogLevel );
$this->weblogLevel( $tempWeblogLevel );
$this->level( $tempLevel );
$this->initialised = true;
Debug( "LogOpts: level=".self::$codes[$this->level]."/".self::$codes[$this->effectiveLevel].", screen=".self::$codes[$this->termLevel].", database=".self::$codes[$this->databaseLevel].", logfile=".self::$codes[$this->fileLevel]."->".$this->logFile.", weblog=".self::$codes[$this->weblogLevel].", syslog=".self::$codes[$this->syslogLevel] );
}
private function terminate()
{
if ( $this->initialised )
{
if ( $this->fileLevel > self::NOLOG )
$this->closeFile();
if ( $this->syslogLevel > self::NOLOG )
$this->closeSyslog();
}
$this->initialised = false;
}
private function limit( $level )
{
if ( $level > self::DEBUG )
return( self::DEBUG );
if ( $level < self::NOLOG )
return( self::NOLOG );
return( $level );
}
private function getTargettedEnv( $name )
{
$envName = $name."_".$this->id;
if ( isset($ENV[$envName]) )
$value = $ENV[$envName];
if ( empty($value) && $this->id != $this->idRoot )
{
$envName = $name."_".$this->idRoot;
if ( isset($ENV[$envName]) )
$value = $ENV[$envName];
}
if ( empty($value) )
{
if ( isset($ENV[$name]) )
$value = $ENV[$name];
}
return( isset($value)?$value:NULL );
}
public static function fetch( $initialise=true )
{
if ( !isset(self::$instance) )
{
$class = __CLASS__;
self::$instance = new $class;
if ( $initialise )
self::$instance->initialise( array( 'id'=>'web_php', 'syslogLevel'=>self::INFO, 'weblogLevel'=>self::INFO ) );
}
return self::$instance;
}
public function id( $id=NULL )
{
if ( isset($id) && $this->id != $id )
{
// Remove whitespace
$id = preg_replace( '/\S/', '', $id );
// Replace non-alphanum with underscore
$id = preg_replace( '/[^a-zA-Z_]/', '_', $id );
if ( $this->id != $id )
{
$this->id = $this->idRoot = $id;
if ( preg_match( '/^([^_]+)_(.+)$/', $id, $matches ) )
{
$this->idRoot = $matches[1];
$this->idArgs = $matches[2];
}
}
}
return( $this->id );
}
public function level( $level )
{
if ( isset($level) )
{
$lastLevel = $this->level;
$this->level = $this->limit($level);
$this->effectiveLevel = self::NOLOG;
if ( $this->termLevel > $this->effectiveLevel )
$this->effectiveLevel = $this->termLevel;
if ( $this->databaseLevel > $this->effectiveLevel )
$this->effectiveLevel = $this->databaseLevel;
if ( $this->fileLevel > $this->effectiveLevel )
$this->effectiveLevel = $this->fileLevel;
if ( $this->weblogLevel > $this->effectiveLevel )
$this->effectiveLevel = $this->weblogLevel;
if ( $this->syslogLevel > $this->effectiveLevel )
$this->effectiveLevel = $this->syslogLevel;
if ( $this->effectiveLevel > $this->level )
$this->effectiveLevel = $this->level;
if ( !$this->hasTerm )
{
if ( $lastLevel < self::DEBUG && $this->level >= self::DEBUG )
{
$this->savedErrorReporting = error_reporting( E_ALL );
$this->savedDisplayErrors = ini_set( 'display_errors', true );
}
elseif ( $lastLevel >= self::DEBUG && $this->level < self::DEBUG )
{
error_reporting( $this->savedErrorReporting );
ini_set( 'display_errors', $this->savedDisplayErrors );
}
}
}
return( $this->level );
}
public function debugOn()
{
return( $this->effectiveLevel >= self::DEBUG );
}
public function termLevel( $termLevel )
{
if ( isset($termLevel) )
{
$termLevel = $this->limit($termLevel);
if ( $this->termLevel != $termLevel )
$this->termLevel = $termLevel;
}
return( $this->termLevel );
}
public function databaseLevel( $databaseLevel=NULL )
{
if ( !is_null($databaseLevel) )
{
$databaseLevel = $this->limit($databaseLevel);
if ( $this->databaseLevel != $databaseLevel )
{
$this->databaseLevel = $databaseLevel;
if ( $this->databaseLevel > self::NOLOG )
{
if ( (include_once 'database.php') === FALSE )
{
$this->databaseLevel = self::NOLOG;
Warning( "Unable to write log entries to DB, database.php not found" );
}
}
}
}
return( $this->databaseLevel );
}
public function fileLevel( $fileLevel )
{
if ( isset($fileLevel) )
{
$fileLevel = $this->limit($fileLevel);
if ( $this->fileLevel != $fileLevel )
{
if ( $this->fileLevel > self::NOLOG )
$this->closeFile();
$this->fileLevel = $fileLevel;
if ( $this->fileLevel > self::NOLOG )
$this->openFile();
}
}
return( $this->fileLevel );
}
public function weblogLevel( $weblogLevel )
{
if ( isset($weblogLevel) )
{
$weblogLevel = $this->limit($weblogLevel);
if ( $this->weblogLevel != $weblogLevel )
{
if ( $weblogLevel > self::NOLOG && $this->weblogLevel <= self::NOLOG )
{
$this->savedLogErrors = ini_set( 'log_errors', true );
}
elseif ( $weblogLevel <= self::NOLOG && $this->weblogLevel > self::NOLOG )
{
ini_set( 'log_errors', $this->savedLogErrors );
}
$this->weblogLevel = $weblogLevel;
}
}
return( $this->weblogLevel );
}
public function syslogLevel( $syslogLevel )
{
if ( isset($syslogLevel) )
{
$syslogLevel = $this->limit($syslogLevel);
if ( $this->syslogLevel != $syslogLevel )
{
if ( $this->syslogLevel > self::NOLOG )
$this->closeSyslog();
$this->syslogLevel = $syslogLevel;
if ( $this->syslogLevel > self::NOLOG )
$this->openSyslog();
}
}
return( $this->syslogLevel );
}
private function openSyslog()
{
openlog( $this->id, LOG_PID|LOG_NDELAY, LOG_LOCAL1 );
}
private function closeSyslog()
{
closelog();
}
private function logFile( $logFile )
{
if ( preg_match( '/^(.+)\+$/', $logFile, $matches ) )
$this->logFile = $matches[1].'.'.getmypid();
else
$this->logFile = $logFile;
}
private function openFile()
{
if ( !$this->useErrorLog )
{
if ( $this->logFd = fopen( $this->logFile, "a+" ) )
{
if ( strnatcmp( phpversion(), '5.2.0' ) >= 0 )
{
$error = error_get_last();
trigger_error( "Can't open log file '$logFile': ".$error['message']." @ ".$error['file']."/".$error['line'], E_USER_ERROR );
}
$this->fileLevel = self::NOLOG;
}
}
}
private function closeFile()
{
if ( $this->logFd )
fclose( $this->logFd );
}
public function logPrint( $level, $string, $file=NULL, $line=NULL )
{
if ( $level <= $this->effectiveLevel )
{
$string = preg_replace( '/[\r\n]+$/', '', $string );
$code = self::$codes[$level];
$time = gettimeofday();
$message = sprintf( "%s.%06d %s[%d].%s [%s]", strftime( "%x %H:%M:%S", $time['sec'] ), $time['usec'], $this->id, getmypid(), $code, $string );
if ( is_null( $file) )
{
if ( $this->useErrorLog || $this->databaseLevel > self::NOLOG )
{
$backTrace = debug_backtrace();
$file = $backTrace[1]['file'];
$line = $backTrace[1]['line'];
if ( $this->hasTerm )
$rootPath = getcwd();
else
$rootPath = $_SERVER['DOCUMENT_ROOT'];
$file = preg_replace( '/^'.addcslashes($rootPath,'/').'\/?/', '', $file );
}
}
if ( $this->useErrorLog )
$message .= " at ".$file." line ".$line;
else
$message = $message;
if ( $level <= $this->termLevel )
if ( $this->hasTerm )
print( $message."\n" );
else
print( preg_replace( "/\n/", '<br/>', htmlspecialchars($message) )."<br/>" );
if ( $level <= $this->fileLevel )
if ( $this->useErrorLog )
{
if ( !error_log( $message."\n", 3, $this->logFile ) )
{
if ( strnatcmp(phpversion(),'5.2.0') >= 0 )
{
$error = error_get_last();
trigger_error( "Can't write to log file '$logFile': ".$error['message']." @ ".$error['file']."/".$error['line'], E_USER_ERROR );
}
}
}
elseif ( $this->logFd )
fprintf( $this->logFd, $message."\n" );
$message = $code." [".$string."]";
if ( $level <= $this->syslogLevel )
syslog( self::$syslogPriorities[$level], $message );
if ( $level <= $this->databaseLevel )
{
$dbFile = is_null($file)?'NULL':"'".dbEscape($file)."'";
$dbLine = is_null($line)?'NULL':dbEscape($line);
$sql = "insert into Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) values ( ".sprintf( "%d.%06d", $time['sec'], $time['usec'] ).", '".dbEscape($this->id)."', ".getmypid().", ".dbEscape($level).", '".dbEscape($code)."', '".dbEscape($string)."', ".$dbFile.", ".$dbLine." )";
if (!($result = mysql_query( $sql )))
{
$this->databaseLevel = self::NOLOG;
Fatal( "Can't write log entry '$sql': ".mysql_error() );
}
}
// This has to be last as trigger_error can be fatal
if ( $level <= $this->weblogLevel )
{
if ( $this->useErrorLog )
error_log( $message, 0 );
else
trigger_error( $message, self::$phpErrorLevels[$level] );
}
}
}
};
function logInit( $options=array() )
{
$logger = Logger::fetch();
$logger->initialise( $options );
set_error_handler( 'ErrorHandler' );
}
function logToDatabase( $level=NULL )
{
return( Logger::fetch()->databaseLevel( $level ) );
}
function Mark( $level=Logger::DEBUG, $tag="Mark" )
{
Logger::fetch()->logPrint( $level, $tag );
}
function Dump( &$var, $label="VAR" )
{
ob_start();
print( $label." => " );
print_r( $var );
Logger::fetch()->logPrint( Logger::DEBUG, ob_get_clean() );
}
function Debug( $string )
{
Logger::fetch()->logPrint( Logger::DEBUG, $string );
}
function Info( $string )
{
Logger::fetch()->logPrint( Logger::INFO, $string );
}
function Warning( $string )
{
Logger::fetch()->logPrint( Logger::WARNING, $string );
}
function Error( $string )
{
Logger::fetch()->logPrint( Logger::ERROR, $string );
}
function Fatal( $string )
{
Logger::fetch()->logPrint( Logger::FATAL, $string );
die( $string );
}
function Panic( $string )
{
if ( true )
{
// Use builtin function
ob_start();
debug_print_backtrace();
$backtrace = "\n".ob_get_clean();
}
else
{
// Roll your own
$backtrace = '';
$frames = debug_backtrace();
for ( $i = 0; $i < count($frames); $i++ )
{
$frame = $frames[$i];
$backtrace .= sprintf( "\n#%d %s() at %s/%d", $i, $frame['function'], $frame['file'], $frame['line'] );
}
}
Logger::fetch()->logPrint( Logger::PANIC, $string.$backtrace );
die( $string );
}
function ErrorHandler( $error, $string, $file, $line )
{
if ( ! (error_reporting() & $error) )
{
// This error code is not included in error_reporting
return( false );
}
switch ( $error )
{
case E_USER_ERROR:
Logger::fetch()->logPrint( Logger::FATAL, $string, $file, $line );
break;
case E_USER_WARNING:
Logger::fetch()->logPrint( Logger::ERROR, $string, $file, $line );
break;
case E_USER_NOTICE:
Logger::fetch()->logPrint( Logger::WARNING, $string, $file, $line );
break;
default:
Panic( "Unknown error type: [$error] $string" );
break;
}
return( true );
}
?>

View File

@ -68,7 +68,7 @@ define( "ZM_SKIN_PATH", "skins/$skin" );
$skinBase = array(); // To allow for inheritance of skins $skinBase = array(); // To allow for inheritance of skins
if ( !file_exists( ZM_SKIN_PATH ) ) if ( !file_exists( ZM_SKIN_PATH ) )
die( "Invalid skin '$skin'" ); Fatal( "Invalid skin '$skin'" );
require_once( ZM_SKIN_PATH.'/includes/init.php' ); require_once( ZM_SKIN_PATH.'/includes/init.php' );
$skinBase[] = $skin; $skinBase[] = $skin;
@ -83,6 +83,7 @@ if ( !isset($_SESSION['skin']) || isset($_REQUEST['skin']) )
} }
require_once( 'includes/config.php' ); require_once( 'includes/config.php' );
require_once( 'includes/logger.php' );
if ( ZM_OPT_USE_AUTH ) if ( ZM_OPT_USE_AUTH )
if ( isset( $_SESSION['user'] ) ) if ( isset( $_SESSION['user'] ) )
@ -113,8 +114,7 @@ if ( isset( $_REQUEST['request'] ) )
{ {
if ( !file_exists( $includeFile ) ) if ( !file_exists( $includeFile ) )
{ {
error_log( "Request '$request' does not exist" ); Fatal( "Request '$request' does not exist" );
die( "Request '$request' does not exist" );
} }
require_once $includeFile; require_once $includeFile;
} }
@ -128,8 +128,7 @@ else
{ {
if ( !file_exists( $includeFile ) ) if ( !file_exists( $includeFile ) )
{ {
error_log( "View '$view' does not exist" ); Fatal( "View '$view' does not exist" );
die( "View '$view' does not exist" );
} }
require_once $includeFile; require_once $includeFile;
} }

View File

@ -3,4 +3,6 @@ AUTOMAKE_OPTIONS = gnu
webdir = @WEB_PREFIX@/js webdir = @WEB_PREFIX@/js
dist_web_DATA = \ dist_web_DATA = \
mootools.ext.js logger.js \
overlay.js \
mootools.ext.js

Some files were not shown because too many files have changed in this diff Show More