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