#!/usr/bin/env perl ## Copyright (C) 2008 by Daniel Friesel ## License: WTFPL use strict; use warnings; use AptPkg::Cache; use Switch; use Getopt::Long; my $cache = AptPkg::Cache->new; my $not = 0; GetOptions( "not" => \$not, ); my $packagename = shift or die("No packagename given"); my $package = $cache->{$packagename}; unless($package) { print STDERR "E: Package not found: $packagename\n"; exit(100); } sub revdeps { my $rdepsref = shift; my $depsref; my $parent; foreach(@$rdepsref) { undef($parent); $parent->{name} = $_->{ParentPkg}{Name}; $parent->{ver} = $_->{ParentVer}{VerStr}; $parent->{current_state} = $cache->{$_->{ParentPkg}{Name}}->{CurrentState}; $parent->{selected_state} = $cache->{$_->{ParentPkg}{Name}}->{SelectedState}; $parent->{deptype} = $_->{DepType}; $parent->{targetname} = $_->{TargetPkg}{Name}; if ($_->{TargetVer}) { $parent->{depsign} = $_; $parent->{depver} = $_; } $depsref->{$parent->{name}} = $parent; } return($depsref); } sub why { my $revdeps = revdeps(shift); my $why; foreach(keys(%$revdeps)) { if ($revdeps->{$_}->{current_state} eq 'Installed' and $revdeps->{$_}->{deptype} !~ /^(Conflicts|Replaces|Obsoletes)$/) { $why->{$_} = $revdeps->{$_}; } } return($why); } sub why_not { my $revdeps = revdeps(shift); my $why_not; foreach(keys(%$revdeps)) { if ($revdeps->{$_}->{current_state} eq 'Installed' and $revdeps->{$_}->{deptype} =~ /^(Conflicts|Replaces|Obsoletes)$/) { $why_not->{$_} = $revdeps->{$_}; } } return($why_not); } sub short_states { my $pkg = shift; my $state = ''; switch($pkg->{selected_state}) { case('Unkwnon') { $state .= ' '; } case('Install') { $state .= 'i'; } case('Hold') { $state .= 'h'; } case('DeInstall') { $state .= 'r'; } case('Purge') { $state .= 'p'; } } switch($pkg->{current_state}) { case('Installed') { $state .= 'i'; } case('UnPacked') { $state .= 'u'; } case('HalfConfigured') { $state .= 'f'; } case('HalfInstalled') { $state .= 'h'; } case('ConfigFiles') { $state .= 'c'; } case('NotInstalled') { $state .= ' '; } } return($state); } sub print_deps { my $deps = shift; foreach(keys(%$deps)) { printf "%-2s %-30s %-15s %s\n", short_states($deps->{$_}), $deps->{$_}->{name}, $deps->{$_}->{deptype}, $deps->{$_}->{targetname}; } } print "State: $package->{CurrentState}\n"; if ($package->{Flags} =~ /Essential/) { print "Essential: yes\n"; } if ($not) { print_deps(why_not($package->{RevDependsList})); } else { print_deps(why($package->{RevDependsList})); } __END__ =head1 NAME apt-why - filtered reverse dependency displayer using AptPkg::Cache =head1 SYNOPSIS B [ B<--not> ] I =head1 DESCRIPTION B displays various informations based on a Is reverse dependencies The output is prefixed by two charactes, the former representing the desired package state, the latter the current state. The states are Install, Iold, Iemove (deinstall), I

urge, Inpacked, halI configured, Ialf installed, Ionfigfiles installed. An empty field means not installed. If B<--not> is specified, reverse dependencies prohibiting the installation of I are shown. Else, reverse dependencies justifying the installation of I are shown =head1 AUTHOR Daniel Friesel =head1 LICENSE 0. You just DO WHAT THE FUCK YOU WANT TO.