Finalized XML version for intranet
[koha.git] / misc / Install.pm
1 package Install; #assumes Install.pm
2
3
4 # Copyright 2000-2002 Katipo Communications
5 # Contains parts Copyright 2003-4 MJ Ray
6 #
7 # This file is part of Koha.
8 #
9 # Koha is free software; you can redistribute it and/or modify it under the
10 # terms of the GNU General Public License as published by the Free Software
11 # Foundation; either version 2 of the License, or (at your option) any later
12 # version.
13 #
14 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License along with
19 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
20 # Suite 330, Boston, MA  02111-1307 USA
21 #
22 # Current maintainer MJR slef at users.sourceforge.net
23
24 use strict;
25 use POSIX;
26 #MJR: everyone will have these modules, right?
27 # They look like part of perl core to me
28 use Term::ANSIColor qw(:constants);
29 use Text::Wrap;
30 use File::Temp qw/ :mktemp /;
31 require Exporter;
32
33 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
34
35 =head1 NAME
36
37 Install.pm - Perl module containing the bulk of the installation logic
38
39 =head1 DESCRIPTION
40
41 The Install.pm module contains the bulk
42 of the code to do installation;
43 this code is used by installer.pl
44 to perform an actual installation.
45
46 =head2 Internal variables
47
48 =over 4
49
50 =item $VERSION, @ISA, @EXPORT
51
52 Defines the version and structure of the module interface
53
54 =cut
55
56 # set the version for version checking
57 $VERSION = 2.2.3;
58
59 @ISA = qw(Exporter);
60 @EXPORT = qw(
61                 &read_autoinstall_file
62                 &checkperlmodules
63                 &checkabortedinstall
64                 &getmessage
65                 &showmessage
66                 &completeupgrade
67                 &releasecandidatewarning
68                 &getinstallationdirectories
69                 &getdatabaseinfo
70                 &getapacheinfo
71                 &getapachevhostinfo
72                 &updateapacheconf
73                 &basicauthentication
74                 &installfiles
75                 &databasesetup
76                 &updatedatabase
77                 &populatedatabase
78                 &restartapache
79                 &backupkoha
80                 &finalizeconfigfile
81                 &loadconfigfile
82                 &backupmycnf
83                 &restoremycnf
84                 );
85
86 =item $kohaversion, $newversion, $language, $clear_string
87
88 Installer setting details
89
90 =item $etcdir, $intranetdir, $opacdir, $kohalogdir
91
92 Directories to use for installation (configuration, intranet, opac, logs)
93
94 =item $domainname, $realhttpdconf, $httpduser, $httpdgroup, $servername, $svr_admin, $opacport, $intranetport, $hostname, $user, $pass
95
96 Apache configuration settings
97
98 =item $mysqldir, $database, $mysqluser, $mysqlpass, $mycnf, $mytmpcnf
99
100 MySQL configuration settings
101
102 =cut
103
104 use vars qw( $kohaversion $newversion $language
105   $etcdir $intranetdir $opacdir $kohalogdir
106   $domainname $realhttpdconf $httpduser $httpdgroup
107   $servername $svr_admin $opacport $intranetport
108   $hostname $user $pass
109   $mysqldir $database $mysqluser $mysqlpass );
110
111 my $clear_string = "\n\n"; #MJR: was $terminal->Tputs('cl');
112
113 my $mycnf = $ENV{HOME}."/.my.cnf";
114 my $mytmpcnf = mktemp("my.cnf.koha.XXXXXX");
115 chomp($mytmpcnf);
116
117 =back
118
119 =head2 Internal functions (not meant to be used outside of Install.pm)
120
121 =over 4
122
123 =item C<heading($)>
124
125 Takes: a string to be displayed as the heading
126
127 Returns: a formatted heading (currently with ANSI colours).
128
129 This reduces the likelihood of pod2man(1) etc. misinterpreting
130 a line of equal signs as illegal POD directives.
131
132 =cut
133
134 sub heading ($) {
135   my $title = shift;
136   my $bal = 5;
137   return($clear_string.ON_BLUE.WHITE.BOLD." "x$bal.uc($title)." "x$bal.RESET."\n\n");
138 }
139
140 my $messages;
141 $messages->{'continuing'}->{en}="Great!  Continuing...\n\n";
142 $messages->{'WelcomeToKohaInstaller'}->{en} =
143    heading('Welcome to the Koha Installer') . qq|
144 This program will ask some questions and try to install koha for you.
145 You need to know: where most koha files should be stored (you can set
146 the prefix environment variable for this); the username and password of
147 a mysql superuser; and details of your library setup.  You may also need
148 to know details of your Apache setup.
149
150 If you want to install the Koha configuration files somewhere other than
151 /etc (for installing not as root, or to have many Kohas on one system, for example), you should
152 set the etcdir environment variable.  Please look at your manuals for
153 details of how to set that.
154
155 Recommended answers are given in brackets after each question.  To accept
156 the default value for any question (indicated by []), simply hit Enter
157 at the prompt.
158
159 Note that you also can define an auto_install_file, that will answer every question automatically.
160 To use this feature, run ./installer.pl -i /path/to/auto_install_file 
161
162 Are you ready to begin the installation? ([Y]/N): |;
163
164 $messages->{'WelcomeToUpgrader'}->{en} =
165    heading('Welcome to the Koha Upgrader') . qq|
166 You are attempting to upgrade from Koha %s to Koha %s.
167
168 We recommend that you do a complete backup of all your files before upgrading.
169 This upgrade script will make a backup copy of your files for you.
170
171 Would you like to proceed?  (Y/[N]):|;
172
173 $messages->{'AbortingInstall'}->{en} =
174    heading('ABORTING') . qq|
175 Aborting as requested.  Please rerun when you are ready.
176 |;
177
178 $messages->{'ReleaseCandidateWarning'}->{en} =
179    heading('RELEASE CANDIDATE') . qq|
180 WARNING: You are about to install Koha version %s.  This is a
181 release candidate, It is NOT bugfree.
182 However, it works, and has been declared stable enough to
183 be released.
184
185 Most people should answer Yes here.
186
187 Are you sure you want to install Koha %s? (Y/[N]): |;
188 $messages->{'WatchForReleaseAnnouncements'}->{en}=qq|
189
190 Watch for announcements of Koha releases on the Koha mailing list or the Koha
191 web site (http://www.koha.org/).
192
193 |;
194
195 $messages->{'NETZ3950Missing'}->{en}=qq|
196
197 The Net::Z3950 module is missing.  This module is necessary if you want to use
198 Koha's Z39.50 client to download bibliographic records from other libraries.
199
200 To install this module, you will need the yaz client installed from
201 http://www.indexdata.dk/yaz/ and then you can install the perl module with the
202 command:
203
204 perl -MCPAN -e 'install Net::Z3950'
205
206 ...or by installing packages for your distribution, if available.
207
208 IMPORTANT NOTE : If you use Perl 5.8.0, you might need to 
209 edit NET::Z3950's Makefile.PL and yazwrap/Makefile.PL to include:
210
211     'DEFINE' => '-D_GNU_SOURCE',
212
213 Also note that some installations of Perl on Red Hat will generate a lot of
214 "'my_perl' undeclared" errors when running make in Net-Z3950.  This is fixed by
215 inserting in yazwrap/ywpriv.h a line saying #include "XSUB.h"
216
217 Press the <ENTER> key to continue: |;   #'
218
219 $messages->{'CheckingPerlModules'}->{en} = heading('PERL MODULES') . qq|
220 Checking perl modules ...
221 |;
222
223 $messages->{'PerlVersionFailure'}->{en}="Sorry, you need at least Perl %s\n";
224
225 $messages->{'MissingPerlModules'}->{en} = heading('MISSING PERL MODULES') . qq|
226 You are missing some Perl modules required by Koha.
227 Please run this again after installing them.
228 They may be installed by finding packages from your operating system supplier, or running (as root) the following commands:
229
230 %s
231 |;
232
233 $messages->{'AllPerlModulesInstalled'}->{en} =
234    heading('PERL MODULES AVAILABLE') . qq|
235 All required perl modules are installed.
236
237 Press <ENTER> to continue: |;
238 $messages->{'KohaVersionInstalled'}->{en}="You currently have Koha %s on your system.";
239 $messages->{'KohaUnknownVersionInstalled'}->{en}="I am not able to determine what version of Koha is installed now.";
240 $messages->{'KohaAlreadyInstalled'}->{en} =
241    heading('Koha already installed') . qq|
242 It looks like Koha is already installed on your system (%s/koha.conf exists).
243 If you would like to upgrade your system to %s, please use
244 the koha.upgrade script in this directory.
245
246 %s
247
248 |;
249 $messages->{'GetOpacDir'}->{en} = heading('OPAC DIRECTORY') . qq|
250 Please supply the directory you want Koha to store its OPAC files in.  This
251 directory will be auto-created for you if it doesn't exist.
252
253 OPAC Directory [%s]: |; #'
254
255 $messages->{'GetIntranetDir'}->{en} =
256    heading('LIBRARIAN DIRECTORY') . qq|
257 Please supply the directory you want Koha to store its Librarian interface
258 files in.  This directory will be auto-created for you if it doesn't exist.
259
260 Intranet Directory [%s]: |;     #'
261
262 $messages->{'GetKohaLogDir'}->{en} = heading('LOG DIRECTORY') . qq|
263 Specify a directory where log files will be written.
264
265 Koha Log Directory [%s]: |;
266
267 $messages->{'AuthenticationWarning'}->{en} = heading('Authentication') . qq|
268 This release of Koha has a new authentication module.
269 You will be required to log in to
270 access some features.
271
272 IMPORTANT: You can log in using the userid and password from the %s/koha.conf configuration file at any time.
273 Use the "Members" screen to add passwords for other accounts and set their flags.
274
275 Press the <ENTER> key to continue: |;
276
277 $messages->{'Completed'}->{en} = heading('INSTALLATION COMPLETE') . qq|
278 Congratulations ... your Koha installation is complete!
279
280 You will be able to connect to your Librarian interface at:
281
282    http://%s\:%s/
283
284    use the koha admin mysql login and password to connect to this interface.
285 and the OPAC interface at:
286
287    http://%s\:%s/
288    
289 NOTE: You need to add lines to your main httpd.conf to include
290 /etc/koha-httpd.conf and to make sure it is listening on the right ports
291 (using the Listen directive). Then, restart Apache.
292
293 Please read the Hints file and visit http://www.koha.org (in english) or www.koha-fr.org (in french)
294 Press <ENTER> to exit the installer: |;
295
296 $messages->{'UpgradeCompleted'}->{en} = heading('UPGRADE COMPLETE') . qq|
297 Congratulations ... your Koha upgrade is finished!
298
299 Please report any problems you encounter through http://bugs.koha.org/
300
301 Press <ENTER> to exit the installer: |;
302
303 #'
304
305 =item C<completeupgrade()>
306
307 Display a message describing what may need changing in httpd.conf
308 and any other instructions for just before exit.
309
310 =cut
311
312 sub completeupgrade {
313         showmessage(getmessage('UpgradeCompleted',[$intranetdir,$intranetdir,$intranetdir,$opacdir,$opacdir,$intranetdir]),'PressEnter');
314 }
315
316 =item C<releasecandidatewarning()>
317
318 Display a warning about upgrading to a public test release.
319
320 =cut
321
322 sub releasecandidatewarning {
323     my $message=getmessage('ReleaseCandidateWarning', [$newversion, $newversion]);
324     my $answer=showmessage($message, 'yn', 'n');
325
326     if ($answer =~ /y/i) {
327         print getmessage('continuing');
328     } else {
329         my $message=getmessage('WatchForReleaseAnnouncements');
330         print $message."\n";
331         exit;
332     };
333 }
334
335 =item C<read_autoinstall_file($)>
336
337 Takes: a configuration file describing the installation
338
339 Returns: a hashref of the configuration
340
341 =cut
342
343 sub read_autoinstall_file
344 {
345         my $fname = shift;      # Config file to read
346         my $retval = {};        # Return value: ref-to-hash holding the
347                                 # configuration
348
349         open (CONF, $fname) or return undef;
350
351         while (<CONF>)
352         {
353                 my $var;                # Variable name
354                 my $value;              # Variable value
355
356                 chomp;
357                 s/#.*//;                # Strip comments
358                 next if /^\s*$/;        # Ignore blank lines
359
360                 # Look for a line of the form
361                 #       var = value
362                 if (!/^\s*(\w+)\s*=\s*(.*?)\s*$/)
363                 {
364                         next;
365                 }
366
367                 # Found a variable assignment
368                 # variable that was already set.
369                 $var = $1;
370                 $value = $2;
371                 $retval->{$var} = $value;
372         }
373         close CONF;
374         if ($retval->{MysqlRootPassword} eq "XXX") {
375                 print "ERROR : the root password is XXX. It is NOT valid. Edit your auto_install_file\n";
376         }
377         return $retval;
378 }
379
380 =back
381
382 =head2 Accessor functions (for installer.pl)
383
384 =over 4
385
386 =item C<setlanguage($)>
387
388 Sets the installation language code, normally "en" (English).
389 Only "en" is supported so far.
390
391 =cut
392
393 sub setlanguage ($) {
394     ($language) = @_;
395 }
396
397 =item C<setdomainname($)>
398
399 Sets the domain name of the host.
400
401 The domain name should not contain a leading dot;
402 otherwise, the results are undefined.
403
404 =cut
405
406 sub setdomainname ($) {
407     ($domainname) = @_;
408 }
409
410 =item C<setetcdir($)>
411
412 Sets the sysconfdir, normally /etc.
413 This should be an absolute path; a trailing / is not required.
414 Must be writeable, else we die.
415
416 =cut
417
418 sub setetcdir ($) {
419     ($etcdir) = @_;
420     if (! ((-d $etcdir) && (-w $etcdir))) { die("Cannot write to $etcdir! Please set the etcdir environment variable to a writeable directory.\nFailed"); }
421 }
422
423 =item C<getkohaversion()>
424
425 Returns: the Koha version as known by the previous config file..
426
427 =cut
428
429 sub getkohaversion () {
430     return($kohaversion);
431 }
432
433 =item C<setkohaversion($)>
434
435 Sets the Koha version as known by the installer.
436
437 Note: function is now misnamed, setting $newversion not $kohaversion
438
439 =cut
440
441 sub setkohaversion ($) {
442     ($newversion) = @_;
443 }
444
445 =item C<getservername()>
446
447 Returns: the name of the Koha virtual server as specified by the user.
448
449 =cut
450
451 sub getservername () {
452     $servername;
453 }
454
455 =item C<getopacport()>
456
457 Returns the port that will run the Koha OPAC virtual server, as
458 specified by the user.
459
460 =cut
461
462 sub getopacport () {
463     $opacport;
464 }
465
466 =item C<getintranetport()>
467
468 Returns the port that will run the Koha INTRANET virtual server, as
469 specified by the user.
470
471 =cut
472
473 sub getintranetport () {
474     $intranetport;
475 }
476
477 =back
478
479 =head2 Miscellaneous utility functions
480
481 =over 4
482
483 =item C<dirname($)>
484
485 Does the equivalent of dirname(1).
486
487 Takes: a path
488
489 Returns: parent directory of path (best guess), except when the path
490 seems to be the same as /, in which case it is returned unchanged.
491
492 =cut
493
494 sub dirname ($;$) {
495     my($path) = @_;
496     if ($path =~ /[^\/]/s) {
497         if ($path =~ /\//) {
498             $path =~ s/\/+[^\/]+\/*$//s;
499         } else {
500             $path = '.';
501         }
502     }
503     return $path;
504 }
505
506 =item C<mkdir_parents($;$)>
507
508 Does the equivalent of mkdir -p, or mkdir --parents.
509
510 Takes: a path and an optional mode.
511
512 Create the directory path, recursively creating any intermediate
513 directories, with the access mode if given.
514
515 WARNING: If the path already exists, mkdir_parents will just return
516 successfully (just like mkdir -p), whether the mode of path conforms
517 to the mode or not. (This is the behaviour of the mkdir -p command.)
518
519 =cut
520
521 sub mkdir_parents ($;$) {
522     my($path, $mode) = @_;
523     my $ok = -d($path)? 1: defined $mode? mkdir($path, $mode): mkdir($path);
524
525     if (!$ok && $! == ENOENT) {
526         my $parent = dirname($path);
527         $ok = &mkdir_parents($parent, $mode);
528
529         # retry and at the same time make sure that $! is set correctly
530         $ok = defined $mode? mkdir($path, $mode): mkdir($path);
531     }
532     return $ok;
533 }
534
535 =item C<getmessage($;$)>
536
537 Takes: a message identifier, an array reference
538
539 Returns: a localized message (format string)
540
541 The first message must be the message identifier corresponding to a
542 defined message string (a valid key to the $Installer::messages hash).
543 The second parameter may be an array reference of variables,
544 to be substituted into the format string.
545
546 getmessage throws an exception if the message cannot be found.
547
548 =cut
549
550 sub getmessage {
551     my $messagename=shift;
552     my $variables=shift;
553     my $message=$messages->{$messagename}->{$language} || $messages->{$messagename}->{en} || RED.BOLD."Error: No message named $messagename in Install.pm\n";
554     if (defined($variables)) {
555         $message=sprintf $message, @$variables;
556     }
557     return $message;
558 }
559
560
561 =item C<showmessage($$;$$)>
562
563 Shows a message and optionally gets a response from the user.
564
565 Takes:
566 message string, question type, default response, noclear
567
568 Returns: response string
569
570 The message must be the actual string to display; the caller is
571 responsible for calling getmessage if required.
572
573 Question type must be 'none' for no response, 'yn' for a yes/no
574 question, 'restrictchar CHARS' for one letter from CHARS (Case is not
575 significant, but case is significant in the list of allowed
576 characters), 'free' for any string, 'silentfree' for any string
577 entered without on-screen display, 'numerical', 'email' or
578 'PressEnter'.  If a response type other than the above-listed is
579 specified, the result is undefined.
580
581 Note that the response type of "email" does not actually
582 guarantee that the returned value is a well-formed RFC-822
583 email address, nor does it accept all well-formed RFC-822 email
584 addresses. What it does is to restrict the returned value to a
585 string that is looks reasonably likely to be an email address
586 in the "real world", given the premise that the user is trying
587 to enter a real email address.
588
589 If a response type other than "none" or "PressEnter" is specified, a
590 third argument, specifying the default value, can be specified: If
591 this default response is not specified, the default response is the
592 first allowed character if the response type is "restrictchar",
593 otherwise the default response is the empty string. This default
594 response is used when the user does not specify a value (i.e., presses
595 Enter without typing in anything), showmessage will assume that the
596 default response is the user's response.
597
598 Note that because the response type "yn" is equivalent to
599 "restrictchar yn", the default value for response type "yn", if
600 unspecified, is "y".
601
602 The screen is normally cleared before the message is displayed; if a
603 fourth argument is specified and is nonzero, this screen-clearing is
604 not done.
605
606 =cut
607 #'
608
609 sub showmessage ($$;$$) {
610     #MJR: Maybe refactor to use anonymous functions that
611     # check the responses instead of RnP branching.
612     my $message=join('',fill('','',(shift)));
613     my $responsetype=shift;
614     my $defaultresponse=shift;
615     my $noclear=shift;
616     $noclear = 0 unless defined $noclear; # defaults to "clear"
617     ($noclear) || (print $clear_string);
618     if ($responsetype =~ /^yn$/) {
619         $responsetype='restrictchar ynYN';
620     }
621     print RESET.$message;
622     if ($responsetype =~/^restrictchar (.*)/i) {
623         my $response='\0';
624         my $options=$1;
625         until ($options=~/$response/) {
626             (defined($defaultresponse)) || ($defaultresponse=substr($options,0,1));
627             $response=<STDIN>;
628             chomp $response;
629             (length($response)) || ($response=$defaultresponse);
630             if ( $response=~/.*[\:\(\)\^\$\*\!\\].*/ ) {
631                 ($noclear) || (print $clear_string);
632                 print RED."Response contains invalid characters.  Choose from [$options].\n\n";
633                 print RESET.$message;
634                 $response='\0';
635             } else {
636                 unless ($options=~/$response/) {
637                     ($noclear) || (print $clear_string);
638                     print RED."Invalid Response.  Choose from [$options].\n\n";
639                     print RESET.$message;
640                 }
641             }
642         }
643         return $response;
644     } elsif ($responsetype =~/^(silent)?free$/i) {
645         (defined($defaultresponse)) || ($defaultresponse='');
646         if ($responsetype =~/^(silent)/i) { setecho(0) }; 
647         my $response=<STDIN>;
648         if ($responsetype =~/^(silent)/i) { setecho(1) }; 
649         chomp $response;
650         ($response) || ($response=$defaultresponse);
651         return $response;
652     } elsif ($responsetype =~/^numerical$/i) {
653         (defined($defaultresponse)) || ($defaultresponse='');
654         my $response='';
655         until ($response=~/^\d+$/) {
656             $response=<STDIN>;
657             chomp $response;
658             ($response) || ($response=$defaultresponse);
659             unless ($response=~/^\d+$/) {
660                 ($noclear) || (print $clear_string);
661                 print RED."Invalid Response ($response).  Response must be a number.\n\n";
662                 print RESET.$message;
663             }
664         }
665         return $response;
666     } elsif ($responsetype =~/^email$/i) {
667         (defined($defaultresponse)) || ($defaultresponse='');
668         my $response='';
669         until ($response=~/.*\@.*\..*/) {
670             $response=<STDIN>;
671             chomp $response;
672             ($response) || ($response=$defaultresponse);
673             if ($response!~/.*\@.*\..*/) {
674                         ($noclear) || (print $clear_string);
675                         print RED."Invalid Response ($response).  Response must be a valid email address.\n\n";
676                         print RESET.$message;
677             }
678         }
679         return $response;
680     } elsif ($responsetype =~/^PressEnter$/i) {
681         <STDIN>;
682         return;
683     } elsif ($responsetype =~/^none$/i) {
684         return;
685     } else {
686         # FIXME: There are a few places where we will get an undef as the
687         # response type. Should we thrown an exception here, or should we
688         # legitimize this usage and say "none" is the default if not specified?
689         #die "Illegal response type \"$responsetype\"";
690     }
691 }
692
693
694 =item C<startsysout()>
695
696 Changes the display to show system output until the next showmessage call.
697 At the time of writing, this means using red text.
698
699 =cut
700
701 sub startsysout {
702         print RED."\n";
703 }
704
705 =back
706
707 =head2 Subtasks of doing an installation
708
709 =over 4
710
711 =item C<checkabortedinstall()>
712
713 Checks whether a previous installation process has been abnormally
714 aborted, by checking whether $etcidr/koha.conf is a symlink matching
715 a particular pattern.  If an aborted installation is detected, give
716 the user a chance to abort, before trying to recover the aborted
717 installation.
718
719 FIXME: The recovery is not complete; it only partially rolls back
720 some changes.
721
722 =cut
723
724 sub checkabortedinstall () {
725     if (-l("$etcdir/koha.conf")
726         && readlink("$etcdir/koha.conf") =~ /\.tmp$/
727     ) {
728         print qq|
729 I have detected that you tried to install Koha before, but the installation
730 was aborted.  I will try to continue, but there might be problems if the
731 database is already created.
732
733 |;
734         print "Please press <ENTER> to continue: ";
735         <STDIN>;
736
737         # Remove the symlink after the <STDIN>, so the user can back out
738         unlink "$etcdir/koha.conf"
739             || die "Failed to remove incomplete $etcdir/koha.conf: $!\n";
740     }
741 }
742
743 =item C<checkpaths()>
744
745 Make sure that we loaded the right dirs from an old koha.conf
746
747 FIXME: needs update to use Install.pm
748
749 =cut
750
751 sub checkpaths {
752 if ($opacdir && $intranetdir) {
753     print qq|
754
755 I believe that your old files are located in:
756
757   OPAC:      $opacdir
758   LIBRARIAN: $intranetdir
759
760
761 Does this look right?  ([Y]/N):
762 |;
763     my $answer = <STDIN>;
764     chomp $answer;
765
766     if ($answer =~/n/i) {
767         $intranetdir='';
768         $opacdir='';
769     } else {
770         print "Great! continuing upgrade... \n";
771     }
772 }
773
774 if (!$opacdir || !$intranetdir) {
775     $intranetdir='';
776     $opacdir='';
777     while (!$intranetdir) {
778         print "Please specify the location of your LIBRARIAN files: ";
779
780         my $answer = <STDIN>;
781         chomp $answer;
782
783         if ($answer) {
784             $intranetdir=$answer;
785         }
786         if (! -e "$intranetdir/htdocs") {
787             print "\nCouldn't find the htdocs directory here.  That doesn't look right.\nPlease enter another location.\n\n";
788             $intranetdir='';
789         }
790     }
791     while (!$opacdir) {
792         print "Please specify the location of your OPAC files: ";  
793
794         my $answer = <STDIN>;
795         chomp $answer;
796
797         if ($answer) {
798             $opacdir=$answer;
799         }
800         if (! -e "$opacdir/htdocs") {
801             print "\nCouldn't find the htdocs directory here.  That doesn't look right.\nPlease enter another location.\n\n";
802             $opacdir='';
803         }
804     }
805 }
806
807 }
808
809 =item C<checkperlmodules(;$)>
810
811 Test whether the version of Perl is new enough, whether Perl is found
812 at the expected location, and whether all required modules have been
813 installed.
814
815 =cut
816
817 sub checkperlmodules(;$) {
818 #
819 # Test for Perl and Modules
820 #
821         my ($auto_install) = @_;
822         my $message = getmessage('CheckingPerlModules');
823         showmessage($message, 'none');
824
825         unless ($] >= 5.006001) {                       # Bug 179
826                 die getmessage('PerlVersionFailure', ['5.6.1']);
827         }
828         startsysout();
829
830         my @missing = ();
831         unless (eval {require DBI})              { push @missing,"DBI" };
832         unless (eval {require Date::Manip})      { push @missing,"Date::Manip" };
833         unless (eval {require DBD::mysql})       { push @missing,"DBD::mysql" };
834         unless (eval {require HTML::Template})   { push @missing,"HTML::Template" };
835         unless (eval {require Digest::MD5})      { push @missing,"Digest::MD5" };
836         unless (eval {require MARC::Record})     { push @missing,"MARC::Record" };
837         unless (eval {require Mail::Sendmail})   { push @missing,"Mail::Sendmail" };
838 # The following modules are not mandatory, depends on how the library want to use Koha
839         unless (eval {require PDF::API2})   { 
840                         if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
841                                 push @missing,"You will need PDF::API2 for barcode generator" 
842                         }
843         }
844                 unless (eval {require PDF::API2::PDF})   {
845                                     if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
846                                             push @missing,"You will need PDF::API2::PDF for spine and barcode printing"
847                                     }
848                     }
849                 unless (eval {require PDF::Reuse})   {
850                                     if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
851                                             push @missing,"You will need PDF::Reuse for spine and barcode printing"
852                                     }
853                     }
854                 unless (eval {require PDF::Reuse::Barcode})   {
855                                     if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
856                                             push @missing,"You will need PDF::Reuse::Barcode for spine and barcode printing"
857                                     }
858                     }
859                 unless (eval {require PDF::Report})   {
860                                     if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
861                                             push @missing,"You will need PDF::Report for spine and barcode printing"
862                                     }
863                     }
864
865                 unless (eval {require GD::Barcode})   {
866                                     if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
867                                             push @missing,"You will need GD::Barcode for spine and barcode printing"
868                                     }
869                     }
870
871                 unless (eval {require GD::Barcode::UPCE})   {
872                                     if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
873                                             push @missing,"You will need GD::Barcode::UPCE for spine and barcode printing"
874                                     }
875                     }
876
877         unless (eval {require Net::LDAP})       {
878                 if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
879                                 push @missing, "Net::LDAP";
880                         }
881     }
882         unless (eval {require Event})       {
883                 if ($#missing>=0) { # only when $#missing >= 0 so this isn't fatal
884                                 push @missing, "Event";
885                         }
886     }
887     unless (eval {require Net::Z3950})       {
888                 showmessage(getmessage('NETZ3950Missing'), 'PressEnter', '', 1);
889                 if ($#missing>=0) { # see above note
890                         push @missing, "Net::Z3950";
891                 }
892     }
893     unless (eval {require LWP::Simple)       {
894                 showmessage(getmessage('LWP::Simple'), 'PressEnter', '', 1);
895                 if ($#missing>=0) { # see above note
896                         push @missing, "LWP::Simple";
897                 }
898     }
899     unless (eval {require XML::Simple)       {
900                 showmessage(getmessage('XML::Simple'), 'PressEnter', '', 1);
901                 if ($#missing>=0) { # see above note
902                         push @missing, "XML::Simple";
903                 }
904     }
905
906 #
907 # Print out a list of any missing modules
908 #
909
910     if (@missing > 0) {
911         my $missing='';
912         if (POSIX::setlocale(LC_ALL) ne "C") {
913                 $missing.="   export LC_ALL=C\n";  
914         }
915         foreach my $module (@missing) {
916             $missing.="   perl -MCPAN -e 'install \"$module\"'\n";
917         }
918         my $message=getmessage('MissingPerlModules', [$missing]);
919         showmessage($message, 'none');
920         print "\n";
921         exit;
922     } else {
923         showmessage(getmessage('AllPerlModulesInstalled'), 'PressEnter', '', 1) unless $auto_install->{NoPressEnter};
924     }
925
926
927         startsysout();
928     unless (-x "/usr/bin/perl") {
929         my $realperl=`which perl`;
930         chomp $realperl;
931         $realperl = showmessage(getmessage('NoUsrBinPerl'), 'none');
932         until (-x $realperl) {
933             $realperl=showmessage(getmessage('AskLocationOfPerlExecutable', $realperl), 'free', $realperl, 1);
934         }
935         my $response=showmessage(getmessage('ConfirmPerlExecutableSymlink', $realperl), 'yn', 'y', 1);
936         unless ($response eq 'n') {
937                 startsysout();
938             system("ln -s $realperl /usr/bin/perl");
939         }
940     }
941
942
943 }
944
945 $messages->{'NoUsrBinPerl'}->{en} =
946    heading('No /usr/bin/perl') . qq|
947 Koha expects to find the perl executable in the /usr/bin
948 directory.  It is not there on your system.
949
950 |;
951
952 $messages->{'AskLocationOfPerlExecutable'}->{en}=qq|Location of Perl Executable [%s]: |;
953 $messages->{'ConfirmPerlExecutableSymlink'}->{en}=qq|
954 Some Koha scripts will _not_ work without a symlink from %s to /usr/bin/perl
955
956 Most users should answer Y here.
957
958 May I try to create this symlink? ([Y]/N):|;
959
960 $messages->{'DirFailed'}->{en} = RED.qq|
961 We could not create %s, but continuing anyway...
962
963 |;
964
965
966
967 =item C<getinstallationdirectories(;$)>
968
969 Asks the user for the various installation directories, and then
970 creates those directories (if they do not already exist).
971
972 These pieces of information are saved to variables; the function does
973 not return any values.
974
975 =cut
976
977 sub getinstallationdirectories(;$) {
978         my ($auto_install) = @_;
979         if (!$ENV{prefix}) { $ENV{prefix} = "/usr/local"; }
980     $opacdir = $ENV{prefix}.'/koha/opac';
981     $intranetdir = $ENV{prefix}.'/koha/intranet';
982     my $getdirinfo=1;
983     while ($getdirinfo) {
984         # Loop until opac directory and koha directory are different
985         my $message;
986         if ($auto_install->{GetOpacDir}) {
987                 $opacdir=$auto_install->{GetOpacDir};
988                 print ON_YELLOW.BLACK."auto-setting OpacDir to : $opacdir".RESET."\n";
989         } else {
990                 $message=getmessage('GetOpacDir', [$opacdir]);
991                 $opacdir=showmessage($message, 'free', $opacdir);
992         }
993         if ($auto_install->{GetIntranetDir}) {
994                 $intranetdir=$auto_install->{GetIntranetDir};
995                 print ON_YELLOW.BLACK."auto-setting IntranetDir to : $intranetdir".RESET."\n";
996         } else {
997                 $message=getmessage('GetIntranetDir', [$intranetdir]);
998                 $intranetdir=showmessage($message, 'free', $intranetdir);
999         }
1000         if ($intranetdir eq $opacdir) {
1001             print qq|
1002
1003 You must specify different directories for the OPAC and INTRANET files!
1004  :: $intranetdir :: $opacdir ::
1005 |;
1006 <STDIN>
1007         } else {
1008             $getdirinfo=0;
1009         }
1010     }
1011     $kohalogdir=$ENV{prefix}.'/koha/log';
1012         if ($auto_install->{GetOpacDir}) {
1013                 $kohalogdir=$auto_install->{KohaLogDir};
1014                 print ON_YELLOW.BLACK."auto-setting log dir to : $kohalogdir".RESET."\n";
1015         } else {
1016             my $message=getmessage('GetKohaLogDir', [$kohalogdir]);
1017         $kohalogdir=showmessage($message, 'free', $kohalogdir);
1018         }
1019
1020
1021     # FIXME: Need better error handling for all mkdir calls here
1022     unless ( -d $intranetdir ) {
1023        mkdir_parents (dirname($intranetdir), 0775) || print getmessage('DirFailed',['parents of '.$intranetdir]);
1024        mkdir ($intranetdir,                  0770) || print getmessage('DirFailed',[$intranetdir]);
1025        if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2], "$intranetdir"); }
1026        chmod 0770, "$intranetdir";
1027     }
1028     mkdir_parents ("$intranetdir/htdocs",    0750);
1029     mkdir_parents ("$intranetdir/cgi-bin",   0750);
1030     mkdir_parents ("$intranetdir/modules",   0750);
1031     mkdir_parents ("$intranetdir/scripts",   0750);
1032     unless ( -d $opacdir ) {
1033        mkdir_parents (dirname($opacdir),     0775) || print getmessage('DirFailed',['parents of '.$opacdir]);
1034        mkdir ($opacdir,                      0770) || print getmessage('DirFailed',[$opacdir]);
1035        if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2], "$opacdir"); }
1036        chmod (oct(770), "$opacdir");
1037     }
1038     mkdir_parents ("$opacdir/htdocs",        0750);
1039     mkdir_parents ("$opacdir/cgi-bin",       0750);
1040
1041
1042     unless ( -d $kohalogdir ) {
1043        mkdir_parents (dirname($kohalogdir),  0775) || print getmessage('DirFailed',['parents of '.$kohalogdir]);
1044        mkdir ($kohalogdir,                   0770) || print getmessage('DirFailed',[$kohalogdir]);
1045        if ($>==0) { chown (oct(0), (getgrnam($httpduser))[2,3], "$kohalogdir"); }
1046        chmod (oct(770), "$kohalogdir");
1047     }
1048 }
1049
1050 =item C<getmysqldir()>
1051
1052 Returns: the MySQL database server installation directory,
1053 automatically if possible and from the user otherwise.
1054
1055 =cut
1056
1057 $messages->{'WhereIsMySQL'}->{en} = heading('MYSQL LOCATION').qq|
1058 Koha can't find the MySQL command-line tools. If you installed a MySQL package, you may need to install an additional package containing mysqladmin.
1059 If you compiled mysql yourself,
1060 please give the value of --prefix when you ran configure.
1061 The file mysqladmin should be in bin/mysqladmin under the directory that you give here.
1062
1063 MySQL installation directory: |;
1064 #'
1065 sub getmysqldir () {
1066     foreach my $mysql (qw(/usr/local/mysql
1067                           /opt/mysql
1068                           /usr/local
1069                           /usr
1070                           )) {
1071        if ( -d $mysql  && -f "$mysql/bin/mysqladmin") {
1072             $mysqldir=$mysql;
1073        }
1074     }
1075     if (!$mysqldir){
1076         for (;;) {
1077             $mysqldir = showmessage(getmessage('WhereIsMySQL'),'free');
1078             last if -f "$mysqldir/bin/mysqladmin";
1079         }
1080     }
1081     return($mysqldir);
1082 }
1083
1084 =item C<getdatabaseinfo(;$)>
1085
1086 Asks for various pieces of information related to the Koha database:
1087 the name of the database, the host on which the SQL server is running,
1088 and the database user name.
1089
1090 These pieces of information are saved to global variables; the
1091 function does not return any values.
1092
1093 =cut
1094
1095 $messages->{'DatabaseName'}->{en} = heading('Database Name') . qq|
1096 Please provide the name that you wish to give your koha database.
1097 It must not exist already on the database server.
1098
1099 Most users give a short single-word name for their library here.
1100
1101 Database name [%s]: |;
1102
1103 $messages->{'DatabaseHost'}->{en} = heading('Database Host') . qq|
1104 Please provide the mysql server name.  Unless the database is stored on
1105 another machine, this should be "localhost".
1106
1107 Database host [%s]: |;
1108
1109 $messages->{'DatabaseUser'}->{en} = heading('Database User') . qq|
1110 We are going to create a new mysql user for Koha. This user will have full administrative rights
1111 to the database called %s when they connect from %s.
1112 This is also the name of the Koha librarian superuser.
1113
1114 Most users give a single-word name here.
1115
1116 Database user [%s]: |;
1117
1118 $messages->{'DatabasePassword'}->{en} = heading('Database Password') . qq|
1119 Please provide a good password for the user %s.
1120
1121 IMPORTANT: You can log in using this user and password at any time.
1122
1123 Password for database user %s: |;
1124
1125 $messages->{'BlankPassword'}->{en} = heading('BLANK PASSWORD') . qq|
1126 You must not use a blank password for your MySQL user.
1127
1128 Press <ENTER> to try again: 
1129 |;
1130
1131 sub getdatabaseinfo(;$) {
1132         my ($auto_install) = @_;
1133     $database = 'Koha';
1134     $hostname = 'localhost';
1135     $user = 'kohaadmin';
1136     $pass = '';
1137
1138 #Get the database name
1139         my $message;
1140         
1141         if ($auto_install->{database}) {
1142                 $database=$auto_install->{database};
1143                 print ON_YELLOW.BLACK."auto-setting database to : $database".RESET."\n";
1144         } else {
1145                 $message=getmessage('DatabaseName', [$database]);
1146                 $database=showmessage($message, 'free', $database);
1147         }
1148 #Get the hostname for the database
1149     
1150         if ($auto_install->{DatabaseHost}) {
1151                 $hostname=$auto_install->{DatabaseHost};
1152                 print ON_YELLOW.BLACK."auto-setting database host to : $hostname".RESET."\n";
1153         } else {
1154                 $message=getmessage('DatabaseHost', [$hostname]);
1155                 $hostname=showmessage($message, 'free', $hostname);
1156         }
1157 #Get the username for the database
1158
1159         if ($auto_install->{DatabaseUser}) {
1160                 $user=$auto_install->{DatabaseUser};
1161                 print ON_YELLOW.BLACK."auto-setting DB user to : $user".RESET."\n";
1162         } else {
1163                 $message=getmessage('DatabaseUser', [$database, $hostname, $user]);
1164                 $user=showmessage($message, 'free', $user);
1165         }
1166 #Get the password for the database user
1167
1168     while ($pass eq '') {
1169                 my $message=getmessage('DatabasePassword', [$user, $user]);
1170                 if ($auto_install->{DatabasePassword}) {
1171                         $pass=$auto_install->{DatabasePassword};
1172                         print ON_YELLOW.BLACK."auto-setting database password to : $pass".RESET."\n";
1173                 } else {
1174                                 $pass=showmessage($message, 'free', $pass);
1175                 }
1176                 if ($pass eq '') {
1177                         my $message=getmessage('BlankPassword');
1178                         showmessage($message,'PressEnter');
1179                 }
1180     }
1181 }
1182
1183
1184
1185 =item C<getapacheinfo(;$)>
1186
1187 Detects or asks for various pieces of information related to the
1188 Apache server: the location of the configuration file and, if needed,
1189 the Unix user that the Koha CGI will be run under.
1190
1191 These pieces of information are saved to global variables; the
1192 function does not return any values.
1193
1194 =cut
1195
1196 $messages->{'FoundMultipleApacheConfFiles'}->{en} = 
1197    heading('MULTIPLE APACHE CONFIG FILES FOUND') . qq|
1198 I found more than one possible Apache configuration file:
1199
1200 %s
1201
1202 Enter number of the file to read [1]: |;
1203
1204 $messages->{'NoApacheConfFiles'}->{en} =
1205    heading('NO APACHE CONFIG FILE FOUND') . qq|
1206 I was not able to find your Apache configuration file.
1207
1208 The file is usually called httpd.conf, apache.conf or similar.
1209
1210 Please enter the full name, starting with /: |;
1211
1212 $messages->{'NotAFile'}->{en} = heading('FILE DOES NOT EXIST') . qq|
1213 The file %s does not exist.
1214
1215 Please press <ENTER> to continue: |;
1216
1217 $messages->{'EnterApacheUser'}->{en} = heading('NEED APACHE USER') . qq\
1218 The installer could not find the User setting in the Apache configuration file.
1219 This is used to set up access permissions for
1220 %s/koha.conf.  This user should be set in one of the Apache configuration.
1221 Please try to find it and enter the user name below.  You might find
1222 that "ps u|grep apache" will tell you.  It probably is NOT "root".
1223
1224 Enter the Apache userid: \;
1225
1226 $messages->{'InvalidUserid'}->{en} = heading('INVALID USER') . qq|
1227 The userid %s is not a valid userid on this system.
1228
1229 Press <ENTER> to continue: |;
1230
1231 sub getapacheinfo (;$) {
1232         my ($auto_install) = @_;
1233     my @confpossibilities;
1234
1235     foreach my $httpdconf (qw(/usr/local/apache/conf/httpd.conf
1236                           /usr/local/etc/apache/httpd.conf
1237                           /usr/local/etc/apache/apache.conf
1238                           /var/www/conf/httpd.conf
1239                           /etc/apache2/httpd.conf
1240                           /etc/apache2/apache2.conf
1241                           /etc/apache/conf/httpd.conf
1242                           /etc/apache/conf/apache.conf
1243                           /etc/apache/httpd.conf
1244                           /etc/apache-ssl/conf/apache.conf
1245                           /etc/apache-ssl/httpd.conf
1246                           /etc/httpd/conf/httpd.conf
1247                           /etc/httpd/httpd.conf
1248                           /etc/httpd/2.0/conf/httpd2.conf
1249                           )) {
1250                 if ( -f $httpdconf ) {
1251                         push @confpossibilities, $httpdconf;
1252                 }
1253     }
1254
1255     if ($#confpossibilities==-1) {
1256                 my $message=getmessage('NoApacheConfFiles');
1257                 my $choice='';
1258                 $realhttpdconf='';
1259                 until (-f $realhttpdconf) {
1260                         $choice=showmessage($message, "free", 1);
1261                         if (-f $choice) {
1262                         $realhttpdconf=$choice;
1263                         } else {
1264                         showmessage(getmessage('NotAFile', [$choice]),'PressEnter', '', 1);
1265                         }
1266                 }
1267     } elsif ($#confpossibilities>0) {
1268                 my $conffiles='';
1269                 my $counter=1;
1270                 my $options='';
1271                 foreach (@confpossibilities) {
1272                         $conffiles.="   $counter: $_\n";
1273                         $options.="$counter";
1274                         $counter++;
1275                 }
1276                 my $message=getmessage('FoundMultipleApacheConfFiles', [$conffiles]);
1277                 my $choice=showmessage($message, "restrictchar $options", 1);
1278                 $realhttpdconf=$confpossibilities[$choice-1];
1279     } else {
1280                 $realhttpdconf=$confpossibilities[0];
1281     }
1282     unless (open (HTTPDCONF, "<$realhttpdconf")) {
1283         warn RED."Insufficient privileges to open $realhttpdconf for reading.\n";
1284         sleep 4;
1285     }
1286
1287     while (<HTTPDCONF>) {
1288                 if (/^\s*User\s+"?([-\w]+)"?\s*$/) {
1289                         $httpduser = $1;
1290                 }
1291     }
1292     close(HTTPDCONF);
1293
1294     unless (defined($httpduser)) {
1295                 my $message;
1296                 if ($auto_install->{EnterApacheUser}) {
1297                         $message = $auto_install->{EnterApacheUser};
1298                         print ON_YELLOW.BLACK."auto-setting Apache User to : $message".RESET."\n";
1299                 } else {
1300                         $message=getmessage('EnterApacheUser', [$etcdir]);
1301                 }
1302                 until (defined($httpduser) && length($httpduser) && getpwnam($httpduser)) {
1303                         if ($auto_install->{EnterApacheUser}) {
1304                                 $httpduser = $auto_install->{EnterApacheUser};
1305                         } else {
1306                                 $httpduser=showmessage($message, "free", '');
1307                         }
1308                         if (length($httpduser)>0) {
1309                                 unless (getpwnam($httpduser)) {
1310                                         my $message=getmessage('InvalidUserid', [$httpduser]);
1311                                         showmessage($message,'PressEnter');
1312                                 }
1313                         } else {
1314                         }
1315                 }
1316         }
1317 }
1318
1319
1320 =item C<getapachevhostinfo(;$)>
1321
1322 Asks for various pieces of information related to virtual hosting: the
1323 webmaster email address, virtual hostname, and the ports that the OPAC
1324 and INTRANET modules run on.
1325
1326 These pieces of information are saved to global variables; the
1327 function does not return any values.
1328
1329 =cut
1330
1331 $messages->{'ApacheConfigIntroduction'}->{en} =
1332    heading('APACHE CONFIGURATION') . qq|
1333 Koha needs to write an Apache configuration file for the
1334 OPAC and Librarian sites.  By default this installer
1335 will do this by using one name and two different ports
1336 for the virtual hosts.  There are other ways to set this up,
1337 and the installer will leave comments in
1338 %s/koha-httpd.conf about them.
1339
1340 NOTE: You will need to add lines to your main httpd.conf to
1341 include %s/koha-httpd.conf
1342 (using the Include directive)
1343 and to make sure it is listening on the right ports
1344 and host names
1345 (using the Listen directive).
1346
1347 Press <ENTER> to continue: |;
1348
1349 $messages->{'GetVirtualHostEmail'}->{en} =
1350    heading('WEB E-MAIL CONTACT') . qq|
1351 Enter the e-mail address to be used as a contact for Koha.  This
1352 address is displayed if fatal errors are encountered.
1353
1354 E-mail contact [%s]: |;
1355
1356 $messages->{'GetServerName'}->{en} =
1357    heading('WEB HOST NAME OR IP ADDRESS') . qq|
1358 Please enter the host name or IP address that you wish to use for koha.
1359 Normally, this should be a name or IP that belongs to this machine.
1360
1361 Host name or IP Address [%s]: |;
1362
1363 $messages->{'GetOpacPort'}->{en} = heading('OPAC PORT') . qq|
1364 Please enter the port for your OPAC interface.  This defaults to port 80, but
1365 if you are already serving web content with this hostname, you should change it
1366 to a different port (8000 might be a good choice, but check any firewalls).
1367
1368 Enter the OPAC Port [%s]: |;
1369
1370 $messages->{'GetIntranetPort'}->{en} =
1371    heading('LIBRARIAN PORT') . qq|
1372 Please enter the port for your Librarian interface.  This must be different from
1373 the OPAC port (%s).
1374
1375 Enter the Intranet Port [%s]: |;
1376
1377
1378 sub getapachevhostinfo (;$) {
1379         my ($auto_install) = @_;
1380     $svr_admin = "webmaster\@$domainname";
1381     $servername=`hostname`;
1382     chomp $servername;
1383     $opacport=80;
1384     $intranetport=8080;
1385
1386         if ($auto_install->{GetVirtualHostEmail}) {
1387                 $svr_admin=$auto_install->{GetVirtualHostEmail};
1388                 print ON_YELLOW.BLACK."auto-setting VirtualHostEmail to : $svr_admin".RESET."\n";
1389         } else {
1390                 showmessage(getmessage('ApacheConfigIntroduction',[$etcdir,$etcdir]), 'PressEnter');
1391                 $svr_admin=showmessage(getmessage('GetVirtualHostEmail', [$svr_admin]), 'email', $svr_admin);
1392         }
1393         if ($auto_install->{servername}) {
1394                 $servername=$auto_install->{servername};
1395                 print ON_YELLOW.BLACK."auto-setting server name to : $servername".RESET."\n";
1396         } else {
1397         $servername=showmessage(getmessage('GetServerName', [$servername]), 'free', $servername);
1398         }
1399         if ($auto_install->{opacport}) {
1400                 $opacport=$auto_install->{opacport};
1401                 print ON_YELLOW.BLACK."auto-setting opac port to : $opacport".RESET."\n";
1402         } else {
1403             $opacport=showmessage(getmessage('GetOpacPort', [$opacport]), 'numerical', $opacport);
1404         }
1405         if ($auto_install->{intranetport}) {
1406                 $intranetport=$auto_install->{intranetport};
1407                 print ON_YELLOW.BLACK."auto-setting intranet port to : $intranetport".RESET."\n";
1408         } else {
1409             $intranetport=showmessage(getmessage('GetIntranetPort', [$opacport, $intranetport]), 'numerical', $intranetport);
1410         }
1411
1412 }
1413
1414
1415 =item C<updateapacheconf(;$)>
1416
1417 Creates the Apache config file according to parameters previously
1418 specified by the user as F<$etcdir/koha-httpd.conf>.
1419
1420 If you need to uninstall Koha for any reason, the lines between
1421
1422     # Ports to listen to for Koha
1423
1424 and the block of comments beginning with
1425
1426     # If you want to use name based Virtual Hosting:
1427
1428 must be removed.
1429
1430 =cut
1431
1432 $messages->{'StartUpdateApache'}->{en} =
1433    heading('UPDATING APACHE CONFIGURATION') . qq|
1434 Checking for modules that need to be loaded...
1435 |;
1436
1437 $messages->{'ApacheConfigMissingModules'}->{en} =
1438    heading('APACHE CONFIGURATION NEEDS UPDATE') . qq|
1439 Koha uses the mod_env and mod_include apache features, but the
1440 installer did not find them in your config.  Please
1441 make sure that they are enabled for your Koha site.
1442
1443 Press <ENTER> to continue: |;
1444
1445
1446 $messages->{'ApacheAlreadyConfigured'}->{en} =
1447    heading('APACHE ALREADY CONFIGURED') . qq|
1448 %s appears to already have an entry for Koha.  You may need to edit %s
1449 if anything has changed since it was last set up.  This
1450 script will not attempt to modify an existing Koha apache
1451 configuration.
1452
1453 Press <ENTER> to continue: |;
1454
1455 sub updateapacheconf (;$) {
1456         my ($auto_install)=@_;
1457     my $logfiledir=$kohalogdir;
1458     my $httpdconf = $etcdir."/koha-httpd.conf";
1459    
1460     showmessage(getmessage('StartUpdateApache'), 'none') unless $auto_install->{NoPressEnter};
1461         # to be polite about it: I don't think this should touch the main httpd.conf
1462
1463         # QUESTION: Should we warn for includes_module too?
1464     my $envmodule=0;
1465     my $includesmodule=0;
1466     open HC, "<$realhttpdconf";
1467     while (<HC>) {
1468         if (/^\s*#\s*LoadModule env_module /) {
1469             showmessage(getmessage('ApacheConfigMissingModules'),'none');
1470             $envmodule=1;
1471         }
1472         if (/\s*LoadModule includes_module / ) {
1473             $includesmodule=1;
1474         }
1475     }
1476
1477         startsysout;
1478     if (`grep -q 'VirtualHost $servername' "$httpdconf" 2>/dev/null`) {
1479         showmessage(getmessage('ApacheAlreadyConfigured', [$httpdconf, $httpdconf]), 'PressEnter');
1480         return;
1481     } else {
1482         my $includesdirectives='';
1483         if ($includesmodule) {
1484             $includesdirectives.="Options +Includes\n";
1485             $includesdirectives.="   AddHandler server-parsed .html\n";
1486         }
1487         open(SITE,">$httpdconf") or warn "Insufficient priveleges to open $httpdconf for writing.\n";
1488         my $opaclisten = '';
1489         if ($opacport != 80) {
1490             $opaclisten="Listen $opacport";
1491         }
1492         my $intranetlisten = '';
1493         if ($intranetport != 80) {
1494             $intranetlisten="Listen $intranetport";
1495         }
1496         print SITE <<EOP
1497
1498 # Koha 2.2 Apache Virtual Host Config File
1499 #
1500 # Please include this file in your apache configuration.
1501 # The best way to do that depends on your site setup.
1502 # Some like an Include adding to /etc/apache/httpd.conf
1503 # and some prefer a symlink to this file from some dir.
1504 # Please refer to your system manuals.
1505
1506 # Ports to listen to for Koha
1507 # uncomment these if they aren't already in main httpd.conf
1508 #$opaclisten
1509 #$intranetlisten
1510
1511 # NameVirtualHost is used by one of the optional configurations detailed below
1512 # Please make sure this line is correct before uncommenting.
1513 # See http://httpd.apache.org/docs/vhosts/ for some guides.
1514
1515 #NameVirtualHost 11.22.33.44
1516
1517 # KOHA's OPAC Configuration
1518 <VirtualHost $servername\:$opacport>
1519    ServerAdmin $svr_admin
1520    DocumentRoot $opacdir/htdocs
1521    ServerName $servername
1522    ScriptAlias /cgi-bin/koha/ $opacdir/cgi-bin/
1523    Redirect permanent index.html http://$servername\:$opacport/cgi-bin/koha/opac-main.pl
1524    ErrorLog $logfiledir/opac-error_log
1525    TransferLog $logfiledir/opac-access_log
1526    SetEnv PERL5LIB "$intranetdir/modules"
1527    SetEnv KOHA_CONF "$etcdir/koha.conf"
1528    $includesdirectives
1529 </VirtualHost>
1530
1531 # KOHA's INTRANET Configuration
1532 <VirtualHost $servername\:$intranetport>
1533    ServerAdmin $svr_admin
1534    DocumentRoot $intranetdir/htdocs
1535    ServerName $servername
1536    ScriptAlias /cgi-bin/koha/ "$intranetdir/cgi-bin/"
1537    Redirect permanent index.html http://$servername\:$intranetport/cgi-bin/koha/mainpage.pl
1538    ErrorLog $logfiledir/koha-error_log
1539    TransferLog $logfiledir/koha-access_log
1540    SetEnv PERL5LIB "$intranetdir/modules"
1541    SetEnv KOHA_CONF "$etcdir/koha.conf"
1542    $includesdirectives
1543 </VirtualHost>
1544
1545 # If you want to use name based Virtual Hosting:
1546 #   1. remove the two Listen lines
1547 #   2. replace $servername\:$opacport wih your.opac.domain.name
1548 #   3. replace ServerName $servername wih ServerName your.opac.domain.name
1549 #   4. replace $servername\:$intranetport wih your intranet domain name
1550 #   5. replace ServerName $servername wih ServerName your.intranet.domain.name
1551 #
1552 # If you want to use NameVirtualHost'ing (using two names on one ip address):
1553 #   1.  Follow steps 1-5 above
1554 #   2.  Uncomment the NameVirtualHost line and set the correct ip address
1555
1556 EOP
1557
1558
1559     }
1560 }
1561
1562
1563 # =item C<basicauthentication(;$)>
1564
1565 # Asks the user whether HTTP basic authentication is wanted, and,
1566 # if so, the user name and password for the basic authentication.
1567
1568 # These pieces of information are saved to global variables; the
1569 # function does not return any values.
1570
1571 # =cut
1572
1573 # $messages->{'IntranetAuthenticationQuestion'}->{en} =
1574 #    heading('LIBRARIAN AUTHENTICATION') . qq|
1575 # The Librarian site can be password protected using
1576 # Apache's Basic Authorization instead of Koha user details.
1577
1578 # This method going to be phased out very soon.  Most users should answer N here.
1579
1580 # Would you like to do this (Y/[N]): |; #'
1581
1582 # $messages->{'BasicAuthUsername'}->{en}="Please enter a username for librarian access [%s]: ";
1583 # $messages->{'BasicAuthPassword'}->{en}="Please enter a password for %s: ";
1584 # $messages->{'BasicAuthPasswordWasBlank'}->{en}="\nYou cannot use a blank password!\n\n";
1585
1586 # sub basicauthentication {
1587 #     my $message=getmessage('IntranetAuthenticationQuestion');
1588 #     my $answer=showmessage($message, 'yn', 'n');
1589 #     my $httpdconf = $etcdir."/koha-httpd.conf";
1590
1591 #     my $apacheauthusername='librarian';
1592 #     my $apacheauthpassword='';
1593 #     if ($answer=~/^y/i) {
1594 #       ($apacheauthusername) = showmessage(getmessage('BasicAuthUsername', [ $apacheauthusername]), 'free', $apacheauthusername, 1);
1595 #       $apacheauthusername=~s/[^a-zA-Z0-9]//g;
1596 #       while (! $apacheauthpassword) {
1597 #           ($apacheauthpassword) = showmessage(getmessage('BasicAuthPassword', [ $apacheauthusername]), 'free', 1);
1598 #           if (!$apacheauthpassword) {
1599 #               ($apacheauthpassword) = showmessage(getmessage('BasicAuthPasswordWasBlank'), 'none', '', 1);
1600 #           }
1601 #       }
1602 #       open AUTH, ">$etcdir/kohaintranet.pass";
1603 #       my $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
1604 #       my $salt=substr($chars, int(rand(length($chars))),1);
1605 #       $salt.=substr($chars, int(rand(length($chars))),1);
1606 #       print AUTH $apacheauthusername.":".crypt($apacheauthpassword, $salt)."\n";
1607 #       close AUTH;
1608 #       open(SITE,">>$httpdconf") or warn "Insufficient priveleges to open $realhttpdconf for writing.\n";
1609 #       print SITE <<EOP
1610
1611 # <Directory $intranetdir>
1612 #     AuthUserFile $etcdir/kohaintranet.pass
1613 #     AuthType Basic
1614 #     AuthName "Koha Intranet (for librarians only)"
1615 #     Require  valid-user
1616 # </Directory>
1617 # EOP
1618 #     }
1619 #     close(SITE);
1620 # }
1621
1622
1623 =item C<installfiles(;$$)>
1624
1625 Copy the Koha files to the specified OPAC and INTRANET
1626 directories (usually in /usr/local/koha).
1627
1628 Creates the koha.conf file, but as koha.conf.tmp. The caller is
1629 responsible for calling C<finalizeconfigfile(;$)> when installation is
1630 completed, to rename it back to koha.conf.
1631
1632 The first parameter may be a marker to say this is a new installation,
1633 rather than an upgrade.
1634
1635 =cut
1636
1637 $messages->{'InstallFiles'}->{en} = heading('INSTALLING FILES') . qq|
1638 Copying files to installation directories:
1639
1640 |;
1641
1642 $messages->{'OldFiles'}->{en} = heading('OLD FILES') . qq|
1643 Any files from the previous edition of Koha have been
1644 copied to a dated backup directory alongside the new
1645 installation. You should move any custom files that you
1646 want to keep (such as your site templates) into the new
1647 directories and then move the backup off of the live
1648 server.
1649
1650 Press ENTER to continue:|;
1651
1652
1653 $messages->{'CopyingFiles'}->{en}="Copying %s to %s.\n";
1654
1655
1656
1657 sub installfiles (;$$) {
1658
1659         my ($is_first_install,$auto_install) = @_;
1660         # $is_install is set if it's a fresh install and not an upgrade. If it's an upgrade, copy old files.
1661         
1662         sub neatcopy {
1663                 my $desc = shift;
1664                 my $src = shift;
1665                 my $tgt = shift;
1666                 my $auto_install = shift;
1667                 my $is_first_install = shift;
1668                 if (!$is_first_install && -e $tgt) {
1669                 print getmessage('CopyingFiles', ["old ".$desc,$tgt.strftime("%Y%m%d%H%M",localtime())]) unless ($auto_install->{NoPressEnter});
1670                         system("mv ".$tgt." ".$tgt.strftime("%Y%m%d%H%M",localtime()));
1671                         system("mkdir ".$tgt);   ##New line 
1672                 }
1673                 print getmessage('CopyingFiles', [$desc,$tgt]) unless ($auto_install->{NoPressEnter});
1674                 system("cp -R ".$src."/* ".$tgt);
1675         }
1676
1677 #       my ($auto_install) = @_;
1678         showmessage(getmessage('InstallFiles'),'none') unless ($auto_install->{NoPressEnter});
1679
1680         neatcopy("admin templates", 'intranet-html', "$intranetdir/htdocs",$auto_install,$is_first_install);
1681         neatcopy("admin interface", 'intranet-cgi', "$intranetdir/cgi-bin",$auto_install,$is_first_install);
1682         neatcopy("main scripts", 'scripts', "$intranetdir/scripts",$auto_install,$is_first_install);
1683         neatcopy("perl modules", 'modules', "$intranetdir/modules",$auto_install,$is_first_install);
1684         neatcopy("OPAC templates", 'opac-html', "$opacdir/htdocs",$auto_install,$is_first_install);
1685         neatcopy("OPAC interface", 'opac-cgi', "$opacdir/cgi-bin",$auto_install,$is_first_install);
1686         startsysout();
1687         system("touch $opacdir/cgi-bin/opac");
1688
1689         #MJR: is this necessary?
1690         if ($> == 0) {
1691                 my $httpdgrp = getgrnam($httpduser);
1692                 system("chown -R $httpduser:$httpdgrp $opacdir $intranetdir");
1693         }
1694         system("chmod -R a+rx $opacdir $intranetdir");
1695
1696         # Create /etc/koha.conf
1697
1698         my $old_umask = umask(027); # make sure koha.conf is never world-readable
1699         open(SITES,">$etcdir/koha.conf.tmp") or warn "Couldn't create file at $etcdir. Must have write capability.\n";
1700         print SITES qq|
1701 database=$database
1702 hostname=$hostname
1703 user=$user
1704 pass=$pass
1705 intranetdir=$intranetdir
1706 opacdir=$opacdir
1707 kohalogdir=$kohalogdir
1708 kohaversion=$newversion
1709 httpduser=$httpduser
1710 intrahtdocs=$intranetdir/htdocs/intranet-tmpl
1711 opachtdocs=$opacdir/htdocs/opac-tmpl
1712 |;
1713         close(SITES);
1714         umask($old_umask);
1715
1716         startsysout();
1717         #MJR: can't help but this be broken, can we?
1718         chmod 0440, "$etcdir/koha.conf.tmp";
1719         
1720         #MJR: does this contain any passwords?
1721         chmod 0755, "$intranetdir/scripts/z3950daemon/z3950-daemon-launch.sh", "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh", "$intranetdir/scripts/z3950daemon/processz3950queue";
1722
1723         open(FILE,">$intranetdir/scripts/z3950daemon/z3950-daemon-options");
1724         print FILE "RunAsUser=$httpduser\nKohaZ3950Dir=$intranetdir/scripts/z3950daemon\nKohaModuleDir=$intranetdir/modules\nLogDir=$kohalogdir\nKohaConf=$etcdir/koha.conf";
1725         close(FILE);
1726
1727         if ($> == 0) {
1728             chown((getpwnam($httpduser)) [2,3], "$etcdir/koha.conf.tmp") or warn "can't chown koha.conf: $!";
1729                 chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh") or warn "can't chown $intranetdir/scripts/z3950daemon/z3950-daemon-shell.sh: $!";
1730                 chown(0, (getpwnam($httpduser)) [3], "$intranetdir/scripts/z3950daemon/processz3950queue") or warn "can't chown $intranetdir/scripts/z3950daemon/processz3950queue: $!";
1731         } #MJR: report that we haven't chown()d.
1732         else {
1733                 print "Please check permissions in $intranetdir/scripts/z3950daemon\n";
1734         }
1735         showmessage(getmessage('OldFiles'),'PressEnter') unless ($auto_install->{NoPressEnter} or $is_first_install);
1736 }
1737
1738
1739 =item C<databasesetup(;$)>
1740
1741 Finds out where the MySQL utitlities are located in the system,
1742 then create the Koha database structure and MySQL permissions.
1743
1744 =cut
1745
1746 $messages->{'MysqlRootPassword'}->{en} =
1747    heading('MYSQL ROOT USER PASSWORD') . qq|
1748 To create the koha database, please enter your
1749 mysql server's root user password:
1750
1751 Password: |;    #'
1752
1753 $messages->{'CreatingDatabase'}->{en} = heading('CREATING DATABASE') . qq|
1754 Creating the MySQL database for Koha...
1755
1756 |;
1757
1758 $messages->{'CreatingDatabaseError'}->{en} =
1759    heading('ERROR CREATING DATABASE') . qq|
1760 Couldn't connect to the MySQL server for the reason given above.
1761 This is a serious problem, the database will not get installed.
1762
1763 Press <ENTER> to continue: |;   #'
1764
1765 $messages->{'SampleData'}->{en} = heading('SAMPLE DATA') . qq|
1766 If you are installing Koha for evaluation purposes,
1767 you can install some sample data now.
1768
1769 If you are installing Koha to use your own
1770 data, you probably don't want this sample data installed.
1771
1772 Would you like to install the sample data? Y/[N]: |;    #'
1773
1774 $messages->{'SampleDataInstalled'}->{en} =
1775    heading('SAMPLE DATA INSTALLED') . qq|
1776 Sample data has been installed.  For some suggestions on testing Koha, please
1777 read the file doc/HOWTO-Testing.  If you find any bugs, please submit them at
1778 http://bugs.koha.org/.  If you need help with testing Koha, you can post a
1779 question through the koha-devel mailing list, or you can check for a developer
1780 online at irc.katipo.co.nz:6667 channel #koha.
1781
1782 You can find instructions for subscribing to the Koha mailing lists at:
1783
1784     http://www.koha.org
1785
1786
1787 Press <ENTER> to continue: |;
1788
1789 $messages->{'AddBranchPrinter'}->{en} = heading('Add Branch and Printer') . qq|
1790 Would you like to describe an initial branch and printer? [Y]/N: |;
1791
1792 $messages->{'BranchName'}->{en}="Branch Name [%s]: ";
1793 $messages->{'BranchCode'}->{en}="Branch Code (4 letters or numbers) [%s]: ";
1794 $messages->{'PrinterQueue'}->{en}="Printer Queue [%s]: ";
1795 $messages->{'PrinterName'}->{en}="Printer Name [%s]: ";
1796
1797 sub databasesetup (;$) {
1798         my ($auto_install) = @_;
1799     $mysqluser = 'root';
1800     $mysqlpass = '';
1801         my $mysqldir = getmysqldir();
1802
1803         if ($auto_install->{MysqlRootPassword}) {
1804                 $mysqlpass=$auto_install->{MysqlRootPassword};
1805         } else {
1806         # we must not put the mysql root password on the command line
1807                 $mysqlpass=     showmessage(getmessage('MysqlRootPassword'),'silentfree');
1808         }
1809         
1810         showmessage(getmessage('CreatingDatabase'),'none') unless ($auto_install->{NoPressEnter});
1811         # set the login up
1812         setmysqlclipass($mysqlpass);
1813         # Set up permissions
1814         startsysout();
1815         print system("$mysqldir/bin/mysql -u$mysqluser -e \"insert into user (Host,User,Password) values ('$hostname','$user',password('$pass'))\" mysql\;");
1816         system("$mysqldir/bin/mysql -u$mysqluser -e \"insert into db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv, index_priv, alter_priv) values ('%','$database','$user','Y','Y','Y','Y','Y','Y','Y','Y')\" mysql");
1817         system("$mysqldir/bin/mysqladmin -u$mysqluser reload");
1818         # Change to admin user login
1819         setmysqlclipass($pass);
1820         my $result=system("$mysqldir/bin/mysqladmin", "-u$user", "create", "$database");
1821         if ($result) {
1822                 showmessage(getmessage('CreatingDatabaseError'),'PressEnter', '', 1);
1823         } else {
1824                 # Create the database structure
1825                 startsysout();
1826                 system("$mysqldir/bin/mysql '-u$user' '$database' < koha.mysql");
1827         }
1828
1829 }
1830
1831
1832 =item C<updatedatabase(;$)>
1833
1834 Updates the Koha database structure, including the addition of
1835 MARC tables.
1836
1837 The MARC tables are also populated in addition to being created.
1838
1839 Because updatedatabase calls scripts/updater/updatedatabase to
1840 do the actual update, and that script uses C4::Context,
1841 $etcdir/koha.conf must exist at this point. We use the KOHA_CONF
1842 environment variable to do this.
1843
1844 FIXME: (See checkabortedinstall as it depends on old symlink way.)
1845
1846 =cut
1847
1848 $messages->{'UpdateMarcTables'}->{en} =
1849    heading('MARC FIELD DEFINITIONS') . qq|
1850 You can import MARC settings for:
1851
1852   1 MARC21
1853   2 UNIMARC
1854   N none
1855
1856 NOTE: If you choose N,
1857 nothing will be added, and you must create them all yourself.
1858 Only choose N if you want to use a MARC format not listed here,
1859 such as DANMARC.  We would like to hear from you if you do.
1860
1861 *** UPGRADE ***
1862 If you UPGRADE your version from a previous 2.x.x, the right choice here is N (None) to preserve your local MARC setup.
1863
1864 Choose MARC definition [1]: |;
1865
1866 $messages->{'Language'}->{en} = heading('CHOOSE LANGUAGE') . qq|
1867 This version of koha supports a few languages.
1868
1869   en : default language, all pages available
1870   fr : complete translation
1871   es : partial librarian site translation
1872   zh_TW : partial translation
1873
1874 en is used when a screen is not available in your language
1875
1876 If you specify a language here, you can still
1877 change it from the system preferences screen in the librarian sit.
1878
1879 Which language do you choose? |;
1880
1881 sub updatedatabase (;$) {
1882         my ($auto_install) = @_;
1883     # At this point, $etcdir/koha.conf must exist, for C4::Context
1884     $ENV{"KOHA_CONF"}=$etcdir.'/koha.conf';
1885     if (! -e $ENV{"KOHA_CONF"}) { $ENV{"KOHA_CONF"}=$etcdir.'/koha.conf.tmp'; }
1886         startsysout();  
1887         setmysqlclipass($pass);
1888         my $result=system ("perl -I $intranetdir/modules scripts/updater/updatedatabase -s");
1889         if ($result) {
1890                 restoremycnf();
1891                 print "Problem updating database...\n";
1892                 exit;
1893         }
1894         my $response;
1895         if ($auto_install->{UpdateMarcTables}) {
1896                 $response=$auto_install->{UpdateMarcTables};
1897                 print ON_YELLOW.BLACK."auto-setting UpdateMarcTable to : $response".RESET."\n";
1898         } else {
1899                 $response=showmessage(getmessage('UpdateMarcTables'), 'restrictchar 12Nn', '1');
1900         }
1901         startsysout();
1902         if ($response eq '1') {
1903                 system("cat scripts/misc/marc_datas/marc21_en/structure_def.sql | $mysqldir/bin/mysql '-u$user' '$database'");
1904         }
1905         if ($response eq '2') {
1906                 system("cat scripts/misc/marc_datas/unimarc_fr/structure_def.sql | $mysqldir/bin/mysql '-u$user' '$database'");
1907         }
1908         delete($ENV{"KOHA_CONF"});
1909
1910         print RESET."\nFinished updating of database. Press <ENTER> to continue..." unless ($auto_install->{NoPressEnter});
1911         <STDIN> unless ($auto_install->{NoPressEnter});
1912 }
1913
1914
1915 =item C<populatedatabase(;$)>
1916
1917 Populates the non-MARC tables and installs sample data,
1918 if wanted.
1919
1920 =cut
1921
1922 $messages->{'ConfirmFileUpload'}->{en} = qq|
1923 Confirm loading of this file into Koha  [Y]/N: |;
1924
1925 sub populatedatabase (;$) {
1926         my ($auto_install) = @_;
1927         my $input;
1928         my $response;
1929         my $branch='MAIN';
1930         if ($auto_install->{BranchName}) {
1931                 $branch=$auto_install->{BranchName};
1932                 print ON_YELLOW.BLACK."auto-setting a branch : $branch".RESET."\n";
1933         } else {
1934                 $response=showmessage(getmessage('AddBranchPrinter'), 'yn', 'y');
1935                 unless ($response =~/^n/i) {
1936                         $branch=showmessage(getmessage('BranchName', [$branch]), 'free', $branch, 1);
1937                         $branch=~s/[^A-Za-z0-9\s]//g;
1938                 }
1939         }
1940         if ($branch) {
1941                 my $branchcode=$branch;
1942                 $branchcode=~s/[^A-Za-z0-9]//g;
1943                 $branchcode=uc($branchcode);
1944                 $branchcode=substr($branchcode,0,4);
1945                 if ($auto_install->{BranchCode}) {
1946                         $branchcode=$auto_install->{BranchCode};
1947                         print ON_YELLOW.BLACK."auto-setting branch code : $branchcode".RESET."\n";
1948                 } else {
1949                         $branchcode=showmessage(getmessage('BranchCode', [$branchcode]), 'free', $branchcode, 1);
1950                 }
1951                 $branchcode=~s/[^A-Za-z0-9]//g;
1952                 $branchcode=uc($branchcode);
1953                 $branchcode=substr($branchcode,0,4);
1954                 $branchcode or $branchcode='DEF';
1955
1956                 startsysout();
1957                 system("$mysqldir/bin/mysql -u$user -e \"insert into branches (branchcode,branchname,issuing) values ('$branchcode', '$branch', 1)\" $database");
1958                 system("$mysqldir/bin/mysql -u$user -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'IS')\" $database");
1959                 system("$mysqldir/bin/mysql -u$user -e \"insert into branchrelations (branchcode,categorycode) values ('MAIN', 'CU')\" $database");
1960
1961                 my $printername='lp';
1962                 my $printerqueue='/dev/lp0';
1963                 if ($auto_install->{PrinterName}) {
1964                         $printername=$auto_install->{PrinterName};
1965                         print ON_YELLOW.BLACK."auto-setting a printer : $printername".RESET."\n";
1966                 } else {
1967                         $printername=showmessage(getmessage('PrinterName', [$printername]), 'free', $printername, 1);
1968                         $printername=~s/[^A-Za-z0-9\s]//g;
1969                 }
1970                 if ($auto_install->{PrinterQueue}) {
1971                         $printerqueue=$auto_install->{PrinterQueue};
1972                         print ON_YELLOW.BLACK."auto-setting printer queue to : $printerqueue".RESET."\n";
1973                 } else {
1974                         $printerqueue=showmessage(getmessage('PrinterQueue', [$printerqueue]), 'free', $printerqueue, 1);
1975                         $printerqueue=~s/[^A-Za-z0-9]//g;
1976                 }
1977                 startsysout();  
1978                 system("$mysqldir/bin/mysql -u$user -e \"insert into printers (printername,printqueue,printtype) values ('$printername', '$printerqueue', '')\" $database");
1979         }
1980         my $language;
1981         if ($auto_install->{Language}) {
1982                 $language=$auto_install->{Language};
1983                 print ON_YELLOW.BLACK."auto-setting language to : $language".RESET."\n";
1984         } else {
1985                 $language=showmessage(getmessage('Language'), 'free', 'en');
1986         }
1987         startsysout();  
1988         system("$mysqldir/bin/mysql -u$user -e \"update systempreferences set value='$language' where variable='opaclanguages'\" $database");
1989         my @dirs;
1990         if (-d "scripts/misc/sql-datas") {
1991                 # ask for directory to look for files to append
1992                 my @directories;
1993                 push @directories,"FINISHED";
1994                 if (-d "scripts/misc/sql-datas") {
1995                         opendir D, "scripts/misc/sql-datas";
1996                         foreach my $dir (readdir D) {
1997                                 next if ($dir =~ /^\./);
1998                                 push @directories, $dir;
1999                         }
2000                 }
2001                 my $loopend=0;
2002                 while (not $loopend) {
2003                         print heading("SELECT SQL DIRECTORY");
2004                         print qq|
2005 Select a directory. You will see every file included in this directory and be able to choose file(s) to import into Koha
2006 This is a VERY important feature. By selecting the proper options, you can get a pre-setup Koha, almost ready to be put in production.
2007 Choose wisely.
2008 |;
2009                         for (my $i=0;$i<=$#directories;$i++) {
2010                                 print "$i => ".$directories[$i]."\n";
2011                         }
2012                         my $sqluploaddir =<STDIN>;
2013                         if ($sqluploaddir==0) {
2014                                 $loopend = 1;
2015                         } else {
2016                                 $sqluploaddir = $directories[$sqluploaddir];
2017                                 # CHECK for any other file to append...
2018                                 my @sql;
2019                                 push @sql,"FINISHED";
2020                                 if (-d "scripts/misc/sql-datas/$sqluploaddir") {
2021                                         opendir D, "scripts/misc/sql-datas/$sqluploaddir";
2022                                         foreach my $sql (readdir D) {
2023                                                 next unless ($sql =~ /.txt$/);
2024                                                 push @sql, $sql;
2025                                         }
2026                                 }
2027                                 $loopend=0;
2028                                 while (not $loopend) {
2029                                         print heading("SELECT SQL FILE");
2030                                         print qq|
2031 Select a file to append to the Koha DB.
2032 enter a number. A detailled explanation of the file will be given
2033 if you confirm, the file will be added to the DB
2034 |;
2035                                         for (my $i=0;$i<=$#sql;$i++) {
2036                                                 print "$i => ".$sql[$i]."\n";
2037                                         }
2038                                         my $response =<STDIN>;
2039                                         if ($response==0) {
2040                                                 $loopend = 1;
2041                                         } else {
2042                                                 # show the content of the file
2043                                                 my $FileToUpload = $sql[$response];
2044                                                 open FILE,"scripts/misc/sql-datas/$sqluploaddir/$FileToUpload";
2045                                                 my $content = <FILE>;
2046                                                 print heading("INSERT $sqluploaddir/$FileToUpload ?")."$content\n";
2047                                                 # ask confirmation
2048                                                 $response=showmessage(getmessage('ConfirmFileUpload'), 'yn', 'y');
2049                                                 # if confirmed, upload the file in the DB
2050                                                 unless ($response =~/^n/i) {
2051                                                         $FileToUpload =~ s/\.txt/\.sql/;
2052                                                         system("$mysqldir/bin/mysql '-u$user' '$database' <scripts/misc/sql-datas/$sqluploaddir/$FileToUpload");
2053                                                 }
2054                                         }
2055                                 }
2056                                 $loopend=0;
2057                         }
2058                 }
2059         }
2060 }
2061
2062 =item C<restartapache(;$)>
2063
2064 Asks the user whether to restart Apache, and restarts it if the user
2065 wants so.
2066
2067 =cut
2068
2069 $messages->{'RestartApache'}->{en} = heading('RESTART APACHE') . qq|
2070 The web server daemon needs to be restarted to load the new configuration for Koha.
2071 The installer can do this if you are using Apache and give the root password.
2072
2073 Would you like to try to restart Apache now?  [Y]/N: |;
2074
2075 sub restartapache (;$) {
2076         my ($auto_install)=@_;
2077         my $response;
2078     $response=showmessage(getmessage('RestartApache'), 'yn', 'y') unless ($auto_install->{NoPressEnter});
2079     $response='y' if ($auto_install->{NoPressEnter});
2080
2081     unless ($response=~/^n/i) {
2082                 startsysout();
2083                 # Need to support other init structures here?
2084                 if (-e "/etc/rc.d/init.d/httpd") {
2085                         system('su root -c "/etc/rc.d/init.d/httpd restart"');
2086                 } elsif (-e "/etc/init.d/apache") {
2087                         system('su root -c "/etc/init.d/apache restart"');
2088                 } elsif (-e "/etc/init.d/apache-ssl") {
2089                         system('su root -c "/etc/init.d/apache-ssl restart"');
2090                 }
2091         }
2092 }
2093
2094 =item C<backupkoha(;$)>
2095
2096 Attempts to make backup copies of all koha's details.
2097
2098 =cut
2099
2100 $messages->{'BackupDir'}->{en} = heading('BACKUP STORAGE').qq|
2101 The upgrader will now try to backup your old files.
2102
2103 Please specify a directory to store the backup in [%s]: |;
2104
2105 $messages->{'BackupSummary'}->{en} = heading('BACKUP SUMMARY').qq|
2106 Backed up:
2107
2108 %6d biblio entries
2109 %6d biblioitems entries
2110 %6d items entries
2111 %6d borrowers
2112
2113 File Listing
2114 ---------------------------------------------------------------------
2115 %s
2116 ---------------------------------------------------------------------
2117
2118 Does this look right? ([Y]/N): |;
2119
2120 #FIXME: rewrite to use Install.pm
2121 sub backupkoha () {
2122 if (!$ENV{prefix}) { $ENV{prefix} = "/usr/local"; }
2123 my $backupdir=$ENV{prefix}.'/backups';
2124
2125 my $answer = showmessage(getmessage('BackupDir',[$backupdir]),'free',$backupdir);
2126 $backupdir = $answer; 
2127
2128 if (! -e $backupdir) {
2129         my $result=mkdir ($backupdir, oct(770));
2130         if ($result==0) {
2131                 my @dirs = split(m#/#, $backupdir);
2132                 my $checkdir='';
2133                 foreach (@dirs) {
2134                         $checkdir.="$_/";
2135                         unless (-e "$checkdir") {
2136                                 mkdir($checkdir, 0775);
2137                         }
2138                 }
2139         }
2140 }
2141
2142 chmod 0770, $backupdir;
2143
2144 # Backup MySql database
2145 #
2146 #
2147 my $mysqldir = getmysqldir();
2148
2149 my ($sec, $min, $hr, $day, $month, $year) = (localtime(time))[0,1,2,3,4,5];
2150 $month++;
2151 $year+=1900;
2152 my $date= sprintf "%4d-%02d-%02d_%02d:%02d:%02d", $year, $month, $day,$hr,$min,$sec;
2153
2154 setmysqlclipass($pass); 
2155 open (MD, "$mysqldir/bin/mysqldump --user=$user --host=$hostname $database|");
2156
2157 (open BF, ">$backupdir/Koha.backup_$date") || (die "Error opening up backup file $backupdir/Koha.backup_$date: $!\n");
2158
2159 my $itemcounter=0;
2160 my $bibliocounter=0;
2161 my $biblioitemcounter=0;
2162 my $membercounter=0;
2163
2164 while (<MD>) {
2165         (/insert into items /i) && ($itemcounter++);
2166         (/insert into biblioitems /i) && ($biblioitemcounter++);
2167         (/insert into biblio /i) && ($bibliocounter++);
2168         (/insert into borrowers /i) && ($membercounter++);
2169         print BF $_;
2170 }
2171
2172 close BF;
2173 close MD;
2174
2175 my $filels=`ls -hl $backupdir/Koha.backup_$date`;
2176 chomp $filels;
2177 $answer = showmessage(getmessage('BackupSummary',[$bibliocounter, $biblioitemcounter, $itemcounter, $membercounter, $filels]),'yn');
2178
2179 if ($answer=~/^n/i) {
2180     print qq|
2181
2182 Aborting.  The database dump is located in:
2183
2184         $backupdir/Koha.backup_$date
2185
2186 |;
2187     exit;
2188 } else {
2189         print "Great! continuing upgrade... \n";
2190 };
2191
2192
2193
2194 }
2195
2196 =item C<finalizeconfigfile()>
2197
2198 Renames F<koha.conf.tmp> file to F<koha.conf>.
2199
2200 This file must be renamed when the installation is complete,
2201 Currently, failure to rename the file results only in a warning.
2202
2203 =cut
2204
2205 sub finalizeconfigfile {
2206         restoremycnf();
2207    rename "$etcdir/koha.conf.tmp", "$etcdir/koha.conf"
2208       || showmessage(<<EOF, 'PressEnter', undef, 1);
2209 An unexpected error, $!, occurred
2210 while the Koha config file is being saved to its final location,
2211 $etcdir/koha.conf.
2212
2213 Couldn't rename file at $etcdir. Must have write capability.
2214
2215 Press Enter to continue.
2216 EOF
2217 #'
2218 }
2219
2220
2221 =item C<loadconfigfile()>
2222
2223 Opens the existing koha.conf file and gets its values, saving the
2224 values to some global variables.  If the existing koha.conf file
2225 cannot be opened for any reason, the file is silently ignored.
2226
2227 =cut
2228
2229 sub loadconfigfile () {
2230     my %configfile;
2231
2232         #MJR: reverted to r1.53.  Please call setetcdir().  Do NOT hardcode this.
2233         #FIXME: make a dated backup
2234     open (KC, "<$etcdir/koha.conf");
2235     while (<KC>) {
2236      chomp;
2237      (next) if (/^\s*#/);
2238      if (/(.*)\s*=\s*(.*)/) {
2239        my $variable=$1;
2240        my $value=$2;
2241        # Clean up white space at beginning and end
2242        $variable=~s/^\s*//g;
2243        $variable=~s/\s*$//g;
2244        $value=~s/^\s*//g;
2245        $value=~s/\s*$//g;
2246        $configfile{$variable}=$value;
2247      }
2248     }
2249
2250         #MJR: Reverted this too. You do not mess with my privates. Please ask for new functions if required.
2251     $intranetdir=$configfile{'intranetdir'};
2252     $opacdir=$configfile{'opacdir'};
2253     $kohaversion=$configfile{'kohaversion'};
2254     $kohalogdir=$configfile{'kohalogdir'};
2255     $database=$configfile{'database'};
2256     $hostname=$configfile{'hostname'};
2257     $user=$configfile{'user'};
2258     $pass=$configfile{'pass'};
2259 }
2260
2261 END { }       # module clean-up code here (global destructor)
2262
2263 ### These things may move
2264
2265 sub setecho {
2266 my $state=shift;
2267 my $t = POSIX::Termios->new;
2268
2269 $t->getattr();
2270 if ($state) {
2271   $t->setlflag(($t->getlflag) | &POSIX::ECHO);
2272   }
2273 else {
2274   $t->setlflag(($t->getlflag) & !(&POSIX::ECHO));
2275   }
2276 $t->setattr();
2277 }
2278
2279 sub setmysqlclipass {
2280         my $pass = shift;
2281         open(MYCNF,">$mycnf");
2282         chmod(0600,$mycnf);
2283         print MYCNF "[client]\npassword=$pass\n";
2284         close(MYCNF);
2285 }
2286
2287 sub backupmycnf {
2288         if (-e $mycnf) {
2289                 rename $mycnf,$mytmpcnf;
2290         }
2291 }
2292
2293 sub restoremycnf {
2294         if (defined $mycnf && -e $mycnf) {
2295                 unlink($mycnf);
2296         }
2297         if (defined $mytmpcnf && -e $mytmpcnf) {
2298                 rename $mytmpcnf,$mycnf;
2299         }
2300 }
2301
2302 =back
2303
2304 =head1 SEE ALSO
2305
2306 buildrelease.pl
2307 installer.pl
2308 koha.upgrade
2309
2310 =cut
2311
2312 1;