Subversion Repositories DevTools

Rev

Rev 6364 | Rev 6734 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1119 dpurdie 1
########################################################################
6302 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
1119 dpurdie 3
#
6302 dpurdie 4
# Module name   : ManifestFiles.pm
1119 dpurdie 5
# Module type   : Makefile system
6302 dpurdie 6
# Environment(s): JATS Build System
5654 dpurdie 7
# Documents     : MASS-00232 Format of the Linux App Upgrade Manifest File
1119 dpurdie 8
#
9
# Description   : This package extends the JATS toolset at build time
10
#                 It provides additional directives to the JATS makefiles
11
#                 to simplify the directives.
12
#
13
#                 This directive does all its work at 'build' time
14
#                 It uses makefile.pl directives
15
#
16
# Operation     : This package adds the JATS directive ManifestFiles
17
#                 This is used to create linux manifest files
18
#
19
# Syntax        : ManifestFiles (<platforms>, Options+);
20
#                 See the function header for details
21
#
22
#......................................................................#
23
 
24
require 5.6.1;
25
use strict;
26
use warnings;
5649 dpurdie 27
use Digest::file qw(digest_file_hex);
5771 alewis 28
use Digest::file qw(digest_file_base64);
6306 dpurdie 29
use ArrayHashUtils;
1119 dpurdie 30
 
31
#
32
#   Globals
33
#
34
my @Manifests;                      # Manifest entries
1125 alewis 35
my $Manifest_has_version = 1;       # Create Manifest_xxxx by default
1121 dpurdie 36
my %package_dirs;                   # Package dirs discovered and used
1125 alewis 37
my $pkg_subdir;                     # Alternate packaging
6314 dpurdie 38
my $ManifestLineWidth;              # Max length of lines
1119 dpurdie 39
 
40
#-------------------------------------------------------------------------------
41
# Function        : BEGIN
42
#
43
# Description     : Setup directive hooks
44
#                   Register a function to be called just before we start to
45
#                   generate makefiles. This will be used to process the data
46
#                   collected in all the ManifestFiles directives
47
#
48
# Inputs          : None
49
#
50
# Returns         : None
51
#
52
BEGIN
53
{
54
    RegisterMakefileGenerate (\&ManifestFiles_Generate);
55
}
56
 
