[LDAPsh-cvs] ldapsh ldapsh,1.50,1.51
Status: Beta
Brought to you by:
rcorvalan
From: <j-d...@us...> - 2004-02-25 02:17:58
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23533 Modified Files: ldapsh Log Message: * Where DN splitting occurs, always use _splitdn * Fix: _splitdn no longer splits in the middle of RDNs that contain \, * Feature: rename, cp and acd now accept a shell-like DN syntax (e.g. ../../ou=Blah). See "Interpretation of Target DNs". Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** ldapsh 24 Feb 2004 05:44:02 -0000 1.50 --- ldapsh 25 Feb 2004 02:03:20 -0000 1.51 *************** *** 184,187 **** --- 184,208 ---- =back + =head2 Interpretation of Target DNs + + For some commands (L<rename|rename>, L<cp|cp>, L<acd|acd>), B<ldapsh> + supports an alternative DN syntax that allows you to specify pseudo-DNs using + shell-like notation. If your target DN begins with a dot (.), it will be + interpreted like a commas-separated file path (you may also choose to separate + your dot sequences with slashes, as shown in the example below). Any futher + comma-separated RDNs will be interpreted in 'file path' order, which is the + reverse of DN order. If the I<current working directory> is: + + ou=B, ou=A, o=Parent Organisation + + And you provide one of the following pseudo-DNs: + + "cn=New CN", "../../ou=Other OU,ou=OU Within Other OU" + "cn=New CN", ".., .., ou=Other OU, ou=OU Within Other OU" + + Then the target would be interpreted as: + + ou=OU Within Other OU, ou=Other OU, o=Parent Organisation + =head2 REDIRECTION *************** *** 671,675 **** sub _splitdn($$) { return (undef, undef) unless defined $_[0]; ! split(/\s*,\s*/, shift, shift); } --- 692,720 ---- sub _splitdn($$) { return (undef, undef) unless defined $_[0]; ! split(/\s*(?<!\\),\s*/, shift, shift); ! } ! ! sub _calc_shell_rdn($) { ! # accepts invalid DNs such as ! # ./cn=A,ou=B or .,cn=A,ou=B ! # to mean ou=B,cn=A,$CWD ! # Moreover, .. can be used. ! my ($to) = shift; ! if ($to =~ m{^([.,/]+)(.*)$}) { ! my @dots = split(m{[,/]}, $1); ! my @dn = reverse _splitdn($2, 0); ! my @pwd = _splitdn($CWD, 0); ! while(scalar(@dots)) { ! if (shift(@dots) =~ /^\.\.$/) { ! shift @pwd; ! } ! # silently ignored . and ... ! } ! push @dn, @pwd; ! return join(",", @dn); ! } ! else { ! return $to; ! } } *************** *** 765,769 **** $TermAttribs->{completion_append_character} = ','; ! my @parts1 = split(/\s*,\s*/, $text, -1); my $partToComplete = pop @parts1 || ''; --- 810,815 ---- $TermAttribs->{completion_append_character} = ','; ! #my @parts1 = split(/\s*,\s*/, $text, -1); ! my @parts1 = _splitdn($text, -1); my $partToComplete = pop @parts1 || ''; *************** *** 1466,1470 **** $SubPath =~ s/\s*,\s*$//; ! $SubPath = join(',', reverse(split(/\s*,\s*/, $SubPath))); # Now the $SubPath variable contains a SubDN where we wanna go, in --- 1512,1517 ---- $SubPath =~ s/\s*,\s*$//; ! #$SubPath = join(',', reverse(split(/\s*,\s*/, $SubPath))); ! $SubPath = join(',', reverse(_splitdn($SubPath, 0))); # Now the $SubPath variable contains a SubDN where we wanna go, in *************** *** 1492,1496 **** B<Synopsis>: C<setdn 'E<lt>DNE<gt>'> ! Change the current directory to the specified DN. Unlike the L<cd|cd> command, the argument is a B<DN>, not an B<RDN>. This command has a synonym named L<acd|acd>. =cut --- 1539,1544 ---- B<Synopsis>: C<setdn 'E<lt>DNE<gt>'> ! Change the current directory to the specified DN. Unlike the L<cd|cd> command, the argument is a B<DN>, not an B<RDN>. ! See also L<acd|acd>. =cut *************** *** 1533,1546 **** B<Synopsis>: C<acd 'E<lt>DNE<gt>'> ! A synonym for L<setdn|setdn>. (The name is an abbreviaton of "B<a>bsolute B<cd>".) =cut sub acd { ! setdn(@_); } - - =head3 pushd --- 1581,1597 ---- B<Synopsis>: C<acd 'E<lt>DNE<gt>'> ! Similar to L<setdn|setdn>. (The name is an abbreviaton of "B<a>bsolute B<cd>".) ! ! You may specify a valid DN, or use alternative syntax that allows you to ! specify pseudo-DNs with shell-like notation (see L<Target DNs|"Interpretation ! of Target DNs">). =cut sub acd { ! my $to = _calc_shell_rdn( join(",", @_) ); ! setdn($to); } =head3 pushd *************** *** 2372,2378 **** the filter C<(objectclass=*)>. ! If the C<to> parameter is an RDN, a single object will be copied to a new RDN within ! the same level of the LDAP tree, and you will get an error if C<from-expansion> ! expands to more than one object. If C<to> is a DN, all the objects from C<from-expansion> will be be copied to --- 2423,2431 ---- the filter C<(objectclass=*)>. ! If the C<to> parameter is an RDN, a single object will be copied to a new RDN ! within the same level of the LDAP tree, and you will get an error if ! C<from-expansion> expands to more than one object. B<ldapsh> also supports an ! alternative DN syntax that allows you to specify C<to> with shell-like notation ! (see L<Target DNs|"Interpretation of Target DNs">). If C<to> is a DN, all the objects from C<from-expansion> will be be copied to *************** *** 2388,2391 **** --- 2441,2445 ---- my ($from, $to) = @_; $from = "objectclass=*" if ($from eq "*"); + $to = _calc_shell_rdn( $to ); my $localcopy = (scalar(_splitdn($to,2)) == 1); #I.e $to is an RDN. my $entries = _entriesExpander undef, $from; *************** *** 2443,2446 **** --- 2497,2504 ---- rename "cn=New CN", "ou=New OU, $CWD" + For C<to>, B<ldapsh> also supports an alternative DN syntax that allows you to + specify DNs with shell-like notation (see L<Target DNs|"Interpretation of + Target DNs">). + If your directory server does not allow subtrees to be moved, you may have to copy entries to a new location and then remove the old subtree (see L<cp|cp> *************** *** 2453,2456 **** --- 2511,2515 ---- $from = "objectclass=*" if ($from eq "*"); my $entries = _entriesExpander undef, $from; + $to = _calc_shell_rdn( $to ); if (scalar(@$entries) > 1) { foreach my $entry (@$entries) { *************** *** 3017,3021 **** Will save the entries found during the last search, so you can use this later. You only have one global variable for your own use, so if you need more than one, set this variable to a hash: ! B<Example>: C<$G = {ENTRIES => $ENTRIES, PWD => $PWD}; $G->{TIME} = time();> =head2 $LASTFILE --- 3076,3080 ---- Will save the entries found during the last search, so you can use this later. You only have one global variable for your own use, so if you need more than one, set this variable to a hash: ! B<Example>: C<$G = {ENTRIES => $ENTRIES, CWD => $CWD}; $G->{TIME} = time();> =head2 $LASTFILE |