diff --git a/.travis.yml b/.travis.yml index da5bf96b4..f51d80cbc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,8 +32,8 @@ install: - sudo make install-libs before_script: - cd $TRAVIS_BUILD_DIR - - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then libtoolize --force; fi - - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then aclocal; fi + - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then libtoolize -v --force; fi + - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then aclocal -I m4; fi - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then autoheader; fi - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then automake --force-missing --add-missing; fi - if [ "$ZM_BUILDMETHOD" = "autotools" ]; then autoconf; fi diff --git a/CMakeLists.txt b/CMakeLists.txt index 1aab0841b..d06415909 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ include (CheckFunctionExists) include (CheckPrototypeDefinition_fixed) include (CheckTypeSize) include (CheckStructHasMember) +include (CheckSendfile) # Configuration options mark_as_advanced(FORCE ZM_EXTRA_LIBS ZM_MYSQL_ENGINE ZM_NO_MMAP CMAKE_INSTALL_FULL_BINDIR ZM_PERL_MM_PARMS ZM_PERL_SEARCH_PATH ZM_TARGET_DISTRO ZM_CONFIG_DIR) diff --git a/Makefile.am b/Makefile.am index f6d46bc3d..62f767e75 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,5 @@ AUTOMAKE_OPTIONS = foreign +ACLOCAL_AMFLAGS = -I m4 # And these to the user and group of your webserver webuser = @WEB_USER@ diff --git a/bootstrap.sh b/bootstrap.sh index 681d5b319..0bc041f18 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,5 +1,5 @@ #!/bin/bash -aclocal +aclocal -I m4 autoheader automake --add-missing autoconf diff --git a/cmake/Modules/CheckSendfile.cmake b/cmake/Modules/CheckSendfile.cmake new file mode 100644 index 000000000..1796b92e3 --- /dev/null +++ b/cmake/Modules/CheckSendfile.cmake @@ -0,0 +1,58 @@ +# Check whether sendfile() is supported and what prototype it has +include(CheckCSourceCompiles) +if (UNIX OR MINGW) +SET(CMAKE_REQUIRED_DEFINITIONS -Werror-implicit-function-declaration) +endif() +check_c_source_compiles("#include +#include +int main() +{ +sendfile(1, 1, NULL, 0); +return 0; +}" HAVE_SENDFILE4_SUPPORT) +if(HAVE_SENDFILE4_SUPPORT) +add_definitions(-DHAVE_SENDFILE4_SUPPORT=1) +unset(CMAKE_REQUIRED_DEFINITIONS) +message(STATUS "Sendfile support: Linux/Solaris sendfile()") +return() +endif() +find_library(SENDFILE_LIBRARIES NAMES sendfile) +if(SENDFILE_LIBRARIES) +include(CheckLibraryExists) +check_library_exists(sendfile sendfile ${SENDFILE_LIBRARIES} HAVE_SENDFILE4_SUPPORT) +if(HAVE_SENDFILE4_SUPPORT) +add_definitions(-DHAVE_SENDFILE4_SUPPORT=1) +unset(CMAKE_REQUIRED_DEFINITIONS) +message(STATUS "Sendfile support: Solaris sendfile()") +return() +endif() +endif() +set(SENDFILE_LIBRARIES "") +check_c_source_compiles("#include +#include +int main() +{ +sendfile(1, 1, 0, 0, NULL, NULL, 0); +return 0; +}" HAVE_SENDFILE7_SUPPORT) +if(HAVE_SENDFILE7_SUPPORT) +add_definitions(-DHAVE_SENDFILE7_SUPPORT=1) +unset(CMAKE_REQUIRED_DEFINITIONS) +message(STATUS "Sendfile support: FreeBSD sendfile()") +return() +endif() +check_c_source_compiles("#include +#include +#include +int main() +{ +sendfile(1, 1, 0, NULL, NULL, 0); +return 0; +}" HAVE_SENDFILE6_SUPPORT) +if(HAVE_SENDFILE6_SUPPORT) +add_definitions(-DHAVE_SENDFILE6_SUPPORT=1) +unset(CMAKE_REQUIRED_DEFINITIONS) +message(STATUS "Sendfile support: MacOS sendfile()") +return() +endif() + diff --git a/configure.ac b/configure.ac index a73821150..35e0e7fb9 100644 --- a/configure.ac +++ b/configure.ac @@ -3,6 +3,7 @@ AC_INIT(zm,1.28.1,[http://www.zoneminder.com/forums/ - Please check FAQ first],z AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR(src/zm.h) AC_CONFIG_HEADERS(config.h) +AC_CONFIG_MACRO_DIR([m4]) AC_SUBST([AM_CXXFLAGS], [-D__STDC_CONSTANT_MACROS]) @@ -26,6 +27,12 @@ case $host_os in *BSD*) # Do something specific for BSD HOST_OS='BSD' + AC_DEFINE(BSD,1,"This is a BSD system") + ;; + *bsd*) + # Do something specific for BSD + HOST_OS='BSD' + AC_DEFINE(BSD,1,"This is a BSD system") ;; *) #Default Case @@ -315,7 +322,8 @@ AC_FUNC_STRTOD AC_FUNC_VPRINTF AC_CHECK_FUNCS([gethostbyname gethostname gettimeofday memmove memset mkdir munmap posix_memalign putenv select sendfile socket sqrt strcasecmp strchr strcspn strerror strncasecmp strrchr strspn strstr strtol strtoull]) AC_CHECK_FUNCS([syscall sleep usleep ioctl ioctlsocket sigaction]) - +# this is required for freebsd to compile. Look for it in m4/ac_check_sendfile.m4 +AC_CHECK_SENDFILE # Other programs AC_CHECK_PROG(OPT_FFMPEG,ffmpeg,yes,no) AC_PATH_PROG(PATH_FFMPEG,ffmpeg) @@ -325,7 +333,9 @@ AC_CHECK_LIB(rt,clock_gettime,,AC_MSG_ERROR(zm requires librt)) AC_SEARCH_LIBS(mysql_init,[mysqlclient mariadbclient],,AC_MSG_ERROR(zm requires libmysqlclient.a or libmariadbclient.a)) AC_CHECK_LIB(jpeg,jpeg_start_compress,,AC_MSG_ERROR(zm requires libjpeg.a)) AC_CHECK_LIB(pthread,pthread_create,,AC_MSG_ERROR(zm requires libpthread.a)) +if test "$BSD" == "0"; then AC_CHECK_LIB(dl,dlsym,,AC_MSG_ERROR(zm requires libdl.a)) +fi if test "$ZM_SSL_LIB" == "openssl"; then AC_CHECK_HEADERS(openssl/md5.h,,AC_MSG_WARN(zm requires openssl/md5.h header to be installed for openssl),) AC_CHECK_LIB(crypto,MD5,,AC_MSG_WARN([libcrypto.a is required for authenticated streaming - use ZM_SSL_LIB option to select gnutls instead])) diff --git a/m4/ac_check_sendfile.m4 b/m4/ac_check_sendfile.m4 new file mode 100644 index 000000000..12605d588 --- /dev/null +++ b/m4/ac_check_sendfile.m4 @@ -0,0 +1,63 @@ +AC_DEFUN([AC_CHECK_SENDFILE],[ +AC_MSG_CHECKING([whether sendfile() is supported and what prototype it has]) + +saved_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -Werror-implicit-function-declaration" +ac_sendfile_supported=no +AC_TRY_LINK([#include + #include ], + [sendfile(1, 1, NULL, 0);], + [ + AC_DEFINE(HAVE_SENDFILE4_SUPPORT, 1, + [Define this if Linux/Solaris sendfile() is supported]) + AC_MSG_RESULT([Linux sendfile()]) + ac_sendfile_supported=yes + ], []) + +if test x$ac_sendfile_supported = xno; then + dnl Checking wether we need libsendfile + dnl Presumably on Solaris + AC_CHECK_LIB(sendfile, sendfile, + [ + AC_DEFINE(HAVE_SENDFILE4_SUPPORT, 1, + [Define this if Linux/Solaris sendfile() is supported]) + SENDFILE_LIBS="-lsendfile" + AC_SUBST(SENDFILE_LIBS) + AC_MSG_RESULT([Solaris sendfile()]) + ac_sendfile_supported=yes + ], []) +fi + +if test x$ac_sendfile_supported = xno; then + dnl Checking wether we have FreeBSD-like sendfile() support. + AC_TRY_LINK([#include + #include ], + [sendfile(1, 1, 0, 0, NULL, NULL, 0);], + [ + AC_DEFINE(HAVE_SENDFILE7_SUPPORT, 1, + [Define this if FreeBSD sendfile() is supported]) + AC_MSG_RESULT([FreeBSD sendfile()]) + ac_sendfile_supported=yes + ], []) +fi + +if test x$ac_sendfile_supported = xno; then + dnl Checking wether we have MacOS-like sendfile() support. + AC_TRY_LINK([#include + #include + #include ], + [sendfile(1, 1, 0, NULL, NULL, 0);], + [ + AC_DEFINE(HAVE_SENDFILE6_SUPPORT, 1, + [Define this if MacOS sendfile() is supported]) + AC_MSG_RESULT([MacOS sendfile()]) + ac_sendfile_supported=yes + ], []) +fi + +CFLAGS="$saved_CFLAGS" + +if test x$ac_sendfile_supported = xno; then + AC_MSG_RESULT([no sendfile() support, using read/send]) +fi +]) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in index 21f7a2d50..5a6c0b774 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/Config.pm.in @@ -72,8 +72,9 @@ BEGIN print( STDERR "Warning, overriding installed $local_config_file file with local copy\n" ); $config_file = $local_config_file; } - open( CONFIG, "<".$config_file ) or croak( "Can't open config file '$config_file': $!" ); - foreach my $str ( ) + open( my $CONFIG, "<", $config_file ) + or croak( "Can't open config file '$config_file': $!" ); + foreach my $str ( <$CONFIG> ) { next if ( $str =~ /^\s*$/ ); next if ( $str =~ /^\s*#/ ); @@ -85,7 +86,7 @@ BEGIN $name =~ tr/a-z/A-Z/; $Config{$name} = $value; } - close( CONFIG ); + close( $CONFIG ); use DBI; my $dbh = DBI->connect( "DBI:mysql:database=".$Config{ZM_DB_NAME}.";host=".$Config{ZM_DB_HOST}, $Config{ZM_DB_USER}, $Config{ZM_DB_PASS} ) or croak( "Can't connect to db" ); diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control.pm index 2a646772d..2e93d4f93 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control.pm @@ -75,7 +75,7 @@ sub AUTOLOAD croak( "Can't access $name member of object of class $class" ); } -sub getKey() +sub getKey { my $self = shift; return( $self->{id} ); @@ -145,7 +145,7 @@ sub executeCommand &{$self->{$command}}( $self, $params ); } -sub printMsg() +sub printMsg { my $self = shift; Fatal( "No printMsg method defined for protocol ".$self->{name} ); diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoP.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoP.pm index c9d9d907d..c8fafe023 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoP.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/PelcoP.pm @@ -22,7 +22,7 @@ # This module contains the implementation of the Pelco-P camera control # protocol # -package ZoneMinder::Control::PelcoD; +package ZoneMinder::Control::PelcoP; use 5.006; use strict; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Database.pm b/scripts/ZoneMinder/lib/ZoneMinder/Database.pm index 29b3c8b2a..94e82da4c 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Database.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Database.pm @@ -70,7 +70,7 @@ use Carp; our $dbh = undef; -sub zmDbConnect( ;$ ) +sub zmDbConnect { my $force = shift; if ( $force ) @@ -94,7 +94,7 @@ sub zmDbConnect( ;$ ) return( $dbh ); } -sub zmDbDisconnect() +sub zmDbDisconnect { if ( defined( $dbh ) ) { @@ -110,7 +110,7 @@ use constant DB_MON_MOTION => 3; # All monitors that are doing motion detection use constant DB_MON_RECORD => 4; # All monitors that are doing unconditional recording use constant DB_MON_PASSIVE => 5; # All monitors that are in nodect state -sub zmDbGetMonitors( ;$ ) +sub zmDbGetMonitors { zmDbConnect(); @@ -152,7 +152,7 @@ sub zmDbGetMonitors( ;$ ) return( \@monitors ); } -sub zmDbGetMonitor( $ ) +sub zmDbGetMonitor { zmDbConnect(); @@ -168,7 +168,7 @@ sub zmDbGetMonitor( $ ) return( $monitor ); } -sub zmDbGetMonitorAndControl( $ ) +sub zmDbGetMonitorAndControl { zmDbConnect(); diff --git a/scripts/ZoneMinder/lib/ZoneMinder/General.pm b/scripts/ZoneMinder/lib/ZoneMinder/General.pm index 4d60852a7..0be45e34d 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/General.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/General.pm @@ -76,7 +76,7 @@ use ZoneMinder::Database qw(:all); use POSIX; # For running general shell commands -sub executeShellCommand( $ ) +sub executeShellCommand { my $command = shift; my $output = qx( $command ); @@ -90,7 +90,7 @@ sub executeShellCommand( $ ) return( $status ); } -sub getCmdFormat() +sub getCmdFormat { Debug( "Testing valid shell syntax\n" ); @@ -162,7 +162,7 @@ our $testedShellSyntax = 0; our ( $cmdPrefix, $cmdSuffix ); # For running ZM daemons etc -sub runCommand( $ ) +sub runCommand { if ( !$testedShellSyntax ) { @@ -196,7 +196,7 @@ sub runCommand( $ ) return( $output ); } -sub getEventPath( $ ) +sub getEventPath { my $event = shift; @@ -213,7 +213,7 @@ sub getEventPath( $ ) return( $event_path ); } -sub createEventPath( $ ) +sub createEventPath { # # WARNING assumes running from events directory @@ -250,8 +250,9 @@ sub createEventPath( $ ) # Create empty id tag file $idFile = sprintf( "%s/.%d", $eventPath, $event->{Id} ); - open( ID_FP, ">$idFile" ) or Fatal( "Can't open $idFile: $!" ); - close( ID_FP ); + open( my $ID_FP, ">", $idFile ) + or Fatal( "Can't open $idFile: $!" ); + close( $ID_FP ); setFileOwner( $idFile ); } else @@ -260,8 +261,9 @@ sub createEventPath( $ ) $eventPath .= '/'.$event->{Id}; my $idFile = sprintf( "%s/.%d", $eventPath, $event->{Id} ); - open( ID_FP, ">$idFile" ) or Fatal( "Can't open $idFile: $!" ); - close( ID_FP ); + open( my $ID_FP, ">", $idFile ) + or Fatal( "Can't open $idFile: $!" ); + close( $ID_FP ); setFileOwner( $idFile ); } return( $eventPath ); @@ -272,7 +274,7 @@ use Data::Dumper; our $_setFileOwner = undef; our ( $_ownerUid, $_ownerGid ); -sub _checkProcessOwner() +sub _checkProcessOwner { if ( !defined($_setFileOwner) ) { @@ -291,7 +293,7 @@ sub _checkProcessOwner() return( $_setFileOwner ); } -sub setFileOwner( $ ) +sub setFileOwner { my $file = shift; @@ -303,7 +305,7 @@ sub setFileOwner( $ ) our $_hasImageInfo = undef; -sub _checkForImageInfo() +sub _checkForImageInfo { if ( !defined($_hasImageInfo) ) { @@ -317,7 +319,7 @@ sub _checkForImageInfo() return( $_hasImageInfo ); } -sub createEvent( $;$ ) +sub createEvent { my $event = shift; @@ -447,7 +449,7 @@ sub createEvent( $;$ ) } } -sub addEventImage( $$ ) +sub addEventImage { my $event = shift; my $frame = shift; @@ -455,7 +457,7 @@ sub addEventImage( $$ ) # TBD } -sub updateEvent( $ ) +sub updateEvent { my $event = shift; @@ -488,7 +490,7 @@ sub updateEvent( $ ) my $res = $sth->execute( @values ) or Fatal( "Can't execute sql '$sql': ".$sth->errstr() ); } -sub deleteEventFiles( $;$ ) +sub deleteEventFiles { # # WARNING assumes running from events directory @@ -541,7 +543,7 @@ sub deleteEventFiles( $;$ ) } } -sub makePath( $;$ ) +sub makePath { my $path = shift; my $root = shift; @@ -585,7 +587,7 @@ sub _testJSON $hasJSONAny = 1 if ( $result ); } -sub _getJSONType( $ ) +sub _getJSONType { my $value = shift; return( 'null' ) unless( defined($value) ); @@ -596,9 +598,9 @@ sub _getJSONType( $ ) return( 'string' ); } -sub jsonEncode( $ ); +sub jsonEncode; -sub jsonEncode( $ ) +sub jsonEncode { my $value = shift; @@ -649,7 +651,7 @@ sub jsonEncode( $ ) } } -sub jsonDecode( $ ) +sub jsonDecode { my $value = shift; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm b/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm index ea786e66a..e10c18a96 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Logger.pm @@ -126,6 +126,7 @@ our %priorities = ( ); our $logger; +our $LOGFILE; sub new { @@ -290,7 +291,7 @@ sub initialise( @ ) 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() +sub terminate { my $this = shift; return unless ( $this->{initialised} ); @@ -300,7 +301,7 @@ sub terminate() $this->termLevel( NOLOG ); } -sub reinitialise() +sub reinitialise { my $this = shift; @@ -322,7 +323,7 @@ sub reinitialise() $this->databaseLevel( $databaseLevel ) if ( $databaseLevel > NOLOG ); } -sub limit( $ ) +sub limit { my $this = shift; my $level = shift; @@ -331,7 +332,7 @@ sub limit( $ ) return( $level ); } -sub getTargettedEnv( $ ) +sub getTargettedEnv { my $this = shift; my $name = shift; @@ -354,7 +355,7 @@ sub getTargettedEnv( $ ) return( $value ); } -sub fetch() +sub fetch { if ( !$logger ) { @@ -364,7 +365,7 @@ sub fetch() return( $logger ); } -sub id( ;$ ) +sub id { my $this = shift; my $id = shift; @@ -388,7 +389,7 @@ sub id( ;$ ) return( $this->{id} ); } -sub level( ;$ ) +sub level { my $this = shift; my $level = shift; @@ -405,20 +406,20 @@ sub level( ;$ ) return( $this->{level} ); } -sub debugOn() +sub debugOn { my $this = shift; return( $this->{effectiveLevel} >= DEBUG ); } -sub trace( ;$ ) +sub trace { my $this = shift; $this->{trace} = $_[0] if ( @_ ); return( $this->{trace} ); } -sub termLevel( ;$ ) +sub termLevel { my $this = shift; my $termLevel = shift; @@ -434,7 +435,7 @@ sub termLevel( ;$ ) return( $this->{termLevel} ); } -sub databaseLevel( ;$ ) +sub databaseLevel { my $this = shift; my $databaseLevel = shift; @@ -486,7 +487,7 @@ sub databaseLevel( ;$ ) return( $this->{databaseLevel} ); } -sub fileLevel( ;$ ) +sub fileLevel { my $this = shift; my $fileLevel = shift; @@ -503,7 +504,7 @@ sub fileLevel( ;$ ) return( $this->{fileLevel} ); } -sub syslogLevel( ;$ ) +sub syslogLevel { my $this = shift; my $syslogLevel = shift; @@ -520,19 +521,19 @@ sub syslogLevel( ;$ ) return( $this->{syslogLevel} ); } -sub openSyslog() +sub openSyslog { my $this = shift; openlog( $this->{id}, "pid", "local1" ); } -sub closeSyslog() +sub closeSyslog { my $this = shift; #closelog(); } -sub logFile( $ ) +sub logFile { my $this = shift; my $logFile = shift; @@ -546,18 +547,19 @@ sub logFile( $ ) } } -sub openFile() +sub openFile { my $this = shift; - if ( open( LOGFILE, ">>".$this->{logFile} ) ) + if ( open( $LOGFILE, ">>", $this->{logFile} ) ) { - LOGFILE->autoflush() if ( $this->{autoFlush} ); + $LOGFILE->autoflush() if ( $this->{autoFlush} ); my $webUid = (getpwnam( $Config{ZM_WEB_USER} ))[2]; my $webGid = (getgrnam( $Config{ZM_WEB_GROUP} ))[2]; if ( $> == 0 ) { - chown( $webUid, $webGid, $this->{logFile} ) or Fatal( "Can't change permissions on log file '".$this->{logFile}."': $!" ) + chown( $webUid, $webGid, $this->{logFile} ) + or Fatal( "Can't change permissions on log file '".$this->{logFile}."': $!" ) } } else @@ -567,13 +569,13 @@ sub openFile() } } -sub closeFile() +sub closeFile { my $this = shift; - close( LOGFILE ) if ( fileno(LOGFILE) ); + close( $LOGFILE ) if ( fileno($LOGFILE) ); } -sub logPrint( $;$ ) +sub logPrint { my $this = shift; my $level = shift; @@ -596,7 +598,7 @@ sub logPrint( $;$ ) $message = $message."\n"; } syslog( $priorities{$level}, $code." [%s]", $string ) if ( $level <= $this->{syslogLevel} ); - print( LOGFILE $message ) if ( $level <= $this->{fileLevel} ); + 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 )"; @@ -624,7 +626,7 @@ sub logInit( ;@ ) $logger->initialise( %options ); } -sub logReinit() +sub logReinit { fetch()->reinitialise(); } @@ -636,7 +638,7 @@ sub logTerm $logger = undef; } -sub logHupHandler() +sub logHupHandler { my $savedErrno = $!; return unless( $logger ); @@ -645,47 +647,47 @@ sub logHupHandler() $! = $savedErrno; } -sub logSetSignal() +sub logSetSignal { $SIG{HUP} = \&logHupHandler; } -sub logClearSignal() +sub logClearSignal { $SIG{HUP} = 'DEFAULT'; } -sub logLevel( ;$ ) +sub logLevel { return( fetch()->level( @_ ) ); } -sub logDebugging() +sub logDebugging { return( fetch()->debugOn() ); } -sub logTermLevel( ;$ ) +sub logTermLevel { return( fetch()->termLevel( @_ ) ); } -sub logDatabaseLevel( ;$ ) +sub logDatabaseLevel { return( fetch()->databaseLevel( @_ ) ); } -sub logFileLevel( ;$ ) +sub logFileLevel { return( fetch()->fileLevel( @_ ) ); } -sub logSyslogLevel( ;$ ) +sub logSyslogLevel { return( fetch()->syslogLevel( @_ ) ); } -sub Mark( ;$$ ) +sub Mark { my $level = shift; $level = DEBUG unless( defined($level) ); @@ -693,7 +695,7 @@ sub Mark( ;$$ ) fetch()->logPrint( $level, $tag ); } -sub Dump( \$;$ ) +sub Dump { my $var = shift; my $label = shift; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Memory.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/Memory.pm.in index fbb213414..b2e0fb448 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Memory.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/Memory.pm.in @@ -249,7 +249,7 @@ sub zmMemInit &zmMemInit(); -sub zmMemVerify( $ ) +sub zmMemVerify { my $monitor = shift; if ( !zmMemAttach( $monitor, $mem_size ) ) @@ -291,7 +291,7 @@ sub zmMemVerify( $ ) return( !undef ); } -sub zmMemRead( $$;$ ) +sub zmMemRead { my $monitor = shift; my $fields = shift; @@ -387,7 +387,7 @@ sub zmMemRead( $$;$ ) return( $values[0] ); } -sub zmMemInvalidate( $ ) +sub zmMemInvalidate { my $monitor = shift; my $mem_key = zmMemKey($monitor); @@ -398,12 +398,12 @@ sub zmMemInvalidate( $ ) } } -sub zmMemTidy() +sub zmMemTidy { zmMemClean(); } -sub zmMemWrite( $$;$ ) +sub zmMemWrite { my $monitor = shift; my $field_values = shift; @@ -489,21 +489,21 @@ sub zmMemWrite( $$;$ ) return( !undef ); } -sub zmGetMonitorState( $ ) +sub zmGetMonitorState { my $monitor = shift; return( zmMemRead( $monitor, "shared_data:state" ) ); } -sub zmGetAlarmLocation( $ ) +sub zmGetAlarmLocation { my $monitor = shift; return( zmMemRead( $monitor, [ "shared_data:alarm_x", "shared_data:alarm_y" ] ) ); } -sub zmSetControlState( $$ ) +sub zmSetControlState { my $monitor = shift; my $control_state = shift; @@ -511,14 +511,14 @@ sub zmSetControlState( $$ ) zmMemWrite( $monitor, { "shared_data:control_state" => $control_state } ); } -sub zmGetControlState( $ ) +sub zmGetControlState { my $monitor = shift; return( zmMemRead( $monitor, "shared_data:control_state" ) ); } -sub zmSaveControlState( $$ ) +sub zmSaveControlState { my $monitor = shift; my $control_state = shift; @@ -526,14 +526,14 @@ sub zmSaveControlState( $$ ) zmSetControlState( $monitor, freeze( $control_state ) ); } -sub zmRestoreControlState( $ ) +sub zmRestoreControlState { my $monitor = shift; return( thaw( zmGetControlState( $monitor ) ) ); } -sub zmIsAlarmed( $ ) +sub zmIsAlarmed { my $monitor = shift; @@ -542,7 +542,7 @@ sub zmIsAlarmed( $ ) return( $state == STATE_ALARM ); } -sub zmInAlarm( $ ) +sub zmInAlarm { my $monitor = shift; @@ -551,7 +551,7 @@ sub zmInAlarm( $ ) return( $state == STATE_ALARM || $state == STATE_ALERT ); } -sub zmHasAlarmed( $$ ) +sub zmHasAlarmed { my $monitor = shift; my $last_event_id = shift; @@ -569,35 +569,35 @@ sub zmHasAlarmed( $$ ) return( undef ); } -sub zmGetLastEvent( $ ) +sub zmGetLastEvent { my $monitor = shift; return( zmMemRead( $monitor, "shared_data:last_event" ) ); } -sub zmGetLastWriteTime( $ ) +sub zmGetLastWriteTime { my $monitor = shift; return( zmMemRead( $monitor, "shared_data:last_write_time" ) ); } -sub zmGetLastReadTime( $ ) +sub zmGetLastReadTime { my $monitor = shift; return( zmMemRead( $monitor, "shared_data:last_read_time" ) ); } -sub zmGetMonitorActions( $ ) +sub zmGetMonitorActions { my $monitor = shift; return( zmMemRead( $monitor, "shared_data:action" ) ); } -sub zmMonitorEnable( $ ) +sub zmMonitorEnable { my $monitor = shift; @@ -606,7 +606,7 @@ sub zmMonitorEnable( $ ) zmMemWrite( $monitor, { "shared_data:action" => $action } ); } -sub zmMonitorDisable( $ ) +sub zmMonitorDisable { my $monitor = shift; @@ -615,7 +615,7 @@ sub zmMonitorDisable( $ ) zmMemWrite( $monitor, { "shared_data:action" => $action } ); } -sub zmMonitorSuspend( $ ) +sub zmMonitorSuspend { my $monitor = shift; @@ -624,7 +624,7 @@ sub zmMonitorSuspend( $ ) zmMemWrite( $monitor, { "shared_data:action" => $action } ); } -sub zmMonitorResume( $ ) +sub zmMonitorResume { my $monitor = shift; @@ -633,14 +633,14 @@ sub zmMonitorResume( $ ) zmMemWrite( $monitor, { "shared_data:action" => $action } ); } -sub zmGetTriggerState( $ ) +sub zmGetTriggerState { my $monitor = shift; return( zmMemRead( $monitor, "trigger_data:trigger_state" ) ); } -sub zmTriggerEventOn( $$$;$$ ) +sub zmTriggerEventOn { my $monitor = shift; my $score = shift; @@ -659,7 +659,7 @@ sub zmTriggerEventOn( $$$;$$ ) zmMemWrite( $monitor, $values ); } -sub zmTriggerEventOff( $ ) +sub zmTriggerEventOff { my $monitor = shift; @@ -674,7 +674,7 @@ sub zmTriggerEventOff( $ ) zmMemWrite( $monitor, $values ); } -sub zmTriggerEventCancel( $ ) +sub zmTriggerEventCancel { my $monitor = shift; @@ -689,7 +689,7 @@ sub zmTriggerEventCancel( $ ) zmMemWrite( $monitor, $values ); } -sub zmTriggerShowtext( $$ ) +sub zmTriggerShowtext { my $monitor = shift; my $showtext = shift; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm b/scripts/ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm index 173c48493..7b5f41a1c 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Memory/Mapped.pm @@ -68,13 +68,13 @@ use ZoneMinder::Logger qw(:all); use Sys::Mmap; -sub zmMemKey( $ ) +sub zmMemKey { my $monitor = shift; return( defined($monitor->{MMapAddr})?$monitor->{MMapAddr}:undef ); } -sub zmMemAttach( $$ ) +sub zmMemAttach { my ( $monitor, $size ) = @_; if ( ! $size ) { @@ -96,7 +96,7 @@ sub zmMemAttach( $$ ) Error( sprintf( "Memory map file '%s' should have been %d but was instead %d", $mmap_file, $size, $mmap_file_size ) ); return ( undef ); } - if ( !open( MMAP, "+<".$mmap_file ) ) + if ( !open( MMAP, "+<", $mmap_file ) ) { Error( sprintf( "Can't open memory map file '%s': $!\n", $mmap_file ) ); return( undef ); @@ -116,7 +116,7 @@ sub zmMemAttach( $$ ) return( !undef ); } -sub zmMemDetach( $ ) +sub zmMemDetach { my $monitor = shift; @@ -138,7 +138,7 @@ sub zmMemDetach( $ ) } } -sub zmMemGet( $$$ ) +sub zmMemGet { my $monitor = shift; my $offset = shift; @@ -154,7 +154,7 @@ sub zmMemGet( $$$ ) return( $data ); } -sub zmMemPut( $$$$ ) +sub zmMemPut { my $monitor = shift; my $offset = shift; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm b/scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm index 59dc399f1..2b8bde5ba 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Memory/Shared.pm @@ -69,13 +69,13 @@ our $VERSION = $ZoneMinder::Base::VERSION; use ZoneMinder::Config qw(:all); use ZoneMinder::Logger qw(:all); -sub zmMemKey( $ ) +sub zmMemKey { my $monitor = shift; return( defined($monitor->{ShmKey})?$monitor->{ShmKey}:undef ); } -sub zmMemAttach( $$ ) +sub zmMemAttach { my $monitor = shift; my $size = shift; @@ -94,14 +94,14 @@ sub zmMemAttach( $$ ) return( !undef ); } -sub zmMemDetach( $ ) +sub zmMemDetach { my $monitor = shift; delete $monitor->{ShmId}; } -sub zmMemGet( $$$ ) +sub zmMemGet { my $monitor = shift; my $offset = shift; @@ -119,7 +119,7 @@ sub zmMemGet( $$$ ) return( $data ); } -sub zmMemPut( $$$$ ) +sub zmMemPut { my $monitor = shift; my $offset = shift; @@ -143,8 +143,9 @@ sub zmMemClean # Find ZoneMinder shared memory my $command = "ipcs -m | grep '^".substr( sprintf( "0x%x", hex($Config{ZM_SHM_KEY}) ), 0, -2 )."'"; Debug( "Checking for shared memory with '$command'\n" ); - open( CMD, "$command |" ) or Fatal( "Can't execute '$command': $!" ); - while( ) + open( my $CMD, '<', "$command |" ) + or Fatal( "Can't execute '$command': $!" ); + while( <$CMD> ) { chomp; my ( $key, $id ) = split( /\s+/ ); @@ -156,7 +157,7 @@ sub zmMemClean qx( $command ); } } - close( CMD ); + close( $CMD ); } 1; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel.pm b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel.pm index 0344e6d94..31b4cbe03 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel.pm @@ -63,33 +63,33 @@ sub clone bless $clone, ref $self; } -sub open() +sub open { my $self = shift; my $class = ref($self) or croak( "Can't get class for non object $self" ); croak( "Abstract base class method called for object of class $class" ); } -sub close() +sub close { my $self = shift; my $class = ref($self) or croak( "Can't get class for non object $self" ); croak( "Abstract base class method called for object of class $class" ); } -sub getState() +sub getState { my $self = shift; return( $self->{state} ); } -sub isOpen() +sub isOpen { my $self = shift; return( $self->{state} eq "open" ); } -sub isConnected() +sub isConnected { my $self = shift; return( $self->{state} eq "connected" ); diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/File.pm b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/File.pm index 234dae3d7..c0f4ef1a4 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/File.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/File.pm @@ -56,13 +56,13 @@ sub new return $self; } -sub open() +sub open { my $self = shift; local *sfh; #sysopen( *sfh, $conn->{path}, O_NONBLOCK|O_RDONLY ) or croak( "Can't sysopen: $!" ); #open( *sfh, "<".$conn->{path} ) or croak( "Can't open: $!" ); - open( *sfh, "+<".$self->{path} ) or croak( "Can't open: $!" ); + open( *sfh, "+<", $self->{path} ) or croak( "Can't open: $!" ); $self->{state} = 'open'; $self->{handle} = *sfh; } diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Handle.pm b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Handle.pm index 353dc4a32..0781150e2 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Handle.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Handle.pm @@ -59,7 +59,7 @@ sub spawns return( undef ); } -sub close() +sub close { my $self = shift; close( $self->{handle} ); @@ -67,7 +67,7 @@ sub close() $self->{handle} = undef; } -sub read() +sub read { my $self = shift; my $buffer; @@ -80,7 +80,7 @@ sub read() return( $buffer ); } -sub write() +sub write { my $self = shift; my $buffer = shift; @@ -94,7 +94,7 @@ sub write() return( !undef ); } -sub fileno() +sub fileno { my $self = shift; return( defined($self->{handle})?fileno($self->{handle}):-1 ); diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Inet.pm b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Inet.pm index 68df0980f..7b8b0163c 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Inet.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Inet.pm @@ -57,7 +57,7 @@ sub new return $self; } -sub open() +sub open { my $self = shift; local *sfh; @@ -70,7 +70,7 @@ sub open() $self->{handle} = *sfh; } -sub _spawn( $ ) +sub _spawn { my $self = shift; my $new_handle = shift; @@ -80,7 +80,7 @@ sub _spawn( $ ) return( $clone ); } -sub accept() +sub accept { my $self = shift; local *cfh; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Serial.pm b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Serial.pm index 7e4ad4730..373b9e615 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Serial.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Serial.pm @@ -54,7 +54,7 @@ sub new return $self; } -sub open() +sub open { my $self = shift; my $device = new Device::SerialPort( $self->{path} ); @@ -72,14 +72,14 @@ sub open() $self->{state} = 'connected'; } -sub close() +sub close { my $self = shift; $self->{device}->close(); $self->{state} = 'closed'; } -sub read() +sub read { my $self = shift; my $buffer = $self->{device}->lookfor(); @@ -91,7 +91,7 @@ sub read() return( $buffer ); } -sub write() +sub write { my $self = shift; my $buffer = shift; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Unix.pm b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Unix.pm index a671ccd66..8ef593870 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Unix.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Channel/Unix.pm @@ -57,7 +57,7 @@ sub new return $self; } -sub open() +sub open { my $self = shift; local *sfh; @@ -69,7 +69,7 @@ sub open() $self->{handle} = *sfh; } -sub _spawn( $ ) +sub _spawn { my $self = shift; my $new_handle = shift; @@ -79,7 +79,7 @@ sub _spawn( $ ) return( $clone ); } -sub accept() +sub accept { my $self = shift; local *cfh; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Connection.pm b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Connection.pm index 41b332d46..bd28e50ff 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Connection.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Trigger/Connection.pm @@ -71,7 +71,7 @@ sub spawns return( $self->{channel}->spawns() ); } -sub _spawn( $ ) +sub _spawn { my $self = shift; my $new_channel = shift; @@ -80,50 +80,50 @@ sub _spawn( $ ) return( $clone ); } -sub accept() +sub accept { my $self = shift; my $new_channel = $self->{channel}->accept(); return( $self->_spawn( $new_channel ) ); } -sub open() +sub open { my $self = shift; return( $self->{channel}->open() ); } -sub close() +sub close { my $self = shift; return( $self->{channel}->close() ); } -sub fileno() +sub fileno { my $self = shift; return( $self->{channel}->fileno() ); } -sub isOpen() +sub isOpen { my $self = shift; return( $self->{channel}->isOpen() ); } -sub isConnected() +sub isConnected { my $self = shift; return( $self->{channel}->isConnected() ); } -sub canRead() +sub canRead { my $self = shift; return( $self->{input} && $self->isConnected() ); } -sub canWrite() +sub canWrite { my $self = shift; return( $self->{output} && $self->isConnected() ); diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 1c7e13e7d..464fe7e56 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -36,6 +36,12 @@ #include "zm_event.h" #include "zm_monitor.h" +// sendfile tricks +extern "C" +{ +#include "zm_sendfile.h" +} + #include "zmf.h" #if HAVE_SYS_SENDFILE_H @@ -1309,7 +1315,7 @@ bool EventStream::sendFrame( int delta_us ) if(send_raw) { #if HAVE_SENDFILE fprintf( stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size ); - if(sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size) { + if(zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size) { /* sendfile() failed, use standard way instead */ img_buffer_size = fread( img_buffer, 1, sizeof(temp_img_buffer), fdj ); if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) { diff --git a/src/zm_logger.cpp b/src/zm_logger.cpp index c64f6e7c0..4b37580f7 100644 --- a/src/zm_logger.cpp +++ b/src/zm_logger.cpp @@ -31,6 +31,9 @@ #include #include #include +#ifdef __FreeBSD__ +#include +#endif bool Logger::smInitialised = false; Logger *Logger::smInstance = 0; @@ -527,9 +530,17 @@ void Logger::logPrint( bool hex, const char * const file, const int line, const #endif pid_t tid; +#ifdef __FreeBSD__ + long lwpid; + thr_self(&lwpid); + tid = lwpid; + + if (tid < 0 ) // Thread/Process id +#else #ifdef HAVE_SYSCALL if ( (tid = syscall(SYS_gettid)) < 0 ) // Thread/Process id #endif // HAVE_SYSCALL +#endif tid = getpid(); // Process id char *logPtr = logString; diff --git a/src/zm_sendfile.h b/src/zm_sendfile.h new file mode 100644 index 000000000..ce3405d66 --- /dev/null +++ b/src/zm_sendfile.h @@ -0,0 +1,31 @@ +#ifdef HAVE_SENDFILE4_SUPPORT +#include +int zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) { + int err; + + err = sendfile(out_fd, in_fd, offset, size); + if (err < 0) + return -errno; + + return err; +} +#elif HAVE_SENDFILE7_SUPPORT +#include +#include +#include +int zm_sendfile(int out_fd, int in_fd, off_t *offset, off_t size) { + int err; + err = sendfile(in_fd, out_fd, *offset, size, NULL, &size, 0); + if (err && errno != EAGAIN) + return -errno; + + if (size) { + *offset += size; + return size; + } + + return -EAGAIN; +} +#else +#error "Your platform does not support sendfile. Sorry." +#endif diff --git a/src/zm_thread.h b/src/zm_thread.h index 6a0d169f0..3ba80c09f 100644 --- a/src/zm_thread.h +++ b/src/zm_thread.h @@ -28,12 +28,26 @@ #endif // HAVE_SYS_SYSCALL_H #include "zm_exception.h" #include "zm_utils.h" +#ifdef __FreeBSD__ +#include +#endif class ThreadException : public Exception { +private: +pid_t pid() { +pid_t tid; +#ifdef __FreeBSD__ +long lwpid; +thr_self(&lwpid); +tid = lwpid; +#else +tid=syscall(SYS_gettid); +#endif +return tid; +} public: - ThreadException( const std::string &message ) : Exception( stringtf( "(%d) "+message, (long int)syscall(SYS_gettid) ) ) - { + ThreadException( const std::string &message ) : Exception( stringtf( "(%d) "+message, (long int)pid() ) ) { } }; @@ -205,7 +219,15 @@ protected: pid_t id() const { - return( (pid_t)syscall(SYS_gettid) ); +pid_t tid; +#ifdef __FreeBSD__ +long lwpid; +thr_self(&lwpid); +tid = lwpid; +#else +tid=syscall(SYS_gettid); +#endif +return tid; } void exit( int status = 0 ) { diff --git a/src/zm_timer.h b/src/zm_timer.h index 6c7663b87..80461cf07 100644 --- a/src/zm_timer.h +++ b/src/zm_timer.h @@ -32,8 +32,20 @@ class Timer private: class TimerException : public Exception { + private: + pid_t pid() { + pid_t tid; +#ifdef __FreeBSD__ + long lwpid; + thr_self(&lwpid); + tid = lwpid; +#else + tid=syscall(SYS_gettid); +#endif + return tid; + } public: - TimerException( const std::string &message ) : Exception( stringtf( "(%d) "+message, (long int)syscall(SYS_gettid) ) ) + TimerException( const std::string &message ) : Exception( stringtf( "(%d) "+message, (long int)pid() ) ) { } }; diff --git a/src/zmc.cpp b/src/zmc.cpp index cbfc80e37..e97f0054f 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -19,12 +19,16 @@ #include #include -#if defined(BSD) +#if defined(__FreeBSD__) #include #else #include #endif +#if !defined(MAXINT) +#define MAXINT INT_MAX +#endif + #include "zm.h" #include "zm_db.h" #include "zm_time.h"