57
#-------------------------------------------------------------------------------
58
# Function        : ManifestFiles
59
#
60
# Description     : Create a ManifestFiles entry
61
#
62
# Inputs          : Platform             - Active Platform Selector
63
#                   Options              - One or more options
64
#                       --Name=Name             - Mandatory
65
#                       --Tier=Name             - Mandatory
66
#                       --Architecture=xxxx     - Default actitecture is the current target
67
#                       --Product=yyyy          - Product Family
68
#                       --Debian=BaseName[,--Prod,--Debug,--Arch=xxxx,--Product=yyyy]
6302 dpurdie 69
#                       --Apk=BaseName[,--Prod,--Debug,--Platform=pppp]
70
#                                                   Default platform = ANDROID
71
#                                                   Default type = Production
1119 dpurdie 72
#                       --MugPackage=Package[,--Subdir=subdir[,subdir]+]
73
#                       --SrcFile=xxx
1125 alewis 74
#                       --SrcFileNoCopy=xxx
1123 dpurdie 75
#                       --Comment=xxx           - Add comment to Manifst
1125 alewis 76
#                       --NoManifestVersion     - Create unversioned Manifest File
77
#                       --PkgSubdir=xxx         - Specifies packaging subdir
5105 dpurdie 78
#                       --ImportManifest=Package[,--Subdir=subdir,--ReWrite] - Import Manifest from package
5649 dpurdie 79
#                       --Md5                   - Add MD5 checksums to the Manifest File
5767 alewis 80
#                       --Dmf                   - Generate the Device Management Framework
81
#                                                 combined archive ZIP file.
82
#                       --DmfVersion=xxxx       - Generate the Device Management Framework
83
#                                                 combined archive ZIP using a modified
84
#                                                 version number; only for testing!
6364 dpurdie 85
#                       --LineLength=nnn        - Limit line length. Default is 79
86
#                       --SubManifest           - Create a sub-manifest (not installable). Manifest will have no version.
87
#                                                 Gives a default name, tier and subdir if not explicitly provided.
1119 dpurdie 88
#
89
# Returns         : Nothing
90
#
91
sub ManifestFiles
92
{
93
    my( $platforms, @elements ) = @_;
94
    Debug2( "ManifestFiles($platforms, @elements)" );
95
    return if ( ! ActivePlatform($platforms) );
96
 
97
    my $name;
98
    my $tier;
99
    my @files;
6306 dpurdie 100
    my %fileVersions;
1119 dpurdie 101
    my $mug_dir;
102
    my $default_arch = $::ScmPlatform;
103
    my $default_prod = '';
1129 dpurdie 104
    my $imported_manifest = 0;
5649 dpurdie 105
    my $include_md5 = 0;
5767 alewis 106
    my $generate_dmf = 0;
5771 alewis 107
    my $dmf_version = $::ScmBuildVersionFull;
6314 dpurdie 108
    my $useDefaultLineWidth = 1;
6364 dpurdie 109
    my $is_sub_manifest = 0;
1119 dpurdie 110
 
111
    #
112
    #   Collect user options
113
    #
114
    foreach ( @elements )
115
    {
116
        if ( m~^--Name=(.+)~ ) {
6302 dpurdie 117
            if ( $name ) {
1119 dpurdie 118
                ReportError ("ManifestFiles:--Name option is only allowed once");
119
                next;
120
            }
121
            $name = $1;
122
 
123
        } elsif ( m~^--Tier=(.+)~ ) {
6302 dpurdie 124
            if ( $tier ) {
1119 dpurdie 125
                ReportError ("ManifestFiles:--Tier option is only allowed once");
126
                next;
127
            }
128
            $tier = $1;
129
 
1123 dpurdie 130
        } elsif ( m~^--Comment=~ ) {
131
            my $cmt = $_;
132
            $cmt =~ s~.+=~~;
133
            $cmt =~ s~\s*\n\s*~\n~g;
134
            push @files, {'cmt' => $cmt };
135
 
1119 dpurdie 136
        } elsif ( m~^--Debian=(.+)~ ) {
6302 dpurdie 137
            push @files, {'file' => _LocateDebianFile($1, $default_arch, $default_prod)};
1119 dpurdie 138
 
6302 dpurdie 139
        } elsif ( m~^--Apk=(.+)~ ) {
6306 dpurdie 140
            my $apkData = _LocateApkFile($1, $default_arch);
141
            my ($fname, $fversion) = split($;, $apkData);
142
            $fileVersions{$fname} = $fversion;
143
            push @files, {'file' => $fname };
6314 dpurdie 144
            $useDefaultLineWidth = 0;
6302 dpurdie 145
 
1119 dpurdie 146
        } elsif ( m~^--SrcFile=(.+)~ ) {
1123 dpurdie 147
            push @files, {'file' => LocatePreReq($1)};
5649 dpurdie 148
 
1125 alewis 149
        } elsif ( m~^--SrcFileNoCopy=(.+)~ ) {
150
            push @files, {'filenocopy' => $1};
5649 dpurdie 151
 
1119 dpurdie 152
        } elsif ( m~^--MugPackage=(.+)~ ) {
6302 dpurdie 153
            if ( $mug_dir ) {
1119 dpurdie 154
                ReportError ("ManifestFiles:--MugPackage option is only allowed once");
155
                next;
5649 dpurdie 156
            }
6302 dpurdie 157
            $mug_dir = _LocateMugDir($1);
1119 dpurdie 158
 
159
        } elsif ( m/^--Arch(.*)=(.+)/ ) {
160
            $default_arch = $2;
161
 
162
        } elsif ( m/^--Product=(.+)/ ) {
163
            $default_prod = $1;
164
 
1125 alewis 165
        } elsif ( m/^--NoManifestVersion/i ) {
166
            $Manifest_has_version = 0;
167
 
168
        } elsif ( m/^--PkgSubdir=(.+)/i ) {
6302 dpurdie 169
            if ( $pkg_subdir ) {
1129 dpurdie 170
                ReportError ("ManifestFiles:--PkgSubdir option is only allowed once");
1125 alewis 171
                next;
172
            }
173
            $pkg_subdir = $1;
174
 
1129 dpurdie 175
        } elsif ( m/^--ImportManifest=(.+)/i ) {
6302 dpurdie 176
            my $import_info = _ImportManifest($1, $tier, $name);
1129 dpurdie 177
#DebugDumpData("ImportInfo", $import_info );
178
            push @files, {'manifest' => $import_info };
179
 
180
            #
181
            #   Fill in details unless already provided
182
            #
183
            $tier = $import_info->{'tier'} unless ( defined $tier );
184
            $name = $import_info->{'name'} unless ( defined $name );
185
            $imported_manifest = 1;
186
 
5649 dpurdie 187
        } elsif (m/^--Md5/i) {
6314 dpurdie 188
            $include_md5 = 1;
189
            $useDefaultLineWidth = 0;
5649 dpurdie 190
 
5767 alewis 191
        } elsif (m/^--Dmf/i) {
192
            $generate_dmf = 1
193
 
194
        } elsif ( m/^--DmfVersion=(.+)/ ) {
195
            $generate_dmf = 1;
196
            $dmf_version = $1;
197
 
6314 dpurdie 198
        } elsif ( m/^--LineLength=(\d+)$/i ) {
199
            $ManifestLineWidth = $1;
200
            $useDefaultLineWidth = 0;
201
 
6364 dpurdie 202
        } elsif (m/^--SubManifest/i) {
203
            $is_sub_manifest = 1;
204
            $Manifest_has_version = 0;
205
            $name = $::ScmPlatform
206
                unless $name;
207
            $pkg_subdir = $name
208
                unless $pkg_subdir;
209
            $tier = 0
210
                unless defined($tier);
211
 
1119 dpurdie 212
        } else {
213
            ReportError ("ManifestFiles: Unknown option or argument: $_");
214
 
215
        }
216
    }
217
 
218
    #
219
    #   Sanity test the user options
220
    #
221
    ReportError ("ManifestFiles: No name specified")
222
        unless $name;
223
    ReportError ("ManifestFiles: No tier specified")
1129 dpurdie 224
        unless defined ($tier);
6302 dpurdie 225
    ReportError ("ManifestFiles: Cannot mix --Debian/-Apk/--SrcFile with --MugPackage in one directive")
1129 dpurdie 226
        if ( $mug_dir && (@files || $imported_manifest) );
1119 dpurdie 227
    ReportError ("ManifestFiles: Must specify files to add to Manifest")
1129 dpurdie 228
        unless ( $mug_dir ||  @files || $imported_manifest);
1119 dpurdie 229
    ErrorDoExit();
230
 
231
    #
6314 dpurdie 232
    #   Set ManifestLineWidth
233
    #   The default is largely historical - for MOS
234
    #   
235
    unless (defined $ManifestLineWidth) {
236
        $ManifestLineWidth = $useDefaultLineWidth ? 79 : 0;
237
    }
238
    Verbose("ManifestLineWidth:$ManifestLineWidth");
239
 
240
    #
1119 dpurdie 241
    #   Save information for processing at the end of the parsing phase
242
    #   Data collected from ALL the ManifestFiles directives will be collected
243
    #   and processed into one Manifest file
244
    #
245
    my %data;
246
    $data{tier} = $tier;
247
    $data{name} = $name;
248
    $data{files} = \@files;
6306 dpurdie 249
    $data{fileVersions} = \%fileVersions;
1119 dpurdie 250
    $data{mugdir} = $mug_dir;
1125 alewis 251
    $data{pkgsubdir} = $pkg_subdir;
5649 dpurdie 252
    $data{md5} = $include_md5;
5767 alewis 253
    $data{dmf} = $generate_dmf;
254
    $data{arch} = $default_arch;
255
    $data{dmf_version} = $dmf_version;
6364 dpurdie 256
    $data{is_sub_manifest} = $is_sub_manifest;
5767 alewis 257
 
1129 dpurdie 258
#DebugDumpData("DirectiveData", \%data );
1119 dpurdie 259
 
260
    push @Manifests, \%data;
261
    return;
6302 dpurdie 262
}
1119 dpurdie 263
 
