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