+ # commands are lower case
+ $short_cmd = lc $short_cmd;
+ dbg('command', "command: $path $short_cmd\n");
+
+ # return immediately if we have it
+ my ($apath, $acmd) = split ',', $cmd_cache{$short_cmd};
+ if ($apath && $acmd) {
+ dbg('command', "cached $short_cmd = ($apath, $acmd)\n");
+ return ($apath, $acmd) if $apath;
+ }
+
+ # if not guess
+ my @parts = split '/', $short_cmd;
+ my $dirfn;
+ my $curdir = $path;
+ my $p;
+ my $i;
+
+ for ($i = 0; $i < @parts; $i++) {
+ my $p = $parts[$i];
+ opendir(D, $curdir) or confess "can't open $curdir $!";
+ my @ls = readdir D;
+ closedir D;
+ my $l;
+ foreach $l (sort @ls) {
+ next if $l =~ /^\./;
+ if ($i < $#parts) { # we are dealing with directories
+ if ((-d "$curdir/$l") && $p eq substr($l, 0, length $p)) {
+ dbg('command', "got dir: $curdir/$l\n");
+ $dirfn .= "$l/";
+ $curdir .= "/$l";
+ last;
+ }
+ } else { # we are dealing with commands
+ next if !$l =~ /\.$suffix$/; # only look for .$suffix files
+ if ($p eq substr($l, 0, length $p)) {
+ $l =~ s/\.$suffix$//; # remove the suffix
+ chop $dirfn; # remove trailing /
+ $cmd_cache{"$short_cmd"} = join(',', ($path, "$dirfn/$l")); # cache it
+ dbg('command', "got path: $path cmd: $dirfn/$l\n");
+ return ($path, "$dirfn/$l");
+ }
+ }
+ }
+ }
+ return ();
+}