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