#!/usr/bin/perl -w # # Module: show_version # # **** License **** # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # This code was originally developed by Vyatta, Inc. # Portions created by Vyatta are Copyright (C) 2005, 2006, 2007 Vyatta, Inc. # All Rights Reserved. # # Author: Rick Balocca # Date: 2007 # Description: # # **** End License **** # use strict; use warnings; # # Global hash of debians in the base install and now. # my $rHoH_base_debs; my $rHoH_now_debs; my $base = '/opt/vyatta/etc'; my $versionfile = "$base/version"; my $buildfile = "$base/build.txt"; my $debsfile = "$base/deb-versions.txt"; sub echo_file { my ($file) = @_; my @lines = (); if (!(-e $file)) { return @lines; } open(my $FH, '<', $file) or die "Unable to open [$file]\n"; @lines=<$FH>; close($FH); return @lines; } # # convert the "dpkg -l" output have same format as deb-versions.txt # sub get_pkg_version { my @lines = @_; my @new_lines = (); foreach my $line (@lines) { if ($line =~ /^[D\|\+]/) { next; # skip header } my ($status, $pkg, $version) = split(/[ \t\n]+/, $line, 4); if ($status =~ /^i/) { push(@new_lines, "$pkg $version"); } } return @new_lines; } sub read_pkg_file { my @pkgs_list = @_; my %HoH = (); my ($name, $version); foreach my $line (@pkgs_list) { ($name, $version) = split(/[ \t\n]+/, $line, 3); $HoH{$name}{'version'} = $version; } return \%HoH; } sub show_added { for my $name (sort keys %$rHoH_now_debs) { if (!$rHoH_base_debs->{$name}) { printf("Aii %-25s %-25s\n", $name, $rHoH_now_debs->{$name}->{'version'}); } } } sub show_deleted { for my $name (sort keys %$rHoH_base_debs) { if (!$rHoH_now_debs->{$name}) { printf("X %-25s %-25s\n", $name, $rHoH_base_debs->{$name}->{'version'}); } } } sub show_upgraded_downgraded { my ($up_down) = @_; my ($symbol, $op, $ver_base, $ver_now, $cmd); if ($up_down eq "upgraded") { $symbol = "U"; $op = "lt"; } else { $symbol = "D"; $op = "gt"; } for my $name (sort keys %$rHoH_base_debs) { if ($rHoH_now_debs->{$name}) { $ver_base = $rHoH_base_debs->{$name}{'version'}; $ver_now = $rHoH_now_debs->{$name}{'version'}; if ($ver_base ne $ver_now) { $cmd = "dpkg --compare-versions \"$ver_base\" $op \"$ver_now\""; if (!system($cmd)) { printf("%sii %-25s %-20s (baseline: %s)\n", $symbol, $name, $ver_now, $ver_base); } } } } } sub show_upgraded { show_upgraded_downgraded("upgraded"); } sub show_downgraded { show_upgraded_downgraded("downgraded"); } sub show_all { show_added(); show_deleted(); show_upgraded(); show_downgraded(); } my %options = ( "added" => \&show_added, "deleted", => \&show_deleted, "upgraded" => \&show_upgraded, "downgraded" => \&show_downgraded, "all" => \&show_all, ); # # main # print(&echo_file($versionfile)); print(&echo_file($buildfile)); my $booted = `grep -e '^unionfs.*/filesystem.squashfs' -e '^aufs.*/filesystem.squashfs' /proc/mounts`; if (defined($booted) && $booted ne "") { $booted="livecd"; } else { my $image_boot = `grep -e '^unionfs / unionfs.*squashfs=ro' /proc/mounts`; if ($image_boot ne "") { $booted="image"; } else { $booted="disk"; } } print "Boot via: $booted\n"; my $uptime = `uptime`; if (defined $uptime && $uptime ne "") { print "Uptime: $uptime\n"; } if (!(-e $debsfile)) { exit 0; } print "\n"; $rHoH_base_debs = read_pkg_file(&echo_file($debsfile)); $rHoH_now_debs = read_pkg_file(get_pkg_version(`dpkg -l`)); if ($#ARGV == 0) { if ($options{$ARGV[0]}) { $options{$ARGV[0]}->(); } else { print "Usage: showversion [added|deleted|upgraded|downgraded|all]\n"; exit 1; } } # end of file