Removing old PO files, removing clutter
[koha_fer] / misc / Install.pm
index a4cfe8e..c4eed88 100644 (file)
@@ -2,7 +2,7 @@ package Install; #assumes Install.pm
 
 
 # Copyright 2000-2002 Katipo Communications
-# Contains parts Copyright 2003 MJ Ray
+# Contains parts Copyright 2003-4 MJ Ray
 #
 # This file is part of Koha.
 #
@@ -19,16 +19,15 @@ package Install; #assumes Install.pm
 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
 # Suite 330, Boston, MA  02111-1307 USA
 #
-# Recent Authors
-# MJR: my.cnf, etcdir, prefix, new display, apache conf, copying fixups
+# Current maintainer MJR slef at users.sourceforge.net
 
 use strict;
 use POSIX;
 #MJR: everyone will have these modules, right?
 # They look like part of perl core to me
-use Term::Cap;
 use Term::ANSIColor qw(:constants);
 use Text::Wrap;
+use File::Temp qw/ :mktemp /;
 require Exporter;
 
 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
@@ -44,20 +43,28 @@ of the code to do installation;
 this code is used by installer.pl
 to perform an actual installation.
 
-=head2 Internal functions (not meant to be used outside of Install.pm)
+=head2 Internal variables
 
 =over 4
 
+=item $VERSION, @ISA, @EXPORT
+
+Defines the version and structure of the module interface
+
 =cut
 
 # set the version for version checking
-$VERSION = 0.01;
+# set the version for version checking
+$VERSION = do { my @v = '$Revision$' =~ /\d+/g; shift(@v) . "." . join( "_", map { sprintf "%03d", $_ } @v ); };
 
 @ISA = qw(Exporter);
