1 package Install; #assumes Install.pm
4 # Copyright 2000-2002 Katipo Communications
6 # This file is part of Koha.
8 # Koha is free software; you can redistribute it and/or modify it under the
9 # terms of the GNU General Public License as published by the Free Software
10 # Foundation; either version 2 of the License, or (at your option) any later
13 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License along with
18 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
19 # Suite 330, Boston, MA 02111-1307 USA
25 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
29 Install.pm - Perl module containing the bulk of the installation logic
33 The Install.pm module contains the bulk
34 of the code to do installation;
35 this code is used by installer.pl
36 to perform an actual installation.
38 =head2 Internal functions (not meant to be used outside of Install.pm)
44 # set the version for version checking
48 @EXPORT = qw( &checkperlmodules
52 &releasecandidatewarning
53 &getinstallationdirectories
67 use vars qw( $kohaversion ); # set in installer.pl
68 use vars qw( $language ); # set in installer.pl
69 use vars qw( $domainname ); # set in installer.pl
71 use vars qw( $etcdir ); # set in installer.pl, usu. /etc
72 use vars qw( $intranetdir $opacdir $kohalogdir );
73 use vars qw( $realhttpdconf $httpduser );
74 use vars qw( $servername $svr_admin $opacport $intranetport );
75 use vars qw( $mysqldir );
76 use vars qw( $database $mysqluser );
77 use vars qw( $mysqlpass ); # normally should not be used
78 use vars qw( $mysqlpass_quoted ); # quoted, contains -p as needed
79 use vars qw( $dbname $hostname $user $pass ); # virtual hosting
81 use vars qw( $newversion ); # XXX this seems to be unused
85 $messages->{'WelcomeToKohaInstaller'
86 = heading('Welcome to the Koha Installer') . qq|...|;
88 The heading function takes one string, the text to be displayed as
89 the heading, and returns a formatted heading (currently formatted
90 in the "traditional Koha installer" style, i.e., surrounded by a
93 This reduces the likelihood of pod2man(1) etc. misinterpreting
94 a line of equal signs as POD directives.
100 my $n = length($s) + 4;
101 my $line = ('=' x $n) . "\n";
102 "\n$line= $s =\n$line\n";
106 $messages->{'continuing'}->{en}="Great! Continuing setup.\n\n";
107 $messages->{'WelcomeToKohaInstaller'}->{en} =
108 heading('Welcome to the Koha Installer') . qq|
109 Welcome to the Koha install script! This script will prompt you for some
110 basic information about your desired setup, then install Koha according to
111 your specifications. To accept the default value for any question, simply hit
114 Please be sure to read the documentation, or visit the Koha website at
115 http://www.koha.org for more information.
117 Are you ready to begin the installation? (Y/[N]): |;
118 $messages->{'ReleaseCandidateWarning'}->{en} =
119 heading('RELEASE CANDIDATE') . qq|
120 WARNING WARNING WARNING WARNING WARNING
122 You are about to install Koha version %s. This version of Koha is a
123 release candidate. It is not intended to be installed on production systems.
124 It is being released so that users can test it before we release a final
127 Are you sure you want to install Koha %s? (Y/[N]): |;
128 $messages->{'WatchForReleaseAnnouncements'}->{en}=qq|
130 Watch for announcements of Koha releases on the Koha mailing list or the Koha
131 web site (http://www.koha.org/).
135 $messages->{'NETZ3950Missing'}->{en}=qq|
137 The Net::Z3950 module is missing. This module is necessary if you want to use
138 Koha's Z39.50 client to download bibliographic records from other libraries.
139 To install this module, you will need the yaz client installed from
140 http://www.indexdata.dk/yaz/ and then you can install the perl module with the
143 perl -MCPAN -e 'install Net::Z3950'
145 Press the <ENTER> key to continue: |;
147 $messages->{'CheckingPerlModules'}->{en} = heading('PERL & MODULES') . qq|
148 Checking perl modules ...
151 $messages->{'PerlVersionFailure'}->{en}="Sorry, you need at least Perl %s\n";
153 $messages->{'MissingPerlModules'}->{en} = heading('MISSING PERL MODULES') . qq|
154 You are missing some Perl modules which are required by Koha.
155 Once these modules have been installed, rerun this installer.
156 They can be installed by running (as root) the following:
161 $messages->{'AllPerlModulesInstalled'}->{en} =
162 heading('ALL PERL MODULES INSTALLED') . qq|
163 All mandatory perl modules are installed.
165 Press <ENTER> to continue: |;
166 $messages->{'KohaVersionInstalled'}->{en}="You currently have Koha %s on your system.";
167 $messages->{'KohaUnknownVersionInstalled'}->{en}="I am not able to determine what version of Koha is installed now.";
168 $messages->{'KohaAlreadyInstalled'}->{en} =
169 heading('Koha already installed') . qq|
170 It looks like Koha is already installed on your system (%s/koha.conf exists
171 already). If you would like to upgrade your system to %s, please use
172 the koha.upgrade script in this directory.
177 $messages->{'GetOpacDir'}->{en} = heading('OPAC DIRECTORY') . qq|
178 Please supply the directory you want Koha to store its OPAC files in. This
179 directory will be auto-created for you if it doesn't exist.
181 OPAC Directory [%s]: |;
183 $messages->{'GetIntranetDir'}->{en} =
184 heading('INTRANET/LIBRARIANS DIRECTORY') . qq|
185 Please supply the directory you want Koha to store its Intranet/Librarians
186 files in. This directory will be auto-created for you if it doesn't exist.
188 Intranet Directory [%s]: |;
190 $messages->{'GetKohaLogDir'}->{en} = heading('KOHA LOG DIRECTORY') . qq|
191 Specify a log directory where any Koha daemons can create log files.
193 Koha Log Directory [%s]: |;
195 $messages->{'AuthenticationWarning'}->{en} = heading('Authentication') . qq|
196 This release of Koha has a new authentication module. If you are not already
197 using basic authentication on your intranet, you will be required to log in to
198 access some of the features of the intranet. You can log in using the userid
199 and password from the %s/koha.conf configuration file at any time. Use the
200 "Members" module to add passwords for other accounts and set their permissions.
202 Press the <ENTER> key to continue: |;
204 $messages->{'Completed'}->{en} = heading('KOHA INSTALLATION COMPLETE') . qq|
205 Congratulations ... your Koha installation is complete!
207 You will be able to connect to your Librarian interface at:
211 and the OPAC interface at :
215 Be sure to read the INSTALL, and Hints files.
217 For more information visit http://www.koha.org
219 Press <ENTER> to exit the installer: |;
221 sub releasecandidatewarning {
222 my $message=getmessage('ReleaseCandidateWarning', [$newversion, $newversion]);
223 my $answer=showmessage($message, 'yn', 'n');
225 if ($answer =~ /y/i) {
226 print getmessage('continuing');
228 my $message=getmessage('WatchForReleaseAnnouncements');
237 =head2 Accessor functions (for installer.pl)
247 Sets the installation language, normally "en" (English).
248 In fact, only "en" is supported.
252 sub setlanguage ($) {
258 setdomainname('example.org');
260 Sets the domain name of the host.
262 The domain name should not contain a leading dot;
263 otherwise, the results are undefined.
267 sub setdomainname ($) {
275 Sets the sysconfdir, normally /etc.
276 This should be an absolute path; a trailing / is not required.
286 setkohaversion('1.3.3RC26');
288 Sets the Koha version as known by the installer.
292 sub setkohaversion ($) {
298 my $servername = getservername;
300 Gets the name of the Koha virtual server as specified by the user.
304 sub getservername () {
312 Gets the port that will run the Koha OPAC virtual server,
313 as specified by the user.
321 =item getintranetport
323 $port = getintranetport;
325 Gets the port that will run the Koha INTRANET virtual server,
326 as specified by the user.
330 sub getintranetport () {
336 =head2 Miscellaneous utility functions
346 Does the equivalent of dirname(1). Given a path $path, return the
347 parent directory of $path (best guess), except when $path seems to
348 be the same as /, in which case $path itself is returned unchanged.
354 if ($path =~ /[^\/]/s) {
356 $path =~ s/\/+[^\/]+\/*$//s;
367 mkdir_parents $path, $mode;
369 Does the equivalent of mkdir -p, or mkdir --parents. Given a path $path,
370 create the directory $path, recursively creating any intermediate
371 directories. If $mode is given, the directory will be created with
374 WARNING: If $path already exists, mkdir_parents will just return
375 successfully (just like mkdir -p), whether the mode of $path conforms
376 to $mode or not. (This is the behaviour of the mkdir -p command.)
380 sub mkdir_parents ($;$) {
381 my($path, $mode) = @_;
382 my $ok = -d($path)? 1: defined $mode? mkdir($path, $mode): mkdir($path);
384 if (!$ok && $! == ENOENT) {
385 my $parent = dirname($path);
386 $ok = mkdir_parents($parent, $mode);
388 # retry and at the same time make sure that $! is set correctly
389 $ok = defined $mode? mkdir($path, $mode): mkdir($path);
398 getmessage($msgid, $variables);
400 Gets a localized message (format string) with message id $msgid,
401 and, if an array reference of variables $variables is given,
402 substitutes variables in the format string with @$variables.
403 Returns the found message string, with variable substitutions
406 $msgid must be the message identifier corresponding to a defined
407 message string (a valid key to the $messages hash in the Installer
408 package). getmessage throws an exception if the message cannot be
414 my $messagename=shift;
416 my $message=$messages->{$messagename}->{$language} || $messages->{$messagename}->{en} || "Error: No message named $messagename in Install.pm\n";
417 if (defined($variables)) {
418 $message=sprintf $message, @$variables;
426 showmessage($message, 'none');
427 showmessage($message, 'none', undef, $noclear);
429 $result = showmessage($message, 'yn');
430 $result = showmessage($message, 'yn', $defaultresponse);
431 $result = showmessage($message, 'yn', $defaultresponse, $noclear);
433 $result = showmessage($message, 'restrictchar CHARS');
434 $result = showmessage($message, 'free');
435 $result = showmessage($message, 'numerical');
436 $result = showmessage($message, 'email');
437 $result = showmessage($message, 'PressEnter');
439 Shows a message and optionally gets a response from the user.
441 The first two arguments, the message and the response type,
442 are mandatory. The message must be the actual string to
443 display. The caller is responsible for calling getmessage if
446 The response type must be one of "none", "yn", "free",
447 "numerical", "email", "PressEnter", or a string consisting
448 of "restrictchar " followed by a list of allowed characters
449 (space can be specified). (Case is not significant, but case is
450 significant in the list of allowed characters.) If a response
451 type other than the above-listed is specified, the result is
454 Note that the response type "yn" is equivalent to "restrictchar yn".
455 Because "restrictchar" is case-sensitive, the user is expected
456 to enter "y" or "n" in lowercase only.
458 Note that the response type of "email" does not actually
459 guarantee that the returned value is a well-formed RFC-822
460 email address, nor does it accept all well-formed RFC-822 email
461 addresses. What it does is to restrict the returned value to a
462 string that is looks reasonably likely to be an email address
465 If a response type other than "none" or "PressEnter" is
466 specified, a third argument, specifying the default value, can
467 be specified: If this default response is not specified, the
468 default response is the first allowed character if the response
469 type is "restrictchar", otherwise the default response is the
470 empty string. This default response is used when the user does
471 not specify a value (i.e., presses Enter without typing in
472 anything), showmessage will assume that the default response is
475 Note that because the response type "yn" is equivalent to
476 "restrictchar yn", the default value for response type "yn",
477 if unspecified, is "y".
479 The screen is normally cleared before the message is displayed;
480 if a fourth argument is specified and is nonzero, this
481 screen-clearing is not done.
483 FIXME: A response type of "yn" should allow the user to specify
484 "y" or "n" in either upercase or lowercase.
486 FIXME: If the response type is "free", the user cannot specify
487 an empty string; showmessage will return "1" as the result.
489 FIXME: A default response of "0" cannot be specified. This is
490 wrong; the default response should be checked for undef, not
493 FIXME: If $noclear is not specified or specified as undef, we
494 just test it for a non-zero value without testing it for being
501 my $responsetype=shift;
502 my $defaultresponse=shift;
504 ($noclear) || (system('clear'));
505 if ($responsetype =~ /^yn$/) {
506 $responsetype='restrictchar yn';
510 if ($responsetype =~/^restrictchar (.*)/i) {
513 until ($options=~/$response/) {
514 ($defaultresponse) || ($defaultresponse=substr($options,0,1));
517 (length($response)) || ($response=$defaultresponse);
518 unless ($options=~/$response/) {
519 ($noclear) || (system('clear'));
520 print "Invalid Response. Choose from [$options].\n\n";
526 if ($responsetype =~/^free$/i) {
527 (defined($defaultresponse)) || ($defaultresponse='');
528 my $response=<STDIN>;
530 ($response) || ($response=$defaultresponse);
533 if ($responsetype =~/^numerical$/i) {
534 (defined($defaultresponse)) || ($defaultresponse='');
536 until ($response=~/^\d+$/) {
539 ($response) || ($response=$defaultresponse);
540 unless ($response=~/^\d+$/) {
541 ($noclear) || (system('clear'));
542 print "Invalid Response ($response). Response must be a number.\n\n";
548 if ($responsetype =~/^email$/i) {
549 (defined($defaultresponse)) || ($defaultresponse='');
551 until ($response=~/.*\@.*\..*/) {
554 ($response) || ($response=$defaultresponse);
555 unless ($response=~/.*\@.*\..*/) {
556 ($noclear) || (system('clear'));
557 print "Invalid Response ($response). Response must be a valid email address.\n\n";
563 if ($responsetype =~/^PressEnter$/i) {
567 if ($responsetype =~/^none$/i) {
576 =head2 Subtasks of doing an installation
582 =item checkabortedinstall
586 Checks whether a previous installation process has been abnormally
587 aborted, by checking whether $etcidr/koha.conf is a symlink matching
588 a particular pattern. If an aborted installation is detected, give
589 the user a chance to abort, before trying to recover the aborted
592 FIXME: The recovery is not complete; it only partially rolls back
597 sub checkabortedinstall () {
598 if (-l("$etcdir/koha.conf")
599 && readlink("$etcdir/koha.conf") =~ /\.tmp$/
602 I have detected that you tried to install Koha before, but the installation
603 was aborted. I will try to continue, but there might be problems if the
604 database is already created.
607 print "Please press <ENTER> to continue: ";
610 # Remove the symlink after the <STDIN>, so the user can back out
611 unlink "$etcdir/koha.conf"
612 || die "Failed to remove incomplete $etcdir/koha.conf: $!\n";
617 =item checkperlmodules
621 Test whether the version of Perl is new enough, whether Perl is
622 found at the expected location, and whether all required modules
627 sub checkperlmodules {
629 # Test for Perl and Modules
632 my $message = getmessage('CheckingPerlModules');
633 showmessage($message, 'none');
635 # FIXME: Perl 5.6 is BUGGY!!! IT SHOULD NOT BE USED in production!!!
636 unless (eval "require 5.006_000") {
637 die getmessage('PerlVersionFailure', ['5.6.0']);
641 unless (eval {require DBI}) { push @missing,"DBI" };
642 unless (eval {require Date::Manip}) { push @missing,"Date::Manip" };
643 unless (eval {require DBD::mysql}) { push @missing,"DBD::mysql" };
644 unless (eval {require HTML::Template}) { push @missing,"HTML::Template" };
645 unless (eval {require Set::Scalar}) { push @missing,"Set::Scalar" };
646 unless (eval {require Digest::MD5}) { push @missing,"Digest::MD5" };
647 unless (eval {require MARC::Record}) { push @missing,"MARC::Record" };
648 unless (eval {require Net::Z3950}) {
649 my $message = getmessage('NETZ3950Missing');
650 showmessage($message, 'PressEnter', '', 1);
652 push @missing, "Net::Z3950";
657 # Print out a list of any missing modules
662 foreach my $module (@missing) {
663 $missing.=" perl -MCPAN -e 'install \"$module\"'\n";
665 my $message=getmessage('MissingPerlModules', [$missing]);
666 showmessage($message, 'none');
669 showmessage(getmessage('AllPerlModulesInstalled'), 'PressEnter', '', 1);
673 unless (-x "/usr/bin/perl") {
674 my $realperl=`which perl`;
676 $realperl = showmessage(getmessage('NoUsrBinPerl'), 'none');
677 until (-x $realperl) {
678 $realperl=showmessage(getmessage('AskLocationOfPerlExecutable', $realperl), 'free', $realperl, 1);
680 my $response=showmessage(getmessage('ConfirmPerlExecutableSymlink', $realperl), 'yn', 'y', 1);
681 unless ($response eq 'n') {
682 system("ln -s $realperl /usr/bin/perl");
689 $messages->{'NoUsrBinPerl'}->{en} =
690 heading('Perl is not located in /usr/bin/perl') . qq|
691 The Koha perl scripts expect to find the perl executable in the /usr/bin
692 directory. It is not there on your system.
696 $messages->{'AskLocationOfPerlExecutable'}->{en}=qq|Location of Perl Executable: [%s]: |;
697 $messages->{'ConfirmPerlExecutableSymlink'}->{en}=qq|
698 The Koha scripts will _not_ work without a symlink from %s to /usr/bin/perl
700 May I create this symlink? ([Y]/N):
704 =item getinstallationdirectories
706 getinstallationdirectories;
708 Get the various installation directories from the user, and then
709 create those directories (if they do not already exist).
711 These pieces of information are saved to global variables; the
712 function does not return any values.
716 sub getinstallationdirectories {
717 $opacdir = '/usr/local/koha/opac';
718 $intranetdir = '/usr/local/koha/intranet';
720 while ($getdirinfo) {
721 # Loop until opac directory and koha directory are different
722 my $message=getmessage('GetOpacDir', [$opacdir]);
723 $opacdir=showmessage($message, 'free', $opacdir);
725 $message=getmessage('GetIntranetDir', [$intranetdir]);
726 $intranetdir=showmessage($message, 'free', $intranetdir);
728 if ($intranetdir eq $opacdir) {
731 You must specify different directories for the OPAC and INTRANET files!
732 :: $intranetdir :: $opacdir ::
739 $kohalogdir='/var/log/koha';
740 my $message=getmessage('GetKohaLogDir', [$kohalogdir]);
741 $kohalogdir=showmessage($message, 'free', $kohalogdir);
744 # FIXME: Missing error handling for all mkdir calls here
745 unless ( -d $intranetdir ) {
746 mkdir_parents (dirname($intranetdir), 0775);
747 mkdir ($intranetdir, 0770);
748 chown (oct(0), (getgrnam($httpduser))[2], "$intranetdir");
749 chmod (oct(770), "$intranetdir");
751 mkdir_parents ("$intranetdir/htdocs", 0750);
752 mkdir_parents ("$intranetdir/cgi-bin", 0750);
753 mkdir_parents ("$intranetdir/modules", 0750);
754 mkdir_parents ("$intranetdir/scripts", 0750);
755 unless ( -d $opacdir ) {
756 mkdir_parents (dirname($opacdir), 0775);
757 mkdir ($opacdir, 0770);
758 chown (oct(0), (getgrnam($httpduser))[2], "$opacdir");
759 chmod (oct(770), "$opacdir");
761 mkdir_parents ("$opacdir/htdocs", 0750);
762 mkdir_parents ("$opacdir/cgi-bin", 0750);
765 unless ( -d $kohalogdir ) {
766 mkdir_parents (dirname($kohalogdir), 0775);
767 mkdir ($kohalogdir, 0770);
768 chown (oct(0), (getgrnam($httpduser))[2,3], "$kohalogdir");
769 chmod (oct(770), "$kohalogdir");
775 =item getdatabaseinfo
779 Get various pieces of information related to the Koha database:
780 the name of the database, the host on which the SQL server is
781 running, and the database user name.
783 These pieces of information are saved to global variables; the
784 function does not return any values.
788 $messages->{'DatabaseName'}->{en} = heading('Name of MySQL database') . qq|
789 Please provide the name of the mysql database for your koha installation.
791 Database name [%s]: |;
793 $messages->{'DatabaseHost'}->{en} = heading('Database Host') . qq|
794 Please provide the hostname for mysql. Unless the database is located on
795 another machine this will be "localhost".
797 Database host [%s]: |;
799 $messages->{'DatabaseUser'}->{en} = heading('Database User') . qq|
800 Please provide the name of the user, who will have full administrative rights
801 to the %s database, when authenticating from %s.
803 This user will also be used to access Koha's INTRANET interface.
805 Database user [%s]: |;
807 $messages->{'DatabasePassword'}->{en} = heading('Database Password') . qq|
808 Please provide a good password for the user %s.
810 Database Password: |;
812 $messages->{'BlankPassword'}->{en} = heading('BLANK PASSWORD') . qq|
813 You must not use a blank password for your MySQL user!
815 Press <ENTER> to try again:
818 sub getdatabaseinfo {
821 $hostname = 'localhost';
825 #Get the database name
827 my $message=getmessage('DatabaseName', [$dbname]);
828 $dbname=showmessage($message, 'free', $dbname);
830 #Get the hostname for the database
832 $message=getmessage('DatabaseHost', [$hostname]);
833 $hostname=showmessage($message, 'free', $hostname);
835 #Get the username for the database
837 $message=getmessage('DatabaseUser', [$dbname, $hostname, $user]);
838 $user=showmessage($message, 'free', $user);
840 #Get the password for the database user
842 while ($pass eq '') {
843 my $message=getmessage('DatabasePassword', [$user]);
844 $pass=showmessage($message, 'free', $pass);
846 my $message=getmessage('BlankPassword');
847 showmessage($message,'PressEnter');
858 Get various pieces of information related to the Apache server:
859 the location of the configuration file and, if needed, the Unix
860 user that the Koha CGI will be run under.
862 These pieces of information are saved to global variables; the
863 function does not return any values.
867 $messages->{'FoundMultipleApacheConfFiles'}->{en} =
868 heading('MULTIPLE APACHE CONFIG FILES') . qq|
869 I found more than one possible Apache configuration file:
873 Choose the correct file [1]: |;
875 $messages->{'NoApacheConfFiles'}->{en} =
876 heading('NO APACHE CONFIG FILE FOUND') . qq|
877 I was not able to find your Apache configuration file.
879 The file is usually called httpd.conf or apache.conf.
881 Please specify the location of your config file: |;
883 $messages->{'NotAFile'}->{en} = heading('FILE DOES NOT EXIST') . qq|
884 The file %s does not exist.
886 Please press <ENTER> to continue: |;
888 $messages->{'EnterApacheUser'}->{en} = heading('NEED APACHE USER') . qq|
889 I was not able to determine the user that Apache is running as. This
890 information is necessary in order to set the access privileges correctly on
891 %s/koha.conf. This user should be set in one of the Apache configuration
892 files using the "User" directive.
894 Enter the Apache userid: |;
896 $messages->{'InvalidUserid'}->{en} = heading('INVALID USERID') . qq|
897 The userid %s is not a valid userid on this system.
899 Press <ENTER> to continue: |;
902 my @confpossibilities;
904 foreach my $httpdconf (qw(/usr/local/apache/conf/httpd.conf
905 /usr/local/etc/apache/httpd.conf
906 /usr/local/etc/apache/apache.conf
907 /var/www/conf/httpd.conf
908 /etc/apache/conf/httpd.conf
909 /etc/apache/conf/apache.conf
910 /etc/apache-ssl/conf/apache.conf
911 /etc/apache-ssl/httpd.conf
912 /etc/httpd/conf/httpd.conf
913 /etc/httpd/httpd.conf)) {
914 if ( -f $httpdconf ) {
915 push @confpossibilities, $httpdconf;
919 if ($#confpossibilities==-1) {
920 my $message=getmessage('NoApacheConfFiles');
922 until (-f $realhttpdconf) {
923 $choice=showmessage($message, "free", 1);
925 $realhttpdconf=$choice;
927 showmessage(getmessage('NotAFile', [$choice]),'PressEnter', '', 1);
930 } elsif ($#confpossibilities>0) {
934 foreach (@confpossibilities) {
935 $conffiles.=" $counter: $_\n";
936 $options.="$counter";
939 my $message=getmessage('FoundMultipleApacheConfFiles', [$conffiles]);
940 my $choice=showmessage($message, "restrictchar $options", 1);
941 $realhttpdconf=$confpossibilities[$choice-1];
943 $realhttpdconf=$confpossibilities[0];
945 unless (open (HTTPDCONF, "<$realhttpdconf")) {
946 warn "Insufficient privileges to open $realhttpdconf for reading.\n";
950 while (<HTTPDCONF>) {
951 if (/^\s*User\s+"?([-\w]+)"?\s*$/) {
960 unless ($httpduser) {
961 my $message=getmessage('EnterApacheUser', [$etcdir]);
962 until (length($httpduser) && getpwnam($httpduser)) {
963 $httpduser=showmessage($message, "free", '');
964 if (length($httpduser)>0) {
965 unless (getpwnam($httpduser)) {
966 my $message=getmessage('InvalidUserid', [$httpduser]);
967 showmessage($message,'PressEnter');
972 print "AU: $httpduser\n";
977 =item getapachevhostinfo
981 Gets various pieces of information related to virtual hosting:
982 the webmaster email address, virtual hostname, and the ports
983 that the OPAC and INTRANET modules run on.
985 These pieces of information are saved to global variables; the
986 function does not return any values.
990 $messages->{'ApacheConfigIntroduction'}->{en} =
991 heading('APACHE CONFIGURATION') . qq|
992 Koha needs to setup your Apache configuration file for the
993 OPAC and LIBRARIAN virtual hosts. By default this installer
994 will do this by using one ip address and two different ports
995 for the virtual hosts. There are other ways to set this up,
996 and the installer will leave comments in httpd.conf detailing
997 what these other options are.
1000 Press <ENTER> to continue: |;
1002 $messages->{'GetVirtualHostEmail'}->{en} =
1003 heading('WEB SERVER E-MAIL CONTACT') . qq|
1004 Enter the e-mail address to be used as a contact for the virtual hosts (this
1005 address is displayed if any errors are encountered).
1007 E-mail contact [%s]: |;
1009 $messages->{'GetServerName'}->{en} =
1010 heading('WEB SERVER HOST NAME OR IP ADDRESS') . qq|
1011 Please enter the domain name or ip address of your computer.
1013 Host name or IP Address [%s]: |;
1015 $messages->{'GetOpacPort'}->{en} = heading('OPAC VIRTUAL HOST PORT') . qq|
1016 Please enter the port for your OPAC interface. This defaults to port 80, but
1017 if you are already serving web content from this server, you should change it
1018 to a different port (8000 might be a good choice).
1020 Enter the OPAC Port [%s]: |;
1022 $messages->{'GetIntranetPort'}->{en} =
1023 heading('INTRANET VIRTUAL HOST PORT') . qq|
1024 Please enter the port for your Intranet interface. This must be different from
1027 Enter the Intranet Port [%s]: |;
1030 sub getapachevhostinfo {
1032 $svr_admin = "webmaster\@$domainname";
1033 $servername=`hostname`;
1038 showmessage(getmessage('ApacheConfigIntroduction'), 'PressEnter');
1040 $svr_admin=showmessage(getmessage('GetVirtualHostEmail', [$svr_admin]), 'email', $svr_admin);
1041 $servername=showmessage(getmessage('GetServerName', [$servername]), 'free', $servername);
1044 $opacport=showmessage(getmessage('GetOpacPort', [$opacport]), 'numerical', $opacport);
1045 $intranetport=showmessage(getmessage('GetIntranetPort', [$opacport, $intranetport]), 'numerical', $intranetport);
1049 $messages->{'StartUpdateApache'}->{en} =
1050 heading('UPDATING APACHE CONFIGURATION') . qq|
1051 Checking for modules that need to be loaded...
1054 $messages->{'LoadingApacheModuleModEnv'}->{en}="Loading SetEnv Apache module.\n";
1056 $messages->{'LoadingApacheModuleModInc'}->{en}="Loading Includes Apache module.\n";
1058 $messages->{'ApacheConfigBackupFailed'}->{en} =
1059 heading('APACHE CONFIGURATION BACKUP FAILED') . qq|
1060 An error occurred while trying to make a backup copy of %s.
1064 No changes will be made to the apache configuration file at this time.
1066 Press <ENTER> to continue: |;
1069 $messages->{'ApacheAlreadyConfigured'}->{en} =
1070 heading('APACHE ALREADY CONFIGURED') . qq|
1071 %s appears to already have an entry for Koha
1072 Virtual Hosts. You may need to edit %s
1073 f anything has changed since it was last set up. This
1074 script will not attempt to modify an existing Koha apache
1077 Press <ENTER> to continue: |;
1079 sub updateapacheconf {
1080 my $logfiledir=`grep ^ErrorLog "$realhttpdconf"`;
1084 $logfiledir=~m#ErrorLog (.*)/[^/]*$#
1085 or die "Can't parse ErrorLog directive\n";
1089 unless ($logfiledir) {
1093 showmessage(getmessage('StartUpdateApache'), 'none');
1097 my $includesmodule=0;
1098 open HC, "<$realhttpdconf";
1100 if (/^\s*#\s*LoadModule env_module /) {
1102 showmessage(getmessage('LoadingApacheModuleModEnv'));
1105 if (/^\s*#\s*LoadModule includes_module /) {
1107 showmessage(getmessage('LoadingApacheModuleModInc'));
1109 if (/\s*LoadModule includes_module / ) {
1116 $backupfailed=`cp -f $realhttpdconf $realhttpdconf\.prekoha`;
1117 if ($backupfailed) {
1118 showmessage(getmessage('ApacheConfigBackupFailed', [$realhttpdconf,$backupfailed ]), 'PressEnter');
1122 if ($envmodule || $includesmodule) {
1123 open HC, ">$realhttpdconf";
1124 print HC $httpdconf;
1130 if (`grep 'VirtualHost $servername' "$realhttpdconf"`) {
1131 showmessage(getmessage('ApacheAlreadyConfigured', [$realhttpdconf, $realhttpdconf]), 'PressEnter');
1134 my $includesdirectives='';
1135 if ($includesmodule) {
1136 $includesdirectives.="Options +Includes\n";
1137 $includesdirectives.=" AddHandler server-parsed .html\n";
1139 open(SITE,">>$realhttpdconf") or warn "Insufficient priveleges to open $realhttpdconf for writing.\n";
1140 my $opaclisten = '';
1141 if ($opacport != 80) {
1142 $opaclisten="Listen $opacport";
1144 my $intranetlisten = '';
1145 if ($intranetport != 80) {
1146 $intranetlisten="Listen $intranetport";
1150 # Ports to listen to for Koha
1154 # NameVirtualHost is used by one of the optional configurations detailed below
1156 #NameVirtualHost 11.22.33.44
1158 # KOHA's OPAC Configuration
1159 <VirtualHost $servername\:$opacport>
1160 ServerAdmin $svr_admin
1161 DocumentRoot $opacdir/htdocs
1162 ServerName $servername
1163 ScriptAlias /cgi-bin/koha/ $opacdir/cgi-bin/
1164 ErrorLog $logfiledir/opac-error_log
1165 TransferLog $logfiledir/opac-access_log
1166 SetEnv PERL5LIB "$intranetdir/modules"
1170 # KOHA's INTRANET Configuration
1171 <VirtualHost $servername\:$intranetport>
1172 ServerAdmin $svr_admin
1173 DocumentRoot $intranetdir/htdocs
1174 ServerName $servername
1175 ScriptAlias /cgi-bin/koha/ "$intranetdir/cgi-bin/"
1176 ErrorLog $logfiledir/koha-error_log
1177 TransferLog $logfiledir/koha-access_log
1178 SetEnv PERL5LIB "$intranetdir/modules"
1182 # If you want to use name based Virtual Hosting:
1183 # 1. remove the two Listen lines
1184 # 2. replace $servername\:$opacport wih your.opac.domain.name
1185 # 3. replace ServerName $servername wih ServerName your.opac.domain.name
1186 # 4. replace $servername\:$intranetport wih your intranet domain name
1187 # 5. replace ServerName $servername wih ServerName your.intranet.domain.name
1189 # If you want to use NameVirtualHost'ing (using two names on one ip address):
1190 # 1. Follow steps 1-5 above
1191 # 2. Uncomment the NameVirtualHost line and set the correct ip address
1199 $messages->{'IntranetAuthenticationQuestion'}->{en} =
1200 heading('INTRANET AUTHENTICATION') . qq|
1201 I can set it up so that the Intranet/Librarian site is password protected using
1202 Apache's Basic Authorization.
1204 This is going to be phased out very soon. However, setting this up can provide
1205 an extra layer of security before the new authentication system is completely
1208 Would you like to do this ([Y]/N): |;
1210 $messages->{'BasicAuthUsername'}->{en}="Please enter a userid for intranet access [%s]: ";
1211 $messages->{'BasicAuthPassword'}->{en}="Please enter a password for %s: ";
1212 $messages->{'BasicAuthPasswordWasBlank'}->{en}="\nYou cannot use a blank password!\n\n";
1214 sub basicauthentication {
1215 my $message=getmessage('IntranetAuthenticationQuestion');
1216 my $answer=showmessage($message, 'yn', 'y');
1218 my $apacheauthusername='librarian';
1219 my $apacheauthpassword='';
1220 if ($answer=~/^y/i) {
1221 ($apacheauthusername) = showmessage(getmessage('BasicAuthUsername', [ $apacheauthusername]), 'free', $apacheauthusername, 1);
1222 $apacheauthusername=~s/[^a-zA-Z0-9]//g;
1223 while (! $apacheauthpassword) {
1224 ($apacheauthpassword) = showmessage(getmessage('BasicAuthPassword', [ $apacheauthusername]), 'free', 1);
1225 if (!$apacheauthpassword) {
1226 ($apacheauthpassword) = showmessage(getmessage('BasicAuthPasswordWasBlank'), 'none', '', 1);
1229 open AUTH, ">$etcdir/kohaintranet.pass";
1230 my $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
1231 my $salt=substr($chars, int(rand(length($chars))),1);
1232 $salt.=substr($chars, int(rand(length($chars))),1);
1233 print AUTH $apacheauthusername.":".crypt($apacheauthpassword, $salt)."\n";
1235 open(SITE,">>$realhttpdconf") or warn "Insufficient priveleges to open $realhttpdconf for writing.\n";
1238 <Directory $intranetdir>
1239 AuthUserFile $etcdir/kohaintranet.pass
1241 AuthName "Koha Intranet (for librarians only)"
1249 $messages->{'InstallFiles'}->{en} = heading('INSTALLING FILES') . qq|
1250 Copying files to installation directories:
1255 $messages->{'CopyingFiles'}->{en}="Copying %s to %s.\n";
1262 showmessage(getmessage('InstallFiles'),'none');
1263 print getmessage('CopyingFiles', ['intranet-html', "$intranetdir/htdocs" ]);
1264 system("cp -R intranet-html/* $intranetdir/htdocs/");
1265 print getmessage('CopyingFiles', ['intranet-cgi', "$intranetdir/cgi-bin" ]);
1266 system("cp -R intranet-cgi/* $intranetdir/cgi-bin/");
1267 print getmessage('CopyingFiles', ['stand-alone scripts', "$intranetdir/scripts" ]);
1268 system("cp -R scripts/* $intranetdir/scripts/");
1269 print getmessage('CopyingFiles', ['perl modules', "$intranetdir/modules" ]);
1270 system("cp -R modules/* $intranetdir/modules/");
1271 print getmessage('CopyingFiles', ['opac-html', "$opacdir/htdocs" ]);
1272 system("cp -R opac-html/* $opacdir/htdocs/");
1273 print getmessage('CopyingFiles', ['opac-cgi', "$opacdir/cgi-bin" ]);
1274 system("cp -R opac-cgi/* $opacdir/cgi-bin/");
1275 system("touch $opacdir/cgi-bin/opac");
1277 system("chown -R root:$httpduser $opacdir");
1278 system("chown -R root:$httpduser $intranetdir");
1280 # Create /etc/koha.conf
1282 my $old_umask = umask(027); # make sure koha.conf is never world-readable
1283 open(SITES,">$etcdir/koha.conf.tmp") or warn "Couldn't create file at $etcdir. Must have write capability.\n";
1289 includes=$opacdir/htdocs/includes
1290 intranetdir=$intranetdir
1292 kohalogdir=$kohalogdir
1293 kohaversion=$kohaversion
1294 httpduser=$httpduser
1295 intrahtdocs=$intranetdir/htdocs/intranet-tmpl
1296 opachtdocs=$opacdir/htdocs/opac-tmpl
1301 chown((getpwnam($httpduser)) [2,3], "$etcdir/koha.conf.tmp") or warn "can't chown koha.conf: $!";
1302 chmod 0440, "$etcdir/koha.conf.tmp";
1304 chmod 0750, "$intranetdir/scripts/z3950daemon/z3950-daemon-launch.sh";
1305 chmod 0750, "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh";
1306 chmod 0750, "$intranetdir/scripts/z3950daemon/processz3950queue";
1307 chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh") or warn "can't chown $intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh: $!";
1308 chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/processz3950queue") or warn "can't chown $intranetdir/scripts/z3950daemon/processz3950queue: $!";
1312 $messages->{'MysqlRootPassword'}->{en} =
1313 heading('MYSQL ROOT USER PASSWORD') . qq|
1314 To allow us to create the koha database please supply your
1315 mysql server's root user password:
1317 Enter MySQL root user password: |;
1319 $messages->{'InvalidMysqlRootPassword'}->{en}="Invalid Password. Please try again.";
1321 $messages->{'CreatingDatabase'}->{en} = heading('CREATING DATABASE') . qq|
1322 Creating the MySQL database for Koha...
1326 $messages->{'CreatingDatabaseError'}->{en} =
1327 heading('ERROR CREATING DATABASE') . qq|
1328 Couldn't connect to the MySQL server for the reason given above.
1329 This is a serious problem, the database will not get installed.
\a
1331 Press <ENTER> to continue: |;
1333 $messages->{'SampleData'}->{en} = heading('SAMPLE DATA') . qq|
1334 If you are installing Koha for evaluation purposes, I have a batch of sample
1335 data that you can install now.
1337 If you are installing Koha with the intention of populating it with your own
1338 data, you probably don't want this sample data installed.
1340 Would you like to install the sample data? Y/[N]: |;
1342 $messages->{'SampleDataInstalled'}->{en} =
1343 heading('SAMPLE DATA INSTALLED') . qq|
1344 Sample data has been installed. For some suggestions on testing Koha, please
1345 read the file doc/HOWTO-Testing. If you find any bugs, please submit them at
1346 http://bugs.koha.org/. If you need help with testing Koha, you can post a
1347 question through the koha-devel mailing list, or you can check for a developer
1348 online at +irc.katipo.co.nz:6667 channel #koha.
1350 You can find instructions for subscribing to the Koha mailing lists at:
1355 Press <ENTER> to continue: |;
1357 $messages->{'AddBranchPrinter'}->{en} = heading('Add Branch and Printer') . qq|
1358 Would you like to install an initial branch and printer? [Y]/N: |;
1360 $messages->{'BranchName'}->{en}="Branch Name [%s]: ";
1361 $messages->{'BranchCode'}->{en}="Branch Code (4 letters or numbers) [%s]: ";
1362 $messages->{'PrinterQueue'}->{en}="Printer Queue [%s]: ";
1363 $messages->{'PrinterName'}->{en}="Printer Name [%s]: ";
1364 $messages->{'BlankMysqlPassword'}->{en} = heading('Blank MySQL Password') . qq|
1365 Do not leave your MySQL root password blank unless you know exactly what you
1366 are doing. To change your MySQL root password use the mysqladmin command:
1368 mysqladmin password NEWPASSWORDHERE
1370 Press <ENTER> to continue:
1374 $mysqluser = 'root';
1377 foreach my $mysql (qw(/usr/local/mysql
1381 if ( -d $mysql && -f "$mysql/bin/mysqladmin") {
1386 print "I don't see mysql in the usual places.\n";
1388 print "Where have you installed mysql? ";
1389 chomp($mysqldir = <STDIN>);
1390 last if -f "$mysqldir/bin/mysqladmin";
1393 I can't find it there either. If you compiled mysql yourself,
1394 please give the value of --prefix when you ran configure.
1396 The file mysqladmin should be in bin/mysqladmin under the directory that you
1405 while ($needpassword) {
1406 $mysqlpass=showmessage(getmessage('MysqlRootPassword'), 'free');
1407 $mysqlpass_quoted = $mysqlpass;
1408 $mysqlpass_quoted =~ s/"/\\"/g;
1409 $mysqlpass_quoted="-p\"$mysqlpass_quoted\"";
1410 $mysqlpass eq '' and $mysqlpass_quoted='';
1411 my $result=system("$mysqldir/bin/mysqladmin -u$mysqluser $mysqlpass_quoted proc > /dev/null 2>&1");
1413 print getmessage('InvalidMysqlRootPassword');
1415 if ($mysqlpass eq '') {
1416 showmessage(getmessage('BlankMysqlPassword'), 'PressEnter');
1422 showmessage(getmessage('CreatingDatabase'),'none');
1424 my $result=system("$mysqldir/bin/mysqladmin", "-u$mysqluser", "-p$mysqlpass", "create", "$dbname");
1426 showmessage(getmessage('CreatingDatabaseError'),'PressEnter', '', 1);
1428 # Populate the Koha database
1429 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname < koha.mysql");
1430 # Set up permissions
1431 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted mysql -e \"insert into user (Host,User,Password) values ('$hostname','$user',password('$pass'))\"\;");
1432 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted 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 ('%','$dbname','$user','Y','Y','Y','Y','Y','Y','Y','Y')\"");
1433 system("$mysqldir/bin/mysqladmin -u$mysqluser $mysqlpass_quoted reload");
1443 $messages->{'UpdateMarcTables'}->{en} =
1444 heading('UPDATING MARC FIELD DEFINITION TABLES') . qq|
1445 You can import marc parameters for :
1451 Please choose which parameter you want to install. Note if you choose 3,
1452 nothing will be added, and it can be a BIG job to manually create those tables
1454 Choose MARC definition [1]: |;
1456 $messages->{'Language'}->{en} = heading('CHOOSE LANGUAGES') . qq|
1457 This version of koha supports a few languages.
1458 Enter you languages preferences : either en, fr, es or pl.
1459 Note that the en is always choosen when the system does not finds the
1460 language you choose in a specific screen.
1461 fr : opac is translated (except pictures)
1462 es : a few intranet is translated (including pictures)
1463 pl : opac is translated (UNTESTED in this release)
1466 sub updatedatabase {
1467 # At this point, $etcdir/koha.conf must exist, for C4::Context
1468 # We must somehow temporarily enable $etcdir/koha.conf. A symlink can
1469 # do this & at the same time facilitate detection of aborted installs.
1470 my $result=system ("perl -I $intranetdir/modules scripts/updater/updatedatabase");
1472 print "Problem updating database...\n";
1476 my $response=showmessage(getmessage('UpdateMarcTables'), 'restrictchar 123', '1');
1478 if ($response == 1) {
1479 system("cat scripts/misc/marc_datas/marc21_en/structure_def.sql | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname");
1481 if ($response == 2) {
1482 system("cat scripts/misc/marc_datas/unimarc_fr/structure_def.sql | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname");
1483 system("cat scripts/misc/lang-datas/fr/stopwords.sql | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname");
1486 $result = system ("perl -I $intranetdir/modules scripts/marc/updatedb2marc.pl");
1488 print "Problem updating database to MARC...\n";
1492 print "\n\nFinished updating of database. Press <ENTER> to continue...";
1496 sub populatedatabase {
1497 my $response=showmessage(getmessage('SampleData'), 'yn', 'n');
1498 if ($response =~/^y/i) {
1499 system("gunzip -d < sampledata-1.2.gz | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname");
1500 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branches (branchcode,branchname,issuing) values ('MAIN', 'Main Library', 1)\"");
1501 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1502 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1503 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into printers (printername,printqueue,printtype) values ('Circulation Desk Printer', 'lp', 'hp')\"");
1504 showmessage(getmessage('SampleDataInstalled'), 'PressEnter','',1);
1507 my $response=showmessage(getmessage('AddBranchPrinter'), 'yn', 'y');
1509 unless ($response =~/^n/i) {
1510 my $branch='Main Library';
1511 $branch=showmessage(getmessage('BranchName', [$branch]), 'free', $branch, 1);
1512 $branch=~s/[^A-Za-z0-9\s]//g;
1514 my $branchcode=$branch;
1515 $branchcode=~s/[^A-Za-z0-9]//g;
1516 $branchcode=uc($branchcode);
1517 $branchcode=substr($branchcode,0,4);
1518 $branchcode=showmessage(getmessage('BranchCode', [$branchcode]), 'free', $branchcode, 1);
1519 $branchcode=~s/[^A-Za-z0-9]//g;
1520 $branchcode=uc($branchcode);
1521 $branchcode=substr($branchcode,0,4);
1522 $branchcode or $branchcode='DEF';
1524 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branches (branchcode,branchname,issuing) values ('$branchcode', '$branch', 1)\"");
1525 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1526 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1528 my $printername='Library Printer';
1529 $printername=showmessage(getmessage('PrinterName', [$printername]), 'free', $printername, 1);
1530 $printername=~s/[^A-Za-z0-9\s]//g;
1532 my $printerqueue='lp';
1533 $printerqueue=showmessage(getmessage('PrinterQueue', [$printerqueue]), 'free', $printerqueue, 1);
1534 $printerqueue=~s/[^A-Za-z0-9]//g;
1535 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into printers (printername,printqueue,printtype) values ('$printername', '$printerqueue', '')\"");
1537 my $language=showmessage(getmessage('Language'), 'free', 'en');
1538 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"update systempreferences set value='$language' where variable='opaclanguages'\"");
1542 $messages->{'RestartApache'}->{en} = heading('RESTART APACHE') . qq|
1543 Apache needs to be restarted to load the new configuration for Koha.
1545 Would you like to restart Apache now? [Y]/N: |;
1549 my $response=showmessage(getmessage('RestartApache'), 'yn', 'y');
1553 unless ($response=~/^n/i) {
1554 # Need to support other init structures here?
1555 if (-e "/etc/rc.d/init.d/httpd") {
1556 system('/etc/rc.d/init.d/httpd restart');
1557 } elsif (-e "/etc/init.d/apache") {
1558 system('/etc//init.d/apache restart');
1559 } elsif (-e "/etc/init.d/apache-ssl") {
1560 system('/etc/init.d/apache-ssl restart');
1567 sub loadconfigfile {
1570 open (KC, "<$etcdir/koha.conf");
1573 (next) if (/^\s*#/);
1574 if (/(.*)\s*=\s*(.*)/) {
1577 # Clean up white space at beginning and end
1578 $variable=~s/^\s*//g;
1579 $variable=~s/\s*$//g;
1582 $configfile{$variable}=$value;
1586 $intranetdir=$configfile{'intranetdir'};
1587 $opacdir=$configfile{'opacdir'};
1588 $kohaversion=$configfile{'kohaversion'};
1589 $kohalogdir=$configfile{'kohalogdir'};
1590 $database=$configfile{'database'};
1591 $hostname=$configfile{'hostname'};
1592 $user=$configfile{'user'};
1593 $pass=$configfile{'pass'};
1596 END { } # module clean-up code here (global destructor)