From bacf65ae9a826461b1e62f5567614448a6edd71f Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 12 Jun 2017 20:39:37 -0500 Subject: [PATCH] Migrate values from Options -> Paths to zm.conf (#1908) * initial commit to migrate contents of Options->Paths to zm.conf * remove paths items from configdata.pm * remove paths tab from options * update deb packaging scripts with new cmake vars * remove extraneous file * save custom paths variables to config file before dB is freshened * don't check configs if the dB version is >= 1.31.0 --- CMakeLists.txt | 19 +++ distros/debian/rules | 5 +- distros/redhat/zoneminder.spec | 4 +- distros/ubuntu1204/rules | 23 +-- distros/ubuntu1504_cmake_split_packages/rules | 6 +- distros/ubuntu1604/rules | 5 +- .../lib/ZoneMinder/ConfigData.pm.in | 156 ------------------ scripts/zmupdate.pl.in | 60 +++++++ src/snprintf.cpp | 8 +- src/zm_config.cpp | 20 +++ src/zm_config.h.in | 10 ++ src/zm_event.cpp | 18 +- src/zm_logger.cpp | 4 +- src/zm_monitor.cpp | 22 +-- src/zm_stream.cpp | 6 +- src/zm_zone.cpp | 10 +- web/includes/actions.php | 1 - web/skins/classic/views/options.php | 1 - zm.conf.in | 40 +++++ 19 files changed, 209 insertions(+), 209 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc1067903..edf9cc615 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,6 +103,8 @@ mark_as_advanced( ZM_PERL_MM_PARMS ZM_PERL_SEARCH_PATH ZM_TARGET_DISTRO + ZM_PATH_MAP + ZM_PATH_ARP ZM_CONFIG_DIR ZM_CONFIG_SUBDIR ZM_SYSTEMD) @@ -135,7 +137,21 @@ set(ZM_WEB_USER "" CACHE STRING set(ZM_WEB_GROUP "" CACHE STRING "The group apache or the local web server runs on, Leave empty to be the same as the web user") +set(ZM_DIR_EVENTS "events" CACHE PATH + "Location where events are recorded to, default: events") +set(ZM_DIR_IMAGES "events" CACHE PATH + "Location where images, not directly associated with events, + are recorded to, default: images") +set(ZM_DIR_SOUNDS "sounds" CACHE PATH + "Location to look for optional sound files, default: sounds") +set(ZM_PATH_ZMS "/cgi-bin/nph-zms" CACHE PATH + "Web url to zms streaming server, default: /cgi-bin/nph-zms") + # Advanced +set(ZM_PATH_MAP "/dev/shm" CACHE PATH + "Location to save mapped memory files, default: /dev/shm") +set(ZM_PATH_ARP "" CACHE PATH + "Full path to compatible arp binary. Leave empty for automatic detection.") set(ZM_CONFIG_DIR "/${CMAKE_INSTALL_SYSCONFDIR}" CACHE PATH "Location of ZoneMinder configuration, default system config directory") set(ZM_CONFIG_SUBDIR "${ZM_CONFIG_DIR}/conf.d" CACHE PATH @@ -183,6 +199,9 @@ if((ZM_TARGET_DISTRO MATCHES "^el") OR (ZM_TARGET_DISTRO MATCHES "^fc")) set(ZM_CONFIG_SUBDIR "/etc/zm/conf.d") set(ZM_WEBDIR "/usr/share/zoneminder/www") set(ZM_CGIDIR "/usr/libexec/zoneminder/cgi-bin") + set(ZM_DIR_EVENTS "/var/lib/zoneminder/events") + set(ZM_DIR_IMAGES "/var/lib/zoneminder/images") + set(ZM_PATH_ZMS "/cgi-bin-zm/nph-zms") elseif(ZM_TARGET_DISTRO STREQUAL "OS13") set(ZM_RUNDIR "/var/run/zoneminder") set(ZM_TMPDIR "/var/run/zoneminder") diff --git a/distros/debian/rules b/distros/debian/rules index 45a64332c..929f054df 100755 --- a/distros/debian/rules +++ b/distros/debian/rules @@ -23,7 +23,10 @@ override_dh_auto_configure: -DZM_WEB_USER=www-data \ -DZM_WEB_GROUP=www-data \ -DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \ - -DZM_CONFIG_DIR="/etc/zm" + -DZM_CONFIG_DIR="/etc/zm" \ + -DZM_DIR_EVENTS="/var/cache/zoneminder/events" \ + -DZM_DIR_IMAGES="/var/cache/zoneminder/images" \ + -DZM_PATH_ZMS="/zm/cgi-bin/nph-zms" override_dh_auto_install: dh_auto_install --buildsystem=cmake diff --git a/distros/redhat/zoneminder.spec b/distros/redhat/zoneminder.spec index 4eab2a429..374b7bf03 100644 --- a/distros/redhat/zoneminder.spec +++ b/distros/redhat/zoneminder.spec @@ -33,7 +33,7 @@ %global _hardened_build 1 Name: zoneminder -Version: 1.30.4 +Version: 1.31.0 Release: 1%{?dist} Summary: A camera monitoring and analysis tool Group: System Environment/Daemons @@ -142,9 +142,7 @@ too much degradation of performance. %{__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 ./utils/zmeditconfigdata.sh ZM_OPT_CAMBOZOLA yes -./utils/zmeditconfigdata.sh ZM_PATH_SWAP /dev/shm ./utils/zmeditconfigdata.sh ZM_UPLOAD_FTP_LOC_DIR %{_localstatedir}/spool/zoneminder-upload ./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes ./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no diff --git a/distros/ubuntu1204/rules b/distros/ubuntu1204/rules index 1f7755c45..dcf11864b 100755 --- a/distros/ubuntu1204/rules +++ b/distros/ubuntu1204/rules @@ -16,16 +16,19 @@ endif --with sphinxdoc,apache2,linktree override_dh_auto_configure: - dh_auto_configure -- $(ARGS) \ - -DCMAKE_VERBOSE_MAKEFILE=ON \ - -DCMAKE_BUILD_TYPE=Release \ - -DZM_CONFIG_DIR="/etc/zm" \ - -DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \ - -DZM_RUNDIR="/var/run/zm" \ - -DZM_SOCKDIR="/var/run/zm" \ - -DZM_TMPDIR="/tmp/zm" \ - -DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \ - -DZM_CONTENTDIR="/var/cache/zoneminder" + dh_auto_configure -- $(ARGS) \ + -DCMAKE_VERBOSE_MAKEFILE=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DZM_CONFIG_DIR="/etc/zm" \ + -DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \ + -DZM_RUNDIR="/var/run/zm" \ + -DZM_SOCKDIR="/var/run/zm" \ + -DZM_TMPDIR="/tmp/zm" \ + -DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \ + -DZM_CONTENTDIR="/var/cache/zoneminder" \ + -DZM_DIR_EVENTS="/var/cache/zoneminder/events" \ + -DZM_DIR_IMAGES="/var/cache/zoneminder/images" \ + -DZM_PATH_ZMS="/zm/cgi-bin/nph-zms" \ override_dh_clean: dh_clean $(MANPAGES1) diff --git a/distros/ubuntu1504_cmake_split_packages/rules b/distros/ubuntu1504_cmake_split_packages/rules index 8a2c2643e..7c8fc232d 100755 --- a/distros/ubuntu1504_cmake_split_packages/rules +++ b/distros/ubuntu1504_cmake_split_packages/rules @@ -63,8 +63,10 @@ override_dh_auto_configure: -DZM_WEB_USER=www-data \ -DZM_WEB_GROUP=www-data \ -DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \ - -DZM_CONFIG_DIR="/etc/zm" - + -DZM_CONFIG_DIR="/etc/zm" \ + -DZM_DIR_EVENTS="/var/cache/zoneminder/events" \ + -DZM_DIR_IMAGES="/var/cache/zoneminder/images" \ + -DZM_PATH_ZMS="/zm/cgi-bin/nph-zms" override_dh_auto_test: # do not run tests... diff --git a/distros/ubuntu1604/rules b/distros/ubuntu1604/rules index c91790d68..b78361212 100755 --- a/distros/ubuntu1604/rules +++ b/distros/ubuntu1604/rules @@ -25,7 +25,10 @@ override_dh_auto_configure: -DZM_SOCKDIR="/var/run/zm" \ -DZM_TMPDIR="/tmp/zm" \ -DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \ - -DZM_CONTENTDIR="/var/cache/zoneminder" + -DZM_CONTENTDIR="/var/cache/zoneminder" \ + -DZM_DIR_EVENTS="/var/cache/zoneminder/events" \ + -DZM_DIR_IMAGES="/var/cache/zoneminder/images" \ + -DZM_PATH_ZMS="/zm/cgi-bin/nph-zms" override_dh_clean: dh_clean $(MANPAGES1) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in index 29efe85ca..43ff70eea 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in @@ -427,23 +427,6 @@ our @options = ( type => $types{string}, category => 'system', }, - { - name => 'ZM_DIR_EVENTS', - default => 'events', - description => 'Directory where events are stored', - help => q` - This is the path to the events directory where all the event - images and other miscellaneous files are stored. CAUTION: The - directory you specify here cannot be outside the web root. This - is a common mistake. Most users should never change this value. - If you intend to record events to a second disk or network - share, then you should mount the drive or share directly to the - ZoneMinder events folder or follow the instructions in the - ZoneMinder Wiki titled Using a dedicated Hard Drive. - `, - type => $types{directory}, - category => 'paths', - }, { name => 'ZM_USE_DEEP_STORAGE', default => 'yes', @@ -465,68 +448,6 @@ our @options = ( type => $types{boolean}, category => 'hidden', }, - { - name => 'ZM_DIR_IMAGES', - default => 'images', - description => 'Directory where the images that the ZoneMinder client generates are stored', - help => q` - ZoneMinder generates a myriad of images, mostly of which are - associated with events. For those that aren't this is where - they go. CAUTION: The directory you specify here cannot be - outside the web root. This is a common mistake. Most users - should never change this value. If you intend to save images to - a second disk or network share, then you should mount the drive - or share directly to the ZoneMinder images folder or follow the - instructions in the ZoneMinder Wiki titled Using a dedicated - Hard Drive. - `, - type => $types{directory}, - category => 'paths', - }, - { - name => 'ZM_DIR_SOUNDS', - default => 'sounds', - description => 'Directory to the sounds that the ZoneMinder client can use', - help => q` - ZoneMinder can optionally play a sound file when an alarm is - detected. This indicates where to look for this file. CAUTION: - The directory you specify here cannot be outside the web root. - Most users should never change this value. - `, - type => $types{directory}, - category => 'paths', - }, - { - name => 'ZM_DIR_EXPORTS', - default => '@ZM_TMPDIR@', - description => 'Directory where exported archives are stored', - help => q` - This is the path to the exports directory where exported - tar.gz and zip archives are stored. By default this points to - ZoneMinder's temp folder, which often sits in ram. Since exported - archives can potentially become large, it is a good idea to move - this folder to some other location on machines with low memory. - `, - type => $types{directory}, - category => 'paths', - }, - { - name => 'ZM_PATH_ZMS', - default => '/cgi-bin/nph-zms', - description => 'Web path to zms streaming server', - help => q` - The ZoneMinder streaming server is required to send streamed - images to your browser. It will be installed into the cgi-bin - path given at configuration time. This option determines what - the web path to the server is rather than the local path on - your machine. Ordinarily the streaming server runs in - parser-header mode however if you experience problems with - streaming you can change this to non-parsed-header (nph) mode - by changing 'zms' to 'nph-zms'. - `, - type => $types{rel_path}, - category => 'paths', - }, { name => 'ZM_COLOUR_JPEG_FILES', default => 'no', @@ -1471,83 +1392,6 @@ our @options = ( type => $types{boolean}, category => 'logging', }, - { - name => 'ZM_PATH_MAP', - default => '/dev/shm', - description => 'Path to the mapped memory files that that ZoneMinder can use', - help => q` - ZoneMinder has historically used IPC shared memory for shared - data between processes. This has it's advantages and - limitations. This version of ZoneMinder can use an alternate - method, mapped memory, instead with can be enabled with the - --enable--mmap directive to configure. This requires less - system configuration and is generally more flexible. However it - requires each shared data segment to map onto a filesystem - file. This option indicates where those mapped files go. You - should ensure that this location has sufficient space for these - files and for the best performance it should be a tmpfs file - system or ramdisk otherwise disk access may render this method - slower than the regular shared memory one. - `, - type => $types{abs_path}, - category => 'paths', - }, - { - name => 'ZM_PATH_SOCKS', - default => '@ZM_SOCKDIR@', - description => 'Path to the various Unix domain socket files that ZoneMinder uses', - help => q` - ZoneMinder generally uses Unix domain sockets where possible. - This reduces the need for port assignments and prevents - external applications from possibly compromising the daemons. - However each Unix socket requires a .sock file to be created. - This option indicates where those socket files go. - `, - type => $types{abs_path}, - category => 'paths', - }, - { - name => 'ZM_PATH_LOGS', - default => '@ZM_LOGDIR@', - description => 'Path to the various logs that the ZoneMinder daemons generate', - help => q` - There are various daemons that are used by ZoneMinder to - perform various tasks. Most generate helpful log files and this - is where they go. They can be deleted if not required for - debugging. - `, - type => $types{abs_path}, - category => 'paths', - }, - { - name => 'ZM_PATH_SWAP', - default => '@ZM_TMPDIR@', - description => 'Path to location for temporary swap images used in streaming', - help => q` - Buffered playback requires temporary swap images to be stored - for each instance of the streaming daemons. This option - determines where these images will be stored. The images will - actually be stored in sub directories beneath this location and - will be automatically cleaned up after a period of time. - `, - type => $types{abs_path}, - category => 'paths', - }, - { - name => 'ZM_PATH_ARP', - default => '', - description => 'Path to a supported ARP tool', - help => q` - The camera probe function uses Address Resolution Protocol in - order to find known devices on the network. Optionally supply - the full path to \"ip neigh\", \"arp -a\", or any other tool on - your system that returns ip/mac address pairs. If this field is - left empty, ZoneMinder will search for the command \"arp\" and - attempt to use that. - `, - type => $types{abs_path}, - category => 'paths', - }, { name => 'ZM_WEB_TITLE_PREFIX', default => 'ZM', diff --git a/scripts/zmupdate.pl.in b/scripts/zmupdate.pl.in index b263ab065..4b08b4deb 100644 --- a/scripts/zmupdate.pl.in +++ b/scripts/zmupdate.pl.in @@ -311,6 +311,7 @@ if ( $migrateEvents ) { } if ( $freshen ) { print( "\nFreshening configuration in database\n" ); + migratePaths(); ZoneMinder::Config::loadConfigFromDB(); ZoneMinder::Config::saveConfigToDB(); } @@ -458,6 +459,7 @@ if ( $version ) { print( "\nUpgrading database to version ".ZM_VERSION."\n" ); # Update config first of all + migratePaths(); ZoneMinder::Config::loadConfigFromDB(); ZoneMinder::Config::saveConfigToDB(); @@ -969,3 +971,61 @@ if ( $version ) { } zmDbDisconnect(); exit( 0 ); + +sub migratePaths { + + my $customConfigFile = "@ZM_CONFIG_SUBDIR@/zmcustom.conf"; + + if ( (! -e $customConfigFile ) && ( ZM_VERSION ge '1.31.0' ) && ($Config{ZM_DYN_DB_VERSION} lt '1.31.0') ) { + + my %customConfig; + + # Check the traditional default values for the variables previsouly found under Options -> Paths + if ( $Config{ZM_DIR_EVENTS} ne "events" ) { + $customConfig{ZM_DIR_EVENTS} = $Config{ZM_DIR_EVENTS}; + } + if ( $Config{ZM_DIR_IMAGES} ne "images" ) { + $customConfig{ZM_DIR_IMAGES} = $Config{ZM_DIR_IMAGES}; + } + if ( $Config{ZM_DIR_SOUNDS} ne "sounds" ) { + $customConfig{ZM_DIR_SOUNDS} = $Config{ZM_DIR_SOUNDS}; + } + if ( $Config{ZM_PATH_ZMS} ne "@ZM_PATH_ZMS@" ) { + $customConfig{ZM_PATH_ZMS} = $Config{ZM_PATH_ZMS}; + } + if ( $Config{ZM_PATH_MAP} ne "/dev/shm" ) { + $customConfig{ZM_PATH_MAP} = $Config{ZM_PATH_MAP}; + } + if ( $Config{ZM_PATH_SOCKS} ne "@ZM_SOCKDIR@" ) { + $customConfig{ZM_PATH_SOCKS} = $Config{ZM_PATH_SOCKS}; + } + if ( $Config{ZM_PATH_LOGS} ne "@ZM_LOGDIR@" ) { + $customConfig{ZM_PATH_LOGS} = $Config{ZM_PATH_LOGS}; + } + if ( $Config{ZM_PATH_SWAP} ne "@ZM_TMPDIR@" ) { + $customConfig{ZM_PATH_SWAP} = $Config{ZM_PATH_SWAP}; + } + if ( $Config{ZM_PATH_ARP} ne "" ) { + $customConfig{ZM_PATH_ARP} = $Config{ZM_PATH_ARP}; + } + + # If any variables differ from their expected default value, + # save them to a config file before they get purged from the database + if ( %customConfig ) { + print("\nMigrating custom config values from Options -> Paths\nto $customConfigFile.\n"); + print("\nPlease verify these values before starting ZoneMinder.\n\n"); + open(my $fh, '>', $customConfigFile) or die "Could open $customConfigFile for writing: $!."; + print $fh "# These values were autogenerated by zmupdate.pl\n"; + print $fh "# You may edit these values. ZoneMinder will not overwrite them.\n"; + print $fh "#\n\n"; + while (my ($key, $value) = each %customConfig) { + print $fh "$key=$value\n"; + } + close $fh; + my $gid = getgrnam("@ZM_WEB_GROUP@"); + chown -1, $gid, $customConfigFile; + chmod 0640, $customConfigFile; + } + } +} + diff --git a/src/snprintf.cpp b/src/snprintf.cpp index 645534e9c..3476822de 100644 --- a/src/snprintf.cpp +++ b/src/snprintf.cpp @@ -1,9 +1,9 @@ -snprintf( swap_path, sizeof(swap_path), "%s/zmswap-m%d/zmswap-q%06d", config.path_swap, monitor->Id(), connkey ); +snprintf( swap_path, sizeof(swap_path), "%s/zmswap-m%d/zmswap-q%06d", staticConfig.PATH_SWAP.c_str(), monitor->Id(), connkey ); int len = snprintf(NULL, 0, "/zmswap-m%d", monitor->Id()); - int swap_path_length = strlen(config.path_swap) + snprintf(NULL, 0, "/zmswap-m%d", monitor->Id() ) + snprintf(NULL, 0, "/zmswap-q%06d", connkey ) + 1; // +1 for NULL terminator + int swap_path_length = strlen(staticConfig.PATH_SWAP.c_str()) + snprintf(NULL, 0, "/zmswap-m%d", monitor->Id() ) + snprintf(NULL, 0, "/zmswap-q%06d", connkey ) + 1; // +1 for NULL terminator if ( connkey && playback_buffer > 0 ) { @@ -11,8 +11,8 @@ int len = snprintf(NULL, 0, "/zmswap-m%d", monitor->Id()); Error( "Swap Path is too long. %d > %d ", swap_path_length+max_swap_len_suffix, PATH_MAX ); } else { swap_path = (char *)malloc( swap_path_length+max_swap_len_suffix ); - Debug( 3, "Checking swap image path %s", config.path_swap ); - strncpy( swap_path, config.path_swap, swap_path_length ); + Debug( 3, "Checking swap image path %s", staticConfig.PATH_SWAP.c_str() ); + strncpy( swap_path, staticConfig.PATH_SWAP.c_str(), swap_path_length ); if ( checkSwapPath( swap_path, false ) ) { snprintf( &(swap_path[swap_path_length]), max_swap_len_suffix, "/zmswap-m%d", monitor->Id() ); if ( checkSwapPath( swap_path, true ) ) { diff --git a/src/zm_config.cpp b/src/zm_config.cpp index eedebaf45..601a4a950 100644 --- a/src/zm_config.cpp +++ b/src/zm_config.cpp @@ -158,6 +158,26 @@ void process_configfile( char* configFile) { staticConfig.SERVER_NAME = std::string(val_ptr); else if ( strcasecmp( name_ptr, "ZM_SERVER_ID" ) == 0 ) staticConfig.SERVER_ID = atoi(val_ptr); + else if ( strcasecmp( name_ptr, "ZM_DIR_EVENTS" ) == 0 ) + staticConfig.DIR_EVENTS = std::string(val_ptr); + else if ( strcasecmp( name_ptr, "ZM_DIR_IMAGES" ) == 0 ) + staticConfig.DIR_IMAGES = std::string(val_ptr); + else if ( strcasecmp( name_ptr, "ZM_DIR_SOUNDS" ) == 0 ) + staticConfig.DIR_SOUNDS = std::string(val_ptr); + else if ( strcasecmp( name_ptr, "ZM_DIR_EXPORTS" ) == 0 ) + staticConfig.DIR_EXPORTS = std::string(val_ptr); + else if ( strcasecmp( name_ptr, "ZM_PATH_ZMS" ) == 0 ) + staticConfig.PATH_ZMS = std::string(val_ptr); + else if ( strcasecmp( name_ptr, "ZM_PATH_MAP" ) == 0 ) + staticConfig.PATH_MAP = std::string(val_ptr); + else if ( strcasecmp( name_ptr, "ZM_PATH_SOCKS" ) == 0 ) + staticConfig.PATH_SOCKS = std::string(val_ptr); + else if ( strcasecmp( name_ptr, "ZM_PATH_LOGS" ) == 0 ) + staticConfig.PATH_LOGS = std::string(val_ptr); + else if ( strcasecmp( name_ptr, "ZM_PATH_SWAP" ) == 0 ) + staticConfig.PATH_SWAP = std::string(val_ptr); + else if ( strcasecmp( name_ptr, "ZM_PATH_ARP" ) == 0 ) + staticConfig.PATH_ARP = std::string(val_ptr); else { // We ignore this now as there may be more parameters than the // c/c++ binaries are bothered about diff --git a/src/zm_config.h.in b/src/zm_config.h.in index 49b983fa7..461e4bb5e 100644 --- a/src/zm_config.h.in +++ b/src/zm_config.h.in @@ -70,6 +70,16 @@ struct StaticConfig std::string PATH_WEB; std::string SERVER_NAME; unsigned int SERVER_ID; + std::string DIR_EVENTS; + std::string DIR_IMAGES; + std::string DIR_SOUNDS; + std::string DIR_EXPORTS; + std::string PATH_ZMS; + std::string PATH_MAP; + std::string PATH_SOCKS; + std::string PATH_LOGS; + std::string PATH_SWAP; + std::string PATH_ARP; }; extern StaticConfig staticConfig; diff --git a/src/zm_event.cpp b/src/zm_event.cpp index e50009c76..44d8cf30b 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -100,7 +100,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string if ( config.use_deep_storage ) { char *path_ptr = path; - path_ptr += snprintf( path_ptr, sizeof(path), "%s/%d", config.dir_events, monitor->Id() ); + path_ptr += snprintf( path_ptr, sizeof(path), "%s/%d", staticConfig.DIR_EVENTS.c_str(), monitor->Id() ); int dt_parts[6]; dt_parts[0] = stime->tm_year-100; @@ -136,7 +136,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string if ( symlink( time_path, id_file ) < 0 ) Fatal( "Can't symlink %s -> %s: %s", id_file, path, strerror(errno)); } else { - snprintf( path, sizeof(path), "%s/%d/%d", config.dir_events, monitor->Id(), id ); + snprintf( path, sizeof(path), "%s/%d/%d", staticConfig.DIR_EVENTS.c_str(), monitor->Id(), id ); errno = 0; stat( path, &statbuf ); @@ -550,7 +550,7 @@ void Event::AddFrame( Image *image, struct timeval timestamp, int score, Image * if ( config.record_diag_images ) { char diag_glob[PATH_MAX] = ""; - snprintf( diag_glob, sizeof(diag_glob), "%s/%d/diag-*.jpg", config.dir_events, monitor->Id() ); + snprintf( diag_glob, sizeof(diag_glob), "%s/%d/diag-*.jpg", staticConfig.DIR_EVENTS.c_str(), monitor->Id() ); glob_t pglob; int glob_status = glob( diag_glob, 0, 0, &pglob ); if ( glob_status != 0 ) { @@ -674,15 +674,15 @@ bool EventStream::loadEventData( int event_id ) { event_data->start_time = atoi(dbrow[2]); if ( config.use_deep_storage ) { struct tm *event_time = localtime( &event_data->start_time ); - if ( config.dir_events[0] == '/' ) - snprintf( event_data->path, sizeof(event_data->path), "%s/%ld/%02d/%02d/%02d/%02d/%02d/%02d", config.dir_events, event_data->monitor_id, event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_hour, event_time->tm_min, event_time->tm_sec ); + if ( staticConfig.DIR_EVENTS.c_str()[0] == '/' ) + snprintf( event_data->path, sizeof(event_data->path), "%s/%ld/%02d/%02d/%02d/%02d/%02d/%02d", staticConfig.DIR_EVENTS.c_str(), event_data->monitor_id, event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_hour, event_time->tm_min, event_time->tm_sec ); else - snprintf( event_data->path, sizeof(event_data->path), "%s/%s/%ld/%02d/%02d/%02d/%02d/%02d/%02d", staticConfig.PATH_WEB.c_str(), config.dir_events, event_data->monitor_id, event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_hour, event_time->tm_min, event_time->tm_sec ); + snprintf( event_data->path, sizeof(event_data->path), "%s/%s/%ld/%02d/%02d/%02d/%02d/%02d/%02d", staticConfig.PATH_WEB.c_str(), staticConfig.DIR_EVENTS.c_str(), event_data->monitor_id, event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_hour, event_time->tm_min, event_time->tm_sec ); } else { - if ( config.dir_events[0] == '/' ) - snprintf( event_data->path, sizeof(event_data->path), "%s/%ld/%ld", config.dir_events, event_data->monitor_id, event_data->event_id ); + if ( staticConfig.DIR_EVENTS.c_str()[0] == '/' ) + snprintf( event_data->path, sizeof(event_data->path), "%s/%ld/%ld", staticConfig.DIR_EVENTS.c_str(), event_data->monitor_id, event_data->event_id ); else - snprintf( event_data->path, sizeof(event_data->path), "%s/%s/%ld/%ld", staticConfig.PATH_WEB.c_str(), config.dir_events, event_data->monitor_id, event_data->event_id ); + snprintf( event_data->path, sizeof(event_data->path), "%s/%s/%ld/%ld", staticConfig.PATH_WEB.c_str(), staticConfig.DIR_EVENTS.c_str(), event_data->monitor_id, event_data->event_id ); } event_data->frame_count = dbrow[1] == NULL ? 0 : atoi(dbrow[1]); event_data->duration = atof(dbrow[3]); diff --git a/src/zm_logger.cpp b/src/zm_logger.cpp index f122fa1d8..013807df6 100644 --- a/src/zm_logger.cpp +++ b/src/zm_logger.cpp @@ -70,7 +70,7 @@ Logger::Logger() : mFileLevel( NOLOG ), mSyslogLevel( NOLOG ), mEffectiveLevel( NOLOG ), - //mLogPath( config.path_logs ), + //mLogPath( staticConfig.PATH_LOGS.c_str() ), //mLogFile( mLogPath+"/"+mId+".log" ), mDbConnected( false ), mLogFileFP( NULL ), @@ -577,7 +577,7 @@ 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; + tempOptions.mLogPath = staticConfig.PATH_LOGS.c_str(); Logger::smInstance->initialise( name, tempOptions ); } diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 392582a21..56b4be9d1 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -80,7 +80,7 @@ Monitor::MonitorLink::MonitorLink( int p_id, const char *p_name ) : id( p_id ) { #if ZM_MEM_MAPPED map_fd = -1; - snprintf( mem_file, sizeof(mem_file), "%s/zm.mmap.%d", config.path_map, id ); + snprintf( mem_file, sizeof(mem_file), "%s/zm.mmap.%d", staticConfig.PATH_MAP.c_str(), id ); #else // ZM_MEM_MAPPED shm_id = 0; #endif // ZM_MEM_MAPPED @@ -450,7 +450,7 @@ Monitor::Monitor( if ( purpose == ANALYSIS ) { static char path[PATH_MAX]; - strncpy( path, config.dir_events, sizeof(path) ); + strncpy( path, staticConfig.DIR_EVENTS.c_str(), sizeof(path) ); struct stat statbuf; errno = 0; @@ -461,7 +461,7 @@ Monitor::Monitor( } } - snprintf( path, sizeof(path), "%s/%d", config.dir_events, id ); + snprintf( path, sizeof(path), "%s/%d", staticConfig.DIR_EVENTS.c_str(), id ); errno = 0; stat( path, &statbuf ); @@ -471,8 +471,8 @@ Monitor::Monitor( } char temp_path[PATH_MAX]; snprintf( temp_path, sizeof(temp_path), "%d", id ); - if ( chdir( config.dir_events ) < 0 ) - Fatal( "Can't change directory to '%s': %s", config.dir_events, strerror(errno) ); + if ( chdir( staticConfig.DIR_EVENTS.c_str() ) < 0 ) + Fatal( "Can't change directory to '%s': %s", staticConfig.DIR_EVENTS.c_str(), strerror(errno) ); if ( symlink( temp_path, name ) < 0 ) Fatal( "Can't symlink '%s' to '%s': %s", temp_path, name, strerror(errno) ); if ( chdir( ".." ) < 0 ) @@ -497,7 +497,7 @@ Monitor::Monitor( bool Monitor::connect() { #if ZM_MEM_MAPPED - snprintf( mem_file, sizeof(mem_file), "%s/zm.mmap.%d", config.path_map, id ); + snprintf( mem_file, sizeof(mem_file), "%s/zm.mmap.%d", staticConfig.PATH_MAP.c_str(), id ); map_fd = open( mem_file, O_RDWR|O_CREAT, (mode_t)0600 ); if ( map_fd < 0 ) Fatal( "Can't open memory map file %s, probably not enough space free: %s", mem_file, strerror(errno) ); @@ -646,7 +646,7 @@ Monitor::~Monitor() { if ( purpose == CAPTURE ) { char mmap_path[PATH_MAX] = ""; - snprintf( mmap_path, sizeof(mmap_path), "%s/zm.mmap.%d", config.path_map, id ); + snprintf( mmap_path, sizeof(mmap_path), "%s/zm.mmap.%d", staticConfig.PATH_MAP.c_str(), id ); if ( unlink( mmap_path ) < 0 ) { Warning( "Can't unlink '%s': %s", mmap_path, strerror(errno) ); @@ -2991,7 +2991,7 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z if ( config.record_diag_images ) { static char diag_path[PATH_MAX] = ""; if ( !diag_path[0] ) { - snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-r.jpg", config.dir_events, id ); + snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-r.jpg", staticConfig.DIR_EVENTS.c_str(), id ); } ref_image.WriteJpeg( diag_path ); } @@ -3001,7 +3001,7 @@ unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &z if ( config.record_diag_images ) { static char diag_path[PATH_MAX] = ""; if ( !diag_path[0] ) { - snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-d.jpg", config.dir_events, id ); + snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-d.jpg", staticConfig.DIR_EVENTS.c_str(), id ); } delta_image.WriteJpeg( diag_path ); } @@ -3688,7 +3688,7 @@ void MonitorStream::runStream() { // 15 is the max length for the swap path suffix, /zmswap-whatever, assuming max 6 digits for monitor id const int max_swap_len_suffix = 15; - int swap_path_length = strlen(config.path_swap) + 1; // +1 for NULL terminator + int swap_path_length = strlen(staticConfig.PATH_SWAP.c_str()) + 1; // +1 for NULL terminator int subfolder1_length = snprintf(NULL, 0, "/zmswap-m%d", monitor->Id() ) + 1; int subfolder2_length = snprintf(NULL, 0, "/zmswap-q%06d", connkey ) + 1; int total_swap_path_length = swap_path_length + subfolder1_length + subfolder2_length; @@ -3699,7 +3699,7 @@ void MonitorStream::runStream() { Error( "Swap Path is too long. %d > %d ", total_swap_path_length+max_swap_len_suffix, PATH_MAX ); } else { swap_path = (char *)malloc( total_swap_path_length+max_swap_len_suffix ); - strncpy( swap_path, config.path_swap, swap_path_length ); + strncpy( swap_path, staticConfig.PATH_SWAP.c_str(), swap_path_length ); Debug( 3, "Checking swap path folder: %s", swap_path ); if ( checkSwapPath( swap_path, false ) ) { diff --git a/src/zm_stream.cpp b/src/zm_stream.cpp index 525d7b8ef..c0b8701a2 100644 --- a/src/zm_stream.cpp +++ b/src/zm_stream.cpp @@ -291,7 +291,7 @@ void StreamBase::openComms() if ( connkey > 0 ) { - unsigned int length = snprintf( sock_path_lock, sizeof(sock_path_lock), "%s/zms-%06d.lock", config.path_socks, connkey); + unsigned int length = snprintf( sock_path_lock, sizeof(sock_path_lock), "%s/zms-%06d.lock", staticConfig.PATH_SOCKS.c_str(), connkey); if ( length >= sizeof(sock_path_lock) ) { Warning("Socket lock path was truncated."); length = sizeof(sock_path_lock)-1; @@ -321,7 +321,7 @@ void StreamBase::openComms() Debug(3, "Have socket %d", sd ); } - length = snprintf( loc_sock_path, sizeof(loc_sock_path), "%s/zms-%06ds.sock", config.path_socks, connkey ); + length = snprintf( loc_sock_path, sizeof(loc_sock_path), "%s/zms-%06ds.sock", staticConfig.PATH_SOCKS.c_str(), connkey ); if ( length >= sizeof(loc_sock_path) ) { Warning("Socket path was truncated."); length = sizeof(loc_sock_path)-1; @@ -339,7 +339,7 @@ void StreamBase::openComms() Fatal( "Can't bind: %s", strerror(errno) ); } - snprintf( rem_sock_path, sizeof(rem_sock_path), "%s/zms-%06dw.sock", config.path_socks, connkey ); + snprintf( rem_sock_path, sizeof(rem_sock_path), "%s/zms-%06dw.sock", staticConfig.PATH_SOCKS.c_str(), connkey ); strncpy( rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path) ); rem_addr.sun_family = AF_UNIX; } // end if connKey > 0 diff --git a/src/zm_zone.cpp b/src/zm_zone.cpp index e92c3d493..7430f2498 100644 --- a/src/zm_zone.cpp +++ b/src/zm_zone.cpp @@ -112,7 +112,7 @@ void Zone::Setup( if ( config.record_diag_images ) { static char diag_path[PATH_MAX] = ""; if ( ! diag_path[0] ) { - snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-poly.jpg", config.dir_events, monitor->Name(), id); + snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-poly.jpg", staticConfig.DIR_EVENTS.c_str(), monitor->Name(), id); } pg_image->WriteJpeg( diag_path ); } @@ -233,7 +233,7 @@ bool Zone::CheckAlarms( const Image *delta_image ) { if ( config.record_diag_images ) { static char diag_path[PATH_MAX] = ""; if ( ! diag_path[0] ) { - snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-%d.jpg", config.dir_events, monitor->Name(), id, 1 ); + snprintf( diag_path, sizeof(diag_path), "%s/%s/diag-%d-%d.jpg", staticConfig.DIR_EVENTS.c_str(), monitor->Name(), id, 1 ); } diff_image->WriteJpeg( diag_path ); } @@ -315,7 +315,7 @@ bool Zone::CheckAlarms( const Image *delta_image ) { if ( config.record_diag_images ) { static char diag_path[PATH_MAX] = ""; if ( !diag_path[0] ) { - snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 2 ); + snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", staticConfig.DIR_EVENTS.c_str(), monitor->Id(), id, 2 ); } diff_image->WriteJpeg( diag_path ); } @@ -525,7 +525,7 @@ bool Zone::CheckAlarms( const Image *delta_image ) { if ( config.record_diag_images ) { static char diag_path[PATH_MAX] = ""; if ( !diag_path[0] ) { - snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 3 ); + snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", staticConfig.DIR_EVENTS.c_str(), monitor->Id(), id, 3 ); } diff_image->WriteJpeg( diag_path ); } @@ -572,7 +572,7 @@ bool Zone::CheckAlarms( const Image *delta_image ) { if ( config.record_diag_images ) { static char diag_path[PATH_MAX] = ""; if ( !diag_path[0] ) { - snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", config.dir_events, monitor->Id(), id, 4 ); + snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-%d-%d.jpg", staticConfig.DIR_EVENTS.c_str(), monitor->Id(), id, 4 ); } diff_image->WriteJpeg( diag_path ); } diff --git a/web/includes/actions.php b/web/includes/actions.php index d306c3bbc..4bd811a41 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -800,7 +800,6 @@ if ( !empty($action) ) { switch( $_REQUEST['tab'] ) { case 'system' : case 'config' : - case 'paths' : $restartWarning = true; break; case 'web' : diff --git a/web/skins/classic/views/options.php b/web/skins/classic/views/options.php index 854f2560c..51cc8f2a6 100644 --- a/web/skins/classic/views/options.php +++ b/web/skins/classic/views/options.php @@ -31,7 +31,6 @@ $tabs['skins'] = translate('Display'); $tabs['system'] = translate('System'); $tabs['config'] = translate('Config'); $tabs['servers'] = translate('Servers'); -$tabs['paths'] = translate('Paths'); $tabs['web'] = translate('Web'); $tabs['images'] = translate('Images'); $tabs['logging'] = translate('Logging'); diff --git a/zm.conf.in b/zm.conf.in index 296078dde..c417aacd2 100644 --- a/zm.conf.in +++ b/zm.conf.in @@ -50,3 +50,43 @@ ZM_DB_USER=@ZM_DB_USER@ # ZoneMinder database password ZM_DB_PASS=@ZM_DB_PASS@ +# Full path to the folder events are recorded to. +# The web account user must have full read/write permission to this folder. +ZM_DIR_EVENTS=@ZM_DIR_EVENTS@ + +# Full path to the folder images, not directly associated with events, +# are recorded to. +# The web account user must have full read/write permission to this folder. +ZM_DIR_IMAGES=@ZM_DIR_IMAGES@ + +# Foldername under the webroot where ZoneMinder looks for optional sound files +# to play when an alarm is detected. +ZM_DIR_SOUNDS=@ZM_DIR_SOUNDS@ + +# Full path to the folder where exported archives are stored +# The web account user must have full read/write permission to this folder. +ZM_DIR_EXPORTS=@ZM_TMPDIR@ + +# ZoneMinder url path to the zms streaming server +ZM_PATH_ZMS=@ZM_PATH_ZMS@ + +# Full Path to ZoneMinder's mapped memory files +# The web account user must have full read/write permission to this folder. +ZM_PATH_MAP=@ZM_PATH_MAP@ + +# Full Path to ZoneMinder's socket folder +# The web account user must have full read/write permission to this folder. +ZM_PATH_SOCKS=@ZM_SOCKDIR@ + +# Full path to ZoneMinder's log folder +# The web account user must have full read/write permission to this folder. +ZM_PATH_LOGS=@ZM_LOGDIR@ + +# Full path to ZoneMinder's swap folder +# The web account user must have full read/write permission to this folder. +ZM_PATH_SWAP=@ZM_TMPDIR@ + +# Full path to optional arp binary +# ZoneMinder will find the arp binary automatically on most systems +ZM_PATH_ARP=@ZM_PATH_ARP@ +