ldapsh-cvs Mailing List for LDAP shell (Page 2)
Status: Beta
Brought to you by:
rcorvalan
You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(7) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(5) |
Jun
|
Jul
(12) |
Aug
(3) |
Sep
(11) |
Oct
|
Nov
(4) |
Dec
(10) |
2004 |
Jan
(2) |
Feb
(8) |
Mar
(4) |
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2007 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <j-d...@us...> - 2003-12-11 12:41:11
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv23154 Modified Files: ldapsh Log Message: * Added the "-" and two-argument syntaxes for "cd" (like real shells). Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** ldapsh 6 Nov 2003 04:14:20 -0000 1.31 --- ldapsh 11 Dec 2003 12:41:07 -0000 1.32 *************** *** 243,246 **** --- 243,247 ---- my $Globals = { CWD => {VALUE => '', RIGHTS => 'RWL'}, + OLDWD => {VALUE => '', RIGHTS => 'RWL'}, CONNPARAMS => {VALUE => { *************** *** 282,286 **** }; ! my ($CWD, $PROMPT, $CONNPARAMS, $LDAPCONN, $ENTRIES, $EDITOR, $COLUMNS, $DNSEP, $G); my ($PERL_RL); # read-only values my ($Term, $TermAttribs); --- 283,287 ---- }; ! my ($CWD, $OLDWD, $PROMPT, $CONNPARAMS, $LDAPCONN, $ENTRIES, $EDITOR, $COLUMNS, $DNSEP, $G); my ($PERL_RL); # read-only values my ($Term, $TermAttribs); *************** *** 1282,1290 **** =head3 cd ! B<Synopsis>: C<cd ['E<lt>RDNE<gt>']> ! Change the I<current working directory> to the specified RDN. You can specify multiple RDNs separated by commas (in the reverse order of the DN, to allow completion). You can also specify ".." to go to the parent DN. If no RDN is specified, the I<current working directory> is not changed. See also the L<acd|acd>, L<setdn|setdn>, L<pushd|pushd> and L<popd|popd> commands. --- 1283,1300 ---- =head3 cd ! B<Synopsis>: C<cd ['E<lt>RDNE<gt>' | 'E<lt>fooE<gt>', 'E<lt>barE<gt>' | '-']> ! Change the I<current working directory> to the specified RDN. ! You can specify multiple RDNs separated by commas (in the reverse order of the DN, to allow completion). ! You can also specify C<..> to go to the parent DN. If no RDN is specified, the I<current working directory> is not changed. + If C<-> is specified, L<$OLDWD|$OLDWD> is swapped with the I<current working directory>. + + If C<foo> and C<bar> are specified, C<bar> will be substituted for C<foo> + in the I<current working directory> and the result will be used to + invoke L<setdn|setdn>. If C<foo> was not present in L<$CWD|$CWD>, + the I<current working directory> is not changed. + See also the L<acd|acd>, L<setdn|setdn>, L<pushd|pushd> and L<popd|popd> commands. *************** *** 1294,1299 **** --- 1304,1336 ---- _bindneeded() or return 0; + if (scalar @_ > 1) { + if (scalar @_ != 2) { + print STDERR "You may not specify more than two RDNs.\n"; + return 0; + } + my $pre = shift; + my $post = shift; + # if you know a better way of doing this, let us know! + my $i = index($Globals->{CWD}{VALUE}, $pre); + if ($i < 0) { + print STDERR "Substitution failed.\n"; + return 0; + } + my $NewPATH = substr($Globals->{CWD}{VALUE}, $i + length($pre)); + if (!defined($NewPATH)) { + print STDERR "Substitution failed.\n"; + return 0; + } + $NewPATH = substr($Globals->{CWD}{VALUE}, 0, $i).$post.$NewPATH; + return setdn($NewPATH); + } + my $SubPath = shift(); $SubPath = "" unless defined($SubPath); + + if ($SubPath eq "-") { + return setdn($Globals->{OLDWD}{VALUE}); + } + $SubPath =~ s/\s*,\s*$//; $SubPath = join(',', reverse(split(/\s*,\s*/, $SubPath))); *************** *** 1329,1332 **** --- 1366,1370 ---- sub setdn { my $NewPATH = shift; + my $OldPATH = $Globals->{CWD}{VALUE}; my $result = _searchWEC( *************** *** 1350,1353 **** --- 1388,1392 ---- if (scalar(@entries) == 1) { $Globals->{CWD}{VALUE} = $NewPATH; + $Globals->{OLDWD}{VALUE} = $OldPATH; return 1; } else { *************** *** 1374,1378 **** =head3 pushd ! B<Synopsis>: C<pushd ['E<lt>RDNE<gt>']> Perform the same action as the L<cd|cd> command. If the action succeeds, the old working directory is stored on a stack (which can be shown using L<dirs|dirs>). It can be restored using L<popd|popd>. --- 1413,1417 ---- =head3 pushd ! B<Synopsis>: C<pushd ['E<lt>RDNE<gt>' | 'E<lt>fooE<gt>', 'E<lt>barE<gt>' | '-']> Perform the same action as the L<cd|cd> command. If the action succeeds, the old working directory is stored on a stack (which can be shown using L<dirs|dirs>). It can be restored using L<popd|popd>. *************** *** 2438,2441 **** --- 2477,2484 ---- Contains the B<Net::LDAP> handler. Use it only if you know what you are doing... + + =head2 $OLDWD + + The immediate past I<current working directory>, updated by the L<cd|cd> and L<setdn|setdn> commands. =head2 $PROMPT |
From: <j-d...@us...> - 2003-11-06 04:14:23
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv16782 Modified Files: ldapsh Log Message: Call Net::LDAP::Constant::* as subroutines (for v0.29 compatibility). Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** ldapsh 6 Nov 2003 03:46:52 -0000 1.30 --- ldapsh 6 Nov 2003 04:14:20 -0000 1.31 *************** *** 397,401 **** sub _isReallyLDAPError ($) { my $code = shift; ! return 1 if $code and $code != Net::LDAP::Constant::LDAP_PARTIAL_RESULTS and $code != Net::LDAP::Constant::LDAP_REFERRAL; return 0; } --- 397,401 ---- sub _isReallyLDAPError ($) { my $code = shift; ! return 1 if $code and $code != Net::LDAP::Constant::LDAP_PARTIAL_RESULTS() and $code != Net::LDAP::Constant::LDAP_REFERRAL(); return 0; } *************** *** 790,794 **** if (_isReallyLDAPError($result->code)) { ! if ($result->code == Net::LDAP::Constant::LDAP_NO_SUCH_OBJECT) { return undef; } else { --- 790,794 ---- if (_isReallyLDAPError($result->code)) { ! if ($result->code == Net::LDAP::Constant::LDAP_NO_SUCH_OBJECT()) { return undef; } else { *************** *** 836,840 **** if (_isReallyLDAPError($result->code)) { ! if ($result->code == Net::LDAP::Constant::LDAP_NO_SUCH_OBJECT) { return undef; } --- 836,840 ---- if (_isReallyLDAPError($result->code)) { ! if ($result->code == Net::LDAP::Constant::LDAP_NO_SUCH_OBJECT()) { return undef; } *************** *** 1339,1343 **** if (_isReallyLDAPError($result->code)) { ! if ($result->code == Net::LDAP::Constant::LDAP_NO_SUCH_OBJECT) { print STDERR "Cannot change BaseDN. No such subpath.\n"; return 0; --- 1339,1343 ---- if (_isReallyLDAPError($result->code)) { ! if ($result->code == Net::LDAP::Constant::LDAP_NO_SUCH_OBJECT()) { print STDERR "Cannot change BaseDN. No such subpath.\n"; return 0; *************** *** 2155,2159 **** $result = $_->update($Globals->{LDAPCONN}{VALUE}); if ($result->is_error) { ! unless ($result->code == Net::LDAP::Constant::LDAP_LOCAL_ERROR and $result->error eq 'No attributes to update') { printf STDERR qq{LDAP Error updating entry '%s'. Code:%s. Message:%s\n}, --- 2155,2159 ---- $result = $_->update($Globals->{LDAPCONN}{VALUE}); if ($result->is_error) { ! unless ($result->code == Net::LDAP::Constant::LDAP_LOCAL_ERROR() and $result->error eq 'No attributes to update') { printf STDERR qq{LDAP Error updating entry '%s'. Code:%s. Message:%s\n}, |
From: <j-d...@us...> - 2003-11-06 03:46:55
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv13311 Modified Files: ldapsh Log Message: The 'set' command can now display read-only variables (upon request). Add PERL_RL as a user-readable variable (read-only). Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** ldapsh 6 Nov 2003 03:36:02 -0000 1.29 --- ldapsh 6 Nov 2003 03:46:52 -0000 1.30 *************** *** 283,286 **** --- 283,287 ---- my ($CWD, $PROMPT, $CONNPARAMS, $LDAPCONN, $ENTRIES, $EDITOR, $COLUMNS, $DNSEP, $G); + my ($PERL_RL); # read-only values my ($Term, $TermAttribs); *************** *** 312,315 **** --- 313,321 ---- sub _InitReadLine { $Term = new Term::ReadLine('LDAPShell', \*STDIN, \*STDERR); + + $Globals->{PERL_RL} = { VALUE => $Term->ReadLine, RIGHTS => 'RL' }; + $Globals->{PERL_RL}{VALUE} =~ s/^Term::ReadLine:://; + eval(sprintf(q{tie ${%s}, 'Tie::Scalar::Hash', $Globals, '%s'}, 'PERL_RL', 'PERL_RL')) || warn $@; + _ReadHistory(); $TermAttribs = $Term->Attribs; *************** *** 965,978 **** =head3 set ! Display the names and values of the global variables you can set. The purpose of this function is to help the user to remember the names of the variables he can set. =cut ! sub set() { my $oldterse = $Data::Dumper::Terse; $Data::Dumper::Terse = 1; foreach (keys %$Globals) { next if /^_/ or not $Globals->{$_}{RIGHTS} =~ /l/i; ! printf {$Output->{FILEHANDLE}} "\$%s = %s\n", $_, Dumper($Globals->{$_}{VALUE}); } $Data::Dumper::Terse = $oldterse; --- 971,991 ---- =head3 set ! B<Synopsis>: C<set ['-a']> ! ! Display the names and values of the global variables you can set. The purpose of this function is to help the user to remember the names of the variables he can set. The C<-a> parameter allows read-only values to be seen. =cut ! sub set { ! my $showall = (scalar(@_) and shift =~ /-a/); ! my $canwrite; my $oldterse = $Data::Dumper::Terse; $Data::Dumper::Terse = 1; foreach (keys %$Globals) { next if /^_/ or not $Globals->{$_}{RIGHTS} =~ /l/i; ! $canwrite = $Globals->{$_}{RIGHTS} =~ /w/i; ! next if not $canwrite and not $showall; ! # Read-only values are displayed with == instead of = ! printf {$Output->{FILEHANDLE}} "\$%s =%s %s\n", $_, $canwrite ? '' : '=', Dumper($Globals->{$_}{VALUE}); } $Data::Dumper::Terse = $oldterse; |
From: <j-d...@us...> - 2003-11-06 03:36:07
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv11989 Modified Files: ldapsh Log Message: PATCH-812862 (multi-column format for ls). Documentation for variables is now in alphabetical order. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** ldapsh 6 Nov 2003 03:20:29 -0000 1.28 --- ldapsh 6 Nov 2003 03:36:02 -0000 1.29 *************** *** 253,257 **** --- 253,263 ---- }, LDAPCONN => {VALUE => undef, RIGHTS => 'RW'}, + DNSEP => {VALUE => "; ", RIGHTS => 'RWL'}, ENTRIES => {VALUE => [], RIGHTS => 'RW'}, + COLUMNS => {VALUE => + ( $ENV{COLUMNS} && $ENV{COLUMNS} =~ /^[+]?\d+$/ ) ? + $ENV{COLUMNS} : ( eval "require Term::Size; Term::Size::chars();" || 80 ), + RIGHTS => 'RWL' + }, PROMPT => {VALUE => '${APP}\[LDAP @ $CONNPARAMS->{SERVER}] $CWD > ', RIGHTS => 'RWL'}, EDITOR => {VALUE => $ENV{VISUAL} ? $ENV{VISUAL} : ($ENV{EDITOR} ? $ENV{EDITOR} : 'vi'), RIGHTS => 'RWL'}, *************** *** 276,280 **** }; ! my ($CWD, $PROMPT, $CONNPARAMS, $LDAPCONN, $ENTRIES, $EDITOR, $G); my ($Term, $TermAttribs); --- 282,286 ---- }; ! my ($CWD, $PROMPT, $CONNPARAMS, $LDAPCONN, $ENTRIES, $EDITOR, $COLUMNS, $DNSEP, $G); my ($Term, $TermAttribs); *************** *** 1682,1698 **** =head3 ls ! B<Synopsis>: C<ls ['-l',] E<lt>expansionE<gt>> ! List the DNs of the entries matched by the expansion (see L<Expansion|expansion>). The C<-r> parameter automatically sets the C<-l> parameter. =cut sub ls { ! my $localArgs = {}; ! my $entries = _entriesExpander [$localArgs, 'l'], @_; return 0 unless defined $entries; ! foreach my $entry (@$entries) { ! printf {$Output->{FILEHANDLE}} ("%s\n", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); } print STDERR "-----\n" . scalar(@$entries) . " entries found.\n"; --- 1688,1754 ---- =head3 ls ! B<Synopsis>: C<ls ['-C',|'-m',] ['-l',] E<lt>expansionE<gt>> ! List the DNs of the entries matched by the expansion (see L<Expansion|expansion>). ! Entries are displayed in the order received (no sorting is performed), ! with one entry per line. ! ! The C<-C> argument requests multi-column output (the default is to print only one column per line). ! B<ldapsh> uses as many columns as will fit into the character width of the terminal (see L<$COLUMNS|"$COLUMNS">). ! If C<-m> is also specified, columns will be separated by L<$DNSEP|"$DNSEP"> (the default string is "; "). ! The separator is omitted from the last entry on each line. ! ! The C<-m> argument requests that all entries be printed on a single line, ! with entries separated by the L<$DNSEP|"$DNSEP"> string (the default string is "; "). ! The separator appears after every entry (including the last one). =cut sub ls { ! my $localArgs = {C => 0, m => 0}; ! my $entries = _entriesExpander [$localArgs, 'C', 'm', 'l'], @_; return 0 unless defined $entries; ! if ($localArgs->{'C'} && $Globals->{COLUMNS}{VALUE} > 0) { ! # determine the width of the longest entry ! my $i; ! my $num; ! my $width = 0; ! my @display = (); ! my $sep = $localArgs->{'m'} ? $Globals->{DNSEP}{VALUE} : " "; ! my $auxwidth = length($sep); ! foreach my $entry (@$entries) { ! unshift @display, $localArgs->{'l'} ? $entry->dn : rdn($entry->dn); ! $num = length($display[0]); ! if ($num > $width) { ! $width = $num; ! } ! } ! # $width is max width of any entry. ! # $num becomes the number of entries per line. ! $num = int(($Globals->{COLUMNS}{VALUE}+$auxwidth)/($width+$auxwidth)); ! ! $auxwidth += $width; ! for ($i = 0; @display; $i++) { ! if (@display == 1 || ($i+1) % $num == 0) { ! printf {$Output->{FILEHANDLE}} ("%-${width}s\n", shift @display); ! } ! else { ! printf {$Output->{FILEHANDLE}} ("%-${auxwidth}s", (shift @display).$sep); ! } ! } ! } ! elsif ($localArgs->{'m'}) { ! foreach my $entry (@$entries) { ! printf {$Output->{FILEHANDLE}} ("%s$Globals->{DNSEP}{VALUE}", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); ! } ! if (@$entries) { ! printf "\n"; ! } ! } ! else { ! foreach my $entry (@$entries) { ! printf {$Output->{FILEHANDLE}} ("%s\n", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); ! } } print STDERR "-----\n" . scalar(@$entries) . " entries found.\n"; *************** *** 2290,2296 **** =item * F</etc/ldapshrc> ! Same as F<~/.ldaprc>, only system-wide. ! =item * F<~/.ldapsh_history> For internal use. The shell saves the history in this file (provided you have --- 2346,2352 ---- =item * F</etc/ldapshrc> ! Same as F<$HOME/.ldaprc>, only system-wide. ! =item * F<$HOME/.ldapsh_history> For internal use. The shell saves the history in this file (provided you have *************** *** 2302,2305 **** --- 2358,2367 ---- =head1 VARIABLES + =head2 $COLUMNS + + The width of the output device in characters (decimal string). + Its initial value is obtained from the environment or the B<Term::Size> module, + with a default of 80 characters. + =head2 $CONNPARAMS-E<gt>{SERVER} *************** *** 2334,2353 **** using this variable). ! =head2 $LDAPCONN ! ! Contains the B<Net::LDAP> handler. Use it only if you know what you are doing... ! ! =head2 $ENTRIES ! ! The buffer of entries (B<Net::LDAP::Entry>). It's an array ref. Contains the last entries got with the ! commands L<ls|ls>, L<cat|cat>, L<search|search>... ! ! =head2 $PROMPT ! ! The prompt template. It will be "eval"ed so will do variable substitution. ! You can use the ${APP} variable to display "**" when you are in "append mode" ! (see L<append|append> and L<noappend|noappend>). ! Example: $PROMPT = '${APP}\[LDAP @ $CONNPARAMS-E<gt>{SERVER}] $CWD E<gt> ' =head2 $EDITOR --- 2396,2402 ---- using this variable). ! =head2 $DNSEP ! String used to separate DNs on a line (see L<ls|ls>). =head2 $EDITOR *************** *** 2356,2359 **** --- 2405,2413 ---- from the environment variable $VISUAL (if set) or $EDITOR (if set) or otherwise "vi". + =head2 $ENTRIES + + The buffer of entries (B<Net::LDAP::Entry>). It's an array ref. Contains the last entries got with the + commands L<ls|ls>, L<cat|cat>, L<search|search>... + =head2 $G *************** *** 2367,2370 **** --- 2421,2436 ---- B<Example>: C<$G = {ENTRIES => $ENTRIES, PWD => $PWD}; $G->{TIME} = time();> + + =head2 $LDAPCONN + + Contains the B<Net::LDAP> handler. Use it only if you know what you are doing... + + =head2 $PROMPT + + The prompt template. It will be "eval"ed so will do variable substitution. + You can use the ${APP} variable to display "**" when you are in "append mode" + (see L<append|append> and L<noappend|noappend>). + + Example: $PROMPT = '${APP}\[LDAP @ $CONNPARAMS-E<gt>{SERVER}] $CWD E<gt> ' =head1 SEE ALSO |
From: <j-d...@us...> - 2003-11-06 03:20:34
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv9585 Modified Files: ldapsh Log Message: Spelling corrections. Added 'sink' as a synonym for 'redir'. Added 'nosink' as a synonym for 'noredir'. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** ldapsh 27 Sep 2003 09:01:04 -0000 1.27 --- ldapsh 6 Nov 2003 03:20:29 -0000 1.28 *************** *** 1179,1183 **** =head3 loadrc ! B<Synopsys>: C<loadrc [E<lt>fileE<gt>]> Load and "run" the Perl file E<lt>fileE<gt> using the C<do> Perl function. If no filename is given, B<ldapsh> tries to load C<~/.ldapshrc>. --- 1179,1183 ---- =head3 loadrc ! B<Synopsis>: C<loadrc [E<lt>fileE<gt>]> Load and "run" the Perl file E<lt>fileE<gt> using the C<do> Perl function. If no filename is given, B<ldapsh> tries to load C<~/.ldapshrc>. *************** *** 1201,1205 **** =head3 source ! B<Synopsys>: C<source E<lt>fileE<gt>> A synonym for C<loadrc E<lt>fileE<gt>>. --- 1201,1205 ---- =head3 source ! B<Synopsis>: C<source E<lt>fileE<gt>> A synonym for C<loadrc E<lt>fileE<gt>>. *************** *** 1746,1749 **** --- 1746,1762 ---- + =head3 sink + + B<Synopsis>: C<sink ['E<lt>specE<gt>']> + + A synonym for C<redir ['E<lt>specE<gt>']>. + + =cut + + sub sink($) { + redir(shift); + } + + =head3 noredir *************** *** 1762,1765 **** --- 1775,1791 ---- return $previous; } + + =head3 nosink + + B<Synopsis>: C<nosink> + + A synonym for C<noredir]>. + + =cut + + sub nosink { + noredir; + } + =head2 Changing entries |
From: <j-d...@us...> - 2003-09-27 09:01:18
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv23203 Modified Files: ldapsh Log Message: Modified the HTML example for better compatibility with both Perl 5.8.0 and 5.6.1 Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** ldapsh 26 Sep 2003 03:29:58 -0000 1.26 --- ldapsh 27 Sep 2003 09:01:04 -0000 1.27 *************** *** 31,34 **** --- 31,35 ---- <pre> + bash-prompt> ldapsh> [LDAP @ ] > ads *************** *** 68,71 **** --- 69,73 ---- [LDAP @ adsserver] ou=Users,ou=Switzerland,dc=linkvest,dc=com > quit bash-prompt> + </pre> |
From: <j-d...@us...> - 2003-09-27 03:37:07
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv12032 Modified Files: Tag: PATCH-813390 ldapsh Log Message: Change some 'my' to 'our' so that $ENTRIES is available to Psh Perl evaluation. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.26.4.1 retrieving revision 1.26.4.2 diff -C2 -d -r1.26.4.1 -r1.26.4.2 *** ldapsh 27 Sep 2003 03:23:08 -0000 1.26.4.1 --- ldapsh 27 Sep 2003 03:36:51 -0000 1.26.4.2 *************** *** 282,286 **** } ! my $RELEASE = '0.9.3-2'; my $Opts = { --- 282,286 ---- } ! our $RELEASE = '0.9.3-2'; my $Opts = { *************** *** 327,331 **** }; ! my ($CONNPARAMS, $CWD, $LDAPCONN, $ENTRIES, $PROMPT, $G, $EDITOR, $LDAPSH_PARSER); my ($Term, $TermAttribs); --- 327,331 ---- }; ! our ($CONNPARAMS, $CWD, $LDAPCONN, $ENTRIES, $PROMPT, $G, $EDITOR, $LDAPSH_PARSER); my ($Term, $TermAttribs); |
From: <j-d...@us...> - 2003-09-27 03:23:23
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv9958 Modified Files: Tag: PATCH-813390 ldapsh Log Message: Replaced Perl -w option with $^W=1 to suppress warnings when Psh is in use. Added dynamic check for availability of Psh module. Added 'history' command to view Term::ReadLine::Gnu command history. Added warnings/errors when 'redir' command fails. Added variables $PSH_SUPPORT and $LDAPSH_PARSER to indicate whether Psh is in use. Documented Psh command-line syntax (dual documentation of ldapsh and Psh syntaxes). Provide Psh::Strategy::Ldapsh::Perlfunc and Psh::Strategy hooks. Modify main loop to use Psh, when it is available. Regex patch for ldapsh built-in pipe syntax. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.26 retrieving revision 1.26.4.1 diff -C2 -d -r1.26 -r1.26.4.1 *** ldapsh 26 Sep 2003 03:29:58 -0000 1.26 --- ldapsh 27 Sep 2003 03:23:08 -0000 1.26.4.1 *************** *** 1,3 **** ! #!/usr/bin/perl -w # vim:ts=4:sw=4:noet:ai: --- 1,3 ---- ! #!/usr/bin/perl # vim:ts=4:sw=4:noet:ai: *************** *** 86,90 **** of Perl functions and all you do is to call functions from a prompt. ! In fact, whatever you type at the prompt will either be: =over 8 --- 86,105 ---- of Perl functions and all you do is to call functions from a prompt. ! You can request help typing L<help [E<lt>commandE<gt>]|help> or, if you use ! B<Term::ReadLine::Gnu>, you can type C<E<lt>CTRL-tE<gt>> after a command ! to get help on it. ! ! B<ldapsh> includes a simple command-line interpreter. It can also make use of ! the optional B<Psh> module for an enhanced user experience. This manual ! describes both interpreters as indicated by [ldapsh] and [Psh], respectively. Both ! interpreters facilitate evaluation of Perl expressions and you may use the ! L<$G|"$G"> variable to store your own data. ! ! In this manual, command options are shown as C<'-l',> to be compatible with the ! Perl C<eval()> function. However, you do not usually need to type the ! apostrophes because B<ldapsh> will insert them automatically. If you have ! B<Psh> installed, you do not need to use commas, either. ! ! [ldapsh] Whatever you type at the prompt will either be: =over 8 *************** *** 94,109 **** =item * Evaluated as a Perl expression (using C<eval()>). For convenience, a few commands (such as L<cd|cd>, L<lcd|lcd> and L<help|help>) automatically quote their arguments. Thus, you can type C<cd ou=Users> instead of C<cd "ou=Users">. - You may use the L<$G|"$G"> variable to store values such as your results. ! =back ! You can request help typing L<help [E<lt>commandE<gt>]|help> or, if you use ! B<Term::ReadLine::Gnu>, you can type C<E<lt>CTRL-tE<gt>> after a command ! to get help on it. ! =head2 Expansion Almost every function that uses LDAP entries (L<ls|ls>, L<cat|cat>, --- 109,149 ---- =item * Evaluated as a Perl expression (using C<eval()>). + =back + For convenience, a few commands (such as L<cd|cd>, L<lcd|lcd> and L<help|help>) automatically quote their arguments. Thus, you can type C<cd ou=Users> instead of C<cd "ou=Users">. ! [Psh] What you type at the prompt will be passed through a number of handlers ! that facilitate a rich shell-like syntax. The order of precedence is: ! exclamation mark, brace, B<ldapsh> commands, Perl functions, shell executables, ! Perl evaluation. Please note the following examples for correct quoting of ! strings, arrays, and hashes: ! =over 8 ! =item * Correct (expands L<$CWD|"$CWD">): echo $CWD ! ! =item * Correct (expands L<$CWD|"$CWD">): echo "$CWD" ! ! =item * Prints C<$CWD> literally: echo '$CWD' ! ! =item * Correct (expands L<$ENTRIES|"$ENTRIES">): nbentries $ENTRIES ! ! =item * Incorrect (converts array reference to a string): nbentries "$ENTRIES" ! ! =item * Incorrect (does not expand the variable): nbentries '$ENTRIES' ! ! =item * Expands $ENV{PATH}: echo "$ENV{PATH}" ! ! =item * Expands $ENV{PATH}: echo $ENV\{PATH\} ! ! =item * $ENV expanded on its own: echo $ENV{PATH} ! ! =item * Prints C<$ENV{PATH}> literally: echo '$ENV{PATH}' ! ! =back ! ! =head2 Expansion of LDAP DNs and Filters Almost every function that uses LDAP entries (L<ls|ls>, L<cat|cat>, *************** *** 111,117 **** identified in the documentation with a usage like: C<ls E<lt>expansionE<gt>> - I tried -- even if it's by far incomplete -- to simulate the mechanism of the - shell parser and its variable substitution, wildcard expansion, etc. - The three syntaxes are: --- 151,154 ---- *************** *** 124,128 **** is the I<current working directory>. ! The results of the search are put in the L<$ENTRIES|"$ENTRIES"> array ref (composed of B<Net::LDAP::Entry> entries). --- 161,165 ---- is the I<current working directory>. ! The results of the search are put in the L<$ENTRIES|"$ENTRIES"> array reference (composed of B<Net::LDAP::Entry> entries). *************** *** 149,155 **** You may redirect search results using the L<redir|redir> command. This will ! stay in effect until L<noredir> is called. ! Alternatively, you can use a special shell syntax which will have only a temporary effect. The special syntax is appending "; | ..." to your command, where "..." is a parameter to the C<open> function. --- 186,195 ---- You may redirect search results using the L<redir|redir> command. This will ! stay in effect until L<noredir|noredir> is called. ! [Psh] Psh allows you to use standard shell symbols such as "|" (for piping) ! and ">" (for output redirection). ! ! [ldapsh] Alternatively, you can use a special shell syntax which will have only a temporary effect. The special syntax is appending "; | ..." to your command, where "..." is a parameter to the C<open> function. *************** *** 204,211 **** --- 244,255 ---- =item * B<POSIX::Termios> + =item * B<Psh> + =item * B<Term::ReadKey> =item * B<Term::ReadLine::Gnu> + =item * B<Term::Size> + =back *************** *** 220,223 **** --- 264,269 ---- use subs qw(connect bind delete dump exit reset); + my $PSH_SUPPORT; + BEGIN { require Net::LDAP; *************** *** 228,231 **** --- 274,283 ---- Getopt::Long::Configure ('bundling_override'); + + $PSH_SUPPORT = eval "require Psh"; + if (!$PSH_SUPPORT) { + #use warnings; + $^W = 1; + } } *************** *** 255,258 **** --- 307,311 ---- EDITOR => {VALUE => $ENV{VISUAL} ? $ENV{VISUAL} : ($ENV{EDITOR} ? $ENV{EDITOR} : 'vi'), RIGHTS => 'RWL'}, G => {VALUE => undef, RIGHTS => 'RWL'}, + LDAPSH_PARSER => {VALUE => $PSH_SUPPORT ? "Psh" : "ldapsh", RIGHTS => 'R'}, _APPENDRESULTS => {VALUE => 0, RIGHTS => ''}, _DIRSSTACK => {VALUE => [], RIGHTS => ''}, *************** *** 274,278 **** }; ! my ($CWD, $PROMPT, $CONNPARAMS, $LDAPCONN, $ENTRIES, $EDITOR, $G); my ($Term, $TermAttribs); --- 327,331 ---- }; ! my ($CONNPARAMS, $CWD, $LDAPCONN, $ENTRIES, $PROMPT, $G, $EDITOR, $LDAPSH_PARSER); my ($Term, $TermAttribs); *************** *** 293,296 **** --- 346,356 ---- $SIG{INT} = 'IGNORE'; $SIG{__DIE__} = \&_resetTermReadline; + + if ($PSH_SUPPORT) { + Psh::minimal_initialize(); + Psh::finish_initialize(); + $Psh::eval_preamble = "package ldapsh;"; + $Psh::PerlEval::current_package = "ldapsh"; + } } *************** *** 1229,1232 **** --- 1289,1306 ---- + =head3 history + + B<Synopsis>: C<history> + + Prints out each line of the command-line history, if B<Term::ReadLine::Gnu> is installed. + + =cut + sub history() { + if (_isGnuReadLine) { + print {$Output->{FILEHANDLE}} join("\n", $Term->GetHistory()) . "\n"; + } + } + + =head3 reset *************** *** 1506,1510 **** B<Synopsis>: C<search E<lt>expansionE<gt>> ! Search for the entries matched by the expansion (see L<Expansion|expansion>). Does not dump the entries themselves, only a summary of the search results. --- 1580,1584 ---- B<Synopsis>: C<search E<lt>expansionE<gt>> ! Search for the entries matched by the expansion (see L<Expansion|"Expansion of LDAP DNs and Filters">). Does not dump the entries themselves, only a summary of the search results. *************** *** 1533,1537 **** B<Synopsis>: C<ldif E<lt>expansionE<gt>> ! Display the entries matched by the expansion (see L<Expansion|expansion>) using the LDIF format. See also L<cat|cat>. --- 1607,1611 ---- B<Synopsis>: C<ldif E<lt>expansionE<gt>> ! Display the entries matched by the expansion (see L<Expansion|"Expansion of LDAP DNs and Filters">) using the LDIF format. See also L<cat|cat>. *************** *** 1567,1571 **** B<Synopsis>: C<dump E<lt>expansionE<gt>> ! Dump the entries matched by the expansion (see L<Expansion|expansion>) in a relatively human-readable format. =cut --- 1641,1645 ---- B<Synopsis>: C<dump E<lt>expansionE<gt>> ! Dump the entries matched by the expansion (see L<Expansion|"Expansion of LDAP DNs and Filters">) in a relatively human-readable format. =cut *************** *** 1584,1588 **** B<Synopsis>: C<list ['-a',] ['-dn',] E<lt>expansionE<gt>> ! Display the attribute values of the entries matched by the expansion (see L<Expansion|expansion>) in a list format (easy to parse). Arguments: --- 1658,1662 ---- B<Synopsis>: C<list ['-a',] ['-dn',] E<lt>expansionE<gt>> ! Display the attribute values of the entries matched by the expansion (see L<Expansion|"Expansion of LDAP DNs and Filters">) in a list format (easy to parse). Arguments: *************** *** 1624,1628 **** B<Synopsis>: C<csv [E<lt>optionsE<gt>,] E<lt>expansionE<gt>> ! Display the entries matched by the expansion (see L<Expansion|expansion>) in a CSV format. The first argument can be a list of options to tell how to format the file. If it's given, it's a hash reference. --- 1698,1702 ---- B<Synopsis>: C<csv [E<lt>optionsE<gt>,] E<lt>expansionE<gt>> ! Display the entries matched by the expansion (see L<Expansion|"Expansion of LDAP DNs and Filters">) in a CSV format. The first argument can be a list of options to tell how to format the file. If it's given, it's a hash reference. *************** *** 1682,1686 **** B<Synopsis>: C<ls ['-l',] E<lt>expansionE<gt>> ! List the DNs of the entries matched by the expansion (see L<Expansion|expansion>). The C<-r> parameter automatically sets the C<-l> parameter. =cut --- 1756,1760 ---- B<Synopsis>: C<ls ['-l',] E<lt>expansionE<gt>> ! List the DNs of the entries matched by the expansion (see L<Expansion|"Expansion of LDAP DNs and Filters">). The C<-r> parameter automatically sets the C<-l> parameter. =cut *************** *** 1735,1739 **** }; ! open $new->{FILEHANDLE}, $out || return $previous; $Output = $new; --- 1809,1819 ---- }; ! if (open($new->{FILEHANDLE}, $out)) { ! print STDERR "Warning: redirection destination did not start with | or >\n" unless $out =~ /^[|>]/; ! } ! else { ! print STDERR "Cannot change redirection.\n"; ! return $previous; ! } $Output = $new; *************** *** 1767,1771 **** B<Synopsis>: C<vi E<lt>expansionE<gt>> ! Show the entries matched by the expansion (see L<Expansion|expansion>) in a text editor. Entries are saved to a temporary file for editing in the LDIF format. If the temporary file is modified, it will be re-read as an LDIF file and used to modify --- 1847,1851 ---- B<Synopsis>: C<vi E<lt>expansionE<gt>> ! Show the entries matched by the expansion (see L<Expansion|"Expansion of LDAP DNs and Filters">) in a text editor. Entries are saved to a temporary file for editing in the LDIF format. If the temporary file is modified, it will be re-read as an LDIF file and used to modify *************** *** 1998,2002 **** B<Synopsis>: C<changes [$entries]> ! Show the changes done to the entries given in the C<$entries> array ref (or L<$ENTRIES|"$ENTRIES">, if omitted). You can apply some changes to a set of entries using the L<apply|apply> command, and see the changes using the L<changes|changes> command. =cut --- 2078,2082 ---- B<Synopsis>: C<changes [$entries]> ! Show the changes done to the entries given in the C<$entries> array reference (or L<$ENTRIES|"$ENTRIES">, if omitted). You can apply some changes to a set of entries using the L<apply|apply> command, and see the changes using the L<changes|changes> command. =cut *************** *** 2082,2086 **** C<from-expansion> will be expanded in the usual way ! (see L<Expansion|expansion>), with the addition that C<*> corresponds to the filter C<(objectclass=*)>. --- 2162,2166 ---- C<from-expansion> will be expanded in the usual way ! (see L<Expansion|"Expansion of LDAP DNs and Filters">), with the addition that C<*> corresponds to the filter C<(objectclass=*)>. *************** *** 2312,2316 **** =head2 $ENTRIES ! The buffer of entries (B<Net::LDAP::Entry>). It's an array ref. Contains the last entries got with the commands L<ls|ls>, L<cat|cat>, L<search|search>... --- 2392,2396 ---- =head2 $ENTRIES ! The buffer of entries (B<Net::LDAP::Entry>). It's an array reference. Contains the last entries got with the commands L<ls|ls>, L<cat|cat>, L<search|search>... *************** *** 2425,2434 **** - - package ldapsh; _Init(); $_ = "@ARGV"; --- 2505,2597 ---- package ldapsh; _Init(); + if ($PSH_SUPPORT) { + package Psh::Strategy::Ldapsh::Perlfunc; + + use strict; + use vars qw(@ISA); + + require Psh::Strategy::Perlfunc; + @ISA=('Psh::Strategy::Perlfunc'); + + sub applies { + my @words= @{$_[2]}; + if ((Psh::PerlEval::protected_eval("defined(&{'ldapsh::$words[0]'})"))[0]) { + @{$_[2]}[0] = "ldapsh::@{$_[2]}[0]"; + } + else { + return Psh::Strategy::Perlfunc::applies($_); + } + + } + + sub variable_expansion { + # Adapted from Gregor N. Purdy's Psh::PerlEval.pm + my ($arref) = @_; + my @retval = (); + my $word; + + for $word (@{$arref}) { + if ($word =~ /^\'(.*)\'/) { + push @retval, $1; + } + else { + no strict qw(vars); + local $SIG{__WARN__} = sub {}; + + my $expr = $word; + $expr = "\"$expr\"" unless $expr =~ /^[\$"\']/; + $expr =~ s/\\/\\\\/g; + + my $val = eval("$Psh::eval_preamble $expr"); + if ($@) { + if ($word =~ /^\"(.*)\"/) { + push @retval, $1; + } + else { + push @retval, $word; + } + } + else { + push @retval, $val; + } + } + } + return @retval; + } + + sub execute { + my @words= @{$_[2]}; + if ($words[0] =~ "^ldapsh::") { + # Adapted from Gregor N. Purdy's Psh::Strategy::Built_in.pm + no strict 'refs'; + my $coderef = *{$words[0]}; + shift @words; + # Should we be using protected_eval? + @words = variable_expansion(\@words); + return (1,sub { &{$coderef}(@words); }, [], 0, undef ); + } + else { + return Psh::Strategy::Perlfunc::execute($_); + } + } + + package Psh::Strategy; + + remove("built_in"); + #remove("executable"); + #remove("eval"); + remove("perl"); + remove("perlfunc"); + + my $obj = Psh::Strategy::Ldapsh::Perlfunc->new(); + add $obj; + } + + package ldapsh; + $_ = "@ARGV"; *************** *** 2438,2441 **** --- 2601,2610 ---- while (1) { last unless defined($_); + + if ($PSH_SUPPORT) { + Psh::_evl(eval {Psh::Parser::parse_line($_) }) if $_; + } + else { + s/^\s+//; s/\s+$//; *************** *** 2444,2448 **** next; } - # The line below will quote everything following some commands. # Purpose: type "cd ou=Users" without a Perl Compiler warning --- 2613,2616 ---- *************** *** 2459,2463 **** # If so, we do a temporary output redirection my $previous; ! if (s/;\s*([|>][\s\w\d_\/.-]+)//) { $previous = redir($1); } --- 2627,2631 ---- # If so, we do a temporary output redirection my $previous; ! if (s/;\s*([|>].+)//) { $previous = redir($1); } *************** *** 2468,2471 **** --- 2636,2640 ---- # temporary filehandle $Output = $previous if ($previous); + } |
From: <j-d...@us...> - 2003-09-26 08:01:29
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv9639 Modified Files: Tag: PATCH-812862 ldapsh Log Message: Added a missing pair of parentheses. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.26.2.1 retrieving revision 1.26.2.2 diff -C2 -d -r1.26.2.1 -r1.26.2.2 *** ldapsh 26 Sep 2003 03:43:48 -0000 1.26.2.1 --- ldapsh 26 Sep 2003 08:01:24 -0000 1.26.2.2 *************** *** 257,261 **** COLUMNS => {VALUE => ( $ENV{COLUMNS} && $ENV{COLUMNS} =~ /^[+]?\d+$/ ) ? ! $ENV{COLUMNS} : ( eval "require Term::Size; Term::Size::chars;" || 80 ), RIGHTS => 'RWL' }, --- 257,261 ---- COLUMNS => {VALUE => ( $ENV{COLUMNS} && $ENV{COLUMNS} =~ /^[+]?\d+$/ ) ? ! $ENV{COLUMNS} : ( eval "require Term::Size; Term::Size::chars();" || 80 ), RIGHTS => 'RWL' }, |
From: <rco...@us...> - 2003-09-26 07:44:59
|
Update of /cvsroot/ldapsh/build-rel/template In directory sc8-pr-cvs1:/tmp/cvs-serv6887 Modified Files: ldapsh.css Log Message: Minor font & color changes Added file revision Index: ldapsh.css =================================================================== RCS file: /cvsroot/ldapsh/build-rel/template/ldapsh.css,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ldapsh.css 31 Jul 2002 15:48:19 -0000 1.1 --- ldapsh.css 26 Sep 2003 07:44:54 -0000 1.2 *************** *** 1,4 **** --- 1,6 ---- /* Created using Style Master from Western Civilisation CSS1 { -23 -4 897 722 } */ + /* $Id$ */ + /* standard elements */ *************** *** 17,22 **** --- 19,31 ---- td.block { + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 18px; + font-weight: bold; + color: #7b1a11; + border-top: 1px #d5ccb7 solid; + border-bottom: 1px #d5ccb7 solid; padding-top: .4em; padding-bottom: .4em; + background-color: #f4e7dd; } *************** *** 37,41 **** blockquote { ! color: #000000; font-size: 11px; font-family: Verdana, Arial, Helvetica, sans-serif; --- 46,50 ---- blockquote { ! color: #400000; font-size: 11px; font-family: Verdana, Arial, Helvetica, sans-serif; *************** *** 427,430 **** --- 436,443 ---- } + pre { + color: #400000; + } + td.treeRefMain { background-color: #FFFFFF; *************** *** 636,638 **** font-weight: bold; color: #FFFFFF; ! } \ No newline at end of file --- 649,651 ---- font-weight: bold; color: #FFFFFF; ! } |
From: <j-d...@us...> - 2003-09-26 03:43:52
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv5812 Modified Files: Tag: PATCH-812862 ldapsh Log Message: Provides -C and -m options for ls, removes some ls documentation that was incorrect. Adds $DNSEP and $COLUMNS, puts documentation of variables into alphabetical order. Untested. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.26 retrieving revision 1.26.2.1 diff -C2 -d -r1.26 -r1.26.2.1 *** ldapsh 26 Sep 2003 03:29:58 -0000 1.26 --- ldapsh 26 Sep 2003 03:43:48 -0000 1.26.2.1 *************** *** 253,257 **** --- 253,263 ---- ENTRIES => {VALUE => [], RIGHTS => 'RW'}, PROMPT => {VALUE => '${APP}\[LDAP @ $CONNPARAMS->{SERVER}] $CWD > ', RIGHTS => 'RWL'}, + DNSEP => {VALUE => "; ", RIGHTS => 'RWL'}, EDITOR => {VALUE => $ENV{VISUAL} ? $ENV{VISUAL} : ($ENV{EDITOR} ? $ENV{EDITOR} : 'vi'), RIGHTS => 'RWL'}, + COLUMNS => {VALUE => + ( $ENV{COLUMNS} && $ENV{COLUMNS} =~ /^[+]?\d+$/ ) ? + $ENV{COLUMNS} : ( eval "require Term::Size; Term::Size::chars;" || 80 ), + RIGHTS => 'RWL' + }, G => {VALUE => undef, RIGHTS => 'RWL'}, _APPENDRESULTS => {VALUE => 0, RIGHTS => ''}, *************** *** 274,278 **** }; ! my ($CWD, $PROMPT, $CONNPARAMS, $LDAPCONN, $ENTRIES, $EDITOR, $G); my ($Term, $TermAttribs); --- 280,284 ---- }; ! my ($CWD, $PROMPT, $CONNPARAMS, $LDAPCONN, $ENTRIES, $EDITOR, $COLUMNS, $DNSEP, $G); my ($Term, $TermAttribs); *************** *** 1680,1696 **** =head3 ls ! B<Synopsis>: C<ls ['-l',] E<lt>expansionE<gt>> ! List the DNs of the entries matched by the expansion (see L<Expansion|expansion>). The C<-r> parameter automatically sets the C<-l> parameter. =cut sub ls { ! my $localArgs = {}; ! my $entries = _entriesExpander [$localArgs, 'l'], @_; return 0 unless defined $entries; ! foreach my $entry (@$entries) { ! printf {$Output->{FILEHANDLE}} ("%s\n", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); } print STDERR "-----\n" . scalar(@$entries) . " entries found.\n"; --- 1686,1751 ---- =head3 ls ! B<Synopsis>: C<ls ['-C',|'-m',] ['-l',] E<lt>expansionE<gt>> ! List the DNs of the entries matched by the expansion (see L<Expansion|expansion>). ! Entries are displayed in the order received (no sorting is performed). ! ! The C<-C> argument requests multi-column output (the default is to print only one column per line). ! B<ldapsh> uses as many columns as will fit into the character width of the terminal (see L<$COLUMNS|"$COLUMNS">). ! If C<-m> is also specified, columns will be separated by L<$DNSEP|"$DNSEP"> (the default string is "; "). ! The separator is omitted from the last entry on each line. ! ! The C<-m> argument requests that all entries be printed on a single line, ! with entries separated by the L<$DNSEP|"$DNSEP"> string (the default string is "; "). ! The separator appears after every entry (including the last one). =cut sub ls { ! my $localArgs = {C => 0, m => 0}; ! my $entries = _entriesExpander [$localArgs, 'C', 'm', 'l'], @_; return 0 unless defined $entries; ! if ($localArgs->{'C'} && $Globals->{COLUMNS}{VALUE} > 0 ) { ! # determine the width of the longest entry ! my $i; ! my $num; ! my $width = 0; ! my @display = (); ! my $sep = $localArgs->{'m'} ? $Globals->{DNSEP}{VALUE} : " "; ! my $auxwidth = length($sep); ! foreach my $entry (@$entries) { ! unshift @display, $localArgs->{'l'} ? $entry->dn : rdn($entry->dn); ! $num = length($display[0]); ! if ($num > $width) { ! $width = $num; ! } ! } ! # $width is max width of any entry. ! # $num becomes the number of entries per line. ! $num = int(($Globals->{COLUMNS}{VALUE}+$auxwidth)/($width+$auxwidth)); ! ! $auxwidth += $width; ! for ($i = 0; @display; $i++) { ! if (@display == 1 || ($i+1) % $num == 0) { ! printf {$Output->{FILEHANDLE}} ("%-${width}s\n", shift @display); ! } ! else { ! printf {$Output->{FILEHANDLE}} ("%-${auxwidth}s", (shift @display).$sep); ! } ! } ! } ! elsif ($localArgs->{'m'}) { ! foreach my $entry (@$entries) { ! printf {$Output->{FILEHANDLE}} ("%s$Globals->{DNSEP}{VALUE}", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); ! } ! if (@$entries) { ! printf "\n"; ! } ! } ! else { ! foreach my $entry (@$entries) { ! printf {$Output->{FILEHANDLE}} ("%s\n", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); ! } } print STDERR "-----\n" . scalar(@$entries) . " entries found.\n"; *************** *** 2262,2268 **** =item * F</etc/ldapshrc> ! Same as F<~/.ldaprc>, only system-wide. ! =item * F<~/.ldapsh_history> For internal use. The shell saves the history in this file (provided you have --- 2317,2323 ---- =item * F</etc/ldapshrc> ! Same as F<$HOME/.ldaprc>, only system-wide. ! =item * F<$HOME/.ldapsh_history> For internal use. The shell saves the history in this file (provided you have *************** *** 2274,2277 **** --- 2329,2338 ---- =head1 VARIABLES + =head2 $COLUMNS + + The width of the output device in characters (decimal string). + Its initial value is obtained from the environment or the B<Term::Size> module, + with a default of 80 characters. + =head2 $CONNPARAMS-E<gt>{SERVER} *************** *** 2306,2325 **** using this variable). ! =head2 $LDAPCONN ! ! Contains the B<Net::LDAP> handler. Use it only if you know what you are doing... ! ! =head2 $ENTRIES ! ! The buffer of entries (B<Net::LDAP::Entry>). It's an array ref. Contains the last entries got with the ! commands L<ls|ls>, L<cat|cat>, L<search|search>... ! ! =head2 $PROMPT ! ! The prompt template. It will be "eval"ed so will do variable substitution. ! You can use the ${APP} variable to display "**" when you are in "append mode" ! (see L<append|append> and L<noappend|noappend>). ! Example: $PROMPT = '${APP}\[LDAP @ $CONNPARAMS-E<gt>{SERVER}] $CWD E<gt> ' =head2 $EDITOR --- 2367,2373 ---- using this variable). ! =head2 $DNSEP ! String used to separate DNs on a line (see L<ls|ls>). =head2 $EDITOR *************** *** 2328,2331 **** --- 2376,2384 ---- from the environment variable $VISUAL (if set) or $EDITOR (if set) or otherwise "vi". + =head2 $ENTRIES + + The buffer of entries (B<Net::LDAP::Entry>). It's an array ref. Contains the last entries got with the + commands L<ls|ls>, L<cat|cat>, L<search|search>... + =head2 $G *************** *** 2339,2342 **** --- 2392,2407 ---- B<Example>: C<$G = {ENTRIES => $ENTRIES, PWD => $PWD}; $G->{TIME} = time();> + + =head2 $LDAPCONN + + Contains the B<Net::LDAP> handler. Use it only if you know what you are doing... + + =head2 $PROMPT + + The prompt template. It will be "eval"ed so will do variable substitution. + You can use the ${APP} variable to display "**" when you are in "append mode" + (see L<append|append> and L<noappend|noappend>). + + Example: $PROMPT = '${APP}\[LDAP @ $CONNPARAMS-E<gt>{SERVER}] $CWD E<gt> ' =head1 SEE ALSO |
From: <j-d...@us...> - 2003-09-26 03:30:10
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv3660 Modified Files: ldapsh Log Message: Replaced some instances of STDERR in favour of $Output->{FILEHANDLE} (including 'help all'). Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** ldapsh 19 Sep 2003 13:20:23 -0000 1.25 --- ldapsh 26 Sep 2003 03:29:58 -0000 1.26 *************** *** 889,893 **** } if (defined($cmd) && $cmd eq "all") { ! $parser->parse_from_file($0, \*STDERR); } else { --- 889,893 ---- } if (defined($cmd) && $cmd eq "all") { ! $parser->parse_from_file($0, $Output->{FILEHANDLE}); } else { *************** *** 945,949 **** sub version() { ! printf STDERR <<'EOF' LDAP Shell (ldapsh) by Rafael Corvalan, Peder O. Klingenberg and James Devenish. CVS File ID: %s --- 945,949 ---- sub version() { ! printf {$Output->{FILEHANDLE}} <<'EOF' LDAP Shell (ldapsh) by Rafael Corvalan, Peder O. Klingenberg and James Devenish. CVS File ID: %s *************** *** 966,970 **** foreach (keys %$Globals) { next if /^_/ or not $Globals->{$_}{RIGHTS} =~ /l/i; ! printf STDERR "\$%s = %s\n", $_, Dumper($Globals->{$_}{VALUE}); } $Data::Dumper::Terse = $oldterse; --- 966,970 ---- foreach (keys %$Globals) { next if /^_/ or not $Globals->{$_}{RIGHTS} =~ /l/i; ! printf {$Output->{FILEHANDLE}} "\$%s = %s\n", $_, Dumper($Globals->{$_}{VALUE}); } $Data::Dumper::Terse = $oldterse; *************** *** 1151,1159 **** sub id { if ($Globals->{_EFFECTIVECONNPARAMS}{VALUE}{BINDDN}) { ! printf STDERR (qq{Bound as "%s"\n}, $Globals->{_EFFECTIVECONNPARAMS}{VALUE}{BINDDN}); } elsif (defined($Globals->{_EFFECTIVECONNPARAMS}{VALUE}{BINDDN})) { ! print STDERR "Bound anonymously\n"; } else { ! print STDERR "Not bound\n"; } } --- 1151,1159 ---- sub id { if ($Globals->{_EFFECTIVECONNPARAMS}{VALUE}{BINDDN}) { ! printf {$Output->{FILEHANDLE}} (qq{Bound as "%s"\n}, $Globals->{_EFFECTIVECONNPARAMS}{VALUE}{BINDDN}); } elsif (defined($Globals->{_EFFECTIVECONNPARAMS}{VALUE}{BINDDN})) { ! print {$Output->{FILEHANDLE}} "Bound anonymously\n"; } else { ! print {$Output->{FILEHANDLE}} "Not bound\n"; } } *************** *** 1411,1415 **** sub dirs { ! print STDERR join('', map {"$_\n"} @{$Globals->{_DIRSSTACK}{VALUE}}) . "\n"; } --- 1411,1415 ---- sub dirs { ! print {$Output->{FILEHANDLE}} join('', map {"$_\n"} @{$Globals->{_DIRSSTACK}{VALUE}}) . "\n"; } *************** *** 1422,1426 **** sub pwd { ! print STDERR $Globals->{CWD}{VALUE} . "\n"; } --- 1422,1426 ---- sub pwd { ! print {$Output->{FILEHANDLE}} $Globals->{CWD}{VALUE} . "\n"; } *************** *** 1440,1444 **** return 1; } else { ! printf STDERR "$@\n"; return 0; } --- 1440,1444 ---- return 1; } else { ! printf STDERR "Cannot change directory.\n"; return 0; } *************** *** 2013,2017 **** if (defined($changes) and scalar(@$changes)) { $nbchanges++; ! printf STDERR ('=' x 40 . qq{\n%s\n}, $_->dn); my @changes = (@$changes); while(scalar(@changes)) { --- 2013,2017 ---- if (defined($changes) and scalar(@$changes)) { $nbchanges++; ! printf {$Output->{FILEHANDLE}} ('=' x 40 . qq{\n%s\n}, $_->dn); my @changes = (@$changes); while(scalar(@changes)) { *************** *** 2021,2031 **** if ($action eq 'add') { ! printf STDERR (qq{\t>>> Add attribute '%s' with values: %s\n}, $data->[0], $attributes); } elsif ($action eq 'replace') { ! printf STDERR (qq{\t>>> Replace attribute '%s' with values: %s\n}, $data->[0], $attributes); } elsif ($action eq 'delete') { ! printf STDERR (qq{\t>>> Delete attribute '%s'\n}, $data->[0]); } else { ! printf STDERR (qq{\t>>> Don't know the action '%s'\n}, $action); } } --- 2021,2031 ---- if ($action eq 'add') { ! printf {$Output->{FILEHANDLE}} (qq{\t>>> Add attribute '%s' with values: %s\n}, $data->[0], $attributes); } elsif ($action eq 'replace') { ! printf {$Output->{FILEHANDLE}} (qq{\t>>> Replace attribute '%s' with values: %s\n}, $data->[0], $attributes); } elsif ($action eq 'delete') { ! printf {$Output->{FILEHANDLE}} (qq{\t>>> Delete attribute '%s'\n}, $data->[0]); } else { ! printf {$Output->{FILEHANDLE}} (qq{\t>>> Don't know the action '%s'\n}, $action); } } *************** *** 2157,2161 **** my $nbentries = scalar(@$entries); ! print STDERR "$nbentries\n"; return $nbentries; } --- 2157,2161 ---- my $nbentries = scalar(@$entries); ! print {$Output->{FILEHANDLE}} "$nbentries\n"; return $nbentries; } *************** *** 2456,2460 **** ! # This will chech for "<ldapsh command> ;| <sheel command>" usage # If so, we do a temporary output redirection my $previous; --- 2456,2460 ---- ! # This will check for "<ldapsh command> ;| <shell command>" usage # If so, we do a temporary output redirection my $previous; |
From: <rco...@us...> - 2003-09-19 20:12:32
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv8702 Modified Files: ldapsh Log Message: Merged with branch "PATCH-778409" which added enhanced redir Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** ldapsh 28 Aug 2003 23:52:35 -0000 1.22 --- ldapsh 19 Sep 2003 12:59:30 -0000 1.23 *************** *** 140,143 **** --- 140,172 ---- =back + =head2 REDIRECTION + + By default, LDAP results are displayed on the "standard output" while + diagnostic messages are printed to the "standard error". + + You may redirect search results using the L<redir|redir> command. This will + stay in effect until L<noredir> is called. + + Alternatively, you can use a special shell syntax which will have only a + temporary effect. The special syntax is appending "; | ..." to your command, + where "..." is a parameter to the C<open> function. + + For example: + + ldapsh> redir '|awk "/Smith/{print}"' + ldapsh> cat + cn: Jack Smith + sn: Smith + cn: Jill Smith + sn: Smith + ldapsh> version;|cat + LDAP Shell (ldapsh) by Rafael Corvalan. + ldapsh> cat + cn: Jack Smith + sn: Smith + cn: Jill Smith + sn: Smith + ldapsh> noredir + =head1 PREREQUISITES *************** *** 237,240 **** --- 266,274 ---- }; + my $Output = { + NAME => "STDOUT", + FILEHANDLE => \*STDOUT + }; + my ($CWD, $PROMPT, $CONNPARAMS, $LDAPCONN, $ENTRIES, $EDITOR, $G); my ($Term, $TermAttribs); *************** *** 246,252 **** } - open(STDOUTBCK, '>&STDOUT'); - select(select(STDOUTBCK)); # Avoid -w warning about useless filehandle - if (-r $Opts->{GlobalRCFile}) { loadrc($Opts->{GlobalRCFile}); --- 280,283 ---- *************** *** 419,425 **** my ($key, $value, $showattribnames) = @_; if ($showattribnames) { ! printf("%s:%s\n", $key, $value); } else { ! print("$value\n"); } } --- 450,456 ---- my ($key, $value, $showattribnames) = @_; if ($showattribnames) { ! printf {$Output->{FILEHANDLE}} ("%s:%s\n", $key, $value); } else { ! print {$Output->{FILEHANDLE}} ("$value\n"); } } *************** *** 883,889 **** } if (-s $podfile) { ! print STDERR "------------------------------\n"; ! $parser->parse_from_file($podfile, \*STDERR); ! print STDERR "------------------------------\n"; $found = 1; last; --- 914,920 ---- } if (-s $podfile) { ! print {$Output->{FILEHANDLE}} "\n------------------------------\n"; ! $parser->parse_from_file($podfile, $Output->{FILEHANDLE}); ! print {$Output->{FILEHANDLE}} "\n------------------------------\n"; $found = 1; last; *************** *** 1132,1136 **** B<Synopsis>: C<echo @list> ! Display each item in the list to STDOUT, appending a carriage return after each item. Example: C<echo scalar(@$ENTRIES)> --- 1163,1167 ---- B<Synopsis>: C<echo @list> ! Display each item in the list, appending a carriage return after each item. Example: C<echo scalar(@$ENTRIES)> *************** *** 1138,1142 **** =cut ! sub echo { print(join("\n", @_, '')); } --- 1169,1173 ---- =cut ! sub echo { print {$Output->{FILEHANDLE}} (join("\n", @_, '')); } *************** *** 1421,1425 **** sub lpwd { ! print Cwd::getcwd() . "\n"; } --- 1452,1456 ---- sub lpwd { ! print {$Output->{FILEHANDLE}} Cwd::getcwd() . "\n"; } *************** *** 1511,1515 **** require Net::LDAP::LDIF; ! Net::LDAP::LDIF->new(\*STDOUT,"w")->write(@$entries); return $entries; } --- 1542,1546 ---- require Net::LDAP::LDIF; ! Net::LDAP::LDIF->new($Output->{FILEHANDLE},"w")->write(@$entries); return $entries; } *************** *** 1626,1632 **** unshift @fields, 'DN' if $localArgs->{'dn'}; ! print join($localArgs->{'fs'}, @fields) . "\n"; foreach my $entry (@$entries) { ! print join( $localArgs->{'fs'}, map { --- 1657,1663 ---- unshift @fields, 'DN' if $localArgs->{'dn'}; ! print {$Output->{FILEHANDLE}} join($localArgs->{'fs'}, @fields) . "\n"; foreach my $entry (@$entries) { ! print {$Output->{FILEHANDLE}} join( $localArgs->{'fs'}, map { *************** *** 1658,1662 **** foreach my $entry (@$entries) { ! printf("%s\n", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); } print STDERR "-----\n" . scalar(@$entries) . " entries found.\n"; --- 1689,1693 ---- foreach my $entry (@$entries) { ! printf {$Output->{FILEHANDLE}} ("%s\n", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); } print STDERR "-----\n" . scalar(@$entries) . " entries found.\n"; *************** *** 1668,1675 **** =head3 redir ! B<Synopsis>: C<redir $spec> ! Redirect the standard output. C<$spec> is used as a parameter to the C<open> ! function, so you can specify for example: =over 8 --- 1699,1706 ---- =head3 redir ! B<Synopsis>: C<redir ['E<lt>specE<gt>']> ! Redirect ldapsh's output. C<spec> is used as a parameter to the C<open> ! function, so you can specify, for example: =over 8 *************** *** 1683,1697 **** =back =cut sub redir { ! my $out = shift || ">&STDOUTBCK"; ! open(tmpSTDOUTBCK, '>&STDOUT'); ! open STDOUT, $out || return 0; ! select STDOUT; $|=1; ! return(\*tmpSTDOUTBCK); } =head2 Changing entries --- 1714,1761 ---- =back + If no argument is given, the current redirection will be displayed. + =cut sub redir { ! my $out = shift; ! my $previous = $Output; ! ! if (!defined $out) { ! print STDERR $Output->{NAME} . "\n"; ! return $Output; ! } ! ! my $new = { ! NAME => $out, ! FILEHANDLE => undef ! }; ! ! open $new->{FILEHANDLE}, $out || return $previous; ! ! $Output = $new; ! $Output->{FILEHANDLE}->autoflush(1); ! ! return $previous; } + =head3 noredir + + B<Synopsis>: C<noredir> + + No longer perform any of the redirections that were previously specified using L<redir|redir>. + + =cut + + sub noredir { + my $previous = $Output; + $Output = { + NAME => "STDOUT", + FILEHANDLE => \*STDOUT + }; + return $previous; + } + =head2 Changing entries *************** *** 2388,2398 **** while (s/([\s,])(-\w|\.)([\s,]|$)/$1'$2'$3/g) {}; - my $redir; - if ($redir = s/;\s*([|>][\s\w\d_\/.-]+)//) { - redir($1); - } ! eval() || print STDERR $@; ! redir if ($redir); my $APP = $Globals->{_APPENDRESULTS}{VALUE} ? '** ' : ''; --- 2452,2472 ---- while (s/([\s,])(-\w|\.)([\s,]|$)/$1'$2'$3/g) {}; ! # Create a context so $previous is deallocated after used, so the temporary ! # filehadle is closed ! { ! # This will chech for "<ldapsh command> ;| <sheel command>" usage ! # If so, we do a temporary output redirection ! my $previous; ! if (s/;\s*([|>][\s\w\d_\/.-]+)//) { ! $previous = redir($1); ! } ! ! eval() || print STDERR $@; ! ! # If we temporary redirected the output, come back and close the ! # temporary filehandle ! $Output = $previous if ($previous); ! } my $APP = $Globals->{_APPENDRESULTS}{VALUE} ? '** ' : ''; |
From: <rco...@us...> - 2003-09-19 20:03:46
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv12864 Modified Files: ldapsh Log Message: Fixed a (little) bug I introduced on temporary redirection. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** ldapsh 19 Sep 2003 13:05:52 -0000 1.24 --- ldapsh 19 Sep 2003 13:20:23 -0000 1.25 *************** *** 2456,2475 **** ! # Create a context so $previous is deallocated after used, so the temporary ! # filehadle is closed ! { ! # This will chech for "<ldapsh command> ;| <sheel command>" usage ! # If so, we do a temporary output redirection ! my $previous; ! if (s/;\s*([|>][\s\w\d_\/.-]+)//) { ! $previous = redir($1); ! } ! eval() || print STDERR $@; ! # If we temporary redirected the output, come back and close the ! # temporary filehandle ! $Output = $previous if ($previous); ! } my $APP = $Globals->{_APPENDRESULTS}{VALUE} ? '** ' : ''; --- 2456,2472 ---- ! # This will chech for "<ldapsh command> ;| <sheel command>" usage ! # If so, we do a temporary output redirection ! my $previous; ! if (s/;\s*([|>][\s\w\d_\/.-]+)//) { ! $previous = redir($1); ! } ! eval() || print STDERR $@; ! # If we temporary redirected the output, come back and close the ! # temporary filehandle ! $Output = $previous if ($previous); ! my $APP = $Globals->{_APPENDRESULTS}{VALUE} ? '** ' : ''; |
From: <rco...@us...> - 2003-09-19 19:55:25
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv9962 Modified Files: ldapsh Log Message: Changed the comment that explained where to post bugs Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** ldapsh 19 Sep 2003 12:59:30 -0000 1.23 --- ldapsh 19 Sep 2003 13:05:52 -0000 1.24 *************** *** 8,12 **** # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. ! # Please submit comments/bugs to <rco...@us...>. ##################################################################### --- 8,15 ---- # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. ! # Please submit comments/bugs/patches using the web tracking system ! # (http://sourceforge.net/tracker/?group_id=54115) or using the ! # mailing lists described at ! # http://sourceforge.net/mail/?group_id=54115 ##################################################################### |
From: <rco...@us...> - 2003-09-17 17:26:58
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv2697 Modified Files: Tag: PATCH-778409 ldapsh Log Message: Applied James patch 778409 enhacing "redir" Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.20.8.1 retrieving revision 1.20.8.1.2.1 diff -C2 -d -r1.20.8.1 -r1.20.8.1.2.1 *** ldapsh 27 Jul 2003 07:47:25 -0000 1.20.8.1 --- ldapsh 17 Sep 2003 17:26:50 -0000 1.20.8.1.2.1 *************** *** 138,141 **** --- 138,170 ---- =back + =head2 REDIRECTION + + By default, LDAP results are displayed on the "standard output" while + diagnostic messages are printed to the "standard error". + + You may redirect search results using the L<redir|redir> command. This will + stay in effect until L<noredir> is called. + + Alternatively, you can use a special shell syntax which will have only a + temporary effect. The special syntax is appending "; | ..." to your command, + where "..." is a parameter to the C<open> function. + + For example: + + ldapsh> redir '|awk "/Smith/{print}"' + ldapsh> cat + cn: Jack Smith + sn: Smith + cn: Jill Smith + sn: Smith + ldapsh> version;|cat + LDAP Shell (ldapsh) by Rafael Corvalan. + ldapsh> cat + cn: Jack Smith + sn: Smith + cn: Jill Smith + sn: Smith + ldapsh> noredir + =head1 PREREQUISITES *************** *** 235,238 **** --- 264,272 ---- }; + my $Output = { + NAME => "STDOUT", + FILEHANDLE => \*STDOUT + }; + my ($CWD, $PROMPT, $CONNPARAMS, $LDAPCONN, $ENTRIES, $EDITOR, $G); my ($Term, $TermAttribs); *************** *** 244,250 **** } - open(STDOUTBCK, '>&STDOUT'); - select(select(STDOUTBCK)); # Avoid -w warning about useless filehandle - if (-r $Opts->{GlobalRCFile}) { loadrc($Opts->{GlobalRCFile}); --- 278,281 ---- *************** *** 417,423 **** my ($key, $value, $showattribnames) = @_; if ($showattribnames) { ! printf("%s:%s\n", $key, $value); } else { ! print("$value\n"); } } --- 448,454 ---- my ($key, $value, $showattribnames) = @_; if ($showattribnames) { ! printf {$Output->{FILEHANDLE}} ("%s:%s\n", $key, $value); } else { ! print {$Output->{FILEHANDLE}} ("$value\n"); } } *************** *** 781,787 **** ); if (-s $podfile) { ! print STDERR "\n------------------------------\n"; ! $parser->parse_from_file($podfile, \*STDERR); ! print STDERR "\n------------------------------\n"; $found = 1; last; --- 812,818 ---- ); if (-s $podfile) { ! print {$Output->{FILEHANDLE}} "\n------------------------------\n"; ! $parser->parse_from_file($podfile, $Output->{FILEHANDLE}); ! print {$Output->{FILEHANDLE}} "\n------------------------------\n"; $found = 1; last; *************** *** 793,797 **** unlink $podfile; } else { ! $parser->parse_from_file($0, \*STDERR); } return 1; --- 824,828 ---- unlink $podfile; } else { ! $parser->parse_from_file($0, $Output->{FILEHANDLE}); } return 1; *************** *** 1022,1026 **** B<Synopsis>: C<echo @list> ! Display each item in the list to STDOUT, appending a carriage return after each item. Example: C<echo scalar(@$ENTRIES)> --- 1053,1057 ---- B<Synopsis>: C<echo @list> ! Display each item in the list, appending a carriage return after each item. Example: C<echo scalar(@$ENTRIES)> *************** *** 1028,1032 **** =cut ! sub echo { print(join("\n", @_, '')); } --- 1059,1063 ---- =cut ! sub echo { print {$Output->{FILEHANDLE}} (join("\n", @_, '')); } *************** *** 1307,1311 **** sub lpwd { ! print Cwd::getcwd() . "\n"; } --- 1338,1342 ---- sub lpwd { ! print {$Output->{FILEHANDLE}} Cwd::getcwd() . "\n"; } *************** *** 1397,1401 **** require Net::LDAP::LDIF; ! Net::LDAP::LDIF->new(\*STDOUT,"w")->write(@$entries); return $entries; } --- 1428,1432 ---- require Net::LDAP::LDIF; ! Net::LDAP::LDIF->new($Output->{FILEHANDLE},"w")->write(@$entries); return $entries; } *************** *** 1512,1518 **** unshift @fields, 'DN' if $localArgs->{'dn'}; ! print join($localArgs->{'fs'}, @fields) . "\n"; foreach my $entry (@$entries) { ! print join( $localArgs->{'fs'}, map { --- 1543,1549 ---- unshift @fields, 'DN' if $localArgs->{'dn'}; ! print {$Output->{FILEHANDLE}} join($localArgs->{'fs'}, @fields) . "\n"; foreach my $entry (@$entries) { ! print {$Output->{FILEHANDLE}} join( $localArgs->{'fs'}, map { *************** *** 1544,1548 **** foreach my $entry (@$entries) { ! printf("%s\n", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); } print STDERR "-----\n" . scalar(@$entries) . " entries found.\n"; --- 1575,1579 ---- foreach my $entry (@$entries) { ! printf {$Output->{FILEHANDLE}} ("%s\n", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); } print STDERR "-----\n" . scalar(@$entries) . " entries found.\n"; *************** *** 1554,1561 **** =head3 redir ! B<Synopsis>: C<redir $spec> ! Redirect the standard output. C<$spec> is used as a parameter to the C<open> ! function, so you can specify for example: =over 8 --- 1585,1592 ---- =head3 redir ! B<Synopsis>: C<redir ['E<lt>specE<gt>']> ! Redirect ldapsh's output. C<spec> is used as a parameter to the C<open> ! function, so you can specify, for example: =over 8 *************** *** 1569,1583 **** =back =cut sub redir { ! my $out = shift || ">&STDOUTBCK"; ! open(tmpSTDOUTBCK, '>&STDOUT'); ! open STDOUT, $out || return 0; ! select STDOUT; $|=1; ! return(\*tmpSTDOUTBCK); } =head2 Changing entries --- 1600,1647 ---- =back + If no argument is given, the current redirection will be displayed. + =cut sub redir { ! my $out = shift; ! my $previous = $Output; ! ! if (!defined $out) { ! print STDERR $Output->{NAME} . "\n"; ! return $Output; ! } ! ! my $new = { ! NAME => $out, ! FILEHANDLE => undef ! }; ! ! open $new->{FILEHANDLE}, $out || return $previous; ! ! $Output = $new; ! $Output->{FILEHANDLE}->autoflush(1); ! ! return $previous; } + =head3 noredir + + B<Synopsis>: C<noredir> + + No longer perform any of the redirections that were previously specified using L<redir|redir>. + + =cut + + sub noredir { + my $previous = $Output; + $Output = { + NAME => "STDOUT", + FILEHANDLE => \*STDOUT + }; + return $previous; + } + =head2 Changing entries *************** *** 2156,2166 **** while (s/([\s,])(-\w)([\s,]|$)/$1'$2'$3/g) {}; ! my $redir; ! if ($redir = s/;\s*([|>][\s\w\d_\/.-]+)//) { ! redir($1); } eval() || print STDERR $@; ! redir if ($redir); } --- 2220,2230 ---- while (s/([\s,])(-\w)([\s,]|$)/$1'$2'$3/g) {}; ! my $previous; ! if (s/;\s*([|>][\s\w\d_\/.-]+)//) { ! $previous = redir($1); } eval() || print STDERR $@; ! $Output = $previous if ($previous); } |
From: <rco...@us...> - 2003-08-28 23:52:38
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv22395 Modified Files: ldapsh Log Message: Added Peder & James as authors Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** ldapsh 28 Aug 2003 23:19:57 -0000 1.21 --- ldapsh 28 Aug 2003 23:52:35 -0000 1.22 *************** *** 911,916 **** sub version() { ! printf STDERR "LDAP Shell (ldapsh) by Rafael Corvalan.\nCVS File ID: %s\nShell release: %s\nhttp://ldapsh.sourceforge.net/\n", ! '$Id$', $RELEASE; } --- 911,921 ---- sub version() { ! printf STDERR <<'EOF' ! LDAP Shell (ldapsh) by Rafael Corvalan, Peder O. Klingenberg and James Devenish. ! CVS File ID: %s ! Shell release: %s ! http://ldapsh.sourceforge.net/ ! EOF ! , '$Id$', $RELEASE; } *************** *** 2280,2286 **** Z<> ! =head1 AUTHOR ! Rafael Corvalan (e-mail E<lt>rco...@us...E<gt>). Please report any bugs, or post any suggestions directly to my e-mail address. --- 2285,2309 ---- Z<> ! =head1 AUTHORS ! By chronological contribution: ! ! =over 8 ! ! =item * Rafael Corvalan (E<lt>rco...@us...E<gt>) ! ! =item * Peder O. Klingenberg ! ! =item * James Devenish ! ! =back ! ! =head1 FEEDBACK ! ! Please report bugs to the mailing list E<lt>lda...@li...E<gt> or through E<lt>http://sourceforge.net/tracker/?group_id=54115&atid=472731E<gt>. ! ! Send comments and suggestions to the above mailing list. ! ! Post Feature Requests to E<lt>http://sourceforge.net/tracker/?group_id=54115&atid=472734E<gt>. |
From: <rco...@us...> - 2003-08-28 23:20:02
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv17309 Modified Files: ldapsh Log Message: Merged patches below into HEAD: 778341 778345 778347 778361 778364 778368 778369 Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** ldapsh 27 Jul 2003 07:03:01 -0000 1.20 --- ldapsh 28 Aug 2003 23:19:57 -0000 1.21 *************** *** 18,22 **** =head1 SYNOPSIS ! ldapsh =head1 EXAMPLE --- 18,22 ---- =head1 SYNOPSIS ! ldapsh [expression] =head1 EXAMPLE *************** *** 124,133 **** (composed of B<Net::LDAP::Entry> entries). ! =item 2. E<lt>functionE<gt> ['-r'] This is like the previous usage. The search filter is C<(objectclass=*)>. ! If the C<-r> option is used, the scope is I<sub>. ! Otherwise, the scope is I<one>. =item 3. E<lt>functionE<gt> $entries --- 124,135 ---- (composed of B<Net::LDAP::Entry> entries). ! =item 2. E<lt>functionE<gt> ['-r'|.] This is like the previous usage. The search filter is C<(objectclass=*)>. ! If neither C<-r> nor the dot (a.k.a. "full stop" or "period") is given, the ! scope is I<one>. If C<-r> is given, the scope is I<sub>. If the dot is ! given, the scope is I<base> (this can be used to match the I<current working ! directory> itself). =item 3. E<lt>functionE<gt> $entries *************** *** 184,188 **** use Data::Dumper qw(Dumper); use Unicode::MapUTF8 qw(to_utf8 from_utf8); ! use subs qw(connect bind dump exit reset); BEGIN { --- 186,190 ---- use Data::Dumper qw(Dumper); use Unicode::MapUTF8 qw(to_utf8 from_utf8); ! use subs qw(connect bind delete dump exit reset); BEGIN { *************** *** 219,223 **** ENTRIES => {VALUE => [], RIGHTS => 'RW'}, PROMPT => {VALUE => '${APP}\[LDAP @ $CONNPARAMS->{SERVER}] $CWD > ', RIGHTS => 'RWL'}, ! EDITOR => {VALUE => 'vi', RIGHTS => 'RWL'}, G => {VALUE => undef, RIGHTS => 'RWL'}, _APPENDRESULTS => {VALUE => 0, RIGHTS => ''}, --- 221,225 ---- ENTRIES => {VALUE => [], RIGHTS => 'RW'}, PROMPT => {VALUE => '${APP}\[LDAP @ $CONNPARAMS->{SERVER}] $CWD > ', RIGHTS => 'RWL'}, ! EDITOR => {VALUE => $ENV{VISUAL} ? $ENV{VISUAL} : ($ENV{EDITOR} ? $ENV{EDITOR} : 'vi'), RIGHTS => 'RWL'}, G => {VALUE => undef, RIGHTS => 'RWL'}, _APPENDRESULTS => {VALUE => 0, RIGHTS => ''}, *************** *** 463,472 **** push(@entries, @$spec); } else { ! my $searchedEntries = _search( ! BaseDN => $Globals->{CWD}{VALUE}, ! Scope => $Options->{r} ? 'sub' : 'one', ! Filter => $spec, ! Attribs => [] ! ); if (defined($searchedEntries)) { push(@entries, @$searchedEntries); --- 465,484 ---- push(@entries, @$spec); } else { ! my $searchedEntries; ! if ($spec =~ /^\.$/) { ! $searchedEntries = _search( ! BaseDN => $Globals->{CWD}{VALUE}, ! Scope => 'base', ! Filter => '(objectclass=*)', ! Attribs => [] ! ); ! } else { ! $searchedEntries = _search( ! BaseDN => $Globals->{CWD}{VALUE}, ! Scope => $Options->{r} ? 'sub' : 'one', ! Filter => $spec, ! Attribs => [] ! ); ! } if (defined($searchedEntries)) { push(@entries, @$searchedEntries); *************** *** 510,513 **** --- 522,556 ---- } + package PodHeadings; + + use strict; + use vars qw(@ISA @EXPORT); + + @ISA = qw(Pod::Select); + + sub verbatim { } + + sub textblock { } + + sub interior_sequence { } + + sub command { + my ($self, $cmd, $text, $line_num, $pod_para) = @_; + ## Just treat this like a textblock + if ($cmd =~ /^head[12]/) { + ## Just treat this like a textblock + my $out_fh = $self->output_handle(); + print $out_fh "\n\n"; + $self->SUPER::textblock($pod_para->raw_text(), $line_num, $pod_para); + } + elsif ($cmd =~ /^head/) { + my $stripped = $pod_para->text(); + my $out_fh = $self->output_handle(); + $stripped =~ s/\s+$//; + print $out_fh $stripped." "; + } + } + + package ldapsh; ############################################################# *************** *** 526,534 **** ### Command completion ### if (substr($line, 0, $start) =~ /^\s*$/) { ! my $oldvalue = $TermAttribs->{completion_word}; ! $TermAttribs->{completion_word} = [_commandListGenerator()]; ! my @ret = $Term->completion_matches($text, $TermAttribs->{'list_completion_function'}); ! $TermAttribs->{completion_word} = $oldvalue; ! return @ret; } --- 569,573 ---- ### Command completion ### if (substr($line, 0, $start) =~ /^\s*$/) { ! return _commandCompletion(@_); } *************** *** 594,603 **** ######################################### ! ### DN Completion ### my $line2 = $line; $line2 =~ s/^\s+//; my ($cmd, $rest) = split(/\s+/, $line2, 2); if ($cmd =~ /^(cd|acd|setdn|pushd|cat|vi|ls|list|dump|ldif|search|cp)$/) { return _cdCommandCompletion(@_); } else { return(); --- 633,649 ---- ######################################### ! ### Parameter Completion ### my $line2 = $line; $line2 =~ s/^\s+//; my ($cmd, $rest) = split(/\s+/, $line2, 2); if ($cmd =~ /^(cd|acd|setdn|pushd|cat|vi|ls|list|dump|ldif|search|cp)$/) { + # DN Completion return _cdCommandCompletion(@_); + } elsif ($cmd =~ /^(help|which)$/) { + # Command Completion + return _commandCompletion(@_); + } elsif ($cmd =~ /^(add|replace|delete)$/) { + # Attribute Completion + return _attributeEditCompletion(@_); } else { return(); *************** *** 610,613 **** --- 656,668 ---- } + sub _commandCompletion { + my ($text, $line, $start, $end) = @_; + my $oldvalue = $TermAttribs->{completion_word}; + $TermAttribs->{completion_word} = [_commandListGenerator()]; + my @ret = $Term->completion_matches($text, $TermAttribs->{'list_completion_function'}); + $TermAttribs->{completion_word} = $oldvalue; + return @ret; + } + sub _cdCommandCompletion { _bindneeded() or return (); *************** *** 631,640 **** return _entryDNCompletion($prefix, $attr, $partToComplete, $BaseDN); } else { ! return _attributeNamesCompletion($prefix, $partToComplete, $BaseDN); } } ! sub _attributeNamesCompletion($$$) { my ($prefix, $partToComplete, $BaseDN) = @_; $TermAttribs->{completion_append_character} = "\0"; --- 686,733 ---- return _entryDNCompletion($prefix, $attr, $partToComplete, $BaseDN); } else { ! return _attributeNamesDNCompletion($prefix, $partToComplete, $BaseDN); } } + sub _attributeEditCompletion{ + my ($text, $line, $start, $end) = @_; + + # Put argument delimiter after current comma + if ($text =~ /,$/) { + $TermAttribs->{completion_append_character} = ' '; + return $text; + } + + my $entries = $Globals->{ENTRIES}{VALUE}; + + unless (defined($entries) && scalar(@{$entries}) > 0) { + return undef; + } + + $TermAttribs->{completion_append_character} = "\0"; + + if (substr($line, 0, $start) =~ /,/) { + my ($name) = ($line =~ /^\S+\s+([^,]*)/); + return undef unless defined($name); + if ($name =~ /^['"]/) { + $name = substr($name, 1, length($name)-2); + } + my @possible_entries = @{$entries}[0]->get_value($name); + @possible_entries = grep {/^$text/i} @possible_entries; + return undef unless scalar(@possible_entries); + # TODO find longest common prefix + return $text, @possible_entries; + } else { + my @possible_entries = @{$entries}[0]->attributes(); + @possible_entries = grep {/^$text/i} @possible_entries; + return undef unless scalar(@possible_entries); + # TODO find longest common prefix + # TODO use a cache + return $text, @possible_entries; + } + return undef; + } ! sub _attributeNamesDNCompletion($$$) { my ($prefix, $partToComplete, $BaseDN) = @_; $TermAttribs->{completion_append_character} = "\0"; *************** *** 741,747 **** =head3 help ! B<Synopsis>: C<help [E<lt>commandE<gt>]> ! Print some help on the given command (or a global help if no command is given). =cut --- 834,841 ---- =head3 help ! B<Synopsis>: C<help ['E<lt>commandE<gt>'|'all']> ! Display help about the given command (or global help, if 'all' is given). ! If no parameter is given, a summary of commands will be shown. =cut *************** *** 760,764 **** $parser = new Pod::Text::Termcap; } ! if (defined($cmd)) { require Pod::Select; require File::Temp; --- 854,861 ---- $parser = new Pod::Text::Termcap; } ! if (defined($cmd) && $cmd eq "all") { ! $parser->parse_from_file($0, \*STDERR); ! } ! else { require Pod::Select; require File::Temp; *************** *** 769,797 **** push(@docfiles, $Opts->{RCFile}) if (-r $Opts->{RCFile}); foreach my $file (@docfiles) { Pod::Select::podselect( { ! -output => $podfile, ! -sections => [ ! "DESCRIPTION/$cmd\\b.*", ! "COMMANDS/${cmd}\\b.*", ! "COMMANDS/.*/${cmd}" ! ] ! }, ! $file ! ); ! if (-s $podfile) { ! print STDERR "\n------------------------------\n"; ! $parser->parse_from_file($podfile, \*STDERR); ! print STDERR "\n------------------------------\n"; ! $found = 1; ! last; } } if (! $found) { ! print STDERR "No help found on '$cmd'.\n"; } unlink $podfile; - } else { - $parser->parse_from_file($0, \*STDERR); } return 1; --- 866,902 ---- push(@docfiles, $Opts->{RCFile}) if (-r $Opts->{RCFile}); foreach my $file (@docfiles) { + if (defined($cmd)) { Pod::Select::podselect( { ! -output => $podfile, ! -sections => [ ! "DESCRIPTION/$cmd\\b.*", ! "COMMANDS/${cmd}\\b.*", ! "COMMANDS/.*/${cmd}" ! ] ! }, $file); ! } ! else { ! my $headings = new PodHeadings(); ! $headings->select("COMMANDS"); ! $headings->parse_from_file($file, $podfile); ! } ! if (-s $podfile) { ! print STDERR "------------------------------\n"; ! $parser->parse_from_file($podfile, \*STDERR); ! print STDERR "------------------------------\n"; ! $found = 1; ! last; } } if (! $found) { ! if (defined($cmd)) { ! print STDERR "No help found for '$cmd'.\n"; ! } ! else { ! print STDERR "No help found.\n"; ! } } unlink $podfile; } return 1; *************** *** 1117,1123 **** =head3 cd ! B<Synopsis>: C<cd 'E<lt>RDNE<gt>'> Change the I<current working directory> to the specified RDN. You can specify multiple RDNs separated by commas (in the reverse order of the DN, to allow completion). You can also specify ".." to go to the parent DN. See also the L<acd|acd>, L<setdn|setdn>, L<pushd|pushd> and L<popd|popd> commands. --- 1222,1229 ---- =head3 cd ! B<Synopsis>: C<cd ['E<lt>RDNE<gt>']> Change the I<current working directory> to the specified RDN. You can specify multiple RDNs separated by commas (in the reverse order of the DN, to allow completion). You can also specify ".." to go to the parent DN. + If no RDN is specified, the I<current working directory> is not changed. See also the L<acd|acd>, L<setdn|setdn>, L<pushd|pushd> and L<popd|popd> commands. *************** *** 1129,1132 **** --- 1235,1239 ---- my $SubPath = shift(); + $SubPath = "" unless defined($SubPath); $SubPath =~ s/\s*,\s*$//; $SubPath = join(',', reverse(split(/\s*,\s*/, $SubPath))); *************** *** 1211,1214 **** --- 1318,1323 ---- Perform the same action as the L<cd|cd> command. If the action succeeds, the old working directory is stored on a stack (which can be shown using L<dirs|dirs>). It can be restored using L<popd|popd>. + If no RDN is given, the I<current working directory> will be pushed onto the stack. + =cut *************** *** 1415,1440 **** - =head3 vi - - B<Synopsis>: C<vi E<lt>expansionE<gt>> - - Show the entries returned by the expansion (see L<Expansion|expansion>) in a vi editor, in read-only mode. Any changes made to the file has no effect on LDAP entries. - - =cut - - sub vi { - my $entries = _entriesExpander undef, @_; - return 0 unless defined $entries; - - require Net::LDAP::LDIF; - require File::Temp; - my (undef, $tempfile) = File::Temp::tempfile('LDAPShell_vi_XXXXXXXXXX', SUFFIX => '.ldif'); - Net::LDAP::LDIF->new($tempfile,"w")->write(@$entries); - system($Globals->{EDITOR}{VALUE}, $tempfile); - unlink $tempfile; - return $entries; - } - - =head3 dump --- 1524,1527 ---- *************** *** 1604,1607 **** --- 1691,1792 ---- =head2 Changing entries + =head3 vi + + B<Synopsis>: C<vi E<lt>expansionE<gt>> + + Show the entries matched by the expansion (see L<Expansion|expansion>) in a text editor. + Entries are saved to a temporary file for editing in the LDIF format. + If the temporary file is modified, it will be re-read as an LDIF file and used to modify + the search results. Any changes can be viewed using L<changes|changes> and will need to + be committed using L<commit|commit>. + BUG (TODO): If you add an attribute to an entry (so, if you add a value to an attribute + that hadn't previously a value), it will not be detected. We should do a two-way check. + + =cut + + sub vi { + my $entries = _entriesExpander undef, @_; + return 0 unless defined $entries; + + require Net::LDAP::LDIF; + require File::Temp; + + my (undef, $tempfile) = File::Temp::tempfile('LDAPShell_vi_XXXXXXXXXX', SUFFIX => '.ldif'); + Net::LDAP::LDIF->new($tempfile,"w")->write(@$entries); + my $mtime = (stat($tempfile))[9]; + + system($Globals->{EDITOR}{VALUE}, $tempfile); + + # If modified, load as LDIF entry and compare to the same DNs in our directory (if they exist). + if ( (stat($tempfile))[9] > $mtime ) { + my $ldif = Net::LDAP::LDIF->new($tempfile, "r", onerror => undef); + my %hash = map { $_->dn => $_ } @$entries; + my $examined = 0; + while (not $ldif->eof()) { + my $entry = $ldif->read_entry(); + if ($ldif->error()) { + printf STDERR "Encountered error reading LDIF format: [[%s]]\n\n", $ldif->error(); + last; + } elsif (defined($entry)) { + $examined++; + print STDERR "Comparing " . $entry->dn . "..."; + if (defined $hash{$entry->dn}) { + my $original = $hash{$entry->dn}; + my %attrs = map { lc $_ => 1 } ($original->attributes(), $entry->attributes()); # unique keys + foreach my $attr (sort(keys %attrs)) { + my $pre_values = $original->get_value($attr, asref => 1 ); + my $post_values = $entry->get_value($attr, asref => 1 ); + if ($pre_values && $post_values) { + if (scalar(@$pre_values) != scalar(@$post_values)) { + foreach my $value ($post_values) { + $original->replace($attr => $value); + } + } + else { # try harder + my @a = sort @$pre_values; + my @b = sort @$post_values; + foreach my $i (0 .. scalar(@a)-1) { + if ($a[$i] ne $b[$i]) { + foreach my $value ($post_values) { + $original->replace($attr => $value); + } + last; + } + } + } + } + elsif ($pre_values) { + $original->delete($attr); + } + elsif ($post_values) { + foreach my $value ($post_values) { + $original->add($attr => $value); + } + } + } + + my $changes = $original->{changes}; + if (defined($changes) and scalar(@$changes)) { + print STDERR "changed\n\n"; + } + else { + print STDERR "no modifications.\n\n"; + } + } + else { + print STDERR "skipped.\n"; + print STDERR "Warning: cannot change a DN or add an entry using vi.\n\n"; + } + } + } + unless ($ldif->error() or $examined >= scalar(@$entries)) { + print STDERR "Warning: some entries were absent from the edited file.\n\n"; + } + } + unlink $tempfile; + return $entries; + } + + =head3 change *************** *** 1643,1646 **** --- 1828,1925 ---- + =head3 add + + B<Synopsis>: C<add 'E<lt>attributeE<gt>', 'E<lt>valueE<gt>' ...> + + Add one or more new attributes to the entries in the L<$ENTRIES|"$ENTRIES"> global variable. + + The values will be added to the values that already exist for the given attribute. + + The entries are locally modified! You must L<commit|commit>! You can see the changes + done using the L<changes|changes> command. + + Example: C<add 'givenName', 'Bob', 'Robert'> + + =cut + + sub add { + my $entries = $Globals->{ENTRIES}{VALUE}; + + _haveentries() or return 0; + + if (scalar @_ < 2) { + print STDERR "You must supply both an attribute and some values.\n"; + return 0; + } + + my $attr = shift; + + map { $_->add($attr, [@_]) } @$entries; + return 1; + } + + + =head3 replace + + B<Synopsis>: C<replace 'E<lt>attributeE<gt>', 'E<lt>valueE<gt>' ...> + + Similar to L<add|add>, except that the given values will replace any values that + already exist for the given attribute. + + The entries are merely locally modified! You must L<commit|commit>! You can see the changes + using the L<changes|changes> command. + + Example: C<replace 'givenName', 'Bill', 'William'> + + =cut + + sub replace { + my $entries = $Globals->{ENTRIES}{VALUE}; + + _haveentries() or return 0; + + if (scalar @_ < 2) { + print STDERR "You must supply both an attribute and some values.\n"; + return 0; + } + + my $attr = shift; + + map { $_->replace($attr, [@_]) } @$entries; + return 1; + } + + + =head3 delete + + B<Synopsis>: C<delete 'E<lt>attributeE<gt>'[, 'E<lt>valueE<gt>' ...]> + + Delete the values of given attribute from the the L<$ENTRIES|"$ENTRIES"> global variable. + If no values are given, the entire attribute will be deleted. + + The entries are locally modified! You must L<commit|commit>! You can see the changes + done using the L<changes|changes> command. + + Example: C<delete 'givenName'> + + =cut + + sub delete { + my $entries = $Globals->{ENTRIES}{VALUE}; + + _haveentries() or return 0; + + if (scalar @_ < 1) { + print STDERR "You must at least supply an attribute name.\n"; + return 0; + } + + my $attr = shift; + + map { $_->delete($attr, [@_]) } @$entries; + return 1; + } + + =head3 changes *************** *** 1904,1907 **** --- 2183,2188 ---- So, in your shell you can type "ads" and get connected to a specific server. + Additionally, you could invoke B<ldapsh> as C<ldapsh ads> to call the function + straight away. Remember: you put in this file Perl code. So you can do whatever you want!!! *************** *** 1972,1976 **** =head2 $EDITOR ! The default editor used when the L<vi|vi> command is called. By default this is "vi". =head2 $G --- 2253,2258 ---- =head2 $EDITOR ! The default editor used when the L<vi|vi> command is called. By default, this is obtained ! from the environment variable $VISUAL (if set) or $EDITOR (if set) or otherwise "vi". =head2 $G *************** *** 2059,2067 **** _Init(); while (1) { - my $APP = $Globals->{_APPENDRESULTS}{VALUE} ? '** ' : ''; - my $P = eval('return("' . $Globals->{PROMPT}{VALUE} . '")'); - print $@ unless defined $P; - $_ = $Term->readline($P); last unless defined($_); s/^\s+//; --- 2341,2350 ---- _Init(); + $_ = "@ARGV"; + + # Note: this loop will be executed once before the prompt is shown. + # This is to support command-line arguments and will occur whether + # or not any were given. while (1) { last unless defined($_); s/^\s+//; *************** *** 2080,2084 **** # The line below will quote some barewords such as "-l", "-a" etc... # It's not perfect, but simple ! while (s/([\s,])(-\w)([\s,]|$)/$1'$2'$3/g) {}; my $redir; --- 2363,2367 ---- # The line below will quote some barewords such as "-l", "-a" etc... # It's not perfect, but simple ! while (s/([\s,])(-\w|\.)([\s,]|$)/$1'$2'$3/g) {}; my $redir; *************** *** 2089,2092 **** --- 2372,2380 ---- eval() || print STDERR $@; redir if ($redir); + + my $APP = $Globals->{_APPENDRESULTS}{VALUE} ? '** ' : ''; + my $P = eval('return("' . $Globals->{PROMPT}{VALUE} . '")'); + print $@ unless defined $P; + $_ = $Term->readline($P); } |
From: <rco...@us...> - 2003-08-28 22:35:30
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv8678 Modified Files: Tag: 1.20.8.2 ldapsh Log Message: Bug fix in sub vi(). The call to Net::LDIF::read_entry() died on error, so we didn't show our error message. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.20.8.1 retrieving revision 1.20.8.2 diff -C2 -d -r1.20.8.1 -r1.20.8.2 *** ldapsh 27 Jul 2003 07:47:25 -0000 1.20.8.1 --- ldapsh 28 Aug 2003 22:35:25 -0000 1.20.8.2 *************** *** 1591,1594 **** --- 1591,1596 ---- the search results. Any changes can be viewed using L<changes|changes> and will need to be committed using L<commit|commit>. + BUG (TODO): If you add an attribute to an entry (so, if you add a value to an attribute + that hadn't previously a value), it will not be detected. We should do a two-way check. =cut *************** *** 1609,1613 **** # If modified, load as LDIF entry and compare to the same DNs in our directory (if they exist). if ( (stat($tempfile))[9] > $mtime ) { ! my $ldif = Net::LDAP::LDIF->new($tempfile,"r"); my %hash = map { $_->dn => $_ } @$entries; my $examined = 0; --- 1611,1615 ---- # If modified, load as LDIF entry and compare to the same DNs in our directory (if they exist). if ( (stat($tempfile))[9] > $mtime ) { ! my $ldif = Net::LDAP::LDIF->new($tempfile, "r", onerror => undef); my %hash = map { $_->dn => $_ } @$entries; my $examined = 0; *************** *** 1615,1619 **** my $entry = $ldif->read_entry(); if ($ldif->error()) { ! print STDERR "Encountered error reading LDIF format.\n\n"; last; } elsif (defined($entry)) { --- 1617,1621 ---- my $entry = $ldif->read_entry(); if ($ldif->error()) { ! printf STDERR "Encountered error reading LDIF format: [[%s]]\n\n", $ldif->error(); last; } elsif (defined($entry)) { *************** *** 1669,1673 **** } } ! if ($examined != scalar(@$entries)) { print STDERR "Warning: some entries were absent from the edited file.\n\n"; } --- 1671,1675 ---- } } ! unless ($ldif->error() or $examined >= scalar(@$entries)) { print STDERR "Warning: some entries were absent from the edited file.\n\n"; } |
From: <j-d...@us...> - 2003-07-27 07:47:28
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv4795 Modified Files: Tag: PATCH-778369 ldapsh Log Message: The "vi" command now supports editing! Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.20 retrieving revision 1.20.8.1 diff -C2 -d -r1.20 -r1.20.8.1 *** ldapsh 27 Jul 2003 07:03:01 -0000 1.20 --- ldapsh 27 Jul 2003 07:47:25 -0000 1.20.8.1 *************** *** 1415,1440 **** - =head3 vi - - B<Synopsis>: C<vi E<lt>expansionE<gt>> - - Show the entries returned by the expansion (see L<Expansion|expansion>) in a vi editor, in read-only mode. Any changes made to the file has no effect on LDAP entries. - - =cut - - sub vi { - my $entries = _entriesExpander undef, @_; - return 0 unless defined $entries; - - require Net::LDAP::LDIF; - require File::Temp; - my (undef, $tempfile) = File::Temp::tempfile('LDAPShell_vi_XXXXXXXXXX', SUFFIX => '.ldif'); - Net::LDAP::LDIF->new($tempfile,"w")->write(@$entries); - system($Globals->{EDITOR}{VALUE}, $tempfile); - unlink $tempfile; - return $entries; - } - - =head3 dump --- 1415,1418 ---- *************** *** 1603,1606 **** --- 1581,1680 ---- =head2 Changing entries + + =head3 vi + + B<Synopsis>: C<vi E<lt>expansionE<gt>> + + Show the entries matched by the expansion (see L<Expansion|expansion>) in a text editor. + Entries are saved to a temporary file for editing in the LDIF format. + If the temporary file is modified, it will be re-read as an LDIF file and used to modify + the search results. Any changes can be viewed using L<changes|changes> and will need to + be committed using L<commit|commit>. + + =cut + + sub vi { + my $entries = _entriesExpander undef, @_; + return 0 unless defined $entries; + + require Net::LDAP::LDIF; + require File::Temp; + + my (undef, $tempfile) = File::Temp::tempfile('LDAPShell_vi_XXXXXXXXXX', SUFFIX => '.ldif'); + Net::LDAP::LDIF->new($tempfile,"w")->write(@$entries); + my $mtime = (stat($tempfile))[9]; + + system($Globals->{EDITOR}{VALUE}, $tempfile); + + # If modified, load as LDIF entry and compare to the same DNs in our directory (if they exist). + if ( (stat($tempfile))[9] > $mtime ) { + my $ldif = Net::LDAP::LDIF->new($tempfile,"r"); + my %hash = map { $_->dn => $_ } @$entries; + my $examined = 0; + while (not $ldif->eof()) { + my $entry = $ldif->read_entry(); + if ($ldif->error()) { + print STDERR "Encountered error reading LDIF format.\n\n"; + last; + } elsif (defined($entry)) { + $examined++; + print STDERR "Comparing " . $entry->dn . "..."; + if (defined $hash{$entry->dn}) { + my $original = $hash{$entry->dn}; + my %attrs = map { lc $_ => 1 } ($original->attributes(), $entry->attributes()); # unique keys + foreach my $attr (sort(keys %attrs)) { + my $pre_values = $original->get_value($attr, asref => 1 ); + my $post_values = $entry->get_value($attr, asref => 1 ); + if ($pre_values && $post_values) { + if (scalar(@$pre_values) != scalar(@$post_values)) { + foreach my $value ($post_values) { + $original->replace($attr => $value); + } + } + else { # try harder + my @a = sort @$pre_values; + my @b = sort @$post_values; + foreach my $i (0 .. scalar(@a)-1) { + if ($a[$i] ne $b[$i]) { + foreach my $value ($post_values) { + $original->replace($attr => $value); + } + last; + } + } + } + } + elsif ($pre_values) { + $original->delete($attr); + } + elsif ($post_values) { + foreach my $value ($post_values) { + $original->add($attr => $value); + } + } + } + + my $changes = $original->{changes}; + if (defined($changes) and scalar(@$changes)) { + print STDERR "changed\n\n"; + } + else { + print STDERR "no modifications.\n\n"; + } + } + else { + print STDERR "skipped.\n"; + print STDERR "Warning: cannot change a DN or add an entry using vi.\n\n"; + } + } + } + if ($examined != scalar(@$entries)) { + print STDERR "Warning: some entries were absent from the edited file.\n\n"; + } + } + unlink $tempfile; + return $entries; + } + =head3 change |
From: <j-d...@us...> - 2003-07-27 07:42:14
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv4036 Modified Files: Tag: PATCH-778368 ldapsh Log Message: 1) Added "add", "replace", "delete" for editing attributes. 2) Added tab completion for attribute names and values. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.20 retrieving revision 1.20.6.1 diff -C2 -d -r1.20 -r1.20.6.1 *** ldapsh 27 Jul 2003 07:03:01 -0000 1.20 --- ldapsh 27 Jul 2003 07:42:11 -0000 1.20.6.1 *************** *** 184,188 **** use Data::Dumper qw(Dumper); use Unicode::MapUTF8 qw(to_utf8 from_utf8); ! use subs qw(connect bind dump exit reset); BEGIN { --- 184,188 ---- use Data::Dumper qw(Dumper); use Unicode::MapUTF8 qw(to_utf8 from_utf8); ! use subs qw(connect bind delete dump exit reset); BEGIN { *************** *** 600,603 **** --- 600,606 ---- if ($cmd =~ /^(cd|acd|setdn|pushd|cat|vi|ls|list|dump|ldif|search|cp)$/) { return _cdCommandCompletion(@_); + } elsif ($cmd =~ /^(add|replace|delete)$/) { + # Attribute Completion + return _attributeEditCompletion(@_); } else { return(); *************** *** 631,640 **** return _entryDNCompletion($prefix, $attr, $partToComplete, $BaseDN); } else { ! return _attributeNamesCompletion($prefix, $partToComplete, $BaseDN); } } ! sub _attributeNamesCompletion($$$) { my ($prefix, $partToComplete, $BaseDN) = @_; $TermAttribs->{completion_append_character} = "\0"; --- 634,681 ---- return _entryDNCompletion($prefix, $attr, $partToComplete, $BaseDN); } else { ! return _attributeNamesDNCompletion($prefix, $partToComplete, $BaseDN); } } + sub _attributeEditCompletion{ + my ($text, $line, $start, $end) = @_; + + # Put argument delimiter after current comma + if ($text =~ /,$/) { + $TermAttribs->{completion_append_character} = ' '; + return $text; + } + + my $entries = $Globals->{ENTRIES}{VALUE}; + + unless (defined($entries) && scalar(@{$entries}) > 0) { + return undef; + } + + $TermAttribs->{completion_append_character} = "\0"; + + if (substr($line, 0, $start) =~ /,/) { + my ($name) = ($line =~ /^\S+\s+([^,]*)/); + return undef unless defined($name); + if ($name =~ /^['"]/) { + $name = substr($name, 1, length($name)-2); + } + my @possible_entries = @{$entries}[0]->get_value($name); + @possible_entries = grep {/^$text/i} @possible_entries; + return undef unless scalar(@possible_entries); + # TODO find longest common prefix + return $text, @possible_entries; + } else { + my @possible_entries = @{$entries}[0]->attributes(); + @possible_entries = grep {/^$text/i} @possible_entries; + return undef unless scalar(@possible_entries); + # TODO find longest common prefix + # TODO use a cache + return $text, @possible_entries; + } + return undef; + } ! sub _attributeNamesDNCompletion($$$) { my ($prefix, $partToComplete, $BaseDN) = @_; $TermAttribs->{completion_append_character} = "\0"; *************** *** 1639,1642 **** --- 1680,1777 ---- map { &$code; } @$entries; + return 1; + } + + + =head3 add + + B<Synopsis>: C<add 'E<lt>attributeE<gt>', 'E<lt>valueE<gt>' ...> + + Add one or more new attributes to the entries in the L<$ENTRIES|"$ENTRIES"> global variable. + + The values will be added to the values that already exist for the given attribute. + + The entries are locally modified! You must L<commit|commit>! You can see the changes + done using the L<changes|changes> command. + + Example: C<add 'givenName', 'Bob', 'Robert'> + + =cut + + sub add { + my $entries = $Globals->{ENTRIES}{VALUE}; + + _haveentries() or return 0; + + if (scalar @_ < 2) { + print STDERR "You must supply both an attribute and some values.\n"; + return 0; + } + + my $attr = shift; + + map { $_->add($attr, [@_]) } @$entries; + return 1; + } + + + =head3 replace + + B<Synopsis>: C<replace 'E<lt>attributeE<gt>', 'E<lt>valueE<gt>' ...> + + Similar to L<add|add>, except that the given values will replace any values that + already exist for the given attribute. + + The entries are merely locally modified! You must L<commit|commit>! You can see the changes + using the L<changes|changes> command. + + Example: C<replace 'givenName', 'Bill', 'William'> + + =cut + + sub replace { + my $entries = $Globals->{ENTRIES}{VALUE}; + + _haveentries() or return 0; + + if (scalar @_ < 2) { + print STDERR "You must supply both an attribute and some values.\n"; + return 0; + } + + my $attr = shift; + + map { $_->replace($attr, [@_]) } @$entries; + return 1; + } + + + =head3 delete + + B<Synopsis>: C<delete 'E<lt>attributeE<gt>'[, 'E<lt>valueE<gt>' ...]> + + Delete the values of given attribute from the the L<$ENTRIES|"$ENTRIES"> global variable. + If no values are given, the entire attribute will be deleted. + + The entries are locally modified! You must L<commit|commit>! You can see the changes + done using the L<changes|changes> command. + + Example: C<delete 'givenName'> + + =cut + + sub delete { + my $entries = $Globals->{ENTRIES}{VALUE}; + + _haveentries() or return 0; + + if (scalar @_ < 1) { + print STDERR "You must at least supply an attribute name.\n"; + return 0; + } + + my $attr = shift; + + map { $_->delete($attr, [@_]) } @$entries; return 1; } |
From: <j-d...@us...> - 2003-07-27 07:34:58
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv3039 Modified Files: Tag: PATCH-778364 ldapsh Log Message: Adds the "." expansion syntax (sets the search scope to 'base'). Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.20 retrieving revision 1.20.4.1 diff -C2 -d -r1.20 -r1.20.4.1 *** ldapsh 27 Jul 2003 07:03:01 -0000 1.20 --- ldapsh 27 Jul 2003 07:34:55 -0000 1.20.4.1 *************** *** 124,133 **** (composed of B<Net::LDAP::Entry> entries). ! =item 2. E<lt>functionE<gt> ['-r'] This is like the previous usage. The search filter is C<(objectclass=*)>. ! If the C<-r> option is used, the scope is I<sub>. ! Otherwise, the scope is I<one>. =item 3. E<lt>functionE<gt> $entries --- 124,135 ---- (composed of B<Net::LDAP::Entry> entries). ! =item 2. E<lt>functionE<gt> ['-r'|.] This is like the previous usage. The search filter is C<(objectclass=*)>. ! If neither C<-r> nor the dot (a.k.a. "full stop" or "period") is given, the ! scope is I<one>. If C<-r> is given, the scope is I<sub>. If the dot is ! given, the scope is I<base> (this can be used to match the I<current working ! directory> itself). =item 3. E<lt>functionE<gt> $entries *************** *** 463,472 **** push(@entries, @$spec); } else { ! my $searchedEntries = _search( ! BaseDN => $Globals->{CWD}{VALUE}, ! Scope => $Options->{r} ? 'sub' : 'one', ! Filter => $spec, ! Attribs => [] ! ); if (defined($searchedEntries)) { push(@entries, @$searchedEntries); --- 465,484 ---- push(@entries, @$spec); } else { ! my $searchedEntries; ! if ($spec =~ /^\.$/) { ! $searchedEntries = _search( ! BaseDN => $Globals->{CWD}{VALUE}, ! Scope => 'base', ! Filter => '(objectclass=*)', ! Attribs => [] ! ); ! } else { ! $searchedEntries = _search( ! BaseDN => $Globals->{CWD}{VALUE}, ! Scope => $Options->{r} ? 'sub' : 'one', ! Filter => $spec, ! Attribs => [] ! ); ! } if (defined($searchedEntries)) { push(@entries, @$searchedEntries); *************** *** 2080,2084 **** # The line below will quote some barewords such as "-l", "-a" etc... # It's not perfect, but simple ! while (s/([\s,])(-\w)([\s,]|$)/$1'$2'$3/g) {}; my $redir; --- 2092,2096 ---- # The line below will quote some barewords such as "-l", "-a" etc... # It's not perfect, but simple ! while (s/([\s,])(-\w|\.)([\s,]|$)/$1'$2'$3/g) {}; my $redir; |
From: <j-d...@us...> - 2003-07-27 07:25:26
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv1862 Modified Files: Tag: PATCH-778361 ldapsh Log Message: 1) Added PodHeadings class to extract headings from POD files. 2) Command completion is now available for "which" and "help". 3) "help" without arguments now displays a list of commands. To get all help (the old default), use "help all". Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.20 retrieving revision 1.20.2.1 diff -C2 -d -r1.20 -r1.20.2.1 *** ldapsh 27 Jul 2003 07:03:01 -0000 1.20 --- ldapsh 27 Jul 2003 07:25:23 -0000 1.20.2.1 *************** *** 510,513 **** --- 510,544 ---- } + package PodHeadings; + + use strict; + use vars qw(@ISA @EXPORT); + + @ISA = qw(Pod::Select); + + sub verbatim { } + + sub textblock { } + + sub interior_sequence { } + + sub command { + my ($self, $cmd, $text, $line_num, $pod_para) = @_; + ## Just treat this like a textblock + if ($cmd =~ /^head[12]/) { + ## Just treat this like a textblock + my $out_fh = $self->output_handle(); + print $out_fh "\n\n"; + $self->SUPER::textblock($pod_para->raw_text(), $line_num, $pod_para); + } + elsif ($cmd =~ /^head/) { + my $stripped = $pod_para->text(); + my $out_fh = $self->output_handle(); + $stripped =~ s/\s+$//; + print $out_fh $stripped." "; + } + } + + package ldapsh; ############################################################# *************** *** 526,534 **** ### Command completion ### if (substr($line, 0, $start) =~ /^\s*$/) { ! my $oldvalue = $TermAttribs->{completion_word}; ! $TermAttribs->{completion_word} = [_commandListGenerator()]; ! my @ret = $Term->completion_matches($text, $TermAttribs->{'list_completion_function'}); ! $TermAttribs->{completion_word} = $oldvalue; ! return @ret; } --- 557,561 ---- ### Command completion ### if (substr($line, 0, $start) =~ /^\s*$/) { ! return _commandCompletion(@_); } *************** *** 594,603 **** ######################################### ! ### DN Completion ### my $line2 = $line; $line2 =~ s/^\s+//; my ($cmd, $rest) = split(/\s+/, $line2, 2); if ($cmd =~ /^(cd|acd|setdn|pushd|cat|vi|ls|list|dump|ldif|search|cp)$/) { return _cdCommandCompletion(@_); } else { return(); --- 621,634 ---- ######################################### ! ### Parameter Completion ### my $line2 = $line; $line2 =~ s/^\s+//; my ($cmd, $rest) = split(/\s+/, $line2, 2); if ($cmd =~ /^(cd|acd|setdn|pushd|cat|vi|ls|list|dump|ldif|search|cp)$/) { + # DN Completion return _cdCommandCompletion(@_); + } elsif ($cmd =~ /^(help|which)$/) { + # Command Completion + return _commandCompletion(@_); } else { return(); *************** *** 610,613 **** --- 641,653 ---- } + sub _commandCompletion { + my ($text, $line, $start, $end) = @_; + my $oldvalue = $TermAttribs->{completion_word}; + $TermAttribs->{completion_word} = [_commandListGenerator()]; + my @ret = $Term->completion_matches($text, $TermAttribs->{'list_completion_function'}); + $TermAttribs->{completion_word} = $oldvalue; + return @ret; + } + sub _cdCommandCompletion { _bindneeded() or return (); *************** *** 741,747 **** =head3 help ! B<Synopsis>: C<help [E<lt>commandE<gt>]> ! Print some help on the given command (or a global help if no command is given). =cut --- 781,788 ---- =head3 help ! B<Synopsis>: C<help ['E<lt>commandE<gt>'|'all']> ! Display help about the given command (or global help, if 'all' is given). ! If no parameter is given, a summary of commands will be shown. =cut *************** *** 760,764 **** $parser = new Pod::Text::Termcap; } ! if (defined($cmd)) { require Pod::Select; require File::Temp; --- 801,808 ---- $parser = new Pod::Text::Termcap; } ! if (defined($cmd) && $cmd eq "all") { ! $parser->parse_from_file($0, \*STDERR); ! } ! else { require Pod::Select; require File::Temp; *************** *** 769,797 **** push(@docfiles, $Opts->{RCFile}) if (-r $Opts->{RCFile}); foreach my $file (@docfiles) { Pod::Select::podselect( { ! -output => $podfile, ! -sections => [ ! "DESCRIPTION/$cmd\\b.*", ! "COMMANDS/${cmd}\\b.*", ! "COMMANDS/.*/${cmd}" ! ] ! }, ! $file ! ); ! if (-s $podfile) { ! print STDERR "\n------------------------------\n"; ! $parser->parse_from_file($podfile, \*STDERR); ! print STDERR "\n------------------------------\n"; ! $found = 1; ! last; } } if (! $found) { ! print STDERR "No help found on '$cmd'.\n"; } unlink $podfile; - } else { - $parser->parse_from_file($0, \*STDERR); } return 1; --- 813,849 ---- push(@docfiles, $Opts->{RCFile}) if (-r $Opts->{RCFile}); foreach my $file (@docfiles) { + if (defined($cmd)) { Pod::Select::podselect( { ! -output => $podfile, ! -sections => [ ! "DESCRIPTION/$cmd\\b.*", ! "COMMANDS/${cmd}\\b.*", ! "COMMANDS/.*/${cmd}" ! ] ! }, $file); ! } ! else { ! my $headings = new PodHeadings(); ! $headings->select("COMMANDS"); ! $headings->parse_from_file($file, $podfile); ! } ! if (-s $podfile) { ! print STDERR "------------------------------\n"; ! $parser->parse_from_file($podfile, \*STDERR); ! print STDERR "------------------------------\n"; ! $found = 1; ! last; } } if (! $found) { ! if (defined($cmd)) { ! print STDERR "No help found for '$cmd'.\n"; ! } ! else { ! print STDERR "No help found.\n"; ! } } unlink $podfile; } return 1; |
From: <j-d...@us...> - 2003-07-27 07:03:04
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv31584 Modified Files: ldapsh Log Message: Define _haventries for uniform reporting of empty $ENTRIES. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** ldapsh 27 Jul 2003 06:56:36 -0000 1.19 --- ldapsh 27 Jul 2003 07:03:01 -0000 1.20 *************** *** 368,371 **** --- 368,379 ---- } + sub _haveentries { + my $entries = shift || $Globals->{ENTRIES}{VALUE}; + unless (defined($entries) && scalar(@{$entries}) > 0) { + print STDERR "No entries defined. Have you forgotten to do a search prior to changing anything?\n"; + return undef; + } + } + # Search with Connection error checking, and try to reconnect if disconnected sub _searchWEC { *************** *** 1628,1635 **** my $entries = shift || $Globals->{ENTRIES}{VALUE}; ! unless (defined($entries)) { ! print STDERR "No entries defined. Have you forgot to do a search prior to change anything?\n"; ! return 0; ! } map { &$code; } @$entries; --- 1636,1640 ---- my $entries = shift || $Globals->{ENTRIES}{VALUE}; ! _haveentries($entries) or return 0; map { &$code; } @$entries; *************** *** 1649,1656 **** my $entries = shift || $Globals->{ENTRIES}{VALUE}; ! unless (defined($entries)) { ! print STDERR "No entries defined. Have you forgot to do a search prior to change anything?\n"; ! return 0; ! } my $nbchanges = 0; --- 1654,1658 ---- my $entries = shift || $Globals->{ENTRIES}{VALUE}; ! _haveentries($entries); my $nbchanges = 0; *************** *** 1698,1705 **** my $entries = shift || $Globals->{ENTRIES}{VALUE}; ! unless (defined($entries)) { ! print STDERR "No entries defined. Have you forgot to do a search prior to change anything?\n"; ! return 0; ! } my $result; --- 1700,1704 ---- my $entries = shift || $Globals->{ENTRIES}{VALUE}; ! _haveentries($entries) or return 0; my $result; *************** *** 1804,1811 **** my $entries = shift || $Globals->{ENTRIES}{VALUE}; ! unless (defined($entries)) { ! print STDERR "No entries defined. Have you forgot to do a search prior to change anything?\n"; ! return 0; ! } my $nbentries = scalar(@$entries); --- 1803,1807 ---- my $entries = shift || $Globals->{ENTRIES}{VALUE}; ! _haveentries($entries) or return 0; my $nbentries = scalar(@$entries); *************** *** 1860,1867 **** if (scalar(@_) == 1) { $entries = $Globals->{ENTRIES}{VALUE}; ! unless (defined($entries)) { ! print STDERR "No entries defined. Have you forgot to do a search prior to exclude something from the results?\n"; ! return undef; ! } $regexp = shift; } elsif (scalar(@_) == 2) { --- 1856,1860 ---- if (scalar(@_) == 1) { $entries = $Globals->{ENTRIES}{VALUE}; ! _haveentries($entries) or return undef; $regexp = shift; } elsif (scalar(@_) == 2) { *************** *** 1882,1888 **** if ($counter) { ! printf STDERR "-----\n%d %s excluded\n", $counter, ($counter > 1 ? 'entries' : 'entry'); } else { ! printf STDERR ">> No entry matched the regular expression\n\n"; } return $entries; --- 1875,1881 ---- if ($counter) { ! printf STDERR "-----\n%d %s excluded.\n", $counter, ($counter > 1 ? 'entries' : 'entry'); } else { ! printf STDERR ">> No entries matched the regular expression.\n"; } return $entries; |
From: <j-d...@us...> - 2003-07-27 06:56:39
|
Update of /cvsroot/ldapsh/ldapsh In directory sc8-pr-cvs1:/tmp/cvs-serv30799 Modified Files: ldapsh Log Message: 1) Fixed spelling in diagnostic messages. 2) Now using consistent punctuation for diagnostic messages. 3) splitdn($$) renamed _splitdn($$) and moved to "utility functions" section. 4) "version" command now outputs ldapsh's SourceForge web address. 5) Fixed _entriesExpander for "csv" command. Index: ldapsh =================================================================== RCS file: /cvsroot/ldapsh/ldapsh/ldapsh,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** ldapsh 27 Jul 2003 06:30:55 -0000 1.18 --- ldapsh 27 Jul 2003 06:56:36 -0000 1.19 *************** *** 354,358 **** if ($Globals->{LDAPCONN}{VALUE}) { unless($Globals->{LDAPCONN}{VALUE}{net_ldap_socket}->connected()) { ! print STDERR "\nConnection lost. Trying to reconnect\n"; undef $Globals->{_EFFECTIVECONNPARAMS}{VALUE}{BINDDN}; return 0 unless connect(); --- 354,358 ---- if ($Globals->{LDAPCONN}{VALUE}) { unless($Globals->{LDAPCONN}{VALUE}{net_ldap_socket}->connected()) { ! print STDERR "\nConnection lost. Trying to reconnect.\n"; undef $Globals->{_EFFECTIVECONNPARAMS}{VALUE}{BINDDN}; return 0 unless connect(); *************** *** 439,443 **** push @Specs, $_; } elsif (ref ($_)) { ! print STDERR "The argument passed as a reference is unknown\n"; return undef; } else { --- 439,443 ---- push @Specs, $_; } elsif (ref ($_)) { ! print STDERR "The argument passed as a reference is unknown.\n"; return undef; } else { *************** *** 464,468 **** push(@entries, @$searchedEntries); } else { ! print STDERR "\nError while searching according to filter '$spec'\n"; } } --- 464,468 ---- push(@entries, @$searchedEntries); } else { ! print STDERR "\nError while searching according to filter '$spec'.\n"; } } *************** *** 492,500 **** return 1; } else { ! print STDERR "No help found\n"; return 0; } } ############################################################# --- 492,505 ---- return 1; } else { ! print STDERR "No help found.\n"; return 0; } } + sub _splitdn($$) { + return (undef, undef) unless defined $_[0]; + split(/\s*,\s*/, shift, shift); + } + ############################################################# *************** *** 718,722 **** B<Synopsis>: C<which 'E<lt>commandE<gt>'> ! A synonym for L<help|help>. =cut --- 723,727 ---- B<Synopsis>: C<which 'E<lt>commandE<gt>'> ! A synonym for L<help E<lt>commandE<gt>|help>. =cut *************** *** 776,780 **** } if (! $found) { ! print STDERR "No help found on '$cmd'\n\n"; } unlink $podfile; --- 781,785 ---- } if (! $found) { ! print STDERR "No help found on '$cmd'.\n"; } unlink $podfile; *************** *** 793,797 **** sub version() { ! printf STDERR "LDAP Shell (ldapsh) by Rafael Corvalan.\nCVS File ID: %s\nShell release: %s\n\n", '$Id$', $RELEASE; } --- 798,802 ---- sub version() { ! printf STDERR "LDAP Shell (ldapsh) by Rafael Corvalan.\nCVS File ID: %s\nShell release: %s\nhttp://ldapsh.sourceforge.net/\n", '$Id$', $RELEASE; } *************** *** 908,912 **** # We will read the password, we need some privacy... ! # If we have Gnu ReadLine, we use it with it's ShadowRedisplay feature # Otherwise, we will use Term::ReadKey if (_isGnuReadLine and defined($attribs->{shadow_redisplay})) { --- 913,917 ---- # We will read the password, we need some privacy... ! # If we have Gnu ReadLine, we use it with its ShadowRedisplay feature # Otherwise, we will use Term::ReadKey if (_isGnuReadLine and defined($attribs->{shadow_redisplay})) { *************** *** 932,936 **** ); } else { ! print STDERR "Warning: Binding as anonymous\n"; $result = $Globals->{LDAPCONN}{VALUE}->bind( anonymous => 1, --- 937,941 ---- ); } else { ! print STDERR "Warning: Binding anonymously.\n"; $result = $Globals->{LDAPCONN}{VALUE}->bind( anonymous => 1, *************** *** 1084,1092 **** - sub splitdn($$) { - return (undef, undef) unless defined $_[0]; - split(/\s*,\s*/, shift, shift); - } - =head3 rdn --- 1089,1092 ---- *************** *** 1099,1103 **** sub rdn($) { ! my ($rdn) = splitdn(shift, 2); return $rdn; } --- 1099,1103 ---- sub rdn($) { ! my ($rdn) = _splitdn(shift, 2); return $rdn; } *************** *** 1130,1134 **** my $BasePath = $Globals->{CWD}{VALUE}; while ($SubPath =~ s/(?:,|^)\s*\.\.\s*$//) { ! (undef, $BasePath) = splitdn($BasePath, 2); unless ($BasePath) { print STDERR "Cannot go up on the directory tree!\n"; --- 1130,1134 ---- my $BasePath = $Globals->{CWD}{VALUE}; while ($SubPath =~ s/(?:,|^)\s*\.\.\s*$//) { ! (undef, $BasePath) = _splitdn($BasePath, 2); unless ($BasePath) { print STDERR "Cannot go up on the directory tree!\n"; *************** *** 1165,1169 **** if (_isReallyLDAPError($result->code)) { if ($result->code == Net::LDAP::Constant::LDAP_NO_SUCH_OBJECT) { ! print STDERR "Cannot change BaseDN. No such subpath\n"; return 0; } else { --- 1165,1169 ---- if (_isReallyLDAPError($result->code)) { if ($result->code == Net::LDAP::Constant::LDAP_NO_SUCH_OBJECT) { ! print STDERR "Cannot change BaseDN. No such subpath.\n"; return 0; } else { *************** *** 1210,1214 **** if ($status) { unshift(@{$Globals->{_DIRSSTACK}{VALUE}}, $cwd); ! print STDERR "Old working directory: '$cwd'\n\n"; } return $status; --- 1210,1214 ---- if ($status) { unshift(@{$Globals->{_DIRSSTACK}{VALUE}}, $cwd); ! print STDERR "Old working directory: '$cwd'\n"; } return $status; *************** *** 1235,1242 **** my $status = setdn($nwd); if ($status) { ! print STDERR "New working directory: '$nwd'\n\n"; } } else { ! print STDERR "The directories stack is empty\n\n"; $status = 0; } --- 1235,1242 ---- my $status = setdn($nwd); if ($status) { ! print STDERR "New working directory: '$nwd'.\n"; } } else { ! print STDERR "The directory stack is empty.\n"; $status = 0; } *************** *** 1338,1343 **** if (defined($entries)) { my ($n1, $n2) = (scalar(@$entries), scalar(@{$Globals->{ENTRIES}{VALUE}})); ! print STDERR "$n1 entries found\n"; ! print STDERR "$n2 entries in \$ENTRIES\n" if ($n1 != $n2); } --- 1338,1343 ---- if (defined($entries)) { my ($n1, $n2) = (scalar(@$entries), scalar(@{$Globals->{ENTRIES}{VALUE}})); ! print STDERR "$n1 entries found.\n"; ! print STDERR "$n2 entries in \$ENTRIES.\n" if ($n1 != $n2); } *************** *** 1363,1368 **** if (defined($entries)) { my ($n1, $n2) = (scalar(@$entries), scalar(@{$Globals->{ENTRIES}{VALUE}})); ! print STDERR "$n1 entries found\n"; ! print STDERR "$n2 entries in \$ENTRIES\n" if ($n1 != $n2); } --- 1363,1368 ---- if (defined($entries)) { my ($n1, $n2) = (scalar(@$entries), scalar(@{$Globals->{ENTRIES}{VALUE}})); ! print STDERR "$n1 entries found.\n"; ! print STDERR "$n2 entries in \$ENTRIES.\n" if ($n1 != $n2); } *************** *** 1514,1518 **** sub csv { my $localArgs = {fs => ';', vs => '|', 'mv' => 1, 'dn' => 0}; ! my $entries = _entriesExpander [$localArgs, 'dn', 'fs=s', 'vs=s', 'mv!', 'dn!'], @_; return 0 unless defined $entries; --- 1514,1518 ---- sub csv { my $localArgs = {fs => ';', vs => '|', 'mv' => 1, 'dn' => 0}; ! my $entries = _entriesExpander [$localArgs, 'fs=s', 'vs=s', 'mv!', 'dn!'], @_; return 0 unless defined $entries; *************** *** 1560,1564 **** printf("%s\n", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); } ! print STDERR "-----\n" . scalar(@$entries) . " entries found\n"; return 1; --- 1560,1564 ---- printf("%s\n", $localArgs->{'l'} ? $entry->dn : rdn($entry->dn)); } ! print STDERR "-----\n" . scalar(@$entries) . " entries found.\n"; return 1; *************** *** 1672,1676 **** printf STDERR (qq{\t>>> Replace attribute '%s' with values: %s\n}, $data->[0], $attributes); } elsif ($action eq 'delete') { ! printf STDERR (qq{\t>>> Deleted attribute '%s'\n}, $data->[0]); } else { printf STDERR (qq{\t>>> Don't know the action '%s'\n}, $action); --- 1672,1676 ---- printf STDERR (qq{\t>>> Replace attribute '%s' with values: %s\n}, $data->[0], $attributes); } elsif ($action eq 'delete') { ! printf STDERR (qq{\t>>> Delete attribute '%s'\n}, $data->[0]); } else { printf STDERR (qq{\t>>> Don't know the action '%s'\n}, $action); *************** *** 1681,1687 **** if ($nbchanges) { ! print STDERR '=' x 40 . "\n$nbchanges entries to commit\n"; } else { ! print STDERR "No entries to commit\n"; } } --- 1681,1687 ---- if ($nbchanges) { ! print STDERR '=' x 40 . "\n$nbchanges entries to commit.\n"; } else { ! print STDERR "No entries to commit.\n"; } } *************** *** 1751,1755 **** my ($from, $to) = @_; $from = undef if ($from eq "*"); ! my $localcopy = (scalar(splitdn($to,2)) == 1); #I.e $to is an RDN. my $entries = _entriesExpander undef, $from; if (scalar(@$entries) != 1 && $localcopy) { --- 1751,1755 ---- my ($from, $to) = @_; $from = undef if ($from eq "*"); ! my $localcopy = (scalar(_splitdn($to,2)) == 1); #I.e $to is an RDN. my $entries = _entriesExpander undef, $from; if (scalar(@$entries) != 1 && $localcopy) { *************** *** 1759,1764 **** foreach my $entry (@$entries) { ! my ($oldrdn, $oldpath) = splitdn($entry->dn, 2); ! my ($newrdn) = splitdn($to, 2); my ($old_rdn_attr, $old_rdn_attr_val) = split("=", $oldrdn, 2); my ($new_rdn_attr, $new_rdn_attr_val) = split("=", $newrdn, 2); --- 1759,1764 ---- foreach my $entry (@$entries) { ! my ($oldrdn, $oldpath) = _splitdn($entry->dn, 2); ! my ($newrdn) = _splitdn($to, 2); my ($old_rdn_attr, $old_rdn_attr_val) = split("=", $oldrdn, 2); my ($new_rdn_attr, $new_rdn_attr_val) = split("=", $newrdn, 2); *************** *** 1868,1872 **** ($entries, $regexp) = @_; } else { ! print STDERR "Usage error\n"; return undef; } --- 1868,1872 ---- ($entries, $regexp) = @_; } else { ! print STDERR "Usage error.\n"; return undef; } *************** *** 2040,2044 **** return $var->{VALUE}; } else { ! print STDERR "You have no rights to fetch this value\n"; return undef; } --- 2040,2044 ---- return $var->{VALUE}; } else { ! print STDERR "You have no rights to fetch this value.\n"; return undef; } *************** *** 2053,2057 **** return($var->{VALUE} = $value); } else { ! print STDERR "You have no rights to set this value\n"; return undef; } --- 2053,2057 ---- return($var->{VALUE} = $value); } else { ! print STDERR "You have no rights to set this value.\n"; return undef; } |