fix to bug 1569
[koha.git] / Makefile.PL
1 # Copyright 2007 MJ Ray
2 #
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 2 of the License, or (at your option) any later
8 # version.
9 #
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along with
15 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
16 # Suite 330, Boston, MA  02111-1307 USA
17 #
18 # Current maintainer MJR http://mjr.towers.org.uk/
19 # See http://www.koha.org/wiki/?page=KohaInstaller
20 #
21
22 use strict;
23 use warnings;
24 use ExtUtils::MakeMaker;
25 use POSIX;
26 use File::Spec;
27
28 my $DEBUG = 0;
29 die "perl 5.6.1 or later required" unless ($] >= 5.006001);
30
31 # Hash up directory structure & files beginning with the directory we were called from (should be the base of koha)...
32
33 my $dirtree = hashdir('.');
34 my %result = ();
35
36 =head1 NAME
37
38 Makefile.PL - Koha packager and installer
39
40 =head1 SYNOPSIS
41
42 =head2 BASIC INSTALLATION
43
44         perl Makefile.PL
45         make
46         sudo make install
47
48 =head2 PACKAGING RELEASE TARBALLS
49
50         make manifest tardist
51         make manifest zipdist
52
53 =head2 CLEANING UP
54
55         make clean
56
57 =head1 DESCRIPTION
58
59 This is a packager and installer that uses
60 ExtUtils::MakeMaker, which is fairly common
61 on perl systems.
62 As well as building tar or zip files
63 and installing with the above commands,
64 it allows us to check pre-requisites
65 and generate configuration files.
66
67 =head1 VARIABLES
68
69 =head2 NAME, VERSION_FROM, ABSTRACT, AUTHOR
70
71 Basic metadata about this software.
72
73 =head2 NO_META
74
75 Suppress generation of META.yml file.
76
77 =head2 PREREQ_PM
78
79 Hash of perl modules and versions required.
80
81 =head2 PM
82
83 Hash of file mappings
84
85 =head2 PL_FILES
86
87 This is a hash of PL scripts to run after installation and
88 the files to ask them to generate.
89 Maybe use the values from CONFIGURE
90 to generate initial configuration files in future.
91
92 =cut
93
94 =head2 target_map
95
96 This is a hash mapping directories and files in the
97 source tree to installation target directories.  The rules
98 for this mapping are:
99
100 =over 4
101
102 =item If a directory or file is specified, it and its
103 contents will be copied to the installation target directory.
104
105 =item If a subdirectory of a mapped directory is specified,
106 its target overrides the parent's target for that subdirectory.
107
108 =item The value of each map entry may either be a scalar containing 
109 one target or a reference to a hash containing 'target' and 'trimdir'
110 keys.
111
112 =item Any files at the top level of the source tree that are
113 not included in the map will not be installed.
114
115 =item Any directories at the top level of the source tree
116 that are not included in the map will be installed in
117 INTRANET_CGI_DIR.  This is a sensible default given the
118 current organization of the source tree, but (FIXME) it
119 would be better to reorganize the source tree to better
120 match the installation system, to allow adding new directories
121 without having to adjust Makefile.PL each time.  The idea
122 is to make the C<$target_map> hash as minimal as possible.
123
124 =back
125
126 The permitted installation targets are:
127
128 =over 4
129
130 =item INTRANET_CGI_DIR 
131
132 CGI scripts for intranet (staff) interface.
133
134 =item INTRANET_TMPL_DIR
135
136 HTML templates for the intranet interface.
137
138 =item INTRANET_WWW_DIR
139
140 HTML files, images, etc. for DocumentRoot for the intranet interface.
141
142 =item OPAC_CGI_DIR
143
144 CGI scripts for OPAC (public) interface.
145
146 =item OPAC_TMPL_DIR
147
148 HTML templates for the OPAC interface.
149
150 =item OPAC_WWW_DIR
151
152 HTML files, images, etc. for DocumentRoot for the OPAC interface.
153
154 =item PERL_MODULE_DIR
155
156 Perl modules (at present just the C4 modules) that are intimately
157 tied to Koha.  Depending on the installation options, these
158 may or may not be installed one of the standard directories
159 in Perl's default @LIB.
160
161 =item KOHA_CONF_DIR
162
163 Directory for Koha configuration files.
164
165 =item ZEBRA_CONF_DIR
166
167 Directory for Zebra configuration files.
168
169 =item ZEBRA_LOCK_DIR
170
171 Directory for Zebra's lock files.
172
173 =item ZEBRA_DATA_DIR
174
175 Directory for Zebra's data files.
176
177 =item ZEBRA_RUN_DIR
178
179 Directory for Zebra's UNIX-domain sockets.
180
181 =item MISC_DIR
182
183 Directory for for miscellaenous scripts, among other
184 things the translation toolkit and RSS feed tools.
185
186 =item SCRIPT_DIR
187
188 Directory for command-line scripts and daemons.
189
190 =item MAN_DIR
191
192 Directory for man pages created from POD -- will mostly
193 contain information of interest to Koha developers.
194
195 =item DOC_DIR
196
197 Directory for Koha documentation accessed from the 
198 command-line, e.g., READMEs.
199
200 =item LOG_DIR
201
202 Directory for Apache and Zebra logs produced by Koha.
203
204 =item NONE
205
206 This is a dummy target used to explicitly state
207 that a given file or directory is not to be installed.
208 This is used either for parts of the installer itself
209 or for development tools that are not applicable to a
210 production installation.
211
212 =back
213
214 =cut
215
216 my $target_map = {
217   './about.pl'                  => 'INTRANET_CGI_DIR',
218   './acqui'                     => 'INTRANET_CGI_DIR',
219   './admin'                     => 'INTRANET_CGI_DIR',
220   './authorities'               => 'INTRANET_CGI_DIR',
221   './C4'                        => 'PERL_MODULE_DIR',
222   './C4/SIP/t'                  => 'NONE',
223   './C4/SIP/koha_test'          => 'NONE',
224   './C4/tests'                  => 'NONE',
225   './catalogue'                 => 'INTRANET_CGI_DIR',
226   './cataloguing'               => 'INTRANET_CGI_DIR',
227   './changelanguage.pl'         => 'INTRANET_CGI_DIR',
228   './check_sysprefs.pl'         => 'NONE',
229   './circ'                      => 'INTRANET_CGI_DIR',
230   './edithelp.pl'               => 'INTRANET_CGI_DIR',
231   './etc'                       => { target => 'KOHA_CONF_DIR', trimdir => -1 },
232   './etc/zebradb'               => { target => 'ZEBRA_CONF_DIR', trimdir => -1 },
233   './help.pl'                   => 'INTRANET_CGI_DIR', 
234   './installer-CPAN.pl'         => 'NONE',
235   './installer'                 => 'INTRANET_CGI_DIR',
236   './koha-tmpl/errors'          => {target => 'INTRANET_CGI_DIR', trimdir => 2},
237   './koha-tmpl/intranet-tmpl'   => {target => 'INTRANET_TMPL_DIR', trimdir => -1},
238   './koha-tmpl/opac-tmpl'       => {target => 'OPAC_TMPL_DIR', trimdir => -1},
239   './kohaversion.pl'            => 'INTRANET_CGI_DIR', 
240   './labels'                    => 'INTRANET_CGI_DIR',
241   './mainpage.pl'               => 'INTRANET_CGI_DIR',
242   './Makefile.PL'               => 'NONE',
243   './MANIFEST.SKIP'             => 'NONE',
244   './members'                   => 'INTRANET_CGI_DIR',
245   './misc'                      => { target => 'SCRIPT_DIR', trimdir => -1 }, 
246   './misc/bin'                  => { target => 'SCRIPT_DIR', trimdir => -1 }, 
247   './misc/info'                 => { target => 'DOC_DIR', trimdir => 2 },
248   './misc/release notes'        => { target => 'DOC_DIR', trimdir => 2 },
249   './misc/translator'           => { target => 'MISC_DIR', trimdir => 2 }, 
250   './misc/installer_devel_notes' => 'NONE',
251   './opac'                      => 'OPAC_CGI_DIR',
252   './README.txt'                => 'NONE',
253   './reports'                   => 'INTRANET_CGI_DIR',
254   './reserve'                   => 'INTRANET_CGI_DIR',
255   './reviews'                   => 'INTRANET_CGI_DIR',
256   './rewrite-config.PL'         => 'NONE',
257   './reviews'                   => 'INTRANET_CGI_DIR',
258   './rss'                       => 'MISC_DIR', 
259   './serials'                   => 'INTRANET_CGI_DIR',
260   './skel'                      => 'NONE',
261   './skel/var/log/koha'         => { target => 'LOG_DIR', trimdir => -1 },
262   './skel/var/run/koha/zebradb' => { target => 'ZEBRA_RUN_DIR', trimdir => -1 },
263   './skel/var/lock/koha/zebradb/authorities' => { target => 'ZEBRA_LOCK_DIR', trimdir => 6 },
264   './skel/var/lib/koha/zebradb/authorities/key'  => { target => 'ZEBRA_DATA_DIR', trimdir => 6 },
265   './skel/var/lib/koha/zebradb/authorities/register'  => { target => 'ZEBRA_DATA_DIR', trimdir => 6 },
266   './skel/var/lib/koha/zebradb/authorities/shadow'  => { target => 'ZEBRA_DATA_DIR', trimdir => 6 },
267   './skel/var/lib/koha/zebradb/authorities/tmp'  => { target => 'ZEBRA_DATA_DIR', trimdir => 6 },
268   './skel/var/lock/koha/zebradb/biblios' => { target => 'ZEBRA_LOCK_DIR', trimdir => 6 },
269   './skel/var/lib/koha/zebradb/biblios/key'  => { target => 'ZEBRA_DATA_DIR', trimdir => 6 },
270   './skel/var/lib/koha/zebradb/biblios/register'  => { target => 'ZEBRA_DATA_DIR', trimdir => 6 },
271   './skel/var/lib/koha/zebradb/biblios/shadow'  => { target => 'ZEBRA_DATA_DIR', trimdir => 6 },
272   './skel/var/lib/koha/zebradb/biblios/tmp'  => { target => 'ZEBRA_DATA_DIR', trimdir => 6 },
273   './sms'                       => 'INTRANET_CGI_DIR',
274   './suggestion'                => 'INTRANET_CGI_DIR',
275   './svc'                       => 'INTRANET_CGI_DIR',
276   './t'                         => 'NONE',
277   './tmp'                       => 'NONE', # FIXME need to determine whether 
278                                            # Koha generates any persistent temp files
279                                            # that should go in /var/tmp/koha
280   './tools'                     => 'INTRANET_CGI_DIR',
281   './virtualshelves'            => 'INTRANET_CGI_DIR',
282   # ignore files and directories created by the install itself
283   './pm_to_blib'                => 'NONE',
284   './blib'                      => 'NONE',
285 };
286
287 =head1 CONFIGURATION OPTIONS
288
289 The following configuration options are used by the installer.
290
291 =over 4
292
293 =item INSTALL_MODE
294
295 Specifies whether installation will be FHS-compliant (default,
296 assumes user has root), put everything under
297 a single directory (for users installing on a web host
298 that allows CGI scripts and a MySQL database but not root 
299 access), or development (for a developer who wants to run
300 Koha from a git clone with no fuss).
301
302 =item INSTALL_BASE
303
304 Directory under which most components will go.  Default
305 value will vary depending on INSTALL_MODE.
306
307 =item DB_TYPE
308
309 Type of DBMS (e.g., mysql or Pg).
310
311 =item DB_HOST
312
313 Name of DBMS server.
314
315 =item DB_PORT
316
317 Port that DBMS server is listening on.
318
319 =item DB_NAME
320
321 Name of the DBMS database for Koha.
322
323 =item DB_USER
324
325 Name of DBMS user account for Koha's database.
326
327 =item DB_PASS
328
329 Pasword of DMBS user account for Koha's database.
330
331 =item INSTALL_ZEBRA
332
333 Whether to install Zebra configuration files and data
334 directories.
335
336 =item ZEBRA_MARC_FORMAT
337
338 Specifies format of MARC records to be indexed by Zebra.
339
340 =item ZEBRA_LANGUAGE
341
342 Specifies primary language of records that will be 
343 indexed by Zebra.
344
345 =item ZEBRA_USER
346
347 Internal Zebra user account for the index.
348
349 =item ZEBRA_PASS
350
351 Internal Zebra user account's password.
352
353 =item KOHA_USER
354
355 System user account that will own Koha's files.
356
357 =item KOHA_GROUP
358
359 System group that will own Koha's files.
360
361 =back
362
363 =cut
364
365 # default configuration options
366 my %config_defaults = (
367   'DB_TYPE'           => 'mysql',
368   'DB_HOST'           => 'localhost',
369   'DB_NAME'           => 'koha',    
370   'DB_USER'           => 'kohaadmin',
371   'DB_PASS'           => 'katikoan',
372   'INSTALL_ZEBRA'     => 'yes',
373   'ZEBRA_MARC_FORMAT' => 'marc21',
374   'ZEBRA_LANGUAGE'    => 'en',
375   'ZEBRA_USER'        => 'kohauser',
376   'ZEBRA_PASS'        => 'zebrastripes',
377   'KOHA_USER'         => 'koha',
378   'KOHA_GROUP'        => 'koha',
379 );
380
381 # set some default configuratio options based on OS
382 # more conditions need to be added for other OS's
383 # this should probably also incorporate usage of Win32::GetOSName() and/or Win32::GetOSVersion()
384 # to allow for more granular decisions based on which Win32 platform
385
386 warn "Your platform appears to be $^O.\n" if $DEBUG;
387
388 if ( $^O eq 'MSWin32' ) {
389         # Most Unix2Win32 ports seem to poke everything into the Program Files directory
390         # this could be changed to put some files (ie. libraries) into system32, etc.
391         $config_defaults{'INSTALL_MODE'} = 'single';
392         $config_defaults{'INSTALL_BASE'} = 'c:/progra~1/koha';  # Use 8.3 names to be safe...
393 }
394 elsif ( $^O eq 'cygwin' ) {
395         # Most Unix2Win32 ports seem to poke everything into the Program Files directory
396         # this could be changed to put some files (ie. libraries) into system32, etc.
397         $config_defaults{'INSTALL_MODE'} = 'single';
398         $config_defaults{'INSTALL_BASE'} = 'c:/progra~1/koha';  # Use 8.3 names to be safe...
399 }
400 else {
401         $config_defaults{'INSTALL_MODE'} = 'standard';
402         $config_defaults{'INSTALL_BASE'} = '/usr/share/koha';
403 }
404
405 # valid values for certain configuration options
406 my %valid_config_values = (
407   'INSTALL_MODE'  => { 'standard' => 1, 'single' => 1, 'dev' => 1 },
408   'DB_TYPE' => { 'mysql' => 1, 'Pg' => 1 },
409   'INSTALL_ZEBRA' => { 'yes' => 1, 'no' => 1 },
410   'ZEBRA_MARC_FORMAT' => { 'marc21' => 1, 'unimarc' => 1 }, # FIXME should generate from contents of distributation
411   'ZEBRA_LANGUAGE'    => { 'en' => 1, 'fr' => 1 }, # FIXME should generate from contents of distribution
412 );
413
414 my %config = get_configuration(\%config_defaults, \%valid_config_values);
415 my ($target_directories, $skip_directories) = get_target_directories(\%config);
416 display_configuration(\%config, $target_directories);
417 my $file_map = {};
418 get_file_map($target_map, $dirtree, $file_map, $config{'INSTALL_ZEBRA'} eq "yes" ? 1: 0);
419
420 my $pl_files = {
421       'rewrite-config.PL' => [
422          'blib/KOHA_CONF_DIR/koha-conf.xml',
423          'blib/KOHA_CONF_DIR/koha-httpd.conf'
424          ],
425           'fix-perl-path.PL' => [       # this script ensures the correct shebang line for the platform installed on...
426                  'blib'
427                  ]
428 };
429
430 if ($config{'INSTALL_ZEBRA'} eq "yes") {
431     push @{ $pl_files->{'rewrite-config.PL'} }, (
432         'blib/ZEBRA_CONF_DIR/etc/passwd',
433         'blib/ZEBRA_CONF_DIR/zebra-biblios.cfg',
434         'blib/ZEBRA_CONF_DIR/zebra-authorities.cfg'
435     );
436     if ($config{'INSTALL_MODE'} ne 'dev') {
437         push @{ $pl_files->{'rewrite-config.PL'} }, (
438             'blib/SCRIPT_DIR/koha-zebra-ctl.sh',
439             'blib/SCRIPT_DIR/koha-zebraqueue-ctl.sh',
440         );
441     }
442 }
443
444 if ($config{'INSTALL_MODE'} ne "dev") {
445     push @{ $pl_files->{'rewrite-config.PL'} }, (
446         'blib/PERL_MODULE_DIR/C4/Context.pm',
447         'blib/SCRIPT_DIR/kohalib.pl'
448     );
449 }
450
451 WriteMakefile(
452     NAME => 'koha',
453     #VERSION => strftime('2.9.%Y%m%d%H',gmtime),
454     VERSION_FROM => 'kohaversion.pl',
455     ABSTRACT => 'Award-winning integrated library system (ILS) and Web OPAC',
456     AUTHOR => 'Koha Developers <koha-devel@nongnu.org>',
457     NO_META => 1,
458     PREREQ_PM => {
459 # awaiting package maintainer's use of $VERSION
460 #'Algorithm::CheckDigits' => 0.48,
461 #'Algorithm::CheckDigits::M43_001' => 0.48,
462 'Biblio::EndnoteStyle' => 0.05,
463 'CGI' => 3.15,
464 'CGI::Carp' => 1.29,
465 'CGI::Session' => '4.10',
466 'Class::Factory::Util' => 1.6,
467 'Class::Accessor' => 0.30,
468 'DBD::mysql' => 3.0008,
469 'DBI' => 1.53,
470 'Data::ICal' => 0.13,
471 'Data::Dumper' => 2.121_08,
472 'Date::Calc' => 5.4,
473 'Date::ICal' => 1.72,
474 'Date::Manip' => 5.44,
475 'Digest::MD5' => 2.36,
476 'File::Temp' => 0.16,
477 'GD::Barcode::UPCE' => 1.1,
478 'Getopt::Long' => 2.35,
479 'Getopt::Std' => 1.05,
480 'HTML::Template::Pro' => 0.65,
481 'HTTP::Cookies' => 1.39,
482 'HTTP::Request::Common' => 1.26,
483 'LWP::Simple' => 1.41,
484 'LWP::UserAgent' => 2.033,
485 'Lingua::Stem' => 0.82,
486 'List::Util' => 1.18,
487 'List::MoreUtils' => 0.21,
488 'Locale::Language' => 2.07,
489 'MARC::Charset' => 0.98,
490 'MARC::Crosswalk::DublinCore' => 0.02,
491 'MARC::File::XML' => 0.88,
492 'MARC::Record' => 2.00,
493 'MIME::Base64' => 3.07,
494 'MIME::QuotedPrint' => 3.07,
495 'Mail::Sendmail' => 0.79,
496 'Net::LDAP' => 0.33,
497 'Net::LDAP::Filter' => 0.14,
498 'Net::Z3950::ZOOM' => 1.16,
499 'PDF::API2' => 2.000,
500 'PDF::API2::Page' => 2.000,
501 'PDF::API2::Util' => 2.000,
502 'PDF::Reuse' => 0.33,
503 'PDF::Reuse::Barcode' => 0.05,
504 'POE' => 0.9999,
505 'POSIX' => 1.09,
506 'Schedule::At' => 1.06,
507 'Term::ANSIColor' => 1.10,
508 'Test' => 1.25,
509 'Test::Harness' => 2.56,
510 'Test::More' => 0.62,
511 'Text::CSV' => 0.01,
512 'Text::CSV_XS' => 0.32,
513 'Text::Wrap' => 2005.082401,
514 'Time::HiRes' => 1.86,
515 'Time::localtime' => 1.02,
516 'Unicode::Normalize' => 0.32,
517 'XML::Dumper' => 0.81,
518 'XML::LibXML' => 1.59,
519 'XML::LibXSLT' => 1.59,
520 'XML::SAX::ParserFactory' => 1.01,
521 'XML::Simple' => 2.14,
522 'XML::RSS' => 1.31,
523         },
524
525         # File tree mapping
526         PM => $file_map,
527
528     # Man pages generated from POD
529     INSTALLMAN1DIR => File::Spec->catdir($target_directories->{'MAN_DIR'}, 'man1'),
530     INSTALLMAN3DIR => File::Spec->catdir($target_directories->{'MAN_DIR'}, 'man3'),
531
532     PL_FILES => $pl_files,
533
534 );
535
536 =head1 FUNCTIONS
537
538 =head2 hashdir
539
540 This function recurses through the directory structure and builds
541 a hash of hashes containing the structure with arrays holding filenames.
542 This directory hashing routine was taken from BrowserUK @ http://www.perlmonks.org/?node_id=219919
543
544 =cut
545
546 sub hashdir{
547     my $dir = shift;
548     opendir my $dh, $dir or die $!;
549     my $tree = {}->{$dir} = {};
550     while( my $file = readdir($dh) ) {
551         next if $file =~ m/^\.{1,2}/ and $file !~ /^\.htaccess/; # .htaccess is a special case
552         my $path = $dir .'/' . $file;
553         $tree->{$file} = hashdir($path), next if -d $path;
554         push @{$tree->{'.'}}, $file;
555     }
556     return $tree;
557 }
558
559 =head2 get_file_map 
560
561 This function combines the target_map and file hash to
562 map each source file to its destination relative to
563 the set of installation targets.
564
565 Output will be a hash mapping from each source file
566 to its destination value, like this:
567
568 'mainpage.pl' => '$(INTRANET_CGI_DIR)/mainpage.pl'
569
570 =cut
571
572 sub get_file_map {
573     my $target_map = shift;
574     my $dirtree = shift;
575     my $file_map = shift;
576     my $install_zebra = shift;
577     my $curr_path = @_ ? shift : ['.'];
578
579     # Traverse the directory tree.
580     # For each file or directory, identify the
581     # most specific match in the target_map
582     foreach my $dir (sort keys %{ $dirtree }) {
583         if ($dir eq '.') {
584             # deal with files in directory
585             foreach my $file (sort @{ $dirtree->{$dir} }) {
586                 my $targetdir = undef;
587                 my $matchlevel = undef;
588                 # first, see if there is a match on this specific
589                 # file in the target map
590                 my $filepath = join("/", @$curr_path, $file);
591                 if (exists $target_map->{$filepath}) {
592                     $targetdir = $target_map->{$filepath};
593                     $matchlevel = scalar(@$curr_path) + 1;
594                 } else {
595                     # no match on the specific file; look for
596                     # a directory match
597                     for (my $i = scalar(@$curr_path) - 1; $i >= 0; $i--)  {
598                         my $dirpath = join("/", @$curr_path[0..$i]);
599                         if (exists $target_map->{$dirpath}) {
600                             $targetdir = $target_map->{$dirpath};
601                             $matchlevel = $i + 1;
602                             last;
603                         }
604                     }
605                 }
606                 if (defined $targetdir) {
607                      _add_to_file_map($file_map, $targetdir, $curr_path, $file, $matchlevel, $install_zebra);
608                 } else {
609                     my $path = join("/", @$curr_path);
610                     print "failed to map: $path/$file\n" if $DEBUG;
611                 }
612             }
613         } else {
614             # dealing with subdirectory
615             push @$curr_path, $dir;
616             get_file_map($target_map, $dirtree->{$dir}, $file_map, $install_zebra, $curr_path);
617             pop @$curr_path;
618         }
619     }
620 }
621
622 sub _add_to_file_map {
623     my $file_map = shift;
624     my $targetdir = shift;
625     my $curr_path = shift;
626     my $file = shift;
627     my $matchlevel = shift;
628     my $install_zebra = shift;
629     my $dest_path = @_ ? shift : $curr_path;
630
631     # The target can be one of the following:
632     # 1. scalar representing target symbol
633     # 2. hash ref containing target and trimdir keys
634     #
635     # Consequently, this routine traverses this structure,
636     # calling itself recursively, until it deals with
637     # all of the scalar target symbols.
638     if (ref $targetdir eq 'HASH') {
639         my $subtarget = $targetdir->{target};
640         if (exists $targetdir->{trimdir}) {
641             # if we get here, we've specified that
642             # rather than installing the file to
643             # $(TARGET)/matching/dirs/subdirs/file,
644             # we want to install it to
645             # $(TARGET)/subdirs/file
646             #
647             # Note that this the only place where
648             # $matchlevel is used.
649             my @new_dest_path = @$dest_path;
650             if ($targetdir->{trimdir} == -1)  {
651                 splice @new_dest_path, 0, $matchlevel;
652             } else {
653                 splice @new_dest_path, 0, $targetdir->{trimdir};
654             }
655             _add_to_file_map($file_map, $subtarget, $curr_path, $file, $matchlevel, $install_zebra, \@new_dest_path);
656         } else {
657             # actually getting here means that the
658             # target was unnecessarily listed
659             # as a hash, but we'll forgive that
660             _add_to_file_map($file_map, $subtarget, $curr_path, $file, $matchlevel, $install_zebra);
661         }
662     } elsif ($targetdir ne 'NONE' and $targetdir ne '') {
663         my $source = File::Spec->catfile(@$curr_path, $file);
664         my $destination = File::Spec->catfile('blib', $targetdir, @$dest_path, $file);
665         #print "$source => $destination\n"; # DEBUG
666         # quote spaces in file names
667         # FIXME: this is of questionable portability and
668         # probably depends on user's make recognizing this
669         # quoting syntax -- probably better to remove
670         # spaces and shell metacharacters from all file names
671         $source =~ s/ /\\ /g;
672         $destination =~ s/ /\\ /g;
673       
674         $file_map->{$source} = $destination unless (!$install_zebra and $targetdir =~ /ZEBRA/);
675     }
676 }
677
678 =head2 get_configuration_options
679
680 This prompts the user for various configuration options.
681
682 =cut
683
684 sub get_configuration {
685   my $defaults = shift;
686   my $valid_values = shift;
687   my %config = ();
688
689   my $msg = q(
690 By default, Koha can be installed in one of three ways:
691
692 standard: Install files in conformance with the Filesystem
693           Hierarchy Standard (FHS).  This is the default mode
694           and should be used when installing a production
695           Koha system.  On Unix systems, root access is 
696           needed to complete a standard installation.
697
698 single:   Install files under a single directory.  This option
699           is useful for installing Koha without root access, e.g.,
700           on a web host that allows CGI scripts and MySQL databases
701           but requires the user to keep all files under the user's
702           HOME directory.
703
704 dev:      Create a set of symbolic links and configuration files to
705           allow Koha to run directly from the source distribution.
706           This mode is useful for developers who want to run
707           Koha from a git clone.
708
709 Installation mode);
710     $msg .= _add_valid_values_disp('INSTALL_MODE', $valid_values);
711     $config{'INSTALL_MODE'} = _get_value('INSTALL_MODE', $msg, $defaults->{'INSTALL_MODE'}, $valid_values);
712
713     # set message and default value for INSTALL_BASE
714     # depending on value of INSTALL_MODE
715     my $install_base_default = $defaults->{'INSTALL_BASE'};
716     if ($config{'INSTALL_MODE'} eq 'dev') {
717         $msg = q(
718 Please specify the directory in which to install Koha's
719 active configuration files and (if applicable) the
720 Zebra database.  Koha's CGI scripts and templates will
721 be run from the current directory.
722
723 Configuration directory:);
724         # FIXME - home directory portability consideration apply
725         $install_base_default = (exists $ENV{'HOME'}) ? "$ENV{'HOME'}/koha-dev" : "$defaults->{'INSTALL_BASE'}-dev";
726     } elsif ($config{'INSTALL_MODE'} eq 'single') {
727         $msg = "\nPlease specify the directory in which to install Koha";
728         # FIXME -- we're assuming under a 'single' mode install
729         # that user will likely want to install under the home
730         # directory.  This is OK in and of itself, but we should
731         # use File::HomeDir to locate the home directory portably.  
732         # This is deferred for now because File::HomeDir is not yet
733         # core.
734                 # --we must also keep this portable to the major OS's -fbcit
735         $install_base_default = (exists $ENV{'HOME'}) ? "$ENV{'HOME'}/koha" : $defaults->{'INSTALL_BASE'};
736     } else {
737         # must be standard
738         $msg = q(
739 Please specify the directory under which most Koha files 
740 will be installed.
741
742 Note that if you are planning in installing more than 
743 one instance of Koha, you may want to modify the last
744 component of the directory path, which will be used
745 as the package name in the FHS layout.
746
747 Base installation directory);
748     }
749     $config{'INSTALL_BASE'} = _get_value('INSTALL_BASE', $msg, $install_base_default, $valid_values);
750
751     $config{'INSTALL_BASE'} = File::Spec->rel2abs($config{'INSTALL_BASE'});
752         print "INSTALL_BASE=$config{'INSTALL_BASE'}\r\n" if $DEBUG;
753     if ($config{'INSTALL_MODE'} eq "standard") {
754         $msg = q(
755 Since you are using the 'standard' install
756 mode, you should run 'make install' as root.
757 However, it is recommended that a non-root
758 user (on Unix and Linux platforms) have 
759 ownership of Koha's files, including the
760 Zebra indexes if applicable.
761
762 Please specify a user account.  This
763 user account does not need to exist
764 right now, but it needs to exist
765 before you run 'make install'.  Please
766 note that for security reasons, this
767 user should not be the same as the user
768 account Apache runs under.
769
770 User account);
771         $config{'KOHA_USER'} = _get_value('KOHA_USER', $msg, $defaults->{'KOHA_USER'}, $valid_values);
772
773         $msg = q(
774 Please specify the group that should own
775 Koha's files.  As above, this group need
776 not exist right now, but should be created
777 before you run 'make install'.
778
779 Group);
780         $config{'KOHA_GROUP'} = _get_value('KOHA_GROUP', $msg, $defaults->{'KOHA_GROUP'}, $valid_values);
781     }
782
783     $msg = q(
784 Please specify which database engine you will use
785 to store data in Koha.  The choices are MySQL and
786 PostgreSQL; please note that at the moment
787 PostgreSQL support is highly experimental.
788
789 DBMS to use);
790     $msg .= _add_valid_values_disp('DB_TYPE', $valid_values);
791     $config{'DB_TYPE'} = _get_value('DB_TYPE', $msg, $defaults->{'DB_TYPE'}, $valid_values);
792
793     $msg = q(
794 Please specify the name or address of your 
795 database server.  Note that the database 
796 does not have to exist at this point, it
797 can be created after running 'make install'
798 and before you try using Koha for the first time.
799
800 Database server);
801     $config{'DB_HOST'} = _get_value('DB_HOST', $msg, $defaults->{'DB_HOST'}, $valid_values);
802
803     $msg = q(
804 Please specify the port used to connect to the
805 DMBS);
806     my $db_port_default = $config{'DB_TYPE'} eq 'mysql' ? '3306' : '5432';
807     $config{'DB_PORT'} = _get_value('DB_PORT', $msg, $db_port_default, $valid_values);
808
809     $msg = q(
810 Please specify the name of the database to be
811 used by Koha);
812     $config{'DB_NAME'} = _get_value('DB_NAME', $msg, $defaults->{'DB_NAME'}, $valid_values);
813
814     $msg = q(
815 Please specify the user that owns the database to be
816 used by Koha);
817     $config{'DB_USER'} = _get_value('DB_USER', $msg, $defaults->{'DB_USER'}, $valid_values);
818
819     $msg = q(
820 Please specify the password of the user that owns the 
821 database to be used by Koha);
822     $config{'DB_PASS'} = _get_value('DB_PASS', $msg, $defaults->{'DB_PASS'}, $valid_values);
823
824     $msg = q(
825 Koha can use the Zebra search engine for high-performance
826 searching of bibliographic and authority records.  If you
827 have installed the Zebra software and would like to use it,
828 please answer 'yes' to the following question.  Otherwise, 
829 Koha will default to using its internal search engine.
830
831 Please note that if you choose *NOT* to install Zebra,
832 koha-conf.xml will still contain some references to Zebra
833 settings.  Those references will be ignored by Koha.
834
835 Install the Zebra configuration files?);
836     $msg .= _add_valid_values_disp('INSTALL_ZEBRA', $valid_values);
837     $config{'INSTALL_ZEBRA'} = _get_value('INSTALL_ZEBRA', $msg, $defaults->{'INSTALL_ZEBRA'}, $valid_values);
838
839     if ($config{'INSTALL_ZEBRA'} eq 'yes') {
840         $msg = q(
841 Since you've chosen to use Zebra with Koha,
842 you must specify the primary MARC format of the
843 records to be indexed by Zebra.
844
845 Koha provides Zebra configuration files for MARC 21
846 and UNIMARC.
847
848 MARC format for Zebra indexing);
849         $msg .= _add_valid_values_disp('ZEBRA_MARC_FORMAT', $valid_values);
850         $config{'ZEBRA_MARC_FORMAT'} = _get_value('ZEBRA_MARC_FORMAT', $msg, $defaults->{'ZEBRA_MARC_FORMAT'}, $valid_values);
851         $msg = q(
852 Koha supplies Zebra configuration files tuned for
853 searching either English (en) or French (fr) MARC
854 records.
855
856 Primary language for Zebra indexing);
857         $msg .= _add_valid_values_disp('ZEBRA_LANGUAGE', $valid_values);
858         $config{'ZEBRA_LANGUAGE'} = _get_value('ZEBRA_LANGUAGE', $msg, $defaults->{'ZEBRA_LANGUAGE'}, $valid_values);
859
860         $msg = q(
861 Please specify Zebra database user);
862         $config{'ZEBRA_USER'} = _get_value('ZEBRA_USER', $msg, $defaults->{'ZEBRA_USER'}, $valid_values);
863
864         $msg = q(
865 Please specify the Zebra database password);
866         $config{'ZEBRA_PASS'} = _get_value('ZEBRA_PASS', $msg, $defaults->{'ZEBRA_PASS'}, $valid_values);
867
868     }
869
870     print "\n\n";
871     return %config;
872 }
873
874 sub _add_valid_values_disp {
875     my $key = shift;
876     my $valid_values = shift;
877    
878     my $disp = "";
879     if (exists $valid_values->{$key}) {
880         $disp = " (" . join(", ", sort keys %{ $valid_values->{$key} }) . ")";
881     }
882     return $disp;
883 }
884
885 sub _get_value {
886     my $key = shift;
887     my $msg = shift;
888     my $default = shift;
889     my $valid_values = shift;
890
891     # override default value from environment
892     if (exists $ENV{$key}) {
893         $default = $ENV{$key};
894         $msg .= " (default from environment)";
895     }
896
897     my $val = prompt($msg, $default);
898
899     while (exists $valid_values->{$key} and 
900            $val ne $default and
901            not exists $valid_values->{$key}->{$val}) {
902         my $retry_msg = "Value '$val' is not a valid option.\n";
903         $retry_msg .= "Please enter a value";
904         $retry_msg .= _add_valid_values_disp($key, $valid_values);
905         $val = prompt($retry_msg, $default);
906     }
907     return $val;
908 }
909
910 =head2 get_target_directories 
911
912 Creates a hash mapping from symbols for installation target
913 directories to actual directory paths.
914
915 Also returns a hash indicating targets for which 
916 files need not be copied -- this is used for the 'dev'
917 mode installation, where some files are installed in place.
918
919 =cut
920
921 sub get_target_directories {
922     my $config = shift;
923
924     my $base = $config->{'INSTALL_BASE'};
925     my $mode = $config->{'INSTALL_MODE'};
926
927     # get last component of install base directory
928     # to treat as package name
929     my ($volume, $directories, $file) = File::Spec->splitpath($base, 1);
930
931     my @basedir = File::Spec->splitdir($directories);
932
933         # for Win32 we need to prepend the volume to the directory path
934         if ( $^O eq 'MSWin32' ) { shift @basedir; unshift @basedir, $volume; }
935         elsif ( $^O eq 'cygwin' ) { shift @basedir; unshift @basedir, 'c:'; }   # in a cygwin environment, $volume is returned empty
936
937     my $package = pop @basedir;
938
939
940     my %dirmap = ();
941     my %skipdirs = ();
942     if ($mode eq 'single') {
943         $dirmap{'INTRANET_CGI_DIR'} = File::Spec->catdir(@basedir, $package, 'intranet', 'cgi-bin');
944         $dirmap{'INTRANET_TMPL_DIR'} = File::Spec->catdir(@basedir, $package, 'intranet', 'htdocs', 'intranet-tmpl');
945         $dirmap{'INTRANET_WWW_DIR'} = File::Spec->catdir(@basedir, $package, 'intranet', 'htdocs');
946         $dirmap{'OPAC_CGI_DIR'} = File::Spec->catdir(@basedir, $package, 'opac', 'cgi-bin');
947         $dirmap{'OPAC_TMPL_DIR'} = File::Spec->catdir(@basedir, $package, 'opac', 'htdocs', 'opac-tmpl');
948         $dirmap{'OPAC_WWW_DIR'} = File::Spec->catdir(@basedir, $package, 'opac', 'htdocs');
949         $dirmap{'PERL_MODULE_DIR'} = File::Spec->catdir(@basedir, $package, 'lib');
950         $dirmap{'KOHA_CONF_DIR'} = File::Spec->catdir(@basedir, $package, 'etc');
951         $dirmap{'ZEBRA_CONF_DIR'} = File::Spec->catdir(@basedir, $package, 'etc', 'zebradb');
952         $dirmap{'MISC_DIR'} = File::Spec->catdir(@basedir, $package, 'misc');
953         $dirmap{'SCRIPT_DIR'} = File::Spec->catdir(@basedir, $package, 'bin');
954         $dirmap{'MAN_DIR'} = File::Spec->catdir(@basedir, $package, 'man');
955         $dirmap{'DOC_DIR'} = File::Spec->catdir(@basedir, $package, 'doc');
956         $dirmap{'ZEBRA_LOCK_DIR'} = File::Spec->catdir(@basedir, $package, 'var', 'lock', 'zebradb');
957         $dirmap{'LOG_DIR'} =  File::Spec->catdir(@basedir, $package, 'var', 'log');
958         $dirmap{'ZEBRA_DATA_DIR'} =  File::Spec->catdir(@basedir, $package, 'var', 'lib', 'zebradb');
959         $dirmap{'ZEBRA_RUN_DIR'} =  File::Spec->catdir(@basedir, $package, 'var', 'run', 'zebradb');
960     } elsif ($mode eq 'dev') {
961         my $curdir = File::Spec->rel2abs(File::Spec->curdir());
962         $dirmap{'INTRANET_CGI_DIR'} = File::Spec->catdir($curdir);
963         $skipdirs{'INTRANET_CGI_DIR'} = 1;
964         $dirmap{'INTRANET_TMPL_DIR'} = File::Spec->catdir($curdir, 'koha-tmpl', 'intranet-tmpl');
965         $skipdirs{'INTRANET_TMPL_DIR'} = 1;
966         $dirmap{'INTRANET_WWW_DIR'} = File::Spec->catdir($curdir, 'koha-tmpl');
967         $skipdirs{'INTRANET_WWW_DIR'} = 1;
968         $dirmap{'OPAC_CGI_DIR'} = File::Spec->catdir($curdir);
969         $skipdirs{'OPAC_CGI_DIR'} = 1;
970         $dirmap{'OPAC_TMPL_DIR'} = File::Spec->catdir($curdir, 'koha-tmpl', 'opac-tmpl');
971         $skipdirs{'OPAC_TMPL_DIR'} = 1;
972         $dirmap{'OPAC_WWW_DIR'} = File::Spec->catdir($curdir, 'koha-tmpl');
973         $skipdirs{'OPAC_WWW_DIR'} = 1;
974         $dirmap{'PERL_MODULE_DIR'} = File::Spec->catdir($curdir);
975         $skipdirs{'PERL_MODULE_DIR'} = 1;
976         $dirmap{'KOHA_CONF_DIR'} = File::Spec->catdir(@basedir, $package, 'etc');
977         $dirmap{'ZEBRA_CONF_DIR'} = File::Spec->catdir(@basedir, $package, 'etc', 'zebradb');
978         $dirmap{'MISC_DIR'} = File::Spec->catdir(@basedir, $package, 'misc');
979         $dirmap{'SCRIPT_DIR'} = File::Spec->catdir(@basedir, $package, 'bin');
980         $skipdirs{'SCRIPT_DIR'} = 1;
981         $dirmap{'MAN_DIR'} = File::Spec->catdir(@basedir, $package, 'man');
982         $dirmap{'DOC_DIR'} = File::Spec->catdir(@basedir, $package, 'doc');
983         $dirmap{'ZEBRA_LOCK_DIR'} = File::Spec->catdir(@basedir, $package, 'var', 'lock', 'zebradb');
984         $dirmap{'LOG_DIR'} =  File::Spec->catdir(@basedir, $package, 'var', 'log');
985         $dirmap{'ZEBRA_DATA_DIR'} =  File::Spec->catdir(@basedir, $package, 'var', 'lib', 'zebradb');
986         $dirmap{'ZEBRA_RUN_DIR'} =  File::Spec->catdir(@basedir, $package, 'var', 'run', 'zebradb');
987     } else {
988         # mode is standard, i.e., 'fhs'
989         $dirmap{'INTRANET_CGI_DIR'} = File::Spec->catdir(@basedir, $package, 'intranet', 'cgi-bin');
990         $dirmap{'INTRANET_TMPL_DIR'} = File::Spec->catdir(@basedir, $package, 'intranet', 'htdocs', 'intranet-tmpl');
991         $dirmap{'INTRANET_WWW_DIR'} = File::Spec->catdir(@basedir, $package, 'intranet', 'htdocs');
992         $dirmap{'OPAC_CGI_DIR'} = File::Spec->catdir(@basedir, $package, 'opac', 'cgi-bin');
993         $dirmap{'OPAC_TMPL_DIR'} = File::Spec->catdir(@basedir, $package, 'opac', 'htdocs', 'opac-tmpl');
994         $dirmap{'OPAC_WWW_DIR'} = File::Spec->catdir(@basedir, $package, 'opac', 'htdocs');
995         $dirmap{'PERL_MODULE_DIR'} = File::Spec->catdir(@basedir, $package, 'lib');
996         $dirmap{'KOHA_CONF_DIR'} = File::Spec->catdir(File::Spec->rootdir(), 'etc', $package);
997         $dirmap{'ZEBRA_CONF_DIR'} = File::Spec->catdir(File::Spec->rootdir(), 'etc', $package, 'zebradb');
998         $dirmap{'MISC_DIR'} = File::Spec->catdir(@basedir, $package, 'misc');
999         $dirmap{'SCRIPT_DIR'} = File::Spec->catdir(@basedir, $package, 'bin');
1000         $dirmap{'MAN_DIR'} = File::Spec->catdir(@basedir, $package, 'man');
1001         $dirmap{'DOC_DIR'} = File::Spec->catdir(@basedir, $package, 'doc');
1002         $dirmap{'ZEBRA_LOCK_DIR'} = File::Spec->catdir(File::Spec->rootdir(), 'var', 'lock', $package, 'zebradb');
1003         $dirmap{'LOG_DIR'} =  File::Spec->catdir(File::Spec->rootdir(), 'var', 'log', $package);
1004         $dirmap{'ZEBRA_DATA_DIR'} =  File::Spec->catdir(File::Spec->rootdir(), 'var', 'lib', $package, 'zebradb');
1005         $dirmap{'ZEBRA_RUN_DIR'} =  File::Spec->catdir(File::Spec->rootdir(), 'var', 'run', $package, 'zebradb');
1006     }
1007
1008     _get_env_overrides(\%dirmap);
1009     _get_argv_overrides(\%dirmap);
1010
1011     return \%dirmap, \%skipdirs;
1012 }
1013
1014 sub _get_env_overrides {
1015     my $dirmap = shift;
1016
1017     foreach my $key (keys %$dirmap) {
1018         if (exists $ENV{$key}) {
1019             $dirmap->{$key} = $ENV{$key};
1020             print "Setting $key from environment\n";
1021         }
1022     }
1023 }
1024
1025 sub _get_argv_overrides {
1026     my $dirmap = shift;
1027     
1028     my @new_argv = ();
1029     for (my $i = 0; $i <= $#ARGV; $i++) {
1030         if ($ARGV[$i] =~ /^([^=]+)=([^=]+)$/ and exists $dirmap->{$1}) {
1031             $dirmap->{$1} = $2;
1032         } else {
1033             push @new_argv, $ARGV[$i];
1034         }
1035     }
1036     @ARGV = @new_argv;
1037 }
1038
1039 sub display_configuration {
1040     my $config = shift;
1041     my $dirmap = shift;
1042     print "\n\nKoha will be installed with the following configuration parameters:\n\n";
1043     foreach my $key (sort keys %$config) {
1044         print sprintf("%-25.25s%s\n", $key, $config->{$key});
1045     }
1046
1047     print "\nand in the following directories:\n\n";
1048     foreach my $key (sort keys %$dirmap) {
1049         print sprintf("%-25.25s%s\n", $key, $dirmap->{$key});
1050     }
1051     print "\n\nTo change any configuration setting, please run\n";
1052     print "perl Makefile.PL again.  To override one of the target\n";
1053     print "directories, you can do so on the command line like this:\n";
1054     print "\nperl Makefile.PL PERL_MODULE_DIR=/usr/share/perl/5.8\n\n";
1055     print "You can also set different default values for parameters\n";
1056     print "or override directory locations by using environment variables.\n";
1057     print "\nFor example:\n\n";
1058     print "export DB_USER=my_koha\n";
1059     print "perl Makefile.PL\n";
1060     print "\nor\n\n";
1061     print "DB_USER=my_koha DOC_DIR=/usr/local/info perl Makefile.PL\n\n";
1062 }
1063
1064 package MY;
1065
1066 # This will have to be reworked in order to accommodate Win32...
1067
1068 sub test {
1069     my $self = shift;
1070     my $test = $self->SUPER::test(@_);
1071     $test =~ s!\$\(INST_LIB\)!blib/PERL_MODULE_DIR!g;
1072     return $test;
1073 }
1074
1075 sub install {
1076     my $self = shift;
1077     my $install = ""; 
1078     # NOTE: we're *not* doing this: my $install = $self->SUPER::install(@_);
1079     # This means that we're completely overriding EU::MM's default
1080     # installation and uninstallation targets.
1081
1082 # If installation is on Win32, we need to do permissions different from *nix
1083     if ( $^O =~ /darwin|linux|cygwin/ ) { # this value needs to be verified for each platform and modified accordingly
1084             foreach my $key (sort keys %$target_directories) {
1085                     $install .= qq(
1086 KOHA_INST_$key = blib/$key
1087 KOHA_DEST_$key = $target_directories->{$key}
1088 )                       unless ($config{'INSTALL_ZEBRA'} ne "yes" and $key =~ /ZEBRA/) or exists $skip_directories->{$key};
1089                 }
1090                 $install .= qq(
1091 install :: all install_koha set_koha_ownership set_koha_permissions warn_koha_env_vars
1092 \t\$(NOECHO) \$(NOOP)
1093 );
1094                         $install .= "install_koha ::\n";      
1095                         $install .= "\t\$(NOECHO) umask 022; \$(MOD_INSTALL) \\\n";
1096                         foreach my $key (sort keys %$target_directories) {
1097                                 $install .= "\t\t\$(KOHA_INST_$key) \$(KOHA_DEST_$key) \\\n" 
1098                                         unless ($config{'INSTALL_ZEBRA'} ne "yes" and $key =~ /ZEBRA/) or exists $skip_directories->{$key};
1099                         }
1100                         $install .= "\t\t\$(INST_MAN1DIR) \$(DESTINSTALLMAN1DIR) \\\n";
1101                         $install .= "\t\t\$(INST_MAN3DIR) \$(DESTINSTALLMAN3DIR)\n";
1102
1103                         $install .= "\n";
1104                         $install .= "set_koha_ownership ::\n";
1105                         if ($config{'INSTALL_MODE'} eq 'standard' and $config{'KOHA_USER'} ne "root") {
1106                                 foreach my $key (sort keys %$target_directories) {
1107                                         $install .= "\t\$(NOECHO) chown -R $config{'KOHA_USER'}:$config{'KOHA_GROUP'} \$(KOHA_DEST_$key)\n"
1108                                                 unless ($config{'INSTALL_ZEBRA'} ne "yes" and $key =~ /ZEBRA/) or exists $skip_directories->{$key};
1109                                 }
1110                         } else {
1111                                 $install .= "\t\t\$(NOECHO) \$(NOOP)\n\n";
1112                         }
1113
1114                         $install .= "\n";
1115                         $install .= "set_koha_permissions ::\n";
1116                         # This is necessary because EU::MM installs files
1117                         # as either 0444 or 0555, and we want the owner
1118                         # of Koha's files to have write permission by default.
1119                         foreach my $key (sort keys %$target_directories) {
1120                                 $install .= "\t\$(NOECHO) chmod -R u+w \$(KOHA_DEST_$key)\n"
1121                                         unless ($config{'INSTALL_ZEBRA'} ne "yes" and $key =~ /ZEBRA/) or exists $skip_directories->{$key};
1122                         }
1123         }
1124         elsif ($^O eq 'MSWin32' ) {     # On Win32, the install probably needs to be done under the user account koha will be running as...
1125                                                                 # We can attempt some creative things with command line utils such as CACLS which allows permission
1126                                                                 # management from Win32 cmd.exe, but permissions really only apply to NTFS.
1127             foreach my $key (sort keys %$target_directories) {
1128                     $install .= qq(
1129 KOHA_INST_$key = blib/$key
1130 KOHA_DEST_$key = $target_directories->{$key}
1131 )                       unless ($config{'INSTALL_ZEBRA'} ne "yes" and $key =~ /ZEBRA/) or exists $skip_directories->{$key};
1132                 }
1133                 $install .= qq(
1134 install :: all install_koha warn_koha_env_vars
1135 \t\$(NOECHO) \$(NOOP)
1136 );
1137                 $install .= "install_koha ::\n";
1138                 $install .= "\t\$(MOD_INSTALL) \\\n";
1139                 foreach my $key (sort keys %$target_directories) {
1140                         $install .= "\t\t\$(KOHA_INST_$key) \$(KOHA_DEST_$key) \\\n" 
1141                                 unless ($config{'INSTALL_ZEBRA'} ne "yes" and $key =~ /ZEBRA/) or exists $skip_directories->{$key};
1142                 }
1143         }
1144         $install .= "\n";
1145
1146     $install .= "warn_koha_env_vars ::\n";
1147     $install .= "\t\$(NOECHO) \$(ECHO)\n";
1148     $install .= "\t\$(NOECHO) \$(ECHO) Koha\\'s files have now been installed. \n";
1149     $install .= "\t\$(NOECHO) \$(ECHO)\n";
1150     $install .= "\t\$(NOECHO) \$(ECHO) In order to use Koha\\'s command-line batch jobs,\n";
1151     $install .= "\t\$(NOECHO) \$(ECHO) you should set the following environment variables:\n";
1152     $install .= "\t\$(NOECHO) \$(ECHO)\n";
1153     $install .= "\t\$(NOECHO) \$(ECHO) export KOHA_CONF=\$(KOHA_DEST_KOHA_CONF_DIR)/koha-conf.xml\n";
1154     $install .= "\t\$(NOECHO) \$(ECHO) export PERL5LIB=$target_directories->{'PERL_MODULE_DIR'}\n";
1155     $install .= "\t\$(NOECHO) \$(ECHO)\n";
1156     $install .= "\t\$(NOECHO) \$(ECHO) If installing on a Win32 platform, be sure to use:\n";
1157     $install .= "\t\$(NOECHO) \$(ECHO) 'dmake -x MAXLINELENGTH=300000'\n";
1158     $install .= "\t\$(NOECHO) \$(ECHO)\n";
1159     $install .= "\t\$(NOECHO) \$(ECHO) For other post-installation tasks, please consult the README.\n";
1160     $install .= "\t\$(NOECHO) \$(ECHO)\n";
1161
1162     return $install;
1163 }
1164
1165 sub postamble {
1166     # put directory mappings into Makefile
1167     # so that Make will export as environment
1168     # variables -- this is for the use of
1169     # rewrite-confg.PL
1170
1171     # quote '$' in the two password parameters
1172     my %config = %config;
1173     $config{'DB_PASS'} =~ s/\$/\$\$/g;
1174     if ($config{'INSTALL_ZEBRA'} eq "yes") {
1175         $config{'ZEBRA_PASS'} =~ s/\$/\$\$/g;
1176     }
1177
1178         # Hereagain, we must alter syntax per platform...
1179         if ( $^O eq 'MSWin32' ) {
1180                 # NOTE: it is imperative that there be no whitespaces in ENV=value...
1181                 my $env = join("\n", map { "__${_}__=$target_directories->{$_}" } keys %$target_directories); 
1182                 $env .= "\n\n";
1183                 $env .= join("\n", map { "__${_}__=$config{$_}" } keys %config);
1184                 return "$env\n";
1185         }
1186     else {
1187                 my $env = join("\n", map { "export __${_}__ := $target_directories->{$_}" } keys %$target_directories); 
1188                 $env .= "\n\n";
1189                 $env .= join("\n", map { "export __${_}__ := $config{$_}" } keys %config);
1190                 return "$env\n";
1191         }
1192 }
1193
1194
1195 __END__
1196
1197
1198 =head1 SEE ALSO
1199
1200 ExtUtils::MakeMaker(3)
1201
1202 =head1 AUTHORS
1203
1204 MJ Ray mjr at phonecoop.coop
1205 Galen Charlton galen.charlton at liblime.com
1206
1207 =cut
1208 FIXME: deal with .htaccess