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