add method path_to_dn() to convert a given "path" to a DN
authorPeter Marschall <peter@adpm.de>
Sun, 06 Mar 2011 20:11:47 +0100
changeset 30 e4b4b0968107
parent 29 bd95c3aea253
child 31 a3a710f720dd
add method path_to_dn() to convert a given "path" to a DN path_to_dn() replaces the occurrences of '~', '.' and '..' in a path given and returns a DN. However, it does not check whether the DN is valid. Especially: - on return it is not guaranteed that the DN exists - on return the first part does not need to be a valid RDN
shelldap
--- a/shelldap	Sun Mar 06 14:53:39 2011 +0100
+++ b/shelldap	Sun Mar 06 20:11:47 2011 +0100
@@ -754,6 +754,53 @@
 	return;
 }
 
+# convert a given path to a DN: deal with '..', '.', '~'
+# Synopsis: $dn = $self->path_to_dn($path, [relative => N]);
+sub path_to_dn
+{
+	my $self  = shift;
+	my $path = shift;
+	my %flags = @_;
+	my $base = $self->base();
+
+	# fail on wrong / missing parameter
+	return undef  if (!defined($path));
+
+	# return configured base DN
+	return($conf->{basedn})  if ($path eq '~');
+
+	# return current base DN
+	return($base)  if ($path eq '.');
+
+	if ($path =~ /^\.\./o) {	# relative path
+		# support '..' (possibly iterated and as prefix to a DN)
+		my @base = @{ldap_explode_dn($base, casefold => 'none')};
+
+		# deal with leading ..,
+		while ($path =~ /^\.\./) {
+			shift(@base)  if (@base);
+			$path =~ s/^\.\.//;
+			last  if ($path !~ /,\s*/);
+			$path =~ s/,\s*//;
+		}
+
+		# build a new absolute DN
+		$path .= ',' . canonical_dn(\@base, casefold => 'none')
+			if (@base);
+	}
+	elsif ($path =~ /,\s*~$/o) {	# absolute path
+		$path =~ s/,\s*~$//;
+		$path.= ','.$conf->{basedn}
+			if ($conf->{basedn});
+	}
+	else {				# relative or absolute path
+		$path.= ','.$conf->{basedn}
+			if ($conf->{basedn} && $flags{relative});
+	}
+
+	return($path);
+}
+
 # given an array ref of shell-like globs, 
 # make and return an LDAP filter object.
 #
@@ -991,25 +1038,8 @@
 		$newbase = $self->{'previous_base'} || return;
 	}
 
-	# support '..' (possibly iterated and as prefix to a DN)
-	if ( $newbase =~ /^\.\.,?/ ) {
-		my @curbase = @{ldap_explode_dn($self->base(), casefold => 'none')};
-
-		# deal with leading ..,
-		while ($newbase =~ /^\.\./) {
-			shift(@curbase)  if (@curbase);
-			$newbase =~ s/^\.\.//;
-			last  if ($newbase !~ /,\s*/);
-			$newbase =~ s/,\s*//;
-		}
-
-		# build a new absolute DN
-		$newbase .= ',' . canonical_dn(\@curbase, casefold => 'none')
-			if (@curbase);
-	}
-	else {
-		$self->rdn_to_dn( \$newbase );
-	}
+	# convert given path to a DN
+	$newbase = $self->path_to_dn($newbase, relative => 1);
 	
 	unless ( $self->is_valid_dn( $newbase ) ) {
 		print "No such object\n";
@@ -1562,8 +1592,8 @@
 		return;
 	}
 
-	# ToDo: path_to_dn
-	$self->rdn_to_dn( \$dir );
+	# convert given path to DN
+	$dir = $self->path_to_dn($dir, relative => 1);
 
 	# normalize name, if it is not yet a legal DN
 	$dir = 'ou='.$dir  if (!canonical_dn($dir));