6302 dpurdie 264
#-------------------------------------------------------------------------------
265
# Function        : _LocateDebianFile
266
#
267
# Description     : Locate a debian file
268
#                   Internal Function
269
#
270
#                   Scan packages for the Debian package specified
271
#                   The user provides the base name of the package
272
#                   A Debian Package name has several fields
273
#                   These are:
274
#                       1) Base Name - Provided by the user
6730 dpurdie 275
#                       2) Version - Default Version will be wildcarded if it hadn't been provided by user
6302 dpurdie 276
#                       3) Architecture - Wildcarded. Uses bin/arch directory
277
#
278
#                   Expect to find Debian Packages in the bin/PLATFORM subdir
279
#
280
# Inputs          : Debian base name, complete with suboptions
281
#
282
# Returns         : Full path of the file
283
#
284
sub _LocateDebianFile
285
{
286
    my ($arg, $arch, $product) = @_;
287
    Verbose("LocateDebianFile: Processing: $arg");
288
 
289
    my @type = qw( P D );
290
    my @debian_file_path;
6306 dpurdie 291
    my @searchPath;
6730 dpurdie 292
    my $version='*';
6302 dpurdie 293
 
1119 dpurdie 294
    #
6302 dpurdie 295
    #   Extract sub-options
296
    #       --Prod[uction]
297
    #       --Debug
298
    #       --Arch[itecture]=yyy
299
    #       --Product=yyy
6730 dpurdie 300
    #       --Version=yy.yy.yyyyy  default value is wildcard 
1119 dpurdie 301
    #
6302 dpurdie 302
    my ($base_name, @opts) = split( ',', $arg );
303
    foreach ( @opts )
304
    {
305
        if ( m/^--Arch(.*)=(.+)/ ) {
306
            $arch=$2;
307
        } elsif ( m/^--Product=(.+)/ ) {
308
            $product=$1;
309
        } elsif ( m/^--Prod/ ) {
310
            @type = 'P';
311
        } elsif ( m/^--Debug/ ) {
312
            @type = 'D';
6730 dpurdie 313
        } elsif ( m/^--Version=(.+)/ ) {
314
            $version=$1;
6302 dpurdie 315
        } else {
316
            Warning ('--Debian: Unknown Option: ' . $_);
317
        }
318
    }
319
 
5649 dpurdie 320
    #
6302 dpurdie 321
    #   Create a list of products
322
    #   ie: PRODUCT_ARCH
1119 dpurdie 323
    #
6302 dpurdie 324
    my @products;
325
    push @products, $product . '_' . $arch if ( $product );
326
    push @products, $arch;
327
 
1119 dpurdie 328
    #
6302 dpurdie 329
    #   Scan all packages for the specified debian package
1119 dpurdie 330
    #
6302 dpurdie 331
    foreach my $package_dir ( getPackagePaths ('--All') )
1119 dpurdie 332
    {
6302 dpurdie 333
        foreach my $type ( @type )
1119 dpurdie 334
        {
6302 dpurdie 335
            foreach my $prd ( @products )
1119 dpurdie 336
            {
6302 dpurdie 337
                foreach my $joiner ( qw(/ .) )
1119 dpurdie 338
                {
6302 dpurdie 339
                    my $dir = "$package_dir/bin$joiner$prd$type";
6306 dpurdie 340
                    UniquePush(\@searchPath, $dir);
5873 acammell 341
                    next unless ( -d $dir );
6730 dpurdie 342
                    my @files = glob ( "$dir/${base_name}_${version}_*.deb" );
5873 acammell 343
                    next unless ( @files );
344
                    push @debian_file_path, @files;
345
                    $package_dirs{$package_dir}{used} = 1;
346
                }
347
            }
1119 dpurdie 348
        }
6302 dpurdie 349
        foreach my $type ( @type )
350
        {
351
            foreach my $prd ( @products )
352
            {
353
                my $dir = "$package_dir";
6306 dpurdie 354
                UniquePush(\@searchPath, $dir);
6730 dpurdie 355
                next unless ( -d $dir ); 
356
                if ( $version eq "*" ){
357
                    my @files = glob ( "$dir/${base_name}_${version}_${prd}_${type}.deb" );
358
                    if ( @files ){
359
                        push @debian_file_path, @files;
360
                        $package_dirs{$package_dir}{used} = 1;
361
                    }
362
                }
363
                else{
364
                    if( -e "$dir/${base_name}_${version}_${prd}_${type}.deb" ) {
365
                        my $file = "$dir/${base_name}_${version}_${prd}_${type}.deb";
366
                        push(@debian_file_path, $file);
367
                        $package_dirs{$package_dir}{used} = 1;
368
                    } elsif ( -e "$dir/${base_name}_${version}_${prd}.deb") {
369
                        my $file = "$dir/${base_name}_${version}_${prd}.deb";
370
                        push(@debian_file_path, $file);
371
                        $package_dirs{$package_dir}{used} = 1;
372
                    } 
373
                }
6302 dpurdie 374
            }
375
        }
1119 dpurdie 376
    }
377
 
6306 dpurdie 378
    #
379
    #   Keep user informed
380
    #   Report errors and provide useful information
381
    #
382
    if (IsVerbose(1) || IsDebug(1) || $#debian_file_path != 0)
383
    {
384
        Message ("Search for ($base_name). In search Path", @searchPath);
385
    }
6730 dpurdie 386
 
6302 dpurdie 387
    ReportError ("Required Debian package not found: $base_name") unless @debian_file_path;
388
    ReportError ("Multiple matching Debian Packages located: $base_name", @debian_file_path ) if ( $#debian_file_path > 0 );
389
    return $debian_file_path[0];
390
}
391
 
392
#-------------------------------------------------------------------------------
393
# Function        : _LocateApkFile
394
#
395
# Description     : Locate a APK file
396
#                   Internal Function
397
#
398
#                   Scan packages for the APK package specified
399
#                   The user provides the base name of the package
400
#                   APK ( Android Packages )
401
#                   Expect to have a '-release' or '-debug' suffix, except those provided via a
402
#                   3rd party SDK.
403
#                   Expect to find APK Packages in the bin/PLATFORM(P/D) subdir
404
#                   Expect to find -debug in the <PLATFORM>D directory
405
#                   Expect to find -release' in the <PLATFORM>P directory
406
#                   
407
#                   Allow for:
408
#                       Full path to .apk file
409
#                       .apk in package root directory
410
#
411
# Inputs          : Apk base name, complete with suboptions
412
#
6306 dpurdie 413
# Returns         : Full path of the file $; PackageVersion
414
#                   apk packages do not appear to have version numbers in the file name
415
#                   Retain package version number for later processing
6302 dpurdie 416
#
417
sub _LocateApkFile
418
{
419
    my ($arg, $arch) = @_;
420
    Verbose("LocateApkFile: Processing: $arg");
421
 
422
    my @type = qw( P );
423
    my @apk_file_path;
424
    my %type = ('P' => '-release', 'D' => '-debug' );
6306 dpurdie 425
    my @searchPath;
6302 dpurdie 426
 
1119 dpurdie 427
    #
6302 dpurdie 428
    #   Extract sub-options
429
    #       --Prod[uction]
430
    #       --Debug
431
    #       --Architecture=yyy
1119 dpurdie 432
    #
6302 dpurdie 433
    my ($base_name, @opts) = split( ',', $arg );
434
    foreach ( @opts )
1119 dpurdie 435
    {
6302 dpurdie 436
        if ( m/^--Arch(.*)=(.+)/ ) {
437
            $arch=$2;
438
        } elsif ( m/^--Prod/ ) {
439
            @type = 'P';
440
        } elsif ( m/^--Debug/ ) {
441
            @type = 'D';
442
        } else {
443
            Warning ('--Apk: Unknown Option: ' . $_);
1119 dpurdie 444
        }
6302 dpurdie 445
    }
1119 dpurdie 446
 
6302 dpurdie 447
    #
448
    #   Scan all packages for the specified APK package
449
    #   Try:
450
    #       Raw name - for apks from the SDK or 3rd parties
451
    #       PLATFORM(P|D)/baseName-(release|debug) - Expected
452
    #       baseName-(release|debug) - Repackaged badly
6306 dpurdie 453
    # 
454
    foreach my $pkgEntry ( getPackageList() )
6302 dpurdie 455
    {
6306 dpurdie 456
        next if ($pkgEntry->getType() eq 'interface');
457
        my $pkgVersion = $pkgEntry->getVersion();
458
 
459
        my $pkgLocal = $pkgEntry->getBase(2);
460
        my $pkgRoot = $pkgEntry->getDir();
1119 dpurdie 461
 
6306 dpurdie 462
        #
463
        #   Helper function
464
        #   Uses closure
465
        #   Notes: Test the package in dpkg_archive so that we can retain the package-version
466
        #          Use the version in the interface directory if BuildPkgArchive
467
        #   $pkgLocal - Local base of the package. May in the interface directory
468
        #   $pkgRoot  - Directory in dpkg_achive. Will have version info
469
        #   $subdir   - subdir within the package
470
        #   $fname    - File to look for
471
        #   
472
        #   Returns: Nothing
473
        #   Maintains: apk_file_path. Tupple: filename, PackageVersion
474
        #
475
        my $testOneFile = sub {
476
            my ( $subdir, $fname) = @_;
477
            my $testFile = "$pkgRoot/$subdir";
478
            $testFile =~ s~//~/~g;
479
            $testFile =~ s~/$~~;
480
            UniquePush(\@searchPath, $testFile);
481
            return unless (-d $testFile);
6302 dpurdie 482
 
6306 dpurdie 483
            $testFile .= '/' . $fname;
484
            if (-f $testFile ) {
485
                if ($pkgLocal ne $pkgRoot) {
486
                    my $testFile2 = "$pkgLocal/$subdir/$fname";
487
                    $testFile2 =~ s~//~/~g;
488
                    if ( -f $testFile2 ) {
489
                        $testFile = $testFile2;
490
                    }
491
                }
492
 
493
             $testFile = join($;, $testFile, $pkgVersion);
494
             push @apk_file_path, $testFile;
495
            }
496
        };
497
 
498
        #
499
        #   Test for the specified file in the package root
500
        #
501
        $testOneFile->("", "${base_name}.apk");
502
 
503
        #
504
        #   Test for BIN/PLATFORM
505
        #   
6302 dpurdie 506
        foreach my $type ( @type )
1119 dpurdie 507
        {
6302 dpurdie 508
            my $typeSuffix = $type{$type};
6306 dpurdie 509
            foreach my $joiner ( qw(/ .) ) {
510
                $testOneFile->("bin$joiner$arch$type","${base_name}${typeSuffix}.apk");
1119 dpurdie 511
            }
512
        }
6306 dpurdie 513
 
6302 dpurdie 514
        foreach my $type ( @type )
515
        {
516
            my $typeSuffix = $type{$type};
6306 dpurdie 517
            $testOneFile->("","${base_name}${typeSuffix}.apk");
6302 dpurdie 518
        }
6306 dpurdie 519
        $package_dirs{$pkgRoot}{used} = 1 if (@apk_file_path) ;
1119 dpurdie 520
    }
1129 dpurdie 521
 
6306 dpurdie 522
    #
523
    #   Keep user informed
524
    #   Report errors and provide useful information
525
    #
526
    if (IsVerbose(1) || IsDebug(1) || $#apk_file_path != 0)
527
    {
528
        Message ("Search for ($base_name). In search Path", @searchPath);
529
    }
530
 
6302 dpurdie 531
    ReportError ("Required APK package not found: $base_name") unless @apk_file_path;
532
    ReportError ("Multiple matching APK Packages located: $base_name", @apk_file_path ) if ( $#apk_file_path > 0 );
6306 dpurdie 533
 
534
#DebugDumpData("apk_file_path", \@apk_file_path);
6302 dpurdie 535
    return $apk_file_path[0];
536
}
537
 
538
#-------------------------------------------------------------------------------
539
# Function        : _LocateMugDir
540
#
541
# Description     : Locate the directory containing the mugfiles
542
#                   Internal Function
543
#
544
# Inputs          : Mufile package, with embedded options
545
#
546
# Returns         : Full path
547
#
548
sub _LocateMugDir
549
{
550
    my ($mug_package) = @_;
551
 
1129 dpurdie 552
    #
6302 dpurdie 553
    #   Locate the mugfile subdir
1129 dpurdie 554
    #
6302 dpurdie 555
    my $package_name = $mug_package;
556
    my @dirs = 'mug';
557
    my $mug_dir;
558
 
1129 dpurdie 559
    #
6302 dpurdie 560
    #   Extract sub options
561
    #       --Subdir=xxxx,yyyy,zzzz
1129 dpurdie 562
    #
6302 dpurdie 563
    if ( $package_name =~ m/(.*?),--Subdir=(.*)/ )
1129 dpurdie 564
    {
6302 dpurdie 565
        $package_name = $1;
566
        @dirs = split( ',', $2 );
567
    }
1129 dpurdie 568
 
6302 dpurdie 569
    my $package = GetPackageEntry( $package_name );
570
    unless ( $package )
571
    {
572
        ReportError ("ManifestFiles: Package not known to build: $package_name");
573
        return undef;
574
    }
1129 dpurdie 575
 
6302 dpurdie 576
    foreach my $subdir ( @dirs )
577
    {
578
        my $dir = "$package->{'ROOT'}/$subdir";
579
        if ( -d $dir )
1129 dpurdie 580
        {
6302 dpurdie 581
            Warning ("Multiple Mugfile directories located. Only the first will be used",
582
                     "Ignoring: $subdir" )if ( $mug_dir );
583
            $mug_dir = $dir;
584
        }
585
    }
586
    ReportError ("Mugfile directory not found in package: $package_name")
587
        unless $mug_dir;
5105 dpurdie 588
 
6302 dpurdie 589
    return $mug_dir;
590
}
5105 dpurdie 591
 
1129 dpurdie 592
 
6302 dpurdie 593
#-------------------------------------------------------------------------------
594
# Function        : _ImportManifest
595
#
596
# Description     : Import an existing manifest
597
#
598
# Inputs          : Args    - PackageName[,Subdir=name,--ReWrite]
599
#                   tier    - May be null
600
#                   name    - May be null
601
#
602
# Returns         : A hash of data to be used later
603
#
604
sub _ImportManifest
605
{
606
    my ($args, $tier, $name) = @_;
607
    my @file_contents;
6364 dpurdie 608
    my @item_list;
1129 dpurdie 609
 
6302 dpurdie 610
    #
611
    #   Locate the mugfile subdir
612
    #
613
    my $package_name = $args;
614
    my @dirs = 'mug';
615
    my $pkg_dir;
616
    my $pkg_root;
617
    my $manifest;
618
    my $first_tier;
619
    my $first_name;
620
    my $rewrite;
621
 
622
    #
623
    #   Extract sub options
624
    #       --Subdir=xxxx,yyyy,zzzz
625
    #       --ReWrite
626
    #
627
    if ( $package_name =~ m/(.*?)(,.*)/ )
628
    {
629
        $package_name = $1;
630
        my @subargs = split(',--', $2);
631
        foreach ( @subargs)
5105 dpurdie 632
        {
6302 dpurdie 633
            next unless (length($_) > 0);
634
            if (m~^Subdir=(.*)~i){
635
                @dirs = split( ',', $1 );
5105 dpurdie 636
 
6302 dpurdie 637
            } elsif (m~^ReWrite~i) {
638
                $rewrite = 1;
639
 
640
            } else {
641
                ReportError("ManifestFiles: Unknown suboption to ImportManifest:" . $_);
1129 dpurdie 642
            }
643
        }
6302 dpurdie 644
    }
1129 dpurdie 645
 
6302 dpurdie 646
    my $package = GetPackageEntry( $package_name );
647
    unless ( $package )
648
    {
649
        ReportError ("ManifestFiles: Package not known to build: $package_name");
650
        return undef;
651
    }
5105 dpurdie 652
 
6302 dpurdie 653
    if (defined ($rewrite) && ( !defined($tier) || !defined($name)))
654
    {
655
        ReportError ("ManifestFiles: ImportManifest. --ReWrite cannot be used unless tier and name are specified");
656
        return undef;
657
    }
1129 dpurdie 658
 
6302 dpurdie 659
    foreach my $subdir ( @dirs )
660
    {
661
        my $dir = "$package->{'ROOT'}/$subdir";
662
        my $root = $package->{'ROOT'};
663
        if ( -d $dir )
5105 dpurdie 664
        {
6302 dpurdie 665
            Warning ("Multiple Package directories located. Only the first will be used",
666
                     "Ignoring: $subdir" )if ( $pkg_dir );
667
            $pkg_dir = $dir;
668
            $pkg_root = $root;
5105 dpurdie 669
        }
6302 dpurdie 670
    }
1129 dpurdie 671
 
6302 dpurdie 672
    unless ($pkg_dir)
673
    {
674
        ReportError ("Package directory not found in package: $package_name");
675
        return undef;
676
    }
5105 dpurdie 677
 
6302 dpurdie 678
    #
679
    #   Determine Manifest File name
680
    #
681
    foreach my $file ( glob ($pkg_dir . '/Manifest*' ) )
682
    {
683
            next unless ( -f $file );
684
            Warning ("Multiple Manifest Files find. Only the first will be used",
685
                     "Using: $manifest",
686
                     "Ignoring: $file" ) if ( $manifest );
687
            $manifest = $file;
688
    }
689
 
690
    unless ($manifest)
691
    {
692
        ReportError ("ImportManifest. No Manifest found: $package_name");
693
        return undef;
694
    }
695
 
696
 
697
    #
698
    #
699
    #
700
    open (MF, '<', $manifest ) || Error ("Cannot open the Manifest file: $manifest", $!);
701
    while ( <MF> )
702
    {
1129 dpurdie 703
        #
6302 dpurdie 704
        #   Clean trailing whitespace ( line-feed and new lines )
705
        #   Comment out [Version] data
1129 dpurdie 706
        #
6302 dpurdie 707
        s~\s+$~~;
708
        s~(\s*\[Version])~#$1~;
709
 
5649 dpurdie 710
        #
6302 dpurdie 711
        #   Part lines and determine files
712
        #
713
        next unless ( $_ );
6364 dpurdie 714
        if (( m~\s*#~ ) || ( m~\s*\[~ )) {
715
            push @item_list, { 'comment' => $_ };
716
            next;
717
        }
718
        my( $aname, $atier, $afile, @additionnal_info) = split(/\s*\,\s*/, $_);
1129 dpurdie 719
#            print "---------- $_\n";
720
#            print "T: $atier, N:$aname, F:$afile\n";
6364 dpurdie 721
        my $file =  { 'file_name' => $afile
722
                    , 'file_info' => \@additionnal_info
723
                    };
724
        push @item_list, $file;
1129 dpurdie 725
 
6302 dpurdie 726
        #
727
        #   Rewrite the name and tier
728
        #
729
        if ($rewrite)
730
        {
731
            $_ = join(',', $name, $tier, $afile);
732
            $first_tier = $tier;
733
            $first_name = $name;
734
        }
735
        else
736
        {
1129 dpurdie 737
            #
6302 dpurdie 738
            #   Capture first tier and name
1129 dpurdie 739
            #
6302 dpurdie 740
            $first_tier = $atier unless ( defined $first_tier );
741
            $first_name = $aname unless ( defined $first_name );
1129 dpurdie 742
        }
6302 dpurdie 743
    }
744
    continue
745
    {
746
        push @file_contents, $_;
747
    }
748
    close MF;
1129 dpurdie 749
 
6302 dpurdie 750
    #
751
    #   Create a hash of data that describes the manifest that has
752
    #   just been read in.
753
    #
754
    $package_dirs{$pkg_root}{used} = 1;
755
    $manifest =~ s~.*/~~;
756
    return { 'contents' => \@file_contents,
6364 dpurdie 757
              'items' => \@item_list,
6302 dpurdie 758
              'file_base' => $pkg_dir,
759
              'manifest' => $manifest,
760
              'pkg_dir' => $pkg_root,
761
              'tier' => $first_tier,
762
              'name' => $first_name,
763
              'rewrite' => $rewrite,
764
            };
1119 dpurdie 765
}
766
 
767
#-------------------------------------------------------------------------------
768
# Function        : ManifestFiles_Generate
769
#
770
# Description     : Internal Function
771
#                   Process all the collected data and create directives
772
#                   for the creation of the manifest
773
#
774
#                   This function will be called, just before the Makefile
775
#                   is created. The function will:
776
#                       1) Create the Manifest File
777
#                       2) Package the Manifest File
778
#                       3) Package the manifest file contents
779
#
780
#                   using (mostly) normal makefile.pl directives.
781
#
782
# Inputs          : None
783
#
784
# Returns         : Nothing
785
#
786
sub ManifestFiles_Generate
787
{
788
    Debug ("ManifestFiles_Generate");
789
    Message ("Generating Manifest File");
1123 dpurdie 790
 
791
    #
792
    #   Need at least one Manifest Entry
793
    #
794
    return unless ( @Manifests );
1119 dpurdie 795
#DebugDumpData ( "Manifests", \@Manifests );
796
 
797
    #
1125 alewis 798
    #   Determine the target packaging directory
799
    #   Default is .../mug
800
    #
801
    my $pkgdir = 'mug';
1129 dpurdie 802
    if ( exists $Manifests[0]->{pkgsubdir} && defined $Manifests[0]->{pkgsubdir} )
1125 alewis 803
    {
804
        my $subdir = $Manifests[0]->{pkgsubdir};
805
        $pkgdir .= '/' . $subdir;
806
        $pkgdir =~ s~^mug/mug~mug~;
807
    }
808
 
809
    #
1119 dpurdie 810
    #   Create the Manifest File as we process the lists
1125 alewis 811
    #   Place this in the 'lib' directory:
1119 dpurdie 812
    #       - So that it will be deleted on clobber
1123 dpurdie 813
    #       - So that it can be placed in a target-specific subdir
1125 alewis 814
    #       - So that we can have one per makefile.pl
1119 dpurdie 815
    #
816
    Error ("ManifestFiles: Needs local directory specified in build.pl") unless ( $::ScmLocal );
817
 
1125 alewis 818
    my $manifest_dir = "$::ScmPlatform.LIB";
1119 dpurdie 819
    System( "$::GBE_BIN/mkdir -p $manifest_dir" );
820
 
1125 alewis 821
    my $manifest_file = $manifest_dir . '/Manifest';
822
    $manifest_file .= '_' . $::ScmBuildVersion if ( $Manifest_has_version );
823
    ToolsetGenerate( $manifest_file );
1119 dpurdie 824
    Verbose ("ManifestFiles_Generate: File: $manifest_file");
5649 dpurdie 825
 
1125 alewis 826
    PackageFile ('*', $manifest_file, '--Subdir=' . $pkgdir, '--Strip' );
1119 dpurdie 827
 
828
    open (MF, '>', $manifest_file ) || Error ("Cannot create the Manifest file: $manifest_file");
829
 
5711 kspencer 830
    binmode (MF);
5767 alewis 831
 
6364 dpurdie 832
    if ($Manifests[0]->{is_sub_manifest} == 1) {
833
        print_mf ("# Package $::ScmBuildPackage $::ScmBuildVersion built: $::CurrentTime");
834
    } else {
835
        print_mf ("# PackageName: $::ScmBuildPackage");
836
        print_mf ("# PackageVersion: $::ScmBuildVersion");
837
        print_mf ("# BuildDate: $::CurrentTime");
838
        print_mf ("#");
839
        print_mf ("[Version],$::ScmBuildVersion");
840
        print_mf ("#");
841
    }
1119 dpurdie 842
 
843
    #
1125 alewis 844
    #   Process each tier in the order presented in the source file
1119 dpurdie 845
    #
1123 dpurdie 846
    my $last_was_comment = 0;
1119 dpurdie 847
    foreach my $entry ( @Manifests )
848
    {
849
 
850
#DebugDumpData ( "Manifest Entry", $entry );
851
 
852
        my $tier = $entry->{tier};
853
        my $name = $entry->{name};
5649 dpurdie 854
        my $include_md5 = $entry->{md5};
1119 dpurdie 855
 
5767 alewis 856
        if ( $entry->{dmf} )
857
        {
6302 dpurdie 858
            DmfGenerate($entry);
5767 alewis 859
        }
860
 
1119 dpurdie 861
        #
862
        #   Insert all the files that have been specified
863
        #   The user specified order is preserved
864
        #
1123 dpurdie 865
        #   Entries may be either a file or a comment
866
        #   Comments: Merge multiple comments and create blocks
867
        #
868
        #
1119 dpurdie 869
        my @files = @{ $entry->{files} };
1123 dpurdie 870
        foreach my $fentry ( @files )
1119 dpurdie 871
        {
1123 dpurdie 872
            if ( my $cmt = $fentry->{'cmt'} )
873
            {
874
                print_mf ('') unless ( $last_was_comment ) ;
875
                print_mf ( map (('# ' . $_) , split ("\n", $cmt) ));
876
                $last_was_comment = 1;
877
                next;
878
            }
879
 
880
            print_mf ('#') if ( $last_was_comment );
881
            if ( my $file = $fentry->{'file'} )
882
            {
883
                my $base_file = StripDir( $file );
6314 dpurdie 884
                my @items = ($name, $tier, $base_file);
5649 dpurdie 885
                if ($include_md5) {
886
                    my $md5 = digest_file_hex($file, 'MD5');
6314 dpurdie 887
                    push @items, "MD5=$md5" ;
6306 dpurdie 888
                }
889
                if (exists $entry->{fileVersions} && exists $entry->{fileVersions}{$file} ) {
6314 dpurdie 890
                    push @items, "VERSION=" . $entry->{fileVersions}{$file};
6306 dpurdie 891
                }
6314 dpurdie 892
                print_mf (join (',', @items));
1125 alewis 893
                PackageFile ('*', $file, '--Subdir=' . $pkgdir, '--Strip' );
1123 dpurdie 894
                $last_was_comment = 0;
895
            }
1125 alewis 896
 
897
            if ( my $file = $fentry->{'filenocopy'} )
898
            {
899
                print_mf ("$name,$tier,$file");
900
                $last_was_comment = 0;
901
            }
1129 dpurdie 902
 
903
            if ( my $emf = $fentry->{'manifest'} )
904
            {
905
                $last_was_comment = 0;
906
                #
907
                #   Insert the entire manifest
908
                #   Items are:
909
                #        contents
6364 dpurdie 910
                #        items:
911
                #               file_name + arrays of file_info
912
                #           or  comment line to copy
1129 dpurdie 913
                #        file_base
914
                #        manifest
915
                #
916
#DebugDumpData ( "Embedded Manifest Entry", $emf );
6364 dpurdie 917
                if ($emf->{'rewrite'}) {
918
                    foreach my $item ( @{$emf->{'items'}}) {
919
                        if (defined($item->{'file_name'}))
920
                        {
921
                            my @items = ($name, $tier, $item->{'file_name'});
922
                            my $md5_added = 0;
923
                            foreach my $info (@{$item->{'file_info'}}) {
924
                                push @items, $info;
925
                                $md5_added = 1 if ($info =~ m~^MD5=~i);
926
                            }
927
                            if ($include_md5 && $md5_added == 0) { # add md5 if requested and not already added from submanifest
928
                                my $md5 = digest_file_hex($emf->{'file_base'} . '/' . $item->{'file_name'}, 'MD5');
929
                                push @items, "MD5=$md5";
930
                            }
931
                            print_mf (join (',', @items));
932
                            PackageFile ('*', $emf->{'file_base'}. '/' . $item->{'file_name'}, '--Subdir=' . $pkgdir, '--Strip' );
933
                        }
934
                        elsif (defined($item->{'comment'})) {
935
                            print_mf($item->{'comment'});
936
                        }
937
                    }
938
                    print_mf('#');
939
                }
940
                else {
941
                    print_mf ($_) foreach  ( @{$emf->{'contents'}} );
942
                    foreach my $item ( @{$emf->{'items'}}) {
943
                        PackageFile ('*', $emf->{'file_base'}. '/' . $item->{'file_name'}, '--Subdir=' . $pkgdir, '--Strip' )
944
                            if (defined($item->{'file_name'}));
945
                    }
946
                    print_mf('#');
947
                }
1129 dpurdie 948
            }
1119 dpurdie 949
        }
950
 
951
        #
952
        #   Expand out the entire MUG directory
953
        #   All .mug files in the MUG directory will be added to the manifest
954
        #   The assumption is that the MUG directory has been created by
955
        #   something that knows what its doing
956
        #
957
        if ( my $mugdir = $entry->{mugdir} )
958
        {
959
            foreach my $file ( glob ($mugdir . '/*.mug' ) )
960
            {
961
                next unless ( -f $file );
962
                my $base_file = StripDir($file);
6314 dpurdie 963
 
964
                my @items = ($name, $tier, $base_file);
965
 
5654 dpurdie 966
                if ($include_md5) {
967
                    my $md5 = digest_file_hex($file, 'MD5');
6314 dpurdie 968
                    push @items, "MD5=$md5" ;
5654 dpurdie 969
                }
6314 dpurdie 970
                print_mf (join (',', @items));
1119 dpurdie 971
                PackageFile ('*', $file, '--Subdir=mug', '--Strip' );
972
            }
973
        }
974
    }
975
 
976
    #
977
    #   Complete the creation of the Manifest File
978
    #
6364 dpurdie 979
    print_mf ("# end of $::ScmBuildPackage");
1119 dpurdie 980
    close MF;
981
    ErrorDoExit();
1121 dpurdie 982
 
983
    #
984
    #   Sanity test of packages that did not provide a debian file
985
    #   Just a hint that something may have been missed
986
    #
987
    my @not_used_packages;
988
    foreach my $package_dir ( getPackagePaths ('--All') )
989
    {
990
        next if ( $package_dir =~ m~/manifest-tool/~ );
991
        unless ( exists $package_dirs{$package_dir}{used} )
992
        {
993
            push @not_used_packages, $package_dir;
994
        }
995
    }
996
    if ( @not_used_packages )
997
    {
998
        Warning ("Packages that did not contribute packages to the manifest:",
999
                  @not_used_packages );
1000
    }
1001
 
1119 dpurdie 1002
    return;
1003
 
1004
    #-------------------------------------------------------------------------------
1005
    # Function        : print_mf
1006
    #
1007
    # Description     : Internal Function
1008
    #                   Print one line to the Manifest File
1009
    #                   Checks the length of the line being created
1010
    #
1011
    # Inputs          : $line
1012
    #
5649 dpurdie 1013
    # Returns         :
1119 dpurdie 1014
    #
1015
 
1016
    sub print_mf
1017
    {
1018
        foreach  ( @_ )
1019
        {
6314 dpurdie 1020
            my $ll = length ($_);
1021
            ReportError ( "Manifest line too long: $ll. Max is $ManifestLineWidth.",
1022
                    "Line: $_" ) if ( $ManifestLineWidth && $ll > $ManifestLineWidth);
1119 dpurdie 1023
            print MF $_ . "\n";
1024
        }
1025
    }
1026
}
1027
 
5767 alewis 1028
# Bring in the DMF build requirements.
1029
my $directory;
1030
BEGIN {
1031
    use File::Spec::Functions qw(rel2abs);
1032
    use File::Basename qw(dirname);
1033
 
1034
    my $path = rel2abs( __FILE__ );
1035
    $directory = dirname( $path );
1036
}
1037
use lib $directory;
1038
 
1039
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
1040
use JSON;
1041
 
1042
#-------------------------------------------------------------------------------
1043
# Function        : DmfGenerate
1044
#
1045
# Description     : Import an existing manifest
1046
#
1047
# Inputs          : entry   - The manifest that is being processed.
1048
#
1049
# Returns         : Nothing
1050
#
1051
sub DmfGenerate
1052
{
1053
    my ($entry) = @_;
1054
 
1055
    # Get the generation time.
1056
    my $gen_time = time();
1057
 
1058
    my $work_dir = "$::ScmPlatform.BIN/";
1059
    System( "$::GBE_BIN/mkdir -p $work_dir" );
1060
 
1061
    my $name = $entry->{name};
1062
    my $version = $entry->{dmf_version};
1063
 
1064
    # Configure base manifest information.
1065
    my %manifest;
5771 alewis 1066
    $manifest{'mugsetId'} = $name . '_' . $version;
5767 alewis 1067
    $manifest{'name'} = $name;
1068
    $manifest{'version'} = $version;
5771 alewis 1069
    $manifest{'packageName'} = $::ScmBuildPackage;
1070
    $manifest{'packageVersion'} = $::ScmBuildVersionFull;
5767 alewis 1071
    $manifest{'datetime'} = localtime($gen_time);
1072
    $gen_time *= 1000;  # Make to milliseconds
1073
    $manifest{'timestamp'} = $gen_time;
1074
    $manifest{'tier'} = $entry->{tier};
1075
 
1076
    # Process each file.
1077
    my @files = @{ $entry->{files} };
1078
    my $zip = Archive::Zip->new();
1079
    my $i = 0;
1080
    foreach my $fentry ( @files )
1081
    {
1082
        if ( my $file = $fentry->{'file'} )
1083
        {
6302 dpurdie 1084
            my $order = $i + 1;
5767 alewis 1085
            my $base_file = StripDir( $file );
1086
            my $publish_file = $name . '_' . $version . '_' . $order . '.aup';
1087
            my $aup_file = $work_dir . $publish_file;
1088
 
1089
            GenerateCesFile($file, $aup_file, 0x3, $gen_time, $publish_file);
1090
 
1091
            my $file_member = $zip->addFile( $aup_file, $publish_file );
1092
 
1093
            $manifest{'tasks'}[$i]{'order'} = 1 * $order;
1094
            $manifest{'tasks'}[$i]{'filename'} = $base_file;
1095
            $manifest{'tasks'}[$i]{'download'} = $publish_file;
5771 alewis 1096
            $manifest{'tasks'}[$i]{'sha256'} = digest_file_base64($file, 'SHA-256');
1097
            $manifest{'tasks'}[$i]{'size'} = -s $file;
1098
 
5767 alewis 1099
            if ($base_file =~ /\.sh$/)
1100
            {
1101
                $manifest{'tasks'}[$i]{'action'} = 'exec-shell';
1102
            }
1103
            elsif ($base_file =~ /\.deb$/)
1104
            {
1105
                $manifest{'tasks'}[$i]{'action'} = 'dpkg-install';
5771 alewis 1106
 
1107
                my ($pkg_name, $pkg_version, $pkg_arch) = ($base_file =~ /([^_]*)_([^_]*)_(.*)/);
1108
                $manifest{'tasks'}[$i]{'arch'} = $pkg_arch;
1109
                $manifest{'tasks'}[$i]{'name'} = $pkg_name;
1110
                $manifest{'tasks'}[$i]{'version'} = $pkg_version;
5767 alewis 1111
            }
1112
            else
1113
            {
1114
                ReportError ("Manifest entry $base_file does not have a supported DMF install action");
1115
            }
1116
 
1117
            $i = $i + 1;
1118
        }
1119
    }
1120
 
1121
    # Encode and commit the JSON.
1122
    my $json_encoder = JSON->new->allow_nonref;
1123
    my $json = $json_encoder->pretty->encode( \%manifest );
1124
 
1125
    my $manifest_filename = $name . '_' . $version;
1126
    my $aum_filename = $manifest_filename . '_0.aum';
1127
    my $manifest_file = $work_dir . $manifest_filename . '.json';
1128
    my $aum_file = $work_dir . $aum_filename;
1129
 
1130
    # Save our manifest.
1131
    open (J, '>', $manifest_file ) || Error ("Cannot create the DMF Manifest file");
1132
    binmode (J);
1133
    print J $json;
1134
 
1135
    close J;
1136
 
1137
    GenerateCesFile($manifest_file, $aum_file, 0x2, $gen_time, $aum_filename);
1138
 
1139
    $zip->addFile($aum_file, $aum_filename);
1140
 
1141
    my $zip_filename = $work_dir . $name . '_' . $version . '.zip';
1142
    if ( $zip->writeToFileNamed($zip_filename) != AZ_OK )
1143
    {
1144
        ReportError("DMF ZIP file creation failed");
1145
    }
1146
    PackageFile('*', $zip_filename, '--Strip');
1147
    PackageFile('*', $manifest_file, '--Strip');
1148
 
1149
}
1150
 
1151
#-------------------------------------------------------------------------------
1152
# Function        : DmfGenerate
1153
#
1154
# Description     : Import an existing manifest
1155
#
1156
# Inputs          : src_file     - The input file.
1157
#                   dst_file     - The output CES file.
1158
#                   content_type - The content type to report.
1159
#                   gen_time     - The generation time for the file.
1160
#                   filename     - The filename to embed in the CES file.
1161
#
1162
#
1163
# Returns         : Nothing
1164
#
1165
sub GenerateCesFile
1166
{
1167
    my ($src_file, $dst_file, $content_type, $gen_time, $filename) = @_;
1168
 
1169
    open (INF, '<', $src_file ) || Error ("Cannot open file $src_file for reading");
1170
    binmode (INF);
1171
 
1172
    open (OUTF, '>', $dst_file ) || Error ("Cannot open file $dst_file for writing");
1173
    binmode (OUTF);
1174
 
1175
    my $signing_key_name = "";
1176
    my $signature_size = 0;
1177
    my $format_version = 0xCE500000;
1178
    my $compression_method = 0;
1179
    my $encryption_method = 0;
1180
    my $kek_name = "";
1181
    my $encryption_key_size = 0;
1182
    my $filename_size = length($filename);
1183
 
1184
    print OUTF pack("Z32", $signing_key_name);
1185
    print OUTF pack("n", $signature_size);
1186
    print OUTF pack("N", $format_version);
1187
    print OUTF pack("N", $content_type);
1188
    print OUTF pack("Q>", $gen_time);
1189
    print OUTF pack("N", $compression_method);
1190
    print OUTF pack("N", $encryption_method);
1191
    print OUTF pack("Z32", $kek_name);
1192
    print OUTF pack("n", $encryption_key_size);
1193
    print OUTF pack("n", $filename_size);
1194
    # Encryption key HERE
1195
    print OUTF pack("A$filename_size", $filename);
1196
 
1197
    my $buf;
1198
    while (read(INF,$buf,65536))
1199
    {
1200
        print OUTF $buf;
1201
    }
1202
    print OUTF $buf;
1203
    close INF;
1204
 
1205
    # Signature HERE
1206
 
1207
    # Finish with file.
1208
    close OUTF;
1209
}
1210
 
1119 dpurdie 1211
1;