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
57 @EXPORT = qw( &checkperlmodules
61 &releasecandidatewarning
63 &getinstallationdirectories
81 use vars qw( $kohaversion $newversion ); # set in loadconfigfile and installer.pl
82 use vars qw( $language ); # set in installer.pl
83 use vars qw( $domainname ); # set in installer.pl
85 use vars qw( $etcdir ); # set in installer.pl, usu. /etc
86 use vars qw( $intranetdir $opacdir $kohalogdir );
87 use vars qw( $realhttpdconf $httpduser );
88 use vars qw( $servername $svr_admin $opacport $intranetport );
89 use vars qw( $mysqldir );
90 use vars qw( $database $mysqluser );
91 use vars qw( $mysqlpass ); # normally should not be used
92 use vars qw( $dbname $hostname $user $pass ); # virtual hosting
96 $messages->{'WelcomeToKohaInstaller'
97 = heading('Welcome to the Koha Installer') . qq|...|;
99 The heading function takes one string, the text to be displayed as
100 the heading, and returns a formatted heading (currently formatted
103 This reduces the likelihood of pod2man(1) etc. misinterpreting
104 a line of equal signs as illegal POD directives.
108 my $termios = POSIX::Termios->new();
110 my $terminal = Term::Cap->Tgetent({OSPEED=>$termios->getospeed()});
111 my $clear_string = "\n\n"; #MJR: was $terminal->Tputs('cl');
116 return($clear_string.ON_BLUE.WHITE.BOLD." "x$bal.uc($title)." "x$bal.RESET."\n\n");
119 my $mycnf = $ENV{HOME}."/.my.cnf";
120 my $mytmpcnf = `mktemp my.cnf.koha.XXXXXX`;
124 $messages->{'continuing'}->{en}="Great! Continuing...\n\n";
125 $messages->{'WelcomeToKohaInstaller'}->{en} =
126 heading('Welcome to the Koha Installer') . qq|
127 This program will ask some questions and try to install koha for you.
128 You need to know: where most koha files should be stored (you can set
129 the prefix environment variable for this); the username and password of
130 a mysql superuser; and details of your library setup. You may also need
131 to know details of your Apache setup.
133 If you want to install the Koha configuration files somewhere other than
134 /etc (for multiple Koha versions on one system, for example), you should
135 set the etcdir environment variable. Please look at your manuals for
136 details of how to set that.
138 Recommended answers are given in brackets after each question. To accept
139 the default value for any question (indicated by []), simply hit Enter
142 Are you ready to begin the installation? ([Y]/N): |;
144 $messages->{'WelcomeToUpgrader'}->{en} =
145 heading('Welcome to the Koha Upgrader') . qq|
146 You are attempting to upgrade from Koha %s to %s.
148 We recommend that you do a complete backup of all your files before upgrading.
149 This upgrade script will make a backup copy of your files for you.
151 Would you like to proceed? (Y/[N]):|;
153 $messages->{'AbortingInstall'}->{en} =
154 heading('ABORTING') . qq|
155 Aborting as requested. Please rerun when you are ready.
158 $messages->{'ReleaseCandidateWarning'}->{en} =
159 heading('RELEASE CANDIDATE') . qq|
160 WARNING: You are about to install Koha version %s. This is a
161 release candidate, not intended for production systems.
162 It is being released so that users can test it before we release a final
163 version and report bugs to us.
165 Most people should answer Yes here.
167 Are you sure you want to install Koha %s? (Y/[N]): |;
168 $messages->{'WatchForReleaseAnnouncements'}->{en}=qq|
170 Watch for announcements of Koha releases on the Koha mailing list or the Koha
171 web site (http://www.koha.org/).
175 $messages->{'NETZ3950Missing'}->{en}=qq|
177 The Net::Z3950 module is missing. This module is necessary if you want to use
178 Koha's Z39.50 client to download bibliographic records from other libraries.
180 To install this module, you will need the yaz client installed from
181 http://www.indexdata.dk/yaz/ and then you can install the perl module with the
184 perl -MCPAN -e 'install Net::Z3950'
186 ...or by installing packages for your distribution, if available.
188 IMPORTANT NOTE : If you use Perl 5.8.0, you might need to
189 edit NET::Z3950's Makefile.PL and yazwrap/Makefile.PL to include:
191 'DEFINE' => '-D_GNU_SOURCE',
193 Also note that some installations of Perl on Red Hat will generate a lot of
194 "'my_perl' undeclared" errors when running make in Net-Z3950. This is fixed by
195 inserting in yazwrap/ywpriv.h a line saying #include "XSUB.h"
197 Press the <ENTER> key to continue: |; #'
199 $messages->{'CheckingPerlModules'}->{en} = heading('PERL MODULES') . qq|
200 Checking perl modules ...
203 $messages->{'PerlVersionFailure'}->{en}="Sorry, you need at least Perl %s\n";
205 $messages->{'MissingPerlModules'}->{en} = heading('MISSING PERL MODULES') . qq|
206 You are missing some Perl modules which are required by Koha.
207 Once these modules have been installed, rerun this installer.
208 They may be installed by running (as root) the following:
213 $messages->{'AllPerlModulesInstalled'}->{en} =
214 heading('PERL MODULES AVAILABLE') . qq|
215 All mandatory perl modules are installed.
217 Press <ENTER> to continue: |;
218 $messages->{'KohaVersionInstalled'}->{en}="You currently have Koha %s on your system.";
219 $messages->{'KohaUnknownVersionInstalled'}->{en}="I am not able to determine what version of Koha is installed now.";
220 $messages->{'KohaAlreadyInstalled'}->{en} =
221 heading('Koha already installed') . qq|
222 It looks like Koha is already installed on your system (%s/koha.conf exists).
223 If you would like to upgrade your system to %s, please use
224 the koha.upgrade script in this directory.
229 $messages->{'GetOpacDir'}->{en} = heading('OPAC DIRECTORY') . qq|
230 Please supply the directory you want Koha to store its OPAC files in. This
231 directory will be auto-created for you if it doesn't exist.
233 OPAC Directory [%s]: |; #'
235 $messages->{'GetIntranetDir'}->{en} =
236 heading('LIBRARIAN DIRECTORY') . qq|
237 Please supply the directory you want Koha to store its Librarian interface
238 files in. This directory will be auto-created for you if it doesn't exist.
240 Intranet Directory [%s]: |; #'
242 $messages->{'GetKohaLogDir'}->{en} = heading('LOG DIRECTORY') . qq|
243 Specify a directory where log files will be written.
245 Koha Log Directory [%s]: |;
247 $messages->{'AuthenticationWarning'}->{en} = heading('Authentication') . qq|
248 This release of Koha has a new authentication module.
249 You will be required to log in to
250 access some features.
252 IMPORTANT: You can log in using the userid and password from the %s/koha.conf configuration file at any time.
253 Use the "Members" screen to add passwords for other accounts and set their flags.
255 Press the <ENTER> key to continue: |;
257 $messages->{'Completed'}->{en} = heading('INSTALLATION COMPLETE') . qq|
258 Congratulations ... your Koha installation is complete!
260 You will be able to connect to your Librarian interface at:
264 use the koha admin mysql login and password to connect to this interface.
266 and the OPAC interface at:
270 Please read the Hints file and visit http://www.koha.org
272 Press <ENTER> to exit the installer: |;
274 $messages->{'UpgradeCompleted'}->{en} = heading('UPGRADE COMPLETE') . qq|
275 Congratulations ... your Koha upgrade is finished!
277 If you are upgrading from a version of Koha
278 prior to 1.2.1, it is likely that you will have to modify your Apache
279 configuration to point it to the new files.
281 In your INTRANET VirtualHost section you should have:
282 DocumentRoot %s/htdocs
283 ScriptAlias /cgi-bin/koha/ %s/cgi-bin/
284 SetEnv PERL5LIB %s/modules
286 In the OPAC VirtualHost section you should have:
287 DocumentRoot %s/htdocs
288 ScriptAlias /cgi-bin/koha/ %s/cgi-bin/
289 SetEnv PERL5LIB %s/modules
291 You may also need to uncomment a "LoadModules env_module ... " line and restart
293 If you're upgrading from 1.2.x version of Koha note that the MARC DB is NOT populated.
296 * Go to Parameters >> Marc structure option and Koha-MARC links option.
297 * Modify default MARC structure to fit your needs.
300 cd /path/to/koha/misc
301 export PERL5LIB=/path/to/koha
303 the old DB is "copied" in the new MARC one.
304 Koha 2.0.0 is ready :-)
306 Please report any problems you encounter through http://bugs.koha.org/
308 Press <ENTER> to exit the installer: |;
310 sub releasecandidatewarning {
311 my $message=getmessage('ReleaseCandidateWarning', [$newversion, $newversion]);
312 my $answer=showmessage($message, 'yn', 'n');
314 if ($answer =~ /y/i) {
315 print getmessage('continuing');
317 my $message=getmessage('WatchForReleaseAnnouncements');
326 =head2 Accessor functions (for installer.pl)
336 Sets the installation language, normally "en" (English).
337 In fact, only "en" is supported.
341 sub setlanguage ($) {
347 setdomainname('example.org');
349 Sets the domain name of the host.
351 The domain name should not contain a leading dot;
352 otherwise, the results are undefined.
356 sub setdomainname ($) {
364 Sets the sysconfdir, normally /etc.
365 This should be an absolute path; a trailing / is not required.
375 setkohaversion('1.3.3RC26');
377 Sets the Koha version as known by the installer.
381 sub setkohaversion ($) {
387 my $servername = getservername;
389 Gets the name of the Koha virtual server as specified by the user.
393 sub getservername () {
401 Gets the port that will run the Koha OPAC virtual server,
402 as specified by the user.
410 =item getintranetport
412 $port = getintranetport;
414 Gets the port that will run the Koha INTRANET virtual server,
415 as specified by the user.
419 sub getintranetport () {
425 =head2 Miscellaneous utility functions
435 Does the equivalent of dirname(1). Given a path $path, return the
436 parent directory of $path (best guess), except when $path seems to
437 be the same as /, in which case $path itself is returned unchanged.
443 if ($path =~ /[^\/]/s) {
445 $path =~ s/\/+[^\/]+\/*$//s;
456 mkdir_parents $path, $mode;
458 Does the equivalent of mkdir -p, or mkdir --parents. Given a path $path,
459 create the directory $path, recursively creating any intermediate
460 directories. If $mode is given, the directory will be created with
463 WARNING: If $path already exists, mkdir_parents will just return
464 successfully (just like mkdir -p), whether the mode of $path conforms
465 to $mode or not. (This is the behaviour of the mkdir -p command.)
470 my($path, $mode) = @_;
471 my $ok = -d($path)? 1: defined $mode? mkdir($path, $mode): mkdir($path);
473 if (!$ok && $! == ENOENT) {
474 my $parent = dirname($path);
475 $ok = mkdir_parents($parent, $mode);
477 # retry and at the same time make sure that $! is set correctly
478 $ok = defined $mode? mkdir($path, $mode): mkdir($path);
487 getmessage($msgid, $variables);
489 Gets a localized message (format string) with message id $msgid,
490 and, if an array reference of variables $variables is given,
491 substitutes variables in the format string with @$variables.
492 Returns the found message string, with variable substitutions
495 $msgid must be the message identifier corresponding to a defined
496 message string (a valid key to the $messages hash in the Installer
497 package). getmessage throws an exception if the message cannot be
503 my $messagename=shift;
505 my $message=$messages->{$messagename}->{$language} || $messages->{$messagename}->{en} || RED.BOLD."Error: No message named $messagename in Install.pm\n";
506 if (defined($variables)) {
507 $message=sprintf $message, @$variables;
515 showmessage($message, 'none');
516 showmessage($message, 'none', undef, $noclear);
518 $result = showmessage($message, 'yn');
519 $result = showmessage($message, 'yn', $defaultresponse);
520 $result = showmessage($message, 'yn', $defaultresponse, $noclear);
522 $result = showmessage($message, 'restrictchar CHARS');
523 $result = showmessage($message, 'free');
524 $result = showmessage($message, 'silentfree');
525 $result = showmessage($message, 'numerical');
526 $result = showmessage($message, 'email');
527 $result = showmessage($message, 'PressEnter');
529 Shows a message and optionally gets a response from the user.
531 The first two arguments, the message and the response type,
532 are mandatory. The message must be the actual string to
533 display; the caller is responsible for calling getmessage if
536 The response type must be one of "none", "yn", "free", "silentfree"
537 "numerical", "email", "PressEnter", or a string consisting
538 of "restrictchar " followed by a list of allowed characters
539 (space can be specified). (Case is not significant, but case is
540 significant in the list of allowed characters.) If a response
541 type other than the above-listed is specified, the result is
544 Note that the response type "yn" is equivalent to "restrictchar yn".
545 Because "restrictchar" is case-sensitive, the user is expected
546 to enter "y" or "n" in lowercase only.
548 Note that the response type of "email" does not actually
549 guarantee that the returned value is a well-formed RFC-822
550 email address, nor does it accept all well-formed RFC-822 email
551 addresses. What it does is to restrict the returned value to a
552 string that is looks reasonably likely to be an email address
553 in the "real world", given the premise that the user is trying
554 to enter a real email address.
556 If a response type other than "none" or "PressEnter" is
557 specified, a third argument, specifying the default value, can
558 be specified: If this default response is not specified, the
559 default response is the first allowed character if the response
560 type is "restrictchar", otherwise the default response is the
561 empty string. This default response is used when the user does
562 not specify a value (i.e., presses Enter without typing in
563 anything), showmessage will assume that the default response is
566 Note that because the response type "yn" is equivalent to
567 "restrictchar yn", the default value for response type "yn",
568 if unspecified, is "y".
570 The screen is normally cleared before the message is displayed;
571 if a fourth argument is specified and is nonzero, this
572 screen-clearing is not done.
578 #MJR: Maybe refactor to use anonymous functions that
579 # check the responses instead of RnP branching.
580 my $message=join('',fill('','',(shift)));
581 my $responsetype=shift;
582 my $defaultresponse=shift;
584 $noclear = 0 unless defined $noclear; # defaults to "clear"
585 ($noclear) || (print $clear_string);
586 if ($responsetype =~ /^yn$/) {
587 $responsetype='restrictchar ynYN';
589 print RESET.$message;
590 if ($responsetype =~/^restrictchar (.*)/i) {
593 until ($options=~/$response/) {
594 (defined($defaultresponse)) || ($defaultresponse=substr($options,0,1));
597 (length($response)) || ($response=$defaultresponse);
598 if ( $response=~/.*[\:\(\)\^\$\*\!\\].*/ ) {
599 ($noclear) || (print $clear_string);
600 print RED."Response contains invalid characters. Choose from [$options].\n\n";
601 print RESET.$message;
604 unless ($options=~/$response/) {
605 ($noclear) || (print $clear_string);
606 print RED."Invalid Response. Choose from [$options].\n\n";
607 print RESET.$message;
612 } elsif ($responsetype =~/^(silent)?free$/i) {
613 (defined($defaultresponse)) || ($defaultresponse='');
614 if ($responsetype =~/^(silent)/i) { setecho(0) };
615 my $response=<STDIN>;
616 if ($responsetype =~/^(silent)/i) { setecho(1) };
618 ($response) || ($response=$defaultresponse);
620 } elsif ($responsetype =~/^numerical$/i) {
621 (defined($defaultresponse)) || ($defaultresponse='');
623 until ($response=~/^\d+$/) {
626 ($response) || ($response=$defaultresponse);
627 unless ($response=~/^\d+$/) {
628 ($noclear) || (print $clear_string);
629 print RED."Invalid Response ($response). Response must be a number.\n\n";
630 print RESET.$message;
634 } elsif ($responsetype =~/^email$/i) {
635 (defined($defaultresponse)) || ($defaultresponse='');
637 until ($response=~/.*\@.*\..*/) {
640 ($response) || ($response=$defaultresponse);
641 if ($response!~/.*\@.*\..*/) {
642 ($noclear) || (print $clear_string);
643 print RED."Invalid Response ($response). Response must be a valid email address.\n\n";
644 print RESET.$message;
648 } elsif ($responsetype =~/^PressEnter$/i) {
651 } elsif ($responsetype =~/^none$/i) {
654 # FIXME: There are a few places where we will get an undef as the
655 # response type. Should we thrown an exception here, or should we
656 # legitimize this usage and say "none" is the default if not specified?
657 #die "Illegal response type \"$responsetype\"";
668 Changes the display to show system output until the next showmessage call.
669 At the time of writing, this means using red text.
680 =head2 Subtasks of doing an installation
686 =item checkabortedinstall
690 Checks whether a previous installation process has been abnormally
691 aborted, by checking whether $etcidr/koha.conf is a symlink matching
692 a particular pattern. If an aborted installation is detected, give
693 the user a chance to abort, before trying to recover the aborted
696 FIXME: The recovery is not complete; it only partially rolls back
701 sub checkabortedinstall () {
702 if (-l("$etcdir/koha.conf")
703 && readlink("$etcdir/koha.conf") =~ /\.tmp$/
706 I have detected that you tried to install Koha before, but the installation
707 was aborted. I will try to continue, but there might be problems if the
708 database is already created.
711 print "Please press <ENTER> to continue: ";
714 # Remove the symlink after the <STDIN>, so the user can back out
715 unlink "$etcdir/koha.conf"
716 || die "Failed to remove incomplete $etcdir/koha.conf: $!\n";
724 Make sure that we loaded the right dirs from an old koha.conf
728 #FIXME: update to use Install.pm
730 if ($opacdir && $intranetdir) {
733 I believe that your old files are located in:
736 LIBRARIAN: $intranetdir
739 Does this look right? ([Y]/N):
741 my $answer = <STDIN>;
744 if ($answer =~/n/i) {
748 print "Great! continuing upgrade... \n";
752 if (!$opacdir || !$intranetdir) {
755 while (!$intranetdir) {
756 print "Please specify the location of your LIBRARIAN files: ";
758 my $answer = <STDIN>;
762 $intranetdir=$answer;
764 if (! -e "$intranetdir/htdocs") {
765 print "\nCouldn't find the htdocs directory here. That doesn't look right.\nPlease enter another location.\n\n";
770 print "Please specify the location of your OPAC files: ";
772 my $answer = <STDIN>;
778 if (! -e "$opacdir/htdocs") {
779 print "\nCouldn't find the htdocs directory here. That doesn't look right.\nPlease enter another location.\n\n";
787 =item checkperlmodules
791 Test whether the version of Perl is new enough, whether Perl is
792 found at the expected location, and whether all required modules
797 sub checkperlmodules {
799 # Test for Perl and Modules
802 my $message = getmessage('CheckingPerlModules');
803 showmessage($message, 'none');
805 unless ($] >= 5.006001) { # Bug 179
806 die getmessage('PerlVersionFailure', ['5.6.1']);
811 unless (eval {require DBI}) { push @missing,"DBI" };
812 unless (eval {require Date::Manip}) { push @missing,"Date::Manip" };
813 unless (eval {require DBD::mysql}) { push @missing,"DBD::mysql" };
814 unless (eval {require HTML::Template}) { push @missing,"HTML::Template" };
815 # unless (eval {require Set::Scalar}) { push @missing,"Set::Scalar" };
816 unless (eval {require Digest::MD5}) { push @missing,"Digest::MD5" };
817 unless (eval {require MARC::Record}) { push @missing,"MARC::Record" };
818 unless (eval {require Mail::Sendmail}) { push @missing,"Mail::Sendmail" };
819 unless (eval {require Event}) {
820 if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
821 push @missing, "Event";
824 unless (eval {require Net::Z3950}) {
825 showmessage(getmessage('NETZ3950Missing'), 'PressEnter', '', 1);
826 if ($#missing>=0) { # see above note
827 push @missing, "Net::Z3950";
832 # Print out a list of any missing modules
837 if (POSIX::setlocale(LC_ALL) != "C") {
838 $missing.=" export LC_ALL=C\n";
840 foreach my $module (@missing) {
841 $missing.=" perl -MCPAN -e 'install \"$module\"'\n";
843 my $message=getmessage('MissingPerlModules', [$missing]);
844 showmessage($message, 'none');
848 showmessage(getmessage('AllPerlModulesInstalled'), 'PressEnter', '', 1);
853 unless (-x "/usr/bin/perl") {
854 my $realperl=`which perl`;
856 $realperl = showmessage(getmessage('NoUsrBinPerl'), 'none');
857 until (-x $realperl) {
858 $realperl=showmessage(getmessage('AskLocationOfPerlExecutable', $realperl), 'free', $realperl, 1);
860 my $response=showmessage(getmessage('ConfirmPerlExecutableSymlink', $realperl), 'yn', 'y', 1);
861 unless ($response eq 'n') {
863 system("ln -s $realperl /usr/bin/perl");
870 $messages->{'NoUsrBinPerl'}->{en} =
871 heading('No /usr/bin/perl') . qq|
872 Koha expects to find the perl executable in the /usr/bin
873 directory. It is not there on your system.
877 $messages->{'AskLocationOfPerlExecutable'}->{en}=qq|Location of Perl Executable [%s]: |;
878 $messages->{'ConfirmPerlExecutableSymlink'}->{en}=qq|
879 Some Koha scripts will _not_ work without a symlink from %s to /usr/bin/perl
881 Most users should answer Y here.
883 May I try to create this symlink? ([Y]/N):|;
885 $messages->{'DirFailed'}->{en} = RED.qq|
886 We could not create %s, but continuing anyway...
892 =item getinstallationdirectories
894 getinstallationdirectories;
896 Get the various installation directories from the user, and then
897 create those directories (if they do not already exist).
899 These pieces of information are saved to global variables; the
900 function does not return any values.
904 sub getinstallationdirectories {
905 if (!$ENV{prefix}) { $ENV{prefix} = "/usr/local"; }
906 $opacdir = $ENV{prefix}.'/koha/opac';
907 $intranetdir = $ENV{prefix}.'/koha/intranet';
909 while ($getdirinfo) {
910 # Loop until opac directory and koha directory are different
911 my $message=getmessage('GetOpacDir', [$opacdir]);
912 $opacdir=showmessage($message, 'free', $opacdir);
914 $message=getmessage('GetIntranetDir', [$intranetdir]);
915 $intranetdir=showmessage($message, 'free', $intranetdir);
917 if ($intranetdir eq $opacdir) {
920 You must specify different directories for the OPAC and INTRANET files!
921 :: $intranetdir :: $opacdir ::
928 $kohalogdir=$ENV{prefix}.'/koha/log';
929 my $message=getmessage('GetKohaLogDir', [$kohalogdir]);
930 $kohalogdir=showmessage($message, 'free', $kohalogdir);
933 # FIXME: Need better error handling for all mkdir calls here
934 unless ( -d $intranetdir ) {
935 mkdir_parents (dirname($intranetdir), 0775) || print getmessage('DirFailed',['parents of '.$intranetdir]);
936 mkdir ($intranetdir, 0770) || print getmessage('DirFailed',[$intranetdir]);
937 if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2], "$intranetdir"); }
938 chmod 0770, "$intranetdir";
940 mkdir_parents ("$intranetdir/htdocs", 0750);
941 mkdir_parents ("$intranetdir/cgi-bin", 0750);
942 mkdir_parents ("$intranetdir/modules", 0750);
943 mkdir_parents ("$intranetdir/scripts", 0750);
944 unless ( -d $opacdir ) {
945 mkdir_parents (dirname($opacdir), 0775) || print getmessage('DirFailed',['parents of '.$opacdir]);
946 mkdir ($opacdir, 0770) || print getmessage('DirFailed',[$opacdir]);
947 if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2], "$opacdir"); }
948 chmod (oct(770), "$opacdir");
950 mkdir_parents ("$opacdir/htdocs", 0750);
951 mkdir_parents ("$opacdir/cgi-bin", 0750);
954 unless ( -d $kohalogdir ) {
955 mkdir_parents (dirname($kohalogdir), 0775) || print getmessage('DirFailed',['parents of '.$kohalogdir]);
956 mkdir ($kohalogdir, 0770) || print getmessage('DirFailed',[$kohalogdir]);
957 if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2,3], "$kohalogdir"); }
958 chmod (oct(770), "$kohalogdir");
966 Get the MySQL database server installation directory, automatically if possible.
970 $messages->{'WhereIsMySQL'}->{en} = heading('MYSQL LOCATION').qq|
971 Koha can't find MySQL. If you compiled mysql yourself,
972 please give the value of --prefix when you ran configure.
973 The file mysqladmin should be in bin/mysqladmin under the directory that you give here.
975 MySQL installation directory: |;
978 foreach my $mysql (qw(/usr/local/mysql
982 if ( -d $mysql && -f "$mysql/bin/mysqladmin") {
988 $mysqldir = showmessage(getmessage('WhereisMySQL'),'free');
989 last if -f "$mysqldir/bin/mysqladmin";
995 =item getdatabaseinfo
999 Get various pieces of information related to the Koha database:
1000 the name of the database, the host on which the SQL server is
1001 running, and the database user name.
1003 These pieces of information are saved to global variables; the
1004 function does not return any values.
1008 $messages->{'DatabaseName'}->{en} = heading('Database Name') . qq|
1009 Please provide the name that you wish to give your koha database.
1010 It must not exist already on the database server.
1012 Most users give a short single-word name for their library here.
1014 Database name [%s]: |;
1016 $messages->{'DatabaseHost'}->{en} = heading('Database Host') . qq|
1017 Please provide the mysql server name. Unless the database is stored on
1018 another machine, this should be "localhost".
1020 Database host [%s]: |;
1022 $messages->{'DatabaseUser'}->{en} = heading('Database User') . qq|
1023 We are going to create a new mysql user for Koha. This user will have full administrative rights
1024 to the database called %s when they connect from %s.
1025 This is also the name of the Koha librarian superuser.
1027 Most users give a single-word name here.
1029 Database user [%s]: |;
1031 $messages->{'DatabasePassword'}->{en} = heading('Database Password') . qq|
1032 Please provide a good password for the user %s.
1034 IMPORTANT: You can log in using this user and password at any time.
1036 Password for database user %s: |;
1038 $messages->{'BlankPassword'}->{en} = heading('BLANK PASSWORD') . qq|
1039 You must not use a blank password for your MySQL user.
1041 Press <ENTER> to try again:
1044 sub getdatabaseinfo {
1047 $hostname = 'localhost';
1048 $user = 'kohaadmin';
1051 #Get the database name
1053 my $message=getmessage('DatabaseName', [$dbname]);
1054 $dbname=showmessage($message, 'free', $dbname);
1056 #Get the hostname for the database
1058 $message=getmessage('DatabaseHost', [$hostname]);
1059 $hostname=showmessage($message, 'free', $hostname);
1061 #Get the username for the database
1063 $message=getmessage('DatabaseUser', [$dbname, $hostname, $user]);
1064 $user=showmessage($message, 'free', $user);
1066 #Get the password for the database user
1068 while ($pass eq '') {
1069 my $message=getmessage('DatabasePassword', [$user, $user]);
1070 $pass=showmessage($message, 'free', $pass);
1072 my $message=getmessage('BlankPassword');
1073 showmessage($message,'PressEnter');
1084 Get various pieces of information related to the Apache server:
1085 the location of the configuration file and, if needed, the Unix
1086 user that the Koha CGI will be run under.
1088 These pieces of information are saved to global variables; the
1089 function does not return any values.
1093 $messages->{'FoundMultipleApacheConfFiles'}->{en} =
1094 heading('MULTIPLE APACHE CONFIG FILES FOUND') . qq|
1095 I found more than one possible Apache configuration file:
1099 Enter number of the file to read [1]: |;
1101 $messages->{'NoApacheConfFiles'}->{en} =
1102 heading('NO APACHE CONFIG FILE FOUND') . qq|
1103 I was not able to find your Apache configuration file.
1105 The file is usually called httpd.conf, apache.conf or similar.
1107 Please enter the full name, starting with /: |;
1109 $messages->{'NotAFile'}->{en} = heading('FILE DOES NOT EXIST') . qq|
1110 The file %s does not exist.
1112 Please press <ENTER> to continue: |;
1114 $messages->{'EnterApacheUser'}->{en} = heading('NEED APACHE USER') . qq\
1115 The installer could not find the User setting in the Apache configuration file.
1116 This is used to set up access permissions for
1117 %s/koha.conf. This user should be set in one of the Apache configuration.
1118 Please try to find it and enter the user name below. You might find
1119 that "ps u|grep apache" will tell you. It probably is NOT "root".
1121 Enter the Apache userid: \;
1123 $messages->{'InvalidUserid'}->{en} = heading('INVALID USER') . qq|
1124 The userid %s is not a valid userid on this system.
1126 Press <ENTER> to continue: |;
1129 my @confpossibilities;
1131 foreach my $httpdconf (qw(/usr/local/apache/conf/httpd.conf
1132 /usr/local/etc/apache/httpd.conf
1133 /usr/local/etc/apache/apache.conf
1134 /var/www/conf/httpd.conf
1135 /etc/apache2/httpd.conf
1136 /etc/apache2/apache2.conf
1137 /etc/apache/conf/httpd.conf
1138 /etc/apache/conf/apache.conf
1139 /etc/apache-ssl/conf/apache.conf
1140 /etc/apache-ssl/httpd.conf
1141 /etc/httpd/conf/httpd.conf
1142 /etc/httpd/httpd.conf
1143 /etc/httpd/2.0/conf/httpd2.conf
1145 if ( -f $httpdconf ) {
1146 push @confpossibilities, $httpdconf;
1150 if ($#confpossibilities==-1) {
1151 my $message=getmessage('NoApacheConfFiles');
1154 until (-f $realhttpdconf) {
1155 $choice=showmessage($message, "free", 1);
1157 $realhttpdconf=$choice;
1159 showmessage(getmessage('NotAFile', [$choice]),'PressEnter', '', 1);
1162 } elsif ($#confpossibilities>0) {
1166 foreach (@confpossibilities) {
1167 $conffiles.=" $counter: $_\n";
1168 $options.="$counter";
1171 my $message=getmessage('FoundMultipleApacheConfFiles', [$conffiles]);
1172 my $choice=showmessage($message, "restrictchar $options", 1);
1173 $realhttpdconf=$confpossibilities[$choice-1];
1175 $realhttpdconf=$confpossibilities[0];
1177 unless (open (HTTPDCONF, "<$realhttpdconf")) {
1178 warn RED."Insufficient privileges to open $realhttpdconf for reading.\n";
1182 while (<HTTPDCONF>) {
1183 if (/^\s*User\s+"?([-\w]+)"?\s*$/) {
1189 unless (defined($httpduser)) {
1190 my $message=getmessage('EnterApacheUser', [$etcdir]);
1191 until (defined($httpduser) && length($httpduser) && getpwnam($httpduser)) {
1192 $httpduser=showmessage($message, "free", '');
1193 if (length($httpduser)>0) {
1194 unless (getpwnam($httpduser)) {
1195 my $message=getmessage('InvalidUserid', [$httpduser]);
1196 showmessage($message,'PressEnter');
1205 =item getapachevhostinfo
1209 Gets various pieces of information related to virtual hosting:
1210 the webmaster email address, virtual hostname, and the ports
1211 that the OPAC and INTRANET modules run on.
1213 These pieces of information are saved to global variables; the
1214 function does not return any values.
1218 $messages->{'ApacheConfigIntroduction'}->{en} =
1219 heading('APACHE CONFIGURATION') . qq|
1220 Koha needs to write an Apache configuration file for the
1221 OPAC and Librarian sites. By default this installer
1222 will do this by using one name and two different ports
1223 for the virtual hosts. There are other ways to set this up,
1224 and the installer will leave comments in
1225 %s/koha-httpd.conf about them.
1227 NOTE: You will need to add lines to your main httpd.conf to
1228 include %s/koha-httpd.conf
1229 and to make sure it is listening on the right ports
1230 (using the Listen directive).
1232 Press <ENTER> to continue: |;
1234 $messages->{'GetVirtualHostEmail'}->{en} =
1235 heading('WEB E-MAIL CONTACT') . qq|
1236 Enter the e-mail address to be used as a contact for Koha. This
1237 address is displayed if fatal errors are encountered.
1239 E-mail contact [%s]: |;
1241 $messages->{'GetServerName'}->{en} =
1242 heading('WEB HOST NAME OR IP ADDRESS') . qq|
1243 Please enter the host name or IP address that you wish to use for koha.
1244 Normally, this should be a name or IP that belongs to this machine.
1246 Host name or IP Address [%s]: |;
1248 $messages->{'GetOpacPort'}->{en} = heading('OPAC PORT') . qq|
1249 Please enter the port for your OPAC interface. This defaults to port 80, but
1250 if you are already serving web content with this hostname, you should change it
1251 to a different port (8000 might be a good choice, but check any firewalls).
1253 Enter the OPAC Port [%s]: |;
1255 $messages->{'GetIntranetPort'}->{en} =
1256 heading('LIBRARIAN PORT') . qq|
1257 Please enter the port for your Librarian interface. This must be different from
1260 Enter the Intranet Port [%s]: |;
1263 sub getapachevhostinfo {
1265 $svr_admin = "webmaster\@$domainname";
1266 $servername=`hostname`;
1271 showmessage(getmessage('ApacheConfigIntroduction',[$etcdir,$etcdir]), 'PressEnter');
1273 $svr_admin=showmessage(getmessage('GetVirtualHostEmail', [$svr_admin]), 'email', $svr_admin);
1274 $servername=showmessage(getmessage('GetServerName', [$servername]), 'free', $servername);
1277 $opacport=showmessage(getmessage('GetOpacPort', [$opacport]), 'numerical', $opacport);
1278 $intranetport=showmessage(getmessage('GetIntranetPort', [$opacport, $intranetport]), 'numerical', $intranetport);
1283 =item updateapacheconf
1287 Updates the Apache config file according to parameters previously
1288 specified by the user.
1290 It will append fully-commented directives at the end of the original
1291 Apache config file. The old config file is renamed with an extension
1294 If you need to uninstall Koha for any reason, the lines between
1296 # Ports to listen to for Koha
1298 and the block of comments beginning with
1300 # If you want to use name based Virtual Hosting:
1306 $messages->{'StartUpdateApache'}->{en} =
1307 heading('UPDATING APACHE CONFIGURATION') . qq|
1308 Checking for modules that need to be loaded...
1311 $messages->{'ApacheConfigMissingModules'}->{en} =
1312 heading('APACHE CONFIGURATION NEEDS UPDATE') . qq|
1313 Koha uses the mod_env and mod_include apache features, but the
1314 installer did not find them in your config. Please
1315 make sure that they are enabled for your Koha site.
1317 Press <ENTER> to continue: |;
1320 $messages->{'ApacheAlreadyConfigured'}->{en} =
1321 heading('APACHE ALREADY CONFIGURED') . qq|
1322 %s appears to already have an entry for Koha. You may need to edit %s
1323 if anything has changed since it was last set up. This
1324 script will not attempt to modify an existing Koha apache
1327 Press <ENTER> to continue: |;
1329 sub updateapacheconf {
1330 my $logfiledir=$kohalogdir;
1331 my $httpdconf = $etcdir."/koha-httpd.conf";
1333 showmessage(getmessage('StartUpdateApache'), 'none');
1334 # to be polite about it: I don't think this should touch the main httpd.conf
1336 # QUESTION: Should we warn for includes_module too?
1338 my $includesmodule=0;
1339 open HC, "<$realhttpdconf";
1341 if (/^\s*#\s*LoadModule env_module /) {
1342 showmessage(getmessage('ApacheConfigMissingModules'));
1345 if (/\s*LoadModule includes_module / ) {
1351 if (`grep -q 'VirtualHost $servername' "$httpdconf" 2>/dev/null`) {
1352 showmessage(getmessage('ApacheAlreadyConfigured', [$httpdconf, $httpdconf]), 'PressEnter');
1355 my $includesdirectives='';
1356 if ($includesmodule) {
1357 $includesdirectives.="Options +Includes\n";
1358 $includesdirectives.=" AddHandler server-parsed .html\n";
1360 open(SITE,">$httpdconf") or warn "Insufficient priveleges to open $httpdconf for writing.\n";
1361 my $opaclisten = '';
1362 if ($opacport != 80) {
1363 $opaclisten="Listen $opacport";
1365 my $intranetlisten = '';
1366 if ($intranetport != 80) {
1367 $intranetlisten="Listen $intranetport";
1371 # Ports to listen to for Koha
1372 # uncomment these if they aren't already in main httpd.conf
1376 # NameVirtualHost is used by one of the optional configurations detailed below
1378 #NameVirtualHost 11.22.33.44
1380 # KOHA's OPAC Configuration
1381 <VirtualHost $servername\:$opacport>
1382 ServerAdmin $svr_admin
1383 DocumentRoot $opacdir/htdocs
1384 ServerName $servername
1385 ScriptAlias /cgi-bin/koha/ $opacdir/cgi-bin/
1386 ErrorLog $logfiledir/opac-error_log
1387 TransferLog $logfiledir/opac-access_log
1388 SetEnv PERL5LIB "$intranetdir/modules"
1389 SetEnv KOHA_CONF "$etcdir/koha.conf"
1393 # KOHA's INTRANET Configuration
1394 <VirtualHost $servername\:$intranetport>
1395 ServerAdmin $svr_admin
1396 DocumentRoot $intranetdir/htdocs
1397 ServerName $servername
1398 ScriptAlias /cgi-bin/koha/ "$intranetdir/cgi-bin/"
1399 ErrorLog $logfiledir/koha-error_log
1400 TransferLog $logfiledir/koha-access_log
1401 SetEnv PERL5LIB "$intranetdir/modules"
1402 SetEnv KOHA_CONF "$etcdir/koha.conf"
1406 # If you want to use name based Virtual Hosting:
1407 # 1. remove the two Listen lines
1408 # 2. replace $servername\:$opacport wih your.opac.domain.name
1409 # 3. replace ServerName $servername wih ServerName your.opac.domain.name
1410 # 4. replace $servername\:$intranetport wih your intranet domain name
1411 # 5. replace ServerName $servername wih ServerName your.intranet.domain.name
1413 # If you want to use NameVirtualHost'ing (using two names on one ip address):
1414 # 1. Follow steps 1-5 above
1415 # 2. Uncomment the NameVirtualHost line and set the correct ip address
1424 =item basicauthentication
1426 basicauthentication;
1428 Asks the user whether HTTP basic authentication is wanted, and,
1429 if so, the user name and password for the basic authentication.
1431 These pieces of information are saved to global variables; the
1432 function does not return any values.
1436 $messages->{'IntranetAuthenticationQuestion'}->{en} =
1437 heading('LIBRARIAN AUTHENTICATION') . qq|
1438 The Librarian site can be password protected using
1439 Apache's Basic Authorization instead of Koha user details.
1441 This method going to be phased out very soon. Most users should answer N here.
1443 Would you like to do this (Y/[N]): |; #'
1445 $messages->{'BasicAuthUsername'}->{en}="Please enter a username for librarian access [%s]: ";
1446 $messages->{'BasicAuthPassword'}->{en}="Please enter a password for %s: ";
1447 $messages->{'BasicAuthPasswordWasBlank'}->{en}="\nYou cannot use a blank password!\n\n";
1449 sub basicauthentication {
1450 my $message=getmessage('IntranetAuthenticationQuestion');
1451 my $answer=showmessage($message, 'yn', 'n');
1452 my $httpdconf = $etcdir."/koha-httpd.conf";
1454 my $apacheauthusername='librarian';
1455 my $apacheauthpassword='';
1456 if ($answer=~/^y/i) {
1457 ($apacheauthusername) = showmessage(getmessage('BasicAuthUsername', [ $apacheauthusername]), 'free', $apacheauthusername, 1);
1458 $apacheauthusername=~s/[^a-zA-Z0-9]//g;
1459 while (! $apacheauthpassword) {
1460 ($apacheauthpassword) = showmessage(getmessage('BasicAuthPassword', [ $apacheauthusername]), 'free', 1);
1461 if (!$apacheauthpassword) {
1462 ($apacheauthpassword) = showmessage(getmessage('BasicAuthPasswordWasBlank'), 'none', '', 1);
1465 open AUTH, ">$etcdir/kohaintranet.pass";
1466 my $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
1467 my $salt=substr($chars, int(rand(length($chars))),1);
1468 $salt.=substr($chars, int(rand(length($chars))),1);
1469 print AUTH $apacheauthusername.":".crypt($apacheauthpassword, $salt)."\n";
1471 open(SITE,">>$httpdconf") or warn "Insufficient priveleges to open $realhttpdconf for writing.\n";
1474 <Directory $intranetdir>
1475 AuthUserFile $etcdir/kohaintranet.pass
1477 AuthName "Koha Intranet (for librarians only)"
1490 Install the Koha files to the specified OPAC and INTRANET
1491 directories (usually in /usr/local/koha).
1493 The koha.conf file is created, but as koha.conf.tmp. The
1494 caller is responsible for calling finalizeconfigfile when
1495 installation is completed, to rename it back to koha.conf.
1499 $messages->{'InstallFiles'}->{en} = heading('INSTALLING FILES') . qq|
1500 Copying files to installation directories:
1504 $messages->{'OldFiles'}->{en} = heading('OLD FILES') . qq|
1505 Any files from the previous edition of Koha have been
1506 copied to a dated backup directory alongside the new
1507 installation. You should move any custom files that you
1508 want to keep (such as your site templates) into the new
1509 directories and then move the backup off of the live
1512 Press ENTER to continue:|;
1515 $messages->{'CopyingFiles'}->{en}="Copying %s to %s.\n";
1521 #MJR: preserve old files, just in case
1528 print getmessage('CopyingFiles', ["old ".$desc,$tgt.strftime("%Y%m%d%H%M",localtime())]);
1530 system("mv ".$tgt." ".$tgt.".old");
1533 print getmessage('CopyingFiles', [$desc,$tgt]);
1535 system("cp -R ".$src." ".$tgt);
1538 showmessage(getmessage('InstallFiles'),'none');
1540 neatcopy("admin templates", 'intranet-html', "$intranetdir/htdocs");
1541 neatcopy("admin interface", 'intranet-cgi', "$intranetdir/cgi-bin");
1542 neatcopy("main scripts", 'scripts', "$intranetdir/scripts");
1543 neatcopy("perl modules", 'modules', "$intranetdir/modules");
1544 neatcopy("OPAC templates", 'opac-html', "$opacdir/htdocs");
1545 neatcopy("OPAC interface", 'opac-cgi', "$opacdir/cgi-bin");
1547 system("touch $opacdir/cgi-bin/opac");
1549 #MJR: is this necessary?
1551 system("chown -R $httpduser:$httpduser $opacdir $intranetdir");
1553 system("chmod -R a+rx $opacdir $intranetdir");
1555 # Create /etc/koha.conf
1557 my $old_umask = umask(027); # make sure koha.conf is never world-readable
1558 open(SITES,">$etcdir/koha.conf.tmp") or warn "Couldn't create file at $etcdir. Must have write capability.\n";
1564 includes=$opacdir/htdocs/includes
1565 intranetdir=$intranetdir
1567 kohalogdir=$kohalogdir
1568 kohaversion=$newversion
1569 httpduser=$httpduser
1570 intrahtdocs=$intranetdir/htdocs/intranet-tmpl
1571 opachtdocs=$opacdir/htdocs/opac-tmpl
1577 #MJR: can't help but this be broken, can we?
1578 chmod 0440, "$etcdir/koha.conf.tmp";
1580 #MJR: does this contain any passwords?
1581 chmod 0755, "$intranetdir/scripts/z3950daemon/z3950-daemon-launch.sh", "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh", "$intranetdir/scripts/z3950daemon/processz3950queue";
1583 #MJR: generate our own settings, to remove the /home/paul hardwired links
1584 open(FILE,">$intranetdir/scripts/z3950daemon/z3950-daemon-options");
1585 print FILE "RunAsUser=apache\nKohaZ3950Dir=$intranetdir/scripts/z3950daemon\nKohaModuleDir=$intranetdir/modules\nLogDir=$kohalogdir\nKohaConf=$etcdir/koha.conf";
1589 chown((getpwnam($httpduser)) [2,3], "$etcdir/koha.conf.tmp") or warn "can't chown koha.conf: $!";
1590 chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh") or warn "can't chown $intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh: $!";
1591 chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/processz3950queue") or warn "can't chown $intranetdir/scripts/z3950daemon/processz3950queue: $!";
1592 } #MJR: FIXME: Should report that we haven't chown()d.
1594 showmessage(getmessage('OldFiles'),'PressEnter');
1602 Finds out where the MySQL utitlities are located in the system,
1603 then create the Koha database structure and MySQL permissions.
1607 $messages->{'MysqlRootPassword'}->{en} =
1608 heading('MYSQL ROOT USER PASSWORD') . qq|
1609 To create the koha database, please enter your
1610 mysql server's root user password:
1614 $messages->{'CreatingDatabase'}->{en} = heading('CREATING DATABASE') . qq|
1615 Creating the MySQL database for Koha...
1619 $messages->{'CreatingDatabaseError'}->{en} =
1620 heading('ERROR CREATING DATABASE') . qq|
1621 Couldn't connect to the MySQL server for the reason given above.
1622 This is a serious problem, the database will not get installed.
1624 Press <ENTER> to continue: |; #'
1626 $messages->{'SampleData'}->{en} = heading('SAMPLE DATA') . qq|
1627 If you are installing Koha for evaluation purposes,
1628 you can install some sample data now.
1630 If you are installing Koha to use your own
1631 data, you probably don't want this sample data installed.
1633 Would you like to install the sample data? Y/[N]: |; #'
1635 $messages->{'SampleDataInstalled'}->{en} =
1636 heading('SAMPLE DATA INSTALLED') . qq|
1637 Sample data has been installed. For some suggestions on testing Koha, please
1638 read the file doc/HOWTO-Testing. If you find any bugs, please submit them at
1639 http://bugs.koha.org/. If you need help with testing Koha, you can post a
1640 question through the koha-devel mailing list, or you can check for a developer
1641 online at irc.katipo.co.nz:6667 channel #koha.
1643 You can find instructions for subscribing to the Koha mailing lists at:
1648 Press <ENTER> to continue: |;
1650 $messages->{'AddBranchPrinter'}->{en} = heading('Add Branch and Printer') . qq|
1651 Would you like to describe an initial branch and printer? [Y]/N: |;
1653 $messages->{'BranchName'}->{en}="Branch Name [%s]: ";
1654 $messages->{'BranchCode'}->{en}="Branch Code (4 letters or numbers) [%s]: ";
1655 $messages->{'PrinterQueue'}->{en}="Printer Queue [%s]: ";
1656 $messages->{'PrinterName'}->{en}="Printer Name [%s]: ";
1659 $mysqluser = 'root';
1661 my $mysqldir = getmysqldir();
1663 # we must not put the mysql root password on the command line
1664 $mysqlpass= showmessage(getmessage('MysqlRootPassword'),'silentfree');
1666 showmessage(getmessage('CreatingDatabase'),'none');
1668 setmysqlclipass($mysqlpass);
1669 # Set up permissions
1671 print system("$mysqldir/bin/mysql -u$mysqluser mysql -e \"insert into user (Host,User,Password) values ('$hostname','$user',password('$pass'))\"\;");
1672 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 ('%','$dbname','$user','Y','Y','Y','Y','Y','Y','Y','Y')\"");
1673 system("$mysqldir/bin/mysqladmin -u$mysqluser reload");
1674 # Change to admin user login
1675 setmysqlclipass($pass);
1676 my $result=system("$mysqldir/bin/mysqladmin", "-u$user", "create", "$dbname");
1678 showmessage(getmessage('CreatingDatabaseError'),'PressEnter', '', 1);
1680 # Create the database structure
1682 system("$mysqldir/bin/mysql -u$user $dbname < koha.mysql");
1688 =item updatedatabase
1692 Updates the Koha database structure, including the addition of
1695 The MARC tables are also populated in addition to being created.
1697 Because updatedatabase calls scripts/updater/updatedatabase to
1698 do the actual update, and that script uses C4::Context,
1699 $etcdir/koha.conf must exist at this point. We use the KOHA_CONF
1700 environment variable to do this.
1702 FIXME: (See checkabortedinstall as it depends on old symlink way.)
1706 $messages->{'UpdateMarcTables'}->{en} =
1707 heading('MARC FIELD DEFINITIONS') . qq|
1708 You can import MARC settings for:
1714 NOTE: If you choose N,
1715 nothing will be added, and you must create them all yourself.
1716 Only choose N if you want to use a MARC format not listed here,
1717 such as DANMARC. We would like to hear from you if you do.
1719 Choose MARC definition [1]: |;
1721 $messages->{'Language'}->{en} = heading('CHOOSE LANGUAGE') . qq|
1722 This version of koha supports a few languages.
1724 en : default language, all pages available
1725 fr : complete translation (except pictures)
1726 es : partial librarian site translation (including pictures)
1727 pl : complete OPAC and partial librarian translation
1728 zh_TW : partial translation
1730 en is used when a screen is not available in your language
1732 If you specify a language here, you can still
1733 change it from the system preferences screen in the librarian sit.
1735 Which language do you choose? |;
1737 sub updatedatabase {
1738 # At this point, $etcdir/koha.conf must exist, for C4::Context
1739 $ENV{"KOHA_CONF"}=$etcdir.'/koha.conf.tmp';
1741 my $result=system ("perl -I $intranetdir/modules scripts/updater/updatedatabase");
1744 print "Problem updating database...\n";
1748 if ($kohaversion =~ /^1\.[012]\./) {
1749 my $response=showmessage(getmessage('UpdateMarcTables'), 'restrictchar 12N', '1');
1752 if ($response eq '1') {
1753 system("cat scripts/misc/marc_datas/marc21_en/structure_def.sql | $mysqldir/bin/mysql -u$user $dbname");
1755 if ($response eq '2') {
1756 system("cat scripts/misc/marc_datas/unimarc_fr/structure_def.sql | $mysqldir/bin/mysql -u$user $dbname");
1757 system("cat scripts/misc/lang-datas/fr/stopwords.sql | $mysqldir/bin/mysql -u$user $dbname");
1759 delete($ENV{"KOHA_CONF"});
1762 print RESET."\n\nFinished updating of database. Press <ENTER> to continue...";
1767 =item populatedatabase
1771 Populate the non-MARC tables. If the user wants to install the
1772 sample data, install them.
1776 sub populatedatabase {
1777 # my $response=showmessage(getmessage('SampleData'), 'yn', 'n');
1778 # if ($response =~/^y/i) {
1780 # FIXME: These calls are now unsafe and should either be removed
1781 # or updated to use -u$user and no mysqlpass_quoted
1783 # system("gunzip -d < sampledata-1.2.gz | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname");
1784 # system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branches (branchcode,branchname,issuing) values ('MAIN', 'Main Library', 1)\"");
1785 # system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1786 # system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1787 # system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into printers (printername,printqueue,printtype) values ('Circulation Desk Printer', 'lp', 'hp')\"");
1788 # showmessage(getmessage('SampleDataInstalled'), 'PressEnter','',1);
1791 my $response=showmessage(getmessage('AddBranchPrinter'), 'yn', 'y');
1793 unless ($response =~/^n/i) {
1794 my $branch='Main Library';
1795 $branch=showmessage(getmessage('BranchName', [$branch]), 'free', $branch, 1);
1796 $branch=~s/[^A-Za-z0-9\s]//g;
1798 my $branchcode=$branch;
1799 $branchcode=~s/[^A-Za-z0-9]//g;
1800 $branchcode=uc($branchcode);
1801 $branchcode=substr($branchcode,0,4);
1802 $branchcode=showmessage(getmessage('BranchCode', [$branchcode]), 'free', $branchcode, 1);
1803 $branchcode=~s/[^A-Za-z0-9]//g;
1804 $branchcode=uc($branchcode);
1805 $branchcode=substr($branchcode,0,4);
1806 $branchcode or $branchcode='DEF';
1809 system("$mysqldir/bin/mysql -u$user $dbname -e \"insert into branches (branchcode,branchname,issuing) values ('$branchcode', '$branch', 1)\"");
1810 system("$mysqldir/bin/mysql -u$user $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1811 system("$mysqldir/bin/mysql -u$user $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1813 my $printername='Library Printer';
1814 $printername=showmessage(getmessage('PrinterName', [$printername]), 'free', $printername, 1);
1815 $printername=~s/[^A-Za-z0-9\s]//g;
1817 my $printerqueue='lp';
1818 $printerqueue=showmessage(getmessage('PrinterQueue', [$printerqueue]), 'free', $printerqueue, 1);
1819 $printerqueue=~s/[^A-Za-z0-9]//g;
1821 system("$mysqldir/bin/mysql -u$user $dbname -e \"insert into printers (printername,printqueue,printtype) values ('$printername', '$printerqueue', '')\"");
1823 my $language=showmessage(getmessage('Language'), 'free', 'en');
1825 system("$mysqldir/bin/mysql -u$user $dbname -e \"update systempreferences set value='$language' where variable='opaclanguages'\"");
1834 Asks the user whether to restart Apache, and restart it if the user
1839 $messages->{'RestartApache'}->{en} = heading('RESTART APACHE') . qq|
1840 The web server daemon needs to be restarted to load the new configuration for Koha.
1841 The installer can do this if you are using Apache and give the root password.
1843 Would you like to try to restart Apache now? [Y]/N: |;
1847 my $response=showmessage(getmessage('RestartApache'), 'yn', 'y');
1849 unless ($response=~/^n/i) {
1851 # Need to support other init structures here?
1852 if (-e "/etc/rc.d/init.d/httpd") {
1853 system('su root -c /etc/rc.d/init.d/httpd restart');
1854 } elsif (-e "/etc/init.d/apache") {
1855 system('su root -c /etc/init.d/apache restart');
1856 } elsif (-e "/etc/init.d/apache-ssl") {
1857 system('su root -c /etc/init.d/apache-ssl restart');
1867 This function attempts to back up all koha's details.
1871 $messages->{'BackupDir'}->{en} = heading('BACKUP STORAGE').qq|
1872 The upgrader will now try to backup your old files.
1874 Please specify a directory to store the backup in [%s]: |;
1876 $messages->{'BackupSummary'}->{en} = heading('BACKUP SUMMARY').qq|
1880 %6d biblioitems entries
1885 ---------------------------------------------------------------------
1887 ---------------------------------------------------------------------
1889 Does this look right? ([Y]/N): |;
1891 #FIXME: rewrite to use Install.pm
1893 my $backupdir=$ENV{'prefix'}.'/backups';
1895 my $answer = showmessage(getmessage('BackupDir',[$backupdir]),'free',$backupdir);
1897 if (! -e $backupdir) {
1898 my $result=mkdir ($backupdir, oct(770));
1900 my @dirs = split(m#/#, $backupdir);
1904 unless (-e "$checkdir") {
1905 mkdir($checkdir, 0775);
1911 chmod 0770, $backupdir;
1913 # Backup MySql database
1916 my $mysqldir = getmysqldir();
1918 my ($sec, $min, $hr, $day, $month, $year) = (localtime(time))[0,1,2,3,4,5];
1921 my $date= sprintf "%4d-%02d-%02d_%02d:%02d:%02d", $year, $month, $day,$hr,$min,$sec;
1923 open (MD, "$mysqldir/bin/mysqldump --user=$user --password=$pass --host=$hostname $database|");
1925 (open BF, ">$backupdir/Koha.backup_$date") || (die "Error opening up backup file $backupdir/Koha.backup_$date: $!\n");
1928 my $bibliocounter=0;
1929 my $biblioitemcounter=0;
1930 my $membercounter=0;
1933 (/insert into items /i) && ($itemcounter++);
1934 (/insert into biblioitems /i) && ($biblioitemcounter++);
1935 (/insert into biblio /i) && ($bibliocounter++);
1936 (/insert into borrowers /i) && ($membercounter++);
1943 my $filels=`ls -hl $backupdir/Koha.backup_$date`;
1945 $answer = showmessage(getmessage('BackupSummary',[$bibliocounter, $biblioitemcounter, $itemcounter, $membercounter, $filels]),'yn');
1947 if ($answer=~/^n/i) {
1950 Aborting. The database dump is located in:
1952 $backupdir/Koha.backup_$date
1957 print "Great! continuing upgrade... \n";
1964 =item finalizeconfigfile
1968 This function must be called when the installation is complete,
1969 to rename the koha.conf.tmp file to koha.conf.
1971 Currently, failure to rename the file results only in a warning.
1975 sub finalizeconfigfile {
1977 rename "$etcdir/koha.conf.tmp", "$etcdir/koha.conf"
1978 || showmessage(<<EOF, 'PressEnter', undef, 1);
1979 An unexpected error, $!, occurred
1980 while the Koha config file is being saved to its final location,
1983 Couldn't rename file at $etcdir. Must have write capability.
1985 Press Enter to continue.
1991 =item loadconfigfile
1995 Open the existing koha.conf file and get its values,
1996 saving the values to some global variables.
1998 If the existing koha.conf file cannot be opened for any reason,
1999 the file is silently ignored.
2003 sub loadconfigfile {
2006 #MJR: reverted to r1.53. Please call setetcdir(). Do NOT hardcode this.
2007 #FIXME: make a dated backup
2008 open (KC, "<$etcdir/koha.conf");
2011 (next) if (/^\s*#/);
2012 if (/(.*)\s*=\s*(.*)/) {
2015 # Clean up white space at beginning and end
2016 $variable=~s/^\s*//g;
2017 $variable=~s/\s*$//g;
2020 $configfile{$variable}=$value;
2024 #MJR: Reverted this too. You do not mess with my privates. Please ask for new functions if required.
2025 $intranetdir=$configfile{'intranetdir'};
2026 $opacdir=$configfile{'opacdir'};
2027 $kohaversion=$configfile{'kohaversion'};
2028 $kohalogdir=$configfile{'kohalogdir'};
2029 $database=$configfile{'database'};
2030 $hostname=$configfile{'hostname'};
2031 $user=$configfile{'user'};
2032 $pass=$configfile{'pass'};
2035 END { } # module clean-up code here (global destructor)
2037 ### These things may move
2041 my $t = POSIX::Termios->new;
2045 $t->setlflag(($t->getlflag) | &POSIX::ECHO);
2048 $t->setlflag(($t->getlflag) & !(&POSIX::ECHO));
2053 sub setmysqlclipass {
2055 open(MYCNF,">$mycnf");
2057 print MYCNF "[client]\npassword=$pass\n";
2063 rename $mycnf,$mytmpcnf;
2072 rename $mytmpcnf,$mycnf;