-@EXPORT = qw(  &checkperlmodules
-                &checkabortedinstall
+@EXPORT = qw(
+               &read_autoinstall_file
+               &checkperlmodules
+               &checkabortedinstall
                &getmessage
                &showmessage
+               &completeupgrade
                &releasecandidatewarning
                &getinstallationdirectories
                &getdatabaseinfo
@@ -77,48 +84,60 @@ $VERSION = 0.01;
                &restoremycnf
                );
 
-use vars qw( $kohaversion $newversion );                       # set in loadconfigfile and installer.pl
-use vars qw( $language );                      # set in installer.pl
-use vars qw( $domainname );                    # set in installer.pl
+=item $kohaversion, $newversion, $language, $clear_string
 
-use vars qw( $etcdir );                                # set in installer.pl, usu. /etc
-use vars qw( $intranetdir $opacdir $kohalogdir );
-use vars qw( $realhttpdconf $httpduser );
-use vars qw( $servername $svr_admin $opacport $intranetport );
-use vars qw( $mysqldir );
-use vars qw( $database $mysqluser );
-use vars qw( $mysqlpass );                     # normally should not be used
-use vars qw( $hostname $user $pass );  # virtual hosting
+Installer setting details
 
-=item heading
+=item $etcdir, $intranetdir, $opacdir, $kohalogdir
 
-    $messages->{'WelcomeToKohaInstaller'
-       = heading('Welcome to the Koha Installer') . qq|...|;
+Directories to use for installation (configuration, intranet, opac, logs)
 
-The heading function takes one string, the text to be displayed as
-the heading, and returns a formatted heading (currently formatted
-with ANSI colours).
+=item $domainname, $realhttpdconf, $httpduser, $httpdgroup, $servername, $svr_admin, $opacport, $intranetport, $hostname, $user, $pass
 
-This reduces the likelihood of pod2man(1) etc. misinterpreting
-a line of equal signs as illegal POD directives.
+Apache configuration settings
+
+=item $mysqldir, $database, $mysqluser, $mysqlpass, $mycnf, $mytmpcnf
+
+MySQL configuration settings
 
 =cut
 
-my $termios = POSIX::Termios->new();
-$termios->getattr();
-my $terminal = Term::Cap->Tgetent({OSPEED=>$termios->getospeed()});
+use vars qw( $kohaversion $newversion $language
+  $etcdir $intranetdir $opacdir $kohalogdir
+  $domainname $realhttpdconf $httpduser $httpdgroup
+  $servername $svr_admin $opacport $intranetport
+  $hostname $user $pass
+  $mysqldir $database $mysqluser $mysqlpass );
+
 my $clear_string = "\n\n"; #MJR: was $terminal->Tputs('cl');
 
+my $mycnf = $ENV{HOME}."/.my.cnf";
+my $mytmpcnf = mktemp("my.cnf.koha.XXXXXX");
+chomp($mytmpcnf);
+
+=back
+
+=head2 Internal functions (not meant to be used outside of Install.pm)
+
+=over 4
+
+=item C<heading($)>
+
+Takes: a string to be displayed as the heading
+
+Returns: a formatted heading (currently with ANSI colours).
+
+This reduces the likelihood of pod2man(1) etc. misinterpreting
+a line of equal signs as illegal POD directives.
+
+=cut
+
 sub heading ($) {
   my $title = shift;
   my $bal = 5;
   return($clear_string.ON_BLUE.WHITE.BOLD." "x$bal.uc($title)." "x$bal.RESET."\n\n");
 }
 
-my $mycnf = $ENV{HOME}."/.my.cnf";
-my $mytmpcnf = `mktemp my.cnf.koha.XXXXXX`;
-chomp($mytmpcnf);
-
 my $messages;
 $messages->{'continuing'}->{en}="Great!  Continuing...\n\n";
 $messages->{'WelcomeToKohaInstaller'}->{en} =
@@ -130,7 +149,7 @@ a mysql superuser; and details of your library setup.  You may also need
 to know details of your Apache setup.
 
 If you want to install the Koha configuration files somewhere other than
-/etc (for multiple Koha versions on one system, for example), you should
+/etc (for installing not as root, or to have many Kohas on one system, for example), you should
 set the etcdir environment variable.  Please look at your manuals for
 details of how to set that.
 
@@ -138,11 +157,14 @@ Recommended answers are given in brackets after each question.  To accept
 the default value for any question (indicated by []), simply hit Enter
 at the prompt.
 
+Note that you also can define an auto_install_file, that will answer every question automatically.
+To use this feature, run ./installer.pl -i /path/to/auto_install_file 
+
 Are you ready to begin the installation? ([Y]/N): |;
 
 $messages->{'WelcomeToUpgrader'}->{en} =
    heading('Welcome to the Koha Upgrader') . qq|
-You are attempting to upgrade from Koha %s to %s.
+You are attempting to upgrade from Koha %s to Koha %s.
 
 We recommend that you do a complete backup of all your files before upgrading.
 This upgrade script will make a backup copy of your files for you.
@@ -261,51 +283,43 @@ You will be able to connect to your Librarian interface at:
    http://%s\:%s/
 
    use the koha admin mysql login and password to connect to this interface.
-
 and the OPAC interface at:
 
    http://%s\:%s/
+   
+NOTE: You need to add lines to your main httpd.conf to include
+/etc/koha-httpd.conf and to make sure it is listening on the right ports
+(using the Listen directive). Then, restart Apache.
 
-Please read the Hints file and visit http://www.koha.org
-
+Please read the Hints file and visit http://www.koha.org (in english) or www.koha-fr.org (in french)
 Press <ENTER> to exit the installer: |;
 
 $messages->{'UpgradeCompleted'}->{en} = heading('UPGRADE COMPLETE') . qq|
 Congratulations ... your Koha upgrade is finished!
 
-If you are upgrading from a version of Koha
-prior to 1.2.1, it is likely that you will have to modify your Apache
-configuration to point it to the new files.
-
-In your INTRANET VirtualHost section you should have:
-  DocumentRoot %s/htdocs
-  ScriptAlias /cgi-bin/koha/ %s/cgi-bin/
-  SetEnv PERL5LIB %s/modules
-
-In the OPAC VirtualHost section you should have:
-  DocumentRoot %s/htdocs
-  ScriptAlias /cgi-bin/koha/ %s/cgi-bin/
-  SetEnv PERL5LIB %s/modules
-
-You may also need to uncomment a "LoadModules env_module ... " line and restart
-Apache.
-If you're upgrading from 1.2.x version of Koha note that the MARC DB is NOT populated.
-To populate it :
-* launch Koha
-* Go to Parameters >> Marc structure option and Koha-MARC links option.
-* Modify default MARC structure to fit your needs.
-* open a console
-* type:
-cd /path/to/koha/misc
-export PERL5LIB=/path/to/koha
-./koha2marc.pl
-the old DB is "copied" in the new MARC one.
-Koha 2.0.0 is ready :-)
-
 Please report any problems you encounter through http://bugs.koha.org/
 
 Press <ENTER> to exit the installer: |;
 
+#'
+
+=item C<completeupgrade()>
+
+Display a message describing what may need changing in httpd.conf
+and any other instructions for just before exit.
+
+=cut
+
+sub completeupgrade {
+       showmessage(getmessage('UpgradeCompleted',[$intranetdir,$intranetdir,$intranetdir,$opacdir,$opacdir,$intranetdir]),'PressEnter');
+}
+
+=item C<releasecandidatewarning()>
+
+Display a warning about upgrading to a public test release.
+
+=cut
+
 sub releasecandidatewarning {
     my $message=getmessage('ReleaseCandidateWarning', [$newversion, $newversion]);
     my $answer=showmessage($message, 'yn', 'n');
@@ -319,6 +333,50 @@ sub releasecandidatewarning {
     };
 }
 
+=item C<read_autoinstall_file($)>
+
+Takes: a configuration file describing the installation
+
+Returns: a hashref of the configuration
+
+=cut
+
+sub read_autoinstall_file
+{
+       my $fname = shift;      # Config file to read
+       my $retval = {};        # Return value: ref-to-hash holding the
+                               # configuration
+
+       open (CONF, $fname) or return undef;
+
+       while (<CONF>)
+       {
+               my $var;                # Variable name
+               my $value;              # Variable value
+
+               chomp;
+               s/#.*//;                # Strip comments
+               next if /^\s*$/;        # Ignore blank lines
+
+               # Look for a line of the form
+               #       var = value
+               if (!/^\s*(\w+)\s*=\s*(.*?)\s*$/)
+               {
+                       next;
+               }
+
+               # Found a variable assignment
+               # variable that was already set.
+               $var = $1;
+               $value = $2;
+               $retval->{$var} = $value;
+       }
+       close CONF;
+       if ($retval->{MysqlRootPassword} eq "XXX") {
+               print "ERROR : the root password is XXX. It is NOT valid. Edit your auto_install_file\n";
+       }
+       return $retval;
+}
 
 =back
 
@@ -326,14 +384,10 @@ sub releasecandidatewarning {
 
 =over 4
 
-=cut
-
-=item setlanguage
+=item C<setlanguage($)>
 
-    setlanguage('en');
-
-Sets the installation language, normally "en" (English).
-In fact, only "en" is supported.
+Sets the installation language code, normally "en" (English).
+Only "en" is supported so far.
 
 =cut
 
@@ -341,9 +395,7 @@ sub setlanguage ($) {
     ($language) = @_;
 }
 
-=item setdomainname
-
-    setdomainname('example.org');
+=item C<setdomainname($)>
 
 Sets the domain name of the host.
 
@@ -356,48 +408,44 @@ sub setdomainname ($) {
     ($domainname) = @_;
 }
 
-=item setetcdir
-
-    setetcdir('/etc');
+=item C<setetcdir($)>
 
 Sets the sysconfdir, normally /etc.
 This should be an absolute path; a trailing / is not required.
+Must be writeable, else we die.
 
 =cut
 
 sub setetcdir ($) {
     ($etcdir) = @_;
+    if (! ((-d $etcdir) && (-w $etcdir))) { die("Cannot write to $etcdir! Please set the etcdir environment variable to a writeable directory.\nFailed"); }
 }
 
-=item getkohaversion
-
-    getkohaversion();
+=item C<getkohaversion()>
 
-Gets the Koha version as known by the previous config file.
+Returns: the Koha version as known by the previous config file..
 
 =cut
 
-sub getkohaversion ($) {
+sub getkohaversion () {
     return($kohaversion);
 }
 
-=item setkohaversion
-
-    setkohaversion('1.3.3RC26');
+=item C<setkohaversion($)>
 
 Sets the Koha version as known by the installer.
 
+Note: function is now misnamed, setting $newversion not $kohaversion
+
 =cut
 
 sub setkohaversion ($) {
     ($newversion) = @_;
 }
 
-=item getservername
+=item C<getservername()>
 
-    my $servername = getservername;
-
-Gets the name of the Koha virtual server as specified by the user.
+Returns: the name of the Koha virtual server as specified by the user.
 
 =cut
 
@@ -405,12 +453,10 @@ sub getservername () {
     $servername;
 }
 
-=item getopacport
-
-    $port = getopacport;
+=item C<getopacport()>
 
-Gets the port that will run the Koha OPAC virtual server,
-as specified by the user.
+Returns the port that will run the Koha OPAC virtual server, as
+specified by the user.
 
 =cut
 
@@ -418,12 +464,10 @@ sub getopacport () {
     $opacport;
 }
 
-=item getintranetport
-
-    $port = getintranetport;
+=item C<getintranetport()>
 
-Gets the port that will run the Koha INTRANET virtual server,
-as specified by the user.
+Returns the port that will run the Koha INTRANET virtual server, as
+specified by the user.
 
 =cut
 
@@ -437,15 +481,14 @@ sub getintranetport () {
 
 =over 4
 
-=cut
+=item C<dirname($)>
 
-=item dirname
+Does the equivalent of dirname(1).
 
-    dirname $path;
+Takes: a path
 
-Does the equivalent of dirname(1). Given a path $path, return the
-parent directory of $path (best guess), except when $path seems to
-be the same as /, in which case $path itself is returned unchanged.
+Returns: parent directory of path (best guess), except when the path
+seems to be the same as /, in which case it is returned unchanged.
 
 =cut
 
@@ -461,29 +504,28 @@ sub dirname ($;$) {
     return $path;
 }
 
-=item mkdir_parents
+=item C<mkdir_parents($;$)>
 
-    mkdir_parents $path;
-    mkdir_parents $path, $mode;
+Does the equivalent of mkdir -p, or mkdir --parents.
 
-Does the equivalent of mkdir -p, or mkdir --parents. Given a path $path,
-create the directory $path, recursively creating any intermediate
-directories. If $mode is given, the directory will be created with
-mode $mode.
+Takes: a path and an optional mode.
 
-WARNING: If $path already exists, mkdir_parents will just return
-successfully (just like mkdir -p), whether the mode of $path conforms
-to $mode or not. (This is the behaviour of the mkdir -p command.)
+Create the directory path, recursively creating any intermediate
+directories, with the access mode if given.
+
+WARNING: If the path already exists, mkdir_parents will just return
+successfully (just like mkdir -p), whether the mode of path conforms
+to the mode or not. (This is the behaviour of the mkdir -p command.)
 
 =cut
 
-sub mkdir_parents {
+sub mkdir_parents ($;$) {
     my($path, $mode) = @_;
     my $ok = -d($path)? 1: defined $mode? mkdir($path, $mode): mkdir($path);
 
     if (!$ok && $! == ENOENT) {
        my $parent = dirname($path);
-       $ok = mkdir_parents($parent, $mode);
+       $ok = &mkdir_parents($parent, $mode);
 
        # retry and at the same time make sure that $! is set correctly
        $ok = defined $mode? mkdir($path, $mode): mkdir($path);
@@ -491,22 +533,18 @@ sub mkdir_parents {
     return $ok;
 }
 
+=item C<getmessage($;$)>
 
-=item getmessage
+Takes: a message identifier, an array reference
 
-    getmessage($msgid);
-    getmessage($msgid, $variables);
+Returns: a localized message (format string)
 
-Gets a localized message (format string) with message id $msgid,
-and, if an array reference of variables $variables is given,
-substitutes variables in the format string with @$variables.
-Returns the found message string, with variable substitutions
-if specified.
+The first message must be the message identifier corresponding to a
+defined message string (a valid key to the $Installer::messages hash).
+The second parameter may be an array reference of variables,
+to be substituted into the format string.
 
-$msgid must be the message identifier corresponding to a defined
-message string (a valid key to the $messages hash in the Installer
-package). getmessage throws an exception if the message cannot be
-found.
+getmessage throws an exception if the message cannot be found.
 
 =cut
 
@@ -521,40 +559,25 @@ sub getmessage {
 }
 
 
-=item showmessage
-
-    showmessage($message, 'none');
-    showmessage($message, 'none', undef, $noclear);
-
-    $result = showmessage($message, 'yn');
-    $result = showmessage($message, 'yn', $defaultresponse);
-    $result = showmessage($message, 'yn', $defaultresponse, $noclear);
-
-    $result = showmessage($message, 'restrictchar CHARS');
-    $result = showmessage($message, 'free');
-    $result = showmessage($message, 'silentfree');
-    $result = showmessage($message, 'numerical');
-    $result = showmessage($message, 'email');
-    $result = showmessage($message, 'PressEnter');
+=item C<showmessage($$;$$)>
 
 Shows a message and optionally gets a response from the user.
 
-The first two arguments, the message and the response type,
-are mandatory.  The message must be the actual string to
-display; the caller is responsible for calling getmessage if
-required.
+Takes:
+message string, question type, default response, noclear
 
-The response type must be one of "none", "yn", "free", "silentfree"
-"numerical", "email", "PressEnter", or a string consisting
-of "restrictchar " followed by a list of allowed characters
-(space can be specified). (Case is not significant, but case is
-significant in the list of allowed characters.) If a response
-type other than the above-listed is specified, the result is
-undefined.
+Returns: response string
 
-Note that the response type "yn" is equivalent to "restrictchar yn".
-Because "restrictchar" is case-sensitive, the user is expected
-to enter "y" or "n" in lowercase only.
+The message must be the actual string to display; the caller is
+responsible for calling getmessage if required.
+
+Question type must be 'none' for no response, 'yn' for a yes/no
+question, 'restrictchar CHARS' for one letter from CHARS (Case is not
+significant, but case is significant in the list of allowed
+characters), 'free' for any string, 'silentfree' for any string
+entered without on-screen display, 'numerical', 'email' or
+'PressEnter'.  If a response type other than the above-listed is
+specified, the result is undefined.
 
 Note that the response type of "email" does not actually
 guarantee that the returned value is a well-formed RFC-822
@@ -564,28 +587,27 @@ string that is looks reasonably likely to be an email address
 in the "real world", given the premise that the user is trying
 to enter a real email address.
 
-If a response type other than "none" or "PressEnter" is
-specified, a third argument, specifying the default value, can
-be specified:  If this default response is not specified, the
-default response is the first allowed character if the response
-type is "restrictchar", otherwise the default response is the
-empty string. This default response is used when the user does
-not specify a value (i.e., presses Enter without typing in
-anything), showmessage will assume that the default response is
-the user's response.
+If a response type other than "none" or "PressEnter" is specified, a
+third argument, specifying the default value, can be specified: If
+this default response is not specified, the default response is the
+first allowed character if the response type is "restrictchar",
+otherwise the default response is the empty string. This default
+response is used when the user does not specify a value (i.e., presses
+Enter without typing in anything), showmessage will assume that the
+default response is the user's response.
 
 Note that because the response type "yn" is equivalent to
-"restrictchar yn", the default value for response type "yn",
-if unspecified, is "y".
+"restrictchar yn", the default value for response type "yn", if
+unspecified, is "y".
 
-The screen is normally cleared before the message is displayed;
-if a fourth argument is specified and is nonzero, this
-screen-clearing is not done.
+The screen is normally cleared before the message is displayed; if a
+fourth argument is specified and is nonzero, this screen-clearing is
+not done.
 
 =cut
 #'
 
-sub showmessage {
+sub showmessage ($$;$$) {
     #MJR: Maybe refactor to use anonymous functions that
     # check the responses instead of RnP branching.
     my $message=join('',fill('','',(shift)));
@@ -670,11 +692,7 @@ sub showmessage {
 }
 
 
-=back
-
-=item startsysout
-
-       startsysout;
+=item C<startsysout()>
 
 Changes the display to show system output until the next showmessage call.
 At the time of writing, this means using red text.
@@ -685,18 +703,13 @@ sub startsysout {
        print RED."\n";
 }
 
-
 =back
 
 =head2 Subtasks of doing an installation
 
 =over 4
 
-=cut
-
-=item checkabortedinstall
-
-    checkabortedinstall;
+=item C<checkabortedinstall()>
 
 Checks whether a previous installation process has been abnormally
 aborted, by checking whether $etcidr/koha.conf is a symlink matching
@@ -728,15 +741,14 @@ database is already created.
     }
 }
 
-=item checkpaths
-
-       checkpaths;
+=item C<checkpaths()>
 
 Make sure that we loaded the right dirs from an old koha.conf
 
+FIXME: needs update to use Install.pm
+
 =cut
 
-#FIXME: update to use Install.pm
 sub checkpaths {
 if ($opacdir && $intranetdir) {
     print qq|
@@ -795,47 +807,105 @@ if (!$opacdir || !$intranetdir) {
 
 }
 
-=item checkperlmodules
-
-    checkperlmodules;
+=item C<checkperlmodules(;$)>
 
-Test whether the version of Perl is new enough, whether Perl is
-found at the expected location, and whether all required modules
-have been installed.
+Test whether the version of Perl is new enough, whether Perl is found
+at the expected location, and whether all required modules have been
+installed.
 
 =cut
 
-sub checkperlmodules {
+sub checkperlmodules(;$) {
 #
 # Test for Perl and Modules
 #
+       my ($auto_install) = @_;
+       my $message = getmessage('CheckingPerlModules');
+       showmessage($message, 'none');
 
-    my $message = getmessage('CheckingPerlModules');
-    showmessage($message, 'none');
-
-    unless ($] >= 5.006001) {                  # Bug 179
-       die getmessage('PerlVersionFailure', ['5.6.1']);
-    }
+       unless ($] >= 5.006001) {                       # Bug 179
+               die getmessage('PerlVersionFailure', ['5.6.1']);
+       }
        startsysout();
 
-    my @missing = ();
-    unless (eval {require DBI})              { push @missing,"DBI" };
-    unless (eval {require Date::Manip})      { push @missing,"Date::Manip" };
-    unless (eval {require DBD::mysql})       { push @missing,"DBD::mysql" };
-    unless (eval {require HTML::Template})   { push @missing,"HTML::Template" };
-#    unless (eval {require Set::Scalar})      { push @missing,"Set::Scalar" };
-    unless (eval {require Digest::MD5})      { push @missing,"Digest::MD5" };
-    unless (eval {require MARC::Record})     { push @missing,"MARC::Record" };
-    unless (eval {require Mail::Sendmail})   { push @missing,"Mail::Sendmail" };
-    unless (eval {require Event})       {
+       my @missing = ();
+       unless (eval {require DBI})              { push @missing,"DBI" };
+       unless (eval {require Date::Manip})      { push @missing,"Date::Manip" };
+       unless (eval {require DBD::mysql})       { push @missing,"DBD::mysql" };
+       unless (eval {require HTML::Template})   { push @missing,"HTML::Template" };
+       unless (eval {require Digest::MD5})      { push @missing,"Digest::MD5" };
+       unless (eval {require MARC::Record})     { push @missing,"MARC::Record" };
+       unless (eval {require Mail::Sendmail})   { push @missing,"Mail::Sendmail" };
+# The following modules are not mandatory, depends on how the library want to use Koha
+       unless (eval {require PDF::API2})   { 
+                       if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
+                               push @missing,"You will need PDF::API2 for barcode generator";
+                       }
+       }
+       unless (eval {require GD::Barcorde})   { 
+                                    if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
+                               push @missing,"You will need GD::Barcode for the new barcode generator";
+                                    }
+                    }
+       unless (eval {require GD::Barcorde})   { 
+                       if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
+                               push @missing,"You will need GD::Barcode for the new barcode generator";
+                       }
+       }
+       unless (eval {require Data::Random})   { 
+                                    if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
+                               push @missing,"You will need Data::Random for the new barcode generator";
+                                    }
+                    }
+                unless (eval {require PDF::Reuse::Barcode})   {
+                                    if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
+                               push @missing,"You will need PDF::Reuse::Barcode for the new barcode generator";
+                                    }
+                    }
+                unless (eval {require PDF::Report})   {
+                                    if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
+                                            push @missing,"You will need PDF::Report for spine and barcode printing"
+                                    }
+                    }
+
+                unless (eval {require GD::Barcode})   {
+                                    if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
+                                            push @missing,"You will need GD::Barcode for spine and barcode printing"
+                                    }
+                    }
+
+                unless (eval {require GD::Barcode::UPCE})   {
+                                    if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
+                                            push @missing,"You will need GD::Barcode::UPCE for spine and barcode printing"
+                                    }
+                    }
+
+       unless (eval {require Net::LDAP})       {
                if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
-                   push @missing, "Event";
-               }
+                               push @missing, "Net::LDAP";
+                       }
+    }
+       unless (eval {require Event})       {
+               if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
+                               push @missing, "Event";
+                       }
     }
     unless (eval {require Net::Z3950})       {
-       showmessage(getmessage('NETZ3950Missing'), 'PressEnter', '', 1);
+               showmessage(getmessage('NETZ3950Missing'), 'PressEnter', '', 1);
+               if ($#missing>=0) { # see above note
+                       push @missing, "Net::Z3950";
+               }
+    }
+    unless (eval {require LWP::Simple})       {
+               showmessage(getmessage('LWP::Simple'), 'PressEnter', '', 1);
+               if ($#missing>=0) { # see above note
+                       push @missing, "LWP::Simple";
+               }
+    }
+    unless (eval {require XML::Simple})       {
+               showmessage(getmessage('XML::Simple'), 'PressEnter', '', 1);
                if ($#missing>=0) { # see above note
-                   push @missing, "Net::Z3950";
+                       push @missing, "XML::Simple";
                }
     }
 
