diff --git a/configure.in b/configure.in index 93e53601f..d3fb5cfdf 100644 --- a/configure.in +++ b/configure.in @@ -190,7 +190,7 @@ AC_DEFINE_DIR([SYSCONFDIR],[sysconfdir],[Expanded configuration directory]) AC_SUBST(ZM_CONFIG,"$SYSCONFDIR/zm.conf") AC_OUTPUT(Makefile src/Makefile web/Makefile web/graphics/Makefile scripts/Makefile db/Makefile) -AC_OUTPUT(zm.conf zmconfig.pl src/zm_config.h web/zm_config.php scripts/zm db/zmschema.sql db/zmdrop.sql) -AC_OUTPUT(scripts/ZoneMinder/lib/ZoneMinder/Base.pm scripts/ZoneMinder/lib/ZoneMinder/Config.pm) +AC_OUTPUT(zm.conf src/zm_config.h web/zm_config.php scripts/zm db/zmschema.sql db/zmdrop.sql) +AC_OUTPUT(scripts/ZoneMinder/lib/ZoneMinder/Base.pm scripts/ZoneMinder/lib/ZoneMinder/Config.pm scripts/ZoneMinder/lib/ZoneMinder/ConfigAdmin.pm ) AC_CHECK_FILE(scripts/ZoneMinder/Makefile,,[cd scripts/ZoneMinder;perl Makefile.PL]) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index f48a92546..8b9fbc504 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -36,8 +36,13 @@ EXTRA_DIST = \ zmcontrol-kx-hcm10.pl zmcontrol-axis-v2.pl zmtrack.pl - ZoneMinder/lib/ZoneMinder.pm.in \ ZoneMinder/lib/ZoneMinder.pm \ + ZoneMinder/lib/ZoneMinder/Base.pm.in \ + ZoneMinder/lib/ZoneMinder/Config.pm.in \ + ZoneMinder/lib/ZoneMinder/Debug.pm \ + ZoneMinder/lib/ZoneMinder/Database.pm \ + ZoneMinder/lib/ZoneMinder/SharedMem.pm \ + ZoneMinder/lib/ZoneMinder/ConfigAdmin.pm \ ZoneMinder/Makefile.PL \ ZoneMinder/README \ ZoneMinder/t/ZoneMinder.t \ diff --git a/scripts/ZoneMinder/Makefile.PL b/scripts/ZoneMinder/Makefile.PL index 9e0f66098..0feaee720 100644 --- a/scripts/ZoneMinder/Makefile.PL +++ b/scripts/ZoneMinder/Makefile.PL @@ -13,6 +13,7 @@ WriteMakefile( 'lib/ZoneMinder/Debug.pm' => '$(INST_LIBDIR)/ZoneMinder/Debug.pm', 'lib/ZoneMinder/Database.pm' => '$(INST_LIBDIR)/ZoneMinder/Database.pm', 'lib/ZoneMinder/SharedMem.pm' => '$(INST_LIBDIR)/ZoneMinder/SharedMem.pm', + 'lib/ZoneMinder/ConfigAdmin.pm' => '$(INST_LIBDIR)/ZoneMinder/ConfigAdmin.pm', }, ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/ZoneMinder.pm', # retrieve abstract from module diff --git a/zmconfig.pl.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigAdmin.pm.in old mode 100755 new mode 100644 similarity index 92% rename from zmconfig.pl.in rename to scripts/ZoneMinder/lib/ZoneMinder/ConfigAdmin.pm.in index 65fdb68e0..2d0639f20 --- a/zmconfig.pl.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigAdmin.pm.in @@ -1,8 +1,6 @@ -#!/usr/bin/perl -w -# # ========================================================================== # -# Zone Minder Configuration Script, $Date$, $Revision$ +# ZoneMinder Config Admin Module, $Date$, $Revision$ # Copyright (C) 2003, 2004, 2005 Philip Coombes # # This program is free software; you can redistribute it and/or @@ -21,60 +19,51 @@ # # ========================================================================== # -# This script is used to provide an interactive initial configuration of -# ZoneMinder in one central place reducing the need to edit individual files. +# This module contains the debug definitions and functions used by the rest +# of the ZoneMinder scripts # +package ZoneMinder::ConfigAdmin; +use 5.006; use strict; -use Data::Dumper; -use Getopt::Long; +use warnings; + +require Exporter; +require ZoneMinder::Base; + +our @ISA = qw(Exporter ZoneMinder::Base); + +# Items to export into callers namespace by default. Note: do not export +# names by default without a very good reason. Use EXPORT_OK instead. +# Do not simply export all your public functions/methods/constants. + +# This allows declaration use ZoneMinder ':all'; +# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK +# will save memory. +our %EXPORT_TAGS = ( 'all' => [ qw( + +) ] ); + +our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); + +our @EXPORT = qw(); + +our $VERSION = $ZoneMinder::Base::VERSION; + +# ========================================================================== +# +# Configuration Administration +# +# ========================================================================== + use DBI; +use Data::Dumper; -$| = 1; - -sub Usage -{ - print( " -Usage: zmconfig.pl [--interactive|--generate] -Parameters are :- --i, --interactive - Whether to include interactive configuration, off by default --g, --generate - Whether to generate config include files, off by default -"); - exit( -1 ); -} - -use constant ZM_DB_HOST => "@ZM_DB_HOST@"; -use constant ZM_DB_NAME => "@ZM_DB_NAME@"; -use constant ZM_DB_USER => "@ZM_DB_USER@"; -use constant ZM_DB_PASS => "@ZM_DB_PASS@"; - -my $config_header = "src/zm_config_defines.h"; -my $config_sql = "db/zm_config.sql"; -my $interactive = undef; -my $generate = undef; - -if ( !GetOptions( 'interactive!'=>\$interactive, 'generate!'=>\$generate ) ) -{ - Usage(); -} - -if ( $interactive && $generate ) -{ - Usage(); -} - -my @match_options; -while( @ARGV ) -{ - push( @match_options, shift( @ARGV ) ); -} -foreach ( @match_options ) -{ - print( "Matching '$_'\n" ); -} +our $config_header = "src/zm_config_defines.h"; +our $config_sql = "db/zm_config.sql"; # Types -my %types = +our %types = ( string => { db_type=>'string', hint=>'string', pattern=>qr|^(.+)$|, format=>q( $1 ) }, alphanum => { db_type=>'string', hint=>'alphanumeric', pattern=>qr|^([a-zA-Z0-9-_]+)$|, format=>q( $1 ) }, @@ -94,7 +83,7 @@ my %types = include => { db_type=>'include', hint=>'local/path/to/file', pattern=>qr|^(.*)?$|, check=>q( -e $1 ), format=>q( $1 ) }, ); -my @options = +our @options = ( { name => "ZM_LANG_DEFAULT", @@ -1459,309 +1448,34 @@ body = "ZM alarm detected - %ED% secs, %EF%/%EFA% frames, t%EST%/m%ESM%/a%ESA% s }, ); -my %options_hash = map { ( $_->{name}, $_ ) } @options; +our %options_hash = map { ( $_->{name}, $_ ) } @options; -foreach my $option ( @options ) +sub INIT { - if ( defined($option->{default}) ) - { - $option->{value} = $option->{default} - } - else - { - $option->{value} = ''; - } -} - -# Create option ids -my $option_id = 0; -foreach my $option ( @options ) -{ - next if ( $option->{category} eq 'core' ); - next if ( $option->{type} == $types{include} ); - $option->{id} = $option_id++; -} - - -if ( $generate ) -{ - print( "Generating '$config_header'\n" ); - open( CFG_HDR_FILE, ">$config_header" ) or die( "Can't open '$config_header' for writing" ); - print( CFG_HDR_FILE "// The file is autogenerated by zmconfig.pl\n" ); - print( CFG_HDR_FILE "// Do not edit this file as any changes will be overwritten\n\n" ); - my $last_id = 0; - my $define_list = ""; - my $declare_list = ""; - my $assign_list = ""; + # Do some initial data munging to finish the data structures foreach my $option ( @options ) { - next if ( !defined($option->{id}) ); - - my $opt_id = $option->{id}; - my $opt_name = $option->{name}; - my $opt_type = $option->{type}; - my $var_name = substr( lc($opt_name), 3 ); - - $define_list .= sprintf( "#define $opt_name $opt_id\n" ); - - $declare_list .= sprintf( "\t" ); - if ( $opt_type->{db_type} eq 'boolean' ) + if ( defined($option->{default}) ) { - $declare_list .= sprintf( "bool " ); - } - elsif ( $opt_type->{db_type} eq 'integer' || $opt_type->{db_type} eq 'hexadecimal' ) - { - $declare_list .= sprintf( "int " ); - } - elsif ( $opt_type->{db_type} eq 'decimal' ) - { - $declare_list .= sprintf( "double " ); + $option->{value} = $option->{default} } else { - $declare_list .= sprintf( "const char *" ); + $option->{value} = ''; } - $declare_list .= sprintf( $var_name.";\\\n" ); - - $assign_list .= sprintf( "\t" ); - $assign_list .= sprintf( $var_name." = " ); - if ( $opt_type->{db_type} eq 'boolean' ) - { - $assign_list .= sprintf( "(bool)" ); - } - elsif ( $opt_type->{db_type} eq 'integer' || $opt_type->{db_type} eq 'hexadecimal' ) - { - $assign_list .= sprintf( "(int)" ); - } - elsif ( $opt_type->{db_type} eq 'decimal' ) - { - $assign_list .= sprintf( "(double) " ); - } - else - { - $assign_list .= sprintf( "(const char *)" ); - } - $assign_list .= sprintf( "config.Item( ".$opt_name." );\\\n" ); - - $last_id = $option->{id}; } - print( CFG_HDR_FILE $define_list."\n\n" ); - print( CFG_HDR_FILE "#define ZM_MAX_CFG_ID $last_id\n\n" ); - print( CFG_HDR_FILE "#define ZM_CFG_DECLARE_LIST \\\n" ); - print( CFG_HDR_FILE $declare_list."\n\n" ); - print( CFG_HDR_FILE "#define ZM_CFG_ASSIGN_LIST \\\n" ); - print( CFG_HDR_FILE $assign_list."\n\n" ); - close( CFG_HDR_FILE ); - print( "Generating '$config_sql'\n" ); - open( CFG_SQL_FILE, ">$config_sql" ) or die( "Can't open '$config_sql' for writing" ); - print( CFG_SQL_FILE "-- The file is autogenerated by zmconfig.pl\n" ); - print( CFG_SQL_FILE "-- Do not edit this file as any changes will be overwritten\n\n" ); - print( CFG_SQL_FILE "delete from Config;\n\n" ); + # Create option ids + my $option_id = 0; foreach my $option ( @options ) { next if ( $option->{category} eq 'core' ); next if ( $option->{type} == $types{include} ); - #print( $option->{name}."\n" ) if ( !$option->{category} ); - $option->{db_type} = $option->{type}->{db_type}; - $option->{db_hint} = $option->{type}->{hint}; - $option->{db_pattern} = $option->{type}->{pattern}; - $option->{db_format} = $option->{type}->{format}; - if ( $option->{db_type} eq "boolean" ) - { - $option->{db_value} = ($option->{value} eq "yes")?"1":"0"; - } - else - { - $option->{db_value} = $option->{value}; - } - if ( my $requires = $option->{requires} ) - { - $option->{db_requires} = join( ";", map { my $value = $_->{value}; $value = ($value eq "yes")?1:0 if ( $options_hash{$_->{name}}->{db_type} eq "boolean" ); ( "$_->{name}=$value" ) } @$requires ); - } - else - { - $option->{db_requires} = ""; - } - printf( CFG_SQL_FILE - "replace into Config set Id = %d, Name = '%s', Value = '%s', Type = '%s', DefaultValue = '%s', Hint = '%s', Pattern = '%s', Format = '%s', Prompt = '%s', Help = '%s', Category = '%s', Readonly = '%s', Requires = '%s';\n", - $option->{id}, $option->{name}, $option->{db_value}, $option->{db_type}, $option->{default}, $option->{db_hint}, $option->{db_pattern}, $option->{db_format}, $option->{description}, $option->{help}, $option->{category}, $option->{readonly}?1:0, $option->{db_requires} - ); + $option->{id} = $option_id++; } - print( CFG_SQL_FILE "\n" ); - close( CFG_SQL_FILE ); -} -else -{ - loadOptionsFromDB(); - - if ( $interactive ) - { - print( " -Welcome to the ZoneMinder interactive configuration utility. - -You will now be prompted to enter information allowing ZoneMinder to -be configured for your system. Entering '?' at most prompts will print -further information about each option if you are not sure what to put. -You can also type 'q' at any time to exit without saving or 'x' to -exit with the remaining options set to their previous or default -values. - -Press enter to continue: " ); - my $input = <>; - print( "\n" ); - - foreach my $option ( @options ) - { - next if ( $option->{readonly} ); - next if ( @match_options && !grep { $option->{name} =~ /^$_$/ } @match_options ); - - if ( my $requires = $option->{requires} ) - { - my $do_option; - foreach my $require ( @$requires ) - { - if ( my $require_option = $options_hash{$require->{name}} ) - { - if ( $require_option->{value} =~ /^$require->{value}/ ) - { - $do_option = !undef; - last; - } - } - } - next if ( !$do_option ); - } - if ( $option->{introduction} ) - { - print( '-'x76 . "\n" ); - print( breaktext( $option->{introduction} ) ); - print( '-'x76 . "\n" ); - } - my $type = $option->{type}; - if ( !$type ) - { - warn( "No type found" ); - $type = $types{string}; - } - while( 1 ) - { - print( "$option->{description} ($type->{hint}) " ); - print( "[$option->{value}] " ) if ( defined($option->{value}) ); - print( ": " ); - my $new_value = <>; - chomp( $new_value ); - if ( defined($new_value) ) - { - if ( $new_value =~ /^\?/ ) - { - if ( $option->{help} ) - { - print( "\n".breaktext($option->{help})."\n" ); - } - else - { - print( "Sorry, no help is available for this item\n" ); - } - next; - } - elsif ( $new_value eq 'x' ) - { - print( "Using existing values for remaining options\n" ); - goto FINISHED; - } - elsif ( $new_value eq 'q' ) - { - print( "Exiting\n" ); - exit( 0 ); - } - elsif ( $new_value eq '' ) - { - if ( $option->{value} ) - { - last; - } - } - #print( "N:$new_value\n" ); - my $pattern = $type->{pattern}; - if ( $new_value !~ $pattern || ( $type->{check} && !eval( $type->{check} ) ) ) - { - print( "Invalid input, please re-enter or type '?' for help.\n" ); - next; - } - #print( "U:$use_value\n" ); - my $format = $type->{format}; - $option->{value} = eval( $format ); - } - last; - } - if ( my $check = $option->{check} ) - { - if ( my $result = &$check( $option->{value} ) ) - { - # All ok - print( "Exists\n" ); - } - else - { - print( "Missing\n" ); - } - } - } - } -FINISHED: - - saveOptionsToDB(); } -exit; - -sub saveOptionsToDB -{ - print( "Saving config to DB\n" ); - my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); - - if ( !$dbh ) - { - print( "Error: unable to save options to database: $DBI::errstr\n" ); - return( 0 ); - } - my $sql = "delete from Config"; - my $res = $dbh->do( $sql ) or die( "Can't do '$sql': ".$dbh->errstr() ); - - $sql = "replace into Config set Id = ?, Name = ?, Value = ?, Type = ?, DefaultValue = ?, Hint = ?, Pattern = ?, Format = ?, Prompt = ?, Help = ?, Category = ?, Readonly = ?, Requires = ?"; - my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); - foreach my $option ( @options ) - { - next if ( $option->{category} eq 'core' ); - next if ( $option->{type} == $types{include} ); - #print( $option->{name}."\n" ) if ( !$option->{category} ); - $option->{db_type} = $option->{type}->{db_type}; - $option->{db_hint} = $option->{type}->{hint}; - $option->{db_pattern} = $option->{type}->{pattern}; - $option->{db_format} = $option->{type}->{format}; - if ( $option->{db_type} eq "boolean" ) - { - $option->{db_value} = ($option->{value} eq "yes")?"1":"0"; - } - else - { - $option->{db_value} = $option->{value}; - } - if ( my $requires = $option->{requires} ) - { - $option->{db_requires} = join( ";", map { my $value = $_->{value}; $value = ($value eq "yes")?1:0 if ( $options_hash{$_->{name}}->{db_type} eq "boolean" ); ( "$_->{name}=$value" ) } @$requires ); - } - else - { - } - my $res = $sth->execute( $option->{id}, $option->{name}, $option->{db_value}, $option->{db_type}, $option->{default}, $option->{db_hint}, $option->{db_pattern}, $option->{db_format}, $option->{description}, $option->{help}, $option->{category}, $option->{readonly}?1:0, $option->{db_requires} ) or die( "Can't execute: ".$sth->errstr() ); - } - $sth->finish(); - $dbh->disconnect(); -} - -sub loadOptionsFromDB +sub loadConfigFromDB { print( "Loading config from DB\n" ); my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); @@ -1807,10 +1521,100 @@ sub loadOptionsFromDB return( $option_count ); } -sub breaktext +sub saveConfigToDB { - my $text = shift; - ( my $broken_text = $text ) =~ s/(.{1,76})(?:\s|$)/$1\n/g; - return( $broken_text ); + print( "Saving config to DB\n" ); + my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); + + if ( !$dbh ) + { + print( "Error: unable to save options to database: $DBI::errstr\n" ); + return( 0 ); + } + my $sql = "delete from Config"; + my $res = $dbh->do( $sql ) or die( "Can't do '$sql': ".$dbh->errstr() ); + + $sql = "replace into Config set Id = ?, Name = ?, Value = ?, Type = ?, DefaultValue = ?, Hint = ?, Pattern = ?, Format = ?, Prompt = ?, Help = ?, Category = ?, Readonly = ?, Requires = ?"; + my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); + foreach my $option ( @options ) + { + next if ( $option->{category} eq 'core' ); + next if ( $option->{type} == $types{include} ); + #print( $option->{name}."\n" ) if ( !$option->{category} ); + $option->{db_type} = $option->{type}->{db_type}; + $option->{db_hint} = $option->{type}->{hint}; + $option->{db_pattern} = $option->{type}->{pattern}; + $option->{db_format} = $option->{type}->{format}; + if ( $option->{db_type} eq "boolean" ) + { + $option->{db_value} = ($option->{value} eq "yes")?"1":"0"; + } + else + { + $option->{db_value} = $option->{value}; + } + if ( my $requires = $option->{requires} ) + { + $option->{db_requires} = join( ";", map { my $value = $_->{value}; $value = ($value eq "yes")?1:0 if ( $options_hash{$_->{name}}->{db_type} eq "boolean" ); ( "$_->{name}=$value" ) } @$requires ); + } + else + { + } + my $res = $sth->execute( $option->{id}, $option->{name}, $option->{db_value}, $option->{db_type}, $option->{default}, $option->{db_hint}, $option->{db_pattern}, $option->{db_format}, $option->{description}, $option->{help}, $option->{category}, $option->{readonly}?1:0, $option->{db_requires} ) or die( "Can't execute: ".$sth->errstr() ); + } + $sth->finish(); + $dbh->disconnect(); } +1; +__END__ +# Below is stub documentation for your module. You'd better edit it! + +=head1 NAME + +ZoneMinder::Debug - Perl extension for blah blah blah + +=head1 SYNOPSIS + + use ZoneMinder::Debug; + blah blah blah + +=head1 DESCRIPTION + +Stub documentation for ZoneMinder, created by h2xs. It looks like the +author of the extension was negligent enough to leave the stub +unedited. + +Blah blah blah. + +=head2 EXPORT + +None by default. + + + +=head1 SEE ALSO + +Mention other useful documentation such as the documentation of +related modules or operating system documentation (such as man pages +in UNIX), or any relevant external documentation such as RFCs or +standards. + +If you have a mailing list set up for your module, mention it here. + +If you have a web site set up for your module, mention it here. + +=head1 AUTHOR + +Philip Coombes, Ephilip.coombes@zoneminder.comE + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2005 by Philip Coombes + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.8.3 or, +at your option, any later version of Perl 5 you may have available. + + +=cut diff --git a/zmconfgen.pl b/zmconfgen.pl new file mode 100644 index 000000000..f11bdfadc --- /dev/null +++ b/zmconfgen.pl @@ -0,0 +1,299 @@ +#!/usr/bin/perl -w +# +# ========================================================================== +# +# Zone Minder Configuration Script, $Date$, $Revision$ +# Copyright (C) 2003, 2004, 2005 Philip Coombes +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# ========================================================================== +# +# This script is used to generate initial config headers and database data. +# + +use strict; +use ZoneMinder::ConfigAdmin; + +$| = 1; + +my $config_header = "src/zm_config_defines.h"; +my $config_sql = "db/zm_config.sql"; + +generateConfigFiles(); + +exit; + +sub generateConfigFiles +{ + generateConfigHeader(); + generateConfigSQL(); +} + +sub generateConfigHeader +{ + print( "Generating '$config_header'\n" ); + open( CFG_HDR_FILE, ">$config_header" ) or die( "Can't open '$config_header' for writing" ); + print( CFG_HDR_FILE "// The file is autogenerated by zmconfig.pl\n" ); + print( CFG_HDR_FILE "// Do not edit this file as any changes will be overwritten\n\n" ); + my $last_id = 0; + my $define_list = ""; + my $declare_list = ""; + my $assign_list = ""; + foreach my $option ( @options ) + { + next if ( !defined($option->{id}) ); + + my $opt_id = $option->{id}; + my $opt_name = $option->{name}; + my $opt_type = $option->{type}; + my $var_name = substr( lc($opt_name), 3 ); + + $define_list .= sprintf( "#define $opt_name $opt_id\n" ); + + $declare_list .= sprintf( "\t" ); + if ( $opt_type->{db_type} eq 'boolean' ) + { + $declare_list .= sprintf( "bool " ); + } + elsif ( $opt_type->{db_type} eq 'integer' || $opt_type->{db_type} eq 'hexadecimal' ) + { + $declare_list .= sprintf( "int " ); + } + elsif ( $opt_type->{db_type} eq 'decimal' ) + { + $declare_list .= sprintf( "double " ); + } + else + { + $declare_list .= sprintf( "const char *" ); + } + $declare_list .= sprintf( $var_name.";\\\n" ); + + $assign_list .= sprintf( "\t" ); + $assign_list .= sprintf( $var_name." = " ); + if ( $opt_type->{db_type} eq 'boolean' ) + { + $assign_list .= sprintf( "(bool)" ); + } + elsif ( $opt_type->{db_type} eq 'integer' || $opt_type->{db_type} eq 'hexadecimal' ) + { + $assign_list .= sprintf( "(int)" ); + } + elsif ( $opt_type->{db_type} eq 'decimal' ) + { + $assign_list .= sprintf( "(double) " ); + } + else + { + $assign_list .= sprintf( "(const char *)" ); + } + $assign_list .= sprintf( "config.Item( ".$opt_name." );\\\n" ); + + $last_id = $option->{id}; + } + print( CFG_HDR_FILE $define_list."\n\n" ); + print( CFG_HDR_FILE "#define ZM_MAX_CFG_ID $last_id\n\n" ); + print( CFG_HDR_FILE "#define ZM_CFG_DECLARE_LIST \\\n" ); + print( CFG_HDR_FILE $declare_list."\n\n" ); + print( CFG_HDR_FILE "#define ZM_CFG_ASSIGN_LIST \\\n" ); + print( CFG_HDR_FILE $assign_list."\n\n" ); + close( CFG_HDR_FILE ); +} + +sub generateConfigSQL +{ + print( "Generating '$config_sql'\n" ); + open( CFG_SQL_FILE, ">$config_sql" ) or die( "Can't open '$config_sql' for writing" ); + print( CFG_SQL_FILE "-- The file is autogenerated by zmconfig.pl\n" ); + print( CFG_SQL_FILE "-- Do not edit this file as any changes will be overwritten\n\n" ); + print( CFG_SQL_FILE "delete from Config;\n\n" ); + foreach my $option ( @options ) + { + next if ( $option->{category} eq 'core' ); + next if ( $option->{type} == $types{include} ); + #print( $option->{name}."\n" ) if ( !$option->{category} ); + $option->{db_type} = $option->{type}->{db_type}; + $option->{db_hint} = $option->{type}->{hint}; + $option->{db_pattern} = $option->{type}->{pattern}; + $option->{db_format} = $option->{type}->{format}; + if ( $option->{db_type} eq "boolean" ) + { + $option->{db_value} = ($option->{value} eq "yes")?"1":"0"; + } + else + { + $option->{db_value} = $option->{value}; + } + if ( my $requires = $option->{requires} ) + { + $option->{db_requires} = join( ";", map { my $value = $_->{value}; $value = ($value eq "yes")?1:0 if ( $options_hash{$_->{name}}->{db_type} eq "boolean" ); ( "$_->{name}=$value" ) } @$requires ); + } + else + { + $option->{db_requires} = ""; + } + printf( CFG_SQL_FILE + "replace into Config set Id = %d, Name = '%s', Value = '%s', Type = '%s', DefaultValue = '%s', Hint = '%s', Pattern = '%s', Format = '%s', Prompt = '%s', Help = '%s', Category = '%s', Readonly = '%s', Requires = '%s';\n", + $option->{id}, $option->{name}, $option->{db_value}, $option->{db_type}, $option->{default}, $option->{db_hint}, $option->{db_pattern}, $option->{db_format}, $option->{description}, $option->{help}, $option->{category}, $option->{readonly}?1:0, $option->{db_requires} + ); + } + print( CFG_SQL_FILE "\n" ); + close( CFG_SQL_FILE ); +} + +sub loadConfigFromDB +{ + print( "Loading config from DB\n" ); + my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); + + if ( !$dbh ) + { + print( "Error: unable to load options from database: $DBI::errstr\n" ); + return( 0 ); + } + my $sql = "select * from Config"; + my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); + my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() ); + my $option_count = 0; + while( my $config = $sth->fetchrow_hashref() ) + { + my ( $name, $value ) = ( $config->{Name}, $config->{Value} ); + #print( "Name = '$name'\n" ); + my $option = $options_hash{$name}; + if ( !$option ) + { + warn( "No option '$name' found, removing" ); + next; + } + next if ( $option->{category} eq 'core' ); + if ( defined($value) ) + { + if ( $name eq "ZM_OPT_MPEG" && $value eq "yes" ) + { + $value = "mpeg_encode"; + } + if ( $option->{type} == $types{boolean} ) + { + $option->{value} = $value?"yes":"no"; + } + else + { + $option->{value} = $value; + } + } + $option_count++;; + } + $dbh->disconnect(); + return( $option_count ); +} + +sub saveConfigToDB +{ + print( "Saving config to DB\n" ); + my $dbh = DBI->connect( "DBI:mysql:database=".ZM_DB_NAME.";host=".ZM_DB_HOST, ZM_DB_USER, ZM_DB_PASS ); + + if ( !$dbh ) + { + print( "Error: unable to save options to database: $DBI::errstr\n" ); + return( 0 ); + } + my $sql = "delete from Config"; + my $res = $dbh->do( $sql ) or die( "Can't do '$sql': ".$dbh->errstr() ); + + $sql = "replace into Config set Id = ?, Name = ?, Value = ?, Type = ?, DefaultValue = ?, Hint = ?, Pattern = ?, Format = ?, Prompt = ?, Help = ?, Category = ?, Readonly = ?, Requires = ?"; + my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() ); + foreach my $option ( @options ) + { + next if ( $option->{category} eq 'core' ); + next if ( $option->{type} == $types{include} ); + #print( $option->{name}."\n" ) if ( !$option->{category} ); + $option->{db_type} = $option->{type}->{db_type}; + $option->{db_hint} = $option->{type}->{hint}; + $option->{db_pattern} = $option->{type}->{pattern}; + $option->{db_format} = $option->{type}->{format}; + if ( $option->{db_type} eq "boolean" ) + { + $option->{db_value} = ($option->{value} eq "yes")?"1":"0"; + } + else + { + $option->{db_value} = $option->{value}; + } + if ( my $requires = $option->{requires} ) + { + $option->{db_requires} = join( ";", map { my $value = $_->{value}; $value = ($value eq "yes")?1:0 if ( $options_hash{$_->{name}}->{db_type} eq "boolean" ); ( "$_->{name}=$value" ) } @$requires ); + } + else + { + } + my $res = $sth->execute( $option->{id}, $option->{name}, $option->{db_value}, $option->{db_type}, $option->{default}, $option->{db_hint}, $option->{db_pattern}, $option->{db_format}, $option->{description}, $option->{help}, $option->{category}, $option->{readonly}?1:0, $option->{db_requires} ) or die( "Can't execute: ".$sth->errstr() ); + } + $sth->finish(); + $dbh->disconnect(); +} + +1; +__END__ +# Below is stub documentation for your module. You'd better edit it! + +=head1 NAME + +ZoneMinder::Debug - Perl extension for blah blah blah + +=head1 SYNOPSIS + + use ZoneMinder::Debug; + blah blah blah + +=head1 DESCRIPTION + +Stub documentation for ZoneMinder, created by h2xs. It looks like the +author of the extension was negligent enough to leave the stub +unedited. + +Blah blah blah. + +=head2 EXPORT + +None by default. + + + +=head1 SEE ALSO + +Mention other useful documentation such as the documentation of +related modules or operating system documentation (such as man pages +in UNIX), or any relevant external documentation such as RFCs or +standards. + +If you have a mailing list set up for your module, mention it here. + +If you have a web site set up for your module, mention it here. + +=head1 AUTHOR + +Philip Coombes, Ephilip.coombes@zoneminder.comE + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2005 by Philip Coombes + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself, either Perl version 5.8.3 or, +at your option, any later version of Perl 5 you may have available. + + +=cut