- Added new getmetadata function for easy access to all available
  metadata of a pak without knowledge about or need to parse
  pakfire internal db files.
- Added new 'pakfire info' functionality for displaying all available
  metadata of (a) pak(s) to the user, using the new getmetadata.
- Use getmetadata function in services.cgi to determine installed
  addon services to display. Removing code duplication and intel that
  should only be known by pakfire itself.

Signed-off-by: Robin Roevens <robin.roevens(a)disroot.org>
---
 html/cgi-bin/services.cgi    | 81 ++++++++++++++++++------------------
 src/pakfire/lib/functions.pl | 55 ++++++++++++++++++++++++
 src/pakfire/pakfire          | 58 ++++++++++++++++++++++++++
 3 files changed, 154 insertions(+), 40 deletions(-)

diff --git a/html/cgi-bin/services.cgi b/html/cgi-bin/services.cgi
index 237475735..896c95ec3 100644
--- a/html/cgi-bin/services.cgi
+++ b/html/cgi-bin/services.cgi
@@ -29,6 +29,7 @@ require '/var/ipfire/general-functions.pl';
 require "${General::swroot}/lang.pl";
 require "${General::swroot}/header.pl";
 require "${General::swroot}/graphs.pl";
+require "/opt/pakfire/lib/functions.pl";
 
 my %color = ();
 my %mainsettings = ();
@@ -160,51 +161,51 @@ END
 
 	my $lines=0; # Used to count the outputlines to make different bgcolor
 
