1#!/usr/bin/perl 2# Copyright (c) 2005 Apple Computer, Inc. All rights reserved. 3# 4# @APPLE_LICENSE_HEADER_START@ 5# 6# This file contains Original Code and/or Modifications of Original Code 7# as defined in and that are subject to the Apple Public Source License 8# Version 2.0 (the 'License'). You may not use this file except in 9# compliance with the License. Please obtain a copy of the License at 10# http://www.opensource.apple.com/apsl/ and read it before using this 11# file. 12# 13# The Original Code and all software distributed under the License are 14# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18# Please see the License for the specific language governing rights and 19# limitations under the License. 20# 21# @APPLE_LICENSE_HEADER_END@ 22 23use strict; 24use File::Basename (); 25use File::Find (); 26use Getopt::Std (); 27 28my $MyName = File::Basename::basename($0); 29my $N = 100; 30my $MinSize = 64; 31my %inodes; 32my @symlinks; 33our $opt_d = ''; 34 35sub wanted { 36 return unless /\.[\dn][a-z]*$/; 37 if(-l $_) { 38 push(@symlinks, $_); 39 } elsif(-f _) { 40 return if -s _ < $MinSize; 41 my($dev, $ino) = stat(_); 42 my $list = $inodes{$ino}; 43 $list = $inodes{$ino} = [] unless defined($list); 44 push(@$list, $_); 45 } 46} 47 48sub usage { 49 die "Usage: $MyName [-d prefix] dir ...\n"; 50} 51 52Getopt::Std::getopts('d:'); 53usage() unless scalar(@ARGV) > 0; 54 55for my $dir (@ARGV) { 56 $dir = $opt_d . $dir if $opt_d ne ''; 57 next unless -e $dir; 58 die "$dir: no such directory\n" unless -d _; 59 60 %inodes = (); 61 @symlinks = (); 62 File::Find::find({ 63 wanted => \&wanted, 64 no_chdir => 1, 65 }, $dir); 66 67 my(@compress, @links); 68 for(values(%inodes)) { 69 push(@compress, $_->[0]); 70 push(@links, $_) if scalar(@$_) > 1; 71 } 72 73 my $count; 74 while(($count = scalar(@compress)) > 0) { 75 $_ = $count > $N ? $N : $count; 76 my @args = splice(@compress, 0, $_); 77 print "gzip -f -n @args\n"; 78 system('gzip', '-f', '-n', @args) == 0 or die "gzip failed\n";; 79 } 80 foreach my $list (@links) { 81 my $main = shift(@$list); 82 for(@$list) { 83 printf "rm $_; ln $main.gz $_.gz\n"; 84 unlink $_ or die "Can't unlink: $!\n"; 85 unlink "$_.gz"; 86 link("$main.gz", "$_.gz") or die "Can't link: $!\n";; 87 } 88 } 89 for(@symlinks) { 90 my $link = readlink($_); 91 printf "rm $_; ln -s $link.gz $_.gz\n"; 92 unlink $_ or die "Can't unlink: $!\n"; 93 symlink("$link.gz", "$_.gz") or die "Can't symlink: $!\n"; 94 } 95} 96