New system preference for setting date format when entering patron birth dates.
[koha.git] / 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 require Exporter;
23
24 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
25
26 # set the version for version checking
27 $VERSION = 0.01;
28
29 @ISA = qw(Exporter);
30 @EXPORT = qw(   &checkperlmodules
31                 &getmessage
32                 &showmessage
33                 &releasecandidatewarning
34                 &getinstallationdirectories
35                 &getdatabaseinfo
36                 &getapacheinfo
37                 &getapachevhostinfo
38                 &updateapacheconf
39                 &basicauthentication
40                 &installfiles
41                 &databasesetup
42                 &updatedatabase
43                 &populatedatabase
44                 &restartapache
45                 &loadconfigfile
46                 );
47
48
49 my $messages;
50 $messages->{'continuing'}->{en}="Great!  Continuing setup.\n\n";
51 $messages->{'WelcomeToKohaInstaller'}->{en}=qq|
52 =================================
53 = Welcome to the Koha Installer =
54 =================================
55
56 Welcome to the Koha install script!  This script will prompt you for some
57 basic information about your desired setup, then install Koha according to
58 your specifications.  To accept the default value for any question, simply hit
59 Enter at the prompt.
60
61 Please be sure to read the documentation, or visit the Koha website at 
62 http://www.koha.org for more information.
63
64 Are you ready to begin the installation? (Y/[N]): |;
65 $messages->{'ReleaseCandidateWarning'}->{en}=qq|
66 =====================
67 = RELEASE CANDIDATE =
68 =====================
69
70 WARNING WARNING WARNING WARNING WARNING
71
72 You are about to install Koha version %s.  This version of Koha is a
73 release candidate.  It is not intended to be installed on production systems.
74 It is being released so that users can test it before we release a final
75 version.
76
77 Are you sure you want to install Koha %s? (Y/[N]): |;
78 $messages->{'WatchForReleaseAnnouncements'}->{en}=qq|
79
80 Watch for announcements of Koha releases on the Koha mailing list or the Koha
81 web site (http://www.koha.org/).
82
83 |;
84
85 $messages->{'NETZ3950Missing'}->{en}=qq|
86
87 The Net::Z3950 module is missing.  This module is necessary if you want to use
88 Koha's Z39.50 client to download bibliographic records from other libraries.
89 To install this module, you will need the yaz client installed from
90 http://www.indexdata.dk/yaz/ and then you can install the perl module with the
91 command:
92
93 perl -MCPAN -e 'install Net::Z3950'
94
95 Press the <ENTER> key to continue: |;
96
97 $messages->{'CheckingPerlModules'}->{en}=qq|
98
99 ==================
100 = PERL & MODULES =
101 ==================
102
103 Checking perl modules ...
104 |;
105
106 $messages->{'PerlVersionFailure'}->{en}="Sorry, you need at least Perl %s\n";
107
108 $messages->{'MissingPerlModules'}->{en}=qq|
109
110 ========================
111 = MISSING PERL MODULES =
112 ========================
113
114 You are missing some Perl modules which are required by Koha.
115 Once these modules have been installed, rerun this installer.
116 They can be installed by running (as root) the following:
117
118 %s
119 |;
120
121 $messages->{'AllPerlModulesInstalled'}->{en}=qq|
122
123 ==============================
124 = ALL PERL MODULES INSTALLED =
125 ==============================
126
127 All mandatory perl modules are installed.
128
129 Press <ENTER> to continue: |;
130 $messages->{'KohaVersionInstalled'}->{en}="You currently have Koha %s on your system.";
131 $messages->{'KohaUnknownVersionInstalled'}->{en}="I am not able to determine what version of Koha is installed now.";
132 $messages->{'KohaAlreadyInstalled'}->{en}=qq|
133 ==========================
134 = Koha already installed =
135 ==========================
136
137 It looks like Koha is already installed on your system (/etc/koha.conf exists
138 already).  If you would like to upgrade your system to %s, please use
139 the koha.upgrade script in this directory.
140
141 %s
142
143 |;
144 $messages->{'GetOpacDir'}->{en}=qq|
145 ==================
146 = OPAC DIRECTORY =
147 ==================
148
149 Please supply the directory you want Koha to store its OPAC files in.  This
150 directory will be auto-created for you if it doesn't exist.
151
152 OPAC Directory [%s]: |;
153
154 $messages->{'GetIntranetDir'}->{en}=qq|
155 =================================
156 = INTRANET/LIBRARIANS DIRECTORY =
157 =================================
158
159 Please supply the directory you want Koha to store its Intranet/Librarians
160 files in.  This directory will be auto-created for you if it doesn't exist.
161
162 Intranet Directory [%s]: |;
163
164 $messages->{'GetKohaLogDir'}->{en}=qq|
165 ======================
166 = KOHA LOG DIRECTORY =
167 ======================
168
169 Specify a log directory where any Koha daemons can create log files.
170
171 Koha Log Directory [%s]: |;
172
173 $messages->{'AuthenticationWarning'}->{en}=qq|
174 ==================
175 = Authentication =
176 ==================
177
178 This release of Koha has a new authentication module.  If you are not already
179 using basic authentication on your intranet, you will be required to log in to
180 access some of the features of the intranet.  You can log in using the userid
181 and password from the /etc/koha.conf configuration file at any time.  Use the
182 "Members" module to add passwords for other accounts and set their permissions.
183
184 [NOTE PERMISSIONS ARE NOT COMPLETED AS OF THIS RELEASE.  Do not give passwords
185 to any patrons unless you want them to have full access to your intranet.]
186
187 Press the <ENTER> key to continue: |;
188
189 $messages->{'Completed'}->{en}=qq|
190 ==============================
191 = KOHA INSTALLATION COMPLETE =
192 ==============================
193
194 Congratulations ... your Koha installation is complete!
195
196 You will be able to connect to your Librarian interface at:
197
198    http://%s\:%s/
199
200 and the OPAC interface at :
201
202    http://%s\:%s/
203
204
205 Be sure to read the INSTALL, and Hints files. 
206
207 For more information visit http://www.koha.org
208
209 Press <ENTER> to exit the installer: |;
210
211 sub releasecandidatewarning {
212     my $message=getmessage('ReleaseCandidateWarning', [$::newversion, $::newversion]);
213     my $answer=showmessage($message, 'yn', 'n');
214
215     if ($answer =~ /y/i) {
216         print getmessage('continuing');
217     } else {
218         my $message=getmessage('WatchForReleaseAnnouncements');
219         print $message;
220         exit;
221     };
222 }
223
224
225 #
226 # Test for Perl and Modules
227 #
228 #
229 sub checkperlmodules {
230     my $message = getmessage('CheckingPerlModules');
231     showmessage($message, 'none');
232     
233     unless (eval "require 5.006_000") {
234         die getmessage('PerlVersionFailure', ['5.6.0']);
235     }
236
237     my @missing = ();
238     unless (eval {require DBI})               { push @missing,"DBI" };
239     unless (eval {require Date::Manip})       { push @missing,"Date::Manip" };
240     unless (eval {require DBD::mysql})        { push @missing,"DBD::mysql" };
241     unless (eval {require HTML::Template})          { push @missing,"HTML::Template" };
242     unless (eval {require Set::Scalar})       { push @missing,"Set::Scalar" };
243     unless (eval {require Digest::MD5})       { push @missing,"Digest::MD5" };
244     unless (eval {require Net::Z3950})        { 
245         my $message = getmessage('NETZ3950Missing');
246         showmessage($message, 'PressEnter', '', 1);
247         if ($#missing>=0) {
248             push @missing, "Net::Z3950";
249         }
250     }
251
252 #
253 # Print out a list of any missing modules
254 #
255
256     if (@missing > 0) {
257         my $missing='';
258         foreach my $module (@missing) {
259             $missing.="   perl -MCPAN -e 'install \"$module\"'\n";
260         }
261         my $message=getmessage('MissingPerlModules', [$missing]);
262         showmessage($message, 'none');
263         exit;
264     } else {
265         showmessage(getmessage('AllPerlModulesInstalled'), 'PressEnter', '', 1);
266     }
267
268
269     unless (-x "/usr/bin/perl") {
270         my $realperl=`which perl`;
271         chomp $realperl;
272         $realperl = showmessage(getmessage('NoUsrBinPerl'), 'none');
273         until (-x $realperl) {
274             $realperl=showmessage(getmessage('AskLocationOfPerlExecutable', $realperl), 'free', $realperl, 1);
275         }
276         my $response=showmessage(getmessage('ConfirmPerlExecutableSymlink', $realperl), 'yn', 'y', 1);
277         unless ($response eq 'n') {
278             system("ln -s $realperl /usr/bin/perl");
279         }
280     }
281
282
283 }
284
285 $messages->{'NoUsrBinPerl'}->{en}=qq|
286
287 ========================================
288 = Perl is not located in /usr/bin/perl =
289 ========================================
290
291 The Koha perl scripts expect to find the perl executable in the /usr/bin
292 directory.  It is not there on your system.
293
294 |;
295
296 $messages->{'AskLocationOfPerlExecutable'}->{en}=qq|Location of Perl Executable: [%s]: |;
297 $messages->{'ConfirmPerlExecutableSymlink'}->{en}=qq|
298 The Koha scripts will _not_ work without a symlink from %s to /usr/bin/perl
299
300 May I create this symlink? ([Y]/N): 
301 : |;
302
303 sub getmessage {
304     my $messagename=shift;
305     my $variables=shift;
306     my $message=$messages->{$messagename}->{$::language} || $messages->{$messagename}->{en} || "Error: No message named $messagename in Install.pm\n";
307     if (defined($variables)) {
308         $message=sprintf $message, @$variables;
309     }
310     return $message;
311 }
312
313
314 sub showmessage {
315     my $message=shift;
316     my $responsetype=shift;
317     my $defaultresponse=shift;
318     my $noclear=shift;
319     ($noclear) || (system('clear'));
320     if ($responsetype =~ /^yn$/) {
321         $responsetype='restrictchar yn';
322     }
323     print $message;
324     SWITCH: {
325         if ($responsetype =~/^restrictchar (.*)/i) {
326             my $response='\0';
327             my $options=$1;
328             until ($options=~/$response/) {
329                 ($defaultresponse) || ($defaultresponse=substr($options,0,1));
330                 $response=<STDIN>;
331                 chomp $response;
332                 (length($response)) || ($response=$defaultresponse);
333                 unless ($options=~/$response/) {
334                     ($noclear) || (system('clear'));
335                     print "Invalid Response.  Choose from [$options].\n\n";
336                     print $message;
337                 }
338             }
339             return $response;
340         }
341         if ($responsetype =~/^free$/i) {
342             (defined($defaultresponse)) || ($defaultresponse='');
343             my $response=<STDIN>;
344             chomp $response;
345             ($response) || ($response=$defaultresponse);
346             return $response;
347         }
348         if ($responsetype =~/^numerical$/i) {
349             (defined($defaultresponse)) || ($defaultresponse='');
350             my $response='';
351             until ($response=~/^\d+$/) {
352                 $response=<STDIN>;
353                 chomp $response;
354                 ($response) || ($response=$defaultresponse);
355                 unless ($response=~/^\d+$/) {
356                     ($noclear) || (system('clear'));
357                     print "Invalid Response ($response).  Response must be a number.\n\n";
358                     print $message;
359                 }
360             }
361             return $response;
362         }
363         if ($responsetype =~/^email$/i) {
364             (defined($defaultresponse)) || ($defaultresponse='');
365             my $response='';
366             until ($response=~/.*\@.*\..*/) {
367                 $response=<STDIN>;
368                 chomp $response;
369                 ($response) || ($response=$defaultresponse);
370                 unless ($response=~/.*\@.*\..*/) {
371                     ($noclear) || (system('clear'));
372                     print "Invalid Response ($response).  Response must be a valid email address.\n\n";
373                     print $message;
374                 }
375             }
376             return $response;
377         }
378         if ($responsetype =~/^PressEnter$/i) {
379             <STDIN>;
380             return;
381         }
382         if ($responsetype =~/^none$/i) {
383             return;
384         }
385     }
386 }
387
388 sub getinstallationdirectories {
389     $::opacdir = '/usr/local/koha/opac';
390     $::intranetdir = '/usr/local/koha/intranet';
391     my $getdirinfo=1;
392     while ($getdirinfo) {
393         # Loop until opac directory and koha directory are different
394         my $message=getmessage('GetOpacDir', [$::opacdir]);
395         $::opacdir=showmessage($message, 'free', $::opacdir);
396
397         $message=getmessage('GetIntranetDir', [$::intranetdir]);
398         $::intranetdir=showmessage($message, 'free', $::intranetdir);
399
400         if ($::intranetdir eq $::opacdir) {
401             print qq|
402
403 You must specify different directories for the OPAC and INTRANET files!
404  :: $::intranetdir :: $::opacdir ::
405 |;
406 <STDIN>
407         } else {
408             $getdirinfo=0;
409         }
410     }
411     $::kohalogdir='/var/log/koha';
412     my $message=getmessage('GetKohaLogDir', [$::kohalogdir]);
413     $::kohalogdir=showmessage($message, 'free', $::kohalogdir);
414
415
416     unless ( -d $::intranetdir ) {
417        my $result=mkdir ($::intranetdir, oct(770));
418        if ($result==0) {
419            my @dirs = split(m#/#, $::intranetdir);
420             my $checkdir='';
421             foreach (@dirs) {
422                 $checkdir.="$_/";
423                 unless (-e "$checkdir") {
424                     mkdir($checkdir, 0775);
425                 }
426             }
427        }
428        chown (oct(0), (getgrnam($::httpduser))[2], "$::intranetdir");
429        chmod (oct(770), "$::intranetdir");
430     }
431     unless ( -d "$::intranetdir/htdocs" ) {
432        mkdir ("$::intranetdir/htdocs", oct(750));
433     }
434     unless ( -d "$::intranetdir/cgi-bin" ) {
435        mkdir ("$::intranetdir/cgi-bin", oct(750));
436     }
437     unless ( -d "$::intranetdir/modules" ) {
438        mkdir ("$::intranetdir/modules", oct(750));
439     }
440     unless ( -d "$::intranetdir/scripts" ) {
441        mkdir ("$::intranetdir/scripts", oct(750));
442     }
443     unless ( -d $::opacdir ) {
444        my $result=mkdir ($::opacdir, oct(770));
445        if ($result==0) {
446            my @dirs = split(m#/#, $::opacdir);
447             my $checkdir='';
448             foreach (@dirs) {
449                 $checkdir.="$_/";
450                 unless (-e "$checkdir") {
451                     mkdir($checkdir, 0775);
452                 }
453             }
454        }
455        chown (oct(0), (getgrnam($::httpduser))[2], "$::opacdir");
456        chmod (oct(770), "$::opacdir");
457     }
458     unless ( -d "$::opacdir/htdocs" ) {
459        mkdir ("$::opacdir/htdocs", oct(750));
460     }
461     unless ( -d "$::opacdir/cgi-bin" ) {
462        mkdir ("$::opacdir/cgi-bin", oct(750));
463     }
464
465
466     unless ( -d $::kohalogdir ) {
467        my $result=mkdir ($::kohalogdir, oct(770));
468        if ($result==0) {
469            my @dirs = split(m#/#, $::kohalogdir);
470             my $checkdir='';
471             foreach (@dirs) {
472                 $checkdir.="$_/";
473                 unless (-e "$checkdir") {
474                     mkdir($checkdir, 0775);
475                 }
476             }
477        }
478
479        chown (oct(0), (getgrnam($::httpduser))[2,3], "$::kohalogdir");
480        chmod (oct(770), "$::kohalogdir");
481     }
482 }
483
484
485
486 $messages->{'DatabaseName'}->{en}=qq|
487 ==========================
488 = Name of MySQL database =
489 ==========================
490
491 Please provide the name of the mysql database for your koha installation.
492
493 Database name [%s]: |;
494
495 $messages->{'DatabaseHost'}->{en}=qq|
496 =================
497 = Database Host =
498 =================
499
500 Please provide the hostname for mysql.  Unless the database is located on
501 another machine this will be "localhost".
502
503 Database host [%s]: |;
504
505 $messages->{'DatabaseUser'}->{en}=qq|
506 =================
507 = Database User =
508 =================
509
510 Please provide the name of the user, who will have full administrative rights
511 to the %s database, when authenticating from %s.
512
513 Database user [%s]: |;
514
515 $messages->{'DatabasePassword'}->{en}=qq|
516 =====================
517 = Database Password =
518 =====================
519
520 Please provide a good password for the user %s.
521
522 Database Password: |;
523
524 $messages->{'BlankPassword'}->{en}=qq|
525 ==================
526 = BLANK PASSWORD =
527 ==================
528
529 You must not use a blank password for your MySQL user!
530
531 Press <ENTER> to try again: 
532 |;
533
534 sub getdatabaseinfo {
535
536     $::dbname = 'Koha';
537     $::hostname = 'localhost';
538     $::user = 'kohaadmin';
539     $::pass = '';
540
541 #Get the database name
542
543     my $message=getmessage('DatabaseName', [$::dbname]);
544     $::dbname=showmessage($message, 'free', $::dbname);
545
546 #Get the hostname for the database
547     
548     $message=getmessage('DatabaseHost', [$::hostname]);
549     $::hostname=showmessage($message, 'free', $::hostname);
550
551 #Get the username for the database
552
553     $message=getmessage('DatabaseUser', [$::dbname, $::hostname, $::user]);
554     $::user=showmessage($message, 'free', $::user);
555
556 #Get the password for the database user
557
558     while ($::pass eq '') {
559         my $message=getmessage('DatabasePassword', [$::user]);
560         $::pass=showmessage($message, 'free', $::pass);
561         if ($::pass eq '') {
562             my $message=getmessage('BlankPassword');
563             showmessage($message,'PressEnter');
564         }
565     }
566 }
567
568
569
570 $messages->{'FoundMultipleApacheConfFiles'}->{en}=qq|
571 ================================
572 = MULTIPLE APACHE CONFIG FILES =
573 ================================
574
575 I found more than one possible Apache configuration file:
576
577 %s
578
579 Choose the correct file [1]: |;
580
581 $messages->{'NoApacheConfFiles'}->{en}=qq|
582 ===============================
583 = NO APACHE CONFIG FILE FOUND =
584 ===============================
585
586 I was not able to find your Apache configuration file.
587
588 The file is usually called httpd.conf or apache.conf.
589
590 Please specify the location of your config file: |;
591
592 $messages->{'NotAFile'}->{en}=qq|
593 =======================
594 = FILE DOES NOT EXIST =
595 =======================
596
597 The file %s does not exist.
598
599 Please press <ENTER> to continue: |;
600
601 $messages->{'EnterApacheUser'}->{en}=qq|
602 ====================
603 = NEED APACHE USER =
604 ====================
605
606 I was not able to determine the user that Apache is running as.  This
607 information is necessary in order to set the access privileges correctly on
608 /etc/koha.conf.  This user should be set in one of the Apache configuration
609 files using the "User" directive.
610
611 Enter the Apache userid: |;
612
613 $messages->{'InvalidUserid'}->{en}=qq|
614 ==================
615 = INVALID USERID =
616 ==================
617
618 The userid %s is not a valid userid on this system.
619
620 Press <ENTER> to continue: |;
621
622 sub getapacheinfo {
623     my @confpossibilities;
624
625     foreach my $httpdconf (qw(/usr/local/apache/conf/httpd.conf
626                           /usr/local/etc/apache/httpd.conf
627                           /usr/local/etc/apache/apache.conf
628                           /var/www/conf/httpd.conf
629                           /etc/apache/conf/httpd.conf
630                           /etc/apache/conf/apache.conf
631                           /etc/apache-ssl/conf/apache.conf
632                           /etc/httpd/conf/httpd.conf
633                           /etc/httpd/httpd.conf)) {
634         if ( -f $httpdconf ) {
635             push @confpossibilities, $httpdconf;
636         }
637     }
638
639     if ($#confpossibilities==-1) {
640         my $message=getmessage('NoApacheConfFiles');
641         my $choice='';
642         until (-f $choice) {
643             $choice=showmessage($message, "free", 1);
644             unless (-f $choice) {
645                 showmessage(getmessage('NotAFile', [$choice]),'PressEnter', '', 1);
646             }
647         }
648     } elsif ($#confpossibilities>0) {
649         my $conffiles='';
650         my $counter=1;
651         my $options='';
652         foreach (@confpossibilities) {
653             $conffiles.="   $counter: $_\n";
654             $options.="$counter";
655             $counter++;
656         }
657         my $message=getmessage('FoundMultipleApacheConfFiles', [$conffiles]);
658         my $choice=showmessage($message, "restrictchar $options", 1);
659         $::realhttpdconf=$confpossibilities[$choice-1];
660     } else {
661         $::realhttpdconf=$confpossibilities[0];
662     }
663     open (HTTPDCONF, $::realhttpdconf) or warn "Insufficient privileges to open $::realhttpdconf for reading.\n";
664     while (<HTTPDCONF>) {
665         if (/^\s*User\s+"?([-\w]+)"?\s*$/) {
666             $::httpduser = $1;
667         }
668     }
669     close(HTTPDCONF);
670
671
672
673
674     unless ($::httpduser) {
675         my $message=getmessage('EnterApacheUser');
676         until (length($::httpduser) && getpwnam($::httpduser)) {
677             $::httpduser=showmessage($message, "free", '');
678             if (length($::httpduser)>0) {
679                 unless (getpwnam($::httpduser)) {
680                     my $message=getmessage('InvalidUserid', [$::httpduser]);
681                     showmessage($message,'PressEnter');
682                 }
683             } else {
684             }
685         }
686         print "AU: $::httpduser\n";
687     }
688 }
689
690
691 $messages->{'ApacheConfigIntroduction'}->{en}=qq|
692 ========================
693 = APACHE CONFIGURATION =
694 ========================
695
696 Koha needs to setup your Apache configuration file for the
697 OPAC and LIBRARIAN virtual hosts.  By default this installer
698 will do this by using one ip address and two different ports
699 for the virtual hosts.  There are other ways to set this up,
700 and the installer will leave comments in httpd.conf detailing
701 what these other options are.
702
703
704 Press <ENTER> to continue: |;
705
706 $messages->{'GetVirtualHostEmail'}->{en}=qq|
707 =============================
708 = WEB SERVER E-MAIL CONTACT =
709 =============================
710
711 Enter the e-mail address to be used as a contact for the virtual hosts (this
712 address is displayed if any errors are encountered).
713
714 E-mail contact [%s]: |;
715
716 $messages->{'GetServerName'}->{en}=qq|
717 ======================================
718 = WEB SERVER HOST NAME OR IP ADDRESS =
719 ======================================
720
721 Please enter the domain name or ip address of your computer.
722
723 Host name or IP Address [%s]: |;
724
725 $messages->{'GetOpacPort'}->{en}=qq|
726 ==========================
727 = OPAC VIRTUAL HOST PORT =
728 ==========================
729
730 Please enter the port for your OPAC interface.  This defaults to port 80, but
731 if you are already serving web content from this server, you should change it
732 to a different port (8000 might be a good choice).
733
734 Enter the OPAC Port [%s]: |;
735
736 $messages->{'GetIntranetPort'}->{en}=qq|
737 ==============================
738 = INTRANET VIRTUAL HOST PORT =
739 ==============================
740
741 Please enter the port for your Intranet interface.  This must be different from
742 the OPAC port (%s).
743
744 Enter the Intranet Port [%s]: |;
745
746
747 sub getapachevhostinfo {
748
749     $::svr_admin = "webmaster\@$::domainname";
750     $::servername=`hostname -f`;
751     chomp $::servername;
752     $::opacport=80;
753     $::intranetport=8080;
754
755     showmessage(getmessage('ApacheConfigIntroduction'), 'PressEnter');
756
757     $::svr_admin=showmessage(getmessage('GetVirtualHostEmail', [$::svr_admin]), 'email', $::svr_admin);
758     $::servername=showmessage(getmessage('GetServerName', [$::servername]), 'free', $::servername);
759
760
761     $::opacport=showmessage(getmessage('GetOpacPort', [$::opacport]), 'numerical', $::opacport);
762     $::intranetport=showmessage(getmessage('GetIntranetPort', [$::opacport, $::intranetport]), 'numerical', $::intranetport);
763
764 }
765
766 $messages->{'StartUpdateApache'}->{en}=qq|
767 =================================
768 = UPDATING APACHE CONFIGURATION =
769 =================================
770
771 Checking for modules that need to be loaded...
772 |;
773
774 $messages->{'LoadingApacheModuleModEnv'}->{en}="Loading SetEnv Apache module.\n";
775
776 $messages->{'LoadingApacheModuleModInc'}->{en}="Loading Includes Apache module.\n";
777
778 $messages->{'ApacheConfigBackupFailed'}->{en}=qq|
779 ======================================
780 = APACHE CONFIGURATION BACKUP FAILED =
781 ======================================
782
783 An error occurred while trying to make a backup copy of %s.
784
785   %s
786
787 No changes will be made to the apache configuration file at this time.
788
789 Press <ENTER> to continue: |;
790
791
792 $messages->{'ApacheAlreadyConfigured'}->{en}=qq|
793 =============================
794 = APACHE ALREADY CONFIGURED =
795 =============================
796
797 %s appears to already have an entry for Koha
798 Virtual Hosts.  You may need to edit %s
799 f anything has changed since it was last set up.  This
800 script will not attempt to modify an existing Koha apache
801 configuration.
802
803 Press <ENTER> to continue: |;
804
805 sub updateapacheconf {
806     my $logfiledir=`grep ^ErrorLog $::realhttpdconf`;
807     chomp $logfiledir;
808
809     if ($logfiledir) {
810         $logfiledir=~m#ErrorLog (.*)/[^/]*$#;
811         $logfiledir=$1;
812     }
813
814     unless ($logfiledir) {
815         $logfiledir='logs';
816     }
817
818     showmessage(getmessage('StartUpdateApache'), 'none');
819
820     my $httpdconf;
821     my $envmodule=0;
822     my $includesmodule=0;
823     open HC, $::realhttpdconf;
824     while (<HC>) {
825         if (/^\s*#\s*LoadModule env_module /) {
826             s/^\s*#\s*//;
827             showmessage(getmessage('LoadingApacheModuleModEnv'));
828             $envmodule=1;
829         }
830         if (/^\s*#\s*LoadModule includes_module /) {
831             s/^\s*#\s*//;
832             showmessage(getmessage('LoadingApacheModuleModInc'));
833         }
834         if (/\s*LoadModule includes_module / ) {
835             $includesmodule=1;
836         }
837         $httpdconf.=$_;
838     }
839
840     my $backupfailed=0;
841     $backupfailed=`cp -f $::realhttpdconf $::realhttpdconf\.prekoha`;
842     if ($backupfailed) {
843         showmessage(getmessage('ApacheConfigBackupFailed', [$::realhttpdconf,$backupfailed ]), 'PressEnter');
844         return;
845     }
846
847     if ($envmodule || $includesmodule) {
848         open HC, ">$::realhttpdconf";
849         print HC $httpdconf;
850         close HC;
851     }
852
853
854     
855     if (`grep 'VirtualHost $::servername' $::realhttpdconf`) {
856         showmessage(getmessage('ApacheAlreadyConfigured', [$::realhttpdconf, $::realhttpdconf]), 'PressEnter');
857         return;
858     } else {
859         my $includesdirectives='';
860         if ($includesmodule) {
861             $includesdirectives.="Options +Includes\n";
862             $includesdirectives.="   AddHandler server-parsed .html\n";
863         }
864         open(SITE,">>$::realhttpdconf") or warn "Insufficient priveleges to open $::realhttpdconf for writing.\n";
865         my $opaclisten = '';
866         if ($::opacport != 80) {
867             $opaclisten="Listen $::opacport";
868         }
869         my $intranetlisten = '';
870         if ($::intranetport != 80) {
871             $intranetlisten="Listen $::intranetport";
872         }
873         print SITE <<EOP
874
875 # Ports to listen to for Koha
876 $opaclisten
877 $intranetlisten
878
879 # NameVirtualHost is used by one of the optional configurations detailed below
880
881 #NameVirtualHost 11.22.33.44
882
883 # KOHA's OPAC Configuration
884 <VirtualHost $::servername\:$::opacport>
885    ServerAdmin $::svr_admin
886    DocumentRoot $::opacdir/htdocs
887    ServerName $::servername
888    ScriptAlias /cgi-bin/koha/ $::opacdir/cgi-bin/
889    ErrorLog $logfiledir/opac-error_log
890    TransferLog $logfiledir/opac-access_log
891    SetEnv PERL5LIB "$::intranetdir/modules"
892    $includesdirectives
893 </VirtualHost>
894
895 # KOHA's INTRANET Configuration
896 <VirtualHost $::servername\:$::intranetport>
897    ServerAdmin $::svr_admin
898    DocumentRoot $::intranetdir/htdocs
899    ServerName $::servername
900    ScriptAlias /cgi-bin/koha/ "$::intranetdir/cgi-bin/"
901    ErrorLog $logfiledir/koha-error_log
902    TransferLog $logfiledir/koha-access_log
903    SetEnv PERL5LIB "$::intranetdir/modules"
904    $includesdirectives
905 </VirtualHost>
906
907 # If you want to use name based Virtual Hosting:
908 #   1. remove the two Listen lines
909 #   2. replace $::servername\:$::opacport wih your.opac.domain.name
910 #   3. replace ServerName $::servername wih ServerName your.opac.domain.name
911 #   4. replace $::servername\:$::intranetport wih your intranet domain name
912 #   5. replace ServerName $::servername wih ServerName your.intranet.domain.name
913 #
914 # If you want to use NameVirtualHost'ing (using two names on one ip address):
915 #   1.  Follow steps 1-5 above
916 #   2.  Uncomment the NameVirtualHost line and set the correct ip address
917
918 EOP
919
920
921     }
922 }
923
924 $messages->{'IntranetAuthenticationQuestion'}->{en}=qq|
925 ===========================
926 = INTRANET AUTHENTICATION =
927 ===========================
928
929 I can set it up so that the Intranet/Librarian site is password protected using
930 Apache's Basic Authorization.
931
932 Would you like to do this ([Y]/N): |;
933
934 $messages->{'BasicAuthUsername'}->{en}="Please enter a userid for intranet access [%s]: ";
935 $messages->{'BasicAuthPassword'}->{en}="Please enter a password for %s: ";
936 $messages->{'BasicAuthPasswordWasBlank'}->{en}="\nYou cannot use a blank password!\n\n";
937
938 sub basicauthentication {
939     my $message=getmessage('IntranetAuthenticationQuestion');
940     my $answer=showmessage($message, 'yn', 'y');
941
942     my $apacheauthusername='librarian';
943     my $apacheauthpassword='';
944     if ($answer=~/^y/i) {
945         ($apacheauthusername) = showmessage(getmessage('BasicAuthUsername', [ $apacheauthusername]), 'free', $apacheauthusername, 1);
946         $apacheauthusername=~s/[^a-zA-Z0-9]//g;
947         while (! $apacheauthpassword) {
948             ($apacheauthpassword) = showmessage(getmessage('BasicAuthPassword', [ $apacheauthusername]), 'free', 1);
949             if (!$apacheauthpassword) {
950                 ($apacheauthpassword) = showmessage(getmessage('BasicAuthPasswordWasBlank'), 'none', '', 1);
951             }
952         }
953         open AUTH, ">/etc/kohaintranet.pass";
954         my $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
955         my $salt=substr($chars, int(rand(length($chars))),1);
956         $salt.=substr($chars, int(rand(length($chars))),1);
957         print AUTH $apacheauthusername.":".crypt($apacheauthpassword, $salt)."\n";
958         close AUTH;
959         open(SITE,">>$::realhttpdconf") or warn "Insufficient priveleges to open $::realhttpdconf for writing.\n";
960         print SITE <<EOP
961
962 <Directory $::intranetdir>
963     AuthUserFile /etc/kohaintranet.pass
964     AuthType Basic
965     AuthName "Koha Intranet (for librarians only)"
966     Require  valid-user
967 </Directory>
968 EOP
969     }
970     close(SITE);
971 }
972
973 $messages->{'InstallFiles'}->{en}=qq|
974 ====================
975 = INSTALLING FILES =
976 ====================
977
978 Copying files to installation directories:
979
980 |;
981
982
983 $messages->{'CopyingFiles'}->{en}="Copying %s to %s.\n";
984
985
986
987 sub installfiles {
988
989
990     showmessage(getmessage('InstallFiles'),'none');
991     print getmessage('CopyingFiles', ['intranet-html', "$::intranetdir/htdocs" ]);
992     system("cp -R intranet-html/* $::intranetdir/htdocs/");
993     print getmessage('CopyingFiles', ['intranet-cgi', "$::intranetdir/cgi-bin" ]);
994     system("cp -R intranet-cgi/* $::intranetdir/cgi-bin/");
995     print getmessage('CopyingFiles', ['stand-alone scripts', "$::intranetdir/scripts" ]);
996     system("cp -R scripts/* $::intranetdir/scripts/");
997     print getmessage('CopyingFiles', ['perl modules', "$::intranetdir/modules" ]);
998     system("cp -R modules/* $::intranetdir/modules/");
999     print getmessage('CopyingFiles', ['opac-html', "$::opacdir/htdocs" ]);
1000     system("cp -R opac-html/* $::opacdir/htdocs/");
1001     print getmessage('CopyingFiles', ['opac-cgi', "$::opacdir/cgi-bin" ]);
1002     system("cp -R opac-cgi/* $::opacdir/cgi-bin/");
1003     system("touch $::opacdir/cgi-bin/opac");
1004
1005     system("chown -R root.$::httpduser $::opacdir");
1006     system("chown -R root.$::httpduser $::intranetdir");
1007
1008     # Create /etc/koha.conf
1009
1010     my $old_umask = umask(027); # make sure koha.conf is never world-readable
1011     open(SITES,">$::etcdir/koha.conf.tmp") or warn "Couldn't create file at $::etcdir. Must have write capability.\n";
1012     print SITES qq|
1013 database=$::dbname
1014 hostname=$::hostname
1015 user=$::user
1016 pass=$::pass
1017 includes=$::intranetdir/htdocs/includes
1018 intranetdir=$::intranetdir
1019 opacdir=$::opacdir
1020 kohalogdir=$::kohalogdir
1021 kohaversion=$::kohaversion
1022 httpduser=$::httpduser
1023 |;
1024     close(SITES);
1025     umask($old_umask);
1026
1027     chown((getpwnam($::httpduser)) [2,3], "$::etcdir/koha.conf.tmp") or warn "can't chown koha.conf: $!";
1028     chmod 0440, "$::etcdir/koha.conf.tmp";
1029
1030     chmod 0750, "$::intranetdir/scripts/z3950daemon/z3950-daemon-launch.sh";
1031     chmod 0750, "$::intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh";
1032     chmod 0750, "$::intranetdir/scripts/z3950daemon/processz3950queue";
1033     chown(0, (getpwnam($::httpduser)) [3], "$::intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh") or warn "can't chown $::intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh: $!";
1034     chown(0, (getpwnam($::httpduser)) [3], "$::intranetdir/scripts/z3950daemon/processz3950queue") or warn "can't chown $::intranetdir/scripts/z3950daemon/processz3950queue: $!";
1035
1036 }
1037
1038 $messages->{'MysqlRootPassword'}->{en}=qq|
1039 ============================
1040 = MYSQL ROOT USER PASSWORD =
1041 ============================
1042
1043 To allow us to create the koha database please supply your
1044 mysql server's root user password:
1045
1046 Enter MySql root user password: |;
1047
1048 $messages->{'InvalidMysqlRootPassword'}->{en}="Invalid Password.  Please try again.";
1049
1050 $messages->{'CreatingDatabase'}->{en}=qq|
1051 =====================
1052 = CREATING DATABASE =
1053 =====================
1054
1055 Creating the MySql database for Koha...
1056
1057 |;
1058
1059 $messages->{'CreatingDatabaseError'}->{en}=qq|
1060 ===========================
1061 = ERROR CREATING DATABASE =
1062 ===========================
1063
1064 Couldn't connect to the MySQL server for the reason given above.
1065 This is a serious problem, the database will not get installed.\a
1066
1067 Press <ENTER> to continue: |;
1068
1069 $messages->{'SampleData'}->{en}=qq|
1070 ===============
1071 = SAMPLE DATA =
1072 ===============
1073
1074 If you are installing Koha for evaluation purposes,  I have a batch of sample
1075 data that you can install now.
1076
1077 If you are installing Koha with the intention of populating it with your own
1078 data, you probably don't want this sample data installed.
1079
1080 Would you like to install the sample data? Y/[N]: |;
1081
1082 $messages->{'SampleDataInstalled'}->{en}=qq|
1083 =========================
1084 = SAMPLE DATA INSTALLED =
1085 =========================
1086
1087 Sample data has been installed.  For some suggestions on testing Koha, please
1088 read the file doc/HOWTO-Testing.  If you find any bugs, please submit them at
1089 http://bugs.koha.org/.  If you need help with testing Koha, you can post a
1090 question through the koha-devel mailing list, or you can check for a developer
1091 online at +irc.katipo.co.nz:6667 channel #koha.
1092
1093 You can find instructions for subscribing to the Koha mailing lists at:
1094
1095     http://www.koha.org
1096
1097
1098 Press <ENTER> to continue: |;
1099
1100 $messages->{'AddBranchPrinter'}->{en}=qq|
1101 ==========================
1102 = Add Branch and Printer =
1103 ==========================
1104
1105 Would you like to install an initial branch and printer? [Y]/N: |;
1106
1107 $messages->{'BranchName'}->{en}="Branch Name [%s]: ";
1108 $messages->{'BranchCode'}->{en}="Branch Code (4 letters or numbers) [%s]: ";
1109 $messages->{'PrinterQueue'}->{en}="Printer Queue [%s]: ";
1110 $messages->{'PrinterName'}->{en}="Printer Name [%s]: ";
1111
1112 sub databasesetup {
1113     $::mysqluser = 'root';
1114     $::mysqlpass = '';
1115
1116     foreach my $mysql (qw(/usr/local/mysql
1117                           /opt/mysql
1118                           /usr
1119                           )) {
1120        if ( -d $mysql  && -f "$mysql/bin/mysqladmin") {
1121             $::mysqldir=$mysql;
1122        }
1123     }
1124     if (!$::mysqldir){
1125         print "I don't see mysql in the usual places.\n";
1126         for (;;) {
1127             print "Where have you installed mysql? ";
1128             chomp($::mysqldir = <STDIN>);
1129             last if -f "$::mysqldir/bin/mysqladmin";
1130         print <<EOP;
1131
1132 I can't find it there either. If you compiled mysql yourself,
1133 please give the value of --prefix when you ran configure.
1134
1135 The file mysqladmin should be in bin/mysqladmin under the directory that you
1136 provide here.
1137
1138 EOP
1139         }
1140     }
1141
1142
1143     my $needpassword=1;
1144     while ($needpassword) {
1145         $::mysqlpass=showmessage(getmessage('MysqlRootPassword'), 'free');
1146         $::mysqlpass_quoted = $::mysqlpass;
1147         $::mysqlpass_quoted =~ s/"/\\"/g;
1148         my $result=system("$::mysqldir/bin/mysqladmin -u$::mysqluser -p\"$::mysqlpass_quoted\" proc > /dev/null 2>&1");
1149         if ($result) {
1150             print getmessage('InvalidMysqlRootPassword');
1151         } else {
1152             $needpassword=0;
1153         }
1154     }
1155
1156     showmessage(getmessage('CreatingDatabase'),'none');
1157
1158     my $result=system("$::mysqldir/bin/mysqladmin -u$::mysqluser -p$::mysqlpass create $::dbname");
1159     if ($result) {
1160         showmessage(getmessage('CreatingDatabaseError'),'PressEnter', '', 1);
1161     } else {
1162         # Populate the Koha database
1163         system("$::mysqldir/bin/mysql -u$::mysqluser -p\"$::mysqlpass_quoted\" $::dbname < koha.mysql");
1164         # Set up permissions
1165         system("$::mysqldir/bin/mysql -u$::mysqluser -p\"$::mysqlpass_quoted\" mysql -e \"insert into user (Host,User,Password) values ('$::hostname','$::user',password('$::pass'))\"\;");
1166         system("$::mysqldir/bin/mysql -u$::mysqluser -p\"$::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')\"");
1167         system("$::mysqldir/bin/mysqladmin -u$::mysqluser -p\"$::mysqlpass_quoted\" reload");
1168
1169
1170
1171
1172
1173     }
1174
1175 }
1176
1177 sub updatedatabase {
1178     my $result=system ("perl -I $::intranetdir/modules scripts/updater/updatedatabase");
1179     if ($result) {
1180         print "Problem updating database...\n";
1181         exit;
1182     }
1183     print "\n\nFinished updating database. Press <ENTER> to continue...";
1184     <STDIN>;
1185 }
1186
1187 sub populatedatabase {
1188     my $response=showmessage(getmessage('SampleData'), 'yn', 'n');
1189     if ($response =~/^y/i) {
1190         system("gunzip sampledata-1.2.gz");
1191         system("cat sampledata-1.2 | $::mysqldir/bin/mysql -u$::mysqluser -p$::mysqlpass $::dbname");
1192         system("gzip -9 sampledata-1.2");
1193         system("$::mysqldir/bin/mysql -u$::mysqluser -p$::mysqlpass $::dbname -e \"insert into branches (branchcode,branchname,issuing) values ('MAIN', 'Main Library', 1)\"");
1194         system("$::mysqldir/bin/mysql -u$::mysqluser -p$::mysqlpass $::dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1195         system("$::mysqldir/bin/mysql -u$::mysqluser -p$::mysqlpass $::dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1196         system("$::mysqldir/bin/mysql -u$::mysqluser -p$::mysqlpass $::dbname -e \"insert into printers (printername,printqueue,printtype) values ('Circulation Desk Printer', 'lp', 'hp')\"");
1197         showmessage(getmessage('SampleDataInstalled'), 'PressEnter','',1);
1198     } else {
1199         my $input;
1200         my $response=showmessage(getmessage('AddBranchPrinter'), 'yn', 'y');
1201
1202         unless ($response =~/^n/i) {
1203             my $branch='Main Library';
1204             print "Enter a name for the library branch [$branch]: ";
1205             $branch=showmessage(getmessage('BranchName', [$branch]), 'free', $branch, 1);
1206             $branch=~s/[^A-Za-z0-9\s]//g;
1207
1208             my $branchcode=$branch;
1209             $branchcode=~s/[^A-Za-z0-9]//g;
1210             $branchcode=uc($branchcode);
1211             $branchcode=substr($branchcode,0,4);
1212             $branchcode=showmessage(getmessage('BranchCode', [$branchcode]), 'free', $branchcode, 1);
1213             $branchcode=~s/[^A-Z]//g;
1214             $branchcode=uc($branchcode);
1215             $branchcode=substr($branchcode,0,4);
1216
1217             system("$::mysqldir/bin/mysql -u$::mysqluser -p$::mysqlpass $::dbname -e \"insert into branches (branchcode,branchname,issuing) values ('$branchcode', '$branch', 1)\"");
1218             system("$::mysqldir/bin/mysql -u$::mysqluser -p$::mysqlpass $::dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\"");
1219             system("$::mysqldir/bin/mysql -u$::mysqluser -p$::mysqlpass $::dbname -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\"");
1220
1221             my $printername='Library Printer';
1222             $printername=showmessage(getmessage('PrinterName', [$printername]), 'free', $printername, 1);
1223             $printername=~s/[^A-Za-z0-9\s]//g;
1224
1225             my $printerqueue='lp';
1226             $printerqueue=showmessage(getmessage('PrinterQueue', [$printerqueue]), 'free', $printerqueue, 1);
1227             $printerqueue=~s/[^A-Za-z0-9]//g;
1228             system("$::mysqldir/bin/mysql -u$::mysqluser -p$::mysqlpass $::dbname -e \"insert into printers (printername,printqueue,printtype) values ('$printername', '$printerqueue', '')\"");
1229
1230         }
1231     }
1232 }
1233
1234 $messages->{'RestartApache'}->{en}=qq|
1235 ==================
1236 = RESTART APACHE =
1237 ==================
1238
1239 Apache needs to be restarted to load the new configuration for Koha.
1240
1241 Would you like to restart Apache now?  [Y]/N: |;
1242
1243 sub restartapache {
1244
1245     my $response=showmessage(getmessage('RestartApache'), 'yn', 'y');
1246
1247
1248
1249     unless ($response=~/^n/i) {
1250         # Need to support other init structures here?
1251         if (-e "/etc/rc.d/init.d/httpd") {
1252             system('/etc/rc.d/init.d/httpd restart');
1253         } elsif (-e "/etc/init.d/apache") {
1254             system('/etc//init.d/apache restart');
1255         } elsif (-e "/etc/init.d/apache-ssl") {
1256             system('/etc/init.d/apache-ssl restart');
1257         }
1258     }
1259
1260 }
1261
1262
1263 sub loadconfigfile {
1264     my %configfile;
1265
1266     open (KC, "/etc/koha.conf");
1267     while (<KC>) {
1268      chomp;
1269      (next) if (/^\s*#/);
1270      if (/(.*)\s*=\s*(.*)/) {
1271        my $variable=$1;
1272        my $value=$2;
1273        # Clean up white space at beginning and end
1274        $variable=~s/^\s*//g;
1275        $variable=~s/\s*$//g;
1276        $value=~s/^\s*//g;
1277        $value=~s/\s*$//g;
1278        $configfile{$variable}=$value;
1279      }
1280     }
1281
1282     $::intranetdir=$configfile{'intranetdir'};
1283     $::opacdir=$configfile{'opacdir'};
1284     $::kohaversion=$configfile{'kohaversion'};
1285     $::kohalogdir=$configfile{'kohalogdir'};
1286     $::database=$configfile{'database'};
1287     $::hostname=$configfile{'hostname'};
1288     $::user=$configfile{'user'};
1289     $::pass=$configfile{'pass'};
1290 }
1291
1292 END { }       # module clean-up code here (global destructor)
1293
1294 1;