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\n"; #MJR: was $terminal->Tputs('cl');
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!
264 You will be able to connect to your Librarian interface at:
268 use the koha admin mysql login and password to connect to this interface.
270 and the OPAC interface at:
274 Please read the Hints file and visit http://www.koha.org
276 Press <ENTER> to exit the installer: |;
278 $messages->{'UpgradeCompleted'}->{en} = heading('UPGRADE COMPLETE') . qq|
279 Congratulations ... your Koha upgrade is finished!
281 If you are upgrading from a version of Koha
282 prior to 1.2.1, it is likely that you will have to modify your Apache
283 configuration to point it to the new files.
285 In your INTRANET VirtualHost section you should have:
286 DocumentRoot %s/htdocs
287 ScriptAlias /cgi-bin/koha/ %s/cgi-bin/
288 SetEnv PERL5LIB %s/modules
290 In the OPAC VirtualHost section you should have:
291 DocumentRoot %s/htdocs
292 ScriptAlias /cgi-bin/koha/ %s/cgi-bin/
293 SetEnv PERL5LIB %s/modules
295 You may also need to uncomment a "LoadModules env_module ... " line and restart
297 If you're upgrading from 1.2.x version of Koha note that the MARC DB is NOT populated.
300 * Go to Parameters >> Marc structure option and Koha-MARC links option.
301 * Modify default MARC structure to fit your needs.
304 cd /path/to/koha/misc
305 export PERL5LIB=/path/to/koha
307 the old DB is "copied" in the new MARC one.
308 Koha 2.0.0 is ready :-)
310 Please report any problems you encounter through http://bugs.koha.org/
312 Press <ENTER> to exit the installer: |;
315 sub releasecandidatewarning {
316 my $message=getmessage('ReleaseCandidateWarning', [$newversion, $newversion]);
317 my $answer=showmessage($message, 'yn', 'n');
319 if ($answer =~ /y/i) {
320 print getmessage('continuing');
322 my $message=getmessage('WatchForReleaseAnnouncements');
328 sub read_autoinstall_file
330 my $fname = shift; # Config file to read
331 my $retval = {}; # Return value: ref-to-hash holding the
334 open (CONF, $fname) or return undef;
338 my $var; # Variable name
339 my $value; # Variable value
342 s/#.*//; # Strip comments
343 next if /^\s*$/; # Ignore blank lines
345 # Look for a line of the form
347 if (!/^\s*(\w+)\s*=\s*(.*?)\s*$/)
352 # Found a variable assignment
353 # variable that was already set.
356 $retval->{$var} = $value;
364 =head2 Accessor functions (for installer.pl)
374 Sets the installation language, normally "en" (English).
375 In fact, only "en" is supported.
379 sub setlanguage ($) {
385 setdomainname('example.org');
387 Sets the domain name of the host.
389 The domain name should not contain a leading dot;
390 otherwise, the results are undefined.
394 sub setdomainname ($) {
402 Sets the sysconfdir, normally /etc.
403 This should be an absolute path; a trailing / is not required.
415 Gets the Koha version as known by the previous config file.
419 sub getkohaversion () {
420 return($kohaversion);
425 setkohaversion('1.3.3RC26');
427 Sets the Koha version as known by the installer.
431 sub setkohaversion ($) {
437 my $servername = getservername;
439 Gets the name of the Koha virtual server as specified by the user.
443 sub getservername () {
451 Gets the port that will run the Koha OPAC virtual server,
452 as specified by the user.
460 =item getintranetport
462 $port = getintranetport;
464 Gets the port that will run the Koha INTRANET virtual server,
465 as specified by the user.
469 sub getintranetport () {
475 =head2 Miscellaneous utility functions
485 Does the equivalent of dirname(1). Given a path $path, return the
486 parent directory of $path (best guess), except when $path seems to
487 be the same as /, in which case $path itself is returned unchanged.
493 if ($path =~ /[^\/]/s) {
495 $path =~ s/\/+[^\/]+\/*$//s;
506 mkdir_parents $path, $mode;
508 Does the equivalent of mkdir -p, or mkdir --parents. Given a path $path,
509 create the directory $path, recursively creating any intermediate
510 directories. If $mode is given, the directory will be created with
513 WARNING: If $path already exists, mkdir_parents will just return
514 successfully (just like mkdir -p), whether the mode of $path conforms
515 to $mode or not. (This is the behaviour of the mkdir -p command.)
520 my($path, $mode) = @_;
521 my $ok = -d($path)? 1: defined $mode? mkdir($path, $mode): mkdir($path);
523 if (!$ok && $! == ENOENT) {
524 my $parent = dirname($path);
525 $ok = mkdir_parents($parent, $mode);
527 # retry and at the same time make sure that $! is set correctly
528 $ok = defined $mode? mkdir($path, $mode): mkdir($path);
537 getmessage($msgid, $variables);
539 Gets a localized message (format string) with message id $msgid,
540 and, if an array reference of variables $variables is given,
541 substitutes variables in the format string with @$variables.
542 Returns the found message string, with variable substitutions
545 $msgid must be the message identifier corresponding to a defined
546 message string (a valid key to the $messages hash in the Installer
547 package). getmessage throws an exception if the message cannot be
553 my $messagename=shift;
555 my $message=$messages->{$messagename}->{$language} || $messages->{$messagename}->{en} || RED.BOLD."Error: No message named $messagename in Install.pm\n";
556 if (defined($variables)) {
557 $message=sprintf $message, @$variables;
565 showmessage($message, 'none');
566 showmessage($message, 'none', undef, $noclear);
568 $result = showmessage($message, 'yn');
569 $result = showmessage($message, 'yn', $defaultresponse);
570 $result = showmessage($message, 'yn', $defaultresponse, $noclear);
572 $result = showmessage($message, 'restrictchar CHARS');
573 $result = showmessage($message, 'free');
574 $result = showmessage($message, 'silentfree');
575 $result = showmessage($message, 'numerical');
576 $result = showmessage($message, 'email');
577 $result = showmessage($message, 'PressEnter');
579 Shows a message and optionally gets a response from the user.
581 The first two arguments, the message and the response type,
582 are mandatory. The message must be the actual string to
583 display; the caller is responsible for calling getmessage if
586 The response type must be one of "none", "yn", "free", "silentfree"
587 "numerical", "email", "PressEnter", or a string consisting
588 of "restrictchar " followed by a list of allowed characters
589 (space can be specified). (Case is not significant, but case is
590 significant in the list of allowed characters.) If a response
591 type other than the above-listed is specified, the result is
594 Note that the response type "yn" is equivalent to "restrictchar yn".
595 Because "restrictchar" is case-sensitive, the user is expected
596 to enter "y" or "n" in lowercase only.
598 Note that the response type of "email" does not actually
599 guarantee that the returned value is a well-formed RFC-822
600 email address, nor does it accept all well-formed RFC-822 email
601 addresses. What it does is to restrict the returned value to a
602 string that is looks reasonably likely to be an email address
603 in the "real world", given the premise that the user is trying
604 to enter a real email address.
606 If a response type other than "none" or "PressEnter" is
607 specified, a third argument, specifying the default value, can
608 be specified: If this default response is not specified, the
609 default response is the first allowed character if the response
610 type is "restrictchar", otherwise the default response is the
611 empty string. This default response is used when the user does
612 not specify a value (i.e., presses Enter without typing in
613 anything), showmessage will assume that the default response is
616 Note that because the response type "yn" is equivalent to
617 "restrictchar yn", the default value for response type "yn",
618 if unspecified, is "y".
620 The screen is normally cleared before the message is displayed;
621 if a fourth argument is specified and is nonzero, this
622 screen-clearing is not done.
628 #MJR: Maybe refactor to use anonymous functions that
629 # check the responses instead of RnP branching.
630 my $message=join('',fill('','',(shift)));
631 my $responsetype=shift;
632 my $defaultresponse=shift;
634 $noclear = 0 unless defined $noclear; # defaults to "clear"
635 ($noclear) || (print $clear_string);
636 if ($responsetype =~ /^yn$/) {
637 $responsetype='restrictchar ynYN';
639 print RESET.$message;
640 if ($responsetype =~/^restrictchar (.*)/i) {
643 until ($options=~/$response/) {
644 (defined($defaultresponse)) || ($defaultresponse=substr($options,0,1));
647 (length($response)) || ($response=$defaultresponse);
648 if ( $response=~/.*[\:\(\)\^\$\*\!\\].*/ ) {
649 ($noclear) || (print $clear_string);
650 print RED."Response contains invalid characters. Choose from [$options].\n\n";
651 print RESET.$message;
654 unless ($options=~/$response/) {
655 ($noclear) || (print $clear_string);
656 print RED."Invalid Response. Choose from [$options].\n\n";
657 print RESET.$message;
662 } elsif ($responsetype =~/^(silent)?free$/i) {
663 (defined($defaultresponse)) || ($defaultresponse='');
664 if ($responsetype =~/^(silent)/i) { setecho(0) };
665 my $response=<STDIN>;
666 if ($responsetype =~/^(silent)/i) { setecho(1) };
668 ($response) || ($response=$defaultresponse);
670 } elsif ($responsetype =~/^numerical$/i) {
671 (defined($defaultresponse)) || ($defaultresponse='');
673 until ($response=~/^\d+$/) {
676 ($response) || ($response=$defaultresponse);
677 unless ($response=~/^\d+$/) {
678 ($noclear) || (print $clear_string);
679 print RED."Invalid Response ($response). Response must be a number.\n\n";
680 print RESET.$message;
684 } elsif ($responsetype =~/^email$/i) {
685 (defined($defaultresponse)) || ($defaultresponse='');
687 until ($response=~/.*\@.*\..*/) {
690 ($response) || ($response=$defaultresponse);
691 if ($response!~/.*\@.*\..*/) {
692 ($noclear) || (print $clear_string);
693 print RED."Invalid Response ($response). Response must be a valid email address.\n\n";
694 print RESET.$message;
698 } elsif ($responsetype =~/^PressEnter$/i) {
701 } elsif ($responsetype =~/^none$/i) {
704 # FIXME: There are a few places where we will get an undef as the
705 # response type. Should we thrown an exception here, or should we
706 # legitimize this usage and say "none" is the default if not specified?
707 #die "Illegal response type \"$responsetype\"";
718 Changes the display to show system output until the next showmessage call.
719 At the time of writing, this means using red text.
730 =head2 Subtasks of doing an installation
736 =item checkabortedinstall
740 Checks whether a previous installation process has been abnormally
741 aborted, by checking whether $etcidr/koha.conf is a symlink matching
742 a particular pattern. If an aborted installation is detected, give
743 the user a chance to abort, before trying to recover the aborted
746 FIXME: The recovery is not complete; it only partially rolls back
751 sub checkabortedinstall () {
752 if (-l("$etcdir/koha.conf")
753 && readlink("$etcdir/koha.conf") =~ /\.tmp$/
756 I have detected that you tried to install Koha before, but the installation
757 was aborted. I will try to continue, but there might be problems if the
758 database is already created.
761 print "Please press <ENTER> to continue: ";
764 # Remove the symlink after the <STDIN>, so the user can back out
765 unlink "$etcdir/koha.conf"
766 || die "Failed to remove incomplete $etcdir/koha.conf: $!\n";
774 Make sure that we loaded the right dirs from an old koha.conf
778 #FIXME: update to use Install.pm
780 if ($opacdir && $intranetdir) {
783 I believe that your old files are located in:
786 LIBRARIAN: $intranetdir
789 Does this look right? ([Y]/N):
791 my $answer = <STDIN>;
794 if ($answer =~/n/i) {
798 print "Great! continuing upgrade... \n";
802 if (!$opacdir || !$intranetdir) {
805 while (!$intranetdir) {
806 print "Please specify the location of your LIBRARIAN files: ";
808 my $answer = <STDIN>;
812 $intranetdir=$answer;
814 if (! -e "$intranetdir/htdocs") {
815 print "\nCouldn't find the htdocs directory here. That doesn't look right.\nPlease enter another location.\n\n";
820 print "Please specify the location of your OPAC files: ";
822 my $answer = <STDIN>;
828 if (! -e "$opacdir/htdocs") {
829 print "\nCouldn't find the htdocs directory here. That doesn't look right.\nPlease enter another location.\n\n";
837 =item checkperlmodules
841 Test whether the version of Perl is new enough, whether Perl is
842 found at the expected location, and whether all required modules
847 sub checkperlmodules {
849 # Test for Perl and Modules
851 my ($auto_install) = @_;
852 my $message = getmessage('CheckingPerlModules');
853 showmessage($message, 'none');
855 unless ($] >= 5.006001) { # Bug 179
856 die getmessage('PerlVersionFailure', ['5.6.1']);
861 unless (eval {require DBI}) { push @missing,"DBI" };
862 unless (eval {require Date::Manip}) { push @missing,"Date::Manip" };
863 unless (eval {require DBD::mysql}) { push @missing,"DBD::mysql" };
864 unless (eval {require HTML::Template}) { push @missing,"HTML::Template" };
865 # unless (eval {require Set::Scalar}) { push @missing,"Set::Scalar" };
866 unless (eval {require Digest::MD5}) { push @missing,"Digest::MD5" };
867 unless (eval {require MARC::Record}) { push @missing,"MARC::Record" };
868 unless (eval {require Mail::Sendmail}) { push @missing,"Mail::Sendmail" };
869 unless (eval {require Event}) {
870 if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
871 push @missing, "Event";
874 unless (eval {require Net::Z3950}) {
875 showmessage(getmessage('NETZ3950Missing'), 'PressEnter', '', 1);
876 if ($#missing>=0) { # see above note
877 push @missing, "Net::Z3950";
882 # Print out a list of any missing modules
887 if (POSIX::setlocale(LC_ALL) ne "C") {
888 $missing.=" export LC_ALL=C\n";
890 foreach my $module (@missing) {
891 $missing.=" perl -MCPAN -e 'install \"$module\"'\n";
893 my $message=getmessage('MissingPerlModules', [$missing]);
894 showmessage($message, 'none');
898 showmessage(getmessage('AllPerlModulesInstalled'), 'PressEnter', '', 1) unless $auto_install->{NoPressEnter};
903 unless (-x "/usr/bin/perl") {
904 my $realperl=`which perl`;
906 $realperl = showmessage(getmessage('NoUsrBinPerl'), 'none');
907 until (-x $realperl) {
908 $realperl=showmessage(getmessage('AskLocationOfPerlExecutable', $realperl), 'free', $realperl, 1);
910 my $response=showmessage(getmessage('ConfirmPerlExecutableSymlink', $realperl), 'yn', 'y', 1);
911 unless ($response eq 'n') {
913 system("ln -s $realperl /usr/bin/perl");
920 $messages->{'NoUsrBinPerl'}->{en} =
921 heading('No /usr/bin/perl') . qq|
922 Koha expects to find the perl executable in the /usr/bin
923 directory. It is not there on your system.
927 $messages->{'AskLocationOfPerlExecutable'}->{en}=qq|Location of Perl Executable [%s]: |;
928 $messages->{'ConfirmPerlExecutableSymlink'}->{en}=qq|
929 Some Koha scripts will _not_ work without a symlink from %s to /usr/bin/perl
931 Most users should answer Y here.
933 May I try to create this symlink? ([Y]/N):|;
935 $messages->{'DirFailed'}->{en} = RED.qq|
936 We could not create %s, but continuing anyway...
942 =item getinstallationdirectories
944 getinstallationdirectories;
946 Get the various installation directories from the user, and then
947 create those directories (if they do not already exist).
949 These pieces of information are saved to global variables; the
950 function does not return any values.
954 sub getinstallationdirectories {
955 my ($auto_install) = @_;
956 if (!$ENV{prefix}) { $ENV{prefix} = "/usr/local"; } #"
957 $opacdir = $ENV{prefix}.'/koha/opac';
958 $intranetdir = $ENV{prefix}.'/koha/intranet';
960 while ($getdirinfo) {
961 # Loop until opac directory and koha directory are different
963 if ($auto_install->{GetOpacDir}) {
964 $opacdir=$auto_install->{GetOpacDir};
965 print "auto-setting OpacDir to $opacdir\n";
967 $message=getmessage('GetOpacDir', [$opacdir]);
968 $opacdir=showmessage($message, 'free', $opacdir);
970 if ($auto_install->{GetIntranetDir}) {
971 $intranetdir=$auto_install->{GetIntranetDir};
972 print "auto-setting IntranetDir to $intranetdir\n";
974 $message=getmessage('GetIntranetDir', [$intranetdir]);
975 $intranetdir=showmessage($message, 'free', $intranetdir);
977 if ($intranetdir eq $opacdir) {
980 You must specify different directories for the OPAC and INTRANET files!
981 :: $intranetdir :: $opacdir ::
988 $kohalogdir=$ENV{prefix}.'/koha/log';
989 if ($auto_install->{GetOpacDir}) {
990 $kohalogdir=$auto_install->{KohaLogDir};
991 print "auto-setting OpacDir to $opacdir\n";
993 my $message=getmessage('GetKohaLogDir', [$kohalogdir]);
994 $kohalogdir=showmessage($message, 'free', $kohalogdir);
998 # FIXME: Need better error handling for all mkdir calls here
999 unless ( -d $intranetdir ) {
1000 mkdir_parents (dirname($intranetdir), 0775) || print getmessage('DirFailed',['parents of '.$intranetdir]);
1001 mkdir ($intranetdir, 0770) || print getmessage('DirFailed',[$intranetdir]);
1002 if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2], "$intranetdir"); }
1003 chmod 0770, "$intranetdir";
1005 mkdir_parents ("$intranetdir/htdocs", 0750);
1006 mkdir_parents ("$intranetdir/cgi-bin", 0750);
1007 mkdir_parents ("$intranetdir/modules", 0750);
1008 mkdir_parents ("$intranetdir/scripts", 0750);
1009 unless ( -d $opacdir ) {
1010 mkdir_parents (dirname($opacdir), 0775) || print getmessage('DirFailed',['parents of '.$opacdir]);
1011 mkdir ($opacdir, 0770) || print getmessage('DirFailed',[$opacdir]);
1012 if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2], "$opacdir"); }
1013 chmod (oct(770), "$opacdir");
1015 mkdir_parents ("$opacdir/htdocs", 0750);
1016 mkdir_parents ("$opacdir/cgi-bin", 0750);
1019 unless ( -d $kohalogdir ) {
1020 mkdir_parents (dirname($kohalogdir), 0775) || print getmessage('DirFailed',['parents of '.$kohalogdir]);
1021 mkdir ($kohalogdir, 0770) || print getmessage('DirFailed',[$kohalogdir]);
1022 if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2,3], "$kohalogdir"); }
1023 chmod (oct(770), "$kohalogdir");
1031 Get the MySQL database server installation directory, automatically if possible.
1035 $messages->{'WhereIsMySQL'}->{en} = heading('MYSQL LOCATION').qq|
1036 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.
1037 If you compiled mysql yourself,
1038 please give the value of --prefix when you ran configure.
1039 The file mysqladmin should be in bin/mysqladmin under the directory that you give here.
1041 MySQL installation directory: |;
1044 foreach my $mysql (qw(/usr/local/mysql
1049 if ( -d $mysql && -f "$mysql/bin/mysqladmin") { #"
1055 $mysqldir = showmessage(getmessage('WhereIsMySQL'),'free');
1056 last if -f "$mysqldir/bin/mysqladmin";
1062 =item getdatabaseinfo
1066 Get various pieces of information related to the Koha database:
1067 the name of the database, the host on which the SQL server is
1068 running, and the database user name.
1070 These pieces of information are saved to global variables; the
1071 function does not return any values.
1075 $messages->{'DatabaseName'}->{en} = heading('Database Name') . qq|
1076 Please provide the name that you wish to give your koha database.
1077 It must not exist already on the database server.
1079 Most users give a short single-word name for their library here.
1081 Database name [%s]: |;
1083 $messages->{'DatabaseHost'}->{en} = heading('Database Host') . qq|
1084 Please provide the mysql server name. Unless the database is stored on
1085 another machine, this should be "localhost".
1087 Database host [%s]: |;
1089 $messages->{'DatabaseUser'}->{en} = heading('Database User') . qq|
1090 We are going to create a new mysql user for Koha. This user will have full administrative rights
1091 to the database called %s when they connect from %s.
1092 This is also the name of the Koha librarian superuser.
1094 Most users give a single-word name here.
1096 Database user [%s]: |;
1098 $messages->{'DatabasePassword'}->{en} = heading('Database Password') . qq|
1099 Please provide a good password for the user %s.
1101 IMPORTANT: You can log in using this user and password at any time.
1103 Password for database user %s: |;
1105 $messages->{'BlankPassword'}->{en} = heading('BLANK PASSWORD') . qq|
1106 You must not use a blank password for your MySQL user.
1108 Press <ENTER> to try again:
1111 sub getdatabaseinfo {
1112 my ($auto_install) = @_;
1114 $hostname = 'localhost';
1115 $user = 'kohaadmin';
1118 #Get the database name
1121 if ($auto_install->{database}) {
1122 $database=$auto_install->{database};
1123 print "auto-setting database to $database\n";
1125 $message=getmessage('DatabaseName', [$database]);
1126 $database=showmessage($message, 'free', $database);
1128 #Get the hostname for the database
1130 if ($auto_install->{DatabaseHost}) {
1131 $hostname=$auto_install->{DatabaseHost};
1132 print "auto-setting database host to $hostname\n";
1134 $message=getmessage('DatabaseHost', [$hostname]);
1135 $hostname=showmessage($message, 'free', $hostname);
1137 #Get the username for the database
1139 if ($auto_install->{DatabaseUser}) {
1140 $user=$auto_install->{DatabaseUser};
1141 print "auto-setting DB user to $user\n";
1143 $message=getmessage('DatabaseUser', [$database, $hostname, $user]);
1144 $user=showmessage($message, 'free', $user);
1146 #Get the password for the database user
1148 while ($pass eq '') {
1149 my $message=getmessage('DatabasePassword', [$user, $user]);
1150 if ($auto_install->{DatabasePassword}) {
1151 $pass=$auto_install->{DatabasePassword};
1152 print "auto-setting database password to $pass\n";
1154 $pass=showmessage($message, 'free', $pass);
1157 my $message=getmessage('BlankPassword');
1158 showmessage($message,'PressEnter');
1169 Get various pieces of information related to the Apache server:
1170 the location of the configuration file and, if needed, the Unix
1171 user that the Koha CGI will be run under.
1173 These pieces of information are saved to global variables; the
1174 function does not return any values.
1178 $messages->{'FoundMultipleApacheConfFiles'}->{en} =
1179 heading('MULTIPLE APACHE CONFIG FILES FOUND') . qq|
1180 I found more than one possible Apache configuration file:
1184 Enter number of the file to read [1]: |;
1186 $messages->{'NoApacheConfFiles'}->{en} =
1187 heading('NO APACHE CONFIG FILE FOUND') . qq|
1188 I was not able to find your Apache configuration file.
1190 The file is usually called httpd.conf, apache.conf or similar.
1192 Please enter the full name, starting with /: |;
1194 $messages->{'NotAFile'}->{en} = heading('FILE DOES NOT EXIST') . qq|
1195 The file %s does not exist.
1197 Please press <ENTER> to continue: |;
1199 $messages->{'EnterApacheUser'}->{en} = heading('NEED APACHE USER') . qq\
1200 The installer could not find the User setting in the Apache configuration file.
1201 This is used to set up access permissions for
1202 %s/koha.conf. This user should be set in one of the Apache configuration.
1203 Please try to find it and enter the user name below. You might find
1204 that "ps u|grep apache" will tell you. It probably is NOT "root".
1206 Enter the Apache userid: \;
1208 $messages->{'InvalidUserid'}->{en} = heading('INVALID USER') . qq|
1209 The userid %s is not a valid userid on this system.
1211 Press <ENTER> to continue: |;
1214 my ($auto_install) = @_;
1215 my @confpossibilities;
1217 foreach my $httpdconf (qw(/usr/local/apache/conf/httpd.conf
1218 /usr/local/etc/apache/httpd.conf
1219 /usr/local/etc/apache/apache.conf
1220 /var/www/conf/httpd.conf
1221 /etc/apache2/httpd.conf
1222 /etc/apache2/apache2.conf
1223 /etc/apache/conf/httpd.conf
1224 /etc/apache/conf/apache.conf
1225 /etc/apache/httpd.conf
1226 /etc/apache-ssl/conf/apache.conf
1227 /etc/apache-ssl/httpd.conf
1228 /etc/httpd/conf/httpd.conf
1229 /etc/httpd/httpd.conf
1230 /etc/httpd/2.0/conf/httpd2.conf
1232 if ( -f $httpdconf ) {
1233 push @confpossibilities, $httpdconf;
1237 if ($#confpossibilities==-1) {
1238 my $message=getmessage('NoApacheConfFiles');
1241 until (-f $realhttpdconf) {
1242 $choice=showmessage($message, "free", 1);
1244 $realhttpdconf=$choice;
1246 showmessage(getmessage('NotAFile', [$choice]),'PressEnter', '', 1);
1249 } elsif ($#confpossibilities>0) {
1253 foreach (@confpossibilities) {
1254 $conffiles.=" $counter: $_\n";
1255 $options.="$counter";
1258 my $message=getmessage('FoundMultipleApacheConfFiles', [$conffiles]);
1259 my $choice=showmessage($message, "restrictchar $options", 1);
1260 $realhttpdconf=$confpossibilities[$choice-1];
1262 $realhttpdconf=$confpossibilities[0];
1264 unless (open (HTTPDCONF, "<$realhttpdconf")) {
1265 warn RED."Insufficient privileges to open $realhttpdconf for reading.\n";
1269 while (<HTTPDCONF>) {
1270 if (/^\s*User\s+"?([-\w]+)"?\s*$/) {
1276 unless (defined($httpduser)) {
1278 if ($auto_install->{EnterApacheUser}) {
1279 $message = $auto_install->{EnterApacheUser};
1280 print "auto-setting ApacheUser to $message\n";
1282 $message=getmessage('EnterApacheUser', [$etcdir]);
1284 until (defined($httpduser) && length($httpduser) && getpwnam($httpduser)) {
1285 if ($auto_install->{EnterApacheUser}) {
1286 $httpduser = $auto_install->{EnterApacheUser};
1288 $httpduser=showmessage($message, "free", '');
1290 if (length($httpduser)>0) {
1291 unless (getpwnam($httpduser)) {
1292 my $message=getmessage('InvalidUserid', [$httpduser]);
1293 showmessage($message,'PressEnter');
1302 =item getapachevhostinfo
1306 Gets various pieces of information related to virtual hosting:
1307 the webmaster email address, virtual hostname, and the ports
1308 that the OPAC and INTRANET modules run on.
1310 These pieces of information are saved to global variables; the
1311 function does not return any values.
1315 $messages->{'ApacheConfigIntroduction'}->{en} =
1316 heading('APACHE CONFIGURATION') . qq|
1317 Koha needs to write an Apache configuration file for the
1318 OPAC and Librarian sites. By default this installer
1319 will do this by using one name and two different ports
1320 for the virtual hosts. There are other ways to set this up,
1321 and the installer will leave comments in
1322 %s/koha-httpd.conf about them.
1324 NOTE: You will need to add lines to your main httpd.conf to
1325 include %s/koha-httpd.conf
1326 and to make sure it is listening on the right ports
1327 (using the Listen directive).
1329 Press <ENTER> to continue: |;
1331 $messages->{'GetVirtualHostEmail'}->{en} =
1332 heading('WEB E-MAIL CONTACT') . qq|
1333 Enter the e-mail address to be used as a contact for Koha. This
1334 address is displayed if fatal errors are encountered.
1336 E-mail contact [%s]: |;
1338 $messages->{'GetServerName'}->{en} =
1339 heading('WEB HOST NAME OR IP ADDRESS') . qq|
1340 Please enter the host name or IP address that you wish to use for koha.
1341 Normally, this should be a name or IP that belongs to this machine.
1343 Host name or IP Address [%s]: |;
1345 $messages->{'GetOpacPort'}->{en} = heading('OPAC PORT') . qq|
1346 Please enter the port for your OPAC interface. This defaults to port 80, but
1347 if you are already serving web content with this hostname, you should change it
1348 to a different port (8000 might be a good choice, but check any firewalls).
1350 Enter the OPAC Port [%s]: |;
1352 $messages->{'GetIntranetPort'}->{en} =
1353 heading('LIBRARIAN PORT') . qq|
1354 Please enter the port for your Librarian interface. This must be different from
1357 Enter the Intranet Port [%s]: |;
1360 sub getapachevhostinfo {
1361 my ($auto_install) = @_;
1362 $svr_admin = "webmaster\@$domainname";
1363 $servername=`hostname`;
1368 if ($auto_install->{GetVirtualHostEmail}) {
1369 $svr_admin=$auto_install->{GetVirtualHostEmail};
1370 print "auto-setting VirtualHostEmail to $svr_admin\n";
1372 showmessage(getmessage('ApacheConfigIntroduction',[$etcdir,$etcdir]), 'PressEnter');
1373 $svr_admin=showmessage(getmessage('GetVirtualHostEmail', [$svr_admin]), 'email', $svr_admin);
1375 if ($auto_install->{servername}) {
1376 $servername=$auto_install->{servername};
1377 print "auto-setting server name to $servername\n";
1379 $servername=showmessage(getmessage('GetServerName', [$servername]), 'free', $servername);
1381 if ($auto_install->{opacport}) {
1382 $opacport=$auto_install->{opacport};
1383 print "auto-setting opac port to $opacport\n";
1385 $opacport=showmessage(getmessage('GetOpacPort', [$opacport]), 'numerical', $opacport);
1387 if ($auto_install->{intranetport}) {
1388 $servername=$auto_install->{intranetport};
1389 print "auto-setting intranet port to $intranetport\n";
1391 $intranetport=showmessage(getmessage('GetIntranetPort', [$opacport, $intranetport]), 'numerical', $intranetport);
1397 =item updateapacheconf
1401 Updates the Apache config file according to parameters previously
1402 specified by the user.
1404 It will append fully-commented directives at the end of the original
1405 Apache config file. The old config file is renamed with an extension
1408 If you need to uninstall Koha for any reason, the lines between
1410 # Ports to listen to for Koha
1412 and the block of comments beginning with
1414 # If you want to use name based Virtual Hosting:
1420 $messages->{'StartUpdateApache'}->{en} =
1421 heading('UPDATING APACHE CONFIGURATION') . qq|
1422 Checking for modules that need to be loaded...
1425 $messages->{'ApacheConfigMissingModules'}->{en} =
1426 heading('APACHE CONFIGURATION NEEDS UPDATE') . qq|
1427 Koha uses the mod_env and mod_include apache features, but the
1428 installer did not find them in your config. Please
1429 make sure that they are enabled for your Koha site.
1431 Press <ENTER> to continue: |;
1434 $messages->{'ApacheAlreadyConfigured'}->{en} =
1435 heading('APACHE ALREADY CONFIGURED') . qq|
1436 %s appears to already have an entry for Koha. You may need to edit %s
1437 if anything has changed since it was last set up. This
1438 script will not attempt to modify an existing Koha apache
1441 Press <ENTER> to continue: |;
1443 sub updateapacheconf {
1444 my $logfiledir=$kohalogdir;
1445 my $httpdconf = $etcdir."/koha-httpd.conf";
1447 showmessage(getmessage('StartUpdateApache'), 'none');
1448 # to be polite about it: I don't think this should touch the main httpd.conf
1450 # QUESTION: Should we warn for includes_module too?
1452 my $includesmodule=0;
1453 open HC, "<$realhttpdconf";
1455 if (/^\s*#\s*LoadModule env_module /) {
1456 showmessage(getmessage('ApacheConfigMissingModules'));
1459 if (/\s*LoadModule includes_module / ) {
1465 if (`grep -q 'VirtualHost $servername' "$httpdconf" 2>/dev/null`) {
1466 showmessage(getmessage('ApacheAlreadyConfigured', [$httpdconf, $httpdconf]), 'PressEnter');
1469 my $includesdirectives='';
1470 if ($includesmodule) {
1471 $includesdirectives.="Options +Includes\n";
1472 $includesdirectives.=" AddHandler server-parsed .html\n";
1474 open(SITE,">$httpdconf") or warn "Insufficient priveleges to open $httpdconf for writing.\n";
1475 my $opaclisten = '';
1476 if ($opacport != 80) {
1477 $opaclisten="Listen $opacport";
1479 my $intranetlisten = '';
1480 if ($intranetport != 80) {
1481 $intranetlisten="Listen $intranetport";
1485 # Ports to listen to for Koha
1486 # uncomment these if they aren't already in main httpd.conf
1490 # NameVirtualHost is used by one of the optional configurations detailed below
1492 #NameVirtualHost 11.22.33.44
1494 # KOHA's OPAC Configuration
1495 <VirtualHost $servername\:$opacport>
1496 ServerAdmin $svr_admin
1497 DocumentRoot $opacdir/htdocs
1498 ServerName $servername
1499 ScriptAlias /cgi-bin/koha/ $opacdir/cgi-bin/
1500 ErrorLog $logfiledir/opac-error_log
1501 TransferLog $logfiledir/opac-access_log
1502 SetEnv PERL5LIB "$intranetdir/modules"
1503 SetEnv KOHA_CONF "$etcdir/koha.conf"
1507 # KOHA's INTRANET Configuration
1508 <VirtualHost $servername\:$intranetport>
1509 ServerAdmin $svr_admin
1510 DocumentRoot $intranetdir/htdocs
1511 ServerName $servername
1512 ScriptAlias /cgi-bin/koha/ "$intranetdir/cgi-bin/"
1513 ErrorLog $logfiledir/koha-error_log
1514 TransferLog $logfiledir/koha-access_log
1515 SetEnv PERL5LIB "$intranetdir/modules"
1516 SetEnv KOHA_CONF "$etcdir/koha.conf"
1520 # If you want to use name based Virtual Hosting:
1521 # 1. remove the two Listen lines
1522 # 2. replace $servername\:$opacport wih your.opac.domain.name
1523 # 3. replace ServerName $servername wih ServerName your.opac.domain.name
1524 # 4. replace $servername\:$intranetport wih your intranet domain name
1525 # 5. replace ServerName $servername wih ServerName your.intranet.domain.name
1527 # If you want to use NameVirtualHost'ing (using two names on one ip address):
1528 # 1. Follow steps 1-5 above
1529 # 2. Uncomment the NameVirtualHost line and set the correct ip address
1538 =item basicauthentication
1540 basicauthentication;
1542 Asks the user whether HTTP basic authentication is wanted, and,
1543 if so, the user name and password for the basic authentication.
1545 These pieces of information are saved to global variables; the
1546 function does not return any values.
1550 # $messages->{'IntranetAuthenticationQuestion'}->{en} =
1551 # heading('LIBRARIAN AUTHENTICATION') . qq|
1552 # The Librarian site can be password protected using
1553 # Apache's Basic Authorization instead of Koha user details.
1555 # This method going to be phased out very soon. Most users should answer N here.
1557 # Would you like to do this (Y/[N]): |; #'
1559 # $messages->{'BasicAuthUsername'}->{en}="Please enter a username for librarian access [%s]: ";
1560 # $messages->{'BasicAuthPassword'}->{en}="Please enter a password for %s: ";
1561 # $messages->{'BasicAuthPasswordWasBlank'}->{en}="\nYou cannot use a blank password!\n\n";
1563 # sub basicauthentication {
1564 # my $message=getmessage('IntranetAuthenticationQuestion');
1565 # my $answer=showmessage($message, 'yn', 'n');
1566 # my $httpdconf = $etcdir."/koha-httpd.conf";
1568 # my $apacheauthusername='librarian';
1569 # my $apacheauthpassword='';
1570 # if ($answer=~/^y/i) {
1571 # ($apacheauthusername) = showmessage(getmessage('BasicAuthUsername', [ $apacheauthusername]), 'free', $apacheauthusername, 1);
1572 # $apacheauthusername=~s/[^a-zA-Z0-9]//g;
1573 # while (! $apacheauthpassword) {
1574 # ($apacheauthpassword) = showmessage(getmessage('BasicAuthPassword', [ $apacheauthusername]), 'free', 1);
1575 # if (!$apacheauthpassword) {
1576 # ($apacheauthpassword) = showmessage(getmessage('BasicAuthPasswordWasBlank'), 'none', '', 1);
1579 # open AUTH, ">$etcdir/kohaintranet.pass";
1580 # my $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
1581 # my $salt=substr($chars, int(rand(length($chars))),1);
1582 # $salt.=substr($chars, int(rand(length($chars))),1);
1583 # print AUTH $apacheauthusername.":".crypt($apacheauthpassword, $salt)."\n";
1585 # open(SITE,">>$httpdconf") or warn "Insufficient priveleges to open $realhttpdconf for writing.\n";
1588 # <Directory $intranetdir>
1589 # AuthUserFile $etcdir/kohaintranet.pass
1591 # AuthName "Koha Intranet (for librarians only)"
1592 # Require valid-user
1604 Install the Koha files to the specified OPAC and INTRANET
1605 directories (usually in /usr/local/koha).
1607 The koha.conf file is created, but as koha.conf.tmp. The
1608 caller is responsible for calling finalizeconfigfile when
1609 installation is completed, to rename it back to koha.conf.
1613 $messages->{'InstallFiles'}->{en} = heading('INSTALLING FILES') . qq|
1614 Copying files to installation directories:
1618 $messages->{'OldFiles'}->{en} = heading('OLD FILES') . qq|
1619 Any files from the previous edition of Koha have been
1620 copied to a dated backup directory alongside the new
1621 installation. You should move any custom files that you
1622 want to keep (such as your site templates) into the new
1623 directories and then move the backup off of the live
1626 Press ENTER to continue:|;
1629 $messages->{'CopyingFiles'}->{en}="Copying %s to %s.\n";
1635 #MJR: preserve old files, just in case
1641 print getmessage('CopyingFiles', ["old ".$desc,$tgt.strftime("%Y%m%d%H%M",localtime())]);
1643 system("mv ".$tgt." ".$tgt.strftime("%Y%m%d%H%M",localtime()));
1646 print getmessage('CopyingFiles', [$desc,$tgt]);
1648 system("cp -R ".$src." ".$tgt);
1651 my ($auto_install) = @_;
1652 showmessage(getmessage('InstallFiles'),'none');
1654 neatcopy("admin templates", 'intranet-html', "$intranetdir/htdocs");
1655 neatcopy("admin interface", 'intranet-cgi', "$intranetdir/cgi-bin");
1656 neatcopy("main scripts", 'scripts', "$intranetdir/scripts");
1657 neatcopy("perl modules", 'modules', "$intranetdir/modules");
1658 neatcopy("OPAC templates", 'opac-html', "$opacdir/htdocs");
1659 neatcopy("OPAC interface", 'opac-cgi', "$opacdir/cgi-bin");
1661 system("touch $opacdir/cgi-bin/opac");
1663 #MJR: is this necessary?
1665 system("chown -R $httpduser:$httpduser $opacdir $intranetdir");
1667 system("chmod -R a+rx $opacdir $intranetdir");
1669 # Create /etc/koha.conf
1671 my $old_umask = umask(027); # make sure koha.conf is never world-readable
1672 open(SITES,">$etcdir/koha.conf.tmp") or warn "Couldn't create file at $etcdir. Must have write capability.\n";
1678 intranetdir=$intranetdir
1680 kohalogdir=$kohalogdir
1681 kohaversion=$newversion
1682 httpduser=$httpduser
1683 intrahtdocs=$intranetdir/htdocs/intranet-tmpl
1684 opachtdocs=$opacdir/htdocs/opac-tmpl
1690 #MJR: can't help but this be broken, can we?
1691 chmod 0440, "$etcdir/koha.conf.tmp";
1693 #MJR: does this contain any passwords?
1694 chmod 0755, "$intranetdir/scripts/z3950daemon/z3950-daemon-launch.sh", "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh", "$intranetdir/scripts/z3950daemon/processz3950queue";
1696 #MJR: generate our own settings, to remove the /home/paul hardwired links
1697 open(FILE,">$intranetdir/scripts/z3950daemon/z3950-daemon-options");
1698 print FILE "RunAsUser=$httpduser\nKohaZ3950Dir=$intranetdir/scripts/z3950daemon\nKohaModuleDir=$intranetdir/modules\nLogDir=$kohalogdir\nKohaConf=$etcdir/koha.conf";
1702 chown((getpwnam($httpduser)) [2,3], "$etcdir/koha.conf.tmp") or warn "can't chown koha.conf: $!";
1703 chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh") or warn "can't chown $intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh: $!";
1704 chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/processz3950queue") or warn "can't chown $intranetdir/scripts/z3950daemon/processz3950queue: $!";
1705 } #MJR: report that we haven't chown()d.
1707 print "Please check permissions in $intranetdir/scripts/z3950daemon\n";
1710 showmessage(getmessage('OldFiles'),'PressEnter') unless $auto_install->{NoPressEnter};
1718 Finds out where the MySQL utitlities are located in the system,
1719 then create the Koha database structure and MySQL permissions.
1723 $messages->{'MysqlRootPassword'}->{en} =
1724 heading('MYSQL ROOT USER PASSWORD') . qq|
1725 To create the koha database, please enter your
1726 mysql server's root user password:
1730 $messages->{'CreatingDatabase'}->{en} = heading('CREATING DATABASE') . qq|
1731 Creating the MySQL database for Koha...
1735 $messages->{'CreatingDatabaseError'}->{en} =
1736 heading('ERROR CREATING DATABASE') . qq|
1737 Couldn't connect to the MySQL server for the reason given above.
1738 This is a serious problem, the database will not get installed.
1740 Press <ENTER> to continue: |; #'
1742 $messages->{'SampleData'}->{en} = heading('SAMPLE DATA') . qq|
1743 If you are installing Koha for evaluation purposes,
1744 you can install some sample data now.
1746 If you are installing Koha to use your own
1747 data, you probably don't want this sample data installed.
1749 Would you like to install the sample data? Y/[N]: |; #'
1751 $messages->{'SampleDataInstalled'}->{en} =
1752 heading('SAMPLE DATA INSTALLED') . qq|
1753 Sample data has been installed. For some suggestions on testing Koha, please
1754 read the file doc/HOWTO-Testing. If you find any bugs, please submit them at
1755 http://bugs.koha.org/. If you need help with testing Koha, you can post a
1756 question through the koha-devel mailing list, or you can check for a developer
1757 online at irc.katipo.co.nz:6667 channel #koha.
1759 You can find instructions for subscribing to the Koha mailing lists at:
1764 Press <ENTER> to continue: |;
1766 $messages->{'AddBranchPrinter'}->{en} = heading('Add Branch and Printer') . qq|
1767 Would you like to describe an initial branch and printer? [Y]/N: |;
1769 $messages->{'BranchName'}->{en}="Branch Name [%s]: ";
1770 $messages->{'BranchCode'}->{en}="Branch Code (4 letters or numbers) [%s]: ";
1771 $messages->{'PrinterQueue'}->{en}="Printer Queue [%s]: ";
1772 $messages->{'PrinterName'}->{en}="Printer Name [%s]: ";
1775 my ($auto_install) = @_;
1776 $mysqluser = 'root';
1778 my $mysqldir = getmysqldir();
1780 if ($auto_install->{MysqlRootPassword}) {
1781 $mysqlpass=$auto_install->{MysqlRootPassword};
1783 # we must not put the mysql root password on the command line
1784 $mysqlpass= showmessage(getmessage('MysqlRootPassword'),'silentfree');
1787 showmessage(getmessage('CreatingDatabase'),'none') unless ($auto_install->{NoPressEnter});
1789 setmysqlclipass($mysqlpass);
1790 # Set up permissions
1792 print system("$mysqldir/bin/mysql -u$mysqluser mysql -e \"insert into user (Host,User,Password) values ('$hostname','$user',password('$pass'))\"\;");#"
1793 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')\"");
1794 system("$mysqldir/bin/mysqladmin -u$mysqluser reload");
1795 # Change to admin user login
1796 setmysqlclipass($pass);
1797 my $result=system("$mysqldir/bin/mysqladmin", "-u$user", "create", "$database");
1799 showmessage(getmessage('CreatingDatabaseError'),'PressEnter', '', 1);
1801 # Create the database structure
1803 system("$mysqldir/bin/mysql -u$user $database < koha.mysql");
1809 =item updatedatabase
1813 Updates the Koha database structure, including the addition of
1816 The MARC tables are also populated in addition to being created.
1818 Because updatedatabase calls scripts/updater/updatedatabase to
1819 do the actual update, and that script uses C4::Context,
1820 $etcdir/koha.conf must exist at this point. We use the KOHA_CONF
1821 environment variable to do this.
1823 FIXME: (See checkabortedinstall as it depends on old symlink way.)
1827 $messages->{'UpdateMarcTables'}->{en} =
1828 heading('MARC FIELD DEFINITIONS') . qq|
1829 You can import MARC settings for:
1835 NOTE: If you choose N,
1836 nothing will be added, and you must create them all yourself.
1837 Only choose N if you want to use a MARC format not listed here,
1838 such as DANMARC. We would like to hear from you if you do.
1840 Choose MARC definition [1]: |;
1842 $messages->{'Language'}->{en} = heading('CHOOSE LANGUAGE') . qq|
1843 This version of koha supports a few languages.
1845 en : default language, all pages available
1846 fr : complete translation (except pictures)
1847 es : partial librarian site translation (including pictures)
1848 pl : complete OPAC and partial librarian translation
1849 zh_TW : partial translation
1851 en is used when a screen is not available in your language
1853 If you specify a language here, you can still
1854 change it from the system preferences screen in the librarian sit.
1856 Which language do you choose? |;
1858 sub updatedatabase {
1859 # At this point, $etcdir/koha.conf must exist, for C4::Context
1860 $ENV{"KOHA_CONF"}=$etcdir.'/koha.conf';
1861 if (! -e $ENV{"KOHA_CONF"}) { $ENV{"KOHA_CONF"}=$etcdir.'/koha.conf.tmp'; }
1863 my $result=system ("perl -I $intranetdir/modules scripts/updater/updatedatabase");
1866 print "Problem updating database...\n";
1870 my $response=showmessage(getmessage('UpdateMarcTables'), 'restrictchar 12N', '1');
1873 if ($response eq '1') {
1874 system("cat scripts/misc/marc_datas/marc21_en/structure_def.sql | $mysqldir/bin/mysql -u$user $database");
1875 system("cat scripts/misc/lang-datas/en/stopwords.sql | $mysqldir/bin/mysql -u$user $database");
1877 if ($response eq '2') {
1878 system("cat scripts/misc/marc_datas/unimarc_fr/structure_def.sql | $mysqldir/bin/mysql -u$user $database");
1879 system("cat scripts/misc/lang-datas/fr/stopwords.sql | $mysqldir/bin/mysql -u$user $database");
1881 delete($ENV{"KOHA_CONF"});
1883 print RESET."\n\nFinished updating of database. Press <ENTER> to continue...";
1888 =item populatedatabase
1892 Populate the non-MARC tables. If the user wants to install the
1893 sample data, install them.
1897 sub populatedatabase {
1898 # my $response=showmessage(getmessage('SampleData'), 'yn', 'n');
1899 # if ($response =~/^y/i) {
1901 # FIXME: These calls are now unsafe and should either be removed
1902 # or updated to use -u$user and no mysqlpass_quoted
1904 # system("gunzip -d < sampledata-1.2.gz | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $database");
1905 # system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $database -e \"insert into branches (branchcode,branchname,issuing) values ('MAIN', 'Main Library', 1)\"");
1906 # system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $database -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1907 # system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $database -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1908 # system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $database -e \"insert into printers (printername,printqueue,printtype) values ('Circulation Desk Printer', 'lp', 'hp')\"");
1909 # showmessage(getmessage('SampleDataInstalled'), 'PressEnter','',1);
1912 my $response=showmessage(getmessage('AddBranchPrinter'), 'yn', 'y');
1914 unless ($response =~/^n/i) {
1915 my $branch='Main Library';
1916 $branch=showmessage(getmessage('BranchName', [$branch]), 'free', $branch, 1);
1917 $branch=~s/[^A-Za-z0-9\s]//g;
1919 my $branchcode=$branch;
1920 $branchcode=~s/[^A-Za-z0-9]//g;
1921 $branchcode=uc($branchcode);
1922 $branchcode=substr($branchcode,0,4);
1923 $branchcode=showmessage(getmessage('BranchCode', [$branchcode]), 'free', $branchcode, 1);
1924 $branchcode=~s/[^A-Za-z0-9]//g;
1925 $branchcode=uc($branchcode);
1926 $branchcode=substr($branchcode,0,4);
1927 $branchcode or $branchcode='DEF';
1930 system("$mysqldir/bin/mysql -u$user $database -e \"insert into branches (branchcode,branchname,issuing) values ('$branchcode', '$branch', 1)\"");
1931 system("$mysqldir/bin/mysql -u$user $database -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1932 system("$mysqldir/bin/mysql -u$user $database -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1934 my $printername='Library Printer';
1935 $printername=showmessage(getmessage('PrinterName', [$printername]), 'free', $printername, 1);
1936 $printername=~s/[^A-Za-z0-9\s]//g;
1938 my $printerqueue='lp';
1939 $printerqueue=showmessage(getmessage('PrinterQueue', [$printerqueue]), 'free', $printerqueue, 1);
1940 $printerqueue=~s/[^A-Za-z0-9]//g;
1942 system("$mysqldir/bin/mysql -u$user $database -e \"insert into printers (printername,printqueue,printtype) values ('$printername', '$printerqueue', '')\"");
1944 my $language=showmessage(getmessage('Language'), 'free', 'en');
1946 system("$mysqldir/bin/mysql -u$user $database -e \"update systempreferences set value='$language' where variable='opaclanguages'\"");
1955 Asks the user whether to restart Apache, and restart it if the user
1960 $messages->{'RestartApache'}->{en} = heading('RESTART APACHE') . qq|
1961 The web server daemon needs to be restarted to load the new configuration for Koha.
1962 The installer can do this if you are using Apache and give the root password.
1964 Would you like to try to restart Apache now? [Y]/N: |;
1968 my $response=showmessage(getmessage('RestartApache'), 'yn', 'y');
1970 unless ($response=~/^n/i) {
1972 # Need to support other init structures here?
1973 if (-e "/etc/rc.d/init.d/httpd") {
1974 system('su root -c /etc/rc.d/init.d/httpd restart');
1975 } elsif (-e "/etc/init.d/apache") {
1976 system('su root -c /etc/init.d/apache restart');
1977 } elsif (-e "/etc/init.d/apache-ssl") {
1978 system('su root -c /etc/init.d/apache-ssl restart');
1988 This function attempts to back up all koha's details.
1992 $messages->{'BackupDir'}->{en} = heading('BACKUP STORAGE').qq|
1993 The upgrader will now try to backup your old files.
1995 Please specify a directory to store the backup in [%s]: |;
1997 $messages->{'BackupSummary'}->{en} = heading('BACKUP SUMMARY').qq|
2001 %6d biblioitems entries
2006 ---------------------------------------------------------------------
2008 ---------------------------------------------------------------------
2010 Does this look right? ([Y]/N): |;
2012 #FIXME: rewrite to use Install.pm
2014 my $backupdir=$ENV{'prefix'}.'/backups';
2016 my $answer = showmessage(getmessage('BackupDir',[$backupdir]),'free',$backupdir);
2018 if (! -e $backupdir) {
2019 my $result=mkdir ($backupdir, oct(770));
2021 my @dirs = split(m#/#, $backupdir);
2025 unless (-e "$checkdir") {
2026 mkdir($checkdir, 0775);
2032 chmod 0770, $backupdir;
2034 # Backup MySql database
2037 my $mysqldir = getmysqldir();
2039 my ($sec, $min, $hr, $day, $month, $year) = (localtime(time))[0,1,2,3,4,5];
2042 my $date= sprintf "%4d-%02d-%02d_%02d:%02d:%02d", $year, $month, $day,$hr,$min,$sec;
2044 open (MD, "$mysqldir/bin/mysqldump --user=$user --password=$pass --host=$hostname $database|");
2046 (open BF, ">$backupdir/Koha.backup_$date") || (die "Error opening up backup file $backupdir/Koha.backup_$date: $!\n");
2049 my $bibliocounter=0;
2050 my $biblioitemcounter=0;
2051 my $membercounter=0;
2054 (/insert into items /i) && ($itemcounter++);
2055 (/insert into biblioitems /i) && ($biblioitemcounter++);
2056 (/insert into biblio /i) && ($bibliocounter++);
2057 (/insert into borrowers /i) && ($membercounter++);
2064 my $filels=`ls -hl $backupdir/Koha.backup_$date`;
2066 $answer = showmessage(getmessage('BackupSummary',[$bibliocounter, $biblioitemcounter, $itemcounter, $membercounter, $filels]),'yn');
2068 if ($answer=~/^n/i) {
2071 Aborting. The database dump is located in:
2073 $backupdir/Koha.backup_$date
2078 print "Great! continuing upgrade... \n";
2085 =item finalizeconfigfile
2089 This function must be called when the installation is complete,
2090 to rename the koha.conf.tmp file to koha.conf.
2092 Currently, failure to rename the file results only in a warning.
2096 sub finalizeconfigfile {
2098 rename "$etcdir/koha.conf.tmp", "$etcdir/koha.conf"
2099 || showmessage(<<EOF, 'PressEnter', undef, 1);
2100 An unexpected error, $!, occurred
2101 while the Koha config file is being saved to its final location,
2104 Couldn't rename file at $etcdir. Must have write capability.
2106 Press Enter to continue.
2112 =item loadconfigfile
2116 Open the existing koha.conf file and get its values,
2117 saving the values to some global variables.
2119 If the existing koha.conf file cannot be opened for any reason,
2120 the file is silently ignored.
2124 sub loadconfigfile {
2127 #MJR: reverted to r1.53. Please call setetcdir(). Do NOT hardcode this.
2128 #FIXME: make a dated backup
2129 open (KC, "<$etcdir/koha.conf");
2132 (next) if (/^\s*#/);
2133 if (/(.*)\s*=\s*(.*)/) {
2136 # Clean up white space at beginning and end
2137 $variable=~s/^\s*//g;
2138 $variable=~s/\s*$//g;
2141 $configfile{$variable}=$value;
2145 #MJR: Reverted this too. You do not mess with my privates. Please ask for new functions if required.
2146 $intranetdir=$configfile{'intranetdir'};
2147 $opacdir=$configfile{'opacdir'};
2148 $kohaversion=$configfile{'kohaversion'};
2149 $kohalogdir=$configfile{'kohalogdir'};
2150 $database=$configfile{'database'};
2151 $hostname=$configfile{'hostname'};
2152 $user=$configfile{'user'};
2153 $pass=$configfile{'pass'};
2156 END { } # module clean-up code here (global destructor)
2158 ### These things may move
2162 my $t = POSIX::Termios->new;
2166 $t->setlflag(($t->getlflag) | &POSIX::ECHO);
2169 $t->setlflag(($t->getlflag) & !(&POSIX::ECHO));
2174 sub setmysqlclipass {
2176 open(MYCNF,">$mycnf");
2178 print MYCNF "[client]\npassword=$pass\n";
2184 rename $mycnf,$mytmpcnf;
2189 if (defined $mycnf && -e $mycnf) {
2192 if (defined $mytmpcnf && -e $mytmpcnf) {
2193 rename $mytmpcnf,$mycnf;