History of Free and Open Source Software. From the university lab to the enterprise. New Zealand Computer Society Innovation Conference.
Thanks to Evonne Cheung for her awesome graphics!
8. #!/usr/bin/perl foreach (@pkglines) {
# close REASON or chomp;
# This program is free software; you can redistribute it and/or modify die "Can't close FILE [$file]: $!n"; $linenbr++;
# it under the terms of the GNU General Public License as published by } if (/^Package:/) {
# the Free Software Foundation; either version 2 of the License, or ($label, $pkg) = split(/:s+/,$_,2);
# (at your option) any later version. # $pkgcnt++;
# # Main program starts here. printf "pkg(%4.4d) pkg=[%s]n",$pkgcnt,$pkg if $debug >= 1;
# This program is distributed in the hope that it will be useful, # $has_pkg = 1; ### we have necessary section
# but WITHOUT ANY WARRANTY; without even the implied warranty of GetOptions('q|quiet' => $quiet, next;
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 's|sparse' => $sparse, }
# GNU General Public License for more details. 'e|explain!' => $explain, if (/^Status:/) {
# 'reason-dir=s' => $reasondir, my $label = "";
'd|debug+' => $debug, ($label, $pkgstatus) = split(/:s+/,$_,2);
use strict; 'h|help' => $help); print "tpkgstatus=[$pkgstatus]n" if $debug >= 1;
use warnings; $pkg_status{$pkg} = $pkgstatus;
if ($help) { ($plan, $state, $status) = split(/s+/,$pkgstatus);
use Getopt::Long; usage(); print "ttplan=[$plan]n" if $debug >= 1;
exit 0; print "ttstate=[$state]n" if $debug >= 1;
# Declaration of important/main variables. } print "ttstatus=[$status]n" if $debug >= 1;
my $quiet = 0; $has_status = 1; ### we have necessary section
my $sparse = 0; opendir(REASONDIR, $reasondir) or next;
my $help = 0; die "Can't open DIR [$reasondir]: $!n"; }
my $explain = 1; # Parse all the reason files in $reasondir except those beginning with if (/^Section:/) {
my $debug = 0; # a . or ending with a ~ my $label = "";
my $reasondir = '/usr/share/vrms/reasons/'; parse_reason_file("$reasondir/$_") ($label, $section) = split(/:s+/,$_,2);
my %reason = (); foreach (grep {!/~$/ && !/^./} readdir(REASONDIR)); print "tsection=[$section]n" if $debug >= 1;
closedir REASONDIR or $has_section = 1; ### we have necessary section
# die "Can't close DIR [$reasondir]: $!n"; if ($section =~ /contrib|non-free|restricted|multiverse/) {
# Auxiliary functions section (FIXME: put them in a file by themselves). ### read thru rest of array to find descr instead of waiting for it
source code
# my $statusfile = '/var/lib/dpkg/status'; my $found_descr =0;
my $is_nonfree = 0; ### preset none found, yet while (! $found_descr) {
# sub usage: my %nonfree = (); if ($linenbr > $#pkglines) {
# Input: nothing. my $is_other_nonfree = 0; ### preset none found, yet ### iff badly formed entry ensure blank description
# Output: Messages to stdout telling the usage of the program. my %other_nonfree = (); print "tEEEE shortdescr=[$shortdescr]n" if $debug >= 1;
sub usage() { my $is_contrib = 0; ### preset none found, yet last;
print <<EOF; my %contrib = (); }
Usage: vrms [OPTIONS] ... my $is_other_contrib = 0; ### preset none found, yet my $dline = $pkglines[$linenbr++];
my %other_contrib = (); if($dline =~ /^Description:/) {
--quiet, -q Do nothing if there are no non-free packages installed. my %pkg_status = (); ($label, $shortdescr) = split(/:s+/,$dline,2);
--explain, -e Give a brief explanation of why a package is non-free, my $pkgcnt = 0; print "tshortdescr=[$shortdescr]n" if $debug >= 1;
if available. my $clumpcnt = 0; $found_descr = 1;
--sparse, -s Just list non-free packages, nothing else. my $dontcarelines = 5; ### no. of lines a non-installed entry may have in the }
--reason-dir=DIR Use DIR as the reason directory. statusfile }
--help, -h Display this help. if ($section =~ /contrib/) {
--debug, -d Generate debugging information. if (lc $status eq 'installed') {
my $sysname = ""; $is_contrib = 1;
All options can be prefixed with "no" (eg: --noexplain) to turn them off. chop($sysname = `uname -n`); $contrib{$pkg} = $shortdescr;
EOF } else {
} open(PKG_SOURCE, "< $statusfile") or $is_other_contrib = 1;
die "Can't open FILE [$statusfile]: $!n"; $other_contrib{$pkg} = $shortdescr;
# sub parse_reason_file: }
# Input: the name of a reason file and the global hash %reason $/ = ""; ### snarf a paragraph at a time } else {
# Output: the hash %reason filled with reasons from the input file while(<PKG_SOURCE>) { if (lc $status eq 'installed') {
# (FIXME: %reason shouldn't be global) my $clump = $_; $is_nonfree = 1;
sub parse_reason_file { $clumpcnt++; $nonfree{$pkg} = $shortdescr;
my $file = shift; my (@pkglines) = split(/n/, $clump); } else {
print "Parsing reason file $filen" if $debug >= 1; ### iff more than $dontcarelines lines, package is installed, so process it $is_other_nonfree = 1;
open(REASON, "<", $file) or ### (speed-up by skipping don't-care entries) $other_nonfree{$pkg} = $shortdescr;
die "Can't open FILE [$file]: $!n"; if (@pkglines > $dontcarelines) { }
my $pkg = ""; ### name of this package }
while (my $line = <REASON>) { my $pkgstatus = ""; ### status }
chomp $line; my $plan = ""; ### install plan (hold, deinstall, purge, install, etc.) last; ### this is last desriptor of package we care about so end loop
# Grab a line of the form 'package: reason', skip if we don't match my $state = ""; ### state (ok or ???) } else {
my ($pkg, $reason) = ($line =~ /^(S+):s+(.*)s*$/) or next; my $status = ""; ### status (installed, not-installed, etc.) ### un-processed lines from package info
print "'$pkg' because '$reason'n" if ($debug >= 1); my $section = ""; ### section this is where non-free is marked if($debug >= 1) {
my $shortdescr = ""; ### one-liner description of pkg print "tt--- $_n";
# If this is _our_ master file, then prefer anything my $linenbr = 0; ### current line number of this pkackag's info }
# else (so that package maintainers can override) my $label = ""; ### junk field (not used, except to catch split values) }
next if exists $reason{$pkg} and $file =~ //vrms$/; my $has_pkg = 0; ### reset the markers }
my $has_status = 0; if (!$has_status or !$has_pkg) {
$reason{$pkg} = $reason; my $has_section = 0; print STDERR "vrms: ERROR- Badly formed dpkg-status entry #$clumpcnt!n";
} print STDERR " pkg=[$pkg], pkgstatus=[$pkgstatus], section=[$section] n";
}
88. Photo credits:
ibm 360 with people: http://www.flickr.com/photos/cote/54408562/sizes/l/in/photostream/
cdc6600: https://secure.wikimedia.org/wikipedia/en/wiki/File:Personable_Computer.jpg
ken and dennis with medals: https://secure.wikimedia.org/wikipedia/commons/wiki/File:Medal_lg.jpeg
warrington logo: http://wikieducator.org/File:Warrington_logo.png
ashs logo: http://wikieducator.org/File:ASHS_logo.png
wanted poster: http://www.flickr.com/photos/mscaprikell/59580038/in/photostream/
tape: http://www.flickr.com/photos/leejordan/486911915/
tim o'reilly: https://secure.wikimedia.org/wikipedia/commons/wiki/File:Tim_O%27Reilly_in_Foo_China_200
fsf logo: https://secure.wikimedia.org/wikipedia/en/wiki/File:FSF-Logo.svg
tux: https://secure.wikimedia.org/wikipedia/commons/wiki/File:Tux.svg
open source: https://secure.wikimedia.org/wikipedia/commons/wiki/File:Opensource.svg
stock market: http://www.flickr.com/photos/thewalkingirony/3051500551/
android logo: https://secure.wikimedia.org/wikipedia/en/wiki/File:Android_logo.svg
in-flight entertainment: http://www.flickr.com/photos/kalleboo/2473197800/
samsung tv: http://www.flickr.com/photos/johannesfreund/2320330661/
Linus: http://en.wikipedia.org/wiki/File:Linus_Torvalds.jpeg
Bill Gates: http://en.wikipedia.org/wiki/File:Bill_Gates_in_WEF_,2007.jpg
Bruce Perens: [not CC] http://perens.com/press/photos/
Lawrence Lessig: http://en.wikipedia.org/wiki/File:Lessig_portrait.jpg
Jimmy Wales: http://en.wikipedia.org/wiki/File:Jimmy_Wales_Fundraiser_Appeal_edit.jpg
Steve Ballmer: http://en.wikipedia.org/wiki/File:Steve_ballmer_2007_outdoors2.jpg
us department of justice: https://secure.wikimedia.org/wikipedia/en/wiki/File:US-DeptOfJustice-Seal.svg