diff --git a/Changelog b/Changelog new file mode 100644 index 0000000..8638ba5 --- /dev/null +++ b/Changelog @@ -0,0 +1,35 @@ + 1.24: - AllowMultiOptions printed out the value and not the + option itself, if more than one of this particular + option occured. + - added -UseApacheInclude feature, contributed by + Thomas Klausner + - fixed bug with multiple options stuff, which did not + work with blocks or named blocks. Pointed out by + Thomas Klausner , who meant it being + feature request, but in fact it was a bug (IMHO). + - Config::General does now contain also it's OO-sister + Config::General::Extended, which is from now on + no more available as an extra module, because it + lived a shadowy existence. + - finally(!) created a Changelog file (this one, yes). + + 1.23: - fixed bug, which removed trailing or leading " even + no matching " was there. + + 1.22: - added a new option to new(): -LowerCaseNames, which + lowercases all option-names (feature request) + + 1.21: - lines with just one "#" became an option array named + "#" with empty entries, very weird, fixed + + 1.20: - added an if(exists... to new() for checking of the + existence of -AllowMultiOptions. + - use now "local $_" because it caused weird results + if a user used $_ with the module. + + 1.19: - you can escape "#" characters using a backslash: "\#" + which will now no more treated as a comment. + - comments inside here-documents will now remain in the + here-doc value. + + previous history logs are lost in space :-( \ No newline at end of file diff --git a/General.pm b/General.pm index d760360..72b8226 100644 --- a/General.pm +++ b/General.pm @@ -10,21 +10,6 @@ # All Rights Reserved. Std. disclaimer applies. # Artificial License, same as perl itself. Have fun. # -# 1.23: - fixed bug, which removed trailing or leading " even -# no matching " was there. -# 1.22: - added a new option to new(): -LowerCaseNames, which -# lowercases all option-names (feature request) -# 1.21: - lines with just one "#" became an option array named -# "#" with empty entries, very weird, fixed -# 1.20: - added an if(exists... to new() for checking of the -# existence of -AllowMultiOptions. -# - use now "local $_" because it caused weird results -# if a user used $_ with the module. -# 1.19: - you can escape "#" characters using a backslash: "\#" -# which will now no more treated as a comment. -# - comments inside here-documents will now remain in the -# here-doc value. - # namespace package Config::General; @@ -32,7 +17,7 @@ use FileHandle; use strict; use Carp; -$Config::General::VERSION = "1.23"; +$Config::General::VERSION = "1.24"; sub new { # @@ -61,6 +46,12 @@ sub new { $self->{LowerCaseNames} = 1; } } + # contributed by Thomas Klausner + if (exists $conf{-UseApacheInclude}) { + if ($conf{-UseApacheInclude}) { + $self->{UseApacheInclude} = 1; + } + } } elsif ($#param == 0) { # use of the old style @@ -178,6 +169,12 @@ sub _open { if (/^<>$/) { # include external config file $this->_open($1) if(!$c_comment); # call _open with the argument to include assuming it is a filename } + elsif ((/^[Ii]nclude (.+?)$/) && ($this->{UseApacheInclude})) { + # contributed by Thomas Klausner + # include external config file, Apache Style + # call _open with the argument to include assuming it is a filename + $this->_open($1) if(!$c_comment); + } else { # standard config line, push it onto the content stack push @{$this->{content}}, $_ if(!$c_comment); } @@ -195,6 +192,8 @@ sub _open { + + sub _parse { # # parse the contents of the file @@ -234,7 +233,7 @@ sub _parse { $option = lc($option) if $this->{LowerCaseNames}; if ($this->{NoMultiOptions}) { # configurable via special method ::NoMultiOptions() if (exists $config->{$option}) { - croak "Option $config->{$option} occurs more than once (level: $this->{level}, chunk $chunk)!\n"; + croak "Option \"$option\" occurs more than once (level: $this->{level}, chunk $chunk)!\n"; } $config->{$option} = $value; } @@ -245,7 +244,7 @@ sub _parse { delete $config->{$option}; push @{$config->{$option}}, $savevalue; } - push @{$config->{$option}}, $value; # it's still an array, just push + push @{$config->{$option}}, $value; # it's already an array, just push } else { $config->{$option} = $value; # standard config option, insert key/value pair into node @@ -263,12 +262,52 @@ sub _parse { push @newcontent, $_; # push onto new content stack } else { # calling myself recursively, end of $block reached, $block_level is 0 - if ($blockname) { - $config->{$block}->{$blockname} = # a named block, make it a hashref inside a hash within the current node - $this->_parse($config->{$block}->{$blockname}, \@newcontent); + if ($blockname) { # a named block, make it a hashref inside a hash within the current node + if (exists $config->{$block}->{$blockname}) { # the named block already exists, make it an array + if ($this->{NoMultiOptions}) { + croak "Named block \"<$block $blockname>\" occurs more than once (level: $this->{level}, chunk $chunk)!\n"; + } + else { # preserve existing data + my $savevalue = $config->{$block}->{$blockname}; + delete $config->{$block}->{$blockname}; + my @ar; + if (ref $savevalue eq "ARRAY") { + push @ar, @{$savevalue}; # preserve array if any + } + else { + push @ar, $savevalue; + } + push @ar, $this->_parse( {}, \@newcontent); # append it + $config->{$block}->{$blockname} = \@ar; + } + } + else { # the first occurence of this particular named block + $config->{$block}->{$blockname} = $this->_parse($config->{$block}->{$blockname}, \@newcontent); + } } else { # standard block - $config->{$block} = $this->_parse($config->{$block}, \@newcontent); + if (exists $config->{$block}) { # the block already exists, make it an array + if ($this->{NoMultiOptions}) { + croak "Block \"<$block>\" occurs more than once (level: $this->{level}, chunk $chunk)!\n"; + } + else { + my $savevalue = $config->{$block}; + delete $config->{$block}; + my @ar; + if (ref $savevalue eq "ARRAY") { + push @ar, @{$savevalue}; + } + else { + push @ar, $savevalue; + } + push @ar, $this->_parse( {}, \@newcontent); + $config->{$block} = \@ar; + } + } + else { + # the first occurence of this particular block + $config->{$block} = $this->_parse($config->{$block}, \@newcontent); + } } undef $blockname; undef $block; @@ -289,6 +328,12 @@ sub _parse { } + + + + + + sub NoMultiOptions { # # turn NoMultiOptions off, still exists for backward compatibility. @@ -376,7 +421,7 @@ Config::General - Generic Config Module =head1 DESCRIPTION -This small module opens a config file and parses it's contents for you. The B method +This module opens a config file and parses it's contents for you. The B method requires one parameter which needs to be a filename. The method B returns a hash which contains all options and it's associated values of your config file. @@ -402,8 +447,9 @@ Possible ways to call B: $conf = new Config::General( -file => "rcfile", - -AllowMultiOptions => "no" - -LowerCaseNames => "yes" + -AllowMultiOptions => "no", + -LowerCaseNames => "yes", + -UseApacheInclude => 1 ); $conf = new Config::General( @@ -429,6 +475,8 @@ still supported. Possible parameters are: -LowerCaseNames - if true (1 or "yes") then all options found in the config will be converted to lowercase. This allows you to provide case-in-sensitive configs + -UseApacheInclude - consider "include ..." as valid include statement (just + like the well known apache include statement). =item NoMultiOptions() @@ -591,31 +639,6 @@ state counter, which indicates a block end. If the module cannot find an end-block statement, then this block will be ignored. -=head1 IDENTICAL OPTIONS - -You may have more than one line of the same option with different values. - -Example: - log log1 - log log2 - log log2 - -You will get a scalar if the option occured only once or an array if it occured -more than once. If you expect multiple identical options, then you may need to -check if an option occured more than once: - - $allowed = $hash{jonas}->{tablestructure}->{allowed}; - if(ref($allowed) eq "ARRAY") { - @ALLOWED = @{$allowed}; - else { - @ALLOWED = ($allowed); - } - -If you don't want to allow more than one identical options, you may turn it off -by setting the flag I in the B method to "no". -If turned off, Config::General will complain about multiple occuring options -whit identical names! - =head1 NAMED BLOCKS @@ -653,6 +676,62 @@ You cannot have more than one named block with the same name because it will be stored in a hashref and therefore be overwritten if a block occurs once more. + +=head1 IDENTICAL OPTIONS + +You may have more than one line of the same option with different values. + +Example: + log log1 + log log2 + log log2 + +You will get a scalar if the option occured only once or an array if it occured +more than once. If you expect multiple identical options, then you may need to +check if an option occured more than once: + + $allowed = $hash{jonas}->{tablestructure}->{allowed}; + if(ref($allowed) eq "ARRAY") { + @ALLOWED = @{$allowed}; + else { + @ALLOWED = ($allowed); + } + +The same applies to blocks and named blocks too (they are described in more detail +below). For example, if you have the following config: + + + user max + + + user hannes + + +then you would end up with a data structure like this: + + $VAR1 = { + 'dir' => { + 'blah' => [ + { + 'user' => 'max' + }, + { + 'user' => 'hannes' + } + ] + } + }; + +As you can see, the two identical blocks are stored in a hash which contains +an array(-reference) of hashes. + +If you don't want to allow more than one identical options, you may turn it off +by setting the flag I in the B method to "no". +If turned off, Config::General will complain about multiple occuring options +whit identical names! + + + =head1 LONG LINES If you have a config value, which is too long and would take more than one line, @@ -714,11 +793,16 @@ line inside the here-document. =head1 INCLUDES -You can include an external file at any posision in you config file using the following statement +You can include an external file at any posision in your config file using the following statement in your config file: <> +If you turned on B<-UseApacheInclude> (see B), then you can also use the following +statement to include an external file: + + include externalconfig.rc + This file will be inserted at the position where it was found as if the contents of this file were directly at this position. @@ -762,9 +846,27 @@ you can use a backlsash in front of it, to escape it. Example: In this example the value of $config{bgcolor} will be "#ffffcc", Config::General will not treat the number sign as the begin of a comment because of the leading backslash. -Inside here-documents escaping of number signs is NOT required! +Inside here-documents escaping of number signs is NOT required! +=head1 OBJECT ORIENTED INTERFACE + +There is a way to access a parsed config the OO-way. +Use the module B, which is +supplied with the Config::General distribution. + + +=head1 SEE ALSO + +I recommend you to read the following documentations, which are supplied with perl: + + perlreftut Perl references short introduction + perlref Perl references, the rest of the story + perldsc Perl data structures intro + perllol Perl data structures: arrays of arrays + + Config::General::Extended Object oriented interface to parsed configs + =head1 COPYRIGHT Copyright (c) 2000-2001 Thomas Linden @@ -785,7 +887,7 @@ Thomas Linden =head1 VERSION -1.22 +1.24 =cut diff --git a/General/Extended.pm b/General/Extended.pm new file mode 100644 index 0000000..841272a --- /dev/null +++ b/General/Extended.pm @@ -0,0 +1,498 @@ +# +# Config::General::Extended - special Class based on Config::General +# +# Copyright (c) 2000-2001 Thomas Linden . +# All Rights Reserved. Std. disclaimer applies. +# Artificial License, same as perl itself. Have fun. +# + +# namespace +package Config::General::Extended; + +# yes we need the hash support of new() in 1.18 or higher! +use Config::General 1.18; + +use FileHandle; +use Carp; +use vars qw(@ISA); + +# inherit new() and so on from Config::General +@ISA = qw(Config::General); + +use strict; + + +$Config::General::Extended::VERSION = "1.2"; + + +sub obj { + # + # returns a config object from a given key + # or from the current config hash if the $key does not exist + # or an empty object if the content of $key is empty. + # + my($this, $key) = @_; + if (exists $this->{config}->{$key}) { + if (!$this->{config}->{$key}) { + return $this->new( () ); # empty object! + } + else { + return $this->new( $this->{config}->{$key} ); + } + } + else { + return $this->new( $this->{config} ); + } +} + + +sub value { + # + # returns a value of the config hash from a given key + # this can be a hashref or a scalar + # + my($this, $key, $value) = @_; + if ($value) { + $this->{config}->{$key} = $value; + } + else { + return $this->{config}->{$key} if(exists $this->{config}->{$key}); + } +} + + +sub hash { + # + # returns a value of the config hash from a given key + # as hash + # + my($this, $key) = @_; + return %{$this->{config}->{$key}} if(exists $this->{config}->{$key}); +} + + +sub array { + # + # returns a value of the config hash from a given key + # as array + # + my($this, $key) = @_; + return @{$this->{config}->{$key}} if(exists $this->{config}->{$key}); +} + + + +sub is_hash { + # + # return true if the given key contains a hashref + # + my($this, $key) = @_; + if (exists $this->{config}->{$key}) { + if (ref($this->{config}->{$key}) eq "HASH") { + return 1; + } + else { + return; + } + } + else { + return; + } +} + + + +sub is_array { + # + # return true if the given key contains an arrayref + # + my($this, $key) = @_; + if (exists $this->{config}->{$key}) { + if (ref($this->{config}->{$key}) eq "ARRAY") { + return 1; + } + else { + return; + } + } + else { + return; + } +} + + +sub is_scalar { + # + # returns true if the given key contains a scalar(or number) + # + my($this, $key) = @_; + if (exists $this->{config}->{$key} && !ref(exists $this->{config}->{$key})) { + return 1; + } + return; +} + + + +sub exists { + # + # returns true if the key exists + # + my($this, $key) = @_; + if (exists $this->{config}->{$key}) { + return 1; + } + else { + return; + } +} + + +sub keys { + # + # returns all keys under in the hash of the specified key, if + # it contains keys (so it must be a hash!) + # + my($this, $key) = @_; + if (exists $this->{config}->{$key} && ref($this->{config}->{$key}) eq "HASH") { + return map { $_ } keys %{$this->{config}->{$key}}; + } + else { + return (); + } +} + +sub save { + # + # save the config back to disk + # + my($this,$file) = @_; + my $fh = new FileHandle; + + if (!$file) { + $file = $this->{configfile}; + } + open $fh, ">$file" or croak "Could not open $file!($!)\n"; + $this->_store($fh, 0,%{$this->{config}}); +} + + +sub configfile { + # + # sets or returns the config filename + # + my($this,$file) = @_; + if ($file) { + $this->{configfile} = $file; + } + return $this->{configfile}; +} + + + +sub AUTOLOAD { + # + # returns the representing value, if it is a scalar. + # + my($this, $value) = @_; + my $key = $Config::General::Extended::AUTOLOAD; # get to know how we were called + $key =~ s/.*:://; # remove package name! + + if ($value) { + # just set $key to $value! + $this->{config}->{$key} = $value; + } + elsif (exists $this->{config}->{$key}) { + if ($this->is_hash($key)) { + croak "\"$key\" points to a hash and cannot be automatically accessed\n"; + } + elsif ($this->is_array($key)) { + croak "\"$key\" points to an array and cannot be automatically accessed\n"; + } + else { + return $this->{config}->{$key}; + } + } + else { + croak "\"$key\" does not exist within current object\n"; + } +} + +sub DESTROY { + my $this = shift; + $this = (); +} + +# keep this one +1; + + + + + +=head1 NAME + +Config::General::Extended - Extended access to Config files + +=head1 SYNOPSIS + + use Config::General::Extended; + $conf = new Config::General::Extended("rcfile"); + # or + $conf = new Config::General::Extended(\%somehash); + +=head1 DESCRIPTION + +This module is a subclass of B. You can use it if +you want OO access to parts of your config file. The following methods +are directly inherited from Config::General: B. + +Please refer to the L, if you want to learn about the usage +of the two methods mentioned above. The possible format of config files supported +by this module is also well described in L. + +=head1 METHODS + +=over + +=item new(filename) or new(\%somehash) + +This method returns a B object (a hash blessed into "Config::General::Extended" +namespace. All further methods must be used from that returned object. see below. + +Read a more detailed discussion on how to use the new() method in L. + + +=item NoMultiOptions() + +This method only exists for compatibility reasons. +Now you should set the new() flag B<-AllowMultiOptions> +to "no". + +Refer to L for details about this method. + +=item getall() + +Returns a hash structure which represents the whole config. + +If you use this method, then it would be probably +better to use the simpler module B. It is just mentioned here +for completeness. + + +=item save() + + +Writes the current config hash back to the harddisk. +It takes an optional argument: B. If you omit a filename, save() will +use the filename configured by the method B or B (see below). + + + +=item configfile('filename') + +Set the filename to be used by B to "filename". It returns the current +configured filename if called without arguments. + + +=item obj('key') + +Returns a new object (of Config::General::Extended Class) from the given key. +Short example: +Assume you have the following config: + + + + age 23 + + + age 56 + + + + blah blubber + blah gobble + leer + + +and already read it in using B, then you can get a +new object from the "individual" block this way: + + $individual = $conf->obj("individual"); + +Now if you call B on I<$individual> (just for reference) you would get: + + $VAR1 = ( + martin => { age => 13 } + ); + +Or, here is another use: + + my $individual = $conf->obj("individual"); + foreach my $person ($conf->keys("individual")) { + $man = $individual->obj($person); + print "$person is " . $man->value("age") . " years old\n"; + } + +See the discussion on B and B below. + +If the key from which you want to create a new object is empty, an empty +object will be returned. If you run the following on the above config: + + $obj = $conf->obj("other")->obj("leer"); + +Then $obj will be empty, just like if you have had run this: + + $obj = new Config::General::Extended( () ); + +Read operations on this empty object will return nothing or even fail. +But you can use an empty object for I a new config using write +operations, i.e.: + + $obj->someoption("value"); + +See the discussion on B below. + +=item hash('key') + +This method returns a hash(if it B one!) from the config which is referenced by +"key". Given the sample config above you would get: + + my %sub_hash = $conf->hash("individual"); + print Dumper(\%sub_hash); + $VAR1 = { + martin => { age => 13 } + }; + +=item array('key') + +This the equivalent of B mentioned above, except that it returns an array. +Again, we use the sample config mentioned above: + + $other = $conf->obj("other"); + my @blahs = $other->array("blah"); + print Dumper(\@blahs); + $VAR1 = [ "blubber", "gobble" ]; + + +=item value('key') + +This method returns the scalar value of a given key. Given the following sample +config: + + name = arthur + age = 23 + +you could do something like that: + + print $conf->value("name") . " is " . $conf->value("age") . " years old\n"; + + + +You can use this method also to set the value of "key" to something if you give over +a hash reference, array reference or a scalar in addition to the key. An example: + + $conf->value("key", \%somehash); + # or + $conf->value("key", \@somearray); + # or + $conf->value("key", $somescalar); + +Please note, that this method does not complain about existing values within "key"! + +=item is_hash('key') is_array('key') is_scalar('key') + +As seen above, you can access parts of your current config using hash, array or scalar +methods. But you are right if you guess, that this might become problematic, if +for example you call B on a key which is in real not a hash but a scalar. Under +normal circumstances perl would refuse this and die. + +To avoid such behavior you can use one of the methods is_hash() is_array() is_scalar() to +check if the value of "key" is really what you expect it to be. + +An example(based on the config example from above): + + if($conf->is_hash("individual") { + $individual = $conf->obj("individual"); + } + else { + die "You need to configure a "individual" block!\n"; + } + + +=item exists('key') + +This method returns just true if the given key exists in the config. + + +=item keys('key') + +Returns an array of the keys under the specified "key". If you use the example +config above you yould do that: + + print Dumper($conf->keys("individual"); + $VAR1 = [ "martin", "joseph" ]; + +You can use this method in B loops as seen in an example above(obj() ). + +=back + + +=head1 AUTOLOAD METHODS + +Another usefull feature is implemented in this class using the B feature +of perl. If you know the keynames of a block within your config, you can access to +the values of each individual key using the method notation. See the following example +and you will get it: + +We assume the following config: + + + name = Moser + prename = Peter + birth = 12.10.1972 + + +Now we read it in and process it: + + my $conf = new Config::General::Extended("configfile"); + my $person = $conf->obj("person"); + print $person->prename . " " . $person->name . " is " . $person->age . " years old\n"; + +This notation supports only scalar values! You need to make sure, that the block + does not contain any subblock or multiple identical options(which will become +an array after parsing)! + +Of course you can use this kind of methods for writing data too: + + $person->name("Neustein"); + +This changes the value of the "name" key to "Neustein". This feature behaves exactly like +B, which means you can assign hash or array references as well and that existing +values under the given key will be overwritten. + + +=head1 COPYRIGHT + +Copyright (c) 2000-2001 Thomas Linden + +This library is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. + + +=head1 BUGS + +none known yet. + + +=head1 AUTHOR + +Thomas Linden + + +=head1 VERSION + +1.1 + +=cut + diff --git a/MANIFEST b/MANIFEST index c954aa2..2f1511e 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,3 +1,5 @@ +Changelog +General/Extended.pm General.pm MANIFEST Makefile.PL diff --git a/README b/README index 2d6c1a0..b8323cb 100644 --- a/README +++ b/README @@ -1,7 +1,6 @@ NAME Config::General - Generic Config Module - SYNOPSIS use Config::General; $conf = new Config::General("rcfile"); @@ -37,6 +36,7 @@ INSTALLATION to read the complete documentation, type: perldoc Config::General + perldoc Config::General::Extended see some example config files which can be parsed with Config::Genreal in the subdirectory @@ -59,4 +59,4 @@ AUTHOR VERSION - 1.23 + 1.24 diff --git a/t/run.t b/t/run.t index 09bb992..427c647 100644 --- a/t/run.t +++ b/t/run.t @@ -1,15 +1,18 @@ # -# testscript for Conf.pm by Thomas Linden +# testscript for Config::General Classes by Thomas Linden +# # needs to be invoked using the command "make test" from -# the Conf.pm source directory. -# Under normal circumstances every test should run. +# the Config::General source directory. +# +# Under normal circumstances every test should succeed. -BEGIN { $| = 1; print "1..8\n";} +BEGIN { $| = 1; print "1..15\n";} use lib "blib/lib"; use Config::General; +use Config::General::Extended; use Data::Dumper; print "ok\n"; -print STDERR "\n1 .. ok # loading Config::General\n"; +print STDERR "\n1 .. ok # loading Config::General and Config::General::Extended\n"; foreach (2..7) { &p("t/cfg." . $_, $_); @@ -37,6 +40,76 @@ else { } +############## Extended Tests ################# + +$conf = new Config::General::Extended("t/test.rc"); +print "ok\n"; +print STDERR "9 .. ok # Creating a new object from config file\n"; + + + + +# now test the new notation of new() +my $conf2 = new Config::General::Extended( + -file => "t/test.rc", + -AllowMultiOptions => "yes" + ); +print "ok\n"; +print STDERR "10 .. ok # Creating a new object using the hash parameter way\n"; + + + + +my $domain = $conf->obj("domain"); +print "ok\n"; +print STDERR "11 .. ok # Creating a new object from a block\n"; + + + + +my $addr = $domain->obj("bar.de"); +print "ok\n"; +print STDERR "12 .. ok # Creating a new object from a sub block\n"; + + + + +my @keys = $conf->keys("domain"); +print "ok\n"; +print STDERR "13 .. ok # Getting values from the object\n"; + + + + + +# test various OO methods +if ($conf->is_hash("domain")) { + my $domains = $conf->obj("domain"); + foreach my $domain ($conf->keys("domain")) { + my $domain_obj = $domains->obj($domain); + foreach my $address ($domains->keys($domain)) { + my $blah = $domain_obj->value($address); + } + } +} +print "ok\n"; +print STDERR "14 .. ok # Using keys() and values() \n"; + +# test AUTOLOAD methods +my $conf3 = new Config::General::Extended( { name => "Moser", prename => "Hannes"} +); +my $n = $conf3->name; +my $p = $conf3->prename; +$conf3->name("Meier"); +$conf3->prename("Max"); +$conf3->save("t/test.cfg"); + +print "ok\n"; +print STDERR "15 .. ok # Using AUTOLOAD methods\n"; + + + + sub p { my($cfg, $t) = @_; open T, "<$cfg"; diff --git a/t/test.rc b/t/test.rc new file mode 100644 index 0000000..86a01b2 --- /dev/null +++ b/t/test.rc @@ -0,0 +1,90 @@ +/* + * Beispiel .redirect Datei. + * + * Wenn diese Datei nicht im $HOME des + * jeweiligen Benutzers vorhanden ist, + * oder wenn die vorhandene Datei aus + * irgendeinem Grund ungültig ist(Syntax) + * dann wird per Default alles an @domain + * zum Benutzer weitergeleitet. + * + * Syntax: + * Domain Blöcke beginnen mit und enden + * mit (equivalent zu apache config). + * Als Kommentare sind # sowie C-Style erlaubt(so + * wie dieser hier). + * Näheres zum Block siehe unten. + * + * Im Block kann man Variablen definieren, auf + * die man dann innerhalb der Blöcke zu- + * greifen kann (siehe sample!) + * + * + * Im Block kann man Mailinglisten einrichten + * allerdings rudimentär, d.h. es sind eigentlich nur + * Verteiler, aber immerhin. Die entsprechende Adresse + * muss im dazugehörigen Block definiert sein. + * + * Angegebene Emailadressen werden (zumindest im Moment) + * nicht überprüft, also 1:1 übernommen, also Sorgfalt + * walten lassen. + * + * Fragen/Kommentare/Kritik/Flames/Mecker an: + * Thomas Linden + * + */ + + + +/* + ********************************************************************* + * Hier kann man Variablen definieren und später mittels + * $variablenname verwenden. + ********************************************************************* + */ + + USER scip # via $USER verwendbar + + +host manna +host gorky + +/* + ********************************************************************* + * Für jede Domain muss ein Block vorhanden sein + ********************************************************************* + */ + + foo max@nasa.gov # foo@bar.de nach max@nasa.gov + + coderz %coderz # coderz@bar.de ist ein Verteiler, der + # in definiert ist. + + @ $USER # alles andere an "scip" schicken. + # Wenn nicht angegeben, kommen unbekannte + # Adressen an den Absender zurück, z.B. + # gibtsnet@bar.de würde "Unknown User" ver- + # ursachen! + + + + + +/* + ********************************************************************* + * Definition einer "Mailingliste", gültige Empfänger müssen mit + * dem Parameter "rcpt" definiert werden. Blöcke sind Domain- + * unabhängig, d.h. sie müssen einen eindeutigen Namen haben. + ********************************************************************* + */ + + rcpt solaar.designer@packetstorm.org + rcpt $USER + rcpt machine@star.wars.de + + + + + + +