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