-	# Generate list of installed addon pak's
-	opendir (DIR, "/opt/pakfire/db/installed") || die "Cannot opendir /opt/pakfire/db/installed/: $!";
-	my @pak = sort readdir DIR;
-	closedir(DIR);
-
-	foreach (@pak){
-		chomp($_);
-		next unless (m/^meta-/);
-		s/^meta-//;
-
-		# Check which of the paks are services
-		if (-e "/etc/init.d/$_") {
-			# blacklist some packages
-			#
-			# alsa has trouble with the volume saving and was not really stopped
-			# mdadm should not stopped with webif because this could crash the system
-			#
-			if ( $_ eq 'squid' ) {
-				next;
-			}
-			if ( ($_ ne "alsa") && ($_ ne "mdadm") ) {
-				$lines++;
-				if ($lines % 2){
-					print "<tr>";
-					$col="bgcolor='$color{'color22'}'";
-				}else{
-					print "<tr>";
-					$col="bgcolor='$color{'color20'}'";
-				}
+	my @paks;
+	my @addon_services;
 
-				print "<td align='left' $col width='31%'>$_</td> ";
-				my $status = isautorun($_,$col);
-				print "$status ";
-				print "<td align='center' $col width='8%'><a href='services.cgi?$_!start'><img alt='$Lang::tr{'start'}' title='$Lang::tr{'start'}' src='/images/go-up.png' border='0' /></a></td>";
-				print "<td align='center' $col width='8%'><a href='services.cgi?$_!stop'><img alt='$Lang::tr{'stop'}' title='$Lang::tr{'stop'}' src='/images/go-down.png' border='0' /></a></td> ";
-				my $status = &isrunningaddon($_,$col);
-		 		$status =~ s/\\[[0-1]\;[0-9]+m//g;
-
-				chomp($status);
-				print "$status";
-				print "</tr>";
+	# Generate list of installed addon pak services
+	my %paklist = &Pakfire::dblist("installed");
+
+	foreach my $pak (keys %paklist) {
+		my %metadata = &Pakfire::getmetadata($pak, "installed");
+			
+		if ("$metadata{'Services'}") {
+			foreach my $service (split(/ /, "$metadata{'Services'}")) {
+				push(@addon_services, $service);
 			}
 		}
 	}
 
+	foreach (@addon_services) {
+		$lines++;
+		if ($lines % 2){
+			print "<tr>";
+			$col="bgcolor='$color{'color22'}'";
+		}else{
+			print "<tr>";
+			$col="bgcolor='$color{'color20'}'";
+		}
+		print "<td align='left' $col width='31%'>$_</td> ";
+		my $status = isautorun($_,$col);
+		print "$status ";
+		# Don't allow user to start/stop folowing services from webui:
+		#  - alsa has trouble with the volume saving and was not really stopped
+		if ($_ eq "alsa") {
+			print "<td align='center' $col width='8%'></td>";
+			print "<td align='center' $col width='8%'></td> ";
+		} else {
+			print "<td align='center' $col width='8%'><a href='services.cgi?$_!start'><img alt='$Lang::tr{'start'}' title='$Lang::tr{'start'}' src='/images/go-up.png' border='0' /></a></td>";
+			print "<td align='center' $col width='8%'><a href='services.cgi?$_!stop'><img alt='$Lang::tr{'stop'}' title='$Lang::tr{'stop'}' src='/images/go-down.png' border='0' /></a></td> ";
+		}
+		my $status = isrunningaddon($_,$col);
+		$status =~ s/\\[[0-1]\;[0-9]+m//g;
+
+		chomp($status);
+		print "$status";
+		print "</tr>";
+	}
+
 	print "</table></div>\n";
 	&Header::closebox();
 
diff --git a/src/pakfire/lib/functions.pl b/src/pakfire/lib/functions.pl
index 028a0277e..6dda8d688 100644
--- a/src/pakfire/lib/functions.pl
+++ b/src/pakfire/lib/functions.pl
@@ -115,6 +115,7 @@ sub usage {
   &Pakfire::message("               <update> - Contacts the servers for new lists of paks.");
   &Pakfire::message("               <upgrade> - Installs the latest version of all paks.");
   &Pakfire::message("               <list> [installed/notinstalled/upgrade] - Outputs a list with all, installed, available or upgradeable paks.");
+  &Pakfire::message("               <info> <pak> [<pak> ...] - Output pak metadata.");
   &Pakfire::message("               <status> - Outputs a summary about available core upgrades, updates and a required reboot");
   &Pakfire::message("");
   &Pakfire::message("       Global options:");
@@ -674,6 +675,60 @@ sub parsemetafile {
 	return %metadata;
 }
 
+sub getmetadata {
+	### This subroutine returns a hash of available info for a package
+	#   Pass package name and type of info as argument: Pakfire::getmetadata(package, type_of_info) 
+	#	Type_of_info can be "latest" or "installed"
+	#   Usage is always with two argument.
+	my ($pak, $type) = @_;
+
+	my %metadata = (
+		Name => $pak, 
+		Installed => "no",
+		Available => "no");
+	my %installed_metadata = ();
+
+	my @templine;
+	my @file;
+
+	### Get available version information
+	if ("$type" eq "latest") {
+		### Check if package is in packages_list and get latest available version
+		my %db = Pakfire::dblist("all");
+		
+		if (defined $db{$pak}) {
+			### Get and parse latest available metadata
+			if (getmetafile("$pak")) {
+				%metadata = parsemetafile("$Conf::dbdir/meta/meta-$pak");
+
+				$metadata{'Available'} = "yes";
+				### Rename version info fields
+				$metadata{'AvailableProgVersion'} = delete $metadata{'ProgVersion'};
+				$metadata{'AvailableRelease'} = delete $metadata{'Release'};
+			}
+		}
+	}
+	
+	### Parse installed pak metadata
+	if (&isinstalled($pak) == 0) {
+	    %installed_metadata = parsemetafile("$Conf::dbdir/installed/meta-$pak");
+
+		if ("$type" eq "latest" && exists($metadata{'AvailableProgVersion'})) {
+			### Add installed version info to latest metadata
+			$metadata{'ProgVersion'} = $installed_metadata{'ProgVersion'};
+			$metadata{'Release'} = $installed_metadata{'Release'};
+		} else {
+			### Use metadata of installed pak
+			%metadata = %installed_metadata;
+		}
+		$metadata{'Installed'} = 'yes';
+	} else {
+		$metadata{'Installed'} = 'no';
+	}
+
+	return %metadata;
+}
+
 sub decryptpak {
 	my $pak = shift;
 
diff --git a/src/pakfire/pakfire b/src/pakfire/pakfire
index 0ed8aacd4..9935481a5 100644
--- a/src/pakfire/pakfire
+++ b/src/pakfire/pakfire
@@ -387,6 +387,64 @@
 		} else {
 			&Pakfire::message("PAKFIRE WARN: No packages where found using filter $filter.");
 		}
+	} elsif ("$ARGV[0]" eq "info") {
+		shift;
+
+		my @paks;
+		my $pak;
+		foreach $pak (@ARGV) {
+			unless ("$pak" =~ "^-") {
+				push(@paks,$pak);
+			}
+		}
+
+		unless ("@paks") {
+			Pakfire::message("PAKFIRE ERROR: missing package name");
+			Pakfire::usage;
+			exit 1;
+		}
+
+		foreach $pak (@paks) {
+			my %metadata = Pakfire::getmetadata($pak, "latest");
+
+			### Check if pakfile was actually found
+			if ($metadata{'Installed'} eq "no" && $metadata{'Available'} eq "no") {
+				Pakfire::message("PAKFIRE WARN: Pak '$pak' not found.");
+				last;
+			}
+
+			unless (defined $metadata{'Available'}) {
+				Pakfire::message("PAKFIRE WARN: Unable to retrieve latest metadata for $pak. Information may be outdated.")
+			}
+
+			### Printout metadata in a user friendly format
+			print "Name: $metadata{'Name'}\n";
+			print "Summary: $metadata{'Summary'}\n";
+			if ($metadata{'Available'} eq "yes") {
+				print "Version: $metadata{'AvailableProgVersion'}-$metadata{'AvailableRelease'}\n";
+			} else {
+				print "Version: $metadata{'ProgVersion'}-$metadata{'Release'}\n";
+			}
+			print "Size: " . Pakfire::beautifysize("$metadata{'Size'}") . "\n";
+			print "Dependencies: $metadata{'Dependencies'}\n";
+			print "Pakfile: $metadata{'File'}\n";
+			print "Service InitScripts: $metadata{'Services'}\n";
+			print "Installed: $metadata{'Installed'}\n";
+			### Generate a pak status message
+			if (! defined $metadata{'Available'}) {
+				print "Status: unknown (an error occured retrieving latest pak metadata)";
+			} elsif ($metadata{'Available'} eq "no") {
+				print "Status: obsolete (version $metadata{'ProgVersion'}-$metadata{'Release'} is installed)\n";
+			} elsif ($metadata{'Installed'} eq "yes" && "$metadata{'Release'}" < "$metadata{'AvailableRelease'}") {
+				print "Status: outdated (version $metadata{'ProgVersion'}-$metadata{'Release'} is installed)\n";
+			} elsif ($metadata{'Installed'} eq "yes") {
+				print "Status: up-to-date\n";
+			} else {
+				print "Status: not installed\n";
+			}
+			print "\n";
+		}
+
 	} elsif ("$ARGV[0]" eq "resolvedeps") {
 		foreach (@ARGV) {
 			next if ("$_" eq "resolvedeps");
-- 
2.34.1


-- 
Dit bericht is gescanned op virussen en andere gevaarlijke
inhoud door MailScanner en lijkt schoon te zijn.