home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / c / cops_104.zip / cops_104 / perl / glob.pl < prev    next >
Perl Script  |  1992-03-10  |  3KB  |  143 lines

  1. #
  2. #  This does shell or perl globbing without resorting
  3. # to the shell -- we were having problems with the shell blowing
  4. # up with extra long pathnames and lots of file names.  set $glob'debug 
  5. # for trace information.
  6. #
  7. # tom christiansen <tchrist@convex.com>
  8.  
  9. package glob;
  10.  
  11. sub main'glob { 
  12.     local($expr) = @_;
  13.     local(@files);
  14.  
  15.     $? = 0;
  16.     open(SAVERR, ">&STDERR"); close(STDERR);  # suppress args too long
  17.     @files = <${expr}>;
  18.     if ($?) {
  19.     print SAVERR "shell glob blew up on $expr\n" if $debug;
  20.     @files = &SHglob($expr);
  21.     }
  22.     open (STDERR, ">&SAVERR");
  23.     # if (@files == 1 && $files[0] eq $expr) { @files = ''; } # sh foo
  24.     @files;
  25. }
  26.  
  27. sub main'SHglob {
  28.     local($expr) = @_;
  29.     local(@retlist) = ();
  30.     local($dir);
  31.  
  32.     print "SHglob: globbing $expr\n" if $debug;
  33.  
  34.     $expr =~ s/([.{+\\])/\\$1/g;
  35.     $expr =~ s/\*/.*/g;
  36.     $expr =~ s/\?/./g;
  37.  
  38.     for $dir (split(' ',$expr)) {
  39.     push(@retlist, &main'REglob($dir));
  40.     } 
  41.  
  42.     return sort @retlist;
  43.  
  44. sub main'REglob {
  45.     local($path) = @_;
  46.     local($_);
  47.     local(@retlist) = ();
  48.     local($root,$expr,$pos);
  49.     local($relative) = 0;
  50.     local(@dirs);
  51.     local($user);
  52.  
  53.     $haveglobbed = 0;
  54.  
  55.     @dirs = split(/\/+/, $path);
  56.  
  57.     if ($dirs[$[] =~ m!~(.*)!) {
  58.     $dirs[$[] = &homedir($1);
  59.     return @retlist unless $dirs[$[];
  60.     } elsif ($dirs[$[] eq '') {
  61.     $dirs[$[] = '/' unless $dirs[$[] =~ m!^\.{1,2}$!;
  62.     } else {
  63.     unshift(@dirs, '.');
  64.     $relative = 1;
  65.     } 
  66.  
  67.     printf "REglob: globbing %s\n", join('/',@dirs) if $debug;
  68.  
  69.     @retlist = &expand(@dirs);
  70.  
  71.     for (@retlist) {
  72.     if ($relative) {
  73.         s!^\./!!o;
  74.     }
  75.     s!/{2,}!/!g;
  76.     } 
  77.  
  78.     return sort @retlist;
  79. }
  80.  
  81. sub expand {
  82.     local($dir, $thisdir, @rest) = @_;
  83.     local($nextdir);
  84.     local($_);
  85.     local(@retlist) = ();
  86.     local(*DIR);
  87.  
  88.     unless ($haveglobbed || $thisdir =~ /([^\\]?)[?.*{[+\\]/ && $1 ne '\\') {
  89.     @retlist = ($thisdir);
  90.     } else {
  91.     unless (opendir(DIR,$dir)) {
  92.         warn "glob: can't opendir $dir: $!\n" if $debug;
  93.     } else {
  94.         @retlist = grep(/^$thisdir$/,readdir(DIR));
  95.         @retlist = grep(!/^\./, @retlist) unless $thisdir =~ /^\\\./;
  96.         $haveglobbed++;
  97.     } 
  98.     closedir DIR;
  99.     } 
  100.  
  101.     for (@retlist) {
  102.     $_ = $dir . '/' . $_;
  103.     }
  104.  
  105.     if ($nextdir = shift @rest) {
  106.     local(@newlist) = ();
  107.     for (@retlist) {
  108.         push(@newlist,&expand($_,$nextdir,@rest));
  109.     } 
  110.     @retlist = @newlist;
  111.     } 
  112.  
  113.     return @retlist;
  114.  
  115. sub homedir {
  116.     local($user) = @_;
  117.     local(@pwent);
  118.     # global %homedir
  119.  
  120.     if (!$user) {
  121.     return $ENV{'HOME'}         if $ENV{'HOME'};
  122.     ($user = $ENV{'USER'})      || 
  123.         ($user = getlogin)         || 
  124.         (($user) = getpwnam($>));
  125.     warn "glob'homedir: who are you, user #$>?\n" unless $user;
  126.     return '/';
  127.     } 
  128.     unless (defined $homedir{$user}) {
  129.     if (@pwent = getpwnam($user)) {
  130.         $homedir{$user} = $pwent[$#pwent - 1];
  131.     } else {
  132.         warn "glob'homedir: who are you, user #$>?\n" unless $user;
  133.         $homedir{$user} = '/';
  134.     }
  135.     }
  136.     return $homedir{$user};
  137.  
  138.  
  139. 1;
  140.