[LDAPsh-cvs] ldapsh ldapsh,1.26,1.26.4.1
Status: Beta
Brought to you by:
rcorvalan
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); + } |