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 = ("org.openafs.OpenAFS-debug",
94 "org.openafs.OpenAFS",
96 "OpenAFS-debug-extension",
104 my $infopath = undef;
105 my $pkgname_plist_newpath = "/var/db/receipts/$pkgname.pkg.plist";
106 my $pkgname_bom_newpath = "/var/db/receipts/$pkgname.pkg.bom";
107 my $pkgname_plist_fullpath = "/Library/Receipts/$pkgname.pkg/Contents/Info.plist";
108 my $pkgname_bom_fullpath = "/Library/Receipts/$pkgname.pkg/Contents/Archive.bom";
110 if (-f $pkgname_plist_newpath && -r $pkgname_plist_newpath && -f $pkgname_bom_newpath && -r $pkgname_bom_newpath) {
111 print_verbose ("Removing package $pkgname.pkg\n");
112 $bompath = $pkgname_bom_newpath;
113 $infopath = $pkgname_plist_newpath;
115 if (-f $pkgname_plist_fullpath && -r $pkgname_plist_fullpath && -f $pkgname_bom_fullpath && -r $pkgname_bom_fullpath) {
116 print_verbose ("Removing package $pkgname.pkg\n");
117 $bompath = $pkgname_bom_fullpath;
118 $infopath = $pkgname_plist_fullpath;
124 next if (!defined ($bompath));
127 open (INFO, "$infopath") or next;
129 m/IFPkgFlagDefaultLocation/ or next;
134 $bomroot =~ />(.*)</;
136 $bomroot =~ s/^\/$//;
140 open (LSBOM, "/usr/bin/lsbom -l -f -p f '$bompath' |") or next;
145 next if (!defined ($1) || $1 eq "");
146 my $filename = $bomroot . $1;
148 remove_a_file ($filename);
154 open (LSBOM, "/usr/bin/lsbom -d -p f '$bompath' |") or next;
159 next if (!defined ($1) || $1 eq "");
160 my $directory = $bomroot . $1;
163 $rooth = add_directory_to_tree ($directory, $rooth);
169 print_warning ("Warning: \"$directory\" listed in BOM but not present on system.\n");
176 remove_empty_directories ($rooth, "/");
178 if (-d "$receipts_dir/$pkgname.pkg" ) {
179 remove_package_receipts ("$pkgname.pkg") if (!defined ($ARGV[1]) || !$ARGV[1]) ;
181 unshift(@rmfiles, "$bompath");
182 unshift(@rmfiles, "$infopath");
187 sub remove_generated_files
195 sub remove_generated_directories
197 remove_empty_directories ($gen_dirs, "/");
200 sub add_directory_to_tree
206 my @pathcomp = split /\//, $dir;
212 if ($cur_name eq "" || !defined ($cur_name))
216 if (!defined ($p->{"$cur_name"}))
218 $p->{$cur_name} = { };
220 $p = $p->{$cur_name};
225 sub remove_empty_directories
229 my $children = (scalar (keys %{$rooth}));
234 foreach my $dirname (sort keys %{$rooth})
237 $printpath = "$path/$dirname";
238 $printpath =~ s#^/*#/#;
239 remove_empty_directories ($rooth->{$dirname}, "$printpath");
240 $dirs_remain = 1 if (-d "$printpath");
244 if ($dirs_remain == 0)
246 maybe_remove_ds_store ("$path");
249 remove_a_dir ("$path");
255 my $dirname = dirname ($fn);
256 my $basename = basename ($fn);
257 my $ufs_rsrc_file = "$dirname/._$basename";
260 return if (!defined ($fn) || $fn eq "");
262 # Leave any files that are shared between packages alone.
263 if (defined($exception_list{$fn}))
267 print_warning ("Warning: file \"$fn\" intentionally not removed, even though it's in the BOM.\n");
272 if (! -f $fn && ! -l $fn)
276 print_warning ("Warning: file \"$fn\" present in BOM but not found on disc.\n");
281 if ($do_nothing == 1)
283 print_donothing ("rm $fn\n");
284 print_donothing ("rm $ufs_rsrc_file\n") if ( -f $ufs_rsrc_file);
288 unshift(@rmfiles, "$fn");
289 unshift(@rmfiles, "$ufs_rsrc_file") if ( -f $ufs_rsrc_file);
298 return if (!defined ($dir) || $dir eq "" || $dir eq "/" || $dir eq "/usr");
303 print_warning ("Warning: directory \"$dir\" present in BOM but not found on disc.\n");
308 if ($do_nothing == 1)
310 print_donothing ("rmdir $dir\n");
314 push(@rmdirs, "$dir");
318 sub remove_package_receipts
321 $pkgname =~ s#/##g; # There shouldn't be any path seps in the pkg name...
322 return if (!defined ($pkgname) || $pkgname eq ""
323 || $pkgname eq "." || $pkgname eq "..");
325 my $pkgdir = "$receipts_dir/$pkgname";
326 return if (!defined ($pkgdir) || $pkgdir eq "" || ! -d $pkgdir);
328 push(@rmpkg, "$pkgdir");
332 sub maybe_remove_ds_store
336 return if (!defined ($path) || $path eq "" || $path eq "/" || $path eq "/usr");
337 return if (! -f "$path/.DS_Store");
339 open (LS, "/bin/ls -a '$path' |");
343 next if (m#^\.$# || m#^\.\.$#);
348 if ($filecount == 1 && -f "$path/.DS_Store")
350 remove_a_file ("$path/.DS_Store");
357 return if ($print_donothing_removals != 1);
365 return if ($verbose != 1);
386 print "
\b" unless ($suppress_spin);
391 $spin_slower_downer = 150;
396 $spin_slower_downer = 75;
401 return if ($suppress_spin);
403 if (($spin_counter % $spin_slower_downer) == 0)
405 my $spin_chars = "|/-\\";
406 my $c = substr ($spin_chars, $spin_state % 4, 1);
408 print "
\e[7m$c
\e[m
\b";
414 #----------------------------------------------------------------------------------------