1 package Install; #assumes Install.pm
4 # Copyright 2000-2002 Katipo Communications
5 # Contains parts Copyright 2003 MJ Ray
7 # This file is part of Koha.
9 # Koha is free software; you can redistribute it and/or modify it under the
10 # terms of the GNU General Public License as published by the Free Software
11 # Foundation; either version 2 of the License, or (at your option) any later
14 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License along with
19 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 # Suite 330, Boston, MA 02111-1307 USA
23 # MJR: my.cnf, etcdir, prefix, new display, apache conf, copying fixups
27 #MJR: everyone will have these modules, right?
28 # They look like part of perl core to me
30 use Term::ANSIColor qw(:constants);
34 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
38 Install.pm - Perl module containing the bulk of the installation logic
42 The Install.pm module contains the bulk
43 of the code to do installation;
44 this code is used by installer.pl
45 to perform an actual installation.
47 =head2 Internal functions (not meant to be used outside of Install.pm)
53 # set the version for version checking
58 &read_autoinstall_file
63 &releasecandidatewarning
64 &getinstallationdirectories
82 use vars qw( $kohaversion $newversion ); # set in loadconfigfile and installer.pl
83 use vars qw( $language ); # set in installer.pl
84 use vars qw( $domainname ); # set in installer.pl
86 use vars qw( $etcdir ); # set in installer.pl, usu. /etc
87 use vars qw( $intranetdir $opacdir $kohalogdir );
88 use vars qw( $realhttpdconf $httpduser );
89 use vars qw( $servername $svr_admin $opacport $intranetport );
90 use vars qw( $mysqldir );
91 use vars qw( $database $mysqluser );
92 use vars qw( $mysqlpass ); # normally should not be used
93 use vars qw( $hostname $user $pass ); # virtual hosting
97 $messages->{'WelcomeToKohaInstaller'
98 = heading('Welcome to the Koha Installer') . qq|...|;
100 The heading function takes one string, the text to be displayed as
101 the heading, and returns a formatted heading (currently formatted
104 This reduces the likelihood of pod2man(1) etc. misinterpreting
105 a line of equal signs as illegal POD directives.
109 my $termios = POSIX::Termios->new();
111 my $terminal = Term::Cap->Tgetent({OSPEED=>$termios->getospeed()});
112 my $clear_string = "\n";
117 return($clear_string.ON_BLUE.WHITE.BOLD." "x$bal.uc($title)." "x$bal.RESET."\n\n");
120 my $mycnf = $ENV{HOME}."/.my.cnf";
121 my $mytmpcnf = `mktemp my.cnf.koha.XXXXXX`;
125 $messages->{'continuing'}->{en}="Great! Continuing...\n\n";
126 $messages->{'WelcomeToKohaInstaller'}->{en} =
127 heading('Welcome to the Koha Installer') . qq|
128 This program will ask some questions and try to install koha for you.
129 You need to know: where most koha files should be stored (you can set
130 the prefix environment variable for this); the username and password of
131 a mysql superuser; and details of your library setup. You may also need
132 to know details of your Apache setup.
134 If you want to install the Koha configuration files somewhere other than
135 /etc (for multiple Koha versions on one system, for example), you should
136 set the etcdir environment variable. Please look at your manuals for
137 details of how to set that.
139 Recommended answers are given in brackets after each question. To accept
140 the default value for any question (indicated by []), simply hit Enter
143 You also can define an auto_install_file, that will answer every question automatically.
144 To use this feature, run ./installer.pl -i /path/to/auto_install_file
146 Are you ready to begin the installation? ([Y]/N): |;
148 $messages->{'WelcomeToUpgrader'}->{en} =
149 heading('Welcome to the Koha Upgrader') . qq|
150 You are attempting to upgrade from Koha %s to %s.
152 We recommend that you do a complete backup of all your files before upgrading.
153 This upgrade script will make a backup copy of your files for you.
155 Would you like to proceed? (Y/[N]):|;
157 $messages->{'AbortingInstall'}->{en} =
158 heading('ABORTING') . qq|
159 Aborting as requested. Please rerun when you are ready.
162 $messages->{'ReleaseCandidateWarning'}->{en} =
163 heading('RELEASE CANDIDATE') . qq|
164 WARNING: You are about to install Koha version %s. This is a
165 release candidate, It is NOT bugfree.
166 However, it works, and has been declared stable enough to
169 Most people should answer Yes here.
171 Are you sure you want to install Koha %s? (Y/[N]): |;
172 $messages->{'WatchForReleaseAnnouncements'}->{en}=qq|
174 Watch for announcements of Koha releases on the Koha mailing list or the Koha
175 web site (http://www.koha.org/).
179 $messages->{'NETZ3950Missing'}->{en}=qq|
181 The Net::Z3950 module is missing. This module is necessary if you want to use
182 Koha's Z39.50 client to download bibliographic records from other libraries.
184 To install this module, you will need the yaz client installed from
185 http://www.indexdata.dk/yaz/ and then you can install the perl module with the
188 perl -MCPAN -e 'install Net::Z3950'
190 ...or by installing packages for your distribution, if available.
192 IMPORTANT NOTE : If you use Perl 5.8.0, you might need to
193 edit NET::Z3950's Makefile.PL and yazwrap/Makefile.PL to include:
195 'DEFINE' => '-D_GNU_SOURCE',
197 Also note that some installations of Perl on Red Hat will generate a lot of
198 "'my_perl' undeclared" errors when running make in Net-Z3950. This is fixed by
199 inserting in yazwrap/ywpriv.h a line saying #include "XSUB.h"
201 Press the <ENTER> key to continue: |; #'
203 $messages->{'CheckingPerlModules'}->{en} = heading('PERL MODULES') . qq|
204 Checking perl modules ...
207 $messages->{'PerlVersionFailure'}->{en}="Sorry, you need at least Perl %s\n";
209 $messages->{'MissingPerlModules'}->{en} = heading('MISSING PERL MODULES') . qq|
210 You are missing some Perl modules required by Koha.
211 Please run this again after installing them.
212 They may be installed by finding packages from your operating system supplier, or running (as root) the following commands:
217 $messages->{'AllPerlModulesInstalled'}->{en} =
218 heading('PERL MODULES AVAILABLE') . qq|
219 All required perl modules are installed.
221 Press <ENTER> to continue: |;
222 $messages->{'KohaVersionInstalled'}->{en}="You currently have Koha %s on your system.";
223 $messages->{'KohaUnknownVersionInstalled'}->{en}="I am not able to determine what version of Koha is installed now.";
224 $messages->{'KohaAlreadyInstalled'}->{en} =
225 heading('Koha already installed') . qq|
226 It looks like Koha is already installed on your system (%s/koha.conf exists).
227 If you would like to upgrade your system to %s, please use
228 the koha.upgrade script in this directory.
233 $messages->{'GetOpacDir'}->{en} = heading('OPAC DIRECTORY') . qq|
234 Please supply the directory you want Koha to store its OPAC files in. This
235 directory will be auto-created for you if it doesn't exist.
237 OPAC Directory [%s]: |; #'
239 $messages->{'GetIntranetDir'}->{en} =
240 heading('LIBRARIAN DIRECTORY') . qq|
241 Please supply the directory you want Koha to store its Librarian interface
242 files in. This directory will be auto-created for you if it doesn't exist.
244 Intranet Directory [%s]: |; #'
246 $messages->{'GetKohaLogDir'}->{en} = heading('LOG DIRECTORY') . qq|
247 Specify a directory where log files will be written.
249 Koha Log Directory [%s]: |;
251 $messages->{'AuthenticationWarning'}->{en} = heading('Authentication') . qq|
252 This release of Koha has a new authentication module.
253 You will be required to log in to
254 access some features.
256 IMPORTANT: You can log in using the userid and password from the %s/koha.conf configuration file at any time.
257 Use the "Members" screen to add passwords for other accounts and set their flags.
259 Press the <ENTER> key to continue: |;
261 $messages->{'Completed'}->{en} = heading('INSTALLATION COMPLETE') . qq|
262 Congratulations ... your Koha installation is complete!
263 You will be able to connect to your Librarian interface at:
265 use the koha admin mysql login and password to connect to this interface.
266 and the OPAC interface at:
268 Please read the Hints file and visit http://www.koha.org
269 Press <ENTER> to exit the installer: |;
271 $messages->{'UpgradeCompleted'}->{en} = heading('UPGRADE COMPLETE') . qq|
272 Congratulations ... your Koha upgrade is finished!
274 Please report any problems you encounter through http://bugs.koha.org/
276 Press <ENTER> to exit the installer: |;
279 sub releasecandidatewarning {
280 my $message=getmessage('ReleaseCandidateWarning', [$newversion, $newversion]);
281 my $answer=showmessage($message, 'yn', 'n');
283 if ($answer =~ /y/i) {
284 print getmessage('continuing');
286 my $message=getmessage('WatchForReleaseAnnouncements');
292 sub read_autoinstall_file
294 my $fname = shift; # Config file to read
295 my $retval = {}; # Return value: ref-to-hash holding the
298 open (CONF, $fname) or return undef;
302 my $var; # Variable name
303 my $value; # Variable value
306 s/#.*//; # Strip comments
307 next if /^\s*$/; # Ignore blank lines
309 # Look for a line of the form
311 if (!/^\s*(\w+)\s*=\s*(.*?)\s*$/)
316 # Found a variable assignment
317 # variable that was already set.
320 $retval->{$var} = $value;
323 if ($retval->{MysqlRootPassword} eq "XXX") {
324 print "ERROR : the root password is XXX. It is NOT valid. Edit your auto_install_file\n";
331 =head2 Accessor functions (for installer.pl)
341 Sets the installation language, normally "en" (English).
342 In fact, only "en" is supported.
346 sub setlanguage ($) {
352 setdomainname('example.org');
354 Sets the domain name of the host.
356 The domain name should not contain a leading dot;
357 otherwise, the results are undefined.
361 sub setdomainname ($) {
369 Sets the sysconfdir, normally /etc.
370 This should be an absolute path; a trailing / is not required.
382 Gets the Koha version as known by the previous config file.
386 sub getkohaversion () {
387 return($kohaversion);
392 setkohaversion('1.3.3RC26');
394 Sets the Koha version as known by the installer.
398 sub setkohaversion ($) {
404 my $servername = getservername;
406 Gets the name of the Koha virtual server as specified by the user.
410 sub getservername () {
418 Gets the port that will run the Koha OPAC virtual server,
419 as specified by the user.
427 =item getintranetport
429 $port = getintranetport;
431 Gets the port that will run the Koha INTRANET virtual server,
432 as specified by the user.
436 sub getintranetport () {
442 =head2 Miscellaneous utility functions
452 Does the equivalent of dirname(1). Given a path $path, return the
453 parent directory of $path (best guess), except when $path seems to
454 be the same as /, in which case $path itself is returned unchanged.
460 if ($path =~ /[^\/]/s) {
462 $path =~ s/\/+[^\/]+\/*$//s;
473 mkdir_parents $path, $mode;
475 Does the equivalent of mkdir -p, or mkdir --parents. Given a path $path,
476 create the directory $path, recursively creating any intermediate
477 directories. If $mode is given, the directory will be created with
480 WARNING: If $path already exists, mkdir_parents will just return
481 successfully (just like mkdir -p), whether the mode of $path conforms
482 to $mode or not. (This is the behaviour of the mkdir -p command.)
487 my($path, $mode) = @_;
488 my $ok = -d($path)? 1: defined $mode? mkdir($path, $mode): mkdir($path);
490 if (!$ok && $! == ENOENT) {
491 my $parent = dirname($path);
492 $ok = mkdir_parents($parent, $mode);
494 # retry and at the same time make sure that $! is set correctly
495 $ok = defined $mode? mkdir($path, $mode): mkdir($path);
504 getmessage($msgid, $variables);
506 Gets a localized message (format string) with message id $msgid,
507 and, if an array reference of variables $variables is given,
508 substitutes variables in the format string with @$variables.
509 Returns the found message string, with variable substitutions
512 $msgid must be the message identifier corresponding to a defined
513 message string (a valid key to the $messages hash in the Installer
514 package). getmessage throws an exception if the message cannot be
520 my $messagename=shift;
522 my $message=$messages->{$messagename}->{$language} || $messages->{$messagename}->{en} || RED.BOLD."Error: No message named $messagename in Install.pm\n";
523 if (defined($variables)) {
524 $message=sprintf $message, @$variables;
532 showmessage($message, 'none');
533 showmessage($message, 'none', undef, $noclear);
535 $result = showmessage($message, 'yn');
536 $result = showmessage($message, 'yn', $defaultresponse);
537 $result = showmessage($message, 'yn', $defaultresponse, $noclear);
539 $result = showmessage($message, 'restrictchar CHARS');
540 $result = showmessage($message, 'free');
541 $result = showmessage($message, 'silentfree');
542 $result = showmessage($message, 'numerical');
543 $result = showmessage($message, 'email');
544 $result = showmessage($message, 'PressEnter');
546 Shows a message and optionally gets a response from the user.
548 The first two arguments, the message and the response type,
549 are mandatory. The message must be the actual string to
550 display; the caller is responsible for calling getmessage if
553 The response type must be one of "none", "yn", "free", "silentfree"
554 "numerical", "email", "PressEnter", or a string consisting
555 of "restrictchar " followed by a list of allowed characters
556 (space can be specified). (Case is not significant, but case is
557 significant in the list of allowed characters.) If a response
558 type other than the above-listed is specified, the result is
561 Note that the response type "yn" is equivalent to "restrictchar yn".
562 Because "restrictchar" is case-sensitive, the user is expected
563 to enter "y" or "n" in lowercase only.
565 Note that the response type of "email" does not actually
566 guarantee that the returned value is a well-formed RFC-822
567 email address, nor does it accept all well-formed RFC-822 email
568 addresses. What it does is to restrict the returned value to a
569 string that is looks reasonably likely to be an email address
570 in the "real world", given the premise that the user is trying
571 to enter a real email address.
573 If a response type other than "none" or "PressEnter" is
574 specified, a third argument, specifying the default value, can
575 be specified: If this default response is not specified, the
576 default response is the first allowed character if the response
577 type is "restrictchar", otherwise the default response is the
578 empty string. This default response is used when the user does
579 not specify a value (i.e., presses Enter without typing in
580 anything), showmessage will assume that the default response is
583 Note that because the response type "yn" is equivalent to
584 "restrictchar yn", the default value for response type "yn",
585 if unspecified, is "y".
587 The screen is normally cleared before the message is displayed;
588 if a fourth argument is specified and is nonzero, this
589 screen-clearing is not done.
595 #MJR: Maybe refactor to use anonymous functions that
596 # check the responses instead of RnP branching.
597 my $message=join('',fill('','',(shift)));
598 my $responsetype=shift;
599 my $defaultresponse=shift;
601 $noclear = 0 unless defined $noclear; # defaults to "clear"
602 ($noclear) || (print $clear_string);
603 if ($responsetype =~ /^yn$/) {
604 $responsetype='restrictchar ynYN';
606 print RESET.$message;
607 if ($responsetype =~/^restrictchar (.*)/i) {
610 until ($options=~/$response/) {
611 (defined($defaultresponse)) || ($defaultresponse=substr($options,0,1));
614 (length($response)) || ($response=$defaultresponse);
615 if ( $response=~/.*[\:\(\)\^\$\*\!\\].*/ ) {
616 ($noclear) || (print $clear_string);
617 print RED."Response contains invalid characters. Choose from [$options].\n\n";
618 print RESET.$message;
621 unless ($options=~/$response/) {
622 ($noclear) || (print $clear_string);
623 print RED."Invalid Response. Choose from [$options].\n\n";
624 print RESET.$message;
629 } elsif ($responsetype =~/^(silent)?free$/i) {
630 (defined($defaultresponse)) || ($defaultresponse='');
631 if ($responsetype =~/^(silent)/i) { setecho(0) };
632 my $response=<STDIN>;
633 if ($responsetype =~/^(silent)/i) { setecho(1) };
635 ($response) || ($response=$defaultresponse);
637 } elsif ($responsetype =~/^numerical$/i) {
638 (defined($defaultresponse)) || ($defaultresponse='');
640 until ($response=~/^\d+$/) {
643 ($response) || ($response=$defaultresponse);
644 unless ($response=~/^\d+$/) {
645 ($noclear) || (print $clear_string);
646 print RED."Invalid Response ($response). Response must be a number.\n\n";
647 print RESET.$message;
651 } elsif ($responsetype =~/^email$/i) {
652 (defined($defaultresponse)) || ($defaultresponse='');
654 until ($response=~/.*\@.*\..*/) {
657 ($response) || ($response=$defaultresponse);
658 if ($response!~/.*\@.*\..*/) {
659 ($noclear) || (print $clear_string);
660 print RED."Invalid Response ($response). Response must be a valid email address.\n\n";
661 print RESET.$message;
665 } elsif ($responsetype =~/^PressEnter$/i) {
668 } elsif ($responsetype =~/^none$/i) {
671 # FIXME: There are a few places where we will get an undef as the
672 # response type. Should we thrown an exception here, or should we
673 # legitimize this usage and say "none" is the default if not specified?
674 #die "Illegal response type \"$responsetype\"";
685 Changes the display to show system output until the next showmessage call.
686 At the time of writing, this means using red text.
697 =head2 Subtasks of doing an installation
703 =item checkabortedinstall
707 Checks whether a previous installation process has been abnormally
708 aborted, by checking whether $etcidr/koha.conf is a symlink matching
709 a particular pattern. If an aborted installation is detected, give
710 the user a chance to abort, before trying to recover the aborted
713 FIXME: The recovery is not complete; it only partially rolls back
718 sub checkabortedinstall () {
719 if (-l("$etcdir/koha.conf")
720 && readlink("$etcdir/koha.conf") =~ /\.tmp$/
723 I have detected that you tried to install Koha before, but the installation
724 was aborted. I will try to continue, but there might be problems if the
725 database is already created.
728 print "Please press <ENTER> to continue: ";
731 # Remove the symlink after the <STDIN>, so the user can back out
732 unlink "$etcdir/koha.conf"
733 || die "Failed to remove incomplete $etcdir/koha.conf: $!\n";
741 Make sure that we loaded the right dirs from an old koha.conf
745 #FIXME: update to use Install.pm
747 if ($opacdir && $intranetdir) {
750 I believe that your old files are located in:
753 LIBRARIAN: $intranetdir
756 Does this look right? ([Y]/N):
758 my $answer = <STDIN>;
761 if ($answer =~/n/i) {
765 print "Great! continuing upgrade... \n";
769 if (!$opacdir || !$intranetdir) {
772 while (!$intranetdir) {
773 print "Please specify the location of your LIBRARIAN files: ";
775 my $answer = <STDIN>;
779 $intranetdir=$answer;
781 if (! -e "$intranetdir/htdocs") {
782 print "\nCouldn't find the htdocs directory here. That doesn't look right.\nPlease enter another location.\n\n";
787 print "Please specify the location of your OPAC files: ";
789 my $answer = <STDIN>;
795 if (! -e "$opacdir/htdocs") {
796 print "\nCouldn't find the htdocs directory here. That doesn't look right.\nPlease enter another location.\n\n";
804 =item checkperlmodules
808 Test whether the version of Perl is new enough, whether Perl is
809 found at the expected location, and whether all required modules
814 sub checkperlmodules {
816 # Test for Perl and Modules
818 my ($auto_install) = @_;
819 my $message = getmessage('CheckingPerlModules');
820 showmessage($message, 'none');
822 unless ($] >= 5.006001) { # Bug 179
823 die getmessage('PerlVersionFailure', ['5.6.1']);
828 unless (eval {require DBI}) { push @missing,"DBI" };
829 unless (eval {require Date::Manip}) { push @missing,"Date::Manip" };
830 unless (eval {require DBD::mysql}) { push @missing,"DBD::mysql" };
831 unless (eval {require HTML::Template}) { push @missing,"HTML::Template" };
832 unless (eval {require Digest::MD5}) { push @missing,"Digest::MD5" };
833 unless (eval {require MARC::Record}) { push @missing,"MARC::Record" };
834 unless (eval {require Mail::Sendmail}) { push @missing,"Mail::Sendmail" };
835 unless (eval {require PDF::API2}) { push @missing,"PDF::API2" };
836 # The following modules are not mandatory, depends on how the library want to use Koha
837 unless (eval {require Net::LDAP}) {
838 if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
839 push @missing, "Net::LDAP";
842 unless (eval {require Event}) {
843 if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
844 push @missing, "Event";
847 unless (eval {require Net::Z3950}) {
848 showmessage(getmessage('NETZ3950Missing'), 'PressEnter', '', 1);
849 if ($#missing>=0) { # see above note
850 push @missing, "Net::Z3950";
855 # Print out a list of any missing modules
860 if (POSIX::setlocale(LC_ALL) ne "C") {
861 $missing.=" export LC_ALL=C\n";
863 foreach my $module (@missing) {
864 $missing.=" perl -MCPAN -e 'install \"$module\"'\n";
866 my $message=getmessage('MissingPerlModules', [$missing]);
867 showmessage($message, 'none');
871 showmessage(getmessage('AllPerlModulesInstalled'), 'PressEnter', '', 1) unless $auto_install->{NoPressEnter};
876 unless (-x "/usr/bin/perl") {
877 my $realperl=`which perl`;
879 $realperl = showmessage(getmessage('NoUsrBinPerl'), 'none');
880 until (-x $realperl) {
881 $realperl=showmessage(getmessage('AskLocationOfPerlExecutable', $realperl), 'free', $realperl, 1);
883 my $response=showmessage(getmessage('ConfirmPerlExecutableSymlink', $realperl), 'yn', 'y', 1);
884 unless ($response eq 'n') {
886 system("ln -s $realperl /usr/bin/perl");
893 $messages->{'NoUsrBinPerl'}->{en} =
894 heading('No /usr/bin/perl') . qq|
895 Koha expects to find the perl executable in the /usr/bin
896 directory. It is not there on your system.
900 $messages->{'AskLocationOfPerlExecutable'}->{en}=qq|Location of Perl Executable [%s]: |;
901 $messages->{'ConfirmPerlExecutableSymlink'}->{en}=qq|
902 Some Koha scripts will _not_ work without a symlink from %s to /usr/bin/perl
904 Most users should answer Y here.
906 May I try to create this symlink? ([Y]/N):|;
908 $messages->{'DirFailed'}->{en} = RED.qq|
909 We could not create %s, but continuing anyway...
915 =item getinstallationdirectories
917 getinstallationdirectories;
919 Get the various installation directories from the user, and then
920 create those directories (if they do not already exist).
922 These pieces of information are saved to global variables; the
923 function does not return any values.
927 sub getinstallationdirectories {
928 my ($auto_install) = @_;
929 if (!$ENV{prefix}) { $ENV{prefix} = "/usr/local"; } #"
930 $opacdir = $ENV{prefix}.'/koha/opac';
931 $intranetdir = $ENV{prefix}.'/koha/intranet';
933 while ($getdirinfo) {
934 # Loop until opac directory and koha directory are different
936 if ($auto_install->{GetOpacDir}) {
937 $opacdir=$auto_install->{GetOpacDir};
938 print ON_YELLOW.BLACK."auto-setting OpacDir to : $opacdir".RESET."\n";
940 $message=getmessage('GetOpacDir', [$opacdir]);
941 $opacdir=showmessage($message, 'free', $opacdir);
943 if ($auto_install->{GetIntranetDir}) {
944 $intranetdir=$auto_install->{GetIntranetDir};
945 print ON_YELLOW.BLACK."auto-setting IntranetDir to : $intranetdir".RESET."\n";
947 $message=getmessage('GetIntranetDir', [$intranetdir]);
948 $intranetdir=showmessage($message, 'free', $intranetdir);
950 if ($intranetdir eq $opacdir) {
953 You must specify different directories for the OPAC and INTRANET files!
954 :: $intranetdir :: $opacdir ::
961 $kohalogdir=$ENV{prefix}.'/koha/log';
962 if ($auto_install->{GetOpacDir}) {
963 $kohalogdir=$auto_install->{KohaLogDir};
964 print ON_YELLOW.BLACK."auto-setting log dir to : $kohalogdir".RESET."\n";
966 my $message=getmessage('GetKohaLogDir', [$kohalogdir]);
967 $kohalogdir=showmessage($message, 'free', $kohalogdir);
971 # FIXME: Need better error handling for all mkdir calls here
972 unless ( -d $intranetdir ) {
973 mkdir_parents (dirname($intranetdir), 0775) || print getmessage('DirFailed',['parents of '.$intranetdir]);
974 mkdir ($intranetdir, 0770) || print getmessage('DirFailed',[$intranetdir]);
975 if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2], "$intranetdir"); }
976 chmod 0770, "$intranetdir";
978 mkdir_parents ("$intranetdir/htdocs", 0750);
979 mkdir_parents ("$intranetdir/cgi-bin", 0750);
980 mkdir_parents ("$intranetdir/modules", 0750);
981 mkdir_parents ("$intranetdir/scripts", 0750);
982 unless ( -d $opacdir ) {
983 mkdir_parents (dirname($opacdir), 0775) || print getmessage('DirFailed',['parents of '.$opacdir]);
984 mkdir ($opacdir, 0770) || print getmessage('DirFailed',[$opacdir]);
985 if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2], "$opacdir"); }
986 chmod (oct(770), "$opacdir");
988 mkdir_parents ("$opacdir/htdocs", 0750);
989 mkdir_parents ("$opacdir/cgi-bin", 0750);
992 unless ( -d $kohalogdir ) {
993 mkdir_parents (dirname($kohalogdir), 0775) || print getmessage('DirFailed',['parents of '.$kohalogdir]);
994 mkdir ($kohalogdir, 0770) || print getmessage('DirFailed',[$kohalogdir]);
995 if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2,3], "$kohalogdir"); }
996 chmod (oct(770), "$kohalogdir");
1004 Get the MySQL database server installation directory, automatically if possible.
1008 $messages->{'WhereIsMySQL'}->{en} = heading('MYSQL LOCATION').qq|
1009 Koha can't find the MySQL command-line tools. If you installed a MySQL package, you may need to install an additional package containing mysqladmin.
1010 If you compiled mysql yourself,
1011 please give the value of --prefix when you ran configure.
1012 The file mysqladmin should be in bin/mysqladmin under the directory that you give here.
1014 MySQL installation directory: |;
1017 foreach my $mysql (qw(/usr/local/mysql
1022 if ( -d $mysql && -f "$mysql/bin/mysqladmin") { #"
1028 $mysqldir = showmessage(getmessage('WhereIsMySQL'),'free');
1029 last if -f "$mysqldir/bin/mysqladmin";
1035 =item getdatabaseinfo
1039 Get various pieces of information related to the Koha database:
1040 the name of the database, the host on which the SQL server is
1041 running, and the database user name.
1043 These pieces of information are saved to global variables; the
1044 function does not return any values.
1048 $messages->{'DatabaseName'}->{en} = heading('Database Name') . qq|
1049 Please provide the name that you wish to give your koha database.
1050 It must not exist already on the database server.
1052 Most users give a short single-word name for their library here.
1054 Database name [%s]: |;
1056 $messages->{'DatabaseHost'}->{en} = heading('Database Host') . qq|
1057 Please provide the mysql server name. Unless the database is stored on
1058 another machine, this should be "localhost".
1060 Database host [%s]: |;
1062 $messages->{'DatabaseUser'}->{en} = heading('Database User') . qq|
1063 We are going to create a new mysql user for Koha. This user will have full administrative rights
1064 to the database called %s when they connect from %s.
1065 This is also the name of the Koha librarian superuser.
1067 Most users give a single-word name here.
1069 Database user [%s]: |;
1071 $messages->{'DatabasePassword'}->{en} = heading('Database Password') . qq|
1072 Please provide a good password for the user %s.
1074 IMPORTANT: You can log in using this user and password at any time.
1076 Password for database user %s: |;
1078 $messages->{'BlankPassword'}->{en} = heading('BLANK PASSWORD') . qq|
1079 You must not use a blank password for your MySQL user.
1081 Press <ENTER> to try again:
1084 sub getdatabaseinfo {
1085 my ($auto_install) = @_;
1087 $hostname = 'localhost';
1088 $user = 'kohaadmin';
1091 #Get the database name
1094 if ($auto_install->{database}) {
1095 $database=$auto_install->{database};
1096 print ON_YELLOW.BLACK."auto-setting database to : $database".RESET."\n";
1098 $message=getmessage('DatabaseName', [$database]);
1099 $database=showmessage($message, 'free', $database);
1101 #Get the hostname for the database
1103 if ($auto_install->{DatabaseHost}) {
1104 $hostname=$auto_install->{DatabaseHost};
1105 print ON_YELLOW.BLACK."auto-setting database host to : $hostname".RESET."\n";
1107 $message=getmessage('DatabaseHost', [$hostname]);
1108 $hostname=showmessage($message, 'free', $hostname);
1110 #Get the username for the database
1112 if ($auto_install->{DatabaseUser}) {
1113 $user=$auto_install->{DatabaseUser};
1114 print ON_YELLOW.BLACK."auto-setting DB user to : $user".RESET."\n";
1116 $message=getmessage('DatabaseUser', [$database, $hostname, $user]);
1117 $user=showmessage($message, 'free', $user);
1119 #Get the password for the database user
1121 while ($pass eq '') {
1122 my $message=getmessage('DatabasePassword', [$user, $user]);
1123 if ($auto_install->{DatabasePassword}) {
1124 $pass=$auto_install->{DatabasePassword};
1125 print ON_YELLOW.BLACK."auto-setting database password to : $pass".RESET."\n";
1127 $pass=showmessage($message, 'free', $pass);
1130 my $message=getmessage('BlankPassword');
1131 showmessage($message,'PressEnter');
1142 Get various pieces of information related to the Apache server:
1143 the location of the configuration file and, if needed, the Unix
1144 user that the Koha CGI will be run under.
1146 These pieces of information are saved to global variables; the
1147 function does not return any values.
1151 $messages->{'FoundMultipleApacheConfFiles'}->{en} =
1152 heading('MULTIPLE APACHE CONFIG FILES FOUND') . qq|
1153 I found more than one possible Apache configuration file:
1157 Enter number of the file to read [1]: |;
1159 $messages->{'NoApacheConfFiles'}->{en} =
1160 heading('NO APACHE CONFIG FILE FOUND') . qq|
1161 I was not able to find your Apache configuration file.
1163 The file is usually called httpd.conf, apache.conf or similar.
1165 Please enter the full name, starting with /: |;
1167 $messages->{'NotAFile'}->{en} = heading('FILE DOES NOT EXIST') . qq|
1168 The file %s does not exist.
1170 Please press <ENTER> to continue: |;
1172 $messages->{'EnterApacheUser'}->{en} = heading('NEED APACHE USER') . qq\
1173 The installer could not find the User setting in the Apache configuration file.
1174 This is used to set up access permissions for
1175 %s/koha.conf. This user should be set in one of the Apache configuration.
1176 Please try to find it and enter the user name below. You might find
1177 that "ps u|grep apache" will tell you. It probably is NOT "root".
1179 Enter the Apache userid: \;
1181 $messages->{'InvalidUserid'}->{en} = heading('INVALID USER') . qq|
1182 The userid %s is not a valid userid on this system.
1184 Press <ENTER> to continue: |;
1187 my ($auto_install) = @_;
1188 my @confpossibilities;
1190 foreach my $httpdconf (qw(/usr/local/apache/conf/httpd.conf
1191 /usr/local/etc/apache/httpd.conf
1192 /usr/local/etc/apache/apache.conf
1193 /var/www/conf/httpd.conf
1194 /etc/apache2/httpd.conf
1195 /etc/apache2/apache2.conf
1196 /etc/apache/conf/httpd.conf
1197 /etc/apache/conf/apache.conf
1198 /etc/apache/httpd.conf
1199 /etc/apache-ssl/conf/apache.conf
1200 /etc/apache-ssl/httpd.conf
1201 /etc/httpd/conf/httpd.conf
1202 /etc/httpd/httpd.conf
1203 /etc/httpd/2.0/conf/httpd2.conf
1205 if ( -f $httpdconf ) {
1206 push @confpossibilities, $httpdconf;
1210 if ($#confpossibilities==-1) {
1211 my $message=getmessage('NoApacheConfFiles');
1214 until (-f $realhttpdconf) {
1215 $choice=showmessage($message, "free", 1);
1217 $realhttpdconf=$choice;
1219 showmessage(getmessage('NotAFile', [$choice]),'PressEnter', '', 1);
1222 } elsif ($#confpossibilities>0) {
1226 foreach (@confpossibilities) {
1227 $conffiles.=" $counter: $_\n";
1228 $options.="$counter";
1231 my $message=getmessage('FoundMultipleApacheConfFiles', [$conffiles]);
1232 my $choice=showmessage($message, "restrictchar $options", 1);
1233 $realhttpdconf=$confpossibilities[$choice-1];
1235 $realhttpdconf=$confpossibilities[0];
1237 unless (open (HTTPDCONF, "<$realhttpdconf")) {
1238 warn RED."Insufficient privileges to open $realhttpdconf for reading.\n";
1242 while (<HTTPDCONF>) {
1243 if (/^\s*User\s+"?([-\w]+)"?\s*$/) {
1249 unless (defined($httpduser)) {
1251 if ($auto_install->{EnterApacheUser}) {
1252 $message = $auto_install->{EnterApacheUser};
1253 print ON_YELLOW.BLACK."auto-setting Apache User to : $message".RESET."\n";
1255 $message=getmessage('EnterApacheUser', [$etcdir]);
1257 until (defined($httpduser) && length($httpduser) && getpwnam($httpduser)) {
1258 if ($auto_install->{EnterApacheUser}) {
1259 $httpduser = $auto_install->{EnterApacheUser};
1261 $httpduser=showmessage($message, "free", '');
1263 if (length($httpduser)>0) {
1264 unless (getpwnam($httpduser)) {
1265 my $message=getmessage('InvalidUserid', [$httpduser]);
1266 showmessage($message,'PressEnter');
1275 =item getapachevhostinfo
1279 Gets various pieces of information related to virtual hosting:
1280 the webmaster email address, virtual hostname, and the ports
1281 that the OPAC and INTRANET modules run on.
1283 These pieces of information are saved to global variables; the
1284 function does not return any values.
1288 $messages->{'ApacheConfigIntroduction'}->{en} =
1289 heading('APACHE CONFIGURATION') . qq|
1290 Koha needs to write an Apache configuration file for the
1291 OPAC and Librarian sites. By default this installer
1292 will do this by using one name and two different ports
1293 for the virtual hosts. There are other ways to set this up,
1294 and the installer will leave comments in
1295 %s/koha-httpd.conf about them.
1297 NOTE: You will need to add lines to your main httpd.conf to
1298 include %s/koha-httpd.conf
1299 and to make sure it is listening on the right ports
1300 (using the Listen directive).
1302 Press <ENTER> to continue: |;
1304 $messages->{'GetVirtualHostEmail'}->{en} =
1305 heading('WEB E-MAIL CONTACT') . qq|
1306 Enter the e-mail address to be used as a contact for Koha. This
1307 address is displayed if fatal errors are encountered.
1309 E-mail contact [%s]: |;
1311 $messages->{'GetServerName'}->{en} =
1312 heading('WEB HOST NAME OR IP ADDRESS') . qq|
1313 Please enter the host name or IP address that you wish to use for koha.
1314 Normally, this should be a name or IP that belongs to this machine.
1316 Host name or IP Address [%s]: |;
1318 $messages->{'GetOpacPort'}->{en} = heading('OPAC PORT') . qq|
1319 Please enter the port for your OPAC interface. This defaults to port 80, but
1320 if you are already serving web content with this hostname, you should change it
1321 to a different port (8000 might be a good choice, but check any firewalls).
1323 Enter the OPAC Port [%s]: |;
1325 $messages->{'GetIntranetPort'}->{en} =
1326 heading('LIBRARIAN PORT') . qq|
1327 Please enter the port for your Librarian interface. This must be different from
1330 Enter the Intranet Port [%s]: |;
1333 sub getapachevhostinfo {
1334 my ($auto_install) = @_;
1335 $svr_admin = "webmaster\@$domainname";
1336 $servername=`hostname`;
1341 if ($auto_install->{GetVirtualHostEmail}) {
1342 $svr_admin=$auto_install->{GetVirtualHostEmail};
1343 print ON_YELLOW.BLACK."auto-setting VirtualHostEmail to : $svr_admin".RESET."\n";
1345 showmessage(getmessage('ApacheConfigIntroduction',[$etcdir,$etcdir]), 'PressEnter');
1346 $svr_admin=showmessage(getmessage('GetVirtualHostEmail', [$svr_admin]), 'email', $svr_admin);
1348 if ($auto_install->{servername}) {
1349 $servername=$auto_install->{servername};
1350 print ON_YELLOW.BLACK."auto-setting server name to : $servername".RESET."\n";
1352 $servername=showmessage(getmessage('GetServerName', [$servername]), 'free', $servername);
1354 if ($auto_install->{opacport}) {
1355 $opacport=$auto_install->{opacport};
1356 print ON_YELLOW.BLACK."auto-setting opac port to : $opacport".RESET."\n";
1358 $opacport=showmessage(getmessage('GetOpacPort', [$opacport]), 'numerical', $opacport);
1360 if ($auto_install->{intranetport}) {
1361 $intranetport=$auto_install->{intranetport};
1362 print ON_YELLOW.BLACK."auto-setting intranet port to : $intranetport".RESET."\n";
1364 $intranetport=showmessage(getmessage('GetIntranetPort', [$opacport, $intranetport]), 'numerical', $intranetport);
1370 =item updateapacheconf
1374 Updates the Apache config file according to parameters previously
1375 specified by the user.
1377 It will append fully-commented directives at the end of the original
1378 Apache config file. The old config file is renamed with an extension
1381 If you need to uninstall Koha for any reason, the lines between
1383 # Ports to listen to for Koha
1385 and the block of comments beginning with
1387 # If you want to use name based Virtual Hosting:
1393 $messages->{'StartUpdateApache'}->{en} =
1394 heading('UPDATING APACHE CONFIGURATION') . qq|
1395 Checking for modules that need to be loaded...
1398 $messages->{'ApacheConfigMissingModules'}->{en} =
1399 heading('APACHE CONFIGURATION NEEDS UPDATE') . qq|
1400 Koha uses the mod_env and mod_include apache features, but the
1401 installer did not find them in your config. Please
1402 make sure that they are enabled for your Koha site.
1404 Press <ENTER> to continue: |;
1407 $messages->{'ApacheAlreadyConfigured'}->{en} =
1408 heading('APACHE ALREADY CONFIGURED') . qq|
1409 %s appears to already have an entry for Koha. You may need to edit %s
1410 if anything has changed since it was last set up. This
1411 script will not attempt to modify an existing Koha apache
1414 Press <ENTER> to continue: |;
1416 sub updateapacheconf {
1417 my ($auto_install)=@_;
1418 my $logfiledir=$kohalogdir;
1419 my $httpdconf = $etcdir."/koha-httpd.conf";
1421 showmessage(getmessage('StartUpdateApache'), 'none') unless $auto_install->{NoPressEnter};
1422 # to be polite about it: I don't think this should touch the main httpd.conf
1424 # QUESTION: Should we warn for includes_module too?
1426 my $includesmodule=0;
1427 open HC, "<$realhttpdconf";
1429 if (/^\s*#\s*LoadModule env_module /) {
1430 showmessage(getmessage('ApacheConfigMissingModules'));
1433 if (/\s*LoadModule includes_module / ) {
1439 if (`grep -q 'VirtualHost $servername' "$httpdconf" 2>/dev/null`) {
1440 showmessage(getmessage('ApacheAlreadyConfigured', [$httpdconf, $httpdconf]), 'PressEnter');
1443 my $includesdirectives='';
1444 if ($includesmodule) {
1445 $includesdirectives.="Options +Includes\n";
1446 $includesdirectives.=" AddHandler server-parsed .html\n";
1448 open(SITE,">$httpdconf") or warn "Insufficient priveleges to open $httpdconf for writing.\n";
1449 my $opaclisten = '';
1450 if ($opacport != 80) {
1451 $opaclisten="Listen $opacport";
1453 my $intranetlisten = '';
1454 if ($intranetport != 80) {
1455 $intranetlisten="Listen $intranetport";
1459 # Ports to listen to for Koha
1460 # uncomment these if they aren't already in main httpd.conf
1464 # NameVirtualHost is used by one of the optional configurations detailed below
1466 #NameVirtualHost 11.22.33.44
1468 # KOHA's OPAC Configuration
1469 <VirtualHost $servername\:$opacport>
1470 ServerAdmin $svr_admin
1471 DocumentRoot $opacdir/htdocs
1472 ServerName $servername
1473 ScriptAlias /cgi-bin/koha/ $opacdir/cgi-bin/
1474 ErrorLog $logfiledir/opac-error_log
1475 TransferLog $logfiledir/opac-access_log
1476 SetEnv PERL5LIB "$intranetdir/modules"
1477 SetEnv KOHA_CONF "$etcdir/koha.conf"
1481 # KOHA's INTRANET Configuration
1482 <VirtualHost $servername\:$intranetport>
1483 ServerAdmin $svr_admin
1484 DocumentRoot $intranetdir/htdocs
1485 ServerName $servername
1486 ScriptAlias /cgi-bin/koha/ "$intranetdir/cgi-bin/"
1487 ErrorLog $logfiledir/koha-error_log
1488 TransferLog $logfiledir/koha-access_log
1489 SetEnv PERL5LIB "$intranetdir/modules"
1490 SetEnv KOHA_CONF "$etcdir/koha.conf"
1494 # If you want to use name based Virtual Hosting:
1495 # 1. remove the two Listen lines
1496 # 2. replace $servername\:$opacport wih your.opac.domain.name
1497 # 3. replace ServerName $servername wih ServerName your.opac.domain.name
1498 # 4. replace $servername\:$intranetport wih your intranet domain name
1499 # 5. replace ServerName $servername wih ServerName your.intranet.domain.name
1501 # If you want to use NameVirtualHost'ing (using two names on one ip address):
1502 # 1. Follow steps 1-5 above
1503 # 2. Uncomment the NameVirtualHost line and set the correct ip address
1512 =item basicauthentication
1514 basicauthentication;
1516 Asks the user whether HTTP basic authentication is wanted, and,
1517 if so, the user name and password for the basic authentication.
1519 These pieces of information are saved to global variables; the
1520 function does not return any values.
1524 # $messages->{'IntranetAuthenticationQuestion'}->{en} =
1525 # heading('LIBRARIAN AUTHENTICATION') . qq|
1526 # The Librarian site can be password protected using
1527 # Apache's Basic Authorization instead of Koha user details.
1529 # This method going to be phased out very soon. Most users should answer N here.
1531 # Would you like to do this (Y/[N]): |; #'
1533 # $messages->{'BasicAuthUsername'}->{en}="Please enter a username for librarian access [%s]: ";
1534 # $messages->{'BasicAuthPassword'}->{en}="Please enter a password for %s: ";
1535 # $messages->{'BasicAuthPasswordWasBlank'}->{en}="\nYou cannot use a blank password!\n\n";
1537 # sub basicauthentication {
1538 # my $message=getmessage('IntranetAuthenticationQuestion');
1539 # my $answer=showmessage($message, 'yn', 'n');
1540 # my $httpdconf = $etcdir."/koha-httpd.conf";
1542 # my $apacheauthusername='librarian';
1543 # my $apacheauthpassword='';
1544 # if ($answer=~/^y/i) {
1545 # ($apacheauthusername) = showmessage(getmessage('BasicAuthUsername', [ $apacheauthusername]), 'free', $apacheauthusername, 1);
1546 # $apacheauthusername=~s/[^a-zA-Z0-9]//g;
1547 # while (! $apacheauthpassword) {
1548 # ($apacheauthpassword) = showmessage(getmessage('BasicAuthPassword', [ $apacheauthusername]), 'free', 1);
1549 # if (!$apacheauthpassword) {
1550 # ($apacheauthpassword) = showmessage(getmessage('BasicAuthPasswordWasBlank'), 'none', '', 1);
1553 # open AUTH, ">$etcdir/kohaintranet.pass";
1554 # my $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
1555 # my $salt=substr($chars, int(rand(length($chars))),1);
1556 # $salt.=substr($chars, int(rand(length($chars))),1);
1557 # print AUTH $apacheauthusername.":".crypt($apacheauthpassword, $salt)."\n";
1559 # open(SITE,">>$httpdconf") or warn "Insufficient priveleges to open $realhttpdconf for writing.\n";
1562 # <Directory $intranetdir>
1563 # AuthUserFile $etcdir/kohaintranet.pass
1565 # AuthName "Koha Intranet (for librarians only)"
1566 # Require valid-user
1578 Install the Koha files to the specified OPAC and INTRANET
1579 directories (usually in /usr/local/koha).
1581 The koha.conf file is created, but as koha.conf.tmp. The
1582 caller is responsible for calling finalizeconfigfile when
1583 installation is completed, to rename it back to koha.conf.
1587 $messages->{'InstallFiles'}->{en} = heading('INSTALLING FILES') . qq|
1588 Copying files to installation directories:
1592 $messages->{'OldFiles'}->{en} = heading('OLD FILES') . qq|
1593 Any files from the previous edition of Koha have been
1594 copied to a dated backup directory alongside the new
1595 installation. You should move any custom files that you
1596 want to keep (such as your site templates) into the new
1597 directories and then move the backup off of the live
1600 Press ENTER to continue:|;
1603 $messages->{'CopyingFiles'}->{en}="Copying %s to %s.\n";
1609 my ($auto_install) = @_;
1610 #MJR: preserve old files, just in case
1616 print getmessage('CopyingFiles', ["old ".$desc,$tgt.strftime("%Y%m%d%H%M",localtime())]) unless ($auto_install->{NoPressEnter});
1618 system("mv ".$tgt." ".$tgt.strftime("%Y%m%d%H%M",localtime()));
1620 print getmessage('CopyingFiles', [$desc,$tgt]) unless ($auto_install->{NoPressEnter});
1622 system("cp -R ".$src." ".$tgt);
1625 # my ($auto_install) = @_;
1626 showmessage(getmessage('InstallFiles'),'none') unless ($auto_install->{NoPressEnter});
1628 neatcopy("admin templates", 'intranet-html', "$intranetdir/htdocs");
1629 neatcopy("admin interface", 'intranet-cgi', "$intranetdir/cgi-bin");
1630 neatcopy("main scripts", 'scripts', "$intranetdir/scripts");
1631 neatcopy("perl modules", 'modules', "$intranetdir/modules");
1632 neatcopy("OPAC templates", 'opac-html', "$opacdir/htdocs");
1633 neatcopy("OPAC interface", 'opac-cgi', "$opacdir/cgi-bin");
1635 system("touch $opacdir/cgi-bin/opac");
1637 #MJR: is this necessary?
1639 system("chown -R $httpduser:$httpduser $opacdir $intranetdir");
1641 system("chmod -R a+rx $opacdir $intranetdir");
1643 # Create /etc/koha.conf
1645 my $old_umask = umask(027); # make sure koha.conf is never world-readable
1646 open(SITES,">$etcdir/koha.conf.tmp") or warn "Couldn't create file at $etcdir. Must have write capability.\n";
1652 intranetdir=$intranetdir
1654 kohalogdir=$kohalogdir
1655 kohaversion=$newversion
1656 httpduser=$httpduser
1657 intrahtdocs=$intranetdir/htdocs/intranet-tmpl
1658 opachtdocs=$opacdir/htdocs/opac-tmpl
1664 #MJR: can't help but this be broken, can we?
1665 chmod 0440, "$etcdir/koha.conf.tmp";
1667 #MJR: does this contain any passwords?
1668 chmod 0755, "$intranetdir/scripts/z3950daemon/z3950-daemon-launch.sh", "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh", "$intranetdir/scripts/z3950daemon/processz3950queue";
1670 #MJR: generate our own settings, to remove the /home/paul hardwired links
1671 open(FILE,">$intranetdir/scripts/z3950daemon/z3950-daemon-options");
1672 print FILE "RunAsUser=$httpduser\nKohaZ3950Dir=$intranetdir/scripts/z3950daemon\nKohaModuleDir=$intranetdir/modules\nLogDir=$kohalogdir\nKohaConf=$etcdir/koha.conf";
1676 chown((getpwnam($httpduser)) [2,3], "$etcdir/koha.conf.tmp") or warn "can't chown koha.conf: $!";
1677 chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh") or warn "can't chown $intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh: $!";
1678 chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/processz3950queue") or warn "can't chown $intranetdir/scripts/z3950daemon/processz3950queue: $!";
1679 } #MJR: report that we haven't chown()d.
1681 print "Please check permissions in $intranetdir/scripts/z3950daemon\n";
1683 showmessage(getmessage('OldFiles'),'PressEnter') unless $auto_install->{NoPressEnter};
1691 Finds out where the MySQL utitlities are located in the system,
1692 then create the Koha database structure and MySQL permissions.
1696 $messages->{'MysqlRootPassword'}->{en} =
1697 heading('MYSQL ROOT USER PASSWORD') . qq|
1698 To create the koha database, please enter your
1699 mysql server's root user password:
1703 $messages->{'CreatingDatabase'}->{en} = heading('CREATING DATABASE') . qq|
1704 Creating the MySQL database for Koha...
1708 $messages->{'CreatingDatabaseError'}->{en} =
1709 heading('ERROR CREATING DATABASE') . qq|
1710 Couldn't connect to the MySQL server for the reason given above.
1711 This is a serious problem, the database will not get installed.
1713 Press <ENTER> to continue: |; #'
1715 $messages->{'SampleData'}->{en} = heading('SAMPLE DATA') . qq|
1716 If you are installing Koha for evaluation purposes,
1717 you can install some sample data now.
1719 If you are installing Koha to use your own
1720 data, you probably don't want this sample data installed.
1722 Would you like to install the sample data? Y/[N]: |; #'
1724 $messages->{'SampleDataInstalled'}->{en} =
1725 heading('SAMPLE DATA INSTALLED') . qq|
1726 Sample data has been installed. For some suggestions on testing Koha, please
1727 read the file doc/HOWTO-Testing. If you find any bugs, please submit them at
1728 http://bugs.koha.org/. If you need help with testing Koha, you can post a
1729 question through the koha-devel mailing list, or you can check for a developer
1730 online at irc.katipo.co.nz:6667 channel #koha.
1732 You can find instructions for subscribing to the Koha mailing lists at:
1737 Press <ENTER> to continue: |;
1739 $messages->{'AddBranchPrinter'}->{en} = heading('Add Branch and Printer') . qq|
1740 Would you like to describe an initial branch and printer? [Y]/N: |;
1742 $messages->{'BranchName'}->{en}="Branch Name [%s]: ";
1743 $messages->{'BranchCode'}->{en}="Branch Code (4 letters or numbers) [%s]: ";
1744 $messages->{'PrinterQueue'}->{en}="Printer Queue [%s]: ";
1745 $messages->{'PrinterName'}->{en}="Printer Name [%s]: ";
1748 my ($auto_install) = @_;
1749 $mysqluser = 'root';
1751 my $mysqldir = getmysqldir();
1753 if ($auto_install->{MysqlRootPassword}) {
1754 $mysqlpass=$auto_install->{MysqlRootPassword};
1756 # we must not put the mysql root password on the command line
1757 $mysqlpass= showmessage(getmessage('MysqlRootPassword'),'silentfree');
1760 showmessage(getmessage('CreatingDatabase'),'none') unless ($auto_install->{NoPressEnter});
1762 setmysqlclipass($mysqlpass);
1763 # Set up permissions
1765 print system("$mysqldir/bin/mysql -u$mysqluser mysql -e \"insert into user (Host,User,Password) values ('$hostname','$user',password('$pass'))\"\;");#"
1766 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')\"");
1767 system("$mysqldir/bin/mysqladmin -u$mysqluser reload");
1768 # Change to admin user login
1769 setmysqlclipass($pass);
1770 my $result=system("$mysqldir/bin/mysqladmin", "-u$user", "create", "$database");
1772 showmessage(getmessage('CreatingDatabaseError'),'PressEnter', '', 1);
1774 # Create the database structure
1776 system("$mysqldir/bin/mysql -u$user $database < koha.mysql");
1782 =item updatedatabase
1786 Updates the Koha database structure, including the addition of
1789 The MARC tables are also populated in addition to being created.
1791 Because updatedatabase calls scripts/updater/updatedatabase to
1792 do the actual update, and that script uses C4::Context,
1793 $etcdir/koha.conf must exist at this point. We use the KOHA_CONF
1794 environment variable to do this.
1796 FIXME: (See checkabortedinstall as it depends on old symlink way.)
1800 $messages->{'UpdateMarcTables'}->{en} =
1801 heading('MARC FIELD DEFINITIONS') . qq|
1802 You can import MARC settings for:
1808 NOTE: If you choose N,
1809 nothing will be added, and you must create them all yourself.
1810 Only choose N if you want to use a MARC format not listed here,
1811 such as DANMARC. We would like to hear from you if you do.
1813 UPDATE : If you UPDATE your version from a previous 2.x.x, the right choice here is N (None) to preserve your local MARC setup.
1815 Choose MARC definition [1]: |;
1817 $messages->{'Language'}->{en} = heading('CHOOSE LANGUAGE') . qq|
1818 This version of koha supports a few languages.
1820 en : default language, all pages available
1821 fr : complete translation (except pictures)
1822 es : partial librarian site translation (including pictures)
1823 pl : complete OPAC and partial librarian translation
1824 zh_TW : partial translation
1826 en is used when a screen is not available in your language
1828 If you specify a language here, you can still
1829 change it from the system preferences screen in the librarian sit.
1831 Which language do you choose? |;
1833 sub updatedatabase {
1834 my ($auto_install) = @_;
1835 # At this point, $etcdir/koha.conf must exist, for C4::Context
1836 $ENV{"KOHA_CONF"}=$etcdir.'/koha.conf';
1837 if (! -e $ENV{"KOHA_CONF"}) { $ENV{"KOHA_CONF"}=$etcdir.'/koha.conf.tmp'; }
1839 my $result=system ("perl -I $intranetdir/modules scripts/updater/updatedatabase -s");
1842 print "Problem updating database...\n";
1846 if ($auto_install->{UpdateMarcTables}) {
1847 $response=$auto_install->{UpdateMarcTables};
1848 print ON_YELLOW.BLACK."auto-setting UpdateMarcTable to : $response".RESET."\n";
1850 $response=showmessage(getmessage('UpdateMarcTables'), 'restrictchar 12N', '1');
1853 if ($response eq '1') {
1854 system("cat scripts/misc/marc_datas/marc21_en/structure_def.sql | $mysqldir/bin/mysql -u$user $database");
1855 system("cat scripts/misc/lang-datas/en/stopwords.sql | $mysqldir/bin/mysql -u$user $database");
1857 if ($response eq '2') {
1858 system("cat scripts/misc/marc_datas/unimarc_fr/structure_def.sql | $mysqldir/bin/mysql -u$user $database");
1859 system("cat scripts/misc/lang-datas/fr/stopwords.sql | $mysqldir/bin/mysql -u$user $database");
1861 delete($ENV{"KOHA_CONF"});
1863 print RESET."\nFinished updating of database. Press <ENTER> to continue..." unless ($auto_install->{NoPressEnter});
1864 <STDIN> unless ($auto_install->{NoPressEnter});
1868 =item populatedatabase
1872 Populate the non-MARC tables. If the user wants to install the
1873 sample data, install them.
1877 $messages->{'ConfirmFileUpload'}->{en} = qq|
1878 Confirm loading of this file into Koha [Y]/N: |;
1880 sub populatedatabase {
1881 my ($auto_install) = @_;
1885 if ($auto_install->{BranchName}) {
1886 $branch=$auto_install->{BranchName};
1887 print ON_YELLOW.BLACK."auto-setting a branch : $branch".RESET."\n";
1889 $response=showmessage(getmessage('AddBranchPrinter'), 'yn', 'y');
1890 unless ($response =~/^n/i) {
1891 $branch=showmessage(getmessage('BranchName', [$branch]), 'free', $branch, 1);
1892 $branch=~s/[^A-Za-z0-9\s]//g;
1896 my $branchcode=$branch;
1897 $branchcode=~s/[^A-Za-z0-9]//g;
1898 $branchcode=uc($branchcode);
1899 $branchcode=substr($branchcode,0,4);
1900 if ($auto_install->{BranchCode}) {
1901 $branchcode=$auto_install->{BranchCode};
1902 print ON_YELLOW.BLACK."auto-setting branch code : $branchcode".RESET."\n";
1904 $branchcode=showmessage(getmessage('BranchCode', [$branchcode]), 'free', $branchcode, 1);
1906 $branchcode=~s/[^A-Za-z0-9]//g;
1907 $branchcode=uc($branchcode);
1908 $branchcode=substr($branchcode,0,4);
1909 $branchcode or $branchcode='DEF';
1912 system("$mysqldir/bin/mysql -u$user $database -e \"insert into branches (branchcode,branchname,issuing) values ('$branchcode', '$branch', 1)\"");
1913 system("$mysqldir/bin/mysql -u$user $database -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1914 system("$mysqldir/bin/mysql -u$user $database -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1918 if ($auto_install->{PrinterName}) {
1919 $printername=$auto_install->{PrinterName};
1920 print ON_YELLOW.BLACK."auto-setting a printer : $printername".RESET."\n";
1922 $printername=showmessage(getmessage('PrinterName', [$printername]), 'free', $printername, 1);
1923 $printername=~s/[^A-Za-z0-9\s]//g;
1925 if ($auto_install->{PrinterQueue}) {
1926 $printerqueue=$auto_install->{PrinterQueue};
1927 print ON_YELLOW.BLACK."auto-setting printer queue to : $printerqueue".RESET."\n";
1929 $printerqueue=showmessage(getmessage('PrinterQueue', [$printerqueue]), 'free', $printerqueue, 1);
1930 $printerqueue=~s/[^A-Za-z0-9]//g;
1933 system("$mysqldir/bin/mysql -u$user $database -e \"insert into printers (printername,printqueue,printtype) values ('$printername', '$printerqueue', '')\"");
1936 if ($auto_install->{Language}) {
1937 $language=$auto_install->{Language};
1938 print ON_YELLOW.BLACK."auto-setting language to : $language".RESET."\n";
1940 $language=showmessage(getmessage('Language'), 'free', 'en');
1943 system("$mysqldir/bin/mysql -u$user $database -e \"update systempreferences set value='$language' where variable='opaclanguages'\"");
1945 if (-d "scripts/misc/sql-datas") {
1946 # ask for directory to look for files to append
1948 push @directories,"FINISHED";
1949 if (-d "scripts/misc/sql-datas") {
1950 opendir D, "scripts/misc/sql-datas";
1951 foreach my $dir (readdir D) {
1952 next if ($dir =~ /^\./);
1953 push @directories, $dir;
1957 while (not $loopend) {
1958 print heading("SELECT SQL DIRECTORY");
1960 Select a directory. You will see every file included in this directory and be able to choose file(s) to import into Koha
1961 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.
1964 for (my $i=0;$i<=$#directories;$i++) {
1965 print "$i => ".$directories[$i]."\n";
1967 my $sqluploaddir =<STDIN>;
1968 if ($sqluploaddir==0) {
1971 $sqluploaddir = $directories[$sqluploaddir];
1972 # CHECK for any other file to append...
1974 push @sql,"FINISHED";
1975 if (-d "scripts/misc/sql-datas/$sqluploaddir") {
1976 opendir D, "scripts/misc/sql-datas/$sqluploaddir";
1977 foreach my $sql (readdir D) {
1978 next unless ($sql =~ /.txt$/);
1983 while (not $loopend) {
1984 print heading("SELECT SQL FILE");
1986 Select a file to append to the Koha DB.
1987 enter a number. A detailled explanation of the file will be given
1988 if you confirm, the file will be added to the DB
1990 for (my $i=0;$i<=$#sql;$i++) {
1991 print "$i => ".$sql[$i]."\n";
1993 my $response =<STDIN>;
1997 # show the content of the file
1998 my $FileToUpload = $sql[$response];
1999 open FILE,"scripts/misc/sql-datas/$sqluploaddir/$FileToUpload";
2000 my $content = <FILE>;
2001 print heading("INSERT $sqluploaddir/$FileToUpload ?")."$content\n";
2003 $response=showmessage(getmessage('ConfirmFileUpload'), 'yn', 'y');
2004 # if confirmed, upload the file in the DB
2005 unless ($response =~/^n/i) {
2006 $FileToUpload =~ s/\.txt/\.sql/;
2007 system("$mysqldir/bin/mysql -u$user $database <scripts/misc/sql-datas/$sqluploaddir/$FileToUpload");
2021 Asks the user whether to restart Apache, and restart it if the user
2026 $messages->{'RestartApache'}->{en} = heading('RESTART APACHE') . qq|
2027 The web server daemon needs to be restarted to load the new configuration for Koha.
2028 The installer can do this if you are using Apache and give the root password.
2030 Would you like to try to restart Apache now? [Y]/N: |;
2033 my ($auto_install)=@_;
2035 $response=showmessage(getmessage('RestartApache'), 'yn', 'y') unless ($auto_install->{NoPressEnter});
2036 $response='y' if ($auto_install->{NoPressEnter});
2038 unless ($response=~/^n/i) {
2040 # Need to support other init structures here?
2041 if (-e "/etc/rc.d/init.d/httpd") {
2042 system('su root -c "/etc/rc.d/init.d/httpd restart"');
2043 } elsif (-e "/etc/init.d/apache") {
2044 system('su root -c "/etc/init.d/apache restart"');
2045 } elsif (-e "/etc/init.d/apache-ssl") {
2046 system('su root -c "/etc/init.d/apache-ssl restart"');
2055 This function attempts to back up all koha's details.
2059 $messages->{'BackupDir'}->{en} = heading('BACKUP STORAGE').qq|
2060 The upgrader will now try to backup your old files.
2062 Please specify a directory to store the backup in [%s]: |;
2064 $messages->{'BackupSummary'}->{en} = heading('BACKUP SUMMARY').qq|
2068 %6d biblioitems entries
2073 ---------------------------------------------------------------------
2075 ---------------------------------------------------------------------
2077 Does this look right? ([Y]/N): |;
2079 #FIXME: rewrite to use Install.pm
2081 if (!$ENV{prefix}) { $ENV{prefix} = "/usr/local"; }
2082 my $backupdir=$ENV{prefix}.'/backups';
2084 my $answer = showmessage(getmessage('BackupDir',[$backupdir]),'free',$backupdir);
2086 if (! -e $backupdir) {
2087 my $result=mkdir ($backupdir, oct(770));
2089 my @dirs = split(m#/#, $backupdir);
2093 unless (-e "$checkdir") {
2094 mkdir($checkdir, 0775);
2100 chmod 0770, $backupdir;
2102 # Backup MySql database
2105 my $mysqldir = getmysqldir();
2107 my ($sec, $min, $hr, $day, $month, $year) = (localtime(time))[0,1,2,3,4,5];
2110 my $date= sprintf "%4d-%02d-%02d_%02d:%02d:%02d", $year, $month, $day,$hr,$min,$sec;
2112 open (MD, "$mysqldir/bin/mysqldump --user=$user --password=$pass --host=$hostname $database|");
2114 (open BF, ">$backupdir/Koha.backup_$date") || (die "Error opening up backup file $backupdir/Koha.backup_$date: $!\n");
2117 my $bibliocounter=0;
2118 my $biblioitemcounter=0;
2119 my $membercounter=0;
2122 (/insert into items /i) && ($itemcounter++);
2123 (/insert into biblioitems /i) && ($biblioitemcounter++);
2124 (/insert into biblio /i) && ($bibliocounter++);
2125 (/insert into borrowers /i) && ($membercounter++);
2132 my $filels=`ls -hl $backupdir/Koha.backup_$date`;
2134 $answer = showmessage(getmessage('BackupSummary',[$bibliocounter, $biblioitemcounter, $itemcounter, $membercounter, $filels]),'yn');
2136 if ($answer=~/^n/i) {
2139 Aborting. The database dump is located in:
2141 $backupdir/Koha.backup_$date
2146 print "Great! continuing upgrade... \n";
2153 =item finalizeconfigfile
2157 This function must be called when the installation is complete,
2158 to rename the koha.conf.tmp file to koha.conf.
2160 Currently, failure to rename the file results only in a warning.
2164 sub finalizeconfigfile {
2166 rename "$etcdir/koha.conf.tmp", "$etcdir/koha.conf"
2167 || showmessage(<<EOF, 'PressEnter', undef, 1);
2168 An unexpected error, $!, occurred
2169 while the Koha config file is being saved to its final location,
2172 Couldn't rename file at $etcdir. Must have write capability.
2174 Press Enter to continue.
2180 =item loadconfigfile
2184 Open the existing koha.conf file and get its values,
2185 saving the values to some global variables.
2187 If the existing koha.conf file cannot be opened for any reason,
2188 the file is silently ignored.
2192 sub loadconfigfile {
2195 #MJR: reverted to r1.53. Please call setetcdir(). Do NOT hardcode this.
2196 #FIXME: make a dated backup
2197 open (KC, "<$etcdir/koha.conf");
2200 (next) if (/^\s*#/);
2201 if (/(.*)\s*=\s*(.*)/) {
2204 # Clean up white space at beginning and end
2205 $variable=~s/^\s*//g;
2206 $variable=~s/\s*$//g;
2209 $configfile{$variable}=$value;
2213 #MJR: Reverted this too. You do not mess with my privates. Please ask for new functions if required.
2214 $intranetdir=$configfile{'intranetdir'};
2215 $opacdir=$configfile{'opacdir'};
2216 $kohaversion=$configfile{'kohaversion'};
2217 $kohalogdir=$configfile{'kohalogdir'};
2218 $database=$configfile{'database'};
2219 $hostname=$configfile{'hostname'};
2220 $user=$configfile{'user'};
2221 $pass=$configfile{'pass'};
2224 END { } # module clean-up code here (global destructor)
2226 ### These things may move
2230 my $t = POSIX::Termios->new;
2234 $t->setlflag(($t->getlflag) | &POSIX::ECHO);
2237 $t->setlflag(($t->getlflag) & !(&POSIX::ECHO));
2242 sub setmysqlclipass {
2244 open(MYCNF,">$mycnf");
2246 print MYCNF "[client]\npassword=$pass\n";
2252 rename $mycnf,$mytmpcnf;
2257 if (defined $mycnf && -e $mycnf) {
2260 if (defined $mytmpcnf && -e $mytmpcnf) {
2261 rename $mytmpcnf,$mycnf;