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
This commit is contained in:
Andrew Bauer 2017-06-12 20:39:37 -05:00 committed by Isaac Connor
parent 4ba9205ba9
commit bacf65ae9a
19 changed files with 209 additions and 209 deletions

View File

@ -103,6 +103,8 @@ mark_as_advanced(
ZM_PERL_MM_PARMS ZM_PERL_MM_PARMS
ZM_PERL_SEARCH_PATH ZM_PERL_SEARCH_PATH
ZM_TARGET_DISTRO ZM_TARGET_DISTRO
ZM_PATH_MAP
ZM_PATH_ARP
ZM_CONFIG_DIR ZM_CONFIG_DIR
ZM_CONFIG_SUBDIR ZM_CONFIG_SUBDIR
ZM_SYSTEMD) ZM_SYSTEMD)
@ -135,7 +137,21 @@ set(ZM_WEB_USER "" CACHE STRING
set(ZM_WEB_GROUP "" CACHE STRING set(ZM_WEB_GROUP "" CACHE STRING
"The group apache or the local web server runs on, "The group apache or the local web server runs on,
Leave empty to be the same as the web user") 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 # 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 set(ZM_CONFIG_DIR "/${CMAKE_INSTALL_SYSCONFDIR}" CACHE PATH
"Location of ZoneMinder configuration, default system config directory") "Location of ZoneMinder configuration, default system config directory")
set(ZM_CONFIG_SUBDIR "${ZM_CONFIG_DIR}/conf.d" CACHE PATH 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_CONFIG_SUBDIR "/etc/zm/conf.d")
set(ZM_WEBDIR "/usr/share/zoneminder/www") set(ZM_WEBDIR "/usr/share/zoneminder/www")
set(ZM_CGIDIR "/usr/libexec/zoneminder/cgi-bin") set(ZM_CGIDIR "/usr/libexec/zoneminder/cgi-bin")
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") elseif(ZM_TARGET_DISTRO STREQUAL "OS13")
set(ZM_RUNDIR "/var/run/zoneminder") set(ZM_RUNDIR "/var/run/zoneminder")
set(ZM_TMPDIR "/var/run/zoneminder") set(ZM_TMPDIR "/var/run/zoneminder")

View File

@ -23,7 +23,10 @@ override_dh_auto_configure:
-DZM_WEB_USER=www-data \ -DZM_WEB_USER=www-data \
-DZM_WEB_GROUP=www-data \ -DZM_WEB_GROUP=www-data \
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \ -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: override_dh_auto_install:
dh_auto_install --buildsystem=cmake dh_auto_install --buildsystem=cmake

View File

@ -33,7 +33,7 @@
%global _hardened_build 1 %global _hardened_build 1
Name: zoneminder Name: zoneminder
Version: 1.30.4 Version: 1.31.0
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons
@ -142,9 +142,7 @@ too much degradation of performance.
%{__mv} -f crud-%{crud_version} ./web/api/app/Plugin/Crud %{__mv} -f crud-%{crud_version} ./web/api/app/Plugin/Crud
# Change the following default values # 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_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_UPLOAD_FTP_LOC_DIR %{_localstatedir}/spool/zoneminder-upload
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes ./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no ./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no

View File

@ -16,16 +16,19 @@ endif
--with sphinxdoc,apache2,linktree --with sphinxdoc,apache2,linktree
override_dh_auto_configure: override_dh_auto_configure:
dh_auto_configure -- $(ARGS) \ dh_auto_configure -- $(ARGS) \
-DCMAKE_VERBOSE_MAKEFILE=ON \ -DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DZM_CONFIG_DIR="/etc/zm" \ -DZM_CONFIG_DIR="/etc/zm" \
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \ -DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \
-DZM_RUNDIR="/var/run/zm" \ -DZM_RUNDIR="/var/run/zm" \
-DZM_SOCKDIR="/var/run/zm" \ -DZM_SOCKDIR="/var/run/zm" \
-DZM_TMPDIR="/tmp/zm" \ -DZM_TMPDIR="/tmp/zm" \
-DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \ -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: override_dh_clean:
dh_clean $(MANPAGES1) dh_clean $(MANPAGES1)

View File

@ -63,8 +63,10 @@ override_dh_auto_configure:
-DZM_WEB_USER=www-data \ -DZM_WEB_USER=www-data \
-DZM_WEB_GROUP=www-data \ -DZM_WEB_GROUP=www-data \
-DZM_CONFIG_SUBDIR="/etc/zm/conf.d" \ -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: override_dh_auto_test:
# do not run tests... # do not run tests...

View File

@ -25,7 +25,10 @@ override_dh_auto_configure:
-DZM_SOCKDIR="/var/run/zm" \ -DZM_SOCKDIR="/var/run/zm" \
-DZM_TMPDIR="/tmp/zm" \ -DZM_TMPDIR="/tmp/zm" \
-DZM_CGIDIR="/usr/lib/zoneminder/cgi-bin" \ -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: override_dh_clean:
dh_clean $(MANPAGES1) dh_clean $(MANPAGES1)

View File

@ -427,23 +427,6 @@ our @options = (
type => $types{string}, type => $types{string},
category => 'system', 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', name => 'ZM_USE_DEEP_STORAGE',
default => 'yes', default => 'yes',
@ -465,68 +448,6 @@ our @options = (
type => $types{boolean}, type => $types{boolean},
category => 'hidden', 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', name => 'ZM_COLOUR_JPEG_FILES',
default => 'no', default => 'no',
@ -1471,83 +1392,6 @@ our @options = (
type => $types{boolean}, type => $types{boolean},
category => 'logging', 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', name => 'ZM_WEB_TITLE_PREFIX',
default => 'ZM', default => 'ZM',

View File

@ -311,6 +311,7 @@ if ( $migrateEvents ) {
} }
if ( $freshen ) { if ( $freshen ) {
print( "\nFreshening configuration in database\n" ); print( "\nFreshening configuration in database\n" );
migratePaths();
ZoneMinder::Config::loadConfigFromDB(); ZoneMinder::Config::loadConfigFromDB();
ZoneMinder::Config::saveConfigToDB(); ZoneMinder::Config::saveConfigToDB();
} }
@ -458,6 +459,7 @@ if ( $version ) {
print( "\nUpgrading database to version ".ZM_VERSION."\n" ); print( "\nUpgrading database to version ".ZM_VERSION."\n" );
# Update config first of all # Update config first of all
migratePaths();
ZoneMinder::Config::loadConfigFromDB(); ZoneMinder::Config::loadConfigFromDB();
ZoneMinder::Config::saveConfigToDB(); ZoneMinder::Config::saveConfigToDB();
@ -969,3 +971,61 @@ if ( $version ) {
} }
zmDbDisconnect(); zmDbDisconnect();
exit( 0 ); 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;
}
}
}

