Index: main/trunk/package-kits/linux/distros/arch
===================================================================
--- main/trunk/package-kits/linux/distros/arch	(revision 29529)
+++ main/trunk/package-kits/linux/distros/arch	(revision 29536)
@@ -1,4 +1,3 @@
 MANAGER:                pacman
-FIELD_SEPARATOR:        \n
 
 SYSTEMLIB:              /usr/lib
@@ -11,8 +10,4 @@
 GLI:                    /opt/gli
 
-PKG_GREENSTONE:         'greenstone'
-PKG_GREENSTONE_TOOLS:   'greenstone-tools'
-PKG_GREENSTONE_DEMO:    'greenstone-demo'
-PKG_GLI:                'gli'
 PKG_SVN:                'svn'
 PKG_JAVA_JRE:           'java-runtime=7'
Index: main/trunk/package-kits/linux/distros/fedora
===================================================================
--- main/trunk/package-kits/linux/distros/fedora	(revision 29529)
+++ main/trunk/package-kits/linux/distros/fedora	(revision 29536)
@@ -1,4 +1,3 @@
 MANAGER:                rpm
-FIELD_SEPARATOR:        ,
 
 SYSTEMLIB:              /usr/lib
@@ -11,8 +10,4 @@
 GLI:                    /usr/share/gli
 
-PKG_GREENSTONE:         greenstone,
-PKG_GREENSTONE_TOOLS:   greenstone-tools,
-PKG_GREENSTONE_DEMO:    greenstone-demo,
-PKG_GLI:                gli,
 PKG_SVN:                svn,
 PKG_JAVA_JRE:           java >= 7,
Index: main/trunk/package-kits/linux/distros/ubuntu
===================================================================
--- main/trunk/package-kits/linux/distros/ubuntu	(revision 29529)
+++ main/trunk/package-kits/linux/distros/ubuntu	(revision 29536)
@@ -1,4 +1,3 @@
 MANAGER:                apt
-FIELD_SEPARATOR:        ,
 
 SYSTEMLIB:              /usr/lib
@@ -11,8 +10,4 @@
 GLI:                    /opt/gli
 
-PKG_GREENSTONE:         greenstone,
-PKG_GREENSTONE_TOOLS:   greenstone-tools,
-PKG_GREENSTONE_DEMO:    greenstone-demo,
-PKG_GLI:                gli,
 PKG_SVN:                subversion,
 PKG_JAVA_JRE:           default-jre,
Index: main/trunk/package-kits/linux/generate
===================================================================
--- main/trunk/package-kits/linux/generate	(revision 29529)
+++ main/trunk/package-kits/linux/generate	(revision 29536)
@@ -2,6 +2,4 @@
 
 # Generates Makefiles for different systems and packages
-# Uses a hashmap to do config variables  (see readvar for how variables are
-#  read in and an example of how they are resolved / used)
 
 use strict;
@@ -9,9 +7,7 @@
 use utf8;
 use File::Basename;
-use File::Path 'make_path';
-use File::Copy 'cp';
-use Storable 'dclone';
-use Digest::MD5;
-
+use lib 'perllib';
+use Greenstone::Helpers;
+use Greenstone::Package;
 
 my $USAGE = "Usage: " . basename($0) . " <distros> <packages>
@@ -24,167 +20,15 @@
 $#ARGV == 1 or die $USAGE;
 
-sub globbify {
-    my ($dir, $files) = @_;
-    $files =~ /^all$/i and return glob "$dir/*";
-    my @list = glob "$dir/{$files}";
-    for (@list) {
-        -f or die "Could not find '", $_, "'";
-    }
-    return @list;
-}
+my @distros  = lsfiles "distros",  shift;
+my @packages = lsfiles "packages", shift;
 
