2
# real Perl code begins here
4
# Adapted from Apple's uninstall-devtools.pl (Version 7 for Xcode Tools 1.2)
6
# BSD License: c.f. <http://www.opensource.org/licenses/bsd-license>
12
use vars qw ($do_nothing $print_donothing_removals $receipts_dir $verbose $noisy_warnings);
13
use vars qw ($suppress_spin $spin_counter $spin_state $spin_slower_downer);
14
use vars qw (%exception_list $gen_dirs @gen_files @rmfiles @rmdirs @rmpkg);
16
#----------------------------------------------------------------------------------------
19
$print_donothing_removals = 1;
23
# One of rm -rf in this script uses $receipts_dir -- change with care.
24
$receipts_dir = "/Library/Receipts";
27
# '/usr/bin/aklog', '',
31
#$gen_dirs->{"/"}->{"Library"}->{"OpenAFS"}->{"Tools"} = {};
34
"/var/db/openafs/etc/cacheinfo",
35
"/var/db/openafs/etc/ThisCell",
36
"/var/db/openafs/etc/config/afsd.options",
37
"/var/db/openafs/etc/CellServDB.save",
38
"/var/db/openafs/etc/CellServDB.master.last",
39
"/var/db/openafs/etc/CellServDB",
40
"/var/db/openafs/etc/config/settings.plist",
43
#----------------------------------------------------------------------------------------
46
#if ($do_nothing == 0 && $< != 0)
48
# die "ERROR: Must be run with root permissions--prefix command with 'sudo'.\n";
54
# 0: dir of packages to remove
55
# 1: flag indicating whether to keep package receipts
56
# 2: flag indicating whether to supress spin indicator
60
@ARGV = ("$Bin/..", 0, 0);
62
$suppress_spin = defined ($ARGV[2]) && $ARGV[2];
69
print "Uninstalling OpenAFS package:\n\n";
71
remove_generated_files ();
72
remove_main_packages ();
73
remove_generated_directories ();
75
if ($do_nothing == 0) {
76
my @rmcmd = ('osascript', '-e', "do shell script \"/bin/rm -f @rmfiles; /bin/rmdir @rmdirs; /bin/rm -rf @rmpkg\" with administrator privileges");
78
my $retcode = $? >> 8;
80
print_warning ("Warning: There may have been a problem uninstalling\n");
85
print "\nFinished uninstalling.\n";
88
sub remove_main_packages
90
# opendir (DIR, $ARGV[0]) or die "ERROR: package directory $ARGV[0] not found\n";
91
# my @pkglist = grep /\.pkg$/, readdir DIR;
93
my @pkglist = ("OpenAFS",
100
my $pkgname_fullpath = "$receipts_dir/$pkgname.pkg";
101
my $pkgname_bom_fullpath = undef;
103
next if (! -d "$pkgname_fullpath" );
105
print_verbose ("Removing package $pkgname.pkg\n");
107
my $f = "$pkgname_fullpath/Contents/Resources/$pkgname.bom";
108
if (-f $f && -r $f) {
109
$pkgname_bom_fullpath = $f;
112
next if (!defined ($pkgname_bom_fullpath));
115
open (INFO, "$pkgname_fullpath/Contents/Info.plist") or next;
117
m/IFPkgFlagDefaultLocation/ or next;
122
$bomroot =~ />(.*)</;
124
$bomroot =~ s/^\/$//;
128
open (LSBOM, "/usr/bin/lsbom -l -f -p f '$pkgname_bom_fullpath' |") or next;
133
next if (!defined ($1) || $1 eq "");
134
my $filename = $bomroot . $1;
136
remove_a_file ($filename);
142
open (LSBOM, "/usr/bin/lsbom -d -p f '$pkgname_bom_fullpath' |") or next;
147
next if (!defined ($1) || $1 eq "");
148
my $directory = $bomroot . $1;
151
$rooth = add_directory_to_tree ($directory, $rooth);
157
print_warning ("Warning: \"$directory\" listed in BOM but not present on system.\n");
164
remove_empty_directories ($rooth, "/");
166
remove_package_receipts ("$pkgname.pkg") if (!defined ($ARGV[1]) || !$ARGV[1]) ;
170
sub remove_generated_files
178
sub remove_generated_directories
180
remove_empty_directories ($gen_dirs, "/");
183
sub add_directory_to_tree
189
my @pathcomp = split /\//, $dir;
195
if ($cur_name eq "" || !defined ($cur_name))
199
if (!defined ($p->{"$cur_name"}))
201
$p->{$cur_name} = { };
203
$p = $p->{$cur_name};
208
sub remove_empty_directories
212
my $children = (scalar (keys %{$rooth}));
217
foreach my $dirname (sort keys %{$rooth})
220
$printpath = "$path/$dirname";
221
$printpath =~ s#^/*#/#;
222
remove_empty_directories ($rooth->{$dirname}, "$printpath");
223
$dirs_remain = 1 if (-d "$printpath");
227
if ($dirs_remain == 0)
229
maybe_remove_ds_store ("$path");
232
remove_a_dir ("$path");
238
my $dirname = dirname ($fn);
239
my $basename = basename ($fn);
240
my $ufs_rsrc_file = "$dirname/._$basename";
243
return if (!defined ($fn) || $fn eq "");
245
# Leave any files that are shared between packages alone.
246
if (defined($exception_list{$fn}))
250
print_warning ("Warning: file \"$fn\" intentionally not removed, even though it's in the BOM.\n");
255
if (! -f $fn && ! -l $fn)
259
print_warning ("Warning: file \"$fn\" present in BOM but not found on disc.\n");
264
if ($do_nothing == 1)
266
print_donothing ("rm $fn\n");
267
print_donothing ("rm $ufs_rsrc_file\n") if ( -f $ufs_rsrc_file);
271
unshift(@rmfiles, "$fn");
272
unshift(@rmfiles, "$fn") if ( -f $ufs_rsrc_file);
281
return if (!defined ($dir) || $dir eq "" || $dir eq "/" || $dir eq "/usr");
286
print_warning ("Warning: directory \"$dir\" present in BOM but not found on disc.\n");
291
if ($do_nothing == 1)
293
print_donothing ("rmdir $dir\n");
297
push(@rmdirs, "$dir");
301
sub remove_package_receipts
304
$pkgname =~ s#/##g; # There shouldn't be any path seps in the pkg name...
305
return if (!defined ($pkgname) || $pkgname eq ""
306
|| $pkgname eq "." || $pkgname eq "..");
308
my $pkgdir = "$receipts_dir/$pkgname";
309
return if (!defined ($pkgdir) || $pkgdir eq "" || ! -d $pkgdir);
311
push(@rmpkg, "$pkgdir");
315
sub maybe_remove_ds_store
319
return if (!defined ($path) || $path eq "" || $path eq "/" || $path eq "/usr");
320
return if (! -f "$path/.DS_Store");
322
open (LS, "/bin/ls -a '$path' |");
326
next if (m#^\.$# || m#^\.\.$#);
331
if ($filecount == 1 && -f "$path/.DS_Store")
333
remove_a_file ("$path/.DS_Store");
340
return if ($print_donothing_removals != 1);
348
return if ($verbose != 1);
369
print " " unless ($suppress_spin);
374
$spin_slower_downer = 150;
379
$spin_slower_downer = 75;
384
return if ($suppress_spin);
386
if (($spin_counter % $spin_slower_downer) == 0)
388
my $spin_chars = "|/-\\";
389
my $c = substr ($spin_chars, $spin_state % 4, 1);
397
#----------------------------------------------------------------------------------------