View File

@ -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 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 ) { 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 ); Error( "Swap Path is too long. %d > %d ", swap_path_length+max_swap_len_suffix, PATH_MAX );
} else { } else {
swap_path = (char *)malloc( swap_path_length+max_swap_len_suffix ); swap_path = (char *)malloc( swap_path_length+max_swap_len_suffix );
Debug( 3, "Checking swap image path %s", config.path_swap ); Debug( 3, "Checking swap image path %s", staticConfig.PATH_SWAP.c_str() );
strncpy( swap_path, config.path_swap, swap_path_length ); strncpy( swap_path, staticConfig.PATH_SWAP.c_str(), swap_path_length );
if ( checkSwapPath( swap_path, false ) ) { if ( checkSwapPath( swap_path, false ) ) {
snprintf( &(swap_path[swap_path_length]), max_swap_len_suffix, "/zmswap-m%d", monitor->Id() ); snprintf( &(swap_path[swap_path_length]), max_swap_len_suffix, "/zmswap-m%d", monitor->Id() );
if ( checkSwapPath( swap_path, true ) ) { if ( checkSwapPath( swap_path, true ) ) {

View File

@ -158,6 +158,26 @@ void process_configfile( char* configFile) {
staticConfig.SERVER_NAME = std::string(val_ptr); staticConfig.SERVER_NAME = std::string(val_ptr);
else if ( strcasecmp( name_ptr, "ZM_SERVER_ID" ) == 0 ) else if ( strcasecmp( name_ptr, "ZM_SERVER_ID" ) == 0 )
staticConfig.SERVER_ID = atoi(val_ptr); 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 { else {
// We ignore this now as there may be more parameters than the // We ignore this now as there may be more parameters than the
// c/c++ binaries are bothered about // c/c++ binaries are bothered about

View File

@ -70,6 +70,16 @@ struct StaticConfig
std::string PATH_WEB; std::string PATH_WEB;
std::string SERVER_NAME; std::string SERVER_NAME;
unsigned int SERVER_ID; 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; extern StaticConfig staticConfig;

View File

@ -100,7 +100,7 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
if ( config.use_deep_storage ) { if ( config.use_deep_storage ) {
char *path_ptr = path; 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]; int dt_parts[6];
dt_parts[0] = stime->tm_year-100; 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 ) if ( symlink( time_path, id_file ) < 0 )
Fatal( "Can't symlink %s -> %s: %s", id_file, path, strerror(errno)); Fatal( "Can't symlink %s -> %s: %s", id_file, path, strerror(errno));
} else { } 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; errno = 0;
stat( path, &statbuf ); stat( path, &statbuf );
@ -550,7 +550,7 @@ void Event::AddFrame( Image *image, struct timeval timestamp, int score, Image *
if ( config.record_diag_images ) { if ( config.record_diag_images ) {
char diag_glob[PATH_MAX] = ""; 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; glob_t pglob;
int glob_status = glob( diag_glob, 0, 0, &pglob ); int glob_status = glob( diag_glob, 0, 0, &pglob );
if ( glob_status != 0 ) { if ( glob_status != 0 ) {
@ -674,15 +674,15 @@ bool EventStream::loadEventData( int event_id ) {
event_data->start_time = atoi(dbrow[2]); event_data->start_time = atoi(dbrow[2]);
if ( config.use_deep_storage ) { if ( config.use_deep_storage ) {
struct tm *event_time = localtime( &event_data->start_time ); struct tm *event_time = localtime( &event_data->start_time );
if ( config.dir_events[0] == '/' ) if ( staticConfig.DIR_EVENTS.c_str()[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 ); 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 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 { } else {
if ( config.dir_events[0] == '/' ) if ( staticConfig.DIR_EVENTS.c_str()[0] == '/' )
snprintf( event_data->path, sizeof(event_data->path), "%s/%ld/%ld", config.dir_events, event_data->monitor_id, event_data->event_id ); 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 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->frame_count = dbrow[1] == NULL ? 0 : atoi(dbrow[1]);
event_data->duration = atof(dbrow[3]); event_data->duration = atof(dbrow[3]);

View File

@ -70,7 +70,7 @@ Logger::Logger() :
mFileLevel( NOLOG ), mFileLevel( NOLOG ),
mSyslogLevel( NOLOG ), mSyslogLevel( NOLOG ),
mEffectiveLevel( NOLOG ), mEffectiveLevel( NOLOG ),
//mLogPath( config.path_logs ), //mLogPath( staticConfig.PATH_LOGS.c_str() ),
//mLogFile( mLogPath+"/"+mId+".log" ), //mLogFile( mLogPath+"/"+mId+".log" ),
mDbConnected( false ), mDbConnected( false ),
mLogFileFP( NULL ), mLogFileFP( NULL ),
@ -577,7 +577,7 @@ void logInit( const char *name, const Logger::Options &options ) {
if ( !Logger::smInstance ) if ( !Logger::smInstance )
Logger::smInstance = new Logger(); Logger::smInstance = new Logger();
Logger::Options tempOptions = options; Logger::Options tempOptions = options;
tempOptions.mLogPath = config.path_logs; tempOptions.mLogPath = staticConfig.PATH_LOGS.c_str();
Logger::smInstance->initialise( name, tempOptions ); Logger::smInstance->initialise( name, tempOptions );
} }

View File

@ -80,7 +80,7 @@ Monitor::MonitorLink::MonitorLink( int p_id, const char *p_name ) : id( p_id ) {
#if ZM_MEM_MAPPED #if ZM_MEM_MAPPED
map_fd = -1; 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 #else // ZM_MEM_MAPPED
shm_id = 0; shm_id = 0;
#endif // ZM_MEM_MAPPED #endif // ZM_MEM_MAPPED
@ -450,7 +450,7 @@ Monitor::Monitor(
if ( purpose == ANALYSIS ) { if ( purpose == ANALYSIS ) {
static char path[PATH_MAX]; static char path[PATH_MAX];
strncpy( path, config.dir_events, sizeof(path) ); strncpy( path, staticConfig.DIR_EVENTS.c_str(), sizeof(path) );
struct stat statbuf; struct stat statbuf;
errno = 0; 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; errno = 0;
stat( path, &statbuf ); stat( path, &statbuf );
@ -471,8 +471,8 @@ Monitor::Monitor(
} }
char temp_path[PATH_MAX]; char temp_path[PATH_MAX];
snprintf( temp_path, sizeof(temp_path), "%d", id ); snprintf( temp_path, sizeof(temp_path), "%d", id );
if ( chdir( config.dir_events ) < 0 ) if ( chdir( staticConfig.DIR_EVENTS.c_str() ) < 0 )
Fatal( "Can't change directory to '%s': %s", config.dir_events, strerror(errno) ); Fatal( "Can't change directory to '%s': %s", staticConfig.DIR_EVENTS.c_str(), strerror(errno) );
if ( symlink( temp_path, name ) < 0 ) if ( symlink( temp_path, name ) < 0 )
Fatal( "Can't symlink '%s' to '%s': %s", temp_path, name, strerror(errno) ); Fatal( "Can't symlink '%s' to '%s': %s", temp_path, name, strerror(errno) );
if ( chdir( ".." ) < 0 ) if ( chdir( ".." ) < 0 )
@ -497,7 +497,7 @@ Monitor::Monitor(
bool Monitor::connect() { bool Monitor::connect() {
#if ZM_MEM_MAPPED #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 ); map_fd = open( mem_file, O_RDWR|O_CREAT, (mode_t)0600 );
if ( map_fd < 0 ) if ( map_fd < 0 )
Fatal( "Can't open memory map file %s, probably not enough space free: %s", mem_file, strerror(errno) ); 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 ) { if ( purpose == CAPTURE ) {
char mmap_path[PATH_MAX] = ""; 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 ) { if ( unlink( mmap_path ) < 0 ) {
Warning( "Can't unlink '%s': %s", mmap_path, strerror(errno) ); 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 ) { if ( config.record_diag_images ) {
static char diag_path[PATH_MAX] = ""; static char diag_path[PATH_MAX] = "";
if ( !diag_path[0] ) { 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 ); 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 ) { if ( config.record_diag_images ) {
static char diag_path[PATH_MAX] = ""; static char diag_path[PATH_MAX] = "";
if ( !diag_path[0] ) { 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 ); 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 // 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; 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 subfolder1_length = snprintf(NULL, 0, "/zmswap-m%d", monitor->Id() ) + 1;
int subfolder2_length = snprintf(NULL, 0, "/zmswap-q%06d", connkey ) + 1; int subfolder2_length = snprintf(NULL, 0, "/zmswap-q%06d", connkey ) + 1;
int total_swap_path_length = swap_path_length + subfolder1_length + subfolder2_length; 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 ); Error( "Swap Path is too long. %d > %d ", total_swap_path_length+max_swap_len_suffix, PATH_MAX );
} else { } else {
swap_path = (char *)malloc( total_swap_path_length+max_swap_len_suffix ); 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 ); Debug( 3, "Checking swap path folder: %s", swap_path );
if ( checkSwapPath( swap_path, false ) ) { if ( checkSwapPath( swap_path, false ) ) {

View File

@ -291,7 +291,7 @@ void StreamBase::openComms()
if ( connkey > 0 ) 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) ) { if ( length >= sizeof(sock_path_lock) ) {
Warning("Socket lock path was truncated."); Warning("Socket lock path was truncated.");
length = sizeof(sock_path_lock)-1; length = sizeof(sock_path_lock)-1;
@ -321,7 +321,7 @@ void StreamBase::openComms()
Debug(3, "Have socket %d", sd ); 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) ) { if ( length >= sizeof(loc_sock_path) ) {
Warning("Socket path was truncated."); Warning("Socket path was truncated.");
length = sizeof(loc_sock_path)-1; length = sizeof(loc_sock_path)-1;
@ -339,7 +339,7 @@ void StreamBase::openComms()
Fatal( "Can't bind: %s", strerror(errno) ); 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) ); strncpy( rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path) );
rem_addr.sun_family = AF_UNIX; rem_addr.sun_family = AF_UNIX;
} // end if connKey > 0 } // end if connKey > 0

View File

@ -112,7 +112,7 @@ void Zone::Setup(
if ( config.record_diag_images ) { if ( config.record_diag_images ) {
static char diag_path[PATH_MAX] = ""; static char diag_path[PATH_MAX] = "";
if ( ! diag_path[0] ) { 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 ); pg_image->WriteJpeg( diag_path );
} }
@ -233,7 +233,7 @@ bool Zone::CheckAlarms( const Image *delta_image ) {
if ( config.record_diag_images ) { if ( config.record_diag_images ) {
static char diag_path[PATH_MAX] = ""; static char diag_path[PATH_MAX] = "";
if ( ! diag_path[0] ) { 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 ); diff_image->WriteJpeg( diag_path );
} }
@ -315,7 +315,7 @@ bool Zone::CheckAlarms( const Image *delta_image ) {
if ( config.record_diag_images ) { if ( config.record_diag_images ) {
static char diag_path[PATH_MAX] = ""; static char diag_path[PATH_MAX] = "";
if ( !diag_path[0] ) { 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 ); diff_image->WriteJpeg( diag_path );
} }
@ -525,7 +525,7 @@ bool Zone::CheckAlarms( const Image *delta_image ) {
if ( config.record_diag_images ) { if ( config.record_diag_images ) {
static char diag_path[PATH_MAX] = ""; static char diag_path[PATH_MAX] = "";
if ( !diag_path[0] ) { 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 ); diff_image->WriteJpeg( diag_path );
} }
@ -572,7 +572,7 @@ bool Zone::CheckAlarms( const Image *delta_image ) {
if ( config.record_diag_images ) { if ( config.record_diag_images ) {
static char diag_path[PATH_MAX] = ""; static char diag_path[PATH_MAX] = "";
if ( !diag_path[0] ) { 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_image->WriteJpeg( diag_path );
} }

View File

@ -800,7 +800,6 @@ if ( !empty($action) ) {
switch( $_REQUEST['tab'] ) { switch( $_REQUEST['tab'] ) {
case 'system' : case 'system' :
case 'config' : case 'config' :
case 'paths' :
$restartWarning = true; $restartWarning = true;
break; break;
case 'web' : case 'web' :

View File

@ -31,7 +31,6 @@ $tabs['skins'] = translate('Display');
$tabs['system'] = translate('System'); $tabs['system'] = translate('System');
$tabs['config'] = translate('Config'); $tabs['config'] = translate('Config');
$tabs['servers'] = translate('Servers'); $tabs['servers'] = translate('Servers');
$tabs['paths'] = translate('Paths');
$tabs['web'] = translate('Web'); $tabs['web'] = translate('Web');
$tabs['images'] = translate('Images'); $tabs['images'] = translate('Images');
$tabs['logging'] = translate('Logging'); $tabs['logging'] = translate('Logging');

View File

@ -50,3 +50,43 @@ ZM_DB_USER=@ZM_DB_USER@
# ZoneMinder database password # ZoneMinder database password
ZM_DB_PASS=@ZM_DB_PASS@ 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@