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
70 $messages->{'WelcomeToKohaInstaller'
71 = heading('Welcome to the Koha Installer') . qq|...|;
73 The heading function takes one string, the text to be displayed as
74 the heading, and returns a formatted heading (currently formatted
75 in the "traditional Koha installer" style, i.e., surrounded by a
78 This reduces the likelihood of pod2man(1) etc. misinterpreting
79 a line of equal signs as POD directives.
85 my $n = length($s) + 4;
86 my $line = ('=' x $n) . "\n";
87 "\n$line= $s =\n$line\n";
91 $messages->{'continuing'}->{en}="Great! Continuing setup.\n\n";
92 $messages->{'WelcomeToKohaInstaller'}->{en} =
93 heading('Welcome to the Koha Installer') . qq|
94 Welcome to the Koha install script! This script will prompt you for some
95 basic information about your desired setup, then install Koha according to
96 your specifications. To accept the default value for any question, simply hit
99 Please be sure to read the documentation, or visit the Koha website at
100 http://www.koha.org for more information.
102 Are you ready to begin the installation? (Y/[N]): |;
103 $messages->{'ReleaseCandidateWarning'}->{en} =
104 heading('RELEASE CANDIDATE') . qq|
105 WARNING WARNING WARNING WARNING WARNING
107 You are about to install Koha version %s. This version of Koha is a
108 release candidate. It is not intended to be installed on production systems.
109 It is being released so that users can test it before we release a final
112 Are you sure you want to install Koha %s? (Y/[N]): |;
113 $messages->{'WatchForReleaseAnnouncements'}->{en}=qq|
115 Watch for announcements of Koha releases on the Koha mailing list or the Koha
116 web site (http://www.koha.org/).
120 $messages->{'NETZ3950Missing'}->{en}=qq|
122 The Net::Z3950 module is missing. This module is necessary if you want to use
123 Koha's Z39.50 client to download bibliographic records from other libraries.
124 To install this module, you will need the yaz client installed from
125 http://www.indexdata.dk/yaz/ and then you can install the perl module with the
128 perl -MCPAN -e 'install Net::Z3950'
130 Press the <ENTER> key to continue: |;
132 $messages->{'CheckingPerlModules'}->{en} = heading('PERL & MODULES') . qq|
133 Checking perl modules ...
136 $messages->{'PerlVersionFailure'}->{en}="Sorry, you need at least Perl %s\n";
138 $messages->{'MissingPerlModules'}->{en} = heading('MISSING PERL MODULES') . qq|
139 You are missing some Perl modules which are required by Koha.
140 Once these modules have been installed, rerun this installer.
141 They can be installed by running (as root) the following:
146 $messages->{'AllPerlModulesInstalled'}->{en} =
147 heading('ALL PERL MODULES INSTALLED') . qq|
148 All mandatory perl modules are installed.
150 Press <ENTER> to continue: |;
151 $messages->{'KohaVersionInstalled'}->{en}="You currently have Koha %s on your system.";
152 $messages->{'KohaUnknownVersionInstalled'}->{en}="I am not able to determine what version of Koha is installed now.";
153 $messages->{'KohaAlreadyInstalled'}->{en} =
154 heading('Koha already installed') . qq|
155 It looks like Koha is already installed on your system (%s/koha.conf exists
156 already). If you would like to upgrade your system to %s, please use
157 the koha.upgrade script in this directory.
162 $messages->{'GetOpacDir'}->{en} = heading('OPAC DIRECTORY') . qq|
163 Please supply the directory you want Koha to store its OPAC files in. This
164 directory will be auto-created for you if it doesn't exist.
166 OPAC Directory [%s]: |;
168 $messages->{'GetIntranetDir'}->{en} =
169 heading('INTRANET/LIBRARIANS DIRECTORY') . qq|
170 Please supply the directory you want Koha to store its Intranet/Librarians
171 files in. This directory will be auto-created for you if it doesn't exist.
173 Intranet Directory [%s]: |;
175 $messages->{'GetKohaLogDir'}->{en} = heading('KOHA LOG DIRECTORY') . qq|
176 Specify a log directory where any Koha daemons can create log files.
178 Koha Log Directory [%s]: |;
180 $messages->{'AuthenticationWarning'}->{en} = heading('Authentication') . qq|
181 This release of Koha has a new authentication module. If you are not already
182 using basic authentication on your intranet, you will be required to log in to
183 access some of the features of the intranet. You can log in using the userid
184 and password from the %s/koha.conf configuration file at any time. Use the
185 "Members" module to add passwords for other accounts and set their permissions.
187 Press the <ENTER> key to continue: |;
189 $messages->{'Completed'}->{en} = heading('KOHA INSTALLATION COMPLETE') . qq|
190 Congratulations ... your Koha installation is complete!
192 You will be able to connect to your Librarian interface at:
196 and the OPAC interface at :
200 Be sure to read the INSTALL, and Hints files.
202 For more information visit http://www.koha.org
204 Press <ENTER> to exit the installer: |;
206 sub releasecandidatewarning {
207 my $message=getmessage('ReleaseCandidateWarning', [$::newversion, $::newversion]);
208 my $answer=showmessage($message, 'yn', 'n');
210 if ($answer =~ /y/i) {
211 print getmessage('continuing');
213 my $message=getmessage('WatchForReleaseAnnouncements');
222 =head2 Miscellaneous utility functions
232 Does the equivalent of dirname(1). Given a path $path, return the
233 parent directory of $path (best guess), except when $path seems to
234 be the same as /, in which case $path itself is returned unchanged.
240 if ($path =~ /[^\/]/s) {
242 $path =~ s/\/+[^\/]+\/*$//s;
253 mkdir_parents $path, $mode;
255 Does the equivalent of mkdir -p. Given a path $path, create the path
256 $path, recursively creating any intermediate directories. If $mode
257 is given, the directory will be created with mode $mode.
259 WARNING: If $path already exists, mkdir_parents will just return
260 successfully (just like mkdir -p), whether the mode of $path conforms
265 sub mkdir_parents ($;$) {
266 my($path, $mode) = @_;
267 my $ok = -d($path)? 1: defined $mode? mkdir($path, $mode): mkdir($path);
269 if (!$ok && $! == ENOENT) {
270 my $parent = dirname($path);
271 $ok = mkdir_parents($parent, $mode);
273 # retry and at the same time make sure that $! is set correctly
274 $ok = defined $mode? mkdir($path, $mode): mkdir($path);
281 =head2 Subtasks of doing an installation
287 =item checkabortedinstall
291 Assuming that Koha will be installed on a modern Unix with symlinks,
292 it is possible to code the installer so that aborted installs can be
293 detected. In case of such an event we can do our best to "roll back"
296 FIXME: The "roll back" is not complete!
300 sub checkabortedinstall () {
301 if (-l("$::etcdir/koha.conf")
302 && readlink("$::etcdir/koha.conf") =~ /\.tmp$/
305 I have detected that you tried to install Koha before, but the installation
306 was aborted. I will try to continue, but there might be problems if the
307 database is already created.
310 print "Please press <ENTER> to continue: ";
313 # Remove the symlink after the <STDIN>, so the user can back out
314 unlink "$::etcdir/koha.conf"
315 || die "Failed to remove incomplete $::etcdir/koha.conf: $!\n";
320 # Test for Perl and Modules
323 sub checkperlmodules {
324 my $message = getmessage('CheckingPerlModules');
325 showmessage($message, 'none');
327 unless (eval "require 5.006_000") {
328 die getmessage('PerlVersionFailure', ['5.6.0']);
332 unless (eval {require DBI}) { push @missing,"DBI" };
333 unless (eval {require Date::Manip}) { push @missing,"Date::Manip" };
334 unless (eval {require DBD::mysql}) { push @missing,"DBD::mysql" };
335 unless (eval {require HTML::Template}) { push @missing,"HTML::Template" };
336 unless (eval {require Set::Scalar}) { push @missing,"Set::Scalar" };
337 unless (eval {require Digest::MD5}) { push @missing,"Digest::MD5" };
338 unless (eval {require MARC::Record}) { push @missing,"MARC::Record" };
339 unless (eval {require Net::Z3950}) {
340 my $message = getmessage('NETZ3950Missing');
341 showmessage($message, 'PressEnter', '', 1);
343 push @missing, "Net::Z3950";
348 # Print out a list of any missing modules
353 foreach my $module (@missing) {
354 $missing.=" perl -MCPAN -e 'install \"$module\"'\n";
356 my $message=getmessage('MissingPerlModules', [$missing]);
357 showmessage($message, 'none');
360 showmessage(getmessage('AllPerlModulesInstalled'), 'PressEnter', '', 1);
364 unless (-x "/usr/bin/perl") {
365 my $realperl=`which perl`;
367 $realperl = showmessage(getmessage('NoUsrBinPerl'), 'none');
368 until (-x $realperl) {
369 $realperl=showmessage(getmessage('AskLocationOfPerlExecutable', $realperl), 'free', $realperl, 1);
371 my $response=showmessage(getmessage('ConfirmPerlExecutableSymlink', $realperl), 'yn', 'y', 1);
372 unless ($response eq 'n') {
373 system("ln -s $realperl /usr/bin/perl");
380 $messages->{'NoUsrBinPerl'}->{en} =
381 heading('Perl is not located in /usr/bin/perl') . qq|
382 The Koha perl scripts expect to find the perl executable in the /usr/bin
383 directory. It is not there on your system.
387 $messages->{'AskLocationOfPerlExecutable'}->{en}=qq|Location of Perl Executable: [%s]: |;
388 $messages->{'ConfirmPerlExecutableSymlink'}->{en}=qq|
389 The Koha scripts will _not_ work without a symlink from %s to /usr/bin/perl
391 May I create this symlink? ([Y]/N):
395 my $messagename=shift;
397 my $message=$messages->{$messagename}->{$::language} || $messages->{$messagename}->{en} || "Error: No message named $messagename in Install.pm\n";
398 if (defined($variables)) {
399 $message=sprintf $message, @$variables;
407 my $responsetype=shift;
408 my $defaultresponse=shift;
410 ($noclear) || (system('clear'));
411 if ($responsetype =~ /^yn$/) {
412 $responsetype='restrictchar yn';
416 if ($responsetype =~/^restrictchar (.*)/i) {
419 until ($options=~/$response/) {
420 ($defaultresponse) || ($defaultresponse=substr($options,0,1));
423 (length($response)) || ($response=$defaultresponse);
424 unless ($options=~/$response/) {
425 ($noclear) || (system('clear'));
426 print "Invalid Response. Choose from [$options].\n\n";
432 if ($responsetype =~/^free$/i) {
433 (defined($defaultresponse)) || ($defaultresponse='');
434 my $response=<STDIN>;
436 ($response) || ($response=$defaultresponse);
439 if ($responsetype =~/^numerical$/i) {
440 (defined($defaultresponse)) || ($defaultresponse='');
442 until ($response=~/^\d+$/) {
445 ($response) || ($response=$defaultresponse);
446 unless ($response=~/^\d+$/) {
447 ($noclear) || (system('clear'));
448 print "Invalid Response ($response). Response must be a number.\n\n";
454 if ($responsetype =~/^email$/i) {
455 (defined($defaultresponse)) || ($defaultresponse='');
457 until ($response=~/.*\@.*\..*/) {
460 ($response) || ($response=$defaultresponse);
461 unless ($response=~/.*\@.*\..*/) {
462 ($noclear) || (system('clear'));
463 print "Invalid Response ($response). Response must be a valid email address.\n\n";
469 if ($responsetype =~/^PressEnter$/i) {
473 if ($responsetype =~/^none$/i) {
479 sub getinstallationdirectories {
480 $::opacdir = '/usr/local/koha/opac';
481 $::intranetdir = '/usr/local/koha/intranet';
483 while ($getdirinfo) {
484 # Loop until opac directory and koha directory are different
485 my $message=getmessage('GetOpacDir', [$::opacdir]);
486 $::opacdir=showmessage($message, 'free', $::opacdir);
488 $message=getmessage('GetIntranetDir', [$::intranetdir]);
489 $::intranetdir=showmessage($message, 'free', $::intranetdir);
491 if ($::intranetdir eq $::opacdir) {
494 You must specify different directories for the OPAC and INTRANET files!
495 :: $::intranetdir :: $::opacdir ::
502 $::kohalogdir='/var/log/koha';
503 my $message=getmessage('GetKohaLogDir', [$::kohalogdir]);
504 $::kohalogdir=showmessage($message, 'free', $::kohalogdir);
507 # FIXME: Missing error handling for all mkdir calls here
508 unless ( -d $::intranetdir ) {
509 mkdir_parents (dirname($::intranetdir), 0775);
510 mkdir ($::intranetdir, 0770);
511 chown (oct(0), (getgrnam($::httpduser))[2], "$::intranetdir");
512 chmod (oct(770), "$::intranetdir");
514 mkdir_parents ("$::intranetdir/htdocs", 0750);
515 mkdir_parents ("$::intranetdir/cgi-bin", 0750);
516 mkdir_parents ("$::intranetdir/modules", 0750);
517 mkdir_parents ("$::intranetdir/scripts", 0750);
518 unless ( -d $::opacdir ) {
519 mkdir_parents (dirname($::opacdir), 0775);
520 mkdir ($::opacdir, 0770);
521 chown (oct(0), (getgrnam($::httpduser))[2], "$::opacdir");
522 chmod (oct(770), "$::opacdir");
524 mkdir_parents ("$::opacdir/htdocs", 0750);
525 mkdir_parents ("$::opacdir/cgi-bin", 0750);
528 unless ( -d $::kohalogdir ) {
529 mkdir_parents (dirname($::kohalogdir), 0775);
530 mkdir ($::kohalogdir, 0770);
531 chown (oct(0), (getgrnam($::httpduser))[2,3], "$::kohalogdir");
532 chmod (oct(770), "$::kohalogdir");
538 $messages->{'DatabaseName'}->{en} = heading('Name of MySQL database') . qq|
539 Please provide the name of the mysql database for your koha installation.
541 Database name [%s]: |;
543 $messages->{'DatabaseHost'}->{en} = heading('Database Host') . qq|
544 Please provide the hostname for mysql. Unless the database is located on
545 another machine this will be "localhost".
547 Database host [%s]: |;
549 $messages->{'DatabaseUser'}->{en} = heading('Database User') . qq|
550 Please provide the name of the user, who will have full administrative rights
551 to the %s database, when authenticating from %s.
553 This user will also be used to access Koha's INTRANET interface.
555 Database user [%s]: |;
557 $messages->{'DatabasePassword'}->{en} = heading('Database Password') . qq|
558 Please provide a good password for the user %s.
560 Database Password: |;
562 $messages->{'BlankPassword'}->{en} = heading('BLANK PASSWORD') . qq|
563 You must not use a blank password for your MySQL user!
565 Press <ENTER> to try again:
568 sub getdatabaseinfo {
571 $::hostname = 'localhost';
572 $::user = 'kohaadmin';
575 #Get the database name
577 my $message=getmessage('DatabaseName', [$::dbname]);
578 $::dbname=showmessage($message, 'free', $::dbname);
580 #Get the hostname for the database
582 $message=getmessage('DatabaseHost', [$::hostname]);
583 $::hostname=showmessage($message, 'free', $::hostname);
585 #Get the username for the database
587 $message=getmessage('DatabaseUser', [$::dbname, $::hostname, $::user]);
588 $::user=showmessage($message, 'free', $::user);
590 #Get the password for the database user
592 while ($::pass eq '') {
593 my $message=getmessage('DatabasePassword', [$::user]);
594 $::pass=showmessage($message, 'free', $::pass);
596 my $message=getmessage('BlankPassword');
597 showmessage($message,'PressEnter');
604 $messages->{'FoundMultipleApacheConfFiles'}->{en} =
605 heading('MULTIPLE APACHE CONFIG FILES') . qq|
606 I found more than one possible Apache configuration file:
610 Choose the correct file [1]: |;
612 $messages->{'NoApacheConfFiles'}->{en} =
613 heading('NO APACHE CONFIG FILE FOUND') . qq|
614 I was not able to find your Apache configuration file.
616 The file is usually called httpd.conf or apache.conf.
618 Please specify the location of your config file: |;
620 $messages->{'NotAFile'}->{en} = heading('FILE DOES NOT EXIST') . qq|
621 The file %s does not exist.
623 Please press <ENTER> to continue: |;
625 $messages->{'EnterApacheUser'}->{en} = heading('NEED APACHE USER') . qq|
626 I was not able to determine the user that Apache is running as. This
627 information is necessary in order to set the access privileges correctly on
628 %s/koha.conf. This user should be set in one of the Apache configuration
629 files using the "User" directive.
631 Enter the Apache userid: |;
633 $messages->{'InvalidUserid'}->{en} = heading('INVALID USERID') . qq|
634 The userid %s is not a valid userid on this system.
636 Press <ENTER> to continue: |;
639 my @confpossibilities;
641 foreach my $httpdconf (qw(/usr/local/apache/conf/httpd.conf
642 /usr/local/etc/apache/httpd.conf
643 /usr/local/etc/apache/apache.conf
644 /var/www/conf/httpd.conf
645 /etc/apache/conf/httpd.conf
646 /etc/apache/conf/apache.conf
647 /etc/apache-ssl/conf/apache.conf
648 /etc/apache-ssl/httpd.conf
649 /etc/httpd/conf/httpd.conf
650 /etc/httpd/httpd.conf)) {
651 if ( -f $httpdconf ) {
652 push @confpossibilities, $httpdconf;
656 if ($#confpossibilities==-1) {
657 my $message=getmessage('NoApacheConfFiles');
659 until (-f $::realhttpdconf) {
660 $choice=showmessage($message, "free", 1);
662 $::realhttpdconf=$choice;
664 showmessage(getmessage('NotAFile', [$choice]),'PressEnter', '', 1);
667 } elsif ($#confpossibilities>0) {
671 foreach (@confpossibilities) {
672 $conffiles.=" $counter: $_\n";
673 $options.="$counter";
676 my $message=getmessage('FoundMultipleApacheConfFiles', [$conffiles]);
677 my $choice=showmessage($message, "restrictchar $options", 1);
678 $::realhttpdconf=$confpossibilities[$choice-1];
680 $::realhttpdconf=$confpossibilities[0];
682 unless (open (HTTPDCONF, "<$::realhttpdconf")) {
683 warn "Insufficient privileges to open $::realhttpdconf for reading.\n";
687 while (<HTTPDCONF>) {
688 if (/^\s*User\s+"?([-\w]+)"?\s*$/) {
697 unless ($::httpduser) {
698 my $message=getmessage('EnterApacheUser', [$::etcdir]);
699 until (length($::httpduser) && getpwnam($::httpduser)) {
700 $::httpduser=showmessage($message, "free", '');
701 if (length($::httpduser)>0) {
702 unless (getpwnam($::httpduser)) {
703 my $message=getmessage('InvalidUserid', [$::httpduser]);
704 showmessage($message,'PressEnter');
709 print "AU: $::httpduser\n";
714 $messages->{'ApacheConfigIntroduction'}->{en} =
715 heading('APACHE CONFIGURATION') . qq|
716 Koha needs to setup your Apache configuration file for the
717 OPAC and LIBRARIAN virtual hosts. By default this installer
718 will do this by using one ip address and two different ports
719 for the virtual hosts. There are other ways to set this up,
720 and the installer will leave comments in httpd.conf detailing
721 what these other options are.
724 Press <ENTER> to continue: |;
726 $messages->{'GetVirtualHostEmail'}->{en} =
727 heading('WEB SERVER E-MAIL CONTACT') . qq|
728 Enter the e-mail address to be used as a contact for the virtual hosts (this
729 address is displayed if any errors are encountered).
731 E-mail contact [%s]: |;
733 $messages->{'GetServerName'}->{en} =
734 heading('WEB SERVER HOST NAME OR IP ADDRESS') . qq|
735 Please enter the domain name or ip address of your computer.
737 Host name or IP Address [%s]: |;
739 $messages->{'GetOpacPort'}->{en} = heading('OPAC VIRTUAL HOST PORT') . qq|
740 Please enter the port for your OPAC interface. This defaults to port 80, but
741 if you are already serving web content from this server, you should change it
742 to a different port (8000 might be a good choice).
744 Enter the OPAC Port [%s]: |;
746 $messages->{'GetIntranetPort'}->{en} =
747 heading('INTRANET VIRTUAL HOST PORT') . qq|
748 Please enter the port for your Intranet interface. This must be different from
751 Enter the Intranet Port [%s]: |;
754 sub getapachevhostinfo {
756 $::svr_admin = "webmaster\@$::domainname";
757 $::servername=`hostname`;
760 $::intranetport=8080;
762 showmessage(getmessage('ApacheConfigIntroduction'), 'PressEnter');
764 $::svr_admin=showmessage(getmessage('GetVirtualHostEmail', [$::svr_admin]), 'email', $::svr_admin);
765 $::servername=showmessage(getmessage('GetServerName', [$::servername]), 'free', $::servername);
768 $::opacport=showmessage(getmessage('GetOpacPort', [$::opacport]), 'numerical', $::opacport);
769 $::intranetport=showmessage(getmessage('GetIntranetPort', [$::opacport, $::intranetport]), 'numerical', $::intranetport);
773 $messages->{'StartUpdateApache'}->{en} =
774 heading('UPDATING APACHE CONFIGURATION') . qq|
775 Checking for modules that need to be loaded...
778 $messages->{'LoadingApacheModuleModEnv'}->{en}="Loading SetEnv Apache module.\n";
780 $messages->{'LoadingApacheModuleModInc'}->{en}="Loading Includes Apache module.\n";
782 $messages->{'ApacheConfigBackupFailed'}->{en} =
783 heading('APACHE CONFIGURATION BACKUP FAILED') . qq|
784 An error occurred while trying to make a backup copy of %s.
788 No changes will be made to the apache configuration file at this time.
790 Press <ENTER> to continue: |;
793 $messages->{'ApacheAlreadyConfigured'}->{en} =
794 heading('APACHE ALREADY CONFIGURED') . qq|
795 %s appears to already have an entry for Koha
796 Virtual Hosts. You may need to edit %s
797 f anything has changed since it was last set up. This
798 script will not attempt to modify an existing Koha apache
801 Press <ENTER> to continue: |;
803 sub updateapacheconf {
804 my $logfiledir=`grep ^ErrorLog "$::realhttpdconf"`;
808 $logfiledir=~m#ErrorLog (.*)/[^/]*$#
809 or die "Can't parse ErrorLog directive\n";
813 unless ($logfiledir) {
817 showmessage(getmessage('StartUpdateApache'), 'none');
821 my $includesmodule=0;
822 open HC, "<$::realhttpdconf";
824 if (/^\s*#\s*LoadModule env_module /) {
826 showmessage(getmessage('LoadingApacheModuleModEnv'));
829 if (/^\s*#\s*LoadModule includes_module /) {
831 showmessage(getmessage('LoadingApacheModuleModInc'));
833 if (/\s*LoadModule includes_module / ) {
840 $backupfailed=`cp -f $::realhttpdconf $::realhttpdconf\.prekoha`;
842 showmessage(getmessage('ApacheConfigBackupFailed', [$::realhttpdconf,$backupfailed ]), 'PressEnter');
846 if ($envmodule || $includesmodule) {
847 open HC, ">$::realhttpdconf";
854 if (`grep 'VirtualHost $::servername' "$::realhttpdconf"`) {
855 showmessage(getmessage('ApacheAlreadyConfigured', [$::realhttpdconf, $::realhttpdconf]), 'PressEnter');
858 my $includesdirectives='';
859 if ($includesmodule) {
860 $includesdirectives.="Options +Includes\n";
861 $includesdirectives.=" AddHandler server-parsed .html\n";
863 open(SITE,">>$::realhttpdconf") or warn "Insufficient priveleges to open $::realhttpdconf for writing.\n";
865 if ($::opacport != 80) {
866 $opaclisten="Listen $::opacport";
868 my $intranetlisten = '';
869 if ($::intranetport != 80) {
870 $intranetlisten="Listen $::intranetport";
874 # Ports to listen to for Koha
878 # NameVirtualHost is used by one of the optional configurations detailed below
880 #NameVirtualHost 11.22.33.44
882 # KOHA's OPAC Configuration
883 <VirtualHost $::servername\:$::opacport>
884 ServerAdmin $::svr_admin
885 DocumentRoot $::opacdir/htdocs
886 ServerName $::servername
887 ScriptAlias /cgi-bin/koha/ $::opacdir/cgi-bin/
888 ErrorLog $logfiledir/opac-error_log
889 TransferLog $logfiledir/opac-access_log
890 SetEnv PERL5LIB "$::intranetdir/modules"
894 # KOHA's INTRANET Configuration
895 <VirtualHost $::servername\:$::intranetport>
896 ServerAdmin $::svr_admin
897 DocumentRoot $::intranetdir/htdocs
898 ServerName $::servername
899 ScriptAlias /cgi-bin/koha/ "$::intranetdir/cgi-bin/"
900 ErrorLog $logfiledir/koha-error_log
901 TransferLog $logfiledir/koha-access_log
902 SetEnv PERL5LIB "$::intranetdir/modules"
906 # If you want to use name based Virtual Hosting:
907 # 1. remove the two Listen lines
908 # 2. replace $::servername\:$::opacport wih your.opac.domain.name
909 # 3. replace ServerName $::servername wih ServerName your.opac.domain.name
910 # 4. replace $::servername\:$::intranetport wih your intranet domain name
911 # 5. replace ServerName $::servername wih ServerName your.intranet.domain.name
913 # If you want to use NameVirtualHost'ing (using two names on one ip address):
914 # 1. Follow steps 1-5 above
915 # 2. Uncomment the NameVirtualHost line and set the correct ip address
923 $messages->{'IntranetAuthenticationQuestion'}->{en} =
924 heading('INTRANET AUTHENTICATION') . qq|
925 I can set it up so that the Intranet/Librarian site is password protected using
926 Apache's Basic Authorization.
928 This is going to be phased out very soon. However, setting this up can provide
929 an extra layer of security before the new authentication system is completely
932 Would you like to do this ([Y]/N): |;
934 $messages->{'BasicAuthUsername'}->{en}="Please enter a userid for intranet access [%s]: ";
935 $messages->{'BasicAuthPassword'}->{en}="Please enter a password for %s: ";
936 $messages->{'BasicAuthPasswordWasBlank'}->{en}="\nYou cannot use a blank password!\n\n";
938 sub basicauthentication {
939 my $message=getmessage('IntranetAuthenticationQuestion');
940 my $answer=showmessage($message, 'yn', 'y');
942 my $apacheauthusername='librarian';
943 my $apacheauthpassword='';
944 if ($answer=~/^y/i) {
945 ($apacheauthusername) = showmessage(getmessage('BasicAuthUsername', [ $apacheauthusername]), 'free', $apacheauthusername, 1);
946 $apacheauthusername=~s/[^a-zA-Z0-9]//g;
947 while (! $apacheauthpassword) {
948 ($apacheauthpassword) = showmessage(getmessage('BasicAuthPassword', [ $apacheauthusername]), 'free', 1);
949 if (!$apacheauthpassword) {
950 ($apacheauthpassword) = showmessage(getmessage('BasicAuthPasswordWasBlank'), 'none', '', 1);
953 open AUTH, ">$::etcdir/kohaintranet.pass";
954 my $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
955 my $salt=substr($chars, int(rand(length($chars))),1);
956 $salt.=substr($chars, int(rand(length($chars))),1);
957 print AUTH $apacheauthusername.":".crypt($apacheauthpassword, $salt)."\n";
959 open(SITE,">>$::realhttpdconf") or warn "Insufficient priveleges to open $::realhttpdconf for writing.\n";
962 <Directory $::intranetdir>
963 AuthUserFile $::etcdir/kohaintranet.pass
965 AuthName "Koha Intranet (for librarians only)"
973 $messages->{'InstallFiles'}->{en} = heading('INSTALLING FILES') . qq|
974 Copying files to installation directories:
979 $messages->{'CopyingFiles'}->{en}="Copying %s to %s.\n";
986 showmessage(getmessage('InstallFiles'),'none');
987 print getmessage('CopyingFiles', ['intranet-html', "$::intranetdir/htdocs" ]);
988 system("cp -R intranet-html/* $::intranetdir/htdocs/");
989 print getmessage('CopyingFiles', ['intranet-cgi', "$::intranetdir/cgi-bin" ]);
990 system("cp -R intranet-cgi/* $::intranetdir/cgi-bin/");
991 print getmessage('CopyingFiles', ['stand-alone scripts', "$::intranetdir/scripts" ]);
992 system("cp -R scripts/* $::intranetdir/scripts/");
993 print getmessage('CopyingFiles', ['perl modules', "$::intranetdir/modules" ]);
994 system("cp -R modules/* $::intranetdir/modules/");
995 print getmessage('CopyingFiles', ['opac-html', "$::opacdir/htdocs" ]);
996 system("cp -R opac-html/* $::opacdir/htdocs/");
997 print getmessage('CopyingFiles', ['opac-cgi', "$::opacdir/cgi-bin" ]);
998 system("cp -R opac-cgi/* $::opacdir/cgi-bin/");
999 system("touch $::opacdir/cgi-bin/opac");
1001 system("chown -R root:$::httpduser $::opacdir");
1002 system("chown -R root:$::httpduser $::intranetdir");
1004 # Create /etc/koha.conf
1006 my $old_umask = umask(027); # make sure koha.conf is never world-readable
1007 open(SITES,">$::etcdir/koha.conf.tmp") or warn "Couldn't create file at $::etcdir. Must have write capability.\n";
1010 hostname=$::hostname
1013 includes=$::opacdir/htdocs/includes
1014 intranetdir=$::intranetdir
1016 kohalogdir=$::kohalogdir
1017 kohaversion=$::kohaversion
1018 httpduser=$::httpduser
1019 intrahtdocs=$::intranetdir/htdocs/intranet-tmpl
1020 opachtdocs=$::opacdir/htdocs/opac-tmpl
1025 chown((getpwnam($::httpduser)) [2,3], "$::etcdir/koha.conf.tmp") or warn "can't chown koha.conf: $!";
1026 chmod 0440, "$::etcdir/koha.conf.tmp";
1028 chmod 0750, "$::intranetdir/scripts/z3950daemon/z3950-daemon-launch.sh";
1029 chmod 0750, "$::intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh";
1030 chmod 0750, "$::intranetdir/scripts/z3950daemon/processz3950queue";
1031 chown(0, (getpwnam($::httpduser)) [3], "$::intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh") or warn "can't chown $::intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh: $!";
1032 chown(0, (getpwnam($::httpduser)) [3], "$::intranetdir/scripts/z3950daemon/processz3950queue") or warn "can't chown $::intranetdir/scripts/z3950daemon/processz3950queue: $!";
1036 $messages->{'MysqlRootPassword'}->{en} =
1037 heading('MYSQL ROOT USER PASSWORD') . qq|
1038 To allow us to create the koha database please supply your
1039 mysql server's root user password:
1041 Enter MySQL root user password: |;
1043 $messages->{'InvalidMysqlRootPassword'}->{en}="Invalid Password. Please try again.";
1045 $messages->{'CreatingDatabase'}->{en} = heading('CREATING DATABASE') . qq|
1046 Creating the MySQL database for Koha...
1050 $messages->{'CreatingDatabaseError'}->{en} =
1051 heading('ERROR CREATING DATABASE') . qq|
1052 Couldn't connect to the MySQL server for the reason given above.
1053 This is a serious problem, the database will not get installed.
\a
1055 Press <ENTER> to continue: |;
1057 $messages->{'SampleData'}->{en} = heading('SAMPLE DATA') . qq|
1058 If you are installing Koha for evaluation purposes, I have a batch of sample
1059 data that you can install now.
1061 If you are installing Koha with the intention of populating it with your own
1062 data, you probably don't want this sample data installed.
1064 Would you like to install the sample data? Y/[N]: |;
1066 $messages->{'SampleDataInstalled'}->{en} =
1067 heading('SAMPLE DATA INSTALLED') . qq|
1068 Sample data has been installed. For some suggestions on testing Koha, please
1069 read the file doc/HOWTO-Testing. If you find any bugs, please submit them at
1070 http://bugs.koha.org/. If you need help with testing Koha, you can post a
1071 question through the koha-devel mailing list, or you can check for a developer
1072 online at +irc.katipo.co.nz:6667 channel #koha.
1074 You can find instructions for subscribing to the Koha mailing lists at:
1079 Press <ENTER> to continue: |;
1081 $messages->{'AddBranchPrinter'}->{en} = heading('Add Branch and Printer') . qq|
1082 Would you like to install an initial branch and printer? [Y]/N: |;
1084 $messages->{'BranchName'}->{en}="Branch Name [%s]: ";
1085 $messages->{'BranchCode'}->{en}="Branch Code (4 letters or numbers) [%s]: ";
1086 $messages->{'PrinterQueue'}->{en}="Printer Queue [%s]: ";
1087 $messages->{'PrinterName'}->{en}="Printer Name [%s]: ";
1088 $messages->{'BlankMysqlPassword'}->{en} = heading('Blank MySQL Password') . qq|
1089 Do not leave your MySQL root password blank unless you know exactly what you
1090 are doing. To change your MySQL root password use the mysqladmin command:
1092 mysqladmin password NEWPASSWORDHERE
1094 Press <ENTER> to continue:
1098 $::mysqluser = 'root';
1101 foreach my $mysql (qw(/usr/local/mysql
1105 if ( -d $mysql && -f "$mysql/bin/mysqladmin") {
1110 print "I don't see mysql in the usual places.\n";
1112 print "Where have you installed mysql? ";
1113 chomp($::mysqldir = <STDIN>);
1114 last if -f "$::mysqldir/bin/mysqladmin";
1117 I can't find it there either. If you compiled mysql yourself,
1118 please give the value of --prefix when you ran configure.
1120 The file mysqladmin should be in bin/mysqladmin under the directory that you
1129 while ($needpassword) {
1130 $::mysqlpass=showmessage(getmessage('MysqlRootPassword'), 'free');
1131 $::mysqlpass_quoted = $::mysqlpass;
1132 $::mysqlpass_quoted =~ s/"/\\"/g;
1133 $::mysqlpass_quoted="-p\"$::mysqlpass_quoted\"";
1134 $::mysqlpass eq '' and $::mysqlpass_quoted='';
1135 my $result=system("$::mysqldir/bin/mysqladmin -u$::mysqluser $::mysqlpass_quoted proc > /dev/null 2>&1");
1137 print getmessage('InvalidMysqlRootPassword');
1139 if ($::mysqlpass eq '') {
1140 showmessage(getmessage('BlankMysqlPassword'), 'PressEnter');
1146 showmessage(getmessage('CreatingDatabase'),'none');
1148 my $result=system("$::mysqldir/bin/mysqladmin", "-u$::mysqluser", "-p$::mysqlpass", "create", "$::dbname");
1150 showmessage(getmessage('CreatingDatabaseError'),'PressEnter', '', 1);
1152 # Populate the Koha database
1153 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname < koha.mysql");
1154 # Set up permissions
1155 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted mysql -e \"insert into user (Host,User,Password) values ('$::hostname','$::user',password('$::pass'))\"\;");
1156 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')\"");
1157 system("$::mysqldir/bin/mysqladmin -u$::mysqluser $::mysqlpass_quoted reload");
1167 $messages->{'UpdateMarcTables'}->{en} =
1168 heading('UPDATING MARC FIELD DEFINITION TABLES') . qq|
1169 You can import marc parameters for :
1175 Please choose which parameter you want to install. Note if you choose 3,
1176 nothing will be added, and it can be a BIG job to manually create those tables
1178 Choose MARC definition [1]: |;
1180 $messages->{'Language'}->{en} = heading('CHOOSE LANGUAGES') . qq|
1181 This version of koha supports a few languages.
1182 Enter you languages preferences : either en, fr, es or pl.
1183 Note that the en is always choosen when the system does not finds the
1184 language you choose in a specific screen.
1185 fr : opac is translated (except pictures)
1186 es : a few intranet is translated (including pictures)
1187 pl : opac is translated (UNTESTED in this release)
1190 sub updatedatabase {
1191 # At this point, $::etcdir/koha.conf must exist, for C4::Context
1192 # We must somehow temporarily enable $::etcdir/koha.conf. A symlink can
1193 # do this & at the same time facilitate detection of aborted installs.
1194 my $result=system ("perl -I $::intranetdir/modules scripts/updater/updatedatabase");
1196 print "Problem updating database...\n";
1200 my $response=showmessage(getmessage('UpdateMarcTables'), 'restrictchar 123', '1');
1202 if ($response == 1) {
1203 system("cat scripts/misc/marc_datas/marc21_en/structure_def.sql | $::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname");
1205 if ($response == 2) {
1206 system("cat scripts/misc/marc_datas/unimarc_fr/structure_def.sql | $::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname");
1207 system("cat scripts/misc/lang-datas/fr/stopwords.sql | $::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname");
1210 $result = system ("perl -I $::intranetdir/modules scripts/marc/updatedb2marc.pl");
1212 print "Problem updating database to MARC...\n";
1216 print "\n\nFinished updating of database. Press <ENTER> to continue...";
1220 sub populatedatabase {
1221 my $response=showmessage(getmessage('SampleData'), 'yn', 'n');
1222 if ($response =~/^y/i) {
1223 system("gunzip -d < sampledata-1.2.gz | $::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname");
1224 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname -e \"insert into branches (branchcode,branchname,issuing) values ('MAIN', 'Main Library', 1)\"");
1225 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1226 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1227 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname -e \"insert into printers (printername,printqueue,printtype) values ('Circulation Desk Printer', 'lp', 'hp')\"");
1228 showmessage(getmessage('SampleDataInstalled'), 'PressEnter','',1);
1231 my $response=showmessage(getmessage('AddBranchPrinter'), 'yn', 'y');
1233 unless ($response =~/^n/i) {
1234 my $branch='Main Library';
1235 $branch=showmessage(getmessage('BranchName', [$branch]), 'free', $branch, 1);
1236 $branch=~s/[^A-Za-z0-9\s]//g;
1238 my $branchcode=$branch;
1239 $branchcode=~s/[^A-Za-z0-9]//g;
1240 $branchcode=uc($branchcode);
1241 $branchcode=substr($branchcode,0,4);
1242 $branchcode=showmessage(getmessage('BranchCode', [$branchcode]), 'free', $branchcode, 1);
1243 $branchcode=~s/[^A-Za-z0-9]//g;
1244 $branchcode=uc($branchcode);
1245 $branchcode=substr($branchcode,0,4);
1246 $branchcode or $branchcode='DEF';
1248 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname -e \"insert into branches (branchcode,branchname,issuing) values ('$branchcode', '$branch', 1)\"");
1249 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1250 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1252 my $printername='Library Printer';
1253 $printername=showmessage(getmessage('PrinterName', [$printername]), 'free', $printername, 1);
1254 $printername=~s/[^A-Za-z0-9\s]//g;
1256 my $printerqueue='lp';
1257 $printerqueue=showmessage(getmessage('PrinterQueue', [$printerqueue]), 'free', $printerqueue, 1);
1258 $printerqueue=~s/[^A-Za-z0-9]//g;
1259 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname -e \"insert into printers (printername,printqueue,printtype) values ('$printername', '$printerqueue', '')\"");
1261 my $language=showmessage(getmessage('Language'), 'free', 'en');
1262 system("$::mysqldir/bin/mysql -u$::mysqluser $::mysqlpass_quoted $::dbname -e \"update systempreferences set value='$language' where variable='opaclanguages'\"");
1266 $messages->{'RestartApache'}->{en} = heading('RESTART APACHE') . qq|
1267 Apache needs to be restarted to load the new configuration for Koha.
1269 Would you like to restart Apache now? [Y]/N: |;
1273 my $response=showmessage(getmessage('RestartApache'), 'yn', 'y');
1277 unless ($response=~/^n/i) {
1278 # Need to support other init structures here?
1279 if (-e "/etc/rc.d/init.d/httpd") {
1280 system('/etc/rc.d/init.d/httpd restart');
1281 } elsif (-e "/etc/init.d/apache") {
1282 system('/etc//init.d/apache restart');
1283 } elsif (-e "/etc/init.d/apache-ssl") {
1284 system('/etc/init.d/apache-ssl restart');
1291 sub loadconfigfile {
1294 open (KC, "<$::etcdir/koha.conf");
1297 (next) if (/^\s*#/);
1298 if (/(.*)\s*=\s*(.*)/) {
1301 # Clean up white space at beginning and end
1302 $variable=~s/^\s*//g;
1303 $variable=~s/\s*$//g;
1306 $configfile{$variable}=$value;
1310 $::intranetdir=$configfile{'intranetdir'};
1311 $::opacdir=$configfile{'opacdir'};
1312 $::kohaversion=$configfile{'kohaversion'};
1313 $::kohalogdir=$configfile{'kohalogdir'};
1314 $::database=$configfile{'database'};
1315 $::hostname=$configfile{'hostname'};
1316 $::user=$configfile{'user'};
1317 $::pass=$configfile{'pass'};
1320 END { } # module clean-up code here (global destructor)