@@ -856,7 +926,7 @@ sub checkperlmodules {
        print "\n";
        exit;
     } else {
-       showmessage(getmessage('AllPerlModulesInstalled'), 'PressEnter', '', 1);
+       showmessage(getmessage('AllPerlModulesInstalled'), 'PressEnter', '', 1) unless $auto_install->{NoPressEnter};
     }
 
 
@@ -900,31 +970,39 @@ We could not create %s, but continuing anyway...
 
 
 
-=item getinstallationdirectories
-
-    getinstallationdirectories;
+=item C<getinstallationdirectories(;$)>
 
-Get the various installation directories from the user, and then
-create those directories (if they do not already exist).
+Asks the user for the various installation directories, and then
+creates those directories (if they do not already exist).
 
-These pieces of information are saved to global variables; the
-function does not return any values.
+These pieces of information are saved to variables; the function does
+not return any values.
 
 =cut
 
-sub getinstallationdirectories {
+sub getinstallationdirectories(;$) {
+       my ($auto_install) = @_;
        if (!$ENV{prefix}) { $ENV{prefix} = "/usr/local"; }
     $opacdir = $ENV{prefix}.'/koha/opac';
     $intranetdir = $ENV{prefix}.'/koha/intranet';
     my $getdirinfo=1;
     while ($getdirinfo) {
        # Loop until opac directory and koha directory are different
-       my $message=getmessage('GetOpacDir', [$opacdir]);
-       $opacdir=showmessage($message, 'free', $opacdir);
-
-       $message=getmessage('GetIntranetDir', [$intranetdir]);
-       $intranetdir=showmessage($message, 'free', $intranetdir);
-
+       my $message;
+       if ($auto_install->{GetOpacDir}) {
+               $opacdir=$auto_install->{GetOpacDir};
+               print ON_YELLOW.BLACK."auto-setting OpacDir to : $opacdir".RESET."\n";
+       } else {
+               $message=getmessage('GetOpacDir', [$opacdir]);
+               $opacdir=showmessage($message, 'free', $opacdir);
+       }
+       if ($auto_install->{GetIntranetDir}) {
+               $intranetdir=$auto_install->{GetIntranetDir};
+               print ON_YELLOW.BLACK."auto-setting IntranetDir to : $intranetdir".RESET."\n";
+       } else {
+               $message=getmessage('GetIntranetDir', [$intranetdir]);
+               $intranetdir=showmessage($message, 'free', $intranetdir);
+       }
        if ($intranetdir eq $opacdir) {
            print qq|
 
@@ -937,8 +1015,13 @@ You must specify different directories for the OPAC and INTRANET files!
        }
     }
     $kohalogdir=$ENV{prefix}.'/koha/log';
-    my $message=getmessage('GetKohaLogDir', [$kohalogdir]);
-    $kohalogdir=showmessage($message, 'free', $kohalogdir);
+       if ($auto_install->{GetOpacDir}) {
+               $kohalogdir=$auto_install->{KohaLogDir};
+               print ON_YELLOW.BLACK."auto-setting log dir to : $kohalogdir".RESET."\n";
+       } else {
+           my $message=getmessage('GetKohaLogDir', [$kohalogdir]);
+       $kohalogdir=showmessage($message, 'free', $kohalogdir);
+       }
 
 
     # FIXME: Need better error handling for all mkdir calls here
@@ -970,11 +1053,10 @@ You must specify different directories for the OPAC and INTRANET files!
     }
 }
 
-=item getmysqldir
+=item C<getmysqldir()>
 
-       getmysqldir;
-
-Get the MySQL database server installation directory, automatically if possible.
+Returns: the MySQL database server installation directory,
+automatically if possible and from the user otherwise.
 
 =cut
 
@@ -985,10 +1067,11 @@ please give the value of --prefix when you ran configure.
 The file mysqladmin should be in bin/mysqladmin under the directory that you give here.
 
 MySQL installation directory: |;
