home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2 / Openstep-4.2-Intel-User.iso / usr / bin / find2perl < prev    next >
Text File  |  1997-03-29  |  12KB  |  573 lines

  1. #!/usr/bin/perl
  2. # Modified September 26, 1993 to provide proper handling of years after 1999
  3. #   Tom Link <tml+@pitt.edu>
  4. #   University of Pittsburgh
  5.  
  6. eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
  7.     if $running_under_some_shell;
  8.  
  9. $bin = "/usr/bin";
  10.  
  11.  
  12. while ($ARGV[0] =~ /^[^-!(]/) {
  13.     push(@roots, shift);
  14. }
  15. @roots = ('.') unless @roots;
  16. for (@roots) { $_ = "e($_); }
  17. $roots = join(',', @roots);
  18.  
  19. $indent = 1;
  20.  
  21. while (@ARGV) {
  22.     $_ = shift;
  23.     s/^-// || /^[()!]/ || die "Unrecognized switch: $_\n";
  24.     if ($_ eq '(') {
  25.     $out .= &tab . "(\n";
  26.     $indent++;
  27.     next;
  28.     }
  29.     elsif ($_ eq ')') {
  30.     $indent--;
  31.     $out .= &tab . ")";
  32.     }
  33.     elsif ($_ eq '!') {
  34.     $out .= &tab . "!";
  35.     next;
  36.     }
  37.     elsif ($_ eq 'name') {
  38.     $out .= &tab;
  39.     $pat = &fileglob_to_re(shift);
  40.     $out .= '/' . $pat . "/";
  41.     }
  42.     elsif ($_ eq 'perm') {
  43.     $onum = shift;
  44.     die "Malformed -perm argument: $onum\n" unless $onum =~ /^-?[0-7]+$/;
  45.     if ($onum =~ s/^-//) {
  46.         $onum = '0' . sprintf("%o", oct($onum) & 017777);    # s/b 07777 ?
  47.         $out .= &tab . "((\$mode & $onum) == $onum)";
  48.     }
  49.     else {
  50.         $onum = '0' . $onum unless $onum =~ /^0/;
  51.         $out .= &tab . "((\$mode & 0777) == $onum)";
  52.     }
  53.     }
  54.     elsif ($_ eq 'type') {
  55.     ($filetest = shift) =~ tr/s/S/;
  56.     $out .= &tab . "-$filetest _";
  57.     }
  58.     elsif ($_ eq 'print') {
  59.     $out .= &tab . 'print("$name\n")';
  60.     }
  61.     elsif ($_ eq 'print0') {
  62.     $out .= &tab . 'print("$name\0")';
  63.     }
  64.     elsif ($_ eq 'fstype') {
  65.     $out .= &tab;
  66.     $type = shift;
  67.     if ($type eq 'nfs')
  68.         { $out .= '($dev < 0)'; }
  69.     else
  70.         { $out .= '($dev >= 0)'; }
  71.     }
  72.     elsif ($_ eq 'user') {
  73.     $uname = shift;
  74.     $out .= &tab . "(\$uid == \$uid{'$uname'})";
  75.     $inituser++;
  76.     }
  77.     elsif ($_ eq 'group') {
  78.     $gname = shift;
  79.     $out .= &tab . "(\$gid == \$gid{'$gname'})";
  80.     $initgroup++;
  81.     }
  82.     elsif ($_ eq 'nouser') {
  83.     $out .= &tab . '!defined $uid{$uid}';
  84.     $inituser++;
  85.     }
  86.     elsif ($_ eq 'nogroup') {
  87.     $out .= &tab . '!defined $gid{$gid}';
  88.     $initgroup++;
  89.     }
  90.     elsif ($_ eq 'links') {
  91.     $out .= &tab . '($nlink ' . &n(shift);
  92.     }
  93.     elsif ($_ eq 'inum') {
  94.     $out .= &tab . '($ino ' . &n(shift);
  95.     }
  96.     elsif ($_ eq 'size') {
  97.     $out .= &tab . '(int(((-s _) + 511) / 512) ' . &n(shift);
  98.     }
  99.     elsif ($_ eq 'atime') {
  100.     $out .= &tab . '(int(-A _) ' . &n(shift);
  101.     }
  102.     elsif ($_ eq 'mtime') {
  103.     $out .= &tab . '(int(-M _) ' . &n(shift);
  104.     }
  105.     elsif ($_ eq 'ctime') {
  106.     $out .= &tab . '(int(-C _) ' . &n(shift);
  107.     }
  108.     elsif ($_ eq 'exec') {
  109.     for (@cmd = (); @ARGV && $ARGV[0] ne ';'; push(@cmd,shift)) { }
  110.     shift;
  111.     $_ = "@cmd";
  112.     if (m#^(/bin/)?rm -f {}$#) {
  113.         if (!@ARGV) {
  114.         $out .= &tab . 'unlink($_)';
  115.         }
  116.         else {
  117.         $out .= &tab . '(unlink($_) || 1)';
  118.         }
  119.     }
  120.     elsif (m#^(/bin/)?rm {}$#) {
  121.         $out .= &tab . '(unlink($_) || warn "$name: $!\n")';
  122.     }
  123.     else {
  124.         for (@cmd) { s/'/\\'/g; }
  125.         $" = "','";
  126.         $out .= &tab . "&exec(0, '@cmd')";
  127.         $" = ' ';
  128.         $initexec++;
  129.     }
  130.     }
  131.     elsif ($_ eq 'ok') {
  132.     for (@cmd = (); @ARGV && $ARGV[0] ne ';'; push(@cmd,shift)) { }
  133.     shift;
  134.     for (@cmd) { s/'/\\'/g; }
  135.     $" = "','";
  136.     $out .= &tab . "&exec(1, '@cmd')";
  137.     $" = ' ';
  138.     $initexec++;
  139.     }
  140.     elsif ($_ eq 'prune') {
  141.     $out .= &tab . '($prune = 1)';
  142.     }
  143.     elsif ($_ eq 'xdev') {
  144.     $out .= &tab . '!($prune |= ($dev != $topdev))';
  145.     }
  146.     elsif ($_ eq 'newer') {
  147.     $out .= &tab;
  148.     $file = shift;
  149.     $newername = 'AGE_OF' . $file;
  150.     $newername =~ s/[^\w]/_/g;
  151.     $newername = '$' . $newername;
  152.     $out .= "(-M _ < $newername)";
  153.     $initnewer .= "$newername = -M " . "e($file) . ";\n";
  154.     }
  155.     elsif ($_ eq 'eval') {
  156.     $prog = "e(shift);
  157.     $out .= &tab . "eval $prog";
  158.     }
  159.     elsif ($_ eq 'depth') {
  160.     $depth++;
  161.     next;
  162.     }
  163.     elsif ($_ eq 'ls') {
  164.     $out .= &tab . "&ls";
  165.     $initls++;
  166.     }
  167.     elsif ($_ eq 'tar') {
  168.     $out .= &tab;
  169.     die "-tar must have a filename argument\n" unless @ARGV;
  170.     $file = shift;
  171.     $fh = 'FH' . $file;
  172.     $fh =~ s/[^\w]/_/g;
  173.     $out .= "&tar($fh)";
  174.     $file = '>' . $file;
  175.     $initfile .= "open($fh, " . "e($file) .
  176.       qq{) || die "Can't open $fh: \$!\\n";\n};
  177.     $inittar++;
  178.     $flushall = "\n&tflushall;\n";
  179.     }
  180.     elsif (/^n?cpio$/) {
  181.     $depth++;
  182.     $out .= &tab;
  183.     die "-$_ must have a filename argument\n" unless @ARGV;
  184.     $file = shift;
  185.     $fh = 'FH' . $file;
  186.     $fh =~ s/[^\w]/_/g;
  187.     $out .= "&cpio('" . substr($_,0,1) . "', $fh)";
  188.     $file = '>' . $file;
  189.     $initfile .= "open($fh, " . "e($file) .
  190.       qq{) || die "Can't open $fh: \$!\\n";\n};
  191.     $initcpio++;
  192.     $flushall = "\n&flushall;\n";
  193.     }
  194.     else {
  195.     die "Unrecognized switch: -$_\n";
  196.     }
  197.     if (@ARGV) {
  198.     if ($ARGV[0] eq '-o') {
  199.         { local($statdone) = 1; $out .= "\n" . &tab . "||\n"; }
  200.         $statdone = 0 if $indent == 1 && $delayedstat;
  201.         $saw_or++;
  202.         shift;
  203.     }
  204.     else {
  205.         $out .= " &&" unless $ARGV[0] eq ')';
  206.         $out .= "\n";
  207.         shift if $ARGV[0] eq '-a';
  208.     }
  209.     }
  210. }
  211.  
  212. print <<"END";
  213. #!$bin/perl
  214.  
  215. eval 'exec $bin/perl -S \$0 \${1+"\$@"}'
  216.     if \$running_under_some_shell;
  217.  
  218. END
  219.  
  220. if ($initls) {
  221.     print <<'END';
  222. @rwx = ('---','--x','-w-','-wx','r--','r-x','rw-','rwx');
  223. @moname = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
  224.  
  225. END
  226. }
  227.  
  228. if ($inituser || $initls) {
  229.     print 'while (($name, $pw, $uid) = getpwent) {', "\n";
  230.     print '    $uid{$name} = $uid{$uid} = $uid;', "\n" if $inituser;
  231.     print '    $user{$uid} = $name unless $user{$uid};', "\n" if $initls;
  232.     print "}\n\n";
  233. }
  234.  
  235. if ($initgroup || $initls) {
  236.     print 'while (($name, $pw, $gid) = getgrent) {', "\n";
  237.     print '    $gid{$name} = $gid{$gid} = $gid;', "\n" if $initgroup;
  238.     print '    $group{$gid} = $name unless $group{$gid};', "\n" if $initls;
  239.     print "}\n\n";
  240. }
  241.  
  242. print $initnewer, "\n" if $initnewer;
  243.  
  244. print $initfile, "\n" if $initfile;
  245.  
  246. $find = $depth ? "finddepth" : "find";
  247. print <<"END";
  248. require "$find.pl";
  249.  
  250. # Traverse desired filesystems
  251.  
  252. &$find($roots);
  253. $flushall
  254. exit;
  255.  
  256. sub wanted {
  257. $out;
  258. }
  259.  
  260. END
  261.  
  262. if ($initexec) {
  263.     print <<'END';
  264. sub exec {
  265.     local($ok, @cmd) = @_;
  266.     foreach $word (@cmd) {
  267.     $word =~ s#{}#$name#g;
  268.     }
  269.     if ($ok) {
  270.     local($old) = select(STDOUT);
  271.     $| = 1;
  272.     print "@cmd";
  273.     select($old);
  274.     return 0 unless <STDIN> =~ /^y/;
  275.     }
  276.     chdir $cwd;        # sigh
  277.     system @cmd;
  278.     chdir $dir;
  279.     return !$?;
  280. }
  281.  
  282. END
  283. }
  284.  
  285. if ($initls) {
  286.     print <<'END';
  287. sub ls {
  288.     ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$sizemm,
  289.       $atime,$mtime,$ctime,$blksize,$blocks) = lstat(_);
  290.  
  291.     $pname = $name;
  292.  
  293.     if (defined $blocks) {
  294.     $blocks = int(($blocks + 1) / 2);
  295.     }
  296.     else {
  297.     $blocks = int(($size + 1023) / 1024);
  298.     }
  299.  
  300.     if    (-f _) { $perms = '-'; }
  301.     elsif (-d _) { $perms = 'd'; }
  302.     elsif (-c _) { $perms = 'c'; $sizemm = &sizemm; }
  303.     elsif (-b _) { $perms = 'b'; $sizemm = &sizemm; }
  304.     elsif (-p _) { $perms = 'p'; }
  305.     elsif (-S _) { $perms = 's'; }
  306.     else         { $perms = 'l'; $pname .= ' -> ' . readlink($_); }
  307.  
  308.     $tmpmode = $mode;
  309.     $tmp = $rwx[$tmpmode & 7];
  310.     $tmpmode >>= 3;
  311.     $tmp = $rwx[$tmpmode & 7] . $tmp;
  312.     $tmpmode >>= 3;
  313.     $tmp = $rwx[$tmpmode & 7] . $tmp;
  314.     substr($tmp,2,1) =~ tr/-x/Ss/ if -u _;
  315.     substr($tmp,5,1) =~ tr/-x/Ss/ if -g _;
  316.     substr($tmp,8,1) =~ tr/-x/Tt/ if -k _;
  317.     $perms .= $tmp;
  318.  
  319.     $user = $user{$uid} || $uid;
  320.     $group = $group{$gid} || $gid;
  321.  
  322.     ($sec,$min,$hour,$mday,$mon,$year) = localtime($mtime);
  323.     $moname = $moname[$mon];
  324.     if (-M _ > 365.25 / 2) {
  325.     $timeyear = $year + 1900;
  326.     }
  327.     else {
  328.     $timeyear = sprintf("%02d:%02d", $hour, $min);
  329.     }
  330.  
  331.     printf "%5lu %4ld %-10s %2d %-8s %-8s %8s %s %2d %5s %s\n",
  332.         $ino,
  333.          $blocks,
  334.               $perms,
  335.                 $nlink,
  336.                 $user,
  337.                      $group,
  338.                       $sizemm,
  339.                           $moname,
  340.                          $mday,
  341.                              $timeyear,
  342.                              $pname;
  343.     1;
  344. }
  345.  
  346. sub sizemm {
  347.     sprintf("%3d, %3d", ($rdev >> 8) & 255, $rdev & 255);
  348. }
  349.  
  350. END
  351. }
  352.  
  353. if ($initcpio) {
  354. print <<'END';
  355. sub cpio {
  356.     local($nc,$fh) = @_;
  357.     local($text);
  358.  
  359.     if ($name eq 'TRAILER!!!') {
  360.     $text = '';
  361.     $size = 0;
  362.     }
  363.     else {
  364.     ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
  365.       $atime,$mtime,$ctime,$blksize,$blocks) = lstat(_);
  366.     if (-f _) {
  367.         open(IN, "./$_\0") || do {
  368.         warn "Couldn't open $name: $!\n";
  369.         return;
  370.         };
  371.     }
  372.     else {
  373.         $text = readlink($_);
  374.         $size = 0 unless defined $text;
  375.     }
  376.     }
  377.  
  378.     ($nm = $name) =~ s#^\./##;
  379.     $nc{$fh} = $nc;
  380.     if ($nc eq 'n') {
  381.     $cpout{$fh} .=
  382.       sprintf("%06o%06o%06o%06o%06o%06o%06o%06o%011lo%06o%011lo%s\0",
  383.         070707,
  384.         $dev & 0777777,
  385.         $ino & 0777777,
  386.         $mode & 0777777,
  387.         $uid & 0777777,
  388.         $gid & 0777777,
  389.         $nlink & 0777777,
  390.         $rdev & 0177777,
  391.         $mtime,
  392.         length($nm)+1,
  393.         $size,
  394.         $nm);
  395.     }
  396.     else {
  397.     $cpout{$fh} .= "\0" if length($cpout{$fh}) & 1;
  398.     $cpout{$fh} .= pack("SSSSSSSSLSLa*",
  399.         070707, $dev, $ino, $mode, $uid, $gid, $nlink, $rdev, $mtime,
  400.         length($nm)+1, $size, $nm . (length($nm) & 1 ? "\0" : "\0\0"));
  401.     }
  402.     if ($text ne '') {
  403.     $cpout{$fh} .= $text;
  404.     }
  405.     elsif ($size) {
  406.     &flush($fh) while ($l = length($cpout{$fh})) >= 5120;
  407.     while (sysread(IN, $cpout{$fh}, 5120 - $l, $l)) {
  408.         &flush($fh);
  409.         $l = length($cpout{$fh});
  410.     }
  411.     }
  412.     close IN;
  413. }
  414.  
  415. sub flush {
  416.     local($fh) = @_;
  417.  
  418.     while (length($cpout{$fh}) >= 5120) {
  419.     syswrite($fh,$cpout{$fh},5120);
  420.     ++$blocks{$fh};
  421.     substr($cpout{$fh}, 0, 5120) = '';
  422.     }
  423. }
  424.  
  425. sub flushall {
  426.     $name = 'TRAILER!!!';
  427.     foreach $fh (keys %cpout) {
  428.     &cpio($nc{$fh},$fh);
  429.     $cpout{$fh} .= "0" x (5120 - length($cpout{$fh}));
  430.     &flush($fh);
  431.     print $blocks{$fh} * 10, " blocks\n";
  432.     }
  433. }
  434.  
  435. END
  436. }
  437.  
  438. if ($inittar) {
  439. print <<'END';
  440. sub tar {
  441.     local($fh) = @_;
  442.     local($linkname,$header,$l,$slop);
  443.     local($linkflag) = "\0";
  444.  
  445.     ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
  446.       $atime,$mtime,$ctime,$blksize,$blocks) = lstat(_);
  447.     $nm = $name;
  448.     if ($nlink > 1) {
  449.     if ($linkname = $linkseen{$fh,$dev,$ino}) {
  450.         $linkflag = 1;
  451.     }
  452.     else {
  453.         $linkseen{$fh,$dev,$ino} = $nm;
  454.     }
  455.     }
  456.     if (-f _) {
  457.     open(IN, "./$_\0") || do {
  458.         warn "Couldn't open $name: $!\n";
  459.         return;
  460.     };
  461.     $size = 0 if $linkflag ne "\0";
  462.     }
  463.     else {
  464.     $linkname = readlink($_);
  465.     $linkflag = 2 if defined $linkname;
  466.     $nm .= '/' if -d _;
  467.     $size = 0;
  468.     }
  469.  
  470.     $header = pack("a100a8a8a8a12a12a8a1a100",
  471.     $nm,
  472.     sprintf("%6o ", $mode & 0777),
  473.     sprintf("%6o ", $uid & 0777777),
  474.     sprintf("%6o ", $gid & 0777777),
  475.     sprintf("%11o ", $size),
  476.     sprintf("%11o ", $mtime),
  477.     "        ",
  478.     $linkflag,
  479.     $linkname);
  480.     $l = length($header) % 512;
  481.     substr($header, 148, 6) = sprintf("%6o", unpack("%16C*", $header));
  482.     substr($header, 154, 1) = "\0";  # blech
  483.     $tarout{$fh} .= $header;
  484.     $tarout{$fh} .= "\0" x (512 - $l) if $l;
  485.     if ($size) {
  486.     &tflush($fh) while ($l = length($tarout{$fh})) >= 10240;
  487.     while (sysread(IN, $tarout{$fh}, 10240 - $l, $l)) {
  488.         $slop = length($tarout{$fh}) % 512;
  489.         $tarout{$fh} .= "\0" x (512 - $slop) if $slop;
  490.         &tflush($fh);
  491.         $l = length($tarout{$fh});
  492.     }
  493.     }
  494.     close IN;
  495. }
  496.  
  497. sub tflush {
  498.     local($fh) = @_;
  499.  
  500.     while (length($tarout{$fh}) >= 10240) {
  501.     syswrite($fh,$tarout{$fh},10240);
  502.     ++$blocks{$fh};
  503.     substr($tarout{$fh}, 0, 10240) = '';
  504.     }
  505. }
  506.  
  507. sub tflushall {
  508.     local($len);
  509.  
  510.     foreach $fh (keys %tarout) {
  511.     $len = 10240 - length($tarout{$fh});
  512.     $len += 10240 if $len < 1024;
  513.     $tarout{$fh} .= "\0" x $len;
  514.     &tflush($fh);
  515.     }
  516. }
  517.  
  518. END
  519. }
  520.  
  521. exit;
  522.  
  523. ############################################################################
  524.  
  525. sub tab {
  526.     local($tabstring);
  527.  
  528.     $tabstring = "\t" x ($indent / 2) . ' ' x ($indent % 2 * 4);
  529.     if (!$statdone) {
  530.     if ($_ =~ /^(name|print|prune|exec|ok|\(|\))/) {
  531.         $delayedstat++;
  532.     }
  533.     else {
  534.         if ($saw_or) {
  535.         $tabstring .= <<'ENDOFSTAT' . $tabstring;
  536. ($nlink || (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_))) &&
  537. ENDOFSTAT
  538.         }
  539.         else {
  540.         $tabstring .= <<'ENDOFSTAT' . $tabstring;
  541. (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
  542. ENDOFSTAT
  543.         }
  544.         $statdone = 1;
  545.     }
  546.     }
  547.     $tabstring =~ s/^\s+/ / if $out =~ /!$/;
  548.     $tabstring;
  549. }
  550.  
  551. sub fileglob_to_re {
  552.     local($tmp) = @_;
  553.  
  554.     $tmp =~ s#([./^\$()])#\\$1#g;
  555.     $tmp =~ s/([?*])/.$1/g;
  556.     "^$tmp\$";
  557. }
  558.  
  559. sub n {
  560.     local($n) = @_;
  561.  
  562.     $n =~ s/^-/< / || $n =~ s/^\+/> / || $n =~ s/^/== /;
  563.     $n =~ s/ 0*(\d)/ $1/;
  564.     $n . ')';
  565. }
  566.  
  567. sub quote {
  568.     local($string) = @_;
  569.     $string =~ s/'/\\'/;
  570.     "'$string'";
  571. }
  572.