1:
2eval 'exec perl -wS $0 ${1+"$@"}'
3    if 0;
4#**************************************************************
5#
6#  Licensed to the Apache Software Foundation (ASF) under one
7#  or more contributor license agreements.  See the NOTICE file
8#  distributed with this work for additional information
9#  regarding copyright ownership.  The ASF licenses this file
10#  to you under the Apache License, Version 2.0 (the
11#  "License"); you may not use this file except in compliance
12#  with the License.  You may obtain a copy of the License at
13#
14#    http://www.apache.org/licenses/LICENSE-2.0
15#
16#  Unless required by applicable law or agreed to in writing,
17#  software distributed under the License is distributed on an
18#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19#  KIND, either express or implied.  See the License for the
20#  specific language governing permissions and limitations
21#  under the License.
22#
23#**************************************************************
24
25
26
27#
28# packconfig.pl - pack xml configuration into archives
29#
30
31use strict;
32use Getopt::Long;
33use File::Find;
34use File::Basename;
35use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
36
37#### globals ####
38
39my $out_file;                # path to output archive
40my $tmp_out_file;            # path to temporary output file
41my $files_path;              # path to look for desired files
42my $verbose;                 # be verbose
43my $extra_verbose;           # be extra verbose
44my $do_rebuild = 0;          # is rebuilding zipfile required?
45
46#### script id #####
47
48( my $script_name = $0 ) =~ s/^.*\b(\w+)\.pl$/$1/;
49
50my $script_rev;
51my $id_str = ' $Revision$ ';
52$id_str =~ /Revision:\s+(\S+)\s+\$/
53  ? ($script_rev = $1) : ($script_rev = "-");
54
55#print "$script_name -- version: $script_rev\n";
56
57#### main #####
58
59parse_options();
60my %files_hash;
61my $file_ref = get_files();
62
63$do_rebuild = is_file_newer(\%files_hash) if $do_rebuild == 0;
64
65if ( $do_rebuild == 1 ) {
66    create_zip_archive(\%files_hash);
67    replace_file($tmp_out_file, $out_file);
68    print_message("packing  $out_file finished.");
69} else {
70    print_message("$out_file up to date. nothing to do.");
71}
72
73exit(0);
74
75#### subroutines ####
76
77sub parse_options
78{
79    my $opt_help;
80    my $p = Getopt::Long::Parser->new();
81    my $success =$p->getoptions(
82                             '-h' => \$opt_help,
83                             '-o=s' => \$out_file,
84                             '-i=s' => \$files_path,
85                             '-v'   => \$verbose,
86                             '-vv'  => \$extra_verbose
87                            );
88
89    if ( $opt_help || !$success || !$out_file || !$files_path )
90    {
91        usage();
92        exit(1);
93    }
94
95    #define intermediate output file
96    $tmp_out_file="$out_file"."$$".$ENV{INPATH};
97    # Sanity checks.
98
99    # Check if out_file can be written.
100    my $out_dir = dirname($out_file);
101    print_error("no such directory: '$out_dir'", 2) if ! -d $out_dir;
102    print_error("can't search directory: '$out_dir'", 2) if ! -x $out_dir;
103    print_error("directory is not writable: '$out_dir'", 2) if ! -w $out_dir;
104
105    # Check paths.
106    foreach ($files_path) {
107        print_error("no such directory: '$_'", 2) if ! -d $_;
108        print_error("can't search directory: '$_'", 2) if ! -x $_;
109    }
110}
111
112sub get_files
113{
114    local @main::file_list;
115
116    find_files(\%files_hash);
117
118    if ( !keys %files_hash ) {
119        print_error("can't find any image lists in '$files_path'", 3);
120    }
121
122    return wantarray ? @main::file_list : \@main::file_list;
123}
124
125sub find_files
126{
127    my $files_hash_ref = shift;
128    find({ wanted => \&wanted, no_chdir => 0 }, "$files_path");
129    foreach ( @main::file_list ) {
130        /^\Q$files_path\E\/(.*)$/o;
131        $files_hash_ref->{$1}++;
132    }
133}
134
135sub wanted
136{
137    my $file = $_;
138
139    if ( $file =~ /.*\.xml$/ && -f $file ) {
140        push @main::file_list, $File::Find::name;
141    }
142}
143
144sub is_file_newer
145{
146    my $test_hash_ref = shift;
147    my $reference_stamp = 0;
148
149    print_message("checking timestamps ...") if $verbose;
150    if ( -e $out_file ) {
151        $reference_stamp = (stat($out_file))[9];
152        print_message("found $out_file with $reference_stamp ...") if $verbose;
153    }
154    return 1 if $reference_stamp == 0;
155
156    foreach ( sort keys %{$test_hash_ref} ) {
157        my $path = $files_path;
158        $path .= "/" if "$path" ne "";
159        $path .= "$_";
160        print_message("checking '$path' ...") if $extra_verbose;
161        my $mtime = (stat($path))[9];
162        return 1 if $reference_stamp < $mtime;
163    }
164    return 0;
165}
166
167sub create_zip_archive
168{
169    my $zip_hash_ref = shift;
170    print_message("creating config archive ...") if $verbose;
171    my $zip = Archive::Zip->new();
172
173    # on Mac OS X Intel we have unxmacxi.pro, on Mac OS X PowerPC unxmacxp.pro .. and so on
174    my $platform = $ENV{INPATH};
175
176    foreach ( sort keys %{$zip_hash_ref} ) {
177        my $path = "$files_path/$_";
178	# only Mac OS X Aqua is concerned here
179	# but changes for other platforms can easely be added following the same principle
180	if ( ( $platform =~ /^.*macx*/) && ($path =~ /^.*menubar.xml/ ) ) {
181	    $path = modify_mac_menus($path);
182	}
183	print_message("zipping '$path' ...") if $extra_verbose;
184	if ( !$zip->addFile($path, $_) ) {
185	    print_error("can't add file '$path' to config zip archive: $!", 5);
186	}
187    }
188    my $status = $zip->writeToFileNamed($tmp_out_file);
189    if ( $status != AZ_OK ) {
190        print_error("write image zip archive '$tmp_out_file' failed. Reason: $status", 6);
191    }
192    return;
193}
194
195sub modify_mac_menus
196{
197    my $path_base = "$ENV{'SOLARENV'}";
198    $path_base =~ s/solenv//;
199
200    my $new_file_name = "$path_base"."postprocess"."\/"."$ENV{INPATH}"."\/"."misc"."\/"."$_";
201
202    my $new_directory = $new_file_name;
203    $new_directory =~ s/\/menubar.xml//;
204    if ( ! -e $new_directory) {
205	`mkdir -p "$new_directory"`;
206    }
207
208    my $old_file_name = "$files_path/$_";
209
210    `cp $old_file_name $new_file_name`;
211
212    my $temp_file_name = "$new_file_name"."_tmp";
213    my $xsl_file = "macosx/macosx_menubar_modification.xsl";
214
215    my $result = `xsltproc $xsl_file $new_file_name > $temp_file_name`;
216
217    if ( $result != 0) {
218	print_error("xsltproc '$xsl_file' '$new_file_name'> '$temp_file_name' failed",1)
219    }
220
221    replace_file( $temp_file_name, $new_file_name );
222    return $new_file_name;
223}
224
225sub replace_file
226{
227    my $source_file = shift;
228    my $dest_file = shift;
229    my $result = 0;
230
231    $result = unlink($dest_file) if -f $dest_file;
232    if ( $result != 1 && -f $dest_file ) {
233        unlink $source_file;
234        print_error("couldn't remove '$dest_file'",1);
235    }  else {
236        if ( !rename($source_file, $dest_file)) {
237            unlink $source_file;
238            print_error("couldn't rename '$source_file'",1);
239        }
240    }
241    return;
242}
243
244sub usage
245{
246    print STDERR "Usage: packimages.pl [-h] -o out_file -i file_path\n";
247    print STDERR "Creates archive of images\n";
248    print STDERR "Options:\n";
249    print STDERR "    -h                 print this help\n";
250    print STDERR "    -o out_file        path to output archive\n";
251    print STDERR "    -i file_path       path to directory containing the config files\n";
252    print STDERR "    -v                 verbose\n";
253    print STDERR "    -vv                very verbose\n";
254}
255
256sub print_message
257{
258    my $message     = shift;
259
260    print "$script_name: ";
261    print "$message\n";
262    return;
263}
264
265sub print_warning
266{
267    my $message     = shift;
268
269    print STDERR "$script_name: ";
270    print STDERR "WARNING $message\n";
271    return;
272}
273
274sub print_error
275{
276    my $message     = shift;
277    my $error_code  = shift;
278
279    print STDERR "$script_name: ";
280    print STDERR "ERROR: $message\n";
281
282    if ( $error_code ) {
283        print STDERR "\nFAILURE: $script_name aborted.\n";
284        exit($error_code);
285    }
286    return;
287}
288