-sub empty {
-    shift =~ /^\s*$/ and return 1;
-}
-
-sub comment {
-    shift =~ /^\s*#/ and return 1;
-}
-
-sub trim {
-    for (@_) {
-        s/^\s+|\s+$//g;
-    }
-    return @_;
-}
-
-sub add {
-    my ($src, $dst, $subst) = @_;
-    $dst =~ s/@([\w]+)@/$subst->{$1}/g;
-
-    if (-d $src) {
-        mkdir $dst;
-        opendir my $DIRFH, $src or die "Could not open '$src': $!";
-        while (readdir $DIRFH) {
-            next if ($_ eq '.' or $_ eq '..');
-            add ("$src/$_", "$dst/$_", $subst);
-        }
-        closedir $DIRFH;
-    } else {
-        print '    - ', $dst, "\n";
-        if (-B $src or $src =~ /\.patch$/i) {
-            # copy binary file
-            cp $src, $dst or die "Failed to copy '$src': $!";
-        } else {
-            # copy normal file
-            open IN, '<', $src
-                or die "Failed to open '$src' for reading: $!";
-            open OUT, '>', $dst
-                or die "Failed to open '$dst' for writing: $!";
-            while (<IN>) {
-                s/@([\w]+)@/$subst->{$1}/g;
-                print OUT;
-            }
-            my $perms = (stat IN)[2] & 07777;
-            close IN;
-            close OUT;
-            chmod ($perms | 0600, $dst);
-        }
+for my $distro (@distros) {
+    print $distro, "\n";
+    for my $package (@packages) {
+        print "  - ", $package, "\n";
+        makepkg (
+            package => $package,
+            distro  => $distro
+        );
     }
 }
-
-my %escape = (
-    "n" => "\n",
-    "\\" => "\\",
-    " " => " "
-);
-
-sub readvar {
-    my ($vars, $line) = @_;
-    my ($var, $val) = trim (split ":", $line, 2);
-    defined $var and defined $val or die "Invalid variable assignment: '$line'";
-    local $/ = '';
-    $val =~ s/@([\w]+)@/$vars->{$1}/g;
-    $val =~ s/\\([ \\n]|$)/$escape{$1}/g;
-    $vars->{$var} = $val;
-}
-
-sub addsource {
-    my ($vars, $source) = @_;
-    my $md5 = Digest::MD5->new;
-    open my $MD5FH, '<', $source;
-    binmode $MD5FH;
-    $md5->addfile ($MD5FH);
-    my $field_separator = $vars->{'FIELD_SEPARATOR'};
-    $vars->{'SOURCES'} .= $field_separator . basename($source);
-    $vars->{'SOURCE_SUMS'} .= $field_separator . $md5->hexdigest;
-    close $MD5FH;
-}
-
-my @distros  = globbify "distros",  shift;
-my @packages = globbify "packages", shift;
-
-for my $dconf (@distros) {
-    my $distro = basename $dconf;
-    print "$distro\n";
-
-    open DISTRO, '<', $dconf;
-    my %distro_vars;
-    while (my $var = <DISTRO>) {
-        chomp $var;
-        (comment $var or empty $var) and next;
-        readvar \%distro_vars, $var;
-    }
-    close DISTRO;
-
-    for my $pconf (@packages) {
-        my $package = basename $pconf;
-        print " - $package\n";
-        my $package_path = "build/$distro/$package";
-        make_path $package_path;
-
-        open PACKAGE, '<', $pconf;
-        my %package_vars = %{dclone \%distro_vars};
-        while (my $var = <PACKAGE>) {
-            chomp $var;
-            empty $var and last;
-            comment $var and next;
-            readvar \%package_vars, $var;
-        }
-        for (keys %package_vars) {
-            defined $package_vars{$_} or $package_vars{$_} = ' ';
-            # print "$_ = $package_vars{$_}\n";
-        }
-
-        while (my $file = <PACKAGE>) {
-            chomp $file;
-            empty $file and last;
-            comment $file and next;
-            add ("files/$file", "$package_path/$file", \%package_vars);
-            addsource (\%package_vars, "$package_path/$file");
-        }
-
-        # write the makefile
-        my $outfile = "$package_path/Makefile";
-        print "    - $outfile\n";
-        open MAKEFILE, '>', $outfile
-            or die "Failed to open '$outfile' for writing: $!";
-        while (my $segment = <PACKAGE>) {
-            chomp $segment;
-            empty $segment and last;
-            comment $segment and next;
-            open IN, '<', "segments/$segment"
-                or die "Failed to open 'segments/$segment' for reading: $!";
-            while (<IN>) {
-                s/@([\w]+)@/$package_vars{$1}/g;
-                print MAKEFILE;
-            }
-            close IN;
-            print MAKEFILE "\n";
-        }
-        close PACKAGE;
-        # add a target for packaging
-        if (open IN, '<', "segments/$distro_vars{'MANAGER'}") {
-            while (<IN>) {
-                s/@([\w]+)@/$package_vars{$1}/g;
-                print MAKEFILE;
-            }
-            close IN;
-        }
-        close MAKEFILE;
-        addsource \%package_vars, $outfile;
-
-        # write the package manager files
-        add ("managers/$distro_vars{'MANAGER'}", $package_path, \%package_vars);
-    }
-}
Index: main/trunk/package-kits/linux/global.conf
===================================================================
--- main/trunk/package-kits/linux/global.conf	(revision 29536)
+++ main/trunk/package-kits/linux/global.conf	(revision 29536)
@@ -0,0 +1,4 @@
+PKG_GREENSTONE:         'greenstone'
+PKG_GREENSTONE_TOOLS:   'greenstone-tools'
+PKG_GREENSTONE_DEMO:    'greenstone-demo'
+PKG_GLI:                'greenstone-gli'
Index: main/trunk/package-kits/linux/packages/demo
===================================================================
--- main/trunk/package-kits/linux/packages/demo	(revision 29529)
+++ main/trunk/package-kits/linux/packages/demo	(revision 29536)
@@ -1,4 +1,4 @@
 SVN_LOCATION:           http://svn.greenstone.org/main/trunk/greenstone3/web/sites/localsite/collect
-NAME:                   greenstone-demo
+NAME:                   @PKG_GREENSTONE_DEMO@
 VERSION:                3.06
 RELEASE:                1
@@ -9,14 +9,26 @@
 LICENSE_SHORT:          GPL-2
 LICENSE:                license
-DEPENDS:                @PKG_GREENSTONE@
-OPTDEPENDS:             
-MAKEDEPENDS:            @PKG_GREENSTONE_TOOLS@ @PKG_SVN@ @PKG_RSYNC@
-PROVIDES:               
-FILES:                  @GSSRV@/sites/localsite/collect/*
 
-build-demo.sh
+DEPENDS:
+    @PKG_GREENSTONE@
 
-base
-src
-clean
-demo
+OPTDEPENDS:
+
+MAKEDEPENDS:
+    @PKG_GREENSTONE_TOOLS@
+    @PKG_SVN@
+    @PKG_RSYNC@
+
+PROVIDES:
+
+FILES:
+    @GSSRV@/sites/localsite/collect/*
+
+SOURCES:
+    build-demo.sh
+
+MAKEFILE:
+    base
+    src
+    clean
+    demo
Index: main/trunk/package-kits/linux/packages/gli
===================================================================
--- main/trunk/package-kits/linux/packages/gli	(revision 29529)
+++ main/trunk/package-kits/linux/packages/gli	(revision 29536)
@@ -1,4 +1,4 @@
 SVN_LOCATION:           http://svn.greenstone.org/main/trunk/gli
-NAME:                   greenstone-gli
+NAME:                   @PKG_GLI@
 VERSION:                3.06
 RELEASE:                1
@@ -9,14 +9,28 @@
 LICENSE_SHORT:          GPL-2
 LICENSE:                license
-DEPENDS:                @PKG_JAVA_JRE@ @PKG_GREENSTONE_TOOLS@
-OPTDEPENDS:             
-MAKEDEPENDS:            @PKG_JAVA_JDK@ @PKG_SVN@ @PKG_RSYNC@
-PROVIDES:               
-FILES:                  @GLI@\n%{_bindir}/*
 
-gli
+DEPENDS:
+    @PKG_JAVA_JRE@
+    @PKG_GREENSTONE_TOOLS@
 
-base
-src
-clean
-gli
+OPTDEPENDS:
+
+MAKEDEPENDS:
+    @PKG_JAVA_JDK@
+    @PKG_SVN@
+    @PKG_RSYNC@
+
+PROVIDES:
+
+FILES:
+    @GLI@
+    %{_bindir}/*
+
+SOURCES:
+    gli
+
+MAKEFILE:
+    base
+    src
+    clean
+    gli
Index: main/trunk/package-kits/linux/packages/main
===================================================================
--- main/trunk/package-kits/linux/packages/main	(revision 29529)
+++ main/trunk/package-kits/linux/packages/main	(revision 29536)
@@ -1,4 +1,4 @@
 SVN_LOCATION:           http://svn.greenstone.org/main/trunk/greenstone3
-NAME:                   greenstone
+NAME:                   @PKG_GREENSTONE@
 VERSION:                3.06
 RELEASE:                1
@@ -9,18 +9,41 @@
 LICENSE_SHORT:          GPL-2
 LICENSE:                license
-DEPENDS:                @PKG_JAVA_JRE@ @PKG_TOMCAT@
-OPTDEPENDS:             @PKG_GREENSTONE_DEMO@ @PKG_GREENSTONE_TOOLS@
-MAKEDEPENDS:            @PKG_JAVA_JDK@ @PKG_SVN@ @PKG_ANT@ @PKG_PATCH@ @PKG_AUTOCONF@ @PKG_GCC@ @PKG_MAKE@ @PKG_RSYNC@
-PROVIDES:               
-FILES:                  @GSSRV@\n@TOMCATCONF@/*\n@TOMCATLIB@/*\n%{_libdir}/*
 
-build.properties
-greenstone3.xml
-gs2build.patch
-perl-util.patch
+DEPENDS:
+    @PKG_JAVA_JRE@
+    @PKG_TOMCAT@
 
-base
-src
-clean
-build-core
-main
+OPTDEPENDS:
+    @PKG_GREENSTONE_DEMO@
+    @PKG_GREENSTONE_TOOLS@
+
+MAKEDEPENDS:
+    @PKG_JAVA_JDK@
+    @PKG_SVN@
+    @PKG_ANT@
+    @PKG_PATCH@
+    @PKG_AUTOCONF@
+    @PKG_GCC@
+    @PKG_MAKE@
+    @PKG_RSYNC@
+
+PROVIDES:
+
+FILES:
+    @GSSRV@
+    @TOMCATCONF@/*
+    @TOMCATLIB@/*
+    %{_libdir}/*
+
+SOURCES:
+    build.properties
+    greenstone3.xml
+    gs2build.patch
+    perl-util.patch
+
+MAKEFILE:
+    base
+    src
+    clean
+    build-core
+    main
Index: main/trunk/package-kits/linux/packages/tools
===================================================================
--- main/trunk/package-kits/linux/packages/tools	(revision 29529)
+++ main/trunk/package-kits/linux/packages/tools	(revision 29536)
@@ -1,4 +1,4 @@
 SVN_LOCATION:           http://svn.greenstone.org/main/trunk/greenstone3
-NAME:                   greenstone-tools
+NAME:                   @PKG_GREENSTONE_TOOLS@
 VERSION:                3.06
 RELEASE:                1
@@ -9,20 +9,41 @@
 LICENSE_SHORT:          GPL-2
 LICENSE:                license
-DEPENDS:                @PKG_WVWARE@ @PKG_PERL@ @PKG_IMAGEMAGICK@
-OPTDEPENDS:             @PKG_GLI@
-MAKEDEPENDS:            @PKG_JAVA_JDK@ @PKG_SVN@ @PKG_ANT@ @PKG_PATCH@ @PKG_AUTOCONF@ @PKG_GCC@ @PKG_MAKE@ @PKG_RSYNC@
-PROVIDES:               
-FILES:                  @GSTOOLS@\n%{_bindir}/*
 
-build.properties
-greenstone
-greenstone3.xml
-gs2build.patch
-perl-util.patch
-wvWare
+DEPENDS:
+    @PKG_WVWARE@
+    @PKG_PERL@
+    @PKG_IMAGEMAGICK@
 
-base
-src
-clean
-build-core
-tools
+OPTDEPENDS:
+    @PKG_GLI@
+
+MAKEDEPENDS:
+    @PKG_JAVA_JDK@
+    @PKG_SVN@
+    @PKG_ANT@
+    @PKG_PATCH@
+    @PKG_AUTOCONF@
+    @PKG_GCC@
+    @PKG_MAKE@
+    @PKG_RSYNC@
+
+PROVIDES:
+
+FILES:
+    @GSTOOLS@
+    %{_bindir}/*
+
+SOURCES:
+    build.properties
+    greenstone
+    greenstone3.xml
+    gs2build.patch
+    perl-util.patch
+    wvWare
+
+MAKEFILE:
+    base
+    src
+    clean
+    build-core
+    tools
Index: main/trunk/package-kits/linux/perllib/Greenstone/Config.pm
===================================================================
--- main/trunk/package-kits/linux/perllib/Greenstone/Config.pm	(revision 29536)
+++ main/trunk/package-kits/linux/perllib/Greenstone/Config.pm	(revision 29536)
@@ -0,0 +1,33 @@
+package Greenstone::Config;
+
+use strict;
+use warnings;
+use utf8; 
+
+# Formats an array
+sub replacement_array {
+    die "Array handling must be defined by implementation";
+}
+
+# Determines the value to replace a variable with
+sub replacement {
+    my ($self, $var) = @_;
+    my $val = $self->{config}->{$var};
+    die "'$var' was not defined!" unless (defined $val);
+    if (ref $val eq 'ARRAY') {
+        return $self->replacement_array ($val);
+    } else {
+        return $val;
+    }
+}
+
+# Substitutes variables with their value
+sub subst {
+    my $self = shift;
+    for (@_) {
+        s/@([\w]+)@/$self->replacement($1)/ge;
+    }
+    return @_;
+}
+
+1;
Index: main/trunk/package-kits/linux/perllib/Greenstone/Config/Loader.pm
===================================================================
--- main/trunk/package-kits/linux/perllib/Greenstone/Config/Loader.pm	(revision 29536)
+++ main/trunk/package-kits/linux/perllib/Greenstone/Config/Loader.pm	(revision 29536)
@@ -0,0 +1,39 @@
+package Greenstone::Config::Loader;
+
+use strict;
+use warnings;
+use utf8;
+use parent 'Greenstone::Config';
+use Greenstone::Helpers;
+
+# Reads a config file into the config hashmap
+sub readconf {
+    my ($self, $conf) = @_;
+    $self->{config} = {} unless exists $self->{config};
+    open CONF, '<', $conf
+        or die "Failed to open '$conf' for reading: $!";
+    my $var;
+    while (my $line = <CONF>) {
+        if (empty $line or comment $line) {
+            $var = undef;
+        } elsif (defined $var and $line =~ /^\s/) {
+            trim $line;
+            $self->subst ($line);
+            escape $line;
+            push @{$self->{config}->{$var}}, $line;
+        } else {
+            ($var, my $val) = trim (split ":", $line, 2);
+            defined $var and defined $val or die "Invalid variable assignment: '$line'";
+            if (empty $val) {
+                $self->{config}->{$var} = [];
+            } else {
+                $self->subst ($val);
+                escape $val;
+                $self->{config}->{$var} = $val;
+            }
+        }
+    }
+    close CONF;
+}
+
+1;
Index: main/trunk/package-kits/linux/perllib/Greenstone/Helpers.pm
===================================================================
--- main/trunk/package-kits/linux/perllib/Greenstone/Helpers.pm	(revision 29536)
+++ main/trunk/package-kits/linux/perllib/Greenstone/Helpers.pm	(revision 29536)
@@ -0,0 +1,81 @@
+package Greenstone::Helpers;
+
+use strict;
+use warnings;
+use utf8;
+use File::Copy 'cp';
+use base 'Exporter';
+
+our $VERSION = 1.00;
+our @EXPORT  = qw(lsfiles empty comment trim escape hashdump);
+
+sub lsfiles {
+    my ($dir, $files) = @_;
+    my $all = $files =~ /^all$/i;
+    my %hash;
+    if (not $all) {
+        for my $file (split ',', $files) {
+            $hash{$file} = 1;
+        }
+    }
+    my @list;
+    opendir DIR, $dir or die "Could not open '$dir': $!";
+    while (my $entry = readdir DIR) {
+        next if (not -f "$dir/$entry");
+        if ($all) {
+            push @list, $entry;
+        } elsif (exists $hash{$entry}) {
+            push @list, $entry;
+            delete $hash{$entry};
+        }
+    }
+    closedir DIR;
+    if (keys %hash) {
+        die "Could not find [ " . join (', ', sort keys %hash) . " ]";
+    }
+    return @list;
+}
+
+sub empty {
+    shift =~ /^\s*$/ and return 1;
+}
+
+sub comment {
+    shift =~ /^\s*#/ and return 1;
+}
+
+sub trim {
+    for (@_) {
+        s/^\s+|\s+$//g;
+    }
+    return @_;
+}
+
+sub escape {
+    for (@_) {
+        s/\\n/\n/g;
+        s/\\ / /g;
+        s/\\\\/\\/g;
+    }
+    return @_;
+}
+
+
+
+sub hashdump {
+    my $hash = shift;
+    for my $key (keys %$hash) {
+        my $val = $hash->{$key};
+        if (ref $val eq 'ARRAY') {
+            print "'$key' =\n";
+            for my $i (@$val) {
+                print "\t'$i'\n";
+            }
+        } else {
+            print "'$key' = '$val'\n";
+        }
+    }
+    print "\n\n";
+}
+
+1;
Index: main/trunk/package-kits/linux/perllib/Greenstone/Package.pm
===================================================================
--- main/trunk/package-kits/linux/perllib/Greenstone/Package.pm	(revision 29536)
+++ main/trunk/package-kits/linux/perllib/Greenstone/Package.pm	(revision 29536)
@@ -0,0 +1,164 @@
+package Greenstone::Package;
+
+use strict;
+use warnings;
+use utf8;
+use File::Path 'make_path';
+use File::Copy 'cp';
+use Greenstone::Helpers;
+use base 'Exporter';
+require Greenstone::Config::Loader;
+
+use parent 'Greenstone::Config';
+
+our $VERSION = 1.00;
+our @EXPORT = qw(makepkg);
+
+=head1 NAME
+
+Greenstone::Package
+
+=head1 SYNOPSIS
+
+use Greenstone::Package;
+makepkg (
+    package => 'package',
+    distro  => 'distro'
+);
+
+=head1 DESCRIPTION
+
+This module will generate scripts for building Greenstone packages
+under various Linux distributions
+
+=head2 FUNCTIONS
+
+Only the makepkg function is exported.
+All other functions are internal and should not be used externally.
+
+=cut
+
+sub makepkg {
+    my %args = @_;
+
+    # sanity checks
+    die "A package must have a name" unless (exists $args{package});
+    die "A package must have a distro" unless (exists $args{distro});
+
+    my $package_conf = "packages/$args{package}";
+    -f $package_conf or die "Package '$args{package}' does not exist";
+
+    my $distro_conf = "distros/$args{distro}";
+    -f $distro_conf or die "Distro '$args{distro}' does not exist";
+
+    # Classify ourselves as config and load the config
+    my $self = bless({}, 'Greenstone::Config::Loader');
+
+    $self->readconf ("global.conf");
+    $self->readconf ($distro_conf);
+    $self->readconf ($package_conf);
+
+    die "Distro '$args{distro}' is invalid (does not specify a manager)"
+        unless (exists $self->{config}->{MANAGER});
+
+    my $class = __PACKAGE__ . '::_' . lc $self->{config}->{MANAGER};
+    eval "require $class; 1" or die "Package manager '$self->{config}->{MANAGER}' does not exist";
+
+    # Reclassify as our implementation
+    bless $self, $class;
+
+    $self->{package} = $args{package};
+    $self->{distro} = $args{distro};
+    $self->{output} = "build/$args{distro}/$args{package}";
+    make_path $self->{output};
+
+    $self->add_sources;
+    $self->add_makefile;
+    $self->add_package;
+}
+
+# Copys the source files required for this package,
+# from the files/ folder
+# Performs variable substitution on file names,
+# and file content for plain-text files
+sub add_sources {
+    my $self = shift;
+    for my $source (@{$self->{config}->{SOURCES}}) {
+        $self->add ("files/$source", "$self->{output}/$source", $self->{config});
+    }
+}
+
+# Generates the Makefile for this package,
+# by concatenating the files in the segments/ folder
+sub add_makefile {
+    my $self = shift;
+    push @{$self->{config}->{SOURCES}}, 'Makefile';
+    my $makefile = "$self->{output}/Makefile";
+    print "    - $makefile\n";
+    open MAKEFILE, '>', $makefile
+        or die "Failed to open '$makefile' for writing: $!";
+    for my $segment (@{$self->{config}->{MAKEFILE}}) {
+        open IN, '<', "segments/$segment"
+            or die "Failed to open 'segments/$segment' for reading: $!";
+        while (my $line = <IN>) {
+            $self->subst ($line);
+            print MAKEFILE $line;
+        }
+        close IN;
+        print MAKEFILE "\n";
+    }
+    # add a target for packaging
+    my $manager_segment = "segments/$self->{config}->{MANAGER}";
+    open IN, '<', $manager_segment
+        or die "Failed to open '$manager_segment' for reading: $!";
+    while (my $line = <IN>) {
+        $self->subst ($line);
+        print MAKEFILE $line;
+    }
+    close IN;
+    close MAKEFILE;
+}
+
+# Generates the package-manager specific package generation scripts
+sub add_package {
+    my $self = shift;
+    $self->add ("managers/$self->{config}->{MANAGER}", $self->{output});
+}
+
+# Adds a file or a folder to the package's folder
+sub add {
+    my ($self, $src, $dst) = @_;
+    $self->subst ($dst);
+
+    if (-d $src) {
+        mkdir $dst;
+        opendir my $DIRFH, $src or die "Could not open '$src': $!";
+        while (readdir $DIRFH) {
+            next if ($_ eq '.' or $_ eq '..');
+            $self->add ("$src/$_", "$dst/$_");
+        }
+        closedir $DIRFH;
+    } else {
+        print '    - ', $dst, "\n";
+        if (-B $src or $src =~ /\.patch$/i) {
+            # copy binary file
+            cp $src, $dst or die "Failed to copy '$src': $!";
+        } else {
+            # copy normal file
+            open IN, '<', $src
+                or die "Failed to open '$src' for reading: $!";
+            open OUT, '>', $dst
+                or die "Failed to open '$dst' for writing: $!";
+            while (my $line = <IN>) {
+                $self->subst ($line);
+                print OUT $line;
+            }
+            my $perms = (stat IN)[2] & 07777;
+            close IN;
+            close OUT;
+            chmod ($perms | 0600, $dst);
+        }
+    }
+}
+
+1;
Index: main/trunk/package-kits/linux/perllib/Greenstone/Package/_pacman.pm
===================================================================
--- main/trunk/package-kits/linux/perllib/Greenstone/Package/_pacman.pm	(revision 29536)
+++ main/trunk/package-kits/linux/perllib/Greenstone/Package/_pacman.pm	(revision 29536)
@@ -0,0 +1,40 @@
+package Greenstone::Package::_pacman;
+
+use strict;
+use warnings;
+use utf8;
+use parent 'Greenstone::Package';
+use Digest::MD5;
+
+sub replacement_array {
+    my $self = shift;
+    my $array = shift;
+    return join "\n", @{$array};
+}
+
+sub add_md5 {
+    my $self = shift;
+    my $md5 = Digest::MD5->new;
+    for my $source (@_) {
+        open my $MD5FH, '<', "$self->{output}/$source";
+        binmode $MD5FH;
+        $md5->addfile ($MD5FH);
+        push @{$self->{config}->{SOURCE_SUMS}}, $md5->hexdigest;
+        close $MD5FH
+    }
+}
+
+sub add_sources {
+    my $self = shift;
+    $self->SUPER::add_sources;
+    $self->{config}->{SOURCE_SUMS} = [];
+    $self->add_md5 (@{$self->{config}->{SOURCES}});
+}
+
+sub add_makefile {
+    my $self = shift;
+    $self->SUPER::add_makefile;
+    $self->add_md5 ('Makefile');
+}
+
+1;
