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_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")

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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...

View File

@ -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)

View File

@ -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',

View File

@ -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;
}
}
}

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 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 ) ) {

View File

@ -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

View File

@ -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;

View File

@ -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]);

View File

@ -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 );
}

View File

@ -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 ) ) {

View File

@ -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

View File

@ -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 );
}

View File

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

View File

@ -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');

View File

@ -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@