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