Moved getmessage and showmessage closer to the front, so that the generated
[koha_fer] / misc / Install.pm
1 package Install; #assumes Install.pm
2
3
4 # Copyright 2000-2002 Katipo Communications
5 #
6 # This file is part of Koha.
7 #
8 # Koha is free software; you can redistribute it and/or modify it under the
9 # terms of the GNU General Public License as published by the Free Software
10 # Foundation; either version 2 of the License, or (at your option) any later
11 # version.
12 #
13 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
14 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License along with
18 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
19 # Suite 330, Boston, MA  02111-1307 USA
20
21 use strict;
22 use POSIX;
23 require Exporter;
24
25 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
26
27 =head1 NAME
28
29 Install.pm - Perl module containing the bulk of the installation logic
30
31 =head1 DESCRIPTION
32
33 The Install.pm module contains the bulk
34 of the code to do installation;
35 this code is used by installer.pl
36 to perform an actual installation.
37
38 =head2 Internal functions (not meant to be used outside of Install.pm)
39
40 =over 4
41
42 =cut
43
44 # set the version for version checking
45 $VERSION = 0.01;
46
47 @ISA = qw(Exporter);
48 @EXPORT = qw(   &checkperlmodules
49                 &checkabortedinstall
50                 &getmessage
51                 &showmessage
52                 &releasecandidatewarning
53                 &getinstallationdirectories
54                 &getdatabaseinfo
55                 &getapacheinfo
56                 &getapachevhostinfo
57                 &updateapacheconf
58                 &basicauthentication
59                 &installfiles
60                 &databasesetup
61                 &updatedatabase
62                 &populatedatabase
63                 &restartapache
64                 &loadconfigfile
65                 );
66
67 use vars qw( $kohaversion );                    # set in installer.pl
68 use vars qw( $language );                       # set in installer.pl
69 use vars qw( $domainname );                     # set in installer.pl
70
71 use vars qw( $etcdir );                         # set in installer.pl, usu. /etc
72 use vars qw( $intranetdir $opacdir $kohalogdir );
73 use vars qw( $realhttpdconf $httpduser );
74 use vars qw( $servername $svr_admin $opacport $intranetport );
75 use vars qw( $mysqldir );
76 use vars qw( $database $mysqluser );
77 use vars qw( $mysqlpass );                      # normally should not be used
78 use vars qw( $mysqlpass_quoted );               # quoted, contains -p as needed
79 use vars qw( $dbname $hostname $user $pass );   # virtual hosting
80
81 use vars qw( $newversion );                     # XXX this seems to be unused
82
83 =item heading
84
85     $messages->{'WelcomeToKohaInstaller'
86         = heading('Welcome to the Koha Installer') . qq|...|;
87
88 The heading function takes one string, the text to be displayed as
89 the heading, and returns a formatted heading (currently formatted
90 in the "traditional Koha installer" style, i.e., surrounded by a
91 box of equal signs).
92
93 This reduces the likelihood of pod2man(1) etc. misinterpreting
94 a line of equal signs as POD directives.
95
96 =cut
97
98 sub heading ($) {
99    my($s) = @_;
100    my $n = length($s) + 4;
101    my $line = ('=' x $n) . "\n";
102    "\n$line= $s =\n$line\n";
103 }
104
105 my $messages;
106 $messages->{'continuing'}->{en}="Great!  Continuing setup.\n\n";
107 $messages->{'WelcomeToKohaInstaller'}->{en} =
108    heading('Welcome to the Koha Installer') . qq|
109 Welcome to the Koha install script!  This script will prompt you for some
110 basic information about your desired setup, then install Koha according to
111 your specifications.  To accept the default value for any question, simply hit
112 Enter at the prompt.
113
114 Please be sure to read the documentation, or visit the Koha website at
115 http://www.koha.org for more information.
116
117 Are you ready to begin the installation? (Y/[N]): |;
118 $messages->{'ReleaseCandidateWarning'}->{en} =
119    heading('RELEASE CANDIDATE') . qq|
120 WARNING WARNING WARNING WARNING WARNING
121
122 You are about to install Koha version %s.  This version of Koha is a
123 release candidate.  It is not intended to be installed on production systems.
124 It is being released so that users can test it before we release a final
125 version.
126
127 Are you sure you want to install Koha %s? (Y/[N]): |;
128 $messages->{'WatchForReleaseAnnouncements'}->{en}=qq|
129
130 Watch for announcements of Koha releases on the Koha mailing list or the Koha
131 web site (http://www.koha.org/).
132
133 |;
134
135 $messages->{'NETZ3950Missing'}->{en}=qq|
136
137 The Net::Z3950 module is missing.  This module is necessary if you want to use
138 Koha's Z39.50 client to download bibliographic records from other libraries.
139 To install this module, you will need the yaz client installed from
140 http://www.indexdata.dk/yaz/ and then you can install the perl module with the
141 command:
142
143 perl -MCPAN -e 'install Net::Z3950'
144
145 Press the <ENTER> key to continue: |;
146
147 $messages->{'CheckingPerlModules'}->{en} = heading('PERL & MODULES') . qq|
148 Checking perl modules ...
149 |;
150
151 $messages->{'PerlVersionFailure'}->{en}="Sorry, you need at least Perl %s\n";
152
153 $messages->{'MissingPerlModules'}->{en} = heading('MISSING PERL MODULES') . qq|
154 You are missing some Perl modules which are required by Koha.
155 Once these modules have been installed, rerun this installer.
156 They can be installed by running (as root) the following:
157
158 %s
159 |;
160
161 $messages->{'AllPerlModulesInstalled'}->{en} =
162    heading('ALL PERL MODULES INSTALLED') . qq|
163 All mandatory perl modules are installed.
164
165 Press <ENTER> to continue: |;
166 $messages->{'KohaVersionInstalled'}->{en}="You currently have Koha %s on your system.";
167 $messages->{'KohaUnknownVersionInstalled'}->{en}="I am not able to determine what version of Koha is installed now.";
168 $messages->{'KohaAlreadyInstalled'}->{en} =
169    heading('Koha already installed') . qq|
170 It looks like Koha is already installed on your system (%s/koha.conf exists
171 already).  If you would like to upgrade your system to %s, please use
172 the koha.upgrade script in this directory.
173
174 %s
175
176 |;
177 $messages->{'GetOpacDir'}->{en} = heading('OPAC DIRECTORY') . qq|
178 Please supply the directory you want Koha to store its OPAC files in.  This
179 directory will be auto-created for you if it doesn't exist.
180
181 OPAC Directory [%s]: |;
182
183 $messages->{'GetIntranetDir'}->{en} =
184    heading('INTRANET/LIBRARIANS DIRECTORY') . qq|
185 Please supply the directory you want Koha to store its Intranet/Librarians
186 files in.  This directory will be auto-created for you if it doesn't exist.
187
188 Intranet Directory [%s]: |;
189
190 $messages->{'GetKohaLogDir'}->{en} = heading('KOHA LOG DIRECTORY') . qq|
191 Specify a log directory where any Koha daemons can create log files.
192
193 Koha Log Directory [%s]: |;
194
195 $messages->{'AuthenticationWarning'}->{en} = heading('Authentication') . qq|
196 This release of Koha has a new authentication module.  If you are not already
197 using basic authentication on your intranet, you will be required to log in to
198 access some of the features of the intranet.  You can log in using the userid
199 and password from the %s/koha.conf configuration file at any time.  Use the
200 "Members" module to add passwords for other accounts and set their permissions.
201
202 Press the <ENTER> key to continue: |;
203
204 $messages->{'Completed'}->{en} = heading('KOHA INSTALLATION COMPLETE') . qq|
205 Congratulations ... your Koha installation is complete!
206
207 You will be able to connect to your Librarian interface at:
208
209    http://%s\:%s/
210
211 and the OPAC interface at :
212
213    http://%s\:%s/
214
215 Be sure to read the INSTALL, and Hints files.
216
217 For more information visit http://www.koha.org
218
219 Press <ENTER> to exit the installer: |;
220
221 sub releasecandidatewarning {
222     my $message=getmessage('ReleaseCandidateWarning', [$newversion, $newversion]);
223     my $answer=showmessage($message, 'yn', 'n');
224
225     if ($answer =~ /y/i) {
226         print getmessage('continuing');
227     } else {
228         my $message=getmessage('WatchForReleaseAnnouncements');
229         print $message;
230         exit;
231     };
232 }
233
234
235 =back
236
237 =head2 Accessor functions (for installer.pl)
238
239 =over 4
240
241 =cut
242
243 =item setlanguage
244
245     setlanguage('en');
246
247 Sets the installation language, normally "en" (English).
248 In fact, only "en" is supported.
249
250 =cut
251
252 sub setlanguage ($) {
253     ($language) = @_;
254 }
255
256 =item setdomainname
257
258     setdomainname('example.org');
259
260 Sets the domain name of the host.
261
262 The domain name should not contain a leading dot;
263 otherwise, the results are undefined.
264
265 =cut
266
267 sub setdomainname ($) {
268     ($domainname) = @_;
269 }
270
271 =item setetcdir
272
273     setetcdir('/etc');
274
275 Sets the sysconfdir, normally /etc.
276 This should be an absolute path; a trailing / is not required.
277
278 =cut
279
280 sub setetcdir ($) {
281     ($etcdir) = @_;
282 }
283
284 =item setkohaversion
285
286     setkohaversion('1.3.3RC26');
287
288 Sets the Koha version as known by the installer.
289
290 =cut
291
292 sub setkohaversion ($) {
293     ($kohaversion) = @_;
294 }
295
296 =item getservername
297
298     my $servername = getservername;
299
300 Gets the name of the Koha virtual server as specified by the user.
301
302 =cut
303
304 sub getservername () {
305     $servername;
306 }
307
308 =item getopacport
309
310     $port = getopacport;
311
312 Gets the port that will run the Koha OPAC virtual server,
313 as specified by the user.
314
315 =cut
316
317 sub getopacport () {
318     $opacport;
319 }
320
321 =item getintranetport
322
323     $port = getintranetport;
324
325 Gets the port that will run the Koha INTRANET virtual server,
326 as specified by the user.
327
328 =cut
329
330 sub getintranetport () {
331     $intranetport;
332 }
333
334 =back
335
336 =head2 Miscellaneous utility functions
337
338 =over 4
339
340 =cut
341
342 =item dirname
343
344     dirname $path;
345
346 Does the equivalent of dirname(1). Given a path $path, return the
347 parent directory of $path (best guess), except when $path seems to
348 be the same as /, in which case $path itself is returned unchanged.
349
350 =cut
351
352 sub dirname ($;$) {
353     my($path) = @_;
354     if ($path =~ /[^\/]/s) {
355         if ($path =~ /\//) {
356             $path =~ s/\/+[^\/]+\/*$//s;
357         } else {
358             $path = '.';
359         }
360     }
361     return $path;
362 }
363
364 =item mkdir_parents
365
366     mkdir_parents $path;
367     mkdir_parents $path, $mode;
368
369 Does the equivalent of mkdir -p, or mkdir --parents. Given a path $path,
370 create the directory $path, recursively creating any intermediate
371 directories. If $mode is given, the directory will be created with
372 mode $mode.
373
374 WARNING: If $path already exists, mkdir_parents will just return
375 successfully (just like mkdir -p), whether the mode of $path conforms
376 to $mode or not. (This is the behaviour of the mkdir -p command.)
377
378 =cut
379
380 sub mkdir_parents ($;$) {
381     my($path, $mode) = @_;
382     my $ok = -d($path)? 1: defined $mode? mkdir($path, $mode): mkdir($path);
383
384     if (!$ok && $! == ENOENT) {
385         my $parent = dirname($path);
386         $ok = mkdir_parents($parent, $mode);
387
388         # retry and at the same time make sure that $! is set correctly
389         $ok = defined $mode? mkdir($path, $mode): mkdir($path);
390     }
391     return $ok;
392 }
393
394
395 =item getmessage
396
397     getmessage($msgid);
398     getmessage($msgid, $variables);
399
400 Gets a localized message (format string) with message id $msgid,
401 and, if an array reference of variables $variables is given,
402 substitutes variables in the format string with @$variables.
403 Returns the found message string, with variable substitutions
404 if specified.
405
406 $msgid must be the message identifier corresponding to a defined
407 message string (a valid key to the $messages hash in the Installer
408 package). getmessage throws an exception if the message cannot be
409 found.
410
411 =cut
412
413 sub getmessage {
414     my $messagename=shift;
415     my $variables=shift;
416     my $message=$messages->{$messagename}->{$language} || $messages->{$messagename}->{en} || "Error: No message named $messagename in Install.pm\n";
417     if (defined($variables)) {
418         $message=sprintf $message, @$variables;
419     }
420     return $message;
421 }
422
423
424 =item showmessage
425
426     showmessage($message, 'none');
427     showmessage($message, 'none', undef, $noclear);
428
429     $result = showmessage($message, 'yn');
430     $result = showmessage($message, 'yn', $defaultresponse);
431     $result = showmessage($message, 'yn', $defaultresponse, $noclear);
432
433     $result = showmessage($message, 'restrictchar CHARS');
434     $result = showmessage($message, 'free');
435     $result = showmessage($message, 'numerical');
436     $result = showmessage($message, 'email');
437     $result = showmessage($message, 'PressEnter');
438
439 Shows a message and optionally gets a response from the user.
440
441 The first two arguments, the message and the response type,
442 are mandatory.  The message must be the actual string to
443 display. The caller is responsible for calling getmessage if
444 required.
445
446 The response type must be one of "none", "yn", "free",
447 "numerical", "email", "PressEnter", or a string consisting
448 of "restrictchar " followed by a list of allowed characters
449 (space can be specified). (Case is not significant, but case is
450 significant in the list of allowed characters.) If a response
451 type other than the above-listed is specified, the result is
452 undefined.
453
454 Note that the response type "yn" is equivalent to "restrictchar yn".
455 Because "restrictchar" is case-sensitive, the user is expected
456 to enter "y" or "n" in lowercase only.
457
458 Note that the response type of "email" does not actually
459 guarantee that the returned value is a well-formed RFC-822
460 email address, nor does it accept all well-formed RFC-822 email
461 addresses. What it does is to restrict the returned value to a
462 string that is looks reasonably likely to be an email address
463 in the "real world".
464
465 If a response type other than "none" or "PressEnter" is
466 specified, a third argument, specifying the default value, can
467 be specified:  If this default response is not specified, the
468 default response is the first allowed character if the response
469 type is "restrictchar", otherwise the default response is the
470 empty string. This default response is used when the user does
471 not specify a value (i.e., presses Enter without typing in
472 anything), showmessage will assume that the default response is
473 the user's response.
474
475 Note that because the response type "yn" is equivalent to
476 "restrictchar yn", the default value for response type "yn",
477 if unspecified, is "y".
478
479 The screen is normally cleared before the message is displayed;
480 if a fourth argument is specified and is nonzero, this
481 screen-clearing is not done.
482
483 FIXME: A response type of "yn" should allow the user to specify
484 "y" or "n" in either upercase or lowercase.
485
486 FIXME: If the response type is "free", the user cannot specify
487 an empty string; showmessage will return "1" as the result.
488
489 FIXME: A default response of "0" cannot be specified. This is
490 wrong; the default response should be checked for undef, not
491 for 0.
492
493 FIXME: If $noclear is not specified or specified as undef, we
494 just test it for a non-zero value without testing it for being
495 undef first.
496
497 =cut
498
499 sub showmessage {
500     my $message=shift;
501     my $responsetype=shift;
502     my $defaultresponse=shift;
503     my $noclear=shift;
504     ($noclear) || (system('clear'));
505     if ($responsetype =~ /^yn$/) {
506         $responsetype='restrictchar yn';
507     }
508     print $message;
509     SWITCH: {
510         if ($responsetype =~/^restrictchar (.*)/i) {
511             my $response='\0';
512             my $options=$1;
513             until ($options=~/$response/) {
514                 ($defaultresponse) || ($defaultresponse=substr($options,0,1));
515                 $response=<STDIN>;
516                 chomp $response;
517                 (length($response)) || ($response=$defaultresponse);
518                 unless ($options=~/$response/) {
519                     ($noclear) || (system('clear'));
520                     print "Invalid Response.  Choose from [$options].\n\n";
521                     print $message;
522                 }
523             }
524             return $response;
525         }
526         if ($responsetype =~/^free$/i) {
527             (defined($defaultresponse)) || ($defaultresponse='');
528             my $response=<STDIN>;
529             chomp $response;
530             ($response) || ($response=$defaultresponse);
531             return $response;
532         }
533         if ($responsetype =~/^numerical$/i) {
534             (defined($defaultresponse)) || ($defaultresponse='');
535             my $response='';
536             until ($response=~/^\d+$/) {
537                 $response=<STDIN>;
538                 chomp $response;
539                 ($response) || ($response=$defaultresponse);
540                 unless ($response=~/^\d+$/) {
541                     ($noclear) || (system('clear'));
542                     print "Invalid Response ($response).  Response must be a number.\n\n";
543                     print $message;
544                 }
545             }
546             return $response;
547         }
548         if ($responsetype =~/^email$/i) {
549             (defined($defaultresponse)) || ($defaultresponse='');
550             my $response='';
551             until ($response=~/.*\@.*\..*/) {
552                 $response=<STDIN>;
553                 chomp $response;
554                 ($response) || ($response=$defaultresponse);
555                 unless ($response=~/.*\@.*\..*/) {
556                     ($noclear) || (system('clear'));
557                     print "Invalid Response ($response).  Response must be a valid email address.\n\n";
558                     print $message;
559                 }
560             }
561             return $response;
562         }
563         if ($responsetype =~/^PressEnter$/i) {
564             <STDIN>;
565             return;
566         }
567         if ($responsetype =~/^none$/i) {
568             return;
569         }
570     }
571 }
572
573
574 =back
575
576 =head2 Subtasks of doing an installation
577
578 =over 4
579
580 =cut
581
582 =item checkabortedinstall
583
584     checkabortedinstall;
585
586 Checks whether a previous installation process has been abnormally
587 aborted, by checking whether $etcidr/koha.conf is a symlink matching
588 a particular pattern.  If an aborted installation is detected, give
589 the user a chance to abort, before trying to recover the aborted
590 installation.
591
592 FIXME: The recovery is not complete; it only partially rolls back
593 some changes.
594
595 =cut
596
597 sub checkabortedinstall () {
598     if (-l("$etcdir/koha.conf")
599         && readlink("$etcdir/koha.conf") =~ /\.tmp$/
600     ) {
601         print qq|
602 I have detected that you tried to install Koha before, but the installation
603 was aborted.  I will try to continue, but there might be problems if the
604 database is already created.
605
606 |;
607         print "Please press <ENTER> to continue: ";
608         <STDIN>;
609
610         # Remove the symlink after the <STDIN>, so the user can back out
611         unlink "$etcdir/koha.conf"
612             || die "Failed to remove incomplete $etcdir/koha.conf: $!\n";
613     }
614 }
615
616
617 =item checkperlmodules
618
619     checkperlmodules;
620
621 Test whether the version of Perl is new enough, whether Perl is
622 found at the expected location, and whether all required modules
623 have been installed.
624
625 =cut
626
627 sub checkperlmodules {
628 #
629 # Test for Perl and Modules
630 #
631
632     my $message = getmessage('CheckingPerlModules');
633     showmessage($message, 'none');
634
635     # FIXME: Perl 5.6 is BUGGY!!! IT SHOULD NOT BE USED in production!!!
636     unless (eval "require 5.006_000") {
637         die getmessage('PerlVersionFailure', ['5.6.0']);
638     }
639
640     my @missing = ();
641     unless (eval {require DBI})               { push @missing,"DBI" };
642     unless (eval {require Date::Manip})       { push @missing,"Date::Manip" };
643     unless (eval {require DBD::mysql})        { push @missing,"DBD::mysql" };
644     unless (eval {require HTML::Template})          { push @missing,"HTML::Template" };
645     unless (eval {require Set::Scalar})       { push @missing,"Set::Scalar" };
646     unless (eval {require Digest::MD5})       { push @missing,"Digest::MD5" };
647     unless (eval {require MARC::Record})       { push @missing,"MARC::Record" };
648     unless (eval {require Net::Z3950})        {
649         my $message = getmessage('NETZ3950Missing');
650         showmessage($message, 'PressEnter', '', 1);
651         if ($#missing>=0) {
652             push @missing, "Net::Z3950";
653         }
654     }
655
656 #
657 # Print out a list of any missing modules
658 #
659
660     if (@missing > 0) {
661         my $missing='';
662         foreach my $module (@missing) {
663             $missing.="   perl -MCPAN -e 'install \"$module\"'\n";
664         }
665         my $message=getmessage('MissingPerlModules', [$missing]);
666         showmessage($message, 'none');
667         exit;
668     } else {
669         showmessage(getmessage('AllPerlModulesInstalled'), 'PressEnter', '', 1);
670     }
671
672
673     unless (-x "/usr/bin/perl") {
674         my $realperl=`which perl`;
675         chomp $realperl;
676         $realperl = showmessage(getmessage('NoUsrBinPerl'), 'none');
677         until (-x $realperl) {
678             $realperl=showmessage(getmessage('AskLocationOfPerlExecutable', $realperl), 'free', $realperl, 1);
679         }
680         my $response=showmessage(getmessage('ConfirmPerlExecutableSymlink', $realperl), 'yn', 'y', 1);
681         unless ($response eq 'n') {
682             system("ln -s $realperl /usr/bin/perl");
683         }
684     }
685
686
687 }
688
689 $messages->{'NoUsrBinPerl'}->{en} =
690    heading('Perl is not located in /usr/bin/perl') . qq|
691 The Koha perl scripts expect to find the perl executable in the /usr/bin
692 directory.  It is not there on your system.
693
694 |;
695
696 $messages->{'AskLocationOfPerlExecutable'}->{en}=qq|Location of Perl Executable: [%s]: |;
697 $messages->{'ConfirmPerlExecutableSymlink'}->{en}=qq|
698 The Koha scripts will _not_ work without a symlink from %s to /usr/bin/perl
699
700 May I create this symlink? ([Y]/N):
701 : |;
702
703
704 =item getinstallationdirectories
705
706     getinstallationdirectories;
707
708 Get the various installation directories from the user, and then
709 create those directories (if they do not already exist).
710
711 These pieces of information are saved to global variables; the
712 function does not return any values.
713
714 =cut
715
716 sub getinstallationdirectories {
717     $opacdir = '/usr/local/koha/opac';
718     $intranetdir = '/usr/local/koha/intranet';
719     my $getdirinfo=1;
720     while ($getdirinfo) {
721         # Loop until opac directory and koha directory are different
722         my $message=getmessage('GetOpacDir', [$opacdir]);
723         $opacdir=showmessage($message, 'free', $opacdir);
724
725         $message=getmessage('GetIntranetDir', [$intranetdir]);
726         $intranetdir=showmessage($message, 'free', $intranetdir);
727
728         if ($intranetdir eq $opacdir) {
729             print qq|
730
731 You must specify different directories for the OPAC and INTRANET files!
732  :: $intranetdir :: $opacdir ::
733 |;
734 <STDIN>
735         } else {
736             $getdirinfo=0;
737         }
738     }
739     $kohalogdir='/var/log/koha';
740     my $message=getmessage('GetKohaLogDir', [$kohalogdir]);
741     $kohalogdir=showmessage($message, 'free', $kohalogdir);
742
743
744     # FIXME: Missing error handling for all mkdir calls here
745     unless ( -d $intranetdir ) {
746        mkdir_parents (dirname($intranetdir), 0775);
747        mkdir ($intranetdir,                  0770);
748        chown (oct(0), (getgrnam($httpduser))[2], "$intranetdir");
749        chmod (oct(770), "$intranetdir");
750     }
751     mkdir_parents ("$intranetdir/htdocs",    0750);
752     mkdir_parents ("$intranetdir/cgi-bin",   0750);
753     mkdir_parents ("$intranetdir/modules",   0750);
754     mkdir_parents ("$intranetdir/scripts",   0750);
755     unless ( -d $opacdir ) {
756        mkdir_parents (dirname($opacdir),     0775);
757        mkdir ($opacdir,                      0770);
758        chown (oct(0), (getgrnam($httpduser))[2], "$opacdir");
759        chmod (oct(770), "$opacdir");
760     }
761     mkdir_parents ("$opacdir/htdocs",        0750);
762     mkdir_parents ("$opacdir/cgi-bin",       0750);
763
764
765     unless ( -d $kohalogdir ) {
766        mkdir_parents (dirname($kohalogdir),  0775);
767        mkdir ($kohalogdir,                   0770);
768        chown (oct(0), (getgrnam($httpduser))[2,3], "$kohalogdir");
769        chmod (oct(770), "$kohalogdir");
770     }
771 }
772
773
774
775 =item getdatabaseinfo
776
777     getdatabaseinfo;
778
779 Get various pieces of information related to the Koha database:
780 the name of the database, the host on which the SQL server is
781 running, and the database user name.
782
783 These pieces of information are saved to global variables; the
784 function does not return any values.
785
786 =cut
787
788 $messages->{'DatabaseName'}->{en} = heading('Name of MySQL database') . qq|
789 Please provide the name of the mysql database for your koha installation.
790
791 Database name [%s]: |;
792
793 $messages->{'DatabaseHost'}->{en} = heading('Database Host') . qq|
794 Please provide the hostname for mysql.  Unless the database is located on
795 another machine this will be "localhost".
796
797 Database host [%s]: |;
798
799 $messages->{'DatabaseUser'}->{en} = heading('Database User') . qq|
800 Please provide the name of the user, who will have full administrative rights
801 to the %s database, when authenticating from %s.
802
803 This user will also be used to access Koha's INTRANET interface.
804
805 Database user [%s]: |;
806
807 $messages->{'DatabasePassword'}->{en} = heading('Database Password') . qq|
808 Please provide a good password for the user %s.
809
810 Database Password: |;
811
812 $messages->{'BlankPassword'}->{en} = heading('BLANK PASSWORD') . qq|
813 You must not use a blank password for your MySQL user!
814
815 Press <ENTER> to try again: 
816 |;
817
818 sub getdatabaseinfo {
819
820     $dbname = 'Koha';
821     $hostname = 'localhost';
822     $user = 'kohaadmin';
823     $pass = '';
824
825 #Get the database name
826
827     my $message=getmessage('DatabaseName', [$dbname]);
828     $dbname=showmessage($message, 'free', $dbname);
829
830 #Get the hostname for the database
831     
832     $message=getmessage('DatabaseHost', [$hostname]);
833     $hostname=showmessage($message, 'free', $hostname);
834
835 #Get the username for the database
836
837     $message=getmessage('DatabaseUser', [$dbname, $hostname, $user]);
838     $user=showmessage($message, 'free', $user);
839
840 #Get the password for the database user
841
842     while ($pass eq '') {
843         my $message=getmessage('DatabasePassword', [$user]);
844         $pass=showmessage($message, 'free', $pass);
845         if ($pass eq '') {
846             my $message=getmessage('BlankPassword');
847             showmessage($message,'PressEnter');
848         }
849     }
850 }
851
852
853
854 =item getapacheinfo
855
856     getapacheinfo;
857
858 Get various pieces of information related to the Apache server:
859 the location of the configuration file and, if needed, the Unix
860 user that the Koha CGI will be run under.
861
862 These pieces of information are saved to global variables; the
863 function does not return any values.
864
865 =cut
866
867 $messages->{'FoundMultipleApacheConfFiles'}->{en} = 
868    heading('MULTIPLE APACHE CONFIG FILES') . qq|
869 I found more than one possible Apache configuration file:
870
871 %s
872
873 Choose the correct file [1]: |;
874
875 $messages->{'NoApacheConfFiles'}->{en} =
876    heading('NO APACHE CONFIG FILE FOUND') . qq|
877 I was not able to find your Apache configuration file.
878
879 The file is usually called httpd.conf or apache.conf.
880
881 Please specify the location of your config file: |;
882
883 $messages->{'NotAFile'}->{en} = heading('FILE DOES NOT EXIST') . qq|
884 The file %s does not exist.
885
886 Please press <ENTER> to continue: |;
887
888 $messages->{'EnterApacheUser'}->{en} = heading('NEED APACHE USER') . qq|
889 I was not able to determine the user that Apache is running as.  This
890 information is necessary in order to set the access privileges correctly on
891 %s/koha.conf.  This user should be set in one of the Apache configuration
892 files using the "User" directive.
893
894 Enter the Apache userid: |;
895
896 $messages->{'InvalidUserid'}->{en} = heading('INVALID USERID') . qq|
897 The userid %s is not a valid userid on this system.
898
899 Press <ENTER> to continue: |;
900
901 sub getapacheinfo {
902     my @confpossibilities;
903
904     foreach my $httpdconf (qw(/usr/local/apache/conf/httpd.conf
905                           /usr/local/etc/apache/httpd.conf
906                           /usr/local/etc/apache/apache.conf
907                           /var/www/conf/httpd.conf
908                           /etc/apache/conf/httpd.conf
909                           /etc/apache/conf/apache.conf
910                           /etc/apache-ssl/conf/apache.conf
911                           /etc/apache-ssl/httpd.conf
912                           /etc/httpd/conf/httpd.conf
913                           /etc/httpd/httpd.conf)) {
914         if ( -f $httpdconf ) {
915             push @confpossibilities, $httpdconf;
916         }
917     }
918
919     if ($#confpossibilities==-1) {
920         my $message=getmessage('NoApacheConfFiles');
921         my $choice='';
922         until (-f $realhttpdconf) {
923             $choice=showmessage($message, "free", 1);
924             if (-f $choice) {
925                 $realhttpdconf=$choice;
926             } else {
927                 showmessage(getmessage('NotAFile', [$choice]),'PressEnter', '', 1);
928             }
929         }
930     } elsif ($#confpossibilities>0) {
931         my $conffiles='';
932         my $counter=1;
933         my $options='';
934         foreach (@confpossibilities) {
935             $conffiles.="   $counter: $_\n";
936             $options.="$counter";
937             $counter++;
938         }
939         my $message=getmessage('FoundMultipleApacheConfFiles', [$conffiles]);
940         my $choice=showmessage($message, "restrictchar $options", 1);
941         $realhttpdconf=$confpossibilities[$choice-1];
942     } else {
943         $realhttpdconf=$confpossibilities[0];
944     }
945     unless (open (HTTPDCONF, "<$realhttpdconf")) {
946         warn "Insufficient privileges to open $realhttpdconf for reading.\n";
947         sleep 4;
948     }
949
950     while (<HTTPDCONF>) {
951         if (/^\s*User\s+"?([-\w]+)"?\s*$/) {
952             $httpduser = $1;
953         }
954     }
955     close(HTTPDCONF);
956
957
958
959
960     unless ($httpduser) {
961         my $message=getmessage('EnterApacheUser', [$etcdir]);
962         until (length($httpduser) && getpwnam($httpduser)) {
963             $httpduser=showmessage($message, "free", '');
964             if (length($httpduser)>0) {
965                 unless (getpwnam($httpduser)) {
966                     my $message=getmessage('InvalidUserid', [$httpduser]);
967                     showmessage($message,'PressEnter');
968                 }
969             } else {
970             }
971         }
972         print "AU: $httpduser\n";
973     }
974 }
975
976
977 =item getapachevhostinfo
978
979     getapachevhostinfo;
980
981 Gets various pieces of information related to virtual hosting:
982 the webmaster email address, virtual hostname, and the ports
983 that the OPAC and INTRANET modules run on.
984
985 These pieces of information are saved to global variables; the
986 function does not return any values.
987
988 =cut
989
990 $messages->{'ApacheConfigIntroduction'}->{en} =
991    heading('APACHE CONFIGURATION') . qq|
992 Koha needs to setup your Apache configuration file for the
993 OPAC and LIBRARIAN virtual hosts.  By default this installer
994 will do this by using one ip address and two different ports
995 for the virtual hosts.  There are other ways to set this up,
996 and the installer will leave comments in httpd.conf detailing
997 what these other options are.
998
999
1000 Press <ENTER> to continue: |;
1001
1002 $messages->{'GetVirtualHostEmail'}->{en} =
1003    heading('WEB SERVER E-MAIL CONTACT') . qq|
1004 Enter the e-mail address to be used as a contact for the virtual hosts (this
1005 address is displayed if any errors are encountered).
1006
1007 E-mail contact [%s]: |;
1008
1009 $messages->{'GetServerName'}->{en} =
1010    heading('WEB SERVER HOST NAME OR IP ADDRESS') . qq|
1011 Please enter the domain name or ip address of your computer.
1012
1013 Host name or IP Address [%s]: |;
1014
1015 $messages->{'GetOpacPort'}->{en} = heading('OPAC VIRTUAL HOST PORT') . qq|
1016 Please enter the port for your OPAC interface.  This defaults to port 80, but
1017 if you are already serving web content from this server, you should change it
1018 to a different port (8000 might be a good choice).
1019
1020 Enter the OPAC Port [%s]: |;
1021
1022 $messages->{'GetIntranetPort'}->{en} =
1023    heading('INTRANET VIRTUAL HOST PORT') . qq|
1024 Please enter the port for your Intranet interface.  This must be different from
1025 the OPAC port (%s).
1026
1027 Enter the Intranet Port [%s]: |;
1028
1029
1030 sub getapachevhostinfo {
1031
1032     $svr_admin = "webmaster\@$domainname";
1033     $servername=`hostname`;
1034     chomp $servername;
1035     $opacport=80;
1036     $intranetport=8080;
1037
1038     showmessage(getmessage('ApacheConfigIntroduction'), 'PressEnter');
1039
1040     $svr_admin=showmessage(getmessage('GetVirtualHostEmail', [$svr_admin]), 'email', $svr_admin);
1041     $servername=showmessage(getmessage('GetServerName', [$servername]), 'free', $servername);
1042
1043
1044     $opacport=showmessage(getmessage('GetOpacPort', [$opacport]), 'numerical', $opacport);
1045     $intranetport=showmessage(getmessage('GetIntranetPort', [$opacport, $intranetport]), 'numerical', $intranetport);
1046
1047 }
1048
1049 $messages->{'StartUpdateApache'}->{en} =
1050    heading('UPDATING APACHE CONFIGURATION') . qq|
1051 Checking for modules that need to be loaded...
1052 |;
1053
1054 $messages->{'LoadingApacheModuleModEnv'}->{en}="Loading SetEnv Apache module.\n";
1055
1056 $messages->{'LoadingApacheModuleModInc'}->{en}="Loading Includes Apache module.\n";
1057
1058 $messages->{'ApacheConfigBackupFailed'}->{en} =
1059    heading('APACHE CONFIGURATION BACKUP FAILED') . qq|
1060 An error occurred while trying to make a backup copy of %s.
1061
1062   %s
1063
1064 No changes will be made to the apache configuration file at this time.
1065
1066 Press <ENTER> to continue: |;
1067
1068
1069 $messages->{'ApacheAlreadyConfigured'}->{en} =
1070    heading('APACHE ALREADY CONFIGURED') . qq|
1071 %s appears to already have an entry for Koha
1072 Virtual Hosts.  You may need to edit %s
1073 f anything has changed since it was last set up.  This
1074 script will not attempt to modify an existing Koha apache
1075 configuration.
1076
1077 Press <ENTER> to continue: |;
1078
1079 sub updateapacheconf {
1080     my $logfiledir=`grep ^ErrorLog "$realhttpdconf"`;
1081     chomp $logfiledir;
1082
1083     if ($logfiledir) {
1084         $logfiledir=~m#ErrorLog (.*)/[^/]*$#
1085             or die "Can't parse ErrorLog directive\n";
1086         $logfiledir=$1;
1087     }
1088
1089     unless ($logfiledir) {
1090         $logfiledir='logs';
1091     }
1092
1093     showmessage(getmessage('StartUpdateApache'), 'none');
1094
1095     my $httpdconf;
1096     my $envmodule=0;
1097     my $includesmodule=0;
1098     open HC, "<$realhttpdconf";
1099     while (<HC>) {
1100         if (/^\s*#\s*LoadModule env_module /) {
1101             s/^\s*#\s*//;
1102             showmessage(getmessage('LoadingApacheModuleModEnv'));
1103             $envmodule=1;
1104         }
1105         if (/^\s*#\s*LoadModule includes_module /) {
1106             s/^\s*#\s*//;
1107             showmessage(getmessage('LoadingApacheModuleModInc'));
1108         }
1109         if (/\s*LoadModule includes_module / ) {
1110             $includesmodule=1;
1111         }
1112         $httpdconf.=$_;
1113     }
1114
1115     my $backupfailed=0;
1116     $backupfailed=`cp -f $realhttpdconf $realhttpdconf\.prekoha`;
1117     if ($backupfailed) {
1118         showmessage(getmessage('ApacheConfigBackupFailed', [$realhttpdconf,$backupfailed ]), 'PressEnter');
1119         return;
1120     }
1121
1122     if ($envmodule || $includesmodule) {
1123         open HC, ">$realhttpdconf";
1124         print HC $httpdconf;
1125         close HC;
1126     }
1127
1128
1129     
1130     if (`grep 'VirtualHost $servername' "$realhttpdconf"`) {
1131         showmessage(getmessage('ApacheAlreadyConfigured', [$realhttpdconf, $realhttpdconf]), 'PressEnter');
1132         return;
1133     } else {
1134         my $includesdirectives='';
1135         if ($includesmodule) {
1136             $includesdirectives.="Options +Includes\n";
1137             $includesdirectives.="   AddHandler server-parsed .html\n";
1138         }
1139         open(SITE,">>$realhttpdconf") or warn "Insufficient priveleges to open $realhttpdconf for writing.\n";
1140         my $opaclisten = '';
1141         if ($opacport != 80) {
1142             $opaclisten="Listen $opacport";
1143         }
1144         my $intranetlisten = '';
1145         if ($intranetport != 80) {
1146             $intranetlisten="Listen $intranetport";
1147         }
1148         print SITE <<EOP
1149
1150 # Ports to listen to for Koha
1151 $opaclisten
1152 $intranetlisten
1153
1154 # NameVirtualHost is used by one of the optional configurations detailed below
1155
1156 #NameVirtualHost 11.22.33.44
1157
1158 # KOHA's OPAC Configuration
1159 <VirtualHost $servername\:$opacport>
1160    ServerAdmin $svr_admin
1161    DocumentRoot $opacdir/htdocs
1162    ServerName $servername
1163    ScriptAlias /cgi-bin/koha/ $opacdir/cgi-bin/
1164    ErrorLog $logfiledir/opac-error_log
1165    TransferLog $logfiledir/opac-access_log
1166    SetEnv PERL5LIB "$intranetdir/modules"
1167    $includesdirectives
1168 </VirtualHost>
1169
1170 # KOHA's INTRANET Configuration
1171 <VirtualHost $servername\:$intranetport>
1172    ServerAdmin $svr_admin
1173    DocumentRoot $intranetdir/htdocs
1174    ServerName $servername
1175    ScriptAlias /cgi-bin/koha/ "$intranetdir/cgi-bin/"
1176    ErrorLog $logfiledir/koha-error_log
1177    TransferLog $logfiledir/koha-access_log
1178    SetEnv PERL5LIB "$intranetdir/modules"
1179    $includesdirectives
1180 </VirtualHost>
1181
1182 # If you want to use name based Virtual Hosting:
1183 #   1. remove the two Listen lines
1184 #   2. replace $servername\:$opacport wih your.opac.domain.name
1185 #   3. replace ServerName $servername wih ServerName your.opac.domain.name
1186 #   4. replace $servername\:$intranetport wih your intranet domain name
1187 #   5. replace ServerName $servername wih ServerName your.intranet.domain.name
1188 #
1189 # If you want to use NameVirtualHost'ing (using two names on one ip address):
1190 #   1.  Follow steps 1-5 above
1191 #   2.  Uncomment the NameVirtualHost line and set the correct ip address
1192
1193 EOP
1194
1195
1196     }
1197 }
1198
1199 $messages->{'IntranetAuthenticationQuestion'}->{en} =
1200    heading('INTRANET AUTHENTICATION') . qq|
1201 I can set it up so that the Intranet/Librarian site is password protected using
1202 Apache's Basic Authorization.
1203
1204 This is going to be phased out very soon. However, setting this up can provide
1205 an extra layer of security before the new authentication system is completely
1206 in place.
1207
1208 Would you like to do this ([Y]/N): |;
1209
1210 $messages->{'BasicAuthUsername'}->{en}="Please enter a userid for intranet access [%s]: ";
1211 $messages->{'BasicAuthPassword'}->{en}="Please enter a password for %s: ";
1212 $messages->{'BasicAuthPasswordWasBlank'}->{en}="\nYou cannot use a blank password!\n\n";
1213
1214 sub basicauthentication {
1215     my $message=getmessage('IntranetAuthenticationQuestion');
1216     my $answer=showmessage($message, 'yn', 'y');
1217
1218     my $apacheauthusername='librarian';
1219     my $apacheauthpassword='';
1220     if ($answer=~/^y/i) {
1221         ($apacheauthusername) = showmessage(getmessage('BasicAuthUsername', [ $apacheauthusername]), 'free', $apacheauthusername, 1);
1222         $apacheauthusername=~s/[^a-zA-Z0-9]//g;
1223         while (! $apacheauthpassword) {
1224             ($apacheauthpassword) = showmessage(getmessage('BasicAuthPassword', [ $apacheauthusername]), 'free', 1);
1225             if (!$apacheauthpassword) {
1226                 ($apacheauthpassword) = showmessage(getmessage('BasicAuthPasswordWasBlank'), 'none', '', 1);
1227             }
1228         }
1229         open AUTH, ">$etcdir/kohaintranet.pass";
1230         my $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
1231         my $salt=substr($chars, int(rand(length($chars))),1);
1232         $salt.=substr($chars, int(rand(length($chars))),1);
1233         print AUTH $apacheauthusername.":".crypt($apacheauthpassword, $salt)."\n";
1234         close AUTH;
1235         open(SITE,">>$realhttpdconf") or warn "Insufficient priveleges to open $realhttpdconf for writing.\n";
1236         print SITE <<EOP
1237
1238 <Directory $intranetdir>
1239     AuthUserFile $etcdir/kohaintranet.pass
1240     AuthType Basic
1241     AuthName "Koha Intranet (for librarians only)"
1242     Require  valid-user
1243 </Directory>
1244 EOP
1245     }
1246     close(SITE);
1247 }
1248
1249 $messages->{'InstallFiles'}->{en} = heading('INSTALLING FILES') . qq|
1250 Copying files to installation directories:
1251
1252 |;
1253
1254
1255 $messages->{'CopyingFiles'}->{en}="Copying %s to %s.\n";
1256
1257
1258
1259 sub installfiles {
1260
1261
1262     showmessage(getmessage('InstallFiles'),'none');
1263     print getmessage('CopyingFiles', ['intranet-html', "$intranetdir/htdocs" ]);
1264     system("cp -R intranet-html/* $intranetdir/htdocs/");
1265     print getmessage('CopyingFiles', ['intranet-cgi', "$intranetdir/cgi-bin" ]);
1266     system("cp -R intranet-cgi/* $intranetdir/cgi-bin/");
1267     print getmessage('CopyingFiles', ['stand-alone scripts', "$intranetdir/scripts" ]);
1268     system("cp -R scripts/* $intranetdir/scripts/");
1269     print getmessage('CopyingFiles', ['perl modules', "$intranetdir/modules" ]);
1270     system("cp -R modules/* $intranetdir/modules/");
1271     print getmessage('CopyingFiles', ['opac-html', "$opacdir/htdocs" ]);
1272     system("cp -R opac-html/* $opacdir/htdocs/");
1273     print getmessage('CopyingFiles', ['opac-cgi', "$opacdir/cgi-bin" ]);
1274     system("cp -R opac-cgi/* $opacdir/cgi-bin/");
1275     system("touch $opacdir/cgi-bin/opac");
1276
1277     system("chown -R root:$httpduser $opacdir");
1278     system("chown -R root:$httpduser $intranetdir");
1279
1280     # Create /etc/koha.conf
1281
1282     my $old_umask = umask(027); # make sure koha.conf is never world-readable
1283     open(SITES,">$etcdir/koha.conf.tmp") or warn "Couldn't create file at $etcdir. Must have write capability.\n";
1284     print SITES qq|
1285 database=$dbname
1286 hostname=$hostname
1287 user=$user
1288 pass=$pass
1289 includes=$opacdir/htdocs/includes
1290 intranetdir=$intranetdir
1291 opacdir=$opacdir
1292 kohalogdir=$kohalogdir
1293 kohaversion=$kohaversion
1294 httpduser=$httpduser
1295 intrahtdocs=$intranetdir/htdocs/intranet-tmpl
1296 opachtdocs=$opacdir/htdocs/opac-tmpl
1297 |;
1298     close(SITES);
1299     umask($old_umask);
1300
1301     chown((getpwnam($httpduser)) [2,3], "$etcdir/koha.conf.tmp") or warn "can't chown koha.conf: $!";
1302     chmod 0440, "$etcdir/koha.conf.tmp";
1303
1304     chmod 0750, "$intranetdir/scripts/z3950daemon/z3950-daemon-launch.sh";
1305     chmod 0750, "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh";
1306     chmod 0750, "$intranetdir/scripts/z3950daemon/processz3950queue";
1307     chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh") or warn "can't chown $intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh: $!";
1308     chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/processz3950queue") or warn "can't chown $intranetdir/scripts/z3950daemon/processz3950queue: $!";
1309
1310 }
1311
1312 $messages->{'MysqlRootPassword'}->{en} =
1313    heading('MYSQL ROOT USER PASSWORD') . qq|
1314 To allow us to create the koha database please supply your
1315 mysql server's root user password:
1316
1317 Enter MySQL root user password: |;
1318
1319 $messages->{'InvalidMysqlRootPassword'}->{en}="Invalid Password.  Please try again.";
1320
1321 $messages->{'CreatingDatabase'}->{en} = heading('CREATING DATABASE') . qq|
1322 Creating the MySQL database for Koha...
1323
1324 |;
1325
1326 $messages->{'CreatingDatabaseError'}->{en} =
1327    heading('ERROR CREATING DATABASE') . qq|
1328 Couldn't connect to the MySQL server for the reason given above.
1329 This is a serious problem, the database will not get installed.\a
1330
1331 Press <ENTER> to continue: |;
1332
1333 $messages->{'SampleData'}->{en} = heading('SAMPLE DATA') . qq|
1334 If you are installing Koha for evaluation purposes,  I have a batch of sample
1335 data that you can install now.
1336
1337 If you are installing Koha with the intention of populating it with your own
1338 data, you probably don't want this sample data installed.
1339
1340 Would you like to install the sample data? Y/[N]: |;
1341
1342 $messages->{'SampleDataInstalled'}->{en} =
1343    heading('SAMPLE DATA INSTALLED') . qq|
1344 Sample data has been installed.  For some suggestions on testing Koha, please
1345 read the file doc/HOWTO-Testing.  If you find any bugs, please submit them at
1346 http://bugs.koha.org/.  If you need help with testing Koha, you can post a
1347 question through the koha-devel mailing list, or you can check for a developer
1348 online at +irc.katipo.co.nz:6667 channel #koha.
1349
1350 You can find instructions for subscribing to the Koha mailing lists at:
1351
1352     http://www.koha.org
1353
1354
1355 Press <ENTER> to continue: |;
1356
1357 $messages->{'AddBranchPrinter'}->{en} = heading('Add Branch and Printer') . qq|
1358 Would you like to install an initial branch and printer? [Y]/N: |;
1359
1360 $messages->{'BranchName'}->{en}="Branch Name [%s]: ";
1361 $messages->{'BranchCode'}->{en}="Branch Code (4 letters or numbers) [%s]: ";
1362 $messages->{'PrinterQueue'}->{en}="Printer Queue [%s]: ";
1363 $messages->{'PrinterName'}->{en}="Printer Name [%s]: ";
1364 $messages->{'BlankMysqlPassword'}->{en} = heading('Blank MySQL Password') . qq|
1365 Do not leave your MySQL root password blank unless you know exactly what you
1366 are doing.  To change your MySQL root password use the mysqladmin command:
1367
1368 mysqladmin password NEWPASSWORDHERE
1369
1370 Press <ENTER> to continue:
1371 |;
1372
1373 sub databasesetup {
1374     $mysqluser = 'root';
1375     $mysqlpass = '';
1376
1377     foreach my $mysql (qw(/usr/local/mysql
1378                           /opt/mysql
1379                           /usr
1380                           )) {
1381        if ( -d $mysql  && -f "$mysql/bin/mysqladmin") {
1382             $mysqldir=$mysql;
1383        }
1384     }
1385     if (!$mysqldir){
1386         print "I don't see mysql in the usual places.\n";
1387         for (;;) {
1388             print "Where have you installed mysql? ";
1389             chomp($mysqldir = <STDIN>);
1390             last if -f "$mysqldir/bin/mysqladmin";
1391         print <<EOP;
1392
1393 I can't find it there either. If you compiled mysql yourself,
1394 please give the value of --prefix when you ran configure.
1395
1396 The file mysqladmin should be in bin/mysqladmin under the directory that you
1397 provide here.
1398
1399 EOP
1400         }
1401     }
1402
1403
1404     my $needpassword=1;
1405     while ($needpassword) {
1406         $mysqlpass=showmessage(getmessage('MysqlRootPassword'), 'free');
1407         $mysqlpass_quoted = $mysqlpass;
1408         $mysqlpass_quoted =~ s/"/\\"/g;
1409         $mysqlpass_quoted="-p\"$mysqlpass_quoted\"";
1410         $mysqlpass eq '' and $mysqlpass_quoted='';
1411         my $result=system("$mysqldir/bin/mysqladmin -u$mysqluser $mysqlpass_quoted proc > /dev/null 2>&1");
1412         if ($result) {
1413             print getmessage('InvalidMysqlRootPassword');
1414         } else {
1415             if ($mysqlpass eq '') {
1416                 showmessage(getmessage('BlankMysqlPassword'), 'PressEnter');
1417             }
1418             $needpassword=0;
1419         }
1420     }
1421
1422     showmessage(getmessage('CreatingDatabase'),'none');
1423
1424     my $result=system("$mysqldir/bin/mysqladmin", "-u$mysqluser", "-p$mysqlpass", "create", "$dbname");
1425     if ($result) {
1426         showmessage(getmessage('CreatingDatabaseError'),'PressEnter', '', 1);
1427     } else {
1428         # Populate the Koha database
1429         system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname < koha.mysql");
1430         # Set up permissions
1431         system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted mysql -e \"insert into user (Host,User,Password) values ('$hostname','$user',password('$pass'))\"\;");
1432         system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted mysql -e \"insert into db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv, index_priv, alter_priv) values ('%','$dbname','$user','Y','Y','Y','Y','Y','Y','Y','Y')\"");
1433         system("$mysqldir/bin/mysqladmin -u$mysqluser $mysqlpass_quoted reload");
1434
1435
1436
1437
1438
1439     }
1440
1441 }
1442
1443 $messages->{'UpdateMarcTables'}->{en} =
1444    heading('UPDATING MARC FIELD DEFINITION TABLES') . qq|
1445 You can import marc parameters for :
1446
1447   1 MARC21
1448   2 UNIMARC
1449   3 none
1450
1451 Please choose which parameter you want to install. Note if you choose 3,
1452 nothing will be added, and it can be a BIG job to manually create those tables
1453
1454 Choose MARC definition [1]: |;
1455
1456 $messages->{'Language'}->{en} = heading('CHOOSE LANGUAGES') . qq|
1457 This version of koha supports a few languages.
1458 Enter you languages preferences : either en, fr, es or pl.
1459 Note that the en is always choosen when the system does not finds the
1460 language you choose in a specific screen.
1461 fr : opac is translated (except pictures)
1462 es : a few intranet is translated (including pictures)
1463 pl : opac is translated (UNTESTED in this release)
1464 |;
1465
1466 sub updatedatabase {
1467     # At this point, $etcdir/koha.conf must exist, for C4::Context
1468     # We must somehow temporarily enable $etcdir/koha.conf. A symlink can
1469     # do this & at the same time facilitate detection of aborted installs.
1470         my $result=system ("perl -I $intranetdir/modules scripts/updater/updatedatabase");
1471         if ($result) {
1472                 print "Problem updating database...\n";
1473                 exit;
1474         }
1475
1476         my $response=showmessage(getmessage('UpdateMarcTables'), 'restrictchar 123', '1');
1477
1478         if ($response == 1) {
1479                 system("cat scripts/misc/marc_datas/marc21_en/structure_def.sql | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname");
1480         }
1481         if ($response == 2) {
1482                 system("cat scripts/misc/marc_datas/unimarc_fr/structure_def.sql | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname");
1483                 system("cat scripts/misc/lang-datas/fr/stopwords.sql | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname");
1484         }
1485
1486         $result = system ("perl -I $intranetdir/modules scripts/marc/updatedb2marc.pl");
1487         if ($result) {
1488                 print "Problem updating database to MARC...\n";
1489                 exit;
1490         }
1491
1492         print "\n\nFinished updating of database. Press <ENTER> to continue...";
1493         <STDIN>;
1494 }
1495
1496 sub populatedatabase {
1497         my $response=showmessage(getmessage('SampleData'), 'yn', 'n');
1498         if ($response =~/^y/i) {
1499                 system("gunzip -d < sampledata-1.2.gz | $mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname");
1500                 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branches (branchcode,branchname,issuing) values ('MAIN', 'Main Library', 1)\"");
1501                 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1502                 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1503                 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into printers (printername,printqueue,printtype) values ('Circulation Desk Printer', 'lp', 'hp')\"");
1504                 showmessage(getmessage('SampleDataInstalled'), 'PressEnter','',1);
1505         } else {
1506                 my $input;
1507                 my $response=showmessage(getmessage('AddBranchPrinter'), 'yn', 'y');
1508
1509                 unless ($response =~/^n/i) {
1510                 my $branch='Main Library';
1511                 $branch=showmessage(getmessage('BranchName', [$branch]), 'free', $branch, 1);
1512                 $branch=~s/[^A-Za-z0-9\s]//g;
1513
1514                 my $branchcode=$branch;
1515                 $branchcode=~s/[^A-Za-z0-9]//g;
1516                 $branchcode=uc($branchcode);
1517                 $branchcode=substr($branchcode,0,4);
1518                 $branchcode=showmessage(getmessage('BranchCode', [$branchcode]), 'free', $branchcode, 1);
1519                 $branchcode=~s/[^A-Za-z0-9]//g;
1520                 $branchcode=uc($branchcode);
1521                 $branchcode=substr($branchcode,0,4);
1522                 $branchcode or $branchcode='DEF';
1523
1524                 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branches (branchcode,branchname,issuing) values ('$branchcode', '$branch', 1)\"");
1525                 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1526                 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1527
1528                 my $printername='Library Printer';
1529                 $printername=showmessage(getmessage('PrinterName', [$printername]), 'free', $printername, 1);
1530                 $printername=~s/[^A-Za-z0-9\s]//g;
1531
1532                 my $printerqueue='lp';
1533                 $printerqueue=showmessage(getmessage('PrinterQueue', [$printerqueue]), 'free', $printerqueue, 1);
1534                 $printerqueue=~s/[^A-Za-z0-9]//g;
1535                 system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"insert into printers (printername,printqueue,printtype) values ('$printername', '$printerqueue', '')\"");
1536                 }
1537         my $language=showmessage(getmessage('Language'), 'free', 'en');
1538         system("$mysqldir/bin/mysql -u$mysqluser $mysqlpass_quoted $dbname -e \"update systempreferences set value='$language' where variable='opaclanguages'\"");
1539         }
1540 }
1541
1542 $messages->{'RestartApache'}->{en} = heading('RESTART APACHE') . qq|
1543 Apache needs to be restarted to load the new configuration for Koha.
1544
1545 Would you like to restart Apache now?  [Y]/N: |;
1546
1547 sub restartapache {
1548
1549     my $response=showmessage(getmessage('RestartApache'), 'yn', 'y');
1550
1551
1552
1553     unless ($response=~/^n/i) {
1554         # Need to support other init structures here?
1555         if (-e "/etc/rc.d/init.d/httpd") {
1556             system('/etc/rc.d/init.d/httpd restart');
1557         } elsif (-e "/etc/init.d/apache") {
1558             system('/etc//init.d/apache restart');
1559         } elsif (-e "/etc/init.d/apache-ssl") {
1560             system('/etc/init.d/apache-ssl restart');
1561         }
1562     }
1563
1564 }
1565
1566
1567 sub loadconfigfile {
1568     my %configfile;
1569
1570     open (KC, "<$etcdir/koha.conf");
1571     while (<KC>) {
1572      chomp;
1573      (next) if (/^\s*#/);
1574      if (/(.*)\s*=\s*(.*)/) {
1575        my $variable=$1;
1576        my $value=$2;
1577        # Clean up white space at beginning and end
1578        $variable=~s/^\s*//g;
1579        $variable=~s/\s*$//g;
1580        $value=~s/^\s*//g;
1581        $value=~s/\s*$//g;
1582        $configfile{$variable}=$value;
1583      }
1584     }
1585
1586     $intranetdir=$configfile{'intranetdir'};
1587     $opacdir=$configfile{'opacdir'};
1588     $kohaversion=$configfile{'kohaversion'};
1589     $kohalogdir=$configfile{'kohalogdir'};
1590     $database=$configfile{'database'};
1591     $hostname=$configfile{'hostname'};
1592     $user=$configfile{'user'};
1593     $pass=$configfile{'pass'};
1594 }
1595
1596 END { }       # module clean-up code here (global destructor)
1597
1598 =back
1599
1600 =head1 SEE ALSO
1601
1602 buildrelease.pl,
1603 installer.pl
1604
1605 =cut
1606
1607 1;