diff --git a/Dockerfile b/Dockerfile index 2c72f0f38..40f759a5b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,7 +43,7 @@ ADD utils/docker/start.sh /tmp/start.sh RUN chown -R www-data:www-data /usr/local/share/zoneminder/ # Adding apache virtual hosts file -ADD utils/docker/apache-vhost /etc/apache2/sites-available/000-default.conf +RUN cp misc/apache.conf /etc/apache2/sites-available/000-default.conf ADD utils/docker/phpdate.ini /etc/php5/apache2/conf.d/25-phpdate.ini # Expose http ports diff --git a/distros/redhat/CMakeLists.txt b/distros/redhat/CMakeLists.txt index f8acef552..69ed05ff3 100644 --- a/distros/redhat/CMakeLists.txt +++ b/distros/redhat/CMakeLists.txt @@ -46,13 +46,16 @@ else("${unzip_jsc}" STREQUAL "") endif("${unzip_jsc}" STREQUAL "") # Create several empty folders -file(MAKE_DIRECTORY sock swap zoneminder zoneminder-upload events images temp) +file(MAKE_DIRECTORY sock swap zoneminder zoneminder-upload events images temp logs cache models persistent views) # Install the empty folders install(DIRECTORY sock swap DESTINATION /var/lib/zoneminder DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(DIRECTORY zoneminder DESTINATION /var/log DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +install(DIRECTORY zoneminder DESTINATION /var/run DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(DIRECTORY zoneminder-upload DESTINATION /var/spool DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(DIRECTORY events images temp DESTINATION /var/lib/zoneminder DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +install(DIRECTORY logs cache DESTINATION /var/lib/zoneminder/temp DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) +install(DIRECTORY models persistent views DESTINATION /var/lib/zoneminder/temp/cache DIRECTORY_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # Create symlinks install(CODE "execute_process(COMMAND ln -sf ../../../../var/lib/zoneminder/events \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/events\")") diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index 0ed6323f0..6fe589949 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -132,8 +132,8 @@ too much degradation of performance. %prep %autosetup -n ZoneMinder-%{version} %autosetup -a 1 -n ZoneMinder-%{version} -rmdir ./web/api/app/Plugin/Crud -mv -f crud-%{crud_version} ./web/api/app/Plugin/Crud +%{__rm} -rf ./web/api/app/Plugin/Crud +%{__mv} -f crud-%{crud_version} ./web/api/app/Plugin/Crud # Change the following default values ./utils/zmeditconfigdata.sh ZM_PATH_ZMS /cgi-bin-zm/nph-zms @@ -333,7 +333,14 @@ rm -rf %{_docdir}/%{name}-%{version} %dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_sharedstatedir}/zoneminder/temp %dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/log/zoneminder %dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/spool/zoneminder-upload -%dir %attr(755,%{zmuid_final},%{zmgid_final}) %ghost %{_localstatedir}/run/zoneminder +%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/run/zoneminder + +# cakephp requires its cache folders to pre-exist +%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_sharedstatedir}/zoneminder/temp/logs +%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_sharedstatedir}/zoneminder/temp/cache +%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_sharedstatedir}/zoneminder/temp/cache/views +%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_sharedstatedir}/zoneminder/temp/cache/models +%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_sharedstatedir}/zoneminder/temp/cache/persistent %changelog * Thu Mar 30 2017 Andrew Bauer - 1.30.2-2 diff --git a/docs/installationguide/redhat.rst b/docs/installationguide/redhat.rst index e6b506ac5..ff68bb685 100644 --- a/docs/installationguide/redhat.rst +++ b/docs/installationguide/redhat.rst @@ -169,8 +169,6 @@ Now clone the ZoneMinder git repository: cd git clone https://github.com/ZoneMinder/ZoneMinder cd ZoneMinder - git submodule init - git submodule update This will create a sub-folder called ZoneMinder, which will contain the latest development. @@ -180,21 +178,22 @@ We want to turn this into a tarball, but first we need to figure out what to nam ls ~/rpmbuild/SOURCES -The tarball from the previsouly installed SRPM should be there. This is the name we will use. For this example, the name is ZoneMinder-1.28.1.tar.gz. From one folder above the local ZoneMinder git repository, execute the following: +The tarball from the previsouly installed SRPM should be there. This is the name we will use. For this example, the name is ZoneMinder-1.28.1.tar.gz. From the local ZoneMinder git repository, execute the following: :: - mv ZoneMinder ZoneMinder-1.28.1 - tar -cvzf ~/rpmbuild/SOURCES/ZoneMinder-1.28.1.tar.gz ZoneMinder-1.28.1/* + git archive --prefix=ZoneMinder-1.28.1/ -o zoneminder-1.28.1.tar.gz HEAD + mv zoneminder-1.28.1.tar.gz ~/rpmbuld/SOURCES/ -The trailing "/\*" leaves off the hidden dot "." file and folders from the git repo, which is what we want. Note that we are overwriting the original tarball. If you wish to keep the original tarball then create a copy prior to creating the new tarball. -Now build a new src.rpm: +From the root of the local ZoneMinder git repo, execute the following: :: - rpmbuild -bs --nodeps ~/rpmbuild/SPECS/zoneminder.el7.spec + rpmbuild -bs --nodeps distros/redhat/zoneminder.spec + +Notice we used the rpm specfile that is part of the latest master branch you just downloaded, rather than the one that may be in your ~/rpmbbuild/SOURCES folder. This step will overwrite the SRPM you originally downloaded, so you may want to back it up prior to completing this step. Note that the name of the specfile will vary slightly depending on the target distro. diff --git a/misc/apache.conf.in b/misc/apache.conf.in index 5ad45338b..d1c6d70db 100644 --- a/misc/apache.conf.in +++ b/misc/apache.conf.in @@ -5,13 +5,22 @@ # Some values may need to manually adjusted to suit your setup # - ServerName @WEB_HOST@ ServerAdmin webmaster@localhost DocumentRoot "@WEB_PREFIX@" + Alias /zm/ "@WEB_PREFIX@/" Options -Indexes +FollowSymLinks AllowOverride All + + # Apache 2.4 + Require all granted + + + # Apache 2.2 + Order deny,allow + Allow from all + ScriptAlias /cgi-bin "@CGI_PREFIX@" diff --git a/scripts/ZoneMinder/lib/ZoneMinder/General.pm b/scripts/ZoneMinder/lib/ZoneMinder/General.pm index bb03fe70c..3d004725b 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/General.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/General.pm @@ -103,8 +103,10 @@ sub getCmdFormat { my $suffix = ""; my $command = $prefix.$null_command.$suffix; Debug( "Testing \"$command\"\n" ); - my $output = qx($command); + my $output = qx($command 2>&1); my $status = $? >> 8; + $output //= $!; + if ( !$status ) { Debug( "Test ok, using format \"$prefix$suffix\"\n" ); return( $prefix, $suffix ); @@ -116,8 +118,10 @@ sub getCmdFormat { $suffix = "'"; $command = $prefix.$null_command.$suffix; Debug( "Testing \"$command\"\n" ); - my $output = qx($command); + my $output = qx($command 2>&1); my $status = $? >> 8; + $output //= $!; + if ( !$status ) { Debug( "Test ok, using format \"$prefix$suffix\"\n" ); return( $prefix, $suffix ); @@ -129,8 +133,10 @@ sub getCmdFormat { $suffix = "'"; $command = $prefix.$null_command.$suffix; Debug( "Testing \"$command\"\n" ); - $output = qx($command); + $output = qx($command 2>&1); $status = $? >> 8; + $output //= $!; + if ( !$status ) { Debug( "Test ok, using format \"$prefix$suffix\"\n" ); return( $prefix, $suffix ); diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index e82115e70..0d300eb92 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -348,7 +348,7 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, palette = V4L2_PIX_FMT_YUYV; } else { if(capture) { - Info("Selected capture palette: %s (%c%c%c%c)", palette_desc, palette&0xff, (palette>>8)&0xff, (palette>>16)&0xff, (palette>>24)&0xff); + Info("Selected capture palette: %s (0x%02hhx%02hhx%02hhx%02hhx)", palette_desc, (palette>>24)&0xff, (palette>>16)&0xff, (palette>>8)&0xff, (palette)&0xff); } } } @@ -409,7 +409,8 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, } else { if( capture ) #if HAVE_LIBSWSCALE - Info("No direct match for the selected palette (%c%c%c%c) and target colorspace (%d). Format conversion is required, performance penalty expected", (capturePixFormat)&0xff,((capturePixFormat>>8)&0xff),((capturePixFormat>>16)&0xff),((capturePixFormat>>24)&0xff), colours ); + Info("No direct match for the selected palette (0x%02hhx%02hhx%02hhx%02hhx) and target colorspace (%02u). Format conversion is required, performance penalty expected", + (capturePixFormat>>24)&0xff,((capturePixFormat>>16)&0xff),((capturePixFormat>>8)&0xff),((capturePixFormat)&0xff), colours); #else Info("No direct match for the selected palette and target colorspace. Format conversion is required, performance penalty expected"); #endif @@ -427,16 +428,18 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, subpixelorder = ZM_SUBPIX_ORDER_NONE; imagePixFormat = AV_PIX_FMT_GRAY8; } else { - Panic("Unexpected colours: %d",colours); + Panic("Unexpected colours: %u",colours); } if( capture ) { #if LIBSWSCALE_VERSION_CHECK(0, 8, 0, 8, 0) if(!sws_isSupportedInput(capturePixFormat)) { - Error("swscale does not support the used capture format: %c%c%c%c",(capturePixFormat)&0xff,((capturePixFormat>>8)&0xff),((capturePixFormat>>16)&0xff),((capturePixFormat>>24)&0xff)); + Error("swscale does not support the used capture format: 0x%02hhx%02hhx%02hhx%02hhx", + (capturePixFormat>>24)&0xff,((capturePixFormat>>16)&0xff),((capturePixFormat>>8)&0xff),((capturePixFormat)&0xff)); conversion_type = 2; /* Try ZM format conversions */ } if(!sws_isSupportedOutput(imagePixFormat)) { - Error("swscale does not support the target format: %c%c%c%c",(imagePixFormat)&0xff,((imagePixFormat>>8)&0xff),((imagePixFormat>>16)&0xff),((imagePixFormat>>24)&0xff)); + Error("swscale does not support the target format: 0x%02hhx%02hhx%02hhx%02hhx", + (imagePixFormat>>24)&0xff,((imagePixFormat>>16)&0xff),((imagePixFormat>>8)&0xff),((imagePixFormat)&0xff)); conversion_type = 2; /* Try ZM format conversions */ } #endif @@ -545,7 +548,7 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, subpixelorder = ZM_SUBPIX_ORDER_NONE; imagePixFormat = AV_PIX_FMT_GRAY8; } else { - Panic("Unexpected colours: %d",colours); + Panic("Unexpected colours: %u",colours); } if( capture ) { if(!sws_isSupportedInput(capturePixFormat)) { @@ -613,7 +616,7 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, #endif // ZM_HAS_V4L1 last_camera = this; - Debug(3,"Selected subpixelorder: %d",subpixelorder); + Debug(3,"Selected subpixelorder: %u",subpixelorder); #if HAVE_LIBSWSCALE /* Initialize swscale stuff */ @@ -632,7 +635,7 @@ LocalCamera::LocalCamera( int p_id, const std::string &p_device, int p_channel, int pSize = avpicture_get_size( imagePixFormat, width, height ); #endif if( (unsigned int)pSize != imagesize) { - Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize); + Fatal("Image size mismatch. Required: %d Available: %u",pSize,imagesize); } imgConversionContext = sws_getContext(width, height, capturePixFormat, width, height, imagePixFormat, SWS_BICUBIC, NULL, NULL, NULL ); @@ -789,7 +792,7 @@ void LocalCamera::Initialise() Debug(3,"Failed to get updated JPEG compression options: %s", strerror(errno) ); } else { Debug(4, "JPEG quality: %d",jpeg_comp.quality); - Debug(4, "JPEG markers: %#x",jpeg_comp.jpeg_markers); + Debug(4, "JPEG markers: 0x%x",jpeg_comp.jpeg_markers); } } } @@ -853,7 +856,7 @@ void LocalCamera::Initialise() v4l2_data.buffers[i].start = mmap( NULL, vid_buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, vid_fd, vid_buf.m.offset ); if ( v4l2_data.buffers[i].start == MAP_FAILED ) - Fatal( "Can't map video buffer %d (%d bytes) to memory: %s(%d)", i, vid_buf.length, strerror(errno), errno ); + Fatal( "Can't map video buffer %u (%u bytes) to memory: %s(%d)", i, vid_buf.length, strerror(errno), errno ); #if HAVE_LIBSWSCALE #if LIBAVCODEC_VERSION_CHECK(55, 28, 1, 45, 101) @@ -1177,7 +1180,8 @@ uint32_t LocalCamera::AutoSelectFormat(int p_colours) { strcpy(fmt_desc[nIndex], (const char*)(fmtinfo.description)); fmt_fcc[nIndex] = fmtinfo.pixelformat; - Debug(6, "Got format: %s (%c%c%c%c) at index %d",fmt_desc[nIndex],fmt_fcc[nIndex]&0xff, (fmt_fcc[nIndex]>>8)&0xff, (fmt_fcc[nIndex]>>16)&0xff, (fmt_fcc[nIndex]>>24)&0xff ,nIndex); + Debug(6, "Got format: %s (0x%02hhx%02hhx%02hhx%02hhx) at index %d", + fmt_desc[nIndex], (fmt_fcc[nIndex]>>24)&0xff, (fmt_fcc[nIndex]>>16)&0xff, (fmt_fcc[nIndex]>>8)&0xff, (fmt_fcc[nIndex])&0xff ,nIndex); /* Proceed to the next index */ memset(&fmtinfo, 0, sizeof(fmtinfo)); @@ -1205,12 +1209,14 @@ uint32_t LocalCamera::AutoSelectFormat(int p_colours) { for( unsigned int i=0; i < n_preferedformats && nIndexUsed < 0; i++ ) { for( unsigned int j=0; j < nIndex; j++ ) { if( preferedformats[i] == fmt_fcc[j] ) { - Debug(6, "Choosing format: %s (%c%c%c%c) at index %d",fmt_desc[j],fmt_fcc[j]&0xff, (fmt_fcc[j]>>8)&0xff, (fmt_fcc[j]>>16)&0xff, (fmt_fcc[j]>>24)&0xff ,j); + Debug(6, "Choosing format: %s (0x%02hhx%02hhx%02hhx%02hhx) at index %u", + fmt_desc[j],fmt_fcc[j]&0xff, (fmt_fcc[j]>>8)&0xff, (fmt_fcc[j]>>16)&0xff, (fmt_fcc[j]>>24)&0xff ,j); /* Found a format! */ nIndexUsed = j; break; } else { - Debug(6, "No match for format: %s (%c%c%c%c) at index %d",fmt_desc[j],fmt_fcc[j]&0xff, (fmt_fcc[j]>>8)&0xff, (fmt_fcc[j]>>16)&0xff, (fmt_fcc[j]>>24)&0xff ,j); + Debug(6, "No match for format: %s (0x%02hhx%02hhx%02hhx%02hhx) at index %u", + fmt_desc[j],fmt_fcc[j]&0xff, (fmt_fcc[j]>>8)&0xff, (fmt_fcc[j]>>16)&0xff, (fmt_fcc[j]>>24)&0xff ,j); } } } @@ -1385,9 +1391,11 @@ bool LocalCamera::GetCurrentSettings( const char *device, char *output, int vers } } if ( verbose ) - sprintf( output+strlen(output), " %s (%c%c%c%c)\n", format.description, format.pixelformat&0xff, (format.pixelformat>>8)&0xff, (format.pixelformat>>16)&0xff, (format.pixelformat>>24)&0xff ); + sprintf( output+strlen(output), " %s (0x%02hhx%02hhx%02hhx%02hhx)\n", + format.description, (format.pixelformat>>24)&0xff, (format.pixelformat>>16)&0xff, (format.pixelformat>>8)&0xff, format.pixelformat&0xff); else - sprintf( output+strlen(output), "%c%c%c%c/", format.pixelformat&0xff, (format.pixelformat>>8)&0xff, (format.pixelformat>>16)&0xff, (format.pixelformat>>24)&0xff ); + sprintf( output+strlen(output), "0x%02hhx%02hhx%02hhx%02hhx/", + (format.pixelformat>>24)&0xff, (format.pixelformat>>16)&0xff, (format.pixelformat>>8)&0xff, (format.pixelformat)&0xff); } while ( formatIndex++ >= 0 ); if ( !verbose ) diff --git a/src/zm_utils.cpp b/src/zm_utils.cpp index e777a9266..b84cead1c 100644 --- a/src/zm_utils.cpp +++ b/src/zm_utils.cpp @@ -25,6 +25,10 @@ #include #include +#ifdef HAVE_CURL_CURL_H +#include +#endif + unsigned int sseversion = 0; std::string trimSet(std::string str, std::string trimset) { @@ -345,3 +349,18 @@ void timespec_diff(struct timespec *start, struct timespec *end, struct timespec } } +std::string UriDecode( const std::string &encoded ) { +#ifdef HAVE_LIBCURL + CURL *curl = curl_easy_init(); + int outlength; + char *cres = curl_easy_unescape(curl, encoded.c_str(), encoded.length(), &outlength); + std::string res(cres, cres + outlength); + curl_free(cres); + curl_easy_cleanup(curl); + return res; +#else +Warning("ZM Compiled without LIBCURL. UriDecoding not implemented."); + return encoded; +#endif +} + diff --git a/src/zm_utils.h b/src/zm_utils.h index 6dbf76a4d..b8345c356 100644 --- a/src/zm_utils.h +++ b/src/zm_utils.h @@ -60,4 +60,6 @@ void timespec_diff(struct timespec *start, struct timespec *end, struct timespec extern unsigned int sseversion; +std::string UriDecode( const std::string &encoded ); + #endif // ZM_UTILS_H diff --git a/src/zms.cpp b/src/zms.cpp index 87eaf3202..c32b9affd 100644 --- a/src/zms.cpp +++ b/src/zms.cpp @@ -69,8 +69,8 @@ int main( int argc, const char *argv[] ) unsigned int bitrate = 100000; unsigned int ttl = 0; EventStream::StreamMode replay = EventStream::MODE_SINGLE; - char username[64] = ""; - char password[64] = ""; + std::string username; + std::string password; char auth[64] = ""; unsigned int connkey = 0; unsigned int playback_buffer = 0; @@ -164,7 +164,7 @@ int main( int argc, const char *argv[] ) { if ( !strcmp( name, "user" ) ) { - strncpy( username, value, sizeof(username) ); + username = value; } } else @@ -180,11 +180,11 @@ int main( int argc, const char *argv[] ) { if ( !strcmp( name, "user" ) ) { - strncpy( username, value, sizeof(username) ); + username = UriDecode(value); } if ( !strcmp( name, "pass" ) ) { - strncpy( password, value, sizeof(password) ); + password = UriDecode( password ); } } } @@ -198,9 +198,9 @@ int main( int argc, const char *argv[] ) if ( strcmp( config.auth_relay, "none" ) == 0 ) { - if ( *username ) + if ( username.length() ) { - user = zmLoadUser( username ); + user = zmLoadUser( username.c_str() ); } } else @@ -214,9 +214,9 @@ int main( int argc, const char *argv[] ) } //else if ( strcmp( config.auth_relay, "plain" ) == 0 ) { - if ( *username && *password ) + if ( username.length() && password.length() ) { - user = zmLoadUser( username, password ); + user = zmLoadUser( username.c_str(), password.c_str() ); } } } diff --git a/utils/docker/apache-vhost b/utils/docker/apache-vhost deleted file mode 100644 index e1821932e..000000000 --- a/utils/docker/apache-vhost +++ /dev/null @@ -1,14 +0,0 @@ - - DocumentRoot /usr/local/share/zoneminder/www - DirectoryIndex index.php - - ScriptAlias /cgi-bin/ /usr/local/libexec/zoneminder/cgi-bin/ - - Require all granted - - - AllowOverride None - Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch - Require all granted - - diff --git a/utils/docker/setup.sh b/utils/docker/setup.sh index fbd3592f0..c7b8b121b 100755 --- a/utils/docker/setup.sh +++ b/utils/docker/setup.sh @@ -27,6 +27,9 @@ mysql -u root < db/zm_create.sql # Add the ZoneMinder DB user mysql -u root -e "grant insert,select,update,delete,lock tables,alter on zm.* to 'zmuser'@'localhost' identified by 'zmpass';" +# Make ZM_LOGDIR +mkdir /var/log/zm + # Activate CGI a2enmod cgi diff --git a/web/skins/classic/views/montagereview.php b/web/skins/classic/views/montagereview.php index 4c1195190..b85ca9fda 100644 --- a/web/skins/classic/views/montagereview.php +++ b/web/skins/classic/views/montagereview.php @@ -145,11 +145,9 @@ $frameSql = " if ( !empty($user['MonitorIds']) ) { - $monFilterSql = ' AND M.Id IN ('.$user['MonitorIds'].')'; - - $eventsSql .= $monFilterSql; - $monitorsSQL .= $monFilterSql; - $frameSql .= $monFilterSql; + $eventsSql .= ' AND M.Id IN ('.$user['MonitorIds'].')'; + $monitorsSql .= ' AND Id IN ('.$user['MonitorIds'].')'; + $frameSql .= ' AND E.MonitorId IN ('.$user['MonitorIds'].')'; } // Parse input parameters -- note for future, validate/clean up better in case we don't get called from self.