New CGI script for browsing installed software and documentation.
[sw-tools] / perl / SWList.pm
diff --git a/perl/SWList.pm b/perl/SWList.pm
new file mode 100644 (file)
index 0000000..e2e83be
--- /dev/null
@@ -0,0 +1,225 @@
+# -*-perl-*-
+#
+# $Id: SWList.pm,v 1.1 1999/07/30 18:46:37 mdw Exp $
+#
+# Create the main list of installed packages
+#
+# (c) 1999 EBI
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of sw-tools.
+#
+# sw-tools is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# sw-tools 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.
+# 
+# You should have received a copy of the GNU General Public License
+# along with sw-tools; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#----- Revision history -----------------------------------------------------
+#
+# $Log: SWList.pm,v $
+# Revision 1.1  1999/07/30 18:46:37  mdw
+# New CGI script for browsing installed software and documentation.
+#
+
+#----- Package header -------------------------------------------------------
+
+package SWList;
+
+use IO;
+use POSIX;
+
+use SWConfig;
+use SW;
+use SWCGI qw(:DEFAULT :layout);
+
+#----- Main code ------------------------------------------------------------
+
+# --- @list@ ---
+#
+# Action to output the installed software list.
+
+%archmap = ( "linux" => 'l',
+            "solaris" => 's',
+            "sunos" => 's',
+            "irix" => 'i',
+            "alpha" => 'a',
+            "hpux" => 'h' );
+            
+
+sub list {
+
+  my @arch = ();
+  my $narch = 0;
+
+  # --- Read the architecture table and assign mnemonic-ish letters ---
+
+  {
+    my $a = IO::File->new("$C{datadir}/archtab") or
+      barf("couldn't open archtab: $!");
+    my %mn = ();
+    LINE: while (my $line = $a->getline()) {
+
+      # --- Skip comments and boring things ---
+
+      chomp($line);
+      next LINE if $line =~ /^\s*$/ || $line =~ /^\s*\#/;
+
+      # --- Break into components ---
+
+      my ($arch, $host) = split(" ", $line, 3);
+
+      # --- Assign a mnemonic character ---
+      #
+      # In dire cases, this will choose multiple characters.  Oh, well.  If
+      # you have more than 26 architectures to maintain, this is the least of
+      # your worries.
+
+      my $mn = "";
+      my $hi;
+      foreach my $k (keys(%archmap)) {
+       if (index($arch, $k) >= 0 && !$mn->{$archmap{$k}}) {
+         $mn = $archmap{$k};
+         last;
+       }
+      }
+      unless ($mn) {
+       for (my $i = 0; $i < length($arch); $i++) {
+         my $ch = lc(substr($arch, $i, 1));
+         next unless $ch =~ /[a-z]/;
+         $mn = $ch, last unless $mn{$ch};
+       }
+      }
+      if ($mn) {
+       ($hi = $arch) =~ s:$mn:<u>$mn</u>:;
+      } else {
+       for ($mn = "a"; $mn{$mn}; $mn++) { }
+       $hi = "$arch (<u>$mn</u>)";
+      }
+      push(@arch, { arch => $arch, host => $host, mn => $mn, hi => $hi });
+    }
+  }
+  @arch = sort { length($a->{mn}) <=> length($b->{mn}) ||
+                  $a->{mn} cmp $b->{mn} } @arch;
+  $narch = @arch;
+
+  # --- Emit a header ---
+
+  header("Installed software");
+
+  print <<EOF;
+<h3>Documentation</h3>
+<ul>
+<li><a href="$ref?act=man">Manual pages</a>
+<li><a href="$ref?act=info">GNU Info</a>
+</ul>
+<hr>
+<h3>Installed software</h3>
+<table>
+<tr align=left>
+  <th rowspan=2>Package
+  <th rowspan=2>Version
+  <th rowspan=2 colspan=2>Maintainer
+  <th colspan=$narch>Architectures
+  <th rowspan=2>Date installed
+  <th rowspan=2>Doc
+EOF
+
+  # --- Spit out the archtecture mnemonics ---
+
+  print "<tr align=left>\n  ";
+  foreach my $a (@arch) { print "<th>" . $a->{mn}; }
+  print "\n";
+
+  # --- Iterate through the installed packages ---
+
+  my $sw = SW->new();
+  foreach my $pkg ($sw->list()) {
+    my $m = $sw->get($pkg);
+    print("<tr>\n");
+
+    # --- The package and version number are easy ---
+
+    print("  <td>$m->{package}\n");
+    print("  <td>$m->{version}\n");
+
+    # --- Resolve the maintainer into a sensible real name ---
+
+    {
+      my $maint = $m->{"maintainer"};
+      my @pw = getpwnam($maint);
+      my ($gecos) = split(/,/, $pw[6], 2);
+      my $addr = $maint . ($C{domain} && "\@" . $C{domain});
+      print("  <td>$gecos<td>&lt;<a href=\"mailto:$addr\">$addr</a>&gt;\n");
+    }
+
+    # --- Dump out the architectures ---
+    #
+    # Assume that the names aren't ambiguous.
+
+    {
+      my %a = ();
+      foreach my $ar (split(/[\s,]+/, $m->{"arch"})) {
+       next unless $ar;
+       foreach my $a (@arch) {
+         if ($a->{arch} =~ /^$ar/) {
+           $a{$a->{arch}} = 1;
+           last;
+         }
+       }
+      }
+
+      print("  ");
+      foreach my $a (@arch) {
+       if ($a{$a->{arch}}) {
+         print("<td>", $a->{mn});
+       } else {
+         print("<td>");
+       }
+      }
+      print("\n");
+    }
+
+    # --- Print the date ---
+
+    print("  <td>$m->{date}\n");
+
+    # --- If the documentation file exists, put a link in ---
+
+    if (-r "$C{doc}/$pkg") {
+      print("  <td><a href=\"$ref?act=doc&pkg=$pkg\">Yes</a>\n");
+    } else {
+      print("  <td>No\n");
+    }
+  }
+
+  # --- Finish up ---
+
+  print "</table>\n";
+
+  # --- Emit a legend for the architecture lists ---
+
+  print "<p><b>Architectures:</b>\n";
+  foreach my $a (@arch) {
+    print $a->{hi}, "\n";
+  }
+  footer();
+}
+
+#----- Register actions -----------------------------------------------------
+
+$main::ACT{"list"} = \&list;
+
+#----- That's all, folks ----------------------------------------------------
+
+1;