-
-sub getmysqldir {
+#'
+sub getmysqldir () {
     foreach my $mysql (qw(/usr/local/mysql
                          /opt/mysql
+                         /usr/local
                          /usr
                          )) {
        if ( -d $mysql  && -f "$mysql/bin/mysqladmin") {
@@ -997,20 +1080,18 @@ sub getmysqldir {
     }
     if (!$mysqldir){
        for (;;) {
-           $mysqldir = showmessage(getmessage('WhereisMySQL'),'free');
+           $mysqldir = showmessage(getmessage('WhereIsMySQL'),'free');
            last if -f "$mysqldir/bin/mysqladmin";
        }
     }
     return($mysqldir);
 }
 
-=item getdatabaseinfo
-
-    getdatabaseinfo;
+=item C<getdatabaseinfo(;$)>
 
-Get various pieces of information related to the Koha database:
-the name of the database, the host on which the SQL server is
-running, and the database user name.
+Asks for various pieces of information related to the Koha database:
+the name of the database, the host on which the SQL server is running,
+and the database user name.
 
 These pieces of information are saved to global variables; the
 function does not return any values.
@@ -1053,49 +1134,65 @@ You must not use a blank password for your MySQL user.
 Press <ENTER> to try again: 
 |;
 
-sub getdatabaseinfo {
-
+sub getdatabaseinfo(;$) {
+       my ($auto_install) = @_;
     $database = 'Koha';
     $hostname = 'localhost';
     $user = 'kohaadmin';
     $pass = '';
 
 #Get the database name
-
-    my $message=getmessage('DatabaseName', [$database]);
-    $database=showmessage($message, 'free', $database);
-
+       my $message;
+       
+       if ($auto_install->{database}) {
+               $database=$auto_install->{database};
+               print ON_YELLOW.BLACK."auto-setting database to : $database".RESET."\n";
+       } else {
+               $message=getmessage('DatabaseName', [$database]);
+               $database=showmessage($message, 'free', $database);
+       }
 #Get the hostname for the database
     
-    $message=getmessage('DatabaseHost', [$hostname]);
-    $hostname=showmessage($message, 'free', $hostname);
-
+       if ($auto_install->{DatabaseHost}) {
+               $hostname=$auto_install->{DatabaseHost};
+               print ON_YELLOW.BLACK."auto-setting database host to : $hostname".RESET."\n";
+       } else {
+               $message=getmessage('DatabaseHost', [$hostname]);
+               $hostname=showmessage($message, 'free', $hostname);
+       }
 #Get the username for the database
 
-    $message=getmessage('DatabaseUser', [$database, $hostname, $user]);
-    $user=showmessage($message, 'free', $user);
-
+       if ($auto_install->{DatabaseUser}) {
+               $user=$auto_install->{DatabaseUser};
+               print ON_YELLOW.BLACK."auto-setting DB user to : $user".RESET."\n";
+       } else {
+               $message=getmessage('DatabaseUser', [$database, $hostname, $user]);
+               $user=showmessage($message, 'free', $user);
+       }
 #Get the password for the database user
 
     while ($pass eq '') {
-       my $message=getmessage('DatabasePassword', [$user, $user]);
-       $pass=showmessage($message, 'free', $pass);
-       if ($pass eq '') {
-           my $message=getmessage('BlankPassword');
-           showmessage($message,'PressEnter');
-       }
+               my $message=getmessage('DatabasePassword', [$user, $user]);
+               if ($auto_install->{DatabasePassword}) {
+                       $pass=$auto_install->{DatabasePassword};
+                       print ON_YELLOW.BLACK."auto-setting database password to : $pass".RESET."\n";
+               } else {
+                               $pass=showmessage($message, 'free', $pass);
+               }
+               if ($pass eq '') {
+                       my $message=getmessage('BlankPassword');
+                       showmessage($message,'PressEnter');
+               }
     }
 }
 
 
 
-=item getapacheinfo
-
-    getapacheinfo;
+=item C<getapacheinfo(;$)>
 
-Get various pieces of information related to the Apache server:
-the location of the configuration file and, if needed, the Unix
-user that the Koha CGI will be run under.
+Detects or asks for various pieces of information related to the
+Apache server: the location of the configuration file and, if needed,
+the Unix user that the Koha CGI will be run under.
 
 These pieces of information are saved to global variables; the
 function does not return any values.
@@ -1137,7 +1234,8 @@ The userid %s is not a valid userid on this system.
 
 Press <ENTER> to continue: |;
 
-sub getapacheinfo {
+sub getapacheinfo (;$) {
+       my ($auto_install) = @_;
     my @confpossibilities;
 
     foreach my $httpdconf (qw(/usr/local/apache/conf/httpd.conf
@@ -1148,43 +1246,44 @@ sub getapacheinfo {
                          /etc/apache2/apache2.conf
                          /etc/apache/conf/httpd.conf
                          /etc/apache/conf/apache.conf
+                         /etc/apache/httpd.conf
                          /etc/apache-ssl/conf/apache.conf
                          /etc/apache-ssl/httpd.conf
                          /etc/httpd/conf/httpd.conf
                          /etc/httpd/httpd.conf
                          /etc/httpd/2.0/conf/httpd2.conf
                          )) {
-       if ( -f $httpdconf ) {
-           push @confpossibilities, $httpdconf;
-       }
+               if ( -f $httpdconf ) {
+                       push @confpossibilities, $httpdconf;
+               }
     }
 
     if ($#confpossibilities==-1) {
-       my $message=getmessage('NoApacheConfFiles');
-       my $choice='';
-       $realhttpdconf='';
-       until (-f $realhttpdconf) {
-           $choice=showmessage($message, "free", 1);
-           if (-f $choice) {
-               $realhttpdconf=$choice;
-           } else {
-               showmessage(getmessage('NotAFile', [$choice]),'PressEnter', '', 1);
-           }
-       }
+               my $message=getmessage('NoApacheConfFiles');
+               my $choice='';
+               $realhttpdconf='';
+               until (-f $realhttpdconf) {
+                       $choice=showmessage($message, "free", 1);
+                       if (-f $choice) {
+                       $realhttpdconf=$choice;
+                       } else {
+                       showmessage(getmessage('NotAFile', [$choice]),'PressEnter', '', 1);
+                       }
+               }
     } elsif ($#confpossibilities>0) {
-       my $conffiles='';
-       my $counter=1;
-       my $options='';
-       foreach (@confpossibilities) {
-           $conffiles.="   $counter: $_\n";
-           $options.="$counter";
-           $counter++;
-       }
-       my $message=getmessage('FoundMultipleApacheConfFiles', [$conffiles]);
-       my $choice=showmessage($message, "restrictchar $options", 1);
-       $realhttpdconf=$confpossibilities[$choice-1];
+               my $conffiles='';
+               my $counter=1;
+               my $options='';
+               foreach (@confpossibilities) {
+                       $conffiles.="   $counter: $_\n";
+                       $options.="$counter";
+                       $counter++;
+               }
+               my $message=getmessage('FoundMultipleApacheConfFiles', [$conffiles]);
+               my $choice=showmessage($message, "restrictchar $options", 1);
+               $realhttpdconf=$confpossibilities[$choice-1];
     } else {
-       $realhttpdconf=$confpossibilities[0];
+               $realhttpdconf=$confpossibilities[0];
     }
     unless (open (HTTPDCONF, "<$realhttpdconf")) {
        warn RED."Insufficient privileges to open $realhttpdconf for reading.\n";
@@ -1192,35 +1291,43 @@ sub getapacheinfo {
     }
 
     while (<HTTPDCONF>) {
-       if (/^\s*User\s+"?([-\w]+)"?\s*$/) {
-           $httpduser = $1;
-       }
+               if (/^\s*User\s+"?([-\w]+)"?\s*$/) {
+                       $httpduser = $1;
+               }
     }
     close(HTTPDCONF);
 
     unless (defined($httpduser)) {
-       my $message=getmessage('EnterApacheUser', [$etcdir]);
-       until (defined($httpduser) && length($httpduser) && getpwnam($httpduser)) {
-           $httpduser=showmessage($message, "free", '');
-           if (length($httpduser)>0) {
-               unless (getpwnam($httpduser)) {
-                   my $message=getmessage('InvalidUserid', [$httpduser]);
-                   showmessage($message,'PressEnter');
+               my $message;
+               if ($auto_install->{EnterApacheUser}) {
+                       $message = $auto_install->{EnterApacheUser};
+                       print ON_YELLOW.BLACK."auto-setting Apache User to : $message".RESET."\n";
+               } else {
+                       $message=getmessage('EnterApacheUser', [$etcdir]);
+               }
+               until (defined($httpduser) && length($httpduser) && getpwnam($httpduser)) {
+                       if ($auto_install->{EnterApacheUser}) {
+                               $httpduser = $auto_install->{EnterApacheUser};
+                       } else {
+                               $httpduser=showmessage($message, "free", '');
+                       }
+                       if (length($httpduser)>0) {
+                               unless (getpwnam($httpduser)) {
+                                       my $message=getmessage('InvalidUserid', [$httpduser]);
+                                       showmessage($message,'PressEnter');
+                               }
+                       } else {
+                       }
                }
-           } else {
-           }
        }
-    }
 }
 
 
-=item getapachevhostinfo
-
-    getapachevhostinfo;
+=item C<getapachevhostinfo(;$)>
 
-Gets various pieces of information related to virtual hosting:
-the webmaster email address, virtual hostname, and the ports
-that the OPAC and INTRANET modules run on.
+Asks for various pieces of information related to virtual hosting: the
+webmaster email address, virtual hostname, and the ports that the OPAC
+and INTRANET modules run on.
 
 These pieces of information are saved to global variables; the
 function does not return any values.
@@ -1238,7 +1345,9 @@ and the installer will leave comments in
 
 NOTE: You will need to add lines to your main httpd.conf to
 include %s/koha-httpd.conf
+(using the Include directive)
 and to make sure it is listening on the right ports
+and host names
 (using the Listen directive).
 
 Press <ENTER> to continue: |;
@@ -1272,36 +1381,47 @@ the OPAC port (%s).
 Enter the Intranet Port [%s]: |;
 
 
-sub getapachevhostinfo {
-
+sub getapachevhostinfo (;$) {
+       my ($auto_install) = @_;
     $svr_admin = "webmaster\@$domainname";
     $servername=`hostname`;
     chomp $servername;
     $opacport=80;
     $intranetport=8080;
 
-    showmessage(getmessage('ApacheConfigIntroduction',[$etcdir,$etcdir]), 'PressEnter');
-
-    $svr_admin=showmessage(getmessage('GetVirtualHostEmail', [$svr_admin]), 'email', $svr_admin);
-    $servername=showmessage(getmessage('GetServerName', [$servername]), 'free', $servername);
-
-
-    $opacport=showmessage(getmessage('GetOpacPort', [$opacport]), 'numerical', $opacport);
-    $intranetport=showmessage(getmessage('GetIntranetPort', [$opacport, $intranetport]), 'numerical', $intranetport);
+       if ($auto_install->{GetVirtualHostEmail}) {
+               $svr_admin=$auto_install->{GetVirtualHostEmail};
+               print ON_YELLOW.BLACK."auto-setting VirtualHostEmail to : $svr_admin".RESET."\n";
+       } else {
+               showmessage(getmessage('ApacheConfigIntroduction',[$etcdir,$etcdir]), 'PressEnter');
+               $svr_admin=showmessage(getmessage('GetVirtualHostEmail', [$svr_admin]), 'email', $svr_admin);
+       }
+       if ($auto_install->{servername}) {
+               $servername=$auto_install->{servername};
+               print ON_YELLOW.BLACK."auto-setting server name to : $servername".RESET."\n";
+       } else {
+       $servername=showmessage(getmessage('GetServerName', [$servername]), 'free', $servername);
+       }
+       if ($auto_install->{opacport}) {
+               $opacport=$auto_install->{opacport};
+               print ON_YELLOW.BLACK."auto-setting opac port to : $opacport".RESET."\n";
+       } else {
+           $opacport=showmessage(getmessage('GetOpacPort', [$opacport]), 'numerical', $opacport);
+       }
+       if ($auto_install->{intranetport}) {
+               $intranetport=$auto_install->{intranetport};
+               print ON_YELLOW.BLACK."auto-setting intranet port to : $intranetport".RESET."\n";
+       } else {
+           $intranetport=showmessage(getmessage('GetIntranetPort', [$opacport, $intranetport]), 'numerical', $intranetport);
+       }
 
 }
 
 
-=item updateapacheconf
+=item C<updateapacheconf(;$)>
 
-    updateapacheconf;
-
-Updates the Apache config file according to parameters previously
-specified by the user.
-
-It will append fully-commented directives at the end of the original
-Apache config file.  The old config file is renamed with an extension
-of .prekoha.
+Creates the Apache config file according to parameters previously
+specified by the user as F<$etcdir/koha-httpd.conf>.
 
 If you need to uninstall Koha for any reason, the lines between
 
@@ -1338,11 +1458,12 @@ configuration.
 
 Press <ENTER> to continue: |;
 
-sub updateapacheconf {
+sub updateapacheconf (;$) {
+       my ($auto_install)=@_;
     my $logfiledir=$kohalogdir;
     my $httpdconf = $etcdir."/koha-httpd.conf";
    
-    showmessage(getmessage('StartUpdateApache'), 'none');
+    showmessage(getmessage('StartUpdateApache'), 'none') unless $auto_install->{NoPressEnter};
        # to be polite about it: I don't think this should touch the main httpd.conf
 
        # QUESTION: Should we warn for includes_module too?
@@ -1351,7 +1472,7 @@ sub updateapacheconf {
     open HC, "<$realhttpdconf";
     while (<HC>) {
        if (/^\s*#\s*LoadModule env_module /) {
-           showmessage(getmessage('ApacheConfigMissingModules'));
+           showmessage(getmessage('ApacheConfigMissingModules'),'none');
            $envmodule=1;
        }
        if (/\s*LoadModule includes_module / ) {
@@ -1380,12 +1501,22 @@ sub updateapacheconf {
        }
        print SITE <<EOP
 
+# Koha 2.2 Apache Virtual Host Config File
+#
+# Please include this file in your apache configuration.
+# The best way to do that depends on your site setup.
+# Some like an Include adding to /etc/apache/httpd.conf
+# and some prefer a symlink to this file from some dir.
+# Please refer to your system manuals.
+
 # Ports to listen to for Koha
 # uncomment these if they aren't already in main httpd.conf
 #$opaclisten
 #$intranetlisten
 
 # NameVirtualHost is used by one of the optional configurations detailed below
+# Please make sure this line is correct before uncommenting.
+# See http://httpd.apache.org/docs/vhosts/ for some guides.
 
 #NameVirtualHost 11.22.33.44
 
@@ -1395,6 +1526,7 @@ sub updateapacheconf {
    DocumentRoot $opacdir/htdocs
    ServerName $servername
    ScriptAlias /cgi-bin/koha/ $opacdir/cgi-bin/
+   Redirect permanent index.html http://$servername\:$opacport/cgi-bin/koha/opac-main.pl
    ErrorLog $logfiledir/opac-error_log
    TransferLog $logfiledir/opac-access_log
    SetEnv PERL5LIB "$intranetdir/modules"
@@ -1408,6 +1540,7 @@ sub updateapacheconf {
    DocumentRoot $intranetdir/htdocs
    ServerName $servername
    ScriptAlias /cgi-bin/koha/ "$intranetdir/cgi-bin/"
+   Redirect permanent index.html http://$servername\:$intranetport/cgi-bin/koha/mainpage.pl
    ErrorLog $logfiledir/koha-error_log
    TransferLog $logfiledir/koha-access_log
    SetEnv PERL5LIB "$intranetdir/modules"
@@ -1433,78 +1566,77 @@ EOP
 }
 
 
-=item basicauthentication
-
-    basicauthentication;
-
-Asks the user whether HTTP basic authentication is wanted, and,
-if so, the user name and password for the basic authentication.
-
-These pieces of information are saved to global variables; the
-function does not return any values.
-
-=cut
-
-$messages->{'IntranetAuthenticationQuestion'}->{en} =
-   heading('LIBRARIAN AUTHENTICATION') . qq|
-The Librarian site can be password protected using
-Apache's Basic Authorization instead of Koha user details.
-
-This method going to be phased out very soon.  Most users should answer N here.
-
-Would you like to do this (Y/[N]): |;  #'
-
-$messages->{'BasicAuthUsername'}->{en}="Please enter a username for librarian access [%s]: ";
-$messages->{'BasicAuthPassword'}->{en}="Please enter a password for %s: ";
-$messages->{'BasicAuthPasswordWasBlank'}->{en}="\nYou cannot use a blank password!\n\n";
-
-sub basicauthentication {
-    my $message=getmessage('IntranetAuthenticationQuestion');
-    my $answer=showmessage($message, 'yn', 'n');
-    my $httpdconf = $etcdir."/koha-httpd.conf";
-
-    my $apacheauthusername='librarian';
-    my $apacheauthpassword='';
-    if ($answer=~/^y/i) {
-       ($apacheauthusername) = showmessage(getmessage('BasicAuthUsername', [ $apacheauthusername]), 'free', $apacheauthusername, 1);
-       $apacheauthusername=~s/[^a-zA-Z0-9]//g;
-       while (! $apacheauthpassword) {
-           ($apacheauthpassword) = showmessage(getmessage('BasicAuthPassword', [ $apacheauthusername]), 'free', 1);
-           if (!$apacheauthpassword) {
-               ($apacheauthpassword) = showmessage(getmessage('BasicAuthPasswordWasBlank'), 'none', '', 1);
-           }
-       }
-       open AUTH, ">$etcdir/kohaintranet.pass";
-       my $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
-       my $salt=substr($chars, int(rand(length($chars))),1);
-       $salt.=substr($chars, int(rand(length($chars))),1);
-       print AUTH $apacheauthusername.":".crypt($apacheauthpassword, $salt)."\n";
-       close AUTH;
-       open(SITE,">>$httpdconf") or warn "Insufficient priveleges to open $realhttpdconf for writing.\n";
-       print SITE <<EOP
-
-<Directory $intranetdir>
-    AuthUserFile $etcdir/kohaintranet.pass
-    AuthType Basic
-    AuthName "Koha Intranet (for librarians only)"
-    Require  valid-user
-</Directory>
-EOP
-    }
-    close(SITE);
-}
-
-
-=item installfiles
-
-    installfiles
-
-Install the Koha files to the specified OPAC and INTRANET
+# =item C<basicauthentication(;$)>
+# 
+# Asks the user whether HTTP basic authentication is wanted, and,
+# if so, the user name and password for the basic authentication.
+# 
+# These pieces of information are saved to global variables; the
+# function does not return any values.
+# 
+# =cut
+# 
+# $messages->{'IntranetAuthenticationQuestion'}->{en} =
+#    heading('LIBRARIAN AUTHENTICATION') . qq|
+# The Librarian site can be password protected using
+# Apache's Basic Authorization instead of Koha user details.
+# 
+# This method going to be phased out very soon.  Most users should answer N here.
+# 
+# Would you like to do this (Y/[N]): |;        #'
+# 
+# $messages->{'BasicAuthUsername'}->{en}="Please enter a username for librarian access [%s]: ";
+# $messages->{'BasicAuthPassword'}->{en}="Please enter a password for %s: ";
+# $messages->{'BasicAuthPasswordWasBlank'}->{en}="\nYou cannot use a blank password!\n\n";
+# 
+# sub basicauthentication {
+#     my $message=getmessage('IntranetAuthenticationQuestion');
+#     my $answer=showmessage($message, 'yn', 'n');
+#     my $httpdconf = $etcdir."/koha-httpd.conf";
+# 
+#     my $apacheauthusername='librarian';
+#     my $apacheauthpassword='';
+#     if ($answer=~/^y/i) {
+#      ($apacheauthusername) = showmessage(getmessage('BasicAuthUsername', [ $apacheauthusername]), 'free', $apacheauthusername, 1);
+#      $apacheauthusername=~s/[^a-zA-Z0-9]//g;
+#      while (! $apacheauthpassword) {
+#          ($apacheauthpassword) = showmessage(getmessage('BasicAuthPassword', [ $apacheauthusername]), 'free', 1);
+#          if (!$apacheauthpassword) {
+#              ($apacheauthpassword) = showmessage(getmessage('BasicAuthPasswordWasBlank'), 'none', '', 1);
+#          }
+#      }
+#      open AUTH, ">$etcdir/kohaintranet.pass";
+#      my $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+#      my $salt=substr($chars, int(rand(length($chars))),1);
+#      $salt.=substr($chars, int(rand(length($chars))),1);
+#      print AUTH $apacheauthusername.":".crypt($apacheauthpassword, $salt)."\n";
+#      close AUTH;
+#      open(SITE,">>$httpdconf") or warn "Insufficient priveleges to open $realhttpdconf for writing.\n";
+#      print SITE <<EOP
+# 
+# <Directory $intranetdir>
+#     AuthUserFile $etcdir/kohaintranet.pass
+#     AuthType Basic
+#     AuthName "Koha Intranet (for librarians only)"
+#     Require  valid-user
+# </Directory>
+# EOP
+#     }
+#     close(SITE);
+# }
+
+
+=item C<installfiles(;$$)>
+
+Copy the Koha files to the specified OPAC and INTRANET
 directories (usually in /usr/local/koha).
 
-The koha.conf file is created, but as koha.conf.tmp. The
-caller is responsible for calling finalizeconfigfile when
-installation is completed, to rename it back to koha.conf.
+Creates the koha.conf file, but as koha.conf.tmp. The caller is
+responsible for calling C<finalizeconfigfile(;$)> when installation is
+completed, to rename it back to koha.conf.
+
+The first parameter may be a marker to say this is a new installation,
+rather than an upgrade.
 
 =cut
 
@@ -1528,47 +1660,50 @@ $messages->{'CopyingFiles'}->{en}="Copying %s to %s.\n";
 
 
 
-sub installfiles {
+sub installfiles (;$$) {
 
-       #MJR: preserve old files, just in case
+       my ($is_first_install,$auto_install) = @_;
+       # $is_install is set if it's a fresh install and not an upgrade. If it's an upgrade, copy old files.
+       
        sub neatcopy {
                my $desc = shift;
                my $src = shift;
                my $tgt = shift;
-               
-               if (-e $tgt) {
-               print getmessage('CopyingFiles', ["old ".$desc,$tgt.strftime("%Y%m%d%H%M",localtime())]);
-                       startsysout();
+               my $auto_install = shift;
+               my $is_first_install = shift;
+               if (!$is_first_install && -e $tgt) {
+               print getmessage('CopyingFiles', ["old ".$desc,$tgt.strftime("%Y%m%d%H%M",localtime())]) unless ($auto_install->{NoPressEnter});
                        system("mv ".$tgt." ".$tgt.strftime("%Y%m%d%H%M",localtime()));
+                       system("mkdir ".$tgt);   ##New line 
                }
-
-       print getmessage('CopyingFiles', [$desc,$tgt]);
-       startsysout;
-           system("cp -R ".$src." ".$tgt);
+               print getmessage('CopyingFiles', [$desc,$tgt]) unless ($auto_install->{NoPressEnter});
+               system("cp -R ".$src."/* ".$tgt);
        }
 
-    showmessage(getmessage('InstallFiles'),'none');
+#      my ($auto_install) = @_;
+       showmessage(getmessage('InstallFiles'),'none') unless ($auto_install->{NoPressEnter});
 
-    neatcopy("admin templates", 'intranet-html', "$intranetdir/htdocs");
-    neatcopy("admin interface", 'intranet-cgi', "$intranetdir/cgi-bin");
-    neatcopy("main scripts", 'scripts', "$intranetdir/scripts");
-    neatcopy("perl modules", 'modules', "$intranetdir/modules");
-    neatcopy("OPAC templates", 'opac-html', "$opacdir/htdocs");
-    neatcopy("OPAC interface", 'opac-cgi', "$opacdir/cgi-bin");
+       neatcopy("admin templates", 'intranet-html', "$intranetdir/htdocs",$auto_install,$is_first_install);
+       neatcopy("admin interface", 'intranet-cgi', "$intranetdir/cgi-bin",$auto_install,$is_first_install);
+       neatcopy("main scripts", 'scripts', "$intranetdir/scripts",$auto_install,$is_first_install);
+       neatcopy("perl modules", 'modules', "$intranetdir/modules",$auto_install,$is_first_install);
+       neatcopy("OPAC templates", 'opac-html', "$opacdir/htdocs",$auto_install,$is_first_install);
+       neatcopy("OPAC interface", 'opac-cgi', "$opacdir/cgi-bin",$auto_install,$is_first_install);
        startsysout();
-    system("touch $opacdir/cgi-bin/opac");
+       system("touch $opacdir/cgi-bin/opac");
 
        #MJR: is this necessary?
        if ($> == 0) {
-           system("chown -R $httpduser:$httpduser $opacdir $intranetdir");
-    }
+               my $httpdgrp = getgrnam($httpduser);
+               system("chown -R $httpduser:$httpdgrp $opacdir $intranetdir");
+       }
        system("chmod -R a+rx $opacdir $intranetdir");
 
-    # Create /etc/koha.conf
+       # Create /etc/koha.conf
 
-    my $old_umask = umask(027); # make sure koha.conf is never world-readable
-    open(SITES,">$etcdir/koha.conf.tmp") or warn "Couldn't create file at $etcdir. Must have write capability.\n";
-    print SITES qq|
+       my $old_umask = umask(027); # make sure koha.conf is never world-readable
+       open(SITES,">$etcdir/koha.conf.tmp") or warn "Couldn't create file at $etcdir. Must have write capability.\n";
+       print SITES qq|
 database=$database
 hostname=$hostname
 user=$user
@@ -1581,37 +1716,33 @@ httpduser=$httpduser
 intrahtdocs=$intranetdir/htdocs/intranet-tmpl
 opachtdocs=$opacdir/htdocs/opac-tmpl
 |;
-    close(SITES);
-    umask($old_umask);
+       close(SITES);
+       umask($old_umask);
 
        startsysout();
        #MJR: can't help but this be broken, can we?
-    chmod 0440, "$etcdir/koha.conf.tmp";
+       chmod 0440, "$etcdir/koha.conf.tmp";
        
        #MJR: does this contain any passwords?
-    chmod 0755, "$intranetdir/scripts/z3950daemon/z3950-daemon-launch.sh", "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh", "$intranetdir/scripts/z3950daemon/processz3950queue";
+       chmod 0755, "$intranetdir/scripts/z3950daemon/z3950-daemon-launch.sh", "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh", "$intranetdir/scripts/z3950daemon/processz3950queue";
 
-       #MJR: generate our own settings, to remove the /home/paul hardwired links
-    open(FILE,">$intranetdir/scripts/z3950daemon/z3950-daemon-options");
-    print FILE "RunAsUser=$httpduser\nKohaZ3950Dir=$intranetdir/scripts/z3950daemon\nKohaModuleDir=$intranetdir/modules\nLogDir=$kohalogdir\nKohaConf=$etcdir/koha.conf";
-    close(FILE);
+       open(FILE,">$intranetdir/scripts/z3950daemon/z3950-daemon-options");
+       print FILE "RunAsUser=$httpduser\nKohaZ3950Dir=$intranetdir/scripts/z3950daemon\nKohaModuleDir=$intranetdir/modules\nLogDir=$kohalogdir\nKohaConf=$etcdir/koha.conf";
+       close(FILE);
 
        if ($> == 0) {
            chown((getpwnam($httpduser)) [2,3], "$etcdir/koha.conf.tmp") or warn "can't chown koha.conf: $!";
-       chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh") or warn "can't chown $intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh: $!";
-       chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/processz3950queue") or warn "can't chown $intranetdir/scripts/z3950daemon/processz3950queue: $!";
+               chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh") or warn "can't chown $intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh: $!";
+               chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/processz3950queue") or warn "can't chown $intranetdir/scripts/z3950daemon/processz3950queue: $!";
        } #MJR: report that we haven't chown()d.
        else {
                print "Please check permissions in $intranetdir/scripts/z3950daemon\n";
        }
-
-    showmessage(getmessage('OldFiles'),'PressEnter');
+       showmessage(getmessage('OldFiles'),'PressEnter') unless ($auto_install->{NoPressEnter} or $is_first_install);
 }
 
 
-=item databasesetup
-
-    databasesetup;
+=item C<databasesetup(;$)>
 
 Finds out where the MySQL utitlities are located in the system,
 then create the Koha database structure and MySQL permissions.
@@ -1623,7 +1754,7 @@ $messages->{'MysqlRootPassword'}->{en} =
 To create the koha database, please enter your
 mysql server's root user password:
 
-Password: |;   #'
+Password: |;
 
 $messages->{'CreatingDatabase'}->{en} = heading('CREATING DATABASE') . qq|
 Creating the MySQL database for Koha...
@@ -1669,39 +1800,44 @@ $messages->{'BranchCode'}->{en}="Branch Code (4 letters or numbers) [%s]: ";
 $messages->{'PrinterQueue'}->{en}="Printer Queue [%s]: ";
 $messages->{'PrinterName'}->{en}="Printer Name [%s]: ";
 
-sub databasesetup {
+sub databasesetup (;$) {
+       my ($auto_install) = @_;
     $mysqluser = 'root';
     $mysqlpass = '';
        my $mysqldir = getmysqldir();
 
-    # we must not put the mysql root password on the command line
-       $mysqlpass=     showmessage(getmessage('MysqlRootPassword'),'silentfree');
+       if ($auto_install->{MysqlRootPassword}) {
+               $mysqlpass=$auto_install->{MysqlRootPassword};
+       } else {
+       # we must not put the mysql root password on the command line
+               $mysqlpass=     showmessage(getmessage('MysqlRootPassword'),'silentfree');
+       }
        
-       showmessage(getmessage('CreatingDatabase'),'none');
+       showmessage(getmessage('CreatingDatabase'),'none') unless ($auto_install->{NoPressEnter});
        # set the login up
        setmysqlclipass($mysqlpass);
        # Set up permissions
        startsysout();
-       print system("$mysqldir/bin/mysql -u$mysqluser mysql -e \"insert into user (Host,User,Password) values ('$hostname','$user',password('$pass'))\"\;");
-       system("$mysqldir/bin/mysql -u$mysqluser mysql -e \"insert into db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv, index_priv, alter_priv) values ('%','$database','$user','Y','Y','Y','Y','Y','Y','Y','Y')\"");
-       system("$mysqldir/bin/mysqladmin -u$mysqluser reload");
+       print system("$mysqldir/bin/mysql -u$mysqluser -e \"insert into user (Host,User,Password) values ('$hostname','$user',password('$pass'))\" -h$hostname mysql\;");
+       system("$mysqldir/bin/mysql -u$mysqluser -e \"insert into db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv, index_priv, alter_priv) values ('%','$database','$user','Y','Y','Y','Y','Y','Y','Y','Y')\" -h$hostname mysql");
+       system("$mysqldir/bin/mysqladmin -u$mysqluser -h$hostname reload");
+
+       my $result=system("$mysqldir/bin/mysqladmin", "-u$mysqluser", "create", "$database");
+       system("$mysqldir/bin/mysql '-u$mysqluser' -e \"GRANT ALL PRIVILEGES on ".$database.".* to '$user' IDENTIFIED BY '$pass' \" mysql");
        # Change to admin user login
        setmysqlclipass($pass);
-       my $result=system("$mysqldir/bin/mysqladmin", "-u$user", "create", "$database");
        if ($result) {
                showmessage(getmessage('CreatingDatabaseError'),'PressEnter', '', 1);
        } else {
                # Create the database structure
                startsysout();
-               system("$mysqldir/bin/mysql -u$user $database < koha.mysql");
+               system("$mysqldir/bin/mysql '-u$user' '$database' < koha.mysql");
        }
 
 }
 
 
-=item updatedatabase
-
-    updatedatabase;
+=item C<updatedatabase(;$)>
 
 Updates the Koha database structure, including the addition of
 MARC tables.
@@ -1721,8 +1857,10 @@ $messages->{'UpdateMarcTables'}->{en} =
    heading('MARC FIELD DEFINITIONS') . qq|
 You can import MARC settings for:
 
-  1 MARC21
-  2 UNIMARC
+  1 MARC21 in english
+  2 UNIMARC in french
+  3 UNIMARC in english
+  4 UNIMARC in ukrainian
   N none
 
 NOTE: If you choose N,
@@ -1730,15 +1868,17 @@ nothing will be added, and you must create them all yourself.
 Only choose N if you want to use a MARC format not listed here,
 such as DANMARC.  We would like to hear from you if you do.
 
+*** UPGRADE ***
+If you UPGRADE your version from a previous 2.x.x, the right choice here is N (None) to preserve your local MARC setup.
+
 Choose MARC definition [1]: |;
 
 $messages->{'Language'}->{en} = heading('CHOOSE LANGUAGE') . qq|
 This version of koha supports a few languages.
 
   en : default language, all pages available
-  fr : complete translation (except pictures)
-  es : partial librarian site translation (including pictures)
-  pl : complete OPAC and partial librarian translation
+  fr : complete translation
+  es : partial librarian site translation
   zh_TW : partial translation
 
 en is used when a screen is not available in your language
@@ -1748,104 +1888,196 @@ change it from the system preferences screen in the librarian sit.
 
 Which language do you choose? |;
 
-sub updatedatabase {
+sub updatedatabase (;$) {
+       my ($auto_install) = @_;
     # At this point, $etcdir/koha.conf must exist, for C4::Context
     $ENV{"KOHA_CONF"}=$etcdir.'/koha.conf';
     if (! -e $ENV{"KOHA_CONF"}) { $ENV{"KOHA_CONF"}=$etcdir.'/koha.conf.tmp'; }
        startsysout();  
-       my $result=system ("perl -I $intranetdir/modules scripts/updater/updatedatabase");
+       setmysqlclipass($pass);
+       my $result=system ("perl -I $intranetdir/modules scripts/updater/updatedatabase -s");
        if ($result) {
                restoremycnf();
                print "Problem updating database...\n";
                exit;
        }
-
-       my $response=showmessage(getmessage('UpdateMarcTables'), 'restrictchar 12N', '1');
-
+       my $response;
+       if ($auto_install->{UpdateMarcTables}) {
+               $response=$auto_install->{UpdateMarcTables};
+               print ON_YELLOW.BLACK."auto-setting UpdateMarcTable to : $response".RESET."\n";
+       } else {
+               $response=showmessage(getmessage('UpdateMarcTables'), 'restrictchar 1234Nn', '1');
+       }
        startsysout();
        if ($response eq '1') {
-               system("cat scripts/misc/marc_datas/marc21_en/structure_def.sql | $mysqldir/bin/mysql -u$user $database");
-               system("cat scripts/misc/lang-datas/en/stopwords.sql | $mysqldir/bin/mysql -u$user $database");
+               system("cat scripts/misc/marc_datas/marc21_en/structure_def.sql | $mysqldir/bin/mysql '-u$user' '$database'");
        }
        if ($response eq '2') {
-               system("cat scripts/misc/marc_datas/unimarc_fr/structure_def.sql | $mysqldir/bin/mysql -u$user $database");
-               system("cat scripts/misc/lang-datas/fr/stopwords.sql | $mysqldir/bin/mysql -u$user $database");
+               system("cat scripts/misc/marc_datas/unimarc_fr/structure_def.sql | $mysqldir/bin/mysql '-u$user' '$database'");
+       }
+       if ($response eq '3') {
+               system("cat scripts/misc/marc_datas/unimarc_en/structure_def.sql | $mysqldir/bin/mysql '-u$user' '$database'");
+       }
+       if ($response eq '4') {
+               system("cat scripts/misc/marc_datas/unimarc_uk/structure_def.sql | $mysqldir/bin/mysql '-u$user' '$database'");
        }
        delete($ENV{"KOHA_CONF"});
 
-       print RESET."\n\nFinished updating of database. Press <ENTER> to continue...";
-       <STDIN>;
+       print RESET."\nFinished updating of database. Press <ENTER> to continue..." unless ($auto_install->{NoPressEnter});
+       <STDIN> unless ($auto_install->{NoPressEnter});
 }
 
 
-=item populatedatabase
-
-    populatedatabase;
+=item C<populatedatabase(;$)>
 
-Populate the non-MARC tables. If the user wants to install the
-sample data, install them.
+Populates the non-MARC tables and installs sample data,
+if wanted.
 
 =cut
 
-sub populatedatabase {
-#      my $response=showmessage(getmessage('SampleData'), 'yn', 'n');
-#      if ($response =~/^y/i) {
-#
-# FIXME: These calls are now unsafe and should either be removed
-# or updated to use -u$user and no mysqlpass_quoted
-#
-#              system("gunzip -d < sampledata-1.2.gz | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $database");
-#              system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $database -e \"insert into branches (branchcode,branchname,issuing) values ('MAIN', 'Main Library', 1)\"");
-#              system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $database -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
-#              system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $database -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
-#              system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $database -e \"insert into printers (printername,printqueue,printtype) values ('Circulation Desk Printer', 'lp', 'hp')\"");
-#              showmessage(getmessage('SampleDataInstalled'), 'PressEnter','',1);
-#      } else {
-               my $input;
-               my $response=showmessage(getmessage('AddBranchPrinter'), 'yn', 'y');
-
+$messages->{'ConfirmFileUpload'}->{en} = qq|
+Confirm loading of this file into Koha  [Y]/N: |;
+
+sub populatedatabase (;$) {
+       my ($auto_install) = @_;
+       my $input;
+       my $response;
+       my $branch='MAIN';
+       if ($auto_install->{BranchName}) {
+               $branch=$auto_install->{BranchName};
+               print ON_YELLOW.BLACK."auto-setting a branch : $branch".RESET."\n";
+       } else {
+               $response=showmessage(getmessage('AddBranchPrinter'), 'yn', 'y');
                unless ($response =~/^n/i) {
-               my $branch='Main Library';
-               $branch=showmessage(getmessage('BranchName', [$branch]), 'free', $branch, 1);
-               $branch=~s/[^A-Za-z0-9\s]//g;
-
+                       $branch=showmessage(getmessage('BranchName', [$branch]), 'free', $branch, 1);
+                       $branch=~s/[^A-Za-z0-9\s]//g;
+               }
+       }
+       if ($branch) {
                my $branchcode=$branch;
                $branchcode=~s/[^A-Za-z0-9]//g;
                $branchcode=uc($branchcode);
                $branchcode=substr($branchcode,0,4);
-               $branchcode=showmessage(getmessage('BranchCode', [$branchcode]), 'free', $branchcode, 1);
+               if ($auto_install->{BranchCode}) {
+                       $branchcode=$auto_install->{BranchCode};
+                       print ON_YELLOW.BLACK."auto-setting branch code : $branchcode".RESET."\n";
+               } else {
+                       $branchcode=showmessage(getmessage('BranchCode', [$branchcode]), 'free', $branchcode, 1);
+               }
                $branchcode=~s/[^A-Za-z0-9]//g;
                $branchcode=uc($branchcode);
                $branchcode=substr($branchcode,0,4);
                $branchcode or $branchcode='DEF';
 
                startsysout();
-               system("$mysqldir/bin/mysql -u$user $database -e \"insert into branches (branchcode,branchname,issuing) values ('$branchcode', '$branch', 1)\"");
-               system("$mysqldir/bin/mysql -u$user $database -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
-               system("$mysqldir/bin/mysql -u$user $database -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
-
-               my $printername='Library Printer';
-               $printername=showmessage(getmessage('PrinterName', [$printername]), 'free', $printername, 1);
-               $printername=~s/[^A-Za-z0-9\s]//g;
-
-               my $printerqueue='lp';
-               $printerqueue=showmessage(getmessage('PrinterQueue', [$printerqueue]), 'free', $printerqueue, 1);
-               $printerqueue=~s/[^A-Za-z0-9]//g;
+               system("$mysqldir/bin/mysql '-u$user' -e \"insert into branches (branchcode,branchname,issuing) values ('$branchcode', '$branch', 1)\" $database");
+               system("$mysqldir/bin/mysql '-u$user' -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\" $database");
+               system("$mysqldir/bin/mysql '-u$user' -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\" $database");
+
+               my $printername='lp';
+               my $printerqueue='/dev/lp0';
+               if ($auto_install->{PrinterName}) {
+                       $printername=$auto_install->{PrinterName};
+                       print ON_YELLOW.BLACK."auto-setting a printer : $printername".RESET."\n";
+               } else {
+                       $printername=showmessage(getmessage('PrinterName', [$printername]), 'free', $printername, 1);
+                       $printername=~s/[^A-Za-z0-9\s]//g;
+               }
+               if ($auto_install->{PrinterQueue}) {
+                       $printerqueue=$auto_install->{PrinterQueue};
+                       print ON_YELLOW.BLACK."auto-setting printer queue to : $printerqueue".RESET."\n";
+               } else {
+                       $printerqueue=showmessage(getmessage('PrinterQueue', [$printerqueue]), 'free', $printerqueue, 1);
+                       $printerqueue=~s/[^A-Za-z0-9]//g;
+               }
                startsysout();  
-               system("$mysqldir/bin/mysql -u$user $database -e \"insert into printers (printername,printqueue,printtype) values ('$printername', '$printerqueue', '')\"");
-#              }
-       my $language=showmessage(getmessage('Language'), 'free', 'en');
+               system("$mysqldir/bin/mysql '-u$user' -e \"insert into printers (printername,printqueue,printtype) values ('$printername', '$printerqueue', '')\" $database");
+       }
+       my $language;
+       if ($auto_install->{Language}) {
+               $language=$auto_install->{Language};
+               print ON_YELLOW.BLACK."auto-setting language to : $language".RESET."\n";
+       } else {
+               $language=showmessage(getmessage('Language'), 'free', 'en');
+       }
        startsysout();  
-       system("$mysqldir/bin/mysql -u$user $database -e \"update systempreferences set value='$language' where variable='opaclanguages'\"");
+       system("$mysqldir/bin/mysql '-u$user' -e \"update systempreferences set value='$language' where variable='opaclanguages'\" $database");
+       my @dirs;
+       if (-d "scripts/misc/sql-datas") {
+               # ask for directory to look for files to append
+               my @directories;
+               push @directories,"FINISHED";
+               if (-d "scripts/misc/sql-datas") {
+                       opendir D, "scripts/misc/sql-datas";
+                       foreach my $dir (readdir D) {
+                               next if ($dir =~ /^\./);
+                               push @directories, $dir;
+                       }
+               }
+               my $loopend=0;
+               while (not $loopend) {
+                       print heading("SELECT SQL DIRECTORY");
+                       print qq|
+Select a directory. You will see every file included in this directory and be able to choose file(s) to import into Koha
+This is a VERY important feature. By selecting the proper options, you can get a pre-setup Koha, almost ready to be put in production.
+Choose wisely.
+|;
+                       for (my $i=0;$i<=$#directories;$i++) {
+                               print "$i => ".$directories[$i]."\n";
+                       }
+                       my $sqluploaddir =<STDIN>;
+                       if ($sqluploaddir==0) {
+                               $loopend = 1;
+                       } else {
+                               $sqluploaddir = $directories[$sqluploaddir];
+                               # CHECK for any other file to append...
+                               my @sql;
+                               push @sql,"FINISHED";
+                               if (-d "scripts/misc/sql-datas/$sqluploaddir") {
+                                       opendir D, "scripts/misc/sql-datas/$sqluploaddir";
+                                       foreach my $sql (readdir D) {
+                                               next unless ($sql =~ /.txt$/);
+                                               push @sql, $sql;
+                                       }
+                               }
+                               $loopend=0;
+                               while (not $loopend) {
+                                       print heading("SELECT SQL FILE");
+                                       print qq|
+Select a file to append to the Koha DB.
+enter a number. A detailled explanation of the file will be given
+if you confirm, the file will be added to the DB
+|;
+                                       for (my $i=0;$i<=$#sql;$i++) {
+                                               print "$i => ".$sql[$i]."\n";
+                                       }
+                                       my $response =<STDIN>;
+                                       if ($response==0) {
+                                               $loopend = 1;
+                                       } else {
+                                               # show the content of the file
+                                               my $FileToUpload = $sql[$response];
+                                               open FILE,"scripts/misc/sql-datas/$sqluploaddir/$FileToUpload";
+                                               my $content = <FILE>;
+                                               print heading("INSERT $sqluploaddir/$FileToUpload ?")."$content\n";
+                                               # ask confirmation
+                                               $response=showmessage(getmessage('ConfirmFileUpload'), 'yn', 'y');
+                                               # if confirmed, upload the file in the DB
+                                               unless ($response =~/^n/i) {
+                                                       $FileToUpload =~ s/\.txt/\.sql/;
+                                                       system("$mysqldir/bin/mysql '-u$user' '$database' <scripts/misc/sql-datas/$sqluploaddir/$FileToUpload");
+                                               }
+                                       }
+                               }
+                               $loopend=0;
+                       }
+               }
        }
 }
 
+=item C<restartapache(;$)>
 
-=item restartapache
-
-    restartapache;
-
-Asks the user whether to restart Apache, and restart it if the user
+Asks the user whether to restart Apache, and restarts it if the user
 wants so.
 
 =cut
@@ -1856,29 +2088,28 @@ The installer can do this if you are using Apache and give the root password.
 
 Would you like to try to restart Apache now?  [Y]/N: |;
 
-sub restartapache {
-
-    my $response=showmessage(getmessage('RestartApache'), 'yn', 'y');
+sub restartapache (;$) {
+       my ($auto_install)=@_;
+       my $response;
+    $response=showmessage(getmessage('RestartApache'), 'yn', 'y') unless ($auto_install->{NoPressEnter});
+    $response='y' if ($auto_install->{NoPressEnter});
 
     unless ($response=~/^n/i) {
-       startsysout();
-       # Need to support other init structures here?
-       if (-e "/etc/rc.d/init.d/httpd") {
-           system('su root -c /etc/rc.d/init.d/httpd restart');
-       } elsif (-e "/etc/init.d/apache") {
-           system('su root -c /etc/init.d/apache restart');
-       } elsif (-e "/etc/init.d/apache-ssl") {
-           system('su root -c /etc/init.d/apache-ssl restart');
+               startsysout();
+               # Need to support other init structures here?
+               if (-e "/etc/rc.d/init.d/httpd") {
+                       system('su root -c "/etc/rc.d/init.d/httpd restart"');
+               } elsif (-e "/etc/init.d/apache") {
+                       system('su root -c "/etc/init.d/apache restart"');
+               } elsif (-e "/etc/init.d/apache-ssl") {
+                       system('su root -c "/etc/init.d/apache-ssl restart"');
+               }
        }
-    }
-
 }
 
-=item backupkoha
+=item C<backupkoha(;$)>
 
-   backupkoha;
-
-This function attempts to back up all koha's details.
+Attempts to make backup copies of all koha's details.
 
 =cut
 
@@ -1903,10 +2134,12 @@ File Listing
 Does this look right? ([Y]/N): |;
 
 #FIXME: rewrite to use Install.pm
-sub backupkoha {
-my $backupdir=$ENV{'prefix'}.'/backups';
+sub backupkoha () {
+if (!$ENV{prefix}) { $ENV{prefix} = "/usr/local"; }
+my $backupdir=$ENV{prefix}.'/backups';
 
 my $answer = showmessage(getmessage('BackupDir',[$backupdir]),'free',$backupdir);
+$backupdir = $answer; 
 
 if (! -e $backupdir) {
        my $result=mkdir ($backupdir, oct(770));
@@ -1934,7 +2167,8 @@ $month++;
 $year+=1900;
 my $date= sprintf "%4d-%02d-%02d_%02d:%02d:%02d", $year, $month, $day,$hr,$min,$sec;
 
-open (MD, "$mysqldir/bin/mysqldump --user=$user --password=$pass --host=$hostname $database|");
+setmysqlclipass($pass); 
+open (MD, "$mysqldir/bin/mysqldump --user=$user --host=$hostname $database|");
 
 (open BF, ">$backupdir/Koha.backup_$date") || (die "Error opening up backup file $backupdir/Koha.backup_$date: $!\n");
 
@@ -1975,13 +2209,11 @@ Aborting.  The database dump is located in:
 
 }
 
-=item finalizeconfigfile
-
-   finalizeconfigfile;
+=item C<finalizeconfigfile()>
 
-This function must be called when the installation is complete,
-to rename the koha.conf.tmp file to koha.conf.
+Renames F<koha.conf.tmp> file to F<koha.conf>.
 
+This file must be renamed when the installation is complete,
 Currently, failure to rename the file results only in a warning.
 
 =cut
@@ -2002,19 +2234,15 @@ EOF
 }
 
 
-=item loadconfigfile
+=item C<loadconfigfile()>
 
-   loadconfigfile
-
-Open the existing koha.conf file and get its values,
-saving the values to some global variables.
-
-If the existing koha.conf file cannot be opened for any reason,
-the file is silently ignored.
+Opens the existing koha.conf file and gets its values, saving the
+values to some global variables.  If the existing koha.conf file
+cannot be opened for any reason, the file is silently ignored.
 
 =cut
 
-sub loadconfigfile {
+sub loadconfigfile () {
     my %configfile;
 
        #MJR: reverted to r1.53.  Please call setetcdir().  Do NOT hardcode this.
@@ -2079,10 +2307,10 @@ sub backupmycnf {
 }
 
 sub restoremycnf {
-       if (-e $mycnf) {
+       if (defined $mycnf && -e $mycnf) {
                unlink($mycnf);
        }
-       if (-e $mytmpcnf) {
+       if (defined $mytmpcnf && -e $mytmpcnf) {
                rename $mytmpcnf,$mycnf;
        }
 }