Multiple help-related changes
- Make every command's POD doc have a single-line introductory description. This help is then used as a one-liner summary in Term::Shell. - Tie %cmd_map to IxHash to preserve hash elements' order. - Fix bug in Term::Shell's code related to command aliases. (Also emailed Term::Shell author to include the fix in next release.) - Remove run_() which already exists in Term::Shell. - Use Term::Shell's help facilities instead of manually redefining run_help() and other related commands. The complete POD documentation is still available for viewing if user invokes ./shelldap --help. - Completer functions are disabled right now (fix coming in the next commit) FossilOrigin-Name: a3bfbcceb8e471a3397b5e90cfe9bd0fa7ebe84934de738e34bc620a24f7fe5c
This commit is contained in:
parent
c89d193e53
commit
c08875fa11
1 changed files with 147 additions and 75 deletions
222
shelldap
222
shelldap
|
|
@ -242,7 +242,9 @@ Display the version number.
|
||||||
|
|
||||||
=head2 cat
|
=head2 cat
|
||||||
|
|
||||||
Display LDIF dump of an entry. Globbing is supported. Specify either full DN, or a RDN.
|
Print contents of LDAP entry to STDOUT in LDIF format.
|
||||||
|
|
||||||
|
Globbing is supported. Specify either full DN, or a RDN.
|
||||||
RDNs are local to the current search base ('cwd' in shell terms). If RDN is '.' or missing,
|
RDNs are local to the current search base ('cwd' in shell terms). If RDN is '.' or missing,
|
||||||
it defaults to the current search base.
|
it defaults to the current search base.
|
||||||
You may additionally add a list of attributes to display (e.g. use '+' for operational
|
You may additionally add a list of attributes to display (e.g. use '+' for operational
|
||||||
|
|
@ -257,11 +259,13 @@ option.
|
||||||
|
|
||||||
=head2 less
|
=head2 less
|
||||||
|
|
||||||
Like cat, but uses the configured pager to display output.
|
Like 'cat', but use configured pager to paginate output.
|
||||||
|
|
||||||
=head2 cd
|
=head2 cd
|
||||||
|
|
||||||
Change directory. Translated to LDAP, this changes the current basedn.
|
Change the working directory (LDAP search base).
|
||||||
|
|
||||||
|
Translated to LDAP, this changes the current basedn.
|
||||||
All commands after a 'cd' operate within the new basedn.
|
All commands after a 'cd' operate within the new basedn.
|
||||||
|
|
||||||
cd change to 'home' (binddn if any, or basedn)
|
cd change to 'home' (binddn if any, or basedn)
|
||||||
|
|
@ -282,11 +286,17 @@ any entry. Many commands then work on '.' or default to '.', meaning
|
||||||
|
|
||||||
=head2 clear
|
=head2 clear
|
||||||
|
|
||||||
Clear the screen.
|
Clear the terminal screen.
|
||||||
|
|
||||||
|
Clears screen similar to 'clear' or Ctrl+l on the shell command line.
|
||||||
|
|
||||||
|
Ctrl+l alias is also supported.
|
||||||
|
|
||||||
=head2 copy
|
=head2 copy
|
||||||
|
|
||||||
Copy an entry to a different DN path. All copies are relative to the
|
Copy an entry.
|
||||||
|
|
||||||
|
All copies are relative to the
|
||||||
current basedn unless a full DN is specified. All attributes are
|
current basedn unless a full DN is specified. All attributes are
|
||||||
copied and then an LDAP moddn() is performed.
|
copied and then an LDAP moddn() is performed.
|
||||||
|
|
||||||
|
|
@ -298,7 +308,9 @@ aliased to: cp
|
||||||
|
|
||||||
=head2 create
|
=head2 create
|
||||||
|
|
||||||
Create an entry from scratch. Arguments are space separated objectClass
|
Create an entry.
|
||||||
|
|
||||||
|
Arguments are space separated objectClass
|
||||||
names. Possible objectClasses are derived automatically from the
|
names. Possible objectClasses are derived automatically from the
|
||||||
server, and will tab-complete.
|
server, and will tab-complete.
|
||||||
|
|
||||||
|
|
@ -313,7 +325,9 @@ aliased to: touch
|
||||||
|
|
||||||
=head2 delete
|
=head2 delete
|
||||||
|
|
||||||
Remove an entry from the directory. Globbing is supported.
|
Remove an entry.
|
||||||
|
|
||||||
|
Globbing is supported.
|
||||||
All deletes are sanity-prompted. The -v flag prints the entries out
|
All deletes are sanity-prompted. The -v flag prints the entries out
|
||||||
for review before delete.
|
for review before delete.
|
||||||
|
|
||||||
|
|
@ -325,7 +339,9 @@ aliased to: rm
|
||||||
|
|
||||||
=head2 edit
|
=head2 edit
|
||||||
|
|
||||||
Edit an entry in an external editor. After the editor exits, the
|
Edit an entry in an external editor.
|
||||||
|
|
||||||
|
After the editor exits, the
|
||||||
resulting LDIF is sanity checked, and changes are written to the LDAP
|
resulting LDIF is sanity checked, and changes are written to the LDAP
|
||||||
directory.
|
directory.
|
||||||
|
|
||||||
|
|
@ -335,11 +351,15 @@ aliased to: vi
|
||||||
|
|
||||||
=head2 env
|
=head2 env
|
||||||
|
|
||||||
Show values for various runtime variables.
|
Print values of configurable shelldap variables.
|
||||||
|
|
||||||
|
This is a subset of all variables configurable via shelldap config
|
||||||
|
file and/or its command line options.
|
||||||
|
|
||||||
=head2 grep
|
=head2 grep
|
||||||
|
|
||||||
Search for arbitrary LDAP filters, and return matching DN results.
|
Search using LDAP filters and return matching DN results.
|
||||||
|
|
||||||
The search string must be a valid LDAP filter.
|
The search string must be a valid LDAP filter.
|
||||||
|
|
||||||
grep uid=mahlon
|
grep uid=mahlon
|
||||||
|
|
@ -350,8 +370,9 @@ The search string must be a valid LDAP filter.
|
||||||
|
|
||||||
=head2 inspect
|
=head2 inspect
|
||||||
|
|
||||||
View schema information about a given entry, or a list of arbitrary
|
View schema and flags for an entry or objectClass.
|
||||||
objectClasses, along with the most common flags for the objectClass
|
|
||||||
|
It also includes the most common flags for the objectClass
|
||||||
attributes.
|
attributes.
|
||||||
|
|
||||||
inspect uid=mahlon
|
inspect uid=mahlon
|
||||||
|
|
@ -369,7 +390,9 @@ is dumped to screen.
|
||||||
|
|
||||||
=head2 list
|
=head2 list
|
||||||
|
|
||||||
List entries for the current basedn. Globbing is supported.
|
List directory contents.
|
||||||
|
|
||||||
|
Globbing is supported.
|
||||||
|
|
||||||
aliased to: ls
|
aliased to: ls
|
||||||
|
|
||||||
|
|
@ -391,19 +414,23 @@ types. You can additionally specify your own mappings in your
|
||||||
|
|
||||||
=head2 mkdir
|
=head2 mkdir
|
||||||
|
|
||||||
Creates a new 'organizationalUnit' entry.
|
Create a new 'organizationalUnit' LDAP entry.
|
||||||
|
|
||||||
mkdir containername
|
mkdir containername
|
||||||
mkdir ou=whatever
|
mkdir ou=whatever
|
||||||
|
|
||||||
=head2 move
|
=head2 move
|
||||||
|
|
||||||
Move an entry to a different dn path. Usage is identical to B<copy>.
|
Move (rename) entry.
|
||||||
|
|
||||||
|
Usage is identical to B<copy>.
|
||||||
|
|
||||||
aliased to: mv
|
aliased to: mv
|
||||||
|
|
||||||
=head2 passwd
|
=head2 passwd
|
||||||
|
|
||||||
|
Change user password.
|
||||||
|
|
||||||
If supported server side, change the password for a specified entry.
|
If supported server side, change the password for a specified entry.
|
||||||
The entry must have a 'userPassword' attribute.
|
The entry must have a 'userPassword' attribute.
|
||||||
|
|
||||||
|
|
@ -411,22 +438,22 @@ The entry must have a 'userPassword' attribute.
|
||||||
|
|
||||||
=head2 pwd
|
=head2 pwd
|
||||||
|
|
||||||
Print the 'working directory' - aka, the current ldap basedn.
|
Print name of current/working LDAP search base.
|
||||||
|
|
||||||
=head2 setenv
|
=head2 setenv
|
||||||
|
|
||||||
Modify various runtime variables normally set from the command line.
|
Change or define shelldap variable.
|
||||||
|
|
||||||
setenv debug 1
|
setenv debug 1
|
||||||
export debug=1
|
export debug=1
|
||||||
|
|
||||||
=head2 whoami
|
=head2 whoami
|
||||||
|
|
||||||
|
Print current bind DN.
|
||||||
|
|
||||||
Show current auth credentials. Unless you specified a binddn, this
|
Show current auth credentials. Unless you specified a binddn, this
|
||||||
will just show an anonymous bind.
|
will just show an anonymous bind.
|
||||||
|
|
||||||
aliased to: id
|
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head1 TODO
|
=head1 TODO
|
||||||
|
|
@ -486,6 +513,7 @@ use File::Temp qw//;
|
||||||
use Algorithm::Diff qw//;
|
use Algorithm::Diff qw//;
|
||||||
use Carp 'confess';
|
use Carp 'confess';
|
||||||
use POSIX qw//;
|
use POSIX qw//;
|
||||||
|
use Tie::IxHash qw//;
|
||||||
use base 'Term::Shell';
|
use base 'Term::Shell';
|
||||||
|
|
||||||
my $conf = $main::conf;
|
my $conf = $main::conf;
|
||||||
|
|
@ -494,6 +522,55 @@ my $conf = $main::conf;
|
||||||
$SIG{'__DIE__'} = \&Carp::confess if $conf->{'debug'};
|
$SIG{'__DIE__'} = \&Carp::confess if $conf->{'debug'};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
### Term::Shell Fixes
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
# Term::Shell function add_handlers() is implemented in an incorrect way.
|
||||||
|
# We reimplement the method here to fix its problems.
|
||||||
|
|
||||||
|
# In add_handlers, we split searching for aliases in a separate loop,
|
||||||
|
# because otherwise not all aliases are registered before we look them
|
||||||
|
# up.
|
||||||
|
sub add_handlers
|
||||||
|
{
|
||||||
|
my $o = shift;
|
||||||
|
for my $hnd (@_)
|
||||||
|
{
|
||||||
|
next unless $hnd =~ /^(run|help|smry|comp|catch|alias)_/o;
|
||||||
|
my $t = $1;
|
||||||
|
my $a = substr( $hnd, length($t) + 1 );
|
||||||
|
|
||||||
|
# Add on the prefix and suffix if the command is defined
|
||||||
|
if ( length $a )
|
||||||
|
{
|
||||||
|
substr( $a, 0, 0 ) = $o->cmd_prefix;
|
||||||
|
$a .= $o->cmd_suffix;
|
||||||
|
}
|
||||||
|
$o->{handlers}{$a}{$t} = $hnd;
|
||||||
|
}
|
||||||
|
for my $hnd (@_)
|
||||||
|
{
|
||||||
|
next unless $hnd =~ /^(run|help|smry|comp|catch|alias)_/o;
|
||||||
|
my $t = $1;
|
||||||
|
my $a = substr( $hnd, length($t) + 1 );
|
||||||
|
|
||||||
|
if ( $o->has_aliases($a) )
|
||||||
|
{
|
||||||
|
my @a = $o->get_aliases($a);
|
||||||
|
for my $alias (@a)
|
||||||
|
{
|
||||||
|
substr( $alias, 0, 0 ) = $o->cmd_prefix;
|
||||||
|
$alias .= $o->cmd_suffix;
|
||||||
|
$o->{handlers}{$alias}{$t} = $hnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
### U T I L I T Y F U N C T I O N S
|
### U T I L I T Y F U N C T I O N S
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
@ -1379,9 +1456,10 @@ sub diff {
|
||||||
#
|
#
|
||||||
# It is not necessary to list all real commands here, but you can/should
|
# It is not necessary to list all real commands here, but you can/should
|
||||||
# do so to assign autocompleter function to them, and/or to define aliases.
|
# do so to assign autocompleter function to them, and/or to define aliases.
|
||||||
my %cmd_map = (
|
tie my %cmd_map, 'Tie::IxHash';
|
||||||
#'whoami' => [ undef ],
|
%cmd_map = (
|
||||||
#'pwd' => [ undef ],
|
'whoami' => [ undef ],
|
||||||
|
'pwd' => [ undef ],
|
||||||
'list' => [ undef, 'comp_cwd' ],
|
'list' => [ undef, 'comp_cwd' ],
|
||||||
'grep' => [ undef, 'comp_cwd' ],
|
'grep' => [ undef, 'comp_cwd' ],
|
||||||
'edit' => [ undef, 'comp_cwd' ],
|
'edit' => [ undef, 'comp_cwd' ],
|
||||||
|
|
@ -1393,11 +1471,11 @@ my %cmd_map = (
|
||||||
'cd' => [ undef, 'comp_cwd' ],
|
'cd' => [ undef, 'comp_cwd' ],
|
||||||
'create' => [ undef, 'comp_create' ],
|
'create' => [ undef, 'comp_create' ],
|
||||||
'setenv' => [ undef, 'comp_setenv' ],
|
'setenv' => [ undef, 'comp_setenv' ],
|
||||||
#'passwd' => [ undef ],
|
'passwd' => [ undef ],
|
||||||
##'clear' => [ undef ],
|
'clear' => [ undef ],
|
||||||
#'env' => [ undef ],
|
'env' => [ undef ],
|
||||||
#'help' => [ undef ],
|
#'help' => [ undef ],
|
||||||
#'mkdir' => [ undef ],
|
'mkdir' => [ undef ],
|
||||||
'inspect' => [ undef, 'comp_inspect' ],
|
'inspect' => [ undef, 'comp_inspect' ],
|
||||||
|
|
||||||
'id' => [ 'whoami' ],
|
'id' => [ 'whoami' ],
|
||||||
|
|
@ -1415,11 +1493,6 @@ my %cmd_map = (
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
### Don't die on a newline, just no-op.
|
|
||||||
###
|
|
||||||
sub run_ { return; }
|
|
||||||
|
|
||||||
|
|
||||||
### Term::Shell hook.
|
### Term::Shell hook.
|
||||||
### Write history for each command, print shell debug actions.
|
### Write history for each command, print shell debug actions.
|
||||||
###
|
###
|
||||||
|
|
@ -1928,28 +2001,6 @@ sub run_grep
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
### Override internal help function with pod2usage output.
|
|
||||||
###
|
|
||||||
sub run_help
|
|
||||||
{
|
|
||||||
my $self = shift;
|
|
||||||
my $section = 'SHELL COMMANDS';
|
|
||||||
|
|
||||||
my $command = shift;
|
|
||||||
if( $command ) {
|
|
||||||
# If it is an alias, resolve to real name:
|
|
||||||
$command = $cmd_map{$command}[0] if $cmd_map{$command}[0];
|
|
||||||
$section .= "/$command"
|
|
||||||
}
|
|
||||||
|
|
||||||
return Pod::Usage::pod2usage(
|
|
||||||
-exitval => 'NOEXIT',
|
|
||||||
-verbose => 99,
|
|
||||||
-sections => $section
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
### Generate and display a list of LDAP entries, relative to the current
|
### Generate and display a list of LDAP entries, relative to the current
|
||||||
### location the command was run from.
|
### location the command was run from.
|
||||||
###
|
###
|
||||||
|
|
@ -2352,26 +2403,47 @@ sub run_inspect
|
||||||
|
|
||||||
### Inject various autocomplete and alias routines into the symbol table.
|
### Inject various autocomplete and alias routines into the symbol table.
|
||||||
###
|
###
|
||||||
|
|
||||||
# setup alias subs
|
|
||||||
#
|
|
||||||
# Term::Shell has an alias_* feature, but
|
|
||||||
# it seems to work about 90% of the time.
|
|
||||||
# that last 10% is something of a mystery.
|
|
||||||
#
|
|
||||||
{ no strict 'refs';
|
{ no strict 'refs';
|
||||||
while(my($cmd, $data) = each %cmd_map ) {
|
local $| = 1;
|
||||||
if( $$data[0]) {
|
my %aliases;
|
||||||
my $alias_sub = 'run_' . $cmd;
|
|
||||||
my $real_sub = 'run_' . $$data[0];
|
|
||||||
*$alias_sub = \&$real_sub;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( $$data[1]) {
|
while(my($cmd, $data) = each %cmd_map ) {
|
||||||
my $comp_sub = "comp_$cmd";
|
# If command is an alias, insert alias symbol.
|
||||||
*$comp_sub = \&{$$data[1]}
|
if( $$data[0]) {
|
||||||
|
$aliases{$$data[0]} ||= [];
|
||||||
|
push @{$aliases{$$data[0]}}, $cmd;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
## If completer is defined, set it.
|
||||||
|
#if( $$data[1]) {
|
||||||
|
# my $comp_sub = "comp_$cmd";
|
||||||
|
# *$comp_sub = \&{$$data[1]}
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Define help and summary functions for the command:
|
||||||
|
my $pod = ''; open my $io, '>', \$pod;
|
||||||
|
Pod::Usage::pod2usage( -exitval => 'NOEXIT', -verbose => 99, -sections => "SHELL COMMANDS/${\( quotemeta $cmd )}", -output => \*$io );
|
||||||
|
my @pod = split /\n/, $pod;
|
||||||
|
my $summary = $pod[1];
|
||||||
|
if($summary) {
|
||||||
|
$summary =~ s/^\s+//s;
|
||||||
|
$summary =~ s/\s+$//s;
|
||||||
|
$summary =~ s/\s+/ /s;
|
||||||
|
}
|
||||||
|
my $help = join "\n", @pod;
|
||||||
|
|
||||||
|
my $helpfunc = sub { "$help\n" };
|
||||||
|
*{"help_$cmd"} = \&$helpfunc;
|
||||||
|
|
||||||
|
my $summfunc = sub { $summary };
|
||||||
|
*{"smry_$cmd"} = \&$summfunc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(my($cmd,$aliases) = each %aliases) {
|
||||||
|
my $aliasfunc = sub { @$aliases };
|
||||||
|
*{"alias_$cmd"} = \&$aliasfunc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2432,10 +2504,10 @@ Getopt::Long::GetOptions(
|
||||||
'tls_key=s',
|
'tls_key=s',
|
||||||
'tls', 'debug', 'version',
|
'tls', 'debug', 'version',
|
||||||
help => sub {
|
help => sub {
|
||||||
Pod::Usage::pod2usage(
|
Pod::Usage::pod2usage(
|
||||||
-verbose => 1,
|
-verbose => 1,
|
||||||
-message => "\n$0 command line flags\n" . '-' x 65
|
-message => "\n$0 command line flags\n" . '-' x 65
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue