Author: rmeggins
Update of /cvs/dirsec/ldapserver/ldap/admin/src/scripts
In directory
cvs-int.fedora.redhat.com:/tmp/cvs-serv5442/ldapserver/ldap/admin/src/scripts
Modified Files:
Dialog.pm DialogManager.pm Resource.pm Setup.pm.in Util.pm
setup-ds.res.in
Log Message:
Resolves: bug 237356
Description: Move DS Admin Code into Admin Server
Reviewed by: nhosoi (Thanks!)
Fix Description: 1) Since we moved the o=NetscapeRoot code out of cfg_sspt.c, we no longer
need to create the suffix and backend in create_instance.c
2) Added code to enable/disable dialogs e.g. for dialogs that can change the flow
conditionally
3) Added code to allow the user to backup to the first prompt on a dialog, for dialogs
with many prompts
4) Allow continuation lines in Resource files, instead of having to have embedded \n
chars. This allows easier editing and layout.
5) Added an addSuffix function
6) Moved the register_servers.pl code from admin server into DS Util.pm and made it a
little more general purpose.
Platforms tested: RHEL4
Index: Dialog.pm
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/scripts/Dialog.pm,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Dialog.pm 12 Jun 2007 21:08:20 -0000 1.2
+++ Dialog.pm 15 Jun 2007 22:11:15 -0000 1.3
@@ -106,6 +106,21 @@
return $self->{type} <= $self->{"manager"}->{type};
}
+sub isEnabled {
+ my $self = shift;
+ return !defined($self->{disabled});
+}
+
+sub enable {
+ my $self = shift;
+ delete $self->{disabled};
+}
+
+sub disable {
+ my $self = shift;
+ $self->{disabled} = 1;
+}
+
# each prompt looks like this:
# [ 'resource key', is pwd, hide ]
# The resource key is the string key of the resource
@@ -135,7 +150,7 @@
my $prompt = $prompts[$index];
my $defaultans = $self->{defaultAns}($self, $index);
my $ans;
- if ($self->isDisplayed() && !$promtpt->[2]) {
+ if ($self->isDisplayed() && !$prompt->[2]) {
$ans = $self->{manager}->showPrompt($prompt->[0], $defaultans,
$prompt->[1]);
} else {
$ans = $defaultans;
@@ -155,12 +170,14 @@
# NOTE: user cannot BACK from prompt to prompt - BACK
# always means BACK to the previous dialog
$resp = $self->{handleResp}($self, $ans, $index);
- if ($resp == $DialogManager::SAME) {
+ if (($resp == $DialogManager::SAME) or ($resp == $DialogManager::FIRST)) {
if (!$self->isDisplayed()) {
$self->{manager}->alert('dialog_use_different_type');
$resp = $DialogManager::ERR;
- } else {
+ } elsif ($resp == $DialogManager::SAME) {
$index--; # reprompt
+ } else {
+ $index = -1; # reshow first prompt on dialog
}
} elsif ($resp == $DialogManager::ERR) {
last;
Index: DialogManager.pm
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/scripts/DialogManager.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DialogManager.pm 8 Jun 2007 01:09:16 -0000 1.1
+++ DialogManager.pm 15 Jun 2007 22:11:15 -0000 1.2
@@ -46,10 +46,11 @@
use SetupLog;
# Dialog responses
-$BACK = -1;
-$SAME = 0;
-$NEXT = 1;
-$ERR = 2;
+$FIRST = -2; # go back to first prompt on a dialog
+$BACK = -1; # go back to previous dialog
+$SAME = 0; # reshow the same prompt or dialog
+$NEXT = 1; # go to the next dialog
+$ERR = 2; # fatal error
# The DialogManager controls the flow of the dialogs and contains context shared
# among all of the dialogs (resources, logs, current setup type, etc.)
@@ -199,18 +200,20 @@
while (!$done) {
my $dialog = $self->{dialogs}->[$index];
- my $resp = $NEXT;
- $resp = $dialog->run();
- if ($resp == $BACK) {
- $incr = -1;
- } elsif ($resp == $NEXT) {
- $incr = 1;
- } elsif ($resp == $SAME) {
- $incr = 0;
- } else {
- $self->handleError($resp);
- $done = 1;
- $rc = 1;
+ if ($dialog->isEnabled()) {
+ my $resp = $NEXT;
+ $resp = $dialog->run();
+ if ($resp == $BACK) {
+ $incr = -1;
+ } elsif ($resp == $NEXT) {
+ $incr = 1;
+ } elsif (($resp == $SAME) or ($resp == $FIRST)) {
+ $incr = 0;
+ } else {
+ $self->handleError($resp);
+ $done = 1;
+ $rc = 1;
+ }
}
$index += $incr;
if ($index < 0) {
Index: Resource.pm
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/scripts/Resource.pm,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Resource.pm 8 Jun 2007 20:36:53 -0000 1.2
+++ Resource.pm 15 Jun 2007 22:11:15 -0000 1.3
@@ -74,19 +74,45 @@
}
for my $filename (@{$self->{filenames}}) {
+ my $incontinuation = 0;
+ my $curkey;
open RES, $filename or die "Error: could not open resource file $filename:
$!";
while (<RES>) {
- next if (/^\s*$/); # skip blank lines
- next if (/^\s*\#/); # skip comment lines
+ my $iscontinuation;
+ chop; # trim trailing newline
+ if (/^\s*$/) { # skip blank/empty lines
+ $incontinuation = 0;
+ next;
+ }
+ if (/^\s*\#/) { # skip comment lines
+ $incontinuation = 0;
+ next;
+ }
# read name = value pairs like this
# bol whitespace* name whitespace* '=' whitespace* value eol
# the value will include any trailing whitespace
- if (/^\s*(.*?)\s*=\s*(.*?)$/) {
- $self->{res}->{$1} = $2;
+ if (/\\$/) {
+ chop;
+ $iscontinuation = 1;
+ }
+ if ($incontinuation) {
+ $self->{res}->{$curkey} .= "\n" . $_;
+ } elsif (/^\s*(.*?)\s*=\s*(.*?)$/) {
# replace \n with real newline
- $self->{res}->{$1} =~ s/\\n/\n/g;
+ if ($curkey) {
+ $self->{res}->{$curkey} =~ s/\\n/\n/g;
+ }
+ $curkey = $1;
+ $self->{res}->{$curkey} = $2;
+ }
+ if ($iscontinuation) { # if line ends with a backslash, continue the data on
the next line
+ $incontinuation = 1;
+ } else {
+ $incontinuation = 0;
}
}
+ # replace \n with real newline
+ $self->{res}->{$curkey} =~ s/\\n/\n/g;
close RES;
}
}
Index: Setup.pm.in
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/scripts/Setup.pm.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Setup.pm.in 12 Jun 2007 21:08:20 -0000 1.2
+++ Setup.pm.in 15 Jun 2007 22:11:15 -0000 1.3
@@ -147,7 +147,7 @@
# arguments override those passed in via an inf file - this
# allows the reuse of .inf files with some parameters overridden
for (@ARGV) {
- if (/^(\w+).(\w+)=(.*)$/) { # e.g. section.param=value
+ if (/^(\w+)\.(\w+)=(.*)$/) { # e.g. section.param=value
$self->{inf}->{$1}->{$2} = $3;
} else { # error
print STDERR "Error: unknown command line option $_\n";
@@ -202,6 +202,21 @@
exit 1;
}
+# get a list of the directory servers in configdir
+sub getDirServers {
+ my $self = shift;
+ if (!$self->{dirservers}) {
+ $self->{dirservers} = [];
+ for my $dir (glob("$self->{configdir}/slapd-*")) {
+ if (-d $dir) {
+ push @{$self->{dirservers}}, $dir;
+ }
+ }
+ }
+ return @{$self->{dirservers}};
+}
+
+
#############################################################################
# Mandatory TRUE return value.
#
Index: Util.pm
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/scripts/Util.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Util.pm 8 Jun 2007 01:09:16 -0000 1.1
+++ Util.pm 15 Jun 2007 22:11:15 -0000 1.2
@@ -37,10 +37,18 @@
#
package Util;
+
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::Utils qw(normalizeDN);
+use Mozilla::LDAP::API; # Direct access to C API
+use Mozilla::LDAP::LDIF;
+
require Exporter;
@ISA = qw(Exporter);
-@EXPORT = qw(portAvailable getAvailablePort isValidDN);
-@EXPORT_OK = qw(portAvailable getAvailablePort isValidDN);
+@EXPORT = qw(portAvailable getAvailablePort isValidDN addSuffix getMappedEntries
+ process_maptbl check_and_add_entry getMappedEntries);
+@EXPORT_OK = qw(portAvailable getAvailablePort isValidDN addSuffix getMappedEntries
+ process_maptbl check_and_add_entry getMappedEntries);
use strict;
@@ -79,4 +87,526 @@
return ($dn =~ /^[0-9a-zA-Z_-]+=.*$/);
}
+sub debug {
+ print @_, "\n";
+}
+
+# delete the subtree starting from the passed entry
+sub delete_all
+{
+ my ($conn, $bentry) = @_;
+ my $sentry = $conn->search($bentry->{dn},
+ "subtree", "(objectclass=*)", 0, ("dn"));
+ my @mystack = ();
+ while ($sentry) {
+ push @mystack, $sentry->getDN();
+ $sentry = $conn->nextEntry();
+ }
+ # reverse order
+ my $dn = pop @mystack;
+ while ($dn) {
+ $conn->delete($dn);
+ my $rc = $conn->getErrorCode();
+ if ( $rc != 0 ) {
+ $conn->printError();
+ print "ERROR: unable to delete entry $dn, error code: $rc\n";
+ return 1;
+ }
+ $dn = pop @mystack;
+ }
+ return 0;
+}
+
+my %ignorelist = (
+ "modifytimestamp", "modifyTimestamp",
+ "createtimestamp", "createTimestamp",
+ "installationtimestamp", "installationTimestamp",
+ "creatorsname", "creatorsName",
+ "modifiersname", "modifiersName",
+ "numsubordinates", "numSubordinates"
+);
+
+my %speciallist = (
+ "uniquemember", 1
+);
+
+# compare 2 entries
+# return 0 if they match 100% (exception: %ignorelist).
+# return 1 if they match except %speciallist.
+# return -1 if they do not match.
+sub comp_entries
+{
+ my ($e0, $e1) = @_;
+ my $rc = 0;
+ foreach my $akey ( keys %{$e0} )
+ {
+ next if ( $ignorelist{lc($akey)} );
+ my $aval0 = $e0->{$akey};
+ my $aval1 = $e1->{$akey};
+ my $amin;
+ my $amax;
+ my $a0max = $#{$aval0};
+ my $a1max = $#{$aval1};
+ if ( $a0max != $a1max )
+ {
+ if ( $speciallist{lc($akey)} )
+ {
+ $rc = 1;
+ if ( $a0max < $a1max )
+ {
+ $amin = $a0max;
+ $amax = $a1max;
+ }
+ else
+ {
+ $amin = $a1max;
+ $amax = $a0max;
+ }
+ }
+ else
+ {
+ $rc = -1;
+ return $rc;
+ }
+ }
+ my @sval0 = sort { $a cmp $b } @{$aval0};
+ my @sval1 = sort { $a cmp $b } @{$aval1};
+ for ( my $i = 0; $i <= $amin; $i++ )
+ {
+ my $isspecial = -1;
+ if ( $sval0[$i] ne $sval1[$i] )
+ {
+ if ( 0 > $isspecial )
+ {
+ $isspecial = $speciallist{lc($akey)};
+ }
+ if ( $isspecial )
+ {
+ $rc = 1;
+ }
+ else
+ {
+ $rc = -1;
+ return $rc;
+ }
+ }
+ }
+ }
+ return $rc;
+}
+
+# if the entry does not exist on the server, add the entry.
+# otherwise, do nothing
+# you can use this as the callback to getMappedEntries, so
+# that for each entry in the ldif file being processed, you
+# can call this subroutine to add or update the entry
+# use like this:
+# getMappedEntries($mapper, \@ldiffiles, \&check_and_add_entry,
+# [$conn, $fresh, $verbose]);
+# where $conn is a perldap Conn
+# $fresh if true will update the entry if it exists
+# $verbose prints out more info
+sub check_and_add_entry
+{
+ my ($context, $aentry) = @_;
+ my $conn = $context->[0];
+ my $fresh = $context->[1];
+ my $verbose = $context->[2];
+ my $sentry = $conn->search($aentry->{dn}, "base",
"(objectclass=*)");
+ do
+ {
+ my $needtoadd = 1;
+ my $needtomod = 0;
+ my $rval = -1;
+ if ( $sentry && !$fresh )
+ {
+ $rval = comp_entries( $sentry, $aentry );
+ }
+ if ( 0 == $rval && !$fresh )
+ {
+ # the identical entry exists on the configuration DS.
+ # no need to add the entry.
+ $needtoadd = 0;
+ goto out;
+ }
+ elsif ( (1 == $rval) && !$fresh )
+ {
+ $needtoadd = 0;
+ $needtomod = 1;
+ }
+ elsif ( $sentry && $sentry->{dn} )
+ {
+ # $fresh || $rval == -1
+ # an entry having the same DN exists, but the attributes do not
+ # match. remove the entry and the subtree underneath.
+ if ( $verbose )
+ {
+ print "Deleting an entry dn: $sentry->{dn} ...\n";
+ }
+ $rval = delete_all($conn, $sentry);
+ if ( 0 != $rval )
+ {
+ return 0;
+ }
+ }
+
+ if ( 1 == $needtoadd )
+ {
+ $conn->add($aentry);
+ my $rc = $conn->getErrorCode();
+ if ( $rc != 0 )
+ {
+ print "ERROR: adding an entry $aentry->{dn} failed, error code: $rc\n";
+ print "[entry]\n";
+ $aentry->printLDIF();
+ $conn->close();
+ return 0;
+ }
+# if ( $verbose )
+# {
+# print "Entry $aentry->{dn} is added\n";
+# }
+ }
+ elsif ( 1 == $needtomod ) # $sentry exists
+ {
+ foreach my $attr ( keys %speciallist )
+ {
+ foreach my $nval ( @{$aentry->{$attr}} )
+ {
+ $sentry->addValue( $attr, $nval );
+ }
+ }
+ $conn->update($sentry);
+ my $rc = $conn->getErrorCode();
+ if ( $rc != 0 )
+ {
+ print "ERROR: updating an entry $sentry->{dn} failed, error code:
$rc\n";
+ print "[entry]\n";
+ $aentry->printLDIF();
+ $conn->close();
+ return 0;
+ }
+ }
+ if ( $sentry )
+ {
+ $sentry = $conn->nextEntry(); # supposed to have no more entries
+ }
+ } until ( !$sentry );
+out:
+ return 1;
+}
+
+# the default callback used with getMappedEntries
+# just adds the given entry to the given list
+sub cbaddent {
+ my $list = shift;
+ my $ent = shift;
+ push @{$list}, $ent;
+ return 1;
+}
+
+# given a mapper and a list of LDIF files, produce a list of
+# perldap Entry objects which have had their tokens subst-ed
+# with values from the mapper
+# An optional callback can be supplied. Each entry will be
+# given to this callback. The callback should return a list
+# of localizable errors. If no callback is supplied, the
+# entries will be returned in a list.
+# Arguments:
+# mapper - a hash ref - the keys are the tokens to replace
+# and the values are the replacements
+# ldiffiles - an array ref - the list of LDIF files to
+# operate on
+# callback (optional) - a code ref - a ref to a subroutine
+# that will be called with each entry - see below
+# context (optional) - this will be passed as the first
+# argument to your given callback - see below
+# errs (optional) - an array ref - This is how errors
+# are returned to the caller - see below
+# Callback:
+# The callback sub will be called for each entry after
+# the entry has been converted. The callback will be
+# called with the given context as the first argument
+# and the Mozilla::LDAP::Entry as the second argument,
+# and an errs array ref as the third argument. The
+# callback should return true to continue processing,
+# or false if a fatal error was encountered that should
+# abort processing of any further.
+# Errors:
+# This function should return an array of errors in the
+# format described below, for use with Resource::getText().
+# If the callback returns any errors
+# Return:
+# The return value is a list of entries.
+# Example usage:
+# sub handle_entries {
+# my $context = shift;
+# my $entry = shift;
+# .... do something with entry ....
+# .... if $context is Mozilla::LDAP::Conn, $conn->add($entry); ...
+# .... report errors ....
+# if ($fatalerror) {
+# return 0;
+# } else {
+# return 1;
+# }
+# }
+# $mapper = {foo => 'bar', baz => 'biff'};
+# @ldiffiles = ('foo.ldif', 'bar.ldif', ..., 'biff.ldif');
+# $conn = new Mozilla::LDAP::Conn(...);
+# @entries = getMappedEntries($mapper, \@ldiffiles, \&handle_entries, $conn);
+# Note that this will return 0 entries since a callback was used.
+# The simpler example is this:
+# @entries = getMappedEntries($mapper, \@ldiffiles);
+#
+sub getMappedEntries {
+ my $mapper = shift;
+ my $ldiffiles = shift;
+ my $callback = shift || \&cbaddent; # default - just add entry to @entries
+ my @entries = ();
+ my $context = shift || \@entries;
+ my $error;
+
+ if (!ref($ldiffiles)) {
+ $ldiffiles = [ $ldiffiles ];
+ }
+
+ foreach my $ldiffile (@{$ldiffiles}) {
+ open(MYLDIF, "< $ldiffile") or die "Can't open $ldiffile :
$!";
+ my $in = new Mozilla::LDAP::LDIF(*MYLDIF);
+ debug("Processing $ldiffile ...");
+ ENTRY: while (my $entry = Mozilla::LDAP::LDIF::readOneEntry($in)) {
+ # first, fix the DN
+ my $dn = $entry->getDN();
+ my $origdn = $dn;
+ while ( $dn =~ /%([\w_-]+)%/ ) {
+ if (exists($mapper->{$1})) {
+ $dn =~ s{%([\w_-]+)%}{$mapper->{$1}}ge;
+ } else {
+ print "ERROR: \"$origdn\" mapped to
\"$dn\".\n";
+ print "The LDIF file $ldiffile contains a token $1 for which
there is no mapper.\n";
+ print "Please check $ldiffile and your mapper to make sure all
tokens are handled correctly.\n";
+ $error = 1;
+ last ENTRY;
+ }
+ }
+ $entry->setDN($dn);
+ # next, fix all of the values in all of the attributes
+ foreach my $attr (keys %{$entry}) {
+ my @newvalues = ();
+ foreach my $value ($entry->getValues($attr)) {
+ # Need to repeat to handle nested subst
+ my $origvalue = $value;
+ while ( $value =~ /%([\w_-]+)%/ ) {
+ if (exists($mapper->{$1})) {
+ $value =~ s{%([\w_-]+)%}{$mapper->{$1}}ge;
+ } else {
+ print "ERROR: \"$origvalue\" mapped to
\"$value\".\n";
+ print "The LDIF file $ldiffile contains a token $1 for
which there is no mapper.\n";
+ print "Please check $ldiffile and your mapper to make
sure all tokens are handled correctly.\n";
+ $error = 1;
+ last ENTRY;
+ }
+ }
+ push @newvalues, $value;
+ }
+ $entry->setValues( $attr, @newvalues );
+ }
+
+ if (!&{$callback}($context, $entry)) {
+ print "There was an error processing entry ",
$entry->getDN(), "\n";
+ print "Cannot continue processing entries.\n";
+ $error = 1;
+ last ENTRY;
+ }
+
+ }
+ close(MYLDIF);
+ last if ($error); # do not process any more ldiffiles if an error occurred
+ }
+
+ return @entries;
+}
+
+# you should only use this function if you know for sure
+# that the suffix and backend do not already exist
+# use addSuffix instead
+sub newSuffixAndBackend {
+ my $context = shift;
+ my $suffix = shift;
+ my $bename = shift;
+ my $nsuffix = normalizeDN($suffix);
+ my @errs;
+
+ my $dn = "cn=$bename, cn=ldbm database, cn=plugins, cn=config";
+ my $entry = new Mozilla::LDAP::Entry();
+ $entry->setDN($dn);
+ $entry->setValues('objectclass', 'top',
'extensibleObject', 'nsBackendInstance');
+ $entry->setValues('cn', $bename);
+ $entry->setValues('nsslapd-suffix', $nsuffix);
+ $context->add($entry);
+ my $rc = $context->getErrorCode();
+ if ($rc) {
+ return ('error_creating_suffix_backend', $suffix, $bename,
$context->getErrorString());
+ }
+
+ $entry = new Mozilla::LDAP::Entry();
+ $dn = "cn=\"$nsuffix\", cn=mapping tree, cn=config";
+ $entry->setDN($dn);
+ $entry->setValues('objectclass', 'top',
'extensibleObject', 'nsMappingTree');
+ $entry->setValues('cn', "\"$nsuffix\"");
+ $entry->setValues('nsslapd-state', 'backend');
+ $entry->setValues('nsslapd-backend', $bename);
+ $context->add($entry);
+ $rc = $context->getErrorCode();
+ if ($rc) {
+ return ('error_creating_suffix', $suffix,
$context->getErrorString());
+ }
+
+ return ();
+}
+
+sub findbecb {
+ my $entry = shift;
+ my $attrs = shift;
+ return $entry->hasValue('objectclass', $attrs->[0], 1) &&
+ $entry->hasValue('cn', $attrs->[1], 1);
+}
+
+sub findBackend {
+ my $context = shift;
+ my $bename = shift;
+ my $ent;
+ if (ref($context) eq 'Mozilla::LDAP::Conn') {
+ $ent = $context->search("cn=ldbm database,cn=plugins,cn=config",
"one",
+
"(&(objectclass=nsBackendInstance)(cn=$bename)")
+ } else {
+ $ent = $context->search("cn=ldbm database,cn=plugins,cn=config",
"one",
+ \&findbecb, ['nsBackendInstance', $bename])
+ }
+}
+
+sub findsuffixcb {
+ my $entry = shift;
+ my $attrs = shift;
+ return $entry->hasValue('cn', $attrs->[0], 1) ||
+ $entry->hasValue('cn', $attrs->[1], 1);
+}
+
+sub findSuffix {
+ my $context = shift;
+ my $suffix = shift;
+ my $nsuffix = normalizeDN($suffix);
+ my $ent;
+ if (ref($context) eq 'Mozilla::LDAP::Conn') {
+ $ent = $context->search("cn=mapping tree,cn=config",
"one",
+
"(|(cn=\"$suffix\")(cn=\"$nsuffix\"))");
+ } else {
+ $ent = $context->search("cn=mapping tree,cn=config",
"one",
+ \&findsuffixcb, ["\"$suffix\"",
"\"$nsuffix\""])
+ }
+}
+
+sub getUniqueBackendName {
+ my $context = shift;
+ my $bename = "backend";
+ my $index = 0;
+ my $ent = findBackend($context, ($bename . $index));
+ while ($ent) {
+ ++$index;
+ $ent = findBackend($context, ($bename . $index));
+ }
+
+ return $bename.$index;
+}
+
+sub addSuffix {
+ my $context = shift; # Conn
+ my $suffix = shift;
+ my $bename = shift; # optional
+ my $ent;
+
+ if ($bename && ($ent = findBackend($context, $bename))) {
+ return ('backend_already_exists', $bename, $ent->getDN());
+ }
+
+ if ($ent = findSuffix($context, $suffix)) {
+ return ('suffix_already_exists', $suffix, $ent->getDN());
+ }
+
+ if (!$bename) {
+ $bename = getUniqueBackendName($context);
+ }
+
+ my @errs = newSuffixAndBackend($context, $suffix, $bename);
+
+ return @errs;
+}
+
+# process map table
+# [map table sample]
+# fqdn = FullMachineName
+# hostname = `use Sys::Hostname; $returnvalue = hostname();`
+# ds_console_jar ="%normbrand%-ds-%ds_version%.jar"
+#
+# * If the right-hand value is in ` (backquote), the value is eval'ed by perl.
+# The output should be stored in $returnvalue to pass to the internal hash.
+# * If the right-hand value is in " (doublequote), the value is passed as is.
+# * If the right-hand value is not in any quote, the value should be found
+# in either of the setup inf file (static) or the install inf file (dynamic).
+# * Variables surrounded by @ (e.g., @admin_confdir@) are replaced with the
+# system path at the compile time.
+# * The right-hand value can contain variables surrounded by % (e.g., %asid%)
+# which refers the right-hand value (key) of this map file.
+# The %token% tokens are replaced in getMappedEntries
+sub process_maptbl
+{
+ my ($mapper, @infdata) = @_;
+
+ if (defined($mapper->{""})) {
+ $mapper = $mapper->{""}; # side effect of Inf with no sections
+ }
+
+ KEY: foreach my $key (keys %{$mapper})
+ {
+ my $value = $mapper->{$key};
+ if ($value =~ /^\"/)
+ {
+ $value =~ tr/\"//d; # value is a regular double quoted string - remove
quotes
+ $mapper->{$key} = $value;
+ }
+ elsif ($value =~ /^\`/)
+ {
+ $value =~ tr/\`//d; # value is a perl expression to eval
+ my $returnvalue; # set in eval expression
+ eval $value;
+ $mapper->{$key} = $returnvalue; # perl expression sets $returnvalue
+ }
+ else
+ {
+ # get the value from one of the Inf passed in
+ my $infsection;
+ foreach my $thisinf (@infdata)
+ {
+ foreach my $section0 (keys %{$thisinf})
+ {
+ $infsection = $thisinf->{$section0};
+ next if (!ref($infsection));
+ if (defined($infsection->{$value}))
+ {
+ $mapper->{$key} = $infsection->{$value};
+ next KEY;
+ }
+ }
+ }
+ if (!defined($infsection->{$value}))
+ {
+ print "ERROR: $value not found in the .inf files\n";
+ return {};
+ }
+ }
+ }
+ return $mapper;
+}
+
1;
Index: setup-ds.res.in
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/admin/src/scripts/setup-ds.res.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- setup-ds.res.in 8 Jun 2007 20:36:53 -0000 1.2
+++ setup-ds.res.in 15 Jun 2007 22:11:15 -0000 1.3
@@ -79,3 +79,9 @@
dialog_dspopulate_text = You may wish to populate your new directory instance with some
data.\n"You may already have a file in LDIF format to use or some suggested\nentries
can be added. If you want to import entries from an LDIF\nfile, you may type in the full
path and filename at the prompt. If\nyou want the setup program to add the suggested
entries, type the\nword suggest at the prompt. The suggested entries are
common\ncontainer entries under your specified suffix, such as ou=People and\nou=Groups,
which are commonly used to hold the entries for the persons\nand groups in your
organization. If you do not want to add any of\nthese entries, type the word none at the
prompt.\n\n
dialog_dspopulate_prompt = Type the full path and filename, the word suggest, or the word
none
dialog_dspopulate_error = The file '%s' was not found. Please choose another
one.\n\n
+
+# ----------- miscellaneous ----------------
+backend_already_exists = A database backend with the name '%s' already exists.
Config entry DN '%s'. Please choose another backend name. addSuffix can generate
a unique backend name if you do not specify a backend name.\n\n
+suffix_already_exists = The suffix '%s' already exists. Config entry DN
'%s'.\n\n
+error_creating_suffix_backend = Could not create the suffix '%s'. There was an
error creating the backend database named '%s' for the suffix. Error: %s\n\n
+error_creating_suffix = Could not create the suffix '%s'. Error: %s\n\n