Lines 28-37
Link Here
|
28 |
|
28 |
|
29 |
# Interactive script for deinstalling "leaf" packages |
29 |
# Interactive script for deinstalling "leaf" packages |
30 |
# |
30 |
# |
31 |
# Syntax: pkg_cutleaves [-cFgLlRVx] |
31 |
# Syntax: pkg_cutleaves [-cgLlRVx] |
32 |
# Options: |
32 |
# Options: |
33 |
# -c: Show comments, too; only works with '-l' (ignored otherwise) |
33 |
# -c: Show comments, too; only works with '-l' (ignored otherwise) |
34 |
# -F: Fix package db after each deinstallation run (via 'pkgdb -F') |
|
|
35 |
# -g: Generate exclude list from kept/installed leaf packages |
34 |
# -g: Generate exclude list from kept/installed leaf packages |
36 |
# -L: Interpret exclude file as list of packages that *should* be installed |
35 |
# -L: Interpret exclude file as list of packages that *should* be installed |
37 |
# -l: List leaf packages only, don't ask if they should be deinstalled |
36 |
# -l: List leaf packages only, don't ask if they should be deinstalled |
Lines 43-57
Link Here
|
43 |
use Getopt::Std; |
42 |
use Getopt::Std; |
44 |
use strict; |
43 |
use strict; |
45 |
|
44 |
|
46 |
my $dbdir = "/var/db/pkg"; |
|
|
47 |
my $excludefile = "/usr/local/etc/pkg_leaves.exclude"; |
45 |
my $excludefile = "/usr/local/etc/pkg_leaves.exclude"; |
48 |
my $pkgdeinstall = "/usr/sbin/pkg_delete"; |
46 |
my @pkgdeinstall = (qw{/usr/local/sbin/pkg delete -y}); |
49 |
my @pkgdb_args = ("/usr/local/sbin/pkgdb", "-F"); |
47 |
my @pkgquery = (qw{/usr/local/sbin/pkg query}); |
50 |
my $exclpattern; |
48 |
my $exclpattern; |
51 |
my %leavestokeep; |
49 |
my %leavestokeep; |
52 |
my %opt; |
50 |
my %opt; |
53 |
|
51 |
|
54 |
getopts('cFgLlRVx', \%opt); |
52 |
getopts('cgLlRVx', \%opt); |
55 |
set_excl_pattern(); |
53 |
set_excl_pattern(); |
56 |
|
54 |
|
57 |
# LIST MODE |
55 |
# LIST MODE |
Lines 77-83
Link Here
|
77 |
my ($file, $required) = @$pkg; |
75 |
my ($file, $required) = @$pkg; |
78 |
# Clobber any exclude patterns that match this package |
76 |
# Clobber any exclude patterns that match this package |
79 |
for (my $i = 0; $i < @excludes; $i++) { |
77 |
for (my $i = 0; $i < @excludes; $i++) { |
80 |
if ($file =~ /\Q@excludes[$i]\E/) { |
78 |
if ($file =~ /\Q$excludes[$i]\E/) { |
81 |
splice(@excludes, $i--, 1); |
79 |
splice(@excludes, $i--, 1); |
82 |
} |
80 |
} |
83 |
} |
81 |
} |
Lines 219-225
Link Here
|
219 |
foreach my $leaf (sort keys %leavestocut) { |
217 |
foreach my $leaf (sort keys %leavestocut) { |
220 |
$noff++; |
218 |
$noff++; |
221 |
print "Deleting $leaf (package $noff of $ncuts).\n"; |
219 |
print "Deleting $leaf (package $noff of $ncuts).\n"; |
222 |
my @deinstall_args = ($pkgdeinstall, $leaf); |
220 |
my @deinstall_args = (@pkgdeinstall, $leaf); |
223 |
if ((my $status = system(@deinstall_args) >> 8) != 0) { |
221 |
if ((my $status = system(@deinstall_args) >> 8) != 0) { |
224 |
print STDERR "\n\n$0: pkg_deinstall returned $status - exiting, fix this first.\n\n"; |
222 |
print STDERR "\n\n$0: pkg_deinstall returned $status - exiting, fix this first.\n\n"; |
225 |
last ROUND; |
223 |
last ROUND; |
Lines 227-241
Link Here
|
227 |
push @cutleaves, $leaf; |
225 |
push @cutleaves, $leaf; |
228 |
} |
226 |
} |
229 |
|
227 |
|
230 |
# Run 'pkgdb -F' if requested |
|
|
231 |
if ($opt{F}) { |
232 |
print "Running 'pkgdb -F'.\n"; |
233 |
if ((my $status = system(@pkgdb_args) >> 8) != 0) { |
234 |
print STDERR "\n\n$0: pkgdb returned $status - exiting, fix this first.\n\n"; |
235 |
last ROUND; |
236 |
} |
237 |
} |
238 |
|
239 |
# Get new list of leaf packages and put them into a hash |
228 |
# Get new list of leaf packages and put them into a hash |
240 |
%leaves = get_leaves(); |
229 |
%leaves = get_leaves(); |
241 |
|
230 |
|
Lines 328-342
Link Here
|
328 |
# |
317 |
# |
329 |
sub get_packages { |
318 |
sub get_packages { |
330 |
my @pkgs; |
319 |
my @pkgs; |
331 |
opendir(DBDIR, $dbdir) |
320 |
open(PKGQUERY, '-|', @pkgquery, '-a', '%n-%v\t%?r\t%c') |
332 |
or die "Can't open package db directory $dbdir!"; |
321 |
or die "Couldn't read output from $pkgquery[0]!"; |
333 |
while (defined(my $file = readdir(DBDIR))) { |
322 |
while (my $p = <PKGQUERY>) { |
334 |
my $path = join('/', $dbdir, $file); |
323 |
chomp($p); |
335 |
unless ($file =~ /^\.+$/o || !(-d $path)) { |
324 |
push(@pkgs, [ split(/\t/, $p) ]); |
336 |
push @pkgs, [$file, -s $path . '/+REQUIRED_BY', join('/', $path, '+COMMENT')]; |
|
|
337 |
} |
338 |
} |
325 |
} |
339 |
closedir DBDIR; |
326 |
close PKGQUERY; |
340 |
return @pkgs; |
327 |
return @pkgs; |
341 |
} |
328 |
} |
342 |
|
329 |
|
Lines 347-366
Link Here
|
347 |
my %leaves; |
334 |
my %leaves; |
348 |
my @pkgs = get_packages(); |
335 |
my @pkgs = get_packages(); |
349 |
foreach my $pkg (@pkgs) { |
336 |
foreach my $pkg (@pkgs) { |
350 |
my ($file, $required, $commentfile) = @$pkg; |
337 |
my ($file, $required, $comment) = @$pkg; |
351 |
unless ($required) { |
338 |
unless ($required) { |
352 |
if ($file =~ $exclpattern) { |
339 |
if ($file =~ $exclpattern) { |
353 |
$leavestokeep{$file} = 1; |
340 |
$leavestokeep{$file} = 1; |
354 |
} |
341 |
} |
355 |
else { |
342 |
else { |
356 |
# Read package's short description/comment |
343 |
unless($comment) { |
357 |
my $comment; |
344 |
$comment = 'No short description'; |
358 |
if ((-s $commentfile) && (open(COMMENT, $commentfile))) { |
|
|
359 |
chomp($comment = <COMMENT>); |
360 |
} |
345 |
} |
361 |
else { |
|
|
362 |
$comment = 'No short description'; |
363 |
} |
364 |
$leaves{$file} = $comment; |
346 |
$leaves{$file} = $comment; |
365 |
} |
347 |
} |
366 |
} |
348 |
} |