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