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