Subversion Repositories DevTools

Rev

Rev 6099 | Rev 6535 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6099 Rev 6242
Line 1... Line 1...
1
########################################################################
1
########################################################################
2
# Copyright (C) 1998-2013 Vix Technology, All rights reserved
2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
3
#
3
#
4
# Module name   : DebianPackager.pl
4
# Module name   : DebianPackager.pl
5
# Module type   : Makefile system
5
# Module type   : Makefile system
6
# Compiler(s)   : Perl
6
# Compiler(s)   : Perl
7
# Environment(s): jats
7
# Environment(s): jats
8
#
8
#
9
# Description   : This program is invoked by the MakeDebianPackage
9
# Description   : This program is invoked by the MakeDebianPackage and MakeRpmPackage
10
#                 directive, that is a part of this package
10
#                 directive that is a part of this package
11
#
11
#
12
#                 The program will use a user-provided script in order
12
#                 The program will use a user-provided script in order
13
#                 to create a Debian Package.
13
#                 to create the output Package.
14
#
14
#
15
#                 The user script may call a number of directives in order to
15
#                 The user script may call a number of directives in order to
16
#                 construct an image of the package being installed.
16
#                 construct an image of the package being installed.
17
#
17
#
18
#                 The script specifies Debian configuration scaripts that
18
#                 The script specifies Debian/RPM configuration scripts that
19
#                 will be embedded in the package.
19
#                 will be embedded in the package.
20
#
20
#
21
#                 This program will:
21
#                 This program will:
22
#                   Construct a filesystem image under control of the directives
22
#                   Construct a filesystem image under control of the directives
23
#                   within the user script
23
#                   within the user script
24
#
24
#
25
#                   Massage the Debian control file
25
#                   Debian:
26
#
26
#                       Massage the Debian control file
27
#                   Create a Debian Package
27
#                       Create a Debian Package
28
#
28
#                       Transfer it to the users 'BIN' directory, where it is available to be packaged.
29
#                   Transfer it to the users 'BIN' directory, where it is
29
#                       
30
#                   available to be packaged.
30
#                   RedHat Package:    
31
#
31
#                       Generate rpmBuilder control files
32
#                 Summary of directives available to the user-script:
32
#                       Create the RPM image
33
#                       Message                 - Display progress text
33
#                       Transfer it to the users 'BIN' directory, where it is available to be packaged.
34
#                       AddInitScript           - Add an init script
34
#                   
35
#                       CatFile                 - Append to a file
35
#                   TarFile:
36
#                       ConvertFile             - Convert file(s) to Unix or Dos Text
36
#                       Tar Gzip the image
37
#                       CopyDir                 - Copy directory tree
37
#                       Transfer it to the users 'BIN' directory, where it is available to be packaged.
38
#                       CopyFile                - Copy a file
38
#
39
#                       CopyBinFile             - Copy an executable file
39
#                 Summary of directives available to the user-script:
40
#                       CopyLibFile             - Copy a library file
40
#                       Message                 - Display progress text
41
#                       CopyDebPackage          - Copy a Debian Package
41
#                       Verbose                 - Display progress text
42
#                       CreateDir               - Create a directory
42
#                       AddInitScript           - Add an init script
43
#                       DebianFiles             - Specify control and script files
43
#                       CatFile                 - Append to a file
44
#                       DebianControlFile       - Specify control and script files
44
#                       ConvertFile             - Convert file(s) to Unix or Dos Text
45
#                       DebianDepends           - Add Depends entry to control file
45
#                       CopyDir                 - Copy directory tree
46
#                       EchoFile                - Place text into a file
46
#                       CopyFile                - Copy a file
47
#                       MakeSymLink             - Create a symbolic link
47
#                       CopyBinFile             - Copy an executable file
48
#                       PackageDescription      - Specify the package description
48
#                       CopyLibFile             - Copy a library file
49
#                       ReplaceTags             - Replace Tags on target file
49
#                       CopyDebPackage          - Copy a Debian Package
50
#                       SetFilePerms            - Set file permissions
50
#                       CreateDir               - Create a directory
51
#                       SetVerbose              - Control progress display
51
#                       AllFiles                - Specify control and script files 
52
#                       IsProduct               - Flow control
52
#                       DebianFiles             - Specify control and script files (Debian Only)
53
#                       IsPlatform              - Flow control
53
#                       RpmFiles                - Specify control and script files (RPM Only)
54
#                       IsTarget                - Flow control
54
#                       AllControlFile          - Specify control and script files
55
#                       IsVariant               - Flow control
55
#                       DebianControlFile       - Specify control and script files (Debian Only)
56
#                       IsAlias                 - Flow control
56
#                       RpmControlFile          - Specify control and script files (RPM Only)
57
#
57
#                       AllDepends              - Add Depends entry to control file
58
#                 Thoughts for expansion:
58
#                       DebianDepends           - Add Depends entry to control file (Debian Only)
59
#                       SrcDir                  - Extend path for resolving local files
59
#                       RpmDepends              - Add Depends entry to control file (RPM Only)
60
#
60
#                       EchoFile                - Place text into a file
61
#                   Less used:
61
#                       MakeSymLink             - Create a symbolic link
62
#                        ExpandLinkFiles        - Expand .LINK files
62
#                       PackageDescription      - Specify the package description
63
#
63
#                       ReplaceTags             - Replace Tags on target file
64
#                   Internal Use:
64
#                       SetFilePerms            - Set file permissions
65
#                        FindFiles              - Find a file
65
#                       SetVerbose              - Control progress display
66
#                        ResolveFile            - Resolve a 'local' source file
66
#                       IsProduct               - Flow control
67
#                        chmodItem              - Set file or directory permissions
67
#                       IsPlatform              - Flow control
68
#                        
68
#                       IsTarget                - Flow control
69
#......................................................................#
69
#                       IsVariant               - Flow control
70
 
70
#                       IsAlias                 - Flow control
71
require 5.006_001;
71
#                       RpmSetDefAttr           - Specify default file properties (RPM Only)
72
use strict;
72
#                       RpmSetAttr              - Specify file properties (RPM Only)    
73
use warnings;
73
#                       SetBaseDir              - Sets base for installed files (RPM Hint for directory ownership)
74
 
74
#                       Section                 - Set current section
75
use Getopt::Long;
75
#                       PackageVersion          - Return the version of a named package
76
use File::Path;
76
#                       ExtractTar              - Extract a tar file into the target
77
use File::Copy;
77
#
78
use File::Find;
78
#                 Thoughts for expansion:
79
use JatsSystem;
79
#                       SrcDir                  - Extend path for resolving local files
80
use FileUtils;
80
#
81
use JatsError;
81
#                   Less used:
82
use JatsLocateFiles;
82
#                        ExpandLinkFiles        - Expand .LINK files
83
use ReadBuildConfig;
83
#
84
use JatsCopy ();                            # Don't import anything
84
#                   Internal Use:
85
 
85
#                        FindFiles              - Find a file
86
#
86
#                        ResolveFile            - Resolve a 'local' source file
87
#   Globals
87
#                        chmodItem              - Set file or directory permissions
88
#
88
#                        
89
my $DebianWorkDirBase;                      # Workspace
89
#......................................................................#
90
my $DebianWorkDir;                          # Dir to create file system image within
90
 
91
 
91
require 5.006_001;
92
#
92
use strict;
93
#   Command line options
93
use warnings;
94
#
94
 
95
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
95
use Getopt::Long;
96
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
96
use File::Path;
97
my $opt_vargs;                              # Verbose arg
97
use File::Copy;
98
my $opt_help = 0;
98
use File::Find;
99
my $opt_manual = 0;
99
use JatsSystem;
100
my $opt_clean = 0;
100
use FileUtils;
101
my $opt_interfacedir;
101
use ArrayHashUtils;
102
my $opt_package_script;
102
use JatsError;
103
my $opt_interfaceincdir;
103
use JatsLocateFiles;
104
my $opt_interfacelibdir;
104
use ReadBuildConfig;
105
my $opt_interfacebindir;
105
use JatsCopy ();                            # Don't import anything
106
my $opt_libdir;
106
use PackagerUtils;
107
my $opt_bindir;
107
 
108
my $opt_localincdir;
108
#
109
my $opt_locallibdir;
109
#   Command line options
110
my $opt_localbindir;
110
#
111
my $opt_pkgdir;
111
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
112
my $opt_pkglibdir;
112
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
113
my $opt_pkgbindir;
113
my $opt_vargs;                              # Verbose arg
114
my $opt_pkgpkgdir;
114
my $opt_help = 0;
115
my $opt_output;
115
my $opt_manual = 0;
116
my $opt_tarFile;
116
my $opt_clean = 0;
117
my $opt_noarch;
117
my $opt_interfacedir;
118
 
118
my $opt_package_script;
119
#
119
my $opt_interfaceincdir;
120
#   Options marked as 'our' so that they are visible within the users script
120
my $opt_interfacelibdir;
121
#   Don't give the user too much
121
my $opt_interfacebindir;
122
#
122
my $opt_libdir;
123
our $opt_platform;
123
my $opt_bindir;
124
our $opt_type;
124
my $opt_localincdir;
125
our $opt_buildname;
125
my $opt_locallibdir;
126
our $opt_buildversion;
126
my $opt_localbindir;
127
our $opt_target;
127
my $opt_pkgdir;
128
our $opt_product;
128
my $opt_pkglibdir;
129
our $opt_name;
129
my $opt_pkgbindir;
130
our $opt_variant;
130
my $opt_pkgpkgdir;
131
our $opt_pkgarch;
131
my $opt_noarch;
132
 
132
my $opt_tarFile;
133
#
133
my $opt_tarOnly;
134
#   Options derived from script directives
134
my $opt_rpm = 0;
135
#
135
my $opt_debian = 0;
136
my $opt_description;
136
my $opt_output;
137
 
137
 
138
#
138
#
139
#   Globals
139
#   Options marked as 'our' so that they are visible within the users script
140
#
140
#   Don't give the user too much
141
my @ResolveFileList;                    # Cached Package File List
141
#
142
my @ResolveBinFileList;                 # Cached PackageBin File List
142
our $opt_platform;
143
my @ResolveDebFileList;                 # Cached PackageDeb File List
143
our $opt_type;
144
my @ResolveLibFileList;                 # Cached PackageLib File List
144
our $opt_buildname;
145
my %DebianControlFiles;                 # Control Files
145
our $opt_buildversion;
146
my %DebianControlFileNames;             # Control Files by name
146
our $opt_target;
147
my @DependencyList;                     # Package Dependencies
147
our $opt_product;
148
my @ConfigList;                         # Config Files
148
our $opt_name;
149
my %opt_aliases;                        # Cached Alias Names
149
our $opt_variant;
150
 
150
our $opt_pkgarch;
151
#-------------------------------------------------------------------------------
151
our $opt_rpmRelease = '';
152
# Function        : Main Entry point
152
 
153
#
153
#
154
# Description     : This function will be called when the package is initialised
154
#   Options derived from script directives
155
#                   Extract arguments from the users environment
155
#
156
#
156
my $opt_description;
157
#                   Done here to greatly simplify the user script
157
my $opt_specFile;
158
#                   There should be no junk in the user script - keep it simple
158
 
159
#
159
#
160
# Inputs          :
160
#   Globals
161
#
161
#
162
# Returns         : 
162
my $WorkDirBase;                            # Workspace
163
#
163
my $WorkDirInit;                            # Initial Dir to create file system image within
164
main();
164
my $WorkDir;                                # Dir to create file system image within
165
sub main
165
my $WorkSubDir = '';                        # Diff between $WorkDirInit and $WorkDir
166
{
166
my @ResolveFileList;                        # Cached Package File List
167
    my $result = GetOptions (
167
my @ResolveBinFileList;                     # Cached PackageBin File List
168
                "verbose:s"         => \$opt_vargs,
168
my @ResolveDebFileList;                     # Cached PackageDeb File List
169
                "clean"             => \$opt_clean,
169
my @ResolveLibFileList;                     # Cached PackageLib File List
170
                "Type=s"            => \$opt_type,
170
my %ControlFiles;                           # Control Files
171
                "BuildName=s"       => \$opt_buildname,                     # Raw Jats Package Name (Do not use)
171
my %ControlFileNames;                       # Control Files by name
172
                "Name=s"            => \$opt_name,                          # Massaged Debian Package Name
172
my @DependencyList;                         # Package Dependencies
173
                "BuildVersion=s"    => \$opt_buildversion,
173
my @ConfigList;                             # Config Files
174
                "Platform=s"        => \$opt_platform,
174
my %opt_aliases;                            # Cached Alias Names
175
                "Target=s"          => \$opt_target,
175
my @RpmDefAttr = ('-','root','root','-');   # RPM: Default File Attributes
176
                "Product=s"         => \$opt_product,
176
my @RpmAttrList;                            # RPM: File attributes
177
                "DebianPackage=s"   => \$opt_package_script,
177
my %OwnedDirs;                              # RPM: Dirs marked as owned
178
                "InterfaceDir=s"    => \$opt_interfacedir,
178
my $ActiveSection = 1;                      # Indicates if the section is active
179
                "InterfaceIncDir=s" => \$opt_interfaceincdir,
179
 
180
                "InterfaceLibDir=s" => \$opt_interfacelibdir,
180
#-------------------------------------------------------------------------------
181
                "InterfaceBinDir=s" => \$opt_interfacebindir,
181
# Function        : Main Entry point
182
                "LibDir=s"          => \$opt_libdir,
182
#
183
                "BinDir=s"          => \$opt_bindir,
183
# Description     : This function will be called when the package is initialised
184
                "LocalIncDir=s"     => \$opt_localincdir,
184
#                   Extract arguments from the users environment
185
                "LocalLibDir=s"     => \$opt_locallibdir,
185
#
186
                "LocalBinDir=s"     => \$opt_localbindir,
186
#                   Done here to greatly simplify the user script
187
                "PackageDir=s"      => \$opt_pkgdir,
187
#                   There should be no junk in the user script - keep it simple
188
                "PackageLibDir=s"   => \$opt_pkglibdir,
188
#
189
                "PackageBinDir=s"   => \$opt_pkgbindir,
189
# Inputs          :
190
                "PackagePkgDir=s"   => \$opt_pkgpkgdir,
190
#
191
                "Output=s"          => \$opt_output,
191
# Returns         : 
192
                "tarFile=s"         => \$opt_tarFile,
192
#
193
                "Variant:s"         => \$opt_variant,
193
main();
194
                "PkgArch:s"         => \$opt_pkgarch,
194
sub main
195
                "NoArch"            => \$opt_noarch,
195
{
196
    );
196
    my $result = GetOptions (
197
    $opt_verbose++ unless ( $opt_vargs eq '@' );
197
                'verbose:s'         => \$opt_vargs,
198
 
198
                'clean'             => \$opt_clean,
199
    ErrorConfig( 'name'    => 'DebianUtils',
199
                'Type=s'            => \$opt_type,
200
                 'verbose' => $opt_verbose,
200
                'BuildName=s'       => \$opt_buildname,                     # Raw Jats Package Name (Do not use)
201
                 'debug'   => $opt_debug );
201
                'Name=s'            => \$opt_name,                          # Massaged Debian Package Name
202
 
202
                'BuildVersion=s'    => \$opt_buildversion,
203
    #
203
                'Platform=s'        => \$opt_platform,
204
    #   Init the FileSystem Uiltity interface
204
                'Target=s'          => \$opt_target,
205
    #
205
                'Product=s'         => \$opt_product,
206
    InitFileUtils();
206
                'InterfaceDir=s'    => \$opt_interfacedir,
207
 
207
                'InterfaceIncDir=s' => \$opt_interfaceincdir,
208
    #
208
                'InterfaceLibDir=s' => \$opt_interfacelibdir,
209
    #   Ensure that we have all required options
209
                'InterfaceBinDir=s' => \$opt_interfacebindir,
210
    #
210
                'LibDir=s'          => \$opt_libdir,
211
    Error ("Platform not set")                  unless ( $opt_platform );
211
                'BinDir=s'          => \$opt_bindir,
212
    Error ("Type not set")                      unless ( $opt_type );
212
                'LocalIncDir=s'     => \$opt_localincdir,
213
    Error ("BuildName not set")                 unless ( $opt_buildname );
213
                'LocalLibDir=s'     => \$opt_locallibdir,
214
    Error ("Debian Package Name not set")       unless ( $opt_name );
214
                'LocalBinDir=s'     => \$opt_localbindir,
215
    Error ("BuildVersion not set")              unless ( $opt_buildversion );
215
                'PackageDir=s'      => \$opt_pkgdir,
216
    Error ("InterfaceDir not set")              unless ( $opt_interfacedir );
216
                'PackageLibDir=s'   => \$opt_pkglibdir,
217
    Error ("Target not set")                    unless ( $opt_target );
217
                'PackageBinDir=s'   => \$opt_pkgbindir,
218
    Error ("Product not set")                   unless ( $opt_product );
218
                'PackagePkgDir=s'   => \$opt_pkgpkgdir,
219
    Error ("DebianPackage not set")             unless ( $opt_package_script );
219
                'Variant:s'         => \$opt_variant,
220
    Error ("Ouput File not set")                unless ( $opt_output );
220
                'PkgArch:s'         => \$opt_pkgarch,
221
 
221
                'NoArch'            => \$opt_noarch,
222
    #
222
                'tarFile=s'         => \$opt_tarFile,
223
    #   Read in relevent config information
223
                'tarOnly'           => \$opt_tarOnly,
224
    #
224
                'genRpm'            => \$opt_rpm,
225
    ReadBuildConfig ($opt_interfacedir, $opt_platform, '--NoTest' );
225
                'genDeb'            => \$opt_debian,
226
 
226
                'output=s'          => \$opt_output,
227
    #
227
                'script=s'          => \$opt_package_script,
228
    #   Build the package image in a directory based on the target being created
228
                'rpmRelease=s'      => \$opt_rpmRelease,
229
    #
229
    );
230
    $DebianWorkDirBase = uc("$opt_platform$opt_type.image");
230
    $opt_verbose++ unless ( $opt_vargs eq '@' );
231
    $DebianWorkDir = "$DebianWorkDirBase/$opt_name";
231
 
232
 
232
    ErrorConfig( 'name'    => 'PackagerUtils',
233
    #
233
                 'verbose' => $opt_verbose,
234
    #   Configure the System command to fail on any error
234
                 'debug'   => $opt_debug );
235
    #
235
 
236
    SystemConfig ( ExitOnError => 1 );
236
    #
237
 
237
    #   Init the FileSystem Uiltity interface
238
    #
238
    #
239
    #   Defaults
239
    InitFileUtils();
240
    #
240
 
241
    $opt_pkgarch = $opt_platform unless ( $opt_pkgarch );
241
    #
242
    $opt_pkgarch = 'all' if ( $opt_noarch );
242
    #   Ensure that we have all required options
243
 
243
    #
244
    #
244
    Error ("Platform not set")                  unless ( $opt_platform );
245
    #   Display variables used
245
    Error ("Type not set")                      unless ( $opt_type );
246
    #
246
    Error ("BuildName not set")                 unless ( $opt_buildname );
247
    Message    ("=Building Debian Package =============================================");
247
    Error ("Package Name not set")              unless ( $opt_name );
248
    Message    ("Build $opt_name");
248
    Error ("BuildVersion not set")              unless ( $opt_buildversion );
249
    Message    ("       Package: $opt_buildname");
249
    Error ("InterfaceDir not set")              unless ( $opt_interfacedir );
250
    Message    ("       Variant: $opt_variant") if ($opt_variant);
250
    Error ("Target not set")                    unless ( $opt_target );
251
    Message    ("       Version: $opt_buildversion");
251
    Error ("Product not set")                   unless ( $opt_product );
252
    Message    ("  Building for: $opt_platform, $opt_target");
252
    Error ("Packaging Script not set")          unless ( $opt_package_script );
253
    Message    ("       Product: $opt_product");
253
 
254
    Message    ("          Type: $opt_type");
254
    #
255
    Message    ("      Pkg Arch: $opt_pkgarch") if ($opt_pkgarch);
255
    #   Read in relevent config information
256
    Verbose    ("       Verbose: $opt_verbose");
256
    #
257
    Verbose    ("  InterfaceDir: $opt_interfacedir");
257
    ReadBuildConfig ($opt_interfacedir, $opt_platform, '--NoTest' );
258
    Message    ("       Package: " . StripDirExt($opt_output));
258
 
259
    Message    ("       TarFile: " . StripDirExt($opt_tarFile)) if ($opt_tarFile);
259
    #
260
    Message    ("======================================================================");
260
    #   Build the package image in a directory based on the target being created
261
 
261
    #
262
    #
262
    $WorkDirBase = uc("$opt_platform$opt_type.image");
263
    #   Perform Clean up
263
    $WorkDirInit = "$WorkDirBase/$opt_name";
264
    #   Invoked during "make clean" or "make clobber"
264
    $WorkDir = $WorkDirInit;
265
    #
265
 
266
    if ( $opt_clean )
266
    #
267
    {
267
    #   Configure the System command to fail on any error
268
        Message ("Remove packaging directory: $DebianWorkDir");
268
    #
269
 
269
    SystemConfig ( ExitOnError => 1 );
270
        #
270
 
271
        #   Remove the directory for this package
271
    #
272
        #   Remove the general work dir - if all packages have been cleaned
272
    #   Defaults
273
        #
273
    #
274
        rmtree( $DebianWorkDir );
274
    $opt_pkgarch = $opt_platform unless ( $opt_pkgarch );
275
        rmdir( $DebianWorkDirBase );
275
 
276
        rmtree ($opt_output) if ( -f $opt_output );
276
    #
277
        exit;
277
    #   Determine build operations
278
    }
278
    #   
279
 
279
    my $genDebian = $opt_debian;
280
    #
280
    my $genRpm = $opt_rpm;
281
    #   NoArch sanity test
281
    if ($opt_tarOnly) {
282
    #   MUST only build no-arch for production
282
        $genDebian = $genRpm = 0; 
283
    #   User MUST do this in the build.pl file
283
    }
284
    #
284
     
285
    if ($opt_noarch && $opt_type ne 'P')
285
 
286
    {
286
    #
287
        Error ("Debian Packages marked as NoArch (all) must be built ONLY for production",
287
    #   Display variables used
288
               "This must be configured in the build.pl" );
288
    #
289
    }
289
    Message    ("= Building Installer ================================================");
290
 
290
    Message    ("        Format: Debian") if ($genDebian);
291
    #
291
    Message    ("        Format: RPM") if ($genRpm);
292
    #   Clean  out the WORK directory
292
    Message    ("        Format: TGZ") if ($opt_tarFile);
293
    #   Always start with a clean slate
293
    Message    ("          Name: $opt_name");
294
    #
294
    Message    ("       Package: $opt_buildname");
295
    #   Ensure that the base of the directory tree does not have 'setgid'
295
    Message    ("       Variant: $opt_variant") if ($opt_variant);
296
    #       This will upset the debian packager
296
    Message    ("       Version: $opt_buildversion");
297
    #       This may be an artifact from the users directory and not expected
297
    Message    ("  Building for: $opt_platform");
298
    #
298
    Message    ("        Target: $opt_target") if ( $opt_platform ne $opt_target);
299
    rmtree( $DebianWorkDir );
299
    Message    ("       Product: $opt_product") if ($opt_product ne $opt_platform);
300
    mkpath( $DebianWorkDir );
300
    Message    ("          Type: $opt_type");
301
 
301
    Message    ("   RPM Release: $opt_rpmRelease") if ($opt_rpmRelease);
302
    my $perm = (stat $DebianWorkDir)[2] & 0777;
302
    Message    ("      Pkg Arch: $opt_pkgarch") if ($opt_pkgarch);
303
    chmod ( $perm & 0777, $DebianWorkDir );
303
    Verbose    ("       Verbose: $opt_verbose");
304
 
304
    Verbose    ("  InterfaceDir: $opt_interfacedir");
305
    #
305
    Message    ("        Output: " . StripDir($opt_output))  if ($genDebian || $genRpm);
306
    #   Invoke the user script to do the hard work
306
    Message    ("        Output: " . StripDir($opt_tarFile)) if $opt_tarFile;
307
    #
307
    Message    ("======================================================================");
308
    unless (my $return = do $opt_package_script) {
308
 
309
            Error ("Couldn't parse $opt_package_script: $@") if $@;
309
    #
310
            Error ("Couldn't do $opt_package_script: $!")    unless defined $return;
310
    #   Perform Clean up
311
        }
311
    #   Invoked during "make clean" or "make clobber"
312
 
312
    #
313
    #
313
    if ( $opt_clean )
314
    #   Complete the building of the package
314
    {
315
    #
315
        Message ("Remove packaging directory: $WorkDirInit");
316
    if ($opt_tarFile)
316
 
317
    {
317
        #
318
        BuildTarFile();
318
        #   Remove the directory for this package
319
        Message ("Created TGZ file");
319
        #   Remove the general work dir - if all packages have been cleaned
320
    }
320
        #
321
 
321
        rmtree( $WorkDirBase );
322
 
322
        rmtree ($opt_tarFile) if ( defined($opt_tarFile) && -f $opt_tarFile );
323
    BuildDebianPackage ();
323
        rmtree ($opt_output) if ( -f $opt_output );
324
    Message ("Created Debian Package");
324
        exit;
325
}
325
    }
326
 
326
 
327
#-------------------------------------------------------------------------------
327
    #
328
# Function        : BuildDebianPackage
328
    #   NoArch sanity test
329
#
329
    #       MUST only build no-arch for production
330
# Description     : This function will create the Debian Package
330
    #       User MUST do this in the build.pl file
331
#                   and transfer it to the target directory
331
    #
332
#
332
    if ($opt_noarch && $opt_type ne 'P')
333
# Inputs          : None
333
    {
334
#
334
        Error ("Installer Packages marked as NoArch (all) must be built ONLY for production",
335
# Returns         : Nothing
335
               "This must be configured in the build.pl" );
336
#
336
    }
337
sub BuildDebianPackage
337
 
338
{
338
    #
339
    Error ("BuildDebianPackage: No Control File or Package Description")
339
    #   Clean  out the WORK directory
340
        unless ( exists($DebianControlFiles{'control'}) || $opt_description );
340
    #   Always start with a clean slate
341
 
341
    #
342
    #
342
    #   Ensure that the base of the directory tree does not have 'setgid'
343
    #   Convert the FileSystem Image into a Debian Package
343
    #       This will upset the debian packager
344
    #       Insert Debian control files
344
    #       This may be an artifact from the users directory and not expected
345
    #
345
    #
346
    Verbose ("Copy in the Debian Control Files");
346
    rmtree( $WorkDirInit );
347
    mkdir ( "$DebianWorkDir/DEBIAN" );
347
    mkpath( $WorkDirInit );
348
 
348
 
349
    #
349
    my $perm = (stat $WorkDirInit)[2] & 0777;
350
    #   Copy in all the named Debian Control files
350
    chmod ( $perm & 0777, $WorkDirInit );
351
    #       Ignore any control file. It will be done next
351
 
352
    #
352
    #
353
    foreach my $key ( keys %DebianControlFiles )
353
    #   Invoke the user script to do the hard work
354
    {
354
    #       Use abs path to avoid issues:
355
        next if ($key eq 'control');
355
    #           * '.' not buing in search path
356
        CopyFile ( $DebianControlFiles{$key}, '/DEBIAN', $key  );
356
    #           * Script name = DebianPackager.pl
357
    }
357
    $opt_package_script = AbsPath($opt_package_script);
358
 
358
    unless (my $return = do $opt_package_script) {
359
    #
359
            Error ("Couldn't parse $opt_package_script: $@") if $@;
360
    #   Create 'conffiles'
360
            Error ("Couldn't do $opt_package_script: $!") unless defined $return;
361
    #       Append to any user provided file
361
        };
362
    if ( @ConfigList )
362
    $ActiveSection = 1;
363
    {
363
 
364
        my $conffiles = "$DebianWorkDir/DEBIAN/conffiles";
364
    #
365
        Warning("Appending user specified entries to conffiles") if ( -f $conffiles);
365
    #   Now have an image of the directory that we wish to package
366
        FileAppend( $conffiles, @ConfigList );
366
    #   Complete the building of the package
367
    }
367
    #
368
    
368
    if ($opt_tarFile) {
369
    #
369
        BuildTarFile();
370
    #   Massage the 'control' file
370
        Message ("Created TGZ file");
371
    #
371
    }
372
    UpdateControlFile ($DebianControlFiles{'control'} );
372
 
373
 
373
    #
374
    #
374
    #   Create an RPM
375
    #   Mark all files in the debian folder as read-execute
375
    #
376
    #
376
    if ($genRpm) {
377
    System ( 'chmod', '-R', 'a+rx', "$DebianWorkDir/DEBIAN" );
377
        BuildRPM ();
378
    System ( 'build_dpkg.sh', '-b', $DebianWorkDir);
378
        Message ("Created RPM");
379
    System ( 'mv', '-f', "$DebianWorkDir.deb", $opt_output );
379
    }
380
 
380
 
381
    System ("build_dpkg.sh", '-I', $opt_output) if (IsVerbose(1));
381
    #
382
 
382
    #   Create a Debian Package
383
}
383
    #
384
 
384
    if ($genDebian) {
385
#-------------------------------------------------------------------------------
385
        BuildDebianPackage ();
386
# Function        : BuildTarFile 
386
        Message ("Created Debian Package");
387
#
387
    }
388
# Description     : This function will create a TGZ file of the constructed package
388
}
389
#                   Not often used 
389
 
390
#
390
#-------------------------------------------------------------------------------
391
# Inputs          : None
391
# Function        : BuildRPM 
392
#
392
#
393
# Returns         : Nothing
393
# Description     : This function will create the Debian Package
394
#
394
#                   and transfer it to the target directory
395
sub BuildTarFile
395
#
396
{
396
# Inputs          : None
397
    Verbose ("Create TGZ file containing body of the package");
397
#
398
    System ('tar', 
398
# Returns         : Nothing
399
            '--create',
399
# 
400
            '--auto-compress',
400
sub BuildRPM
401
            '--owner=0' ,
401
{
402
            '--group=0' ,
402
    #
403
            '--one-file-system' ,
403
    #   Sanity Checks
404
            '--exclude=./DEBIAN' ,
404
    #
405
            '-C', $DebianWorkDir,  
405
    Error ("BuildRPM: Release")
406
            '--file', $opt_tarFile,
406
        unless ( $opt_rpmRelease );
407
            '.'
407
    Error ("BuildRPM: No Control File or Package Description")
408
            );
408
        unless ( exists($ControlFiles{'control'}) || $opt_description );
409
}
409
 
410
 
410
    #
411
 
411
    #   Massage the 'control' file
412
#-------------------------------------------------------------------------------
412
    #   Generate or Massage
413
# Function        : UpdateControlFile
413
    #
414
#
414
    $opt_specFile = catfile($WorkDirBase, 'RPM.spec' );
415
# Description     : Update the Debian 'control' file to fix up various fields
415
    UpdateRedHatControlFile ($ControlFiles{'control'} );
416
#                   within the file.
416
 
417
#
417
    #   Generate a dummy rc file
418
#                   If the files has not been specified, then a basic control
418
    my $rcFile = catdir($WorkDirBase,'tmprc');
419
#                   file will be provided.
419
    TouchFile($rcFile);
420
#
420
 
421
#                   This routine knows where the control file will be placed
421
    #
422
#                   within the output work space.
422
    #   Run the RPM builder
423
#
423
    #   Expect it to be installed on the build machine
424
# Inputs          : $src            - Path to source file
424
    #
425
#                   Uses global variables
425
    my $prog = LocateProgInPath( 'rpmbuild', '--All');
426
#
426
    Error ("RPM Packager: The rpmbuild utility is not installed") unless $prog;
427
# Returns         : Nothing
427
    System ($prog, '-bb', $opt_specFile, 
428
#
428
                   '--buildroot', AbsPath($WorkDirInit) ,
429
sub UpdateControlFile
429
                   '--define', '_rpmdir ' . StripFileExt($opt_output),
430
{
430
                   '--define', '_rpmfilename ' .  StripDir($opt_output),
431
    my($src) = @_;
431
                   '--define', '_topdir ' . catfile($WorkDirBase, 'RPMBUILD' ),
432
    my $dst = "$DebianWorkDir/DEBIAN/control";
432
                   '--noclean',
433
 
433
                   $opt_verbose ? '-v' : '--quiet',
434
    unless ( $src )
434
                   #$opt_noarch ?  '--target=noarch' : undef,
435
    {
435
                   '--rcfile', $rcFile ,
436
        CreateControlFile();
436
                   );
437
        return;
437
 
438
    }
438
 
439
 
439
}
440
    #
440
 
441
    #   User has provided a control file
441
#-------------------------------------------------------------------------------
442
    #       Tweak the internals
442
# Function        : BuildDebianPackage
443
    #
443
#
444
    Verbose ("UpdateControlFile: $dst" );
444
# Description     : This function will create the Debian Package
445
    $src = ResolveFile( 0, $src );
445
#                   and transfer it to the target directory
446
 
446
#
447
    #   Calc depends line
447
# Inputs          : None
448
    my $depData = join (', ', @DependencyList );
448
#
449
 
449
# Returns         : Nothing
450
    open (SF, '<', $src) || Error ("UpdateControlFile: Cannot open:$src, $!");
450
#
451
    open (DF, '>', $dst) || Error ("UpdateControlFile: Cannot create:$dst, $!");
451
sub BuildDebianPackage
452
    while ( <SF> )
452
{
453
    {
453
    Error ("BuildDebianPackage: No Control File or Package Description")
454
        s~\s*$~~;
454
        unless ( exists($ControlFiles{'control'}) || $opt_description );
455
        if ( m~^Package:~ ) {
455
 
456
            $_ = "Package: $opt_name";
456
    #
457
 
457
    #   Convert the FileSystem Image into a Debian Package
458
        } elsif ( m~^Version:~ ) {
458
    #       Insert Debian control files
459
            $_ = "Version: $opt_buildversion";
459
    #
460
 
460
    Verbose ("Copy in the Debian Control Files");
461
        } elsif ( m~^Architecture:~ ) {
461
    mkdir ( "$WorkDirInit/DEBIAN" );
462
            $_ = "Architecture: $opt_pkgarch";
462
 
463
 
463
    #
464
        } elsif ( $opt_description && m~^Description:~ ) {
464
    #   Copy in all the named Debian Control files
465
            $_ = "Description: $opt_description";
465
    #       Ignore any control file. It will be done next
466
 
466
    #
467
        } elsif ( m~^Depends:~ ) {
467
    foreach my $key ( keys %ControlFiles )
468
            $_ = "Depends: $depData";
468
    {
469
            $depData = '';
469
        next if ($key eq 'control');
470
        }
470
        CopyFile ( $ControlFiles{$key}, '/DEBIAN', $key  );
471
        print DF $_ , "\n";
471
    }
472
    }
472
 
473
 
473
    #
474
    close (SF);
474
    #   Create 'conffiles'
475
    close (DF);
475
    #       Append to any user provided file
476
 
476
    if ( @ConfigList )
477
    #
477
    {
478
    #   Warn if Depends section is needed
478
        my $conffiles = "$WorkDirInit/DEBIAN/conffiles";
479
    #
479
        Warning("Appending user specified entries to conffiles") if ( -f $conffiles);
480
    Error ("No Depends section seen in user control file") 
480
        FileAppend( $conffiles, @ConfigList );
481
        if ($depData);
481
    }
482
}
482
    
483
 
483
    #
484
#-------------------------------------------------------------------------------
484
    #   Massage the 'control' file
485
# Function        : CreateControlFile
485
    #
486
#
486
    UpdateDebianControlFile ($ControlFiles{'control'} );
487
# Description     : Craete a basic debian control file
487
 
488
#
488
    #
489
# Inputs          : Uses global variables
489
    #   Mark all files in the debian folder as read-execute
490
#
490
    #
491
# Returns         : 
491
    System ( 'chmod', '-R', 'a+rx', "$WorkDirInit/DEBIAN" );
492
#
492
    System ( 'build_dpkg.sh', '-b', $WorkDirInit);
493
sub CreateControlFile
493
    System ( 'mv', '-f', "$WorkDirInit.deb", $opt_output );
494
{
494
 
495
    my $dst = "$DebianWorkDir/DEBIAN/control";
495
    System ("build_dpkg.sh", '-I', $opt_output) if (IsVerbose(1));
496
 
496
 
497
    Verbose ("CreateControlFile: $dst" );
497
}
498
 
498
 
499
    my $depData = join (', ', @DependencyList );
499
#-------------------------------------------------------------------------------
500
 
500
# Function        : BuildTarFile 
501
    open (DF, '>', $dst) || Error ("CreateControlFile: Cannot create:$dst");
501
#
502
    print DF "Package: $opt_name\n";
502
# Description     : This function will create a TGZ file of the constructed package
503
    print DF "Version: $opt_buildversion\n";
503
#                   Not often used 
504
    print DF "Section: main\n";
504
#
505
    print DF "Priority: standard\n";
505
# Inputs          : None
506
    print DF "Architecture: $opt_pkgarch\n";
506
#
507
    print DF "Essential: No\n";
507
# Returns         : Nothing
508
    print DF "Maintainer: Vix Technology\n";
508
#
509
    print DF "Description: $opt_description\n";
509
sub BuildTarFile
510
    print DF "Depends: $depData\n" if ($depData);
510
{
511
 
511
    Verbose ("Create TGZ file containing body of the package");
512
    close (DF);
512
    System ('tar', 
513
}
513
            '--create',
514
 
514
            '--auto-compress',
515
#-------------------------------------------------------------------------------
515
            '--owner=0' ,
516
# Function        : SetVerbose
516
            '--group=0' ,
517
#
517
            '--one-file-system' ,
518
# Description     : Set the level of verbosity
518
            '--exclude=./DEBIAN' ,
519
#                   Display activity
519
            '-C', $WorkDirInit,  
520
#
520
            '--file', $opt_tarFile,
521
# Inputs          : Verbosity level
521
            '.'
522
#                       0 - Use makefile verbosity (Default)
522
            );
523
#                       1..2
523
}
524
#
524
 
525
# Returns         : 
525
#-------------------------------------------------------------------------------
526
#
526
# Function        : Section 
527
sub SetVerbose
527
#
528
{
528
# Description     : Allows the Package file to be split into section
529
    my ($level) = @_;
529
#                   This direcive is always active.
530
 
530
#
531
    $level = $opt_verbose unless ( $level );
531
# Inputs          : Selector
532
    $opt_verbose = $level;
532
#                       ALL     - Active
533
    ErrorConfig( 'verbose' => $level);
533
#                       RPM     - Active section when building an RPM
534
}
534
#                       DEBIAN  - Active section if build a Debian package
535
 
535
#                       TAR     - Active section if building a TAR
536
 
536
#
537
#-------------------------------------------------------------------------------
537
# Returns         : Nothing
538
# Function        : DebianFiles
538
#                   Will fkag to indicate if directives are active. 
539
#
539
#
540
# Description     : Name Debian builder control files
540
sub Section
541
#                   May be called multiple times
541
{
542
#
542
    my $newActiveSection;
543
# Inputs          : Options
543
    my $flip = sub {
544
#                       --Control=file
544
        my ($val, $mode) = @_;
545
#                       --PreRm=file
545
        if ( defined $mode) {
546
#                       --PostRm=file
546
            return $val ? 0 : 1;
547
#                       --PreInst=file
547
        }
548
#                       --PostInst=file
548
        return $val;
549
#                         
549
    };
550
#
550
 
551
# Returns         : Nothing
551
    $newActiveSection = 1 unless (@_);
552
#
552
    foreach my $arg ( @_)
553
sub DebianFiles
553
    {
554
{
554
        if ($arg =~ m/^(!)*DEBIAN/i) {
555
    #
555
            $newActiveSection = 1 if  $flip->($opt_debian, $1);
556
    #   Extract names
556
 
557
    #
557
        } elsif ($arg =~ m/^(!)*RPM/i) {
558
    Verbose ("Specify Debian Control Files and Scripts");
558
            $newActiveSection = 1 if  $flip->($opt_rpm, $1);
559
    foreach  ( @_ )
559
 
560
    {
560
        } elsif ($arg =~ m/^(!)*TAR/i) {
561
        if ( m/^--Control=(.+)/i ) {
561
            $newActiveSection = 1 if $flip->($opt_tarFile, $1);
562
            DebianControlFile('control',$1)
562
 
563
 
563
        } elsif (uc($arg) eq 'ALL') {
564
        } elsif ( m/^--PreRm=(.+)/i ) {
564
            $newActiveSection = 1;
565
            DebianControlFile('prerm',$1)
565
 
566
 
566
        } elsif ( $arg eq 1  ) {
567
        } elsif ( m/^--PostRm=(.+)/i ) {
567
                $newActiveSection = 1;
568
            DebianControlFile('postrm',$1)
568
 
569
 
569
        } elsif ( $arg eq 0  ) {
570
        } elsif ( m/^--PreInst=(.+)/i ) {
570
 
571
            DebianControlFile('preinst',$1)
571
        } else {
572
 
572
            Warning ("Section: Unknown argument $arg");
573
        } elsif ( m/^--PostInst=(.+)/i ) {
573
        }
574
            DebianControlFile('postinst',$1)
574
    }
575
 
575
 
576
        } else {
576
    $ActiveSection = $newActiveSection ? 1: 0;
577
            Error ("DebianFiles: Unknown option: $_");
577
    Verbose ("Section State: $ActiveSection");
578
        }
578
 
579
    }
579
}
580
}
580
 
581
 
581
#-------------------------------------------------------------------------------
582
#-------------------------------------------------------------------------------
582
# Function        : UpdateDebianControlFile
583
# Function        : DebianControlFile 
583
#
584
#
584
# Description     : Update the Debian 'control' file to fix up various fields
585
# Description     : Add special control files to the Debian Installer 
585
#                   within the file.
586
#                   Not useful for embedded installers
586
#
587
#
587
#                   If the files has not been specified, then a basic control
588
#                   More general than DebianFiles()
588
#                   file will be provided.
589
#
589
#
590
# Inputs          : name            - Target Name
590
#                   This routine knows where the control file will be placed
591
#                                     If the name starts with 'package.' then it will be replaced
591
#                   within the output work space.
592
#                                     with the name of the current package
592
#
593
#                   file            - Source File Name
593
# Inputs          : $src            - Path to source file
594
#                   options         - Options include
594
#                   Uses global variables
595
#                                       --FromPackage
595
#
596
#
596
# Returns         : Nothing
597
# Returns         : 
597
#
598
#
598
sub UpdateDebianControlFile
599
sub DebianControlFile
599
{
600
{
600
    my($src) = @_;
601
    my ($name, $file, @options) = @_;
601
    return 1 unless ($ActiveSection);
602
    my $fromPackage = 0;
602
    my $dst = "$WorkDirInit/DEBIAN/control";
603
 
603
 
604
    #
604
    unless ( $src )
605
    #   Process options
605
    {
606
    foreach ( @options)
606
        CreateDebianControlFile();
607
    {
607
        return;
608
        if (m~^--FromPackage~) {
608
    }
609
            $fromPackage = 1;
609
 
610
        }
610
    #
611
        else  {
611
    #   User has provided a control file
612
            ReportError(("DebianControlFile: Unknown argument: $_"));
612
    #       Tweak the internals
613
        }
613
    #
614
    }
614
    Verbose ("UpdateDebianControlFile: $dst" );
615
    ErrorDoExit();
615
    $src = ResolveFile( 0, $src );
616
 
616
 
617
    #
617
    #   Calc depends line
618
    #   Some control files need to have the package name prepended
618
    my $depData = join (', ', @DependencyList );
619
    #
619
 
620
    $name =~ s~^package\.~$opt_name.~;
620
    open (SF, '<', $src) || Error ("UpdateDebianControlFile: Cannot open:$src, $!");
621
 
621
    open (DF, '>', $dst) || Error ("UpdateDebianControlFile: Cannot create:$dst, $!");
622
    #
622
    while ( <SF> )
623
    #   Only allow one file of each type
623
    {
624
    #       Try to protect the user by testing for names by lowercase
624
        s~\s*$~~;
625
    #
625
        if ( m~^Package:~ ) {
626
    my $simpleName = lc($name);
626
            $_ = "Package: $opt_name";
627
    Error("DebianControlFile: Multiple definitions for '$name' not allowed")
627
 
628
        if (exists $DebianControlFileNames{$simpleName});
628
        } elsif ( m~^Version:~ ) {
629
 
629
            $_ = "Version: $opt_buildversion";
630
    my $filePath = ResolveFile($fromPackage, $file);
630
 
631
 
631
        } elsif ( m~^Architecture:~ ) {
632
    #
632
            $_ = "Architecture: $opt_pkgarch";
633
    #   Add info to data structures
633
 
634
    #
634
        } elsif ( $opt_description && m~^Description:~ ) {
635
    $DebianControlFiles{$name} = $filePath;
635
            $_ = "Description: $opt_description";
636
    $DebianControlFileNames{$simpleName} = $name;
636
 
637
}
637
        } elsif ( m~^Depends:~ ) {
638
 
638
            $_ = "Depends: $depData";
639
#-------------------------------------------------------------------------------
639
            $depData = '';
640
# Function        : DebianDepends 
640
        }
641
#
641
        print DF $_ , "\n";
642
# Description     : This directive allows simple dependency information to be  
642
    }
643
#                   inserted into the control file
643
 
644
#
644
    close (SF);
645
#                   Not useful in embedded system
645
    close (DF);
646
#
646
 
647
# Inputs          : Entry             - A dependency entry
647
    #
648
#                   ...               - More entries
648
    #   Warn if Depends section is needed
649
#                   
649
    #
650
#
650
    Error ("No Depends section seen in user control file") 
651
# Returns         : Nothing
651
        if ($depData);
652
#
652
}
653
sub DebianDepends
653
 
654
{
654
#-------------------------------------------------------------------------------
655
    push @DependencyList, @_;
655
# Function        : CreateDebianControlFile
656
}
656
#
657
 
657
# Description     : Create a basic debian control file
658
 
658
#
659
#-------------------------------------------------------------------------------
659
# Inputs          : Uses global variables
660
# Function        : PackageDescription
660
#
661
#
661
# Returns         : 
662
# Description     : Specify the Package Description
662
#
663
#                   Keep it short
663
sub CreateDebianControlFile
664
#
664
{
665
# Inputs          : $description
665
    return 1 unless ($ActiveSection);
666
#
666
    my $dst = "$WorkDirInit/DEBIAN/control";
667
# Returns         : 
667
 
668
#
668
    Verbose ("CreateDebianControlFile: $dst" );
669
sub PackageDescription
669
 
670
{
670
    my $depData = join (', ', @DependencyList );
671
    ($opt_description) = @_;
671
 
672
}
672
    open (DF, '>', $dst) || Error ("CreateDebianControlFile: Cannot create:$dst");
673
 
673
    print DF "Package: $opt_name\n";
674
#-------------------------------------------------------------------------------
674
    print DF "Version: $opt_buildversion\n";
675
# Function        : MakeSymLink
675
    print DF "Section: main\n";
676
#
676
    print DF "Priority: standard\n";
677
# Description     : Create a symlink - with error detection
677
    print DF "Architecture: $opt_pkgarch\n";
678
#
678
    print DF "Essential: No\n";
679
# Inputs          : old_file    - Link Target
679
    print DF "Maintainer: Vix Technology\n";
680
#                                 Path to the link target
680
    print DF "Description: $opt_description\n";
681
#                                 If an ABS path is provided, the routine will
681
    print DF "Depends: $depData\n" if ($depData);
682
#                                 attempt to create a relative link.
682
 
683
#                   new_file    - Relative to the output work space
683
    close (DF);
684
#                                 Path to where the 'link' file will be created
684
}
685
#                   Options     - Must be last
685
 
686
#                                 --NoClean         - Don't play with links
686
#-------------------------------------------------------------------------------
687
#                                 --NoDotDot        - Don't create symlinks with ..
687
# Function        : UpdateRedHatControlFile 
688
#
688
#
689
# Returns         : Nothing
689
# Description     : Update the Redhat 'control' file to fix up various fields
690
#
690
#                   within the file.
691
sub MakeSymLink
691
#
692
{
692
#                   If the files has not been specified, then a basic control
693
    my $no_clean;
693
#                   (spec) file will be provided.
694
    my $no_dot;
694
#                   Various tags will be replaced
695
    my @args;
695
#                       tag_name
696
 
696
#                       tag_version
697
    #
697
#                       tag_buildarch
698
    #   Extract options
698
#                       tag_release
699
    #
699
#                       tag_description
700
    foreach ( @_ )
700
#                       tag_requires
701
    {
701
#                       tag_filelist
702
        if ( m/^--NoClean/i ) {
702
#
703
            $no_clean = 1;
703
# Inputs          : $src            - Path to source file
704
 
704
#                   Uses global variables
705
        } elsif ( m/^--NoDotDot/i ) {
705
#
706
            $no_dot = 1;
706
# Returns         : Nothing
707
 
707
#
708
        } elsif ( m/^--/ ) {
708
sub UpdateRedHatControlFile
709
            Error ("MakeSymLink: Unknown option: $_");
709
{
710
 
710
    my($src) = @_;
711
        } else {
711
    return 1 unless ($ActiveSection);
712
            push @args, $_;
712
    my $dst = $opt_specFile;
713
        }
713
    unless ( $src )
714
    }
714
    {
715
 
715
        CreateRedHatControlFile();
716
    my ($old_file, $new_file) = @args;
716
        return;
717
 
717
    }
718
    my $tfile = $DebianWorkDir . '/' . $new_file;
718
 
719
    $tfile =~ s~//~/~;
719
    #
720
    Verbose ("Symlink $old_file -> $new_file" );
720
    #   User has provided a control file
721
 
721
    #       Tweak the internals
722
    #
722
    #
723
    #   Create the directory in which the link will be placed
723
    Verbose ("UpdateRedHatControlFile: $dst" );
724
    #   Remove any existing file of the same name
724
    $src = ResolveFile( 0, $src );
725
    #
725
 
726
    my $dir = StripFileExt( $tfile );
726
    my @depList = @DependencyList;
727
    mkpath( $dir) unless -d $dir;
727
    my $cleanSeen;
728
    unlink $tfile;
728
 
729
 
729
    open (my $sf, '<', $src) || Error ("UpdateRedHatControlFile: Cannot open:$src, $!");
730
    #
730
    open (my $df, '>', $dst) || Error ("UpdateRedHatControlFile: Cannot create:$dst, $!");
731
    #   Determine a good name of the link
731
    while ( <$sf> )
732
    #   Convert to a relative link in an attempt to prune them
732
    {
733
    #
733
        s~\s*$~~;
734
    my $sfile = $old_file;
734
        if ( m~^tag_Name~i ) {
735
    unless ( $no_clean )
735
            $_ = "Name: $opt_name";
736
    {
736
 
737
        $sfile = CalcRelPath( StripFileExt( $new_file ), $old_file );
737
        } elsif ( m~^tag_Version~i ) {
738
        $sfile = $old_file if ( $no_dot && $sfile =~ m~^../~ );
738
            $_ = "Version: $opt_buildversion";
739
    }
739
 
740
 
740
        } elsif ( m~^tag_BuildArch~i ) {
741
    my $result = symlink $sfile, $tfile;
741
            $_ = "BuildArch: $opt_pkgarch";
742
    Error ("Cannot create symlink. $old_file -> $new_file") unless ( $result );
742
 
743
}
743
        } elsif ( m~^tag_Release~i ) {
744
 
744
            $_ = "Release: $opt_rpmRelease";
745
#-------------------------------------------------------------------------------
745
 
746
# Function        : CopyFile
746
        } elsif ( $opt_description && m~^tag_Description~i ) {
747
#
747
            print $df "%description\n";
748
# Description     : Copy a file to a target dir
748
            print $df "$opt_description\n";
749
#                   Used for text files, or files with fixed names
749
            $_ = undef;
750
#
750
 
751
# Inputs          : $src
751
        } elsif ( m~^tag_Requires~i ) {
752
#                   $dst_dir    - Within the output workspace
752
            foreach my $item (@depList) {
753
#                   $dst_name   - Output Name [Optional]
753
                print $df "Requires:       $item\n";
754
#                   Options     - Common Copy Options
754
            }
755
#
755
            $_ = undef;
756
# Returns         : Full path to destination file
756
            @depList = ();
757
#
757
 
758
sub CopyFile
758
        } elsif ( m~^tag_filelist~i ) {
759
{
759
            GenerateRedHatFileList ($df);
760
    CopyFileCommon( \&ResolveFile, @_ );
760
            $_ = undef;
761
}
761
 
762
 
762
        } elsif ( m~^%clean~i ) {
763
#-------------------------------------------------------------------------------
763
            $cleanSeen  = 1;
764
# Function        : CopyBinFile
764
        }
765
#
765
        print $df ($_ , "\n") if defined ($_);
766
# Description     : Copy a file to a target dir
766
    }
767
#                   Used for executable programs. Will look in places where
767
 
768
#                   programs are stored.
768
    close ($sf);
769
#
769
    close ($df);
770
# Inputs          : $src
770
 
771
#                   $dst_dir    - Within the output workspace
771
    #
772
#                   $dst_name   - Output Name [Optional]
772
    #   Warn if Depends section is needed
773
#
773
    #
774
#                   Options:
774
    Error ("No %clean section seen in user control file") unless $cleanSeen; 
775
#                       --FromPackage
775
    Error ("No Requires tag seen in user control file") if (@depList);
776
#                       --SoftLink=xxxx
776
}
777
#                       --LinkFile=xxxx
777
 
778
#
778
#-------------------------------------------------------------------------------
779
#
779
# Function        : CreateRedHatControlFile
780
# Returns         : Full path to destination file
780
#
781
#
781
# Description     : Create a binary RedHat spec file
782
sub CopyBinFile
782
#
783
{
783
# Inputs          : Uses global variables
784
    CopyFileCommon( \&ResolveBinFile, @_ );
784
#
785
}
785
# Returns         : 
786
 
786
#
787
#-------------------------------------------------------------------------------
787
sub CreateRedHatControlFile
788
# Function        : CopyLibFile
788
{
789
#
789
    #
790
# Description     : Copy a file to a target dir
790
    #   Generate the RPM spec file
791
#                   Used for shared programs. Will look in places where
791
    #
792
#                   shared libraries are stored.
792
    open (my $sf, '>', $opt_specFile) || Error ("RPM Spec File: Cannot create: $opt_specFile, $!");
793
#
793
 
794
# Inputs          : $src        - Base for 'realname' (no lib, no extension)
794
    # Standard tags
795
#                   $dst_dir    - Within the output workspace
795
    print $sf ("# Standard SPEC Tags\n");
796
#                   $dst_name   - Output Name [Optional, but not suggested]
796
    print $sf "Summary:        Installer for the $opt_name Package\n";
797
#
797
    print $sf "Name:           $opt_name\n";
798
# Returns         : Full path to destination file
798
    print $sf "Version:        $opt_buildversion\n";
799
#
799
    print $sf "Release:        $opt_rpmRelease\n";
800
# Notes           : Copying 'lib' files
800
    print $sf "License:        COPYRIGHT - VIX IP PTY LTD (\"VIX\"). ALL RIGHTS RESERVED.\n";
801
#                   These are 'shared libaries. There is no provision for copying
801
    print $sf "Source:         None\n";
802
#                   static libraries.
802
    print $sf "BuildArch:      $opt_pkgarch\n";
803
#
803
    print $sf "Group:          VIX/System\n";
804
#                   The tool will attempt to copy a well-formed 'realname' library
804
    print $sf "Vendor:         Vix Technology\n";
805
#                   The soname of the library should be constructed on the target
805
    print $sf "Autoreq:        No\n";
806
#                   platform using ldconfig.
806
    #
807
#                   There is no provision to copy the 'linker' name
807
    #   Requires tags
808
#
808
    #
809
#                   Given a request to copy a library called 'fred', then the
809
    print $sf "\n# Dependencies\n" if @DependencyList;
810
#                   well formed 'realname' will be:
810
    foreach my $item (@DependencyList) {
811
#                           libfred[P|D|]].so.nnnnn
811
        print $sf "Requires:       $item\n";
812
#                   where:
812
    }
813
#                           nnnn is the library version
813
    
814
#                           [P|D|] indicates Production, Debug or None
814
    print $sf "\n";
815
#
815
    print $sf "%description\n";
816
#                   The 'soname' is held within the realname form of the library
816
    print $sf "$opt_description\n";
817
#                   and will be created by lsconfig.
817
 
818
#
818
    print $sf "\n";
819
#                   The 'linkername' would be libfred[P|D|].so. This is only
819
    print $sf "%clean\n";
820
#                   needed when linking against the library.
820
 
821
#
821
    #
822
#
822
    #   Insert various scripts
823
#                   The routine will also recognize Windows DLLs
823
    #
824
#                   These are of the form fred[P|D|].nnnnn.dll
824
    my $insertRpmControlFile = sub {
825
#
825
        my ($sname, $cname) = @_;
826
sub CopyLibFile
826
        if ( my $src = $ControlFiles{$cname} ) {
827
{
827
            print $sf "\n";
828
    CopyFileCommon( \&ResolveLibFile, @_ );
828
            print $sf '%' . $sname . "\n";
829
}
829
            open ( my $cf, '<', $src ) || Error ("BuildRPM: Cannot open:$src, $!");
830
 
830
            while ( <$cf> ) {
831
#-------------------------------------------------------------------------------
831
                $_ =~ s~\%~%%~g;
832
# Function        : CopyDebianPackage
832
                print $sf $_;
833
#
833
            }
834
# Description     : Copy a Debian Package to a target dir
834
            close ($cf);
835
#                   Will look in places where Debian Packages are stored.
835
            print $sf "\n";
836
#
836
        }
837
# Inputs          : $src        - BaseName for 'Debian Package' (no version, no extension)
837
    };
838
#                   $dst_dir    - Within the output workspace
838
    
839
#                   Optional arguments embedded into the BaseName
839
    #   Run the PreInstall script as %pretrans
840
#                   --Arch=XXXX         - Architecture - if not current
840
    #       %pretrans is the only script that can terminate the RPM installation
841
#                   --Product=XXXX      - Product - if required
841
    &$insertRpmControlFile ('pretrans', 'preinst');
842
#                   --Debug             - If not the current type
842
    &$insertRpmControlFile ('post',     'postinst');
843
#                   --Prod              - If not the current type
843
    &$insertRpmControlFile ('preun',    'prerm');
844
#
844
    &$insertRpmControlFile ('postun',   'postrm');
845
# Returns         : Full path to destination file
845
 
846
#
846
    #
847
# Notes           : Copying Debian Packages from external packages
847
    #   Insert the list of files to be processed
848
#
848
    #       Can't use /* as this will mess with permissions of the root directory. 
849
#                   The tool will attempt to copy a well-formed debian packages
849
    #       Can list Top Level directories and then use *
850
#                   These are:
850
    #
851
#                   
851
    print $sf "\n%files\n";
852
#                       "BaseName_VersionString[_Product]_Arch${PkgType}.deb";
852
    print $sf "%defattr(",join (',', @RpmDefAttr),")\n";
853
#                   
853
    GenerateRedHatFileList ($sf);
854
#                   Where 'Product' is optional (and rare)
854
    print $sf "\n";
855
#                   Where 'PkgType' is P or D or nothing
855
    close ($sf);
856
#                   Where 'Arch' may be 'all'
856
}
857
#                   
857
 
858
#                   The routine will locate Debian packages in
858
#-------------------------------------------------------------------------------
859
#                       - The root of the package
859
# Function        : GenerateRedHatFileList 
860
#                       - bin/TARGET[P|D/]
860
#
861
#                       - bin/Arch[P|D]
861
# Description     : Internal function
862
#
862
#                   Generate a file list to be inserted into an RPM spec file
863
#
863
#
864
sub CopyDebianPackage
864
# Inputs          : $fd     - File descriptor.
865
{
865
#                             Function will write directly to the output
866
    CopyFileCommon( \&ResolveDebPackage, '--FromPackage', @_ );
866
#
867
}
867
# Returns         : Nothing 
868
 
868
#
869
#-------------------------------------------------------------------------------
869
sub GenerateRedHatFileList
870
# Function        : CopyFileCommon
870
{
871
#
871
    my ($fd) = @_;
872
# Description     : Common ( internal File Copy )
872
 
873
#
873
    #
874
# Inputs          : $resolver           - Ref to function to resolve source file
874
    #   Sanity Test
875
#                   $src                - Source File Name
875
    #
876
#                   $dst_dir            - Target Dir
876
    Warning ("No directories has been marked as 'Owned'",
877
#                   $dst_name           - Target Name (optional)
877
             "Under RedHat a directory must be 'owned' by a package so that it can be removed.",
878
#                   Options
878
             "This ownership may be in that package or a 'Required' package.",
879
#                   Options:
879
             "This ownership may be shared or exclusive.",
880
#                       --FromPackage
880
             ) unless scalar keys %OwnedDirs;
881
#                       --FromBuild
881
 
882
#                       --SoftLink=xxxx
882
    #
883
#                       --LinkFile=xxxx
883
    #   Flag files and directories with attributes
884
#                       --ConfigFile
884
    #
885
#
885
    my %Attrs;
886
# Returns         : 
886
    my %Dirs;
887
#
887
    foreach my $item ( @RpmAttrList ) {
888
sub CopyFileCommon
888
        my $file =  $item->[0]; 
889
{
889
        my $full_path = $WorkDirInit . $file;
890
    my $from_package = 0;
890
        $Attrs{$file} =  '%attr(' . join(',',@{$item}[1..3] ) . ')';
891
    my $isa_linkfile = 0;
891
        $Dirs{$file} = '%dir' if (-d $full_path);
892
    my $isa_configFile = 0;
892
    }
893
    my @llist;
893
    
894
    my @args;
894
    #
895
 
895
    #   Flag configuration files ( ConfFile )
896
    #
896
    #
897
    #   Parse options
897
    my %Configs;
898
    #
898
    foreach my $item (@ConfigList) {
899
    foreach ( @_ )
899
        $Configs{$item} = '%config';
900
    {
900
    }
901
        if ( m/^--FromPackage/ ) {
901
 
902
            $from_package = 1;
902
    #
903
 
903
    #   Internal subroutine to pretty-print a file/dirname with attributes
904
        } elsif ( m/^--FromBuild/ ) {
904
    #       $path   - path element
905
            $from_package = 0;
905
    #       $isDir  - True if a directory
906
 
906
    #   
907
        } elsif ( m/^--LinkFile/ ) {
907
    my $printer = sub {
908
            $isa_linkfile = 1;
908
        my ($path, $isDir) = @_;
909
 
909
        my $attrText =  delete $Attrs{$path};
910
        } elsif ( m/^--ConfFile/i ) {
910
        my $confText =  delete $Configs{$path};
911
            $isa_configFile = 1;
911
        my $dirText  =  delete $Dirs{$path};
912
 
912
        $dirText = '%dir' if $isDir;
913
        } elsif ( m/^--SoftLink=(.+)/ ) {
913
 
914
            push @llist, $1;
914
        my $txt;
915
 
915
        my $joiner = '';
916
        } elsif ( m/^--/ ) {
916
        $path = '"' . $path . '"';
917
            Error ("FileCopy: Unknown option: $_");
917
        foreach ($attrText,$dirText,$confText, $path) {
918
 
918
            next unless $_;
919
        } else {
919
            $txt .= $joiner . $_;
920
            push @args, $_;
920
            $joiner = ' ';
921
        }
921
        }
922
    }
922
        print $fd ("$txt\n");
923
 
923
    };
924
    #
924
 
925
    #   Extract non-options.
925
    #
926
    #   These are the bits that are left over
926
    #   List all files in the tree
927
    #
927
    #       If we use wildcards we get interpackage dependency issues
928
    my ($resolver, $src, $dst_dir, $dst_name ) = @args;
928
    #       Process files and directories
929
 
929
    #
930
    #
930
    my $search =  JatsLocateFiles->new( '--Recurse', '--NoFullPath', '--DirsToo' );
931
    #   Clean up dest_dir. Must start with a / and not end with one
931
    my @flist = $search->search($WorkDirInit);
932
    #
932
    foreach (@flist) {
933
    $dst_dir = "/$dst_dir/";
933
        my $file = '/' . $_;
934
    $dst_dir =~ s~/+~/~g;
934
        my $full_path = $WorkDirInit . $file;
935
    $dst_dir =~ s~/$~~;
935
        my $isDir = (-d $full_path) || 0;
936
 
936
 
937
    Verbose ("CopyFile: $src, $dst_dir, " . ($dst_name || ''));
937
        #
938
    foreach $src ( &$resolver( $from_package, $src ) )
938
        #   Determine if the element is within a known RootDir
939
    {
939
        #
940
        my $dst_fname = $dst_name ? $dst_name : StripDir($src);
940
        my $inRoot = 0;
941
        my $dst_file = "$dst_dir/$dst_fname";
941
        my $isOwner = 0;
942
        Verbose ("CopyFile: Copy $src, $dst_file" );
942
        foreach (keys %OwnedDirs) {
943
        
943
            if ($file =~ m~^$_~) {
944
 
944
                $inRoot = 1;
945
        #
945
                $isOwner = $OwnedDirs {$_};
946
        #   LinkFiles are special
946
                last;
947
        #   They get concatenated to any existing LINKS File
947
            }
948
        #
948
        }
949
        if ( $isa_linkfile )
949
 
950
        {
950
        #
951
            CatFile ( $src, "$dst_dir/.LINKS" );
951
        #   Ignore directories that are not within a RootDir
952
        }
952
        #   
953
        else
953
        unless ($inRoot) {
954
        {
954
            next if $isDir;
955
            mkpath( "$DebianWorkDir$dst_dir", 0, 0775);
955
        }
956
            unlink ("$DebianWorkDir$dst_file");
956
 
957
            System ('cp','-f', $src, "$DebianWorkDir$dst_file" );
957
        #
958
 
958
        #   Ignore directories that are not within an 'owned' directory
959
            foreach my $lname ( @llist )
959
        #
960
            {
960
        if ( !$isOwner && $isDir ) {
961
                $lname = $dst_dir . '/' . $lname unless ( $lname =~ m ~^/~ );
961
            next;
962
                MakeSymLink( $dst_file ,$lname);
962
        }
963
            }
963
        
964
        }
964
        &$printer($file, $isDir);
965
 
965
    }
966
        #
966
 
967
        #   ConfigFiles are marked so that they can be handled by the debain installer
967
    #
968
        #
968
    #   Sanity tests
969
        if ($isa_configFile)
969
    #   We should have process all the Configs and Attributes
970
        {
970
    #
971
            push @ConfigList, $dst_file;
971
    if ( (keys %Configs) || ( keys %Attrs))
972
        }
972
    {
973
    }
973
        Error ("Internal Error. Unprocessed Config or Attributes.",
974
}
974
               keys %Configs, keys %Attrs );
975
 
975
    }
976
#-------------------------------------------------------------------------------
976
 
977
# Function        : CopyDir
977
}
978
#
978
 
979
# Description     : Copy a directory to a target dir
979
#-------------------------------------------------------------------------------
980
#
980
# Function        : SetVerbose
981
# Inputs          : $src_dir    - Local to the user
981
#
982
#                                 Symbolic Name
982
# Description     : Set the level of verbosity
983
#                   $dst_dir    - Within the output workspace
983
#                   Display activity
984
#                   Options
984
#
985
#                       --Merge                 - Don't delete first
985
# Inputs          : Verbosity level
986
#                       --Source=Name           - Source via Symbolic Name
986
#                       0 - Use makefile verbosity (Default)
987
#                       --FromPackage           - Source via package roots
987
#                       1..2
988
#                       --NoIgnoreDbgFiles      - Do not ignore .dbg and .debug files in dir copy
988
#
989
#                       --IfPresent             - Not an error if the path cannot be found
989
# Returns         : 
990
#                       --ConfFile              - Mark transferred files as config files
990
#
991
#                       --Flatten               - Copy all to one directory
991
sub SetVerbose
992
#                       --FilterOut=xxx         - Ignore files. DOS Wildcard
992
{
993
#                       --FilterOutRe=xxx       - Ignore files. Regular expression name
993
    return 1 unless ($ActiveSection);
994
#                       --FilterOutDir=xxx      - Ignore directories. DOS Wilcard
994
    my ($level) = @_;
995
#                       --FilterOutDirRe=xxx    - Ignore directories. Regular expression name
995
 
996
#                       --SkipTLF               - Ignore files in the Top Level Directory
996
    $level = $opt_verbose unless ( $level );
997
#                       --NoRecurse             - Only process files in the Top Level Directory
997
    $opt_verbose = $level;
998
#                       --FilterIn=xxx          - Include files. DOS Wildcard
998
    ErrorConfig( 'verbose' => $level);
999
#                       --FilterInRe=xxx        - Include files. Regular expression name
999
}
1000
#                       --FilterInDir=xxx       - Include directories. DOS Wilcard
1000
 
1001
#                       --FilterInDirRe=xxx     - Include directories. Regular expression name
1001
#-------------------------------------------------------------------------------
1002
#
1002
# Function        : SetBaseDir 
1003
# Returns         :
1003
#
1004
#
1004
# Description     : Sets the root directory for all directories
1005
sub CopyDir
1005
#                   Used to simplify scripts
1006
{
1006
#                   
1007
    my ($src_dir, $dst_dir, @opts) = @_;
1007
# Inputs          : $path           - Absolute path. Now within the RootDir
1008
    my $opt_base;
1008
#                   @options        - As for CreateDir
1009
    my $from_interface = 0;
1009
#
1010
    my $ignoreDbg = 1;
1010
# Returns         : Nothing 
1011
    my $ignoreNoDir;
1011
#                   Sets $WorkDir
1012
    my $user_src_dir = $src_dir;
1012
#
1013
    my $opt_source;
1013
sub SetBaseDir
1014
    my $opt_package;
1014
{
1015
    my @fileList;
1015
    my ($path, @opts) = @_;
1016
    my $isFiltered;
1016
    return 1 unless ($ActiveSection);
1017
 
1017
    
1018
    #
1018
    my $rootdir = $path || '/';
1019
    #   Setup the basic copy options
1019
    $rootdir = '/' . $rootdir;
1020
    #       May be altered as we parse user options
1020
    $rootdir =~ s~/+~/~g; 
1021
    #
1021
    Verbose ("Setting RootDir: $rootdir");
1022
    my %copyOpts;
1022
 
1023
    $copyOpts{'IgnoreDirs'} = ['.svn', '.git', '.cvs', '.hg'];
1023
    #
1024
    $copyOpts{'Ignore'} = ['.gbedir', '_gbedir'];
1024
    #   Create the directory
1025
    $copyOpts{'Log'} = 1 if ( $opt_verbose > 1 );
1025
    #
1026
    $copyOpts{'DeleteFirst'} = 1;
1026
    $WorkDir = $WorkDirInit;
1027
 
1027
    CreateDir ($rootdir, @opts);
1028
    $dst_dir = $DebianWorkDir . '/' . $dst_dir;
1028
    $WorkSubDir = $rootdir;
1029
    $dst_dir =~ s~//~/~;
1029
    $WorkDir = $WorkDirInit . $rootdir;
1030
 
1030
}
1031
    #
1031
 
1032
    #   Scan and collect user options
1032
#-------------------------------------------------------------------------------
1033
    #
1033
# Function        : DebianFiles
1034
    foreach  ( @opts )
1034
#                   RpmFiles
1035
    {
1035
#                   AllFiles
1036
        Verbose2 ("CopyDir: $_");
1036
#
1037
        if ( m/^--Merge/ ) {
1037
# Description     : Name Debian and RPM builder control files
1038
            $copyOpts{'DeleteFirst'} = 0;
1038
#                   May be called multiple times
1039
 
1039
#
1040
        } elsif ( m/^--Source=(.+)/ ) {
1040
# Inputs          :   $fName    - Name under which the function is being called
1041
            Error ("Source directory can only be specified once")
1041
#                     Options
1042
                if ( defined $opt_source );
1042
#                       --Control=file
1043
            $opt_source = $1;
1043
#                       --PreRm=file
1044
 
1044
#                       --PostRm=file
1045
        } elsif ( m/^--FromPackage/ ) {
1045
#                       --PreInst=file
1046
            Error ("FromPackage can only be specified once")
1046
#                       --PostInst=file
1047
                if ( defined $opt_package );
1047
#                       --SimpleSharedLibs
1048
            $opt_package = 1;
1048
#                         
1049
 
1049
#
1050
        } elsif ( m/^--NoIgnoreDbgFiles/ ) {
1050
# Returns         : Nothing
1051
            $ignoreDbg = 0;
1051
#
1052
 
1052
sub MULTI_Files
1053
        } elsif ( m/^--IfPresent/ ) {
1053
{
1054
            $ignoreNoDir = 1;
1054
    my $fName = shift;
1055
            
1055
    return 1 unless ($ActiveSection);
1056
        } elsif ( m/^--ConfFile/i ) {
1056
    Verbose ("Specify Installer Control Files and Scripts");
1057
            $copyOpts{'FileList'} = \@fileList;
1057
    foreach  ( @_ )
1058
           
1058
    {
1059
        } elsif ( m/^--Flatten/i ) {
1059
        if ( m/^--Control=(.+)/i ) {
1060
            $copyOpts{'Flatten'} = 1;
1060
            MULTI_ControlFile($fName, 'control',$1)
1061
 
1061
 
1062
        } elsif ( m/^--FilterOut=(.+)/i ) {
1062
        } elsif ( m/^--PreRm=(.+)/i ) {
1063
            push (@{$copyOpts{'Ignore'}}, $1);
1063
            MULTI_ControlFile($fName, 'prerm',$1)
1064
            $isFiltered = 1;
1064
 
1065
 
1065
        } elsif ( m/^--PostRm=(.+)/i ) {
1066
        } elsif ( m/^--FilterOutRe=(.+)/i ) {
1066
            MULTI_ControlFile($fName, 'postrm',$1)
1067
            push (@{$copyOpts{'IgnoreRE'}}, $1);
1067
 
1068
            $isFiltered = 1;
1068
        } elsif ( m/^--PreInst=(.+)/i ) {
1069
 
1069
            MULTI_ControlFile($fName, 'preinst',$1)
1070
        } elsif ( m/^--FilterOutDir=(.+)/i ) {
1070
 
1071
            push (@{$copyOpts{'IgnoreDirs'}}, $1);
1071
        } elsif ( m/^--PostInst=(.+)/i ) {
1072
            $isFiltered = 1;
1072
            MULTI_ControlFile($fName, 'postinst',$1)
1073
 
1073
 
1074
        } elsif ( m/^--FilterOutDirRe=(.+)/i ) {
1074
        } elsif ( m/^--SimpleSharedLibs/i ) {
1075
            push (@{$copyOpts{'IgnoreDirsRE'}}, $1);
1075
 
1076
            $isFiltered = 1;
1076
            my $file = catfile($WorkDirBase, 'ldconfig.sh' );
1077
 
1077
 
1078
        } elsif ( m/^--FilterIn=(.+)/i ) {
1078
            open (my $df, '>', $file) || Error ("$fName: Cannot create:$file");
1079
            push (@{$copyOpts{'Match'}}, $1);
1079
            print $df "#!/bin/sh\n";
1080
            $isFiltered = 1;
1080
            print $df "/sbin/ldconfig\n";
1081
 
1081
            print $df "exit 0\n";
1082
        } elsif ( m/^--FilterInRe=(.+)/i ) {
1082
            close $df;
1083
            push (@{$copyOpts{'MatchRE'}}, $1);
1083
 
1084
            $isFiltered = 1;
1084
            MULTI_ControlFile($fName, 'postinst',$file);
1085
 
1085
            MULTI_ControlFile($fName, 'postrm',$file);
1086
        } elsif ( m/^--FilterInDir=(.+)/i ) {
1086
 
1087
            push (@{$copyOpts{'MatchDirs'}}, $1);
1087
        } else {
1088
            $isFiltered = 1;
1088
            Error ("$fName: Unknown option: $_");
1089
 
1089
        }
1090
        } elsif ( m/^--FilterInDirRe=(.+)/i ) {
1090
    }
1091
            push (@{$copyOpts{'MatchDirsRE'}}, $1);
1091
}
1092
            $isFiltered = 1;
1092
 
1093
 
1093
#-------------------------------------------------------------------------------
1094
        } elsif ( m/^--SkipTLF$/i ) {
1094
# Function        : DebianControlFile
1095
            $copyOpts{'SkipTLF'} = 1;
1095
#                   RpmControlFile 
1096
 
1096
#                   AllControlFile
1097
        } elsif ( m/^--NoRecurse$/i ) {
1097
#
1098
            $copyOpts{'NoSubDirs'} = 1;
1098
# Description     : Add special control files to the Debian/RedHat Installer 
1099
 
1099
#                   Not useful for embedded installers
1100
        } else {
1100
#
1101
            Error ("CopyDir: Unknown option: $_" );
1101
#                   More general than DebianFiles() or RpmFiles
1102
        }
1102
#
1103
    }
1103
# Inputs          : name            - Target Name
1104
 
1104
#                                     If the name starts with 'package.' then it will be replaced
1105
    #
1105
#                                     with the name of the current package
1106
    #   All options have been gathered. Now process some of them
1106
#                                     Ideally: prerm, postrm, preinst, postinst
1107
    #
1107
#                   file            - Source File Name
1108
    Error ("CopyDir: Cannot use both --Source and --FromPackage: $src_dir") if ($opt_source && $opt_package);
1108
#                   options         - Options include
1109
 
1109
#                                       --FromPackage
1110
    #
1110
#
1111
    #   Convert a symbolic path into a physical path
1111
# Returns         : 
1112
    #
1112
#
1113
    if ($opt_source)
1113
sub MULTI_ControlFile
1114
    {
1114
{
1115
        Verbose2 ("CopyDir: Determine Source: $opt_source");
1115
    my ($fName, $name, $file, @options) = @_;
1116
 
1116
    return 1 unless ($ActiveSection);
1117
        $opt_source = lc($opt_source);
1117
    my $fromPackage = 0;
1118
        my %CopyDirSymbolic = (
1118
 
1119
            'interfaceincdir'   => $opt_interfaceincdir,
1119
    #
1120
            'interfacelibdir'   => $opt_interfacelibdir,
1120
    #   Process options
1121
            'interfacebindir'   => $opt_interfacebindir,
1121
    foreach ( @options)
1122
            'libdir'            => $opt_libdir,
1122
    {
1123
            'bindir'            => $opt_bindir,
1123
        if (m~^--FromPackage~) {
1124
            'localincdir'       => $opt_localincdir,
1124
            $fromPackage = 1;
1125
            'locallibdir'       => $opt_locallibdir,
1125
        }
1126
            'localbindir'       => $opt_localbindir,
1126
        else  {
1127
            'packagebindir'     => $opt_pkgbindir,
1127
            ReportError(("$fName: Unknown argument: $_"));
1128
            'packagelibdir'     => $opt_pkglibdir,
1128
        }
1129
            'packagepkgdir'     => $opt_pkgpkgdir,
1129
    }
1130
            'packagedir'        => $opt_pkgdir,
1130
    ErrorDoExit();
1131
        );
1131
 
1132
 
1132
    #
1133
        if ( exists $CopyDirSymbolic{$opt_source} )
1133
    #   Some control files need to have the package name prepended
1134
        {
1134
    #
1135
            $opt_base = $CopyDirSymbolic{$opt_source};
1135
    $name =~ s~^package\.~$opt_name.~;
1136
 
1136
 
1137
            #
1137
    #
1138
            #   If sourceing from interface, then follow
1138
    #   Only allow one file of each type
1139
            #   symlinks in the copy. All files will be links anyway
1139
    #       Try to protect the user by testing for names by lowercase
1140
            #
1140
    #
1141
            $from_interface = 1
1141
    my $simpleName = lc($name);
1142
                if ( $opt_source =~ m~^interface~ );
1142
    Error("$fName: Multiple definitions for '$name' not allowed")
1143
        }
1143
        if (exists $ControlFileNames{$simpleName});
1144
        else
1144
 
1145
        {
1145
    my $filePath = ResolveFile($fromPackage, $file);
1146
            DebugDumpData ("CopyDirSymbolic", \%CopyDirSymbolic);
1146
 
1147
            Error ("CopyDir: Unknown Source Name: $opt_source" );
1147
    #
1148
        }
1148
    #   Add info to data structures
1149
    }
1149
    #
1150
 
1150
    $ControlFiles{$name} = $filePath;
1151
    #
1151
    $ControlFileNames{$simpleName} = $name;
1152
    #   Locate the path within an external package
1152
}
1153
    #
1153
 
1154
    if ($opt_package)
1154
#-------------------------------------------------------------------------------
1155
    {
1155
# Function        : DebianDepends 
1156
        Verbose2 ("CopyDir: FromPackage: $src_dir");
1156
#                   RpmDepends
1157
 
1157
#                   AllDepends
1158
        my @path;
1158
#
1159
        foreach my $entry ( getPackageList() )
1159
# Description     : This directive allows simple dependency information to be  
1160
        {
1160
#                   inserted into the control file
1161
            my $base = $entry->getBase(3);
1161
#                   
1162
            next unless ( defined $base );
1162
#                   Names will be massaged into conforming names.
1163
            if ( -d $base . '/' . $src_dir )
1163
#
1164
            {
1164
#                   Not useful in embedded system
1165
                push @path, $base;
1165
#
1166
                $from_interface = 1
1166
# Inputs          : Entry             - A dependency entry
1167
                    if ( $entry->{'TYPE'} eq 'interface' );
1167
#                   ...               - More entries
1168
            }
1168
#                   Options
1169
        }
1169
#                       --Raw          - Prevent name modification
1170
 
1170
#                       --NoRaw        - Enable name modification
1171
        if ( $#path < 0 )
1171
#                   
1172
        {
1172
#
1173
            Error ("CopyDir: Cannot find source dir in any package: $user_src_dir") unless ($ignoreNoDir);
1173
# Returns         : Nothing
1174
            Message ("CopyDir: Optional path not found: $user_src_dir");
1174
#
1175
            return;
1175
sub MULTI_Depends
1176
        }
1176
{
1177
 
1177
    return 1 unless ($ActiveSection);
1178
        Error ("CopyDir: Requested path found in mutiple packages: $user_src_dir",
1178
    shift;
1179
                @path ) if ( $#path > 0 );
1179
    my $raw = 0;
1180
        $opt_base = pop @path;
1180
 
1181
 
1181
    #
1182
        #
1182
    #   Convert the provided name into a canonical name
1183
        #   If sourceing from interface, then follow symlinks in the copy.
1183
    #   Simplifies use when using both RPM and Debian
1184
        #   All files will be links anyway
1184
    foreach ( @_)
1185
        #
1185
    {
1186
        #   This is a very ugly test for 'interface'
1186
        if (m~^--(No)?Raw~i) {
1187
        #
1187
            $raw = ! defined($1);
1188
        $from_interface = 1
1188
            next;
1189
            if ( $opt_base =~ m~/interface/~ );
1189
        }
1190
 
1190
        my $name = $_;
1191
    }
1191
        $name = canonicalName($_, $opt_rpm ? 'RPM' : 'DEBIAN' , 1) unless $raw;
1192
 
1192
        push @DependencyList, $name;
1193
    #
1193
    }
1194
    #   Create the full source path
1194
    
1195
    #   May be: from a package, from a known directory, from a local directory
1195
}
1196
    #
1196
 
1197
 
1197
#-------------------------------------------------------------------------------
1198
    $src_dir = $opt_base . '/' . $src_dir if ( $opt_base );
1198
# Function        : PackageDescription
1199
    $src_dir =~ s~//~/~g;
1199
#
1200
    $src_dir =~ s~/$~~;
1200
# Description     : Specify the Package Description
1201
 
1201
#                   Keep it short
1202
    Verbose ("CopyDir: $src_dir, $dst_dir");
1202
#
1203
    unless ( -d $src_dir )
1203
# Inputs          : $description
1204
    {
1204
#
1205
        Error ("CopyDir: Directory not found: $user_src_dir") unless ($ignoreNoDir);
1205
# Returns         : 
1206
        Message ("CopyDir: Optional path not found: $user_src_dir");
1206
#
1207
        return;
1207
sub PackageDescription
1208
    }
1208
{
1209
 
1209
    return 1 unless ($ActiveSection);
1210
    #
1210
    ($opt_description) = @_;
1211
    #   Continue to configure the copy options
1211
}
1212
    #
1212
 
1213
    push (@{$copyOpts{'Ignore'}}, '*.debug', '*.dbg') if $ignoreDbg;
1213
#-------------------------------------------------------------------------------
1214
    $copyOpts{'DuplicateLinks'} = 1 unless ( $from_interface );
1214
# Function        : MakeSymLink
1215
    $copyOpts{'EmptyDirs'} = 1 unless ($isFiltered);
1215
#
1216
 
1216
# Description     : Create a symlink - with error detection
1217
    #
1217
#
1218
    #   Transfer the directory
1218
# Inputs          : old_file    - Link Target
1219
    #
1219
#                                 Path to the link target
1220
    JatsCopy::CopyDir ( $src_dir, $dst_dir, \%copyOpts );
1220
#                                 If an ABS path is provided, the routine will
1221
 
1221
#                                 attempt to create a relative link.
1222
    #
1222
#                   new_file    - Relative to the output work space
1223
    #   If requested, mark files as config files
1223
#                                 Path to where the 'link' file will be created
1224
    #   Must remove the DebianWorkDir prefix
1224
#                   Options     - Must be last
1225
    #
1225
#                                 --NoClean         - Don't play with links
1226
    if(@fileList)
1226
#                                 --NoDotDot        - Don't create symlinks with ..
1227
    {
1227
#
1228
        Verbose ("Mark all transfered files as ConfFiles");
1228
# Returns         : Nothing
1229
        my $removePrefix = length ($DebianWorkDir);
1229
#
1230
        foreach my $file (@fileList)
1230
sub MakeSymLink
1231
        {
1231
{
1232
            push @ConfigList, substr($file, $removePrefix);
1232
    my $no_clean;
1233
        }
1233
    my $no_dot;
1234
    }
1234
    my @args;
1235
 
1235
    return 1 unless ($ActiveSection);
1236
    #
1236
 
1237
    #   Expand link files that may have been copied in
1237
    #
1238
    #
1238
    #   Extract options
1239
    Verbose ("Locate LINKFILES in $DebianWorkDir");
1239
    #
1240
    ExpandLinkFiles();
1240
    foreach ( @_ )
1241
}
1241
    {
1242
 
1242
        if ( m/^--NoClean/i ) {
1243
#-------------------------------------------------------------------------------
1243
            $no_clean = 1;
1244
# Function        : AddInitScript
1244
 
1245
#
1245
        } elsif ( m/^--NoDotDot/i ) {
1246
# Description     : Add an Init Script to the target
1246
            $no_dot = 1;
1247
#                   Optionally create start and stop links
1247
 
1248
#
1248
        } elsif ( m/^--/ ) {
1249
# Inputs          : $script     - Name of the init script
1249
            Error ("MakeSymLink: Unknown option: $_");
1250
#                   $start      - Start Number
1250
 
1251
#                   $stop       - Stop Number
1251
        } else {
1252
#                   Options:
1252
            push @args, $_;
1253
#                       --NoCopy        - Don't copy the script, just add links
1253
        }
1254
#                       --Afc           - Place in AFC init area
1254
    }
1255
#                       --FromPackage   - Source is in a package
1255
 
1256
#
1256
    my ($old_file, $new_file) = @args;
1257
# Returns         : 
1257
 
1258
#
1258
    my $tfile = $WorkDir . '/' . $new_file;
1259
sub AddInitScript
1259
    $tfile =~ s~//~/~;
1260
{
1260
    Verbose ("Symlink $old_file -> $new_file" );
1261
    my $no_copy;
1261
 
1262
    my $basedir = "";
1262
    #
1263
    my @args;
1263
    #   Create the directory in which the link will be placed
1264
    my $from_package = 0;
1264
    #   Remove any existing file of the same name
1265
 
1265
    #
1266
    # This directive is only available on the VIX platforms
1266
    my $dir = StripFileExt( $tfile );
1267
    #   Kludgey test - at the moment
1267
    mkpath( $dir) unless -d $dir;
1268
    #
1268
    unlink $tfile;
1269
    if ($opt_pkgarch =~ m~i386~)
1269
 
1270
    {
1270
    #
1271
        Error ("AddInitScript is not supported on this platform"); 
1271
    #   Determine a good name of the link
1272
    }
1272
    #   Convert to a relative link in an attempt to prune them
1273
 
1273
    #
1274
    #
1274
    my $sfile = $old_file;
1275
    #   Process and Remove options
1275
    unless ( $no_clean )
1276
    #
1276
    {
1277
    foreach  ( @_ )
1277
        $sfile = CalcRelPath( StripFileExt( $new_file ), $old_file );
1278
    {
1278
        $sfile = $old_file if ( $no_dot && $sfile =~ m~^../~ );
1279
        if ( m/^--NoCopy/ ) {
1279
    }
1280
            $no_copy = 1;
1280
 
1281
 
1281
    my $result = symlink $sfile, $tfile;
1282
        } elsif ( m/^--Afc/ ) {
1282
    Error ("Cannot create symlink. $old_file -> $new_file") unless ( $result );
1283
            $basedir = "/afc";
1283
}
1284
 
1284
 
1285
        } elsif ( m/^--FromPackage/ ) {
1285
#-------------------------------------------------------------------------------
1286
            $from_package = 1;
1286
# Function        : CopyFile
1287
 
1287
#
1288
        } elsif ( m/^--/ ) {
1288
# Description     : Copy a file to a target dir
1289
            Error ("AddInitScript: Unknown option: $_");
1289
#                   Used for text files, or files with fixed names
1290
 
1290
#
1291
        } else {
1291
# Inputs          : $src
1292
            push @args, $_;
1292
#                   $dst_dir    - Within the output workspace
1293
 
1293
#                   $dst_name   - Output Name [Optional]
1294
        }
1294
#                   Options     - Common Copy Options
1295
    }
1295
#
1296
 
1296
# Returns         : Full path to destination file
1297
    my( $script, $start, $stop ) = @args;
1297
#
1298
    Error ("No script file specified") unless ( $script );
1298
sub CopyFile
1299
    Warning("AddInitScript: No start or stop index specified") unless ( $start || $stop );
1299
{
1300
    Verbose ("AddInitScript: $script, " . ($start || 'No Start') . ", " . ($stop || 'No Stop'));
1300
    return 1 unless ($ActiveSection);
1301
    $script = ResolveFile($from_package, $script );
1301
    CopyFileCommon( \&ResolveFile, @_ );
1302
 
1302
}
1303
    my $tdir = $basedir . "/etc/init.d/init.d";
1303
 
1304
    my $base = StripDir($script);
1304
#-------------------------------------------------------------------------------
1305
 
1305
# Function        : CopyBinFile
1306
    CopyFile( $script, $tdir ) unless $no_copy;
1306
#
1307
 
1307
# Description     : Copy a file to a target dir
1308
    my $link;
1308
#                   Used for executable programs. Will look in places where
1309
    if ( $start )
1309
#                   programs are stored.
1310
    {
1310
#
1311
        $link = sprintf ("${basedir}/etc/init.d/S%2.2d%s", $start, $base );
1311
# Inputs          : $src
1312
        MakeSymLink( "$tdir/$base", $link);
1312
#                   $dst_dir    - Within the output workspace
1313
    }
1313
#                   $dst_name   - Output Name [Optional]
1314
 
1314
#
1315
    if ( $stop )
1315
#                   Options:
1316
    {
1316
#                       --FromPackage
1317
        $link = sprintf ("${basedir}/etc/init.d/K%2.2d%s", $stop, $base );
1317
#                       --SoftLink=xxxx
1318
        MakeSymLink( "$tdir/$base", $link);
1318
#                       --LinkFile=xxxx
1319
    }
1319
#
1320
}
1320
# Returns         : Full path to destination file
1321
 
1321
#
1322
#-------------------------------------------------------------------------------
1322
sub CopyBinFile
1323
# Function        : CatFile
1323
{
1324
#
1324
    return 1 unless ($ActiveSection);
1325
# Description     : Copy a file to the end of a file
1325
    CopyFileCommon( \&ResolveBinFile, @_ );
1326
#
1326
}
1327
# Inputs          : $src
1327
 
1328
#                   $dst    - Within the output workspace
1328
#-------------------------------------------------------------------------------
1329
#
1329
# Function        : CopyLibFile
1330
# Returns         :
1330
#
1331
#
1331
# Description     : Copy a file to a target dir
1332
sub CatFile
1332
#                   Used for shared programs. Will look in places where
1333
{
1333
#                   shared libraries are stored.
1334
    my ($src, $dst) = @_;
1334
#
1335
 
1335
# Inputs          : $src        - Base for 'realname' (no lib, no extension)
1336
    $dst = $DebianWorkDir . '/' . $dst;
1336
#                   $dst_dir    - Within the output workspace
1337
    $dst =~ s~//~/~;
1337
#                   $dst_name   - Output Name [Optional, but not suggested]
1338
    Verbose ("CatFile: $src, $dst");
1338
#
1339
    $src = ResolveFile(0, $src );
1339
# Returns         : Full path to destination file
1340
 
1340
#
1341
    open (SF, '<', $src)  || Error ("CatFile: Cannot open $src");
1341
# Notes           : Copying 'lib' files
1342
    open (DF, '>>', $dst) || Error ("CatFile: Cannot create:$dst");
1342
#                   These are 'shared libaries. There is no provision for copying
1343
    while ( <SF> )
1343
#                   static libraries.
1344
    {
1344
#
1345
        print DF $_;
1345
#                   The tool will attempt to copy a well-formed 'realname' library
1346
    }
1346
#                   The soname of the library should be constructed on the target
1347
    close (SF);
1347
#                   platform using ldconfig.
1348
    close (DF);
1348
#                   There is no provision to copy the 'linker' name
1349
}
1349
#
1350
 
1350
#                   Given a request to copy a library called 'fred', then the
1351
#-------------------------------------------------------------------------------
1351
#                   well formed 'realname' will be:
1352
# Function        : EchoFile
1352
#                           libfred[P|D|]].so.nnnnn
1353
#
1353
#                   where:
1354
# Description     : Echo simple text to a file
1354
#                           nnnn is the library version
1355
#
1355
#                           [P|D|] indicates Production, Debug or None
1356
# Inputs          : $file   - Within the output workspace
1356
#
1357
#                   $text
1357
#                   The 'soname' is held within the realname form of the library
1358
#
1358
#                   and will be created by lsconfig.
1359
# Returns         : 
1359
#
1360
#
1360
#                   The 'linkername' would be libfred[P|D|].so. This is only
1361
sub EchoFile
1361
#                   needed when linking against the library.
1362
{
1362
#
1363
    my ($file, $text) = @_;
1363
#
1364
    Verbose ("EchoFile: $file");
1364
#                   The routine will also recognize Windows DLLs
1365
 
1365
#                   These are of the form fred[P|D|].nnnnn.dll
1366
    $file = $DebianWorkDir . '/' . $file;
1366
#
1367
    $file =~ s~//~/~;
1367
sub CopyLibFile
1368
 
1368
{
1369
    unlink $file;
1369
    return 1 unless ($ActiveSection);
1370
    open (DT, ">", $file ) || Error ("Cannot create $file");
1370
    CopyFileCommon( \&ResolveLibFile, @_ );
1371
    print DT  $text || Error ("Cannot print to $file");
1371
}
1372
    close DT;
1372
 
1373
}
1373
#-------------------------------------------------------------------------------
1374
 
1374
# Function        : CopyDebianPackage
1375
#-------------------------------------------------------------------------------
1375
#
1376
# Function        : ConvertFiles
1376
# Description     : Copy a Debian Package to a target dir
1377
#
1377
#                   Will look in places where Debian Packages are stored.
1378
# Description     : This sub-routine is used to remove all carrage return\line
1378
#
1379
#                   feeds from a line and replace them with the platform
1379
# Inputs          : $src        - BaseName for 'Debian Package' (no version, no extension)
1380
#                   specific equivalent chars.
1380
#                   $dst_dir    - Within the output workspace
1381
#
1381
#                   Optional arguments embedded into the BaseName
1382
#                   We let PERL determine what characters are written to the
1382
#                   --Arch=XXXX         - Architecture - if not current
1383
#                   file base on the  platform you are running on.
1383
#                   --Product=XXXX      - Product - if required
1384
#
1384
#                   --Debug             - If not the current type
1385
#                   i.e. LF    for unix
1385
#                   --Prod              - If not the current type
1386
#                        CR\LF for win32
1386
#
1387
#
1387
# Returns         : Full path to destination file
1388
# Inputs          : outPath                 - Output directory
1388
#
1389
#                   flist                   - List of files in that directory
1389
# Notes           : Copying Debian Packages from external packages
1390
#                   or
1390
#
1391
#                   SearchOptions           - Search options to find files
1391
#                   The tool will attempt to copy a well-formed debian packages
1392
#                                           --Recurse
1392
#                   These are:
1393
#                                           --NoRecurse
1393
#                   
1394
#                                           --FilterIn=xxx
1394
#                       "BaseName_VersionString[_Product]_Arch${PkgType}.deb";
1395
#                                           --FilterInRe=xxx
1395
#                   
1396
#                                           --FilterOut=xxx
1396
#                   Where 'Product' is optional (and rare)
1397
#                                           --FilterOutRe=xxx
1397
#                   Where 'PkgType' is P or D or nothing
1398
#                   Common options
1398
#                   Where 'Arch' may be 'all'
1399
#                                           --Dos
1399
#                   
1400
#                                           --Unix
1400
#                   The routine will locate Debian packages in
1401
#
1401
#                       - The root of the package
1402
#
1402
#                       - bin/TARGET[P|D/]
1403
# Returns         : 1
1403
#                       - bin/Arch[P|D]
1404
#
1404
#
1405
sub ConvertFiles
1405
#
1406
{
1406
sub CopyDebianPackage
1407
    my @uargs;
1407
{
1408
    my $lineEnding = "\n";
1408
    return 1 unless ($ActiveSection);
1409
    my ($dosSet, $unixSet);
1409
    CopyFileCommon( \&ResolveDebPackage, '--FromPackage', @_ );
1410
    my $search =  JatsLocateFiles->new( '--NoRecurse' );
1410
}
1411
 
1411
 
1412
    #
1412
#-------------------------------------------------------------------------------
1413
    #   Process user arguments extracting options
1413
# Function        : CopyFileCommon
1414
    #
1414
#
1415
    foreach  ( @_ )
1415
# Description     : Common ( internal File Copy )
1416
    {
1416
#
1417
        if ( m~^--Recurse~ ) {
1417
# Inputs          : $resolver           - Ref to function to resolve source file
1418
            $search->recurse(1);
1418
#                   $src                - Source File Name
1419
 
1419
#                   $dst_dir            - Target Dir
1420
        } elsif ( m~^--NoRecurse~) {
1420
#                   $dst_name           - Target Name (optional)
1421
            $search->recurse(0);
1421
#                   Options
1422
 
1422
#                   Options:
1423
        } elsif ( /^--FilterOut=(.*)/ ) {
1423
#                       --FromPackage
1424
            $search->filter_out($1);
1424
#                       --FromBuild
1425
 
1425
#                       --SoftLink=xxxx
1426
        } elsif ( /^--FilterOutRe=(.*)/ ) {
1426
#                       --LinkFile=xxxx
1427
            $search->filter_out_re($1);
1427
#                       --ConfFile
1428
 
1428
#                       --Platform=xxxx[,yyyyy]
1429
        } elsif ( /^--FilterIn=(.*)/ ) {
1429
#
1430
            $search->filter_in($1);
1430
# Returns         : 
1431
 
1431
#
1432
        } elsif ( /^--FilterInRe=(.*)/ ) {
1432
sub CopyFileCommon
1433
            $search->filter_in_re($1);
1433
{
1434
 
1434
    my $from_package = 0;
1435
        } elsif ( m~^--Dos~) {
1435
    my $isa_linkfile = 0;
1436
            $lineEnding = "\r\n";
1436
    my $isa_configFile = 0;
1437
            $dosSet = 1;
1437
    my @llist;
1438
 
1438
    my @args;
1439
        } elsif ( m~^--Unix~) {
1439
    my @platforms;
1440
            $lineEnding = "\n";
1440
 
1441
            $unixSet = 1;
1441
    #
1442
 
1442
    #   Parse options
1443
        } elsif ( m~^--~) {
1443
    #
1444
            Error ("ConvertFiles: Unknown option: $_");
1444
    foreach ( @_ )
1445
 
1445
    {
1446
        } else {
1446
        if ( m/^--FromPackage/ ) {
1447
            push @uargs, $_;
1447
            $from_package = 1;
1448
        }
1448
 
1449
    }
1449
        } elsif ( m/^--FromBuild/ ) {
1450
 
1450
            $from_package = 0;
1451
    #
1451
 
1452
    #   Process non-option arguments
1452
        } elsif ( m/^--LinkFile/ ) {
1453
    #       - Base dir
1453
            $isa_linkfile = 1;
1454
    #       - List of files
1454
 
1455
    #
1455
        } elsif ( m/^--ConfFile/i ) {
1456
    my ($outPath, @flist) = @uargs;
1456
            $isa_configFile = 1;
1457
    Error ("ConvertFiles: Target Dir must be specified" ) unless ( $outPath );
1457
 
1458
 
1458
        } elsif ( m/^--SoftLink=(.+)/ ) {
1459
    #
1459
            push @llist, $1;
1460
    #   Sanity Tests
1460
 
1461
    #
1461
        } elsif ( m/^--Platform=(.+)/ ) {
1462
    Error ("ConvertFiles: --Dos and --Unix are mutually exclusive" ) if ( $dosSet && $unixSet );
1462
            push @platforms, split(',', $1 );
1463
 
1463
 
1464
 
1464
        } elsif ( m/^--/ ) {
1465
    #
1465
            Error ("FileCopy: Unknown option: $_");
1466
    # Convert output path to physical path
1466
 
1467
    #
1467
        } else {
1468
    my $topDir = catdir($DebianWorkDir, $outPath);
1468
            push @args, $_;
1469
    Verbose("ConvertFiles: topDir: $topDir");
1469
        }
1470
    Error ("ConvertFiles: Path does not exist", $topDir) unless ( -e $topDir );
1470
    }
1471
    Error ("ConvertFiles: Path is not a directory", $topDir) unless ( -d $topDir );
1471
 
1472
 
1472
    #
1473
    #
1473
    #   Extract non-options.
1474
    #   Need to determine if we are searching or simply using a file list
1474
    #   These are the bits that are left over
1475
    #   There are two forms of the functions. If any of the search options have
1475
    #
1476
    #   been used then we assume that we are searchine
1476
    my ($resolver, $src, $dst_dir, $dst_name ) = @args;
1477
    #
1477
 
1478
    if ( $search->has_filter() )
1478
    #
1479
    {
1479
    #   Clean up dest_dir. Must start with a / and not end with one
1480
        Error ("ConvertFiles: Cannot mix search options with named files") if ( @flist );
1480
    #
1481
        @flist = $search->search($topDir);
1481
    $dst_dir = "/$dst_dir/";
1482
    }
1482
    $dst_dir =~ s~/+~/~g;
1483
    Error ("ConvertFiles: No files specified") unless ( @flist );
1483
    $dst_dir =~ s~/$~~;
1484
 
1484
 
1485
    #
1485
    Verbose ("CopyFile: $src, $dst_dir, " . ($dst_name || ''));
1486
    #   Process all named files
1486
    foreach $src ( &$resolver( $from_package, $src, \@platforms ) )
1487
    #
1487
    {
1488
    foreach my $file ( @flist )
1488
        my $dst_fname = $dst_name ? $dst_name : StripDir($src);
1489
    {
1489
        my $dst_file = "$dst_dir/$dst_fname";
1490
 
1490
        Verbose ("CopyFile: Copy $src, $dst_file" );
1491
        # this is our file that we want to clean.
1491
        
1492
        my ($ifileLoc) = "$topDir/$file";
1492
 
1493
        my ($tfileLoc) = "$topDir/$file\.tmp";
1493
        #
1494
        Verbose("ConvertFiles: $file");
1494
        #   LinkFiles are special
1495
 
1495
        #   They get concatenated to any existing LINKS File
1496
        # we will check to see if the file exists.
1496
        #
1497
        #
1497
        if ( $isa_linkfile )
1498
        my $ifile;
1498
        {
1499
        my $tfile;
1499
            CatFile ( $src, "$dst_dir/.LINKS" );
1500
        if ( -f "$ifileLoc" )
1500
        }
1501
        {
1501
        else
1502
            open ($ifile, "< $ifileLoc" ) or
1502
        {
1503
                Error("Failed to open file [$ifileLoc] : $!");
1503
            mkpath( "$WorkDir$dst_dir", 0, 0775);
1504
 
1504
            unlink ("$WorkDir$dst_file");
1505
            open ($tfile, "> $tfileLoc" ) or
1505
            System ('cp','-f', $src, "$WorkDir$dst_file" );
1506
                Error("Failed to open file [$tfileLoc] : $!");
1506
 
1507
            binmode $tfile;
1507
            foreach my $lname ( @llist )
1508
 
1508
            {
1509
            while ( <$ifile> ) 
1509
                $lname = $dst_dir . '/' . $lname unless ( $lname =~ m ~^/~ );
1510
            {
1510
                MakeSymLink( $dst_file ,$lname);
1511
                s~[\n\r]+$~~;               # Chomp
1511
            }
1512
                print $tfile "$_" . $lineEnding;
1512
        }
1513
            }
1513
 
1514
        }
1514
        #
1515
        else
1515
        #   ConfigFiles are marked so that they can be handled by the debain installer
1516
        {
1516
        #
1517
            Error("ConvertFiles [$ifileLoc] does not exist.");
1517
        if ($isa_configFile)
1518
        }
1518
        {
1519
 
1519
            push @ConfigList, $WorkSubDir . $dst_file;
1520
        close $ifile;
1520
        }
1521
        close $tfile;
1521
    }
1522
 
1522
}
1523
 
1523
 
1524
        # lets replace our original file with the new one
1524
#-------------------------------------------------------------------------------
1525
        #
1525
# Function        : ExtractTar 
1526
        if(File::Copy::move("$tfileLoc", "$ifileLoc"))
1526
#
1527
        {
1527
# Description     : Extract a tar file into a target directory
1528
            Verbose2("ConvertFiles: Renamed [$tfileLoc] to [$ifileLoc] ...");
1528
#                   Useful for massive structures and those with embedded symlinks
1529
        }
1529
#                   Performs an implicit merge
1530
        else
1530
#                   Will create output root if it does not exist
1531
        {
1531
#
1532
            Error("ConvertFiles: Failed to rename file [$tfileLoc] to [$ifileLoc]: $!");
1532
# Inputs          : $srcTar      - Source Tar file
1533
        }
1533
#                   $dst_dir     - Within the output workspace
1534
    }
1534
#                   Options
1535
 
1535
#                       --Source=Name           - Source via Symbolic Name
1536
    return 1;
1536
#                       --FromPackage           - Source via package roots
1537
}
1537
#                       --Strip=nn              - Strip nn path elements from the dir
1538
 
1538
#
1539
#----------------------------------------------------------------------------
1539
# Returns         : 
1540
# Function        : ReplaceTags
1540
#
1541
#
1541
sub ExtractTar
1542
# Description     : This sub-routine is used to replace Tags in one or more files
1542
{
1543
#
1543
    my ($srcTar, $dst_dir, @opts) = @_;
1544
# Inputs          : outPath                 - Output directory
1544
    my $userSrcTar = $srcTar;
1545
#                   flist                   - List of files in that directory
1545
    my $opt_source;
1546
#                   or
1546
    my $opt_package;
1547
#                   SearchOptions           - Search options to find files
1547
    my $opt_strip;
1548
#                                           --Recurse
1548
    my $opt_base;
1549
#                                           --NoRecurse
1549
    my $from_interface;
1550
#                                           --FilterIn=xxx
1550
    my $dname = StripDir($userSrcTar);
1551
#                                           --FilterInRe=xxx
1551
    my $errConfig = ErrorReConfig( prefix => "ExtractTar($dname): ");
1552
#                                           --FilterOut=xxx
1552
    #
1553
#                                           --FilterOutRe=xxx
1553
    #   Setup the basic options
1554
#                   Common options
1554
    #       May be altered as we parse user options
1555
#                                           --Tag=Tag,Replace
1555
    #
1556
#                                           
1556
    $dst_dir = $WorkDir . '/' . $dst_dir;
1557
#
1557
    $dst_dir =~ s~//~/~;
1558
# Returns         : 1
1558
 
1559
#
1559
    #
1560
sub ReplaceTags
1560
    #   Scan and collect user options
1561
{
1561
    #
1562
    my @uargs;
1562
    foreach  ( @opts )
1563
    my $search =  JatsLocateFiles->new( '--NoRecurse' );
1563
    {
1564
    my @tagsList;
1564
        Verbose2 ("$_");
1565
    my $tagSep = ',';
1565
        if ( m/^--Source=(.+)/ ) {
1566
    my @tagOrder;
1566
            Error ("Source directory can only be specified once")
1567
    my %tagData;
1567
                if ( defined $opt_source );
1568
 
1568
            $opt_source = $1;
1569
    #
1569
 
1570
    #   Process user arguments extracting options
1570
        } elsif ( m/^--FromPackage/ ) {
1571
    #
1571
            Error ("FromPackage can only be specified once")
1572
    foreach  ( @_ )
1572
                if ( defined $opt_package );
1573
    {
1573
            $opt_package = 1;
1574
        if ( m~^--Recurse~ ) {
1574
 
1575
            $search->recurse(1);
1575
        } elsif ( m/^--Strip=(\d+)$/i ) {
1576
 
1576
            Error ("Strip can only be specified once")
1577
        } elsif ( m~^--NoRecurse~) {
1577
                if ( defined $opt_package );
1578
            $search->recurse(0);
1578
            $opt_strip = $1;
1579
 
1579
 
1580
        } elsif ( /^--FilterOut=(.*)/ ) {
1580
        } else {
1581
            $search->filter_out($1);
1581
            Error ("Unknown option: $_" );
1582
 
1582
        }
1583
        } elsif ( /^--FilterOutRe=(.*)/ ) {
1583
    }
1584
            $search->filter_out_re($1);
1584
 
1585
 
1585
    #
1586
        } elsif ( /^--FilterIn=(.*)/ ) {
1586
    #   All options have been gathered. Now process some of them
1587
            $search->filter_in($1);
1587
    #
1588
 
1588
    Error ("Cannot use both --Source and --FromPackage: $srcTar") if ($opt_source && $opt_package);
1589
        } elsif ( /^--FilterInRe=(.*)/ ) {
1589
 
1590
            $search->filter_in_re($1);
1590
    #
1591
 
1591
    #   Convert a symbolic path into a physical path
1592
        } elsif ( m~^--Tag=(.*)~) {
1592
    #
1593
            push @tagsList, $1;
1593
    if ($opt_source)
1594
 
1594
    {
1595
        } elsif ( m~^--~) {
1595
        Verbose2 ("Determine Source: $opt_source");
1596
            Error ("ReplaceTags: Unknown option: $_");
1596
 
1597
 
1597
        $opt_source = lc($opt_source);
1598
        } else {
1598
        my %ExtractTarSymbolic = (
1599
            push @uargs, $_;
1599
            'interfaceincdir'   => $opt_interfaceincdir,
1600
        }
1600
            'interfacelibdir'   => $opt_interfacelibdir,
1601
    }
1601
            'interfacebindir'   => $opt_interfacebindir,
1602
 
1602
            'libdir'            => $opt_libdir,
1603
    #
1603
            'bindir'            => $opt_bindir,
1604
    #   Process non-option arguments
1604
            'localincdir'       => $opt_localincdir,
1605
    #       - Base dir
1605
            'locallibdir'       => $opt_locallibdir,
1606
    #       - List of files
1606
            'localbindir'       => $opt_localbindir,
1607
    #
1607
            'packagebindir'     => $opt_pkgbindir,
1608
    my ($outPath, @flist) = @uargs;
1608
            'packagelibdir'     => $opt_pkglibdir,
1609
    Error ("ReplaceTags: Target Dir must be specified" ) unless ( $outPath );
1609
            'packagepkgdir'     => $opt_pkgpkgdir,
1610
 
1610
            'packagedir'        => $opt_pkgdir,
1611
    #
1611
        );
1612
    #   Sanity Tests
1612
 
1613
    #
1613
        if ( exists $ExtractTarSymbolic{$opt_source} )
1614
    Error ("ReplaceTags: No tags specified" ) unless ( @tagsList );
1614
        {
1615
 
1615
            $opt_base = $ExtractTarSymbolic{$opt_source};
1616
    #
1616
 
1617
    # Convert output path to physical path
1617
            #
1618
    #
1618
            #   If sourceing from interface, then follow
1619
    my $topDir = catdir($DebianWorkDir, $outPath);
1619
            #   symlinks in the copy. All files will be links anyway
1620
    Verbose("ReplaceTags: topDir: $topDir");
1620
            #
1621
    Error ("ReplaceTags: Path does not exist", $topDir) unless ( -e $topDir );
1621
            $from_interface = 1
1622
    Error ("ReplaceTags: Path is not a directory", $topDir) unless ( -d $topDir );
1622
                if ( $opt_source =~ m~^interface~ );
1623
 
1623
        }
1624
    #
1624
        else
1625
    #   Convert Tags into pairs for latter use
1625
        {
1626
    #
1626
            DebugDumpData ("ExtractTarSymbolic", \%ExtractTarSymbolic);
1627
    my $sep = quotemeta ($tagSep );
1627
            Error ("Unknown Source Name: $opt_source" );
1628
    foreach my $tag ( @tagsList )
1628
        }
1629
    {
1629
    }
1630
        my ($tname,$tvalue) = split ( $sep, $tag, 2 );
1630
 
1631
        Error ("No tag value in: $tag" ) unless ( defined $tvalue );
1631
    #
1632
        Error ("Duplicate Tag: $tname" ) if ( exists $tagData{$tname} );
1632
    #   Locate the path within an external package
1633
        Verbose ("Tag: $tname :: $tvalue");
1633
    #
1634
        push @tagOrder, $tname;
1634
    if ($opt_package)
1635
        $tagData{$tname} = $tvalue;
1635
    {
1636
    }
1636
        Verbose2 ("FromPackage: $srcTar");
1637
 
1637
 
1638
    #
1638
        my @path;
1639
    #   Need to determine if we are searching or simply using a file list
1639
        my @scanned;
1640
    #   There are two forms of the functions. If any of the search options have
1640
        foreach my $entry ( getPackageList() )
1641
    #   been used then we assume that we are searchine
1641
        {
1642
    #
1642
            my $base = $entry->getBase(3);
1643
    if ( $search->has_filter() )
1643
            next unless ( defined $base );
1644
    {
1644
            push @scanned, $base;
1645
        Error ("ReplaceTags: Cannot mix search options with named files") if ( @flist );
1645
            if ( -f $base . '/' . $srcTar )
1646
        @flist = $search->search($topDir);
1646
            {
1647
    }
1647
                push @path, $base;
1648
    Error ("ReplaceTags: No files specified") unless ( @flist );
1648
                $from_interface = 1
1649
 
1649
                    if ( $entry->{'TYPE'} eq 'interface' );
1650
    #
1650
            }
1651
    #   Process all named files
1651
        }
1652
    #
1652
 
1653
    foreach my $file ( @flist )
1653
        if ( $#path < 0 )
1654
    {
1654
        {
1655
 
1655
            Error ("Cannot find source dir in any package: $userSrcTar", @scanned);
1656
        # this is our file that we want to clean.
1656
        }
1657
        my ($ifileLoc) = "$topDir/$file";
1657
 
1658
        my ($tfileLoc) = "$topDir/$file\.tmp";
1658
        Error ("Requested path found in mutiple packages: $userSrcTar",
1659
        Verbose("ReplaceTags: $file");
1659
                @path ) if ( $#path > 0 );
1660
 
1660
        $opt_base = pop @path;
1661
        # we will check to see if the file exists.
1661
 
1662
        #
1662
        #
1663
        my $ifile;
1663
        #   If sourceing from interface, then follow symlinks in the copy.
1664
        my $tfile;
1664
        #   All files will be links anyway
1665
        if ( -f "$ifileLoc" )
1665
        #
1666
        {
1666
        #   This is a very ugly test for 'interface'
1667
            open ($ifile, "< $ifileLoc" ) or
1667
        #
1668
                Error("Failed to open file [$ifileLoc] : $!");
1668
        $from_interface = 1
1669
 
1669
            if ( $opt_base =~ m~/interface/~ );
1670
            open ($tfile, "> $tfileLoc" ) or
1670
    }
1671
                Error("Failed to open file [$tfileLoc] : $!");
1671
 
1672
 
1672
    #
1673
            while ( <$ifile> ) 
1673
    #   Create the full source path
1674
            {
1674
    #   May be: from a package, from a known directory, from a local directory
1675
                s~[\n\r]+$~~;               # Chomp
1675
    #
1676
 
1676
    $srcTar = $opt_base . '/' . $srcTar if ( $opt_base );
1677
                #
1677
    $srcTar =~ s~//~/~g;
1678
                #   Perform tag replacement
1678
 
1679
                #
1679
    Verbose ("$srcTar, $dst_dir");
1680
                foreach my $tag ( @tagOrder )
1680
    Error ("Tar File not found: $userSrcTar") unless ( -f $srcTar );
1681
                {
1681
 
1682
                    my $value = $tagData{$tag};
1682
    #
1683
                    if ( s~$tag~$value~g )
1683
    #   Create the output path if it does not exist
1684
                    {
1684
    #
1685
                        Verbose2("Replaced: $tag with $value");
1685
    mkpath( $dst_dir ) unless -d $dst_dir;
1686
                    }
1686
 
1687
                }
1687
    #
1688
 
1688
    #   Generate and execute the tar command
1689
                print $tfile "$_\n";
1689
    #   
1690
            }
1690
    my @cmd = qw (tar -x --keep-old-files);
1691
        }
1691
    push @cmd, '-f', $srcTar;
1692
        else
1692
    push (@cmd, qw(-v --show-transformed-names)) if ($opt_verbose > 2);
1693
        {
1693
    push (@cmd, "--strip=$opt_strip") if (defined $opt_strip);
1694
            Error("ReplaceTags [$ifileLoc] does not exist.");
1694
    push @cmd, '-C', $dst_dir;
1695
        }
1695
    System (@cmd);
1696
 
1696
}
1697
        close $ifile;
1697
 
1698
        close $tfile;
1698
 
1699
 
1699
#-------------------------------------------------------------------------------
1700
 
1700
# Function        : CopyDir
1701
        # lets replace our original file with the new one
1701
#
1702
        #
1702
# Description     : Copy a directory to a target dir
1703
        if(File::Copy::move("$tfileLoc", "$ifileLoc"))
1703
#
1704
        {
1704
# Inputs          : $src_dir    - Local to the user
1705
            Verbose2("ReplaceTags: Renamed [$tfileLoc] to [$ifileLoc] ...");
1705
#                                 Symbolic Name
1706
        }
1706
#                   $dst_dir    - Within the output workspace
1707
        else
1707
#                   Options
1708
        {
1708
#                       --Merge                 - Don't delete first
1709
            Error("ReplaceTags: Failed to rename file [$tfileLoc] to [$ifileLoc]: $!");
1709
#                       --Source=Name           - Source via Symbolic Name
1710
        }
1710
#                       --FromPackage           - Source via package roots
1711
    }
1711
#                       --NoIgnoreDbgFiles      - Do not ignore .dbg and .debug files in dir copy
1712
 
1712
#                       --IfPresent             - Not an error if the path cannot be found
1713
    return 1;
1713
#                       --ConfFile              - Mark transferred files as config files
1714
}
1714
#                       --Flatten               - Copy all to one directory
1715
 
1715
#                       --FilterOut=xxx         - Ignore files. DOS Wildcard
1716
#-------------------------------------------------------------------------------
1716
#                       --FilterOutRe=xxx       - Ignore files. Regular expression name
1717
# Function        : SetFilePerms
1717
#                       --FilterOutDir=xxx      - Ignore directories. DOS Wilcard
1718
#
1718
#                       --FilterOutDirRe=xxx    - Ignore directories. Regular expression name
1719
# Description     : Set file permissions on one or more files or directories
1719
#                       --SkipTLF               - Ignore files in the Top Level Directory
1720
#
1720
#                       --NoRecurse             - Only process files in the Top Level Directory
1721
# Inputs          : $perm           - Perm Mask
1721
#                       --FilterIn=xxx          - Include files. DOS Wildcard
1722
#                   @paths          - List of paths/files to process
1722
#                       --FilterInRe=xxx        - Include files. Regular expression name
1723
#                   Options
1723
#                       --FilterInDir=xxx       - Include directories. DOS Wilcard
1724
#                       --Recurse   - Recurse subdirs
1724
#                       --FilterInDirRe=xxx     - Include directories. Regular expression name
1725
#
1725
#
1726
# Returns         : 
1726
# Returns         :
1727
#
1727
#
1728
sub SetFilePerms
1728
sub CopyDir
1729
{
1729
{
1730
 
1730
    my ($src_dir, $dst_dir, @opts) = @_;
1731
    my @args;
1731
    my $opt_base;
1732
    my $perms;
1732
    my $from_interface = 0;
1733
    my $recurse = 0;
1733
    my $ignoreDbg = 1;
1734
 
1734
    my $ignoreNoDir;
1735
    #
1735
    my $user_src_dir = $src_dir;
1736
    #   Process and Remove options
1736
    my $opt_source;
1737
    #
1737
    my $opt_package;
1738
    foreach  ( @_ )
1738
    my @fileList;
1739
    {
1739
    my $isFiltered;
1740
        if ( m/^--Recurse/ ) {
1740
    return 1 unless ($ActiveSection);
1741
            $recurse = 1;
1741
 
1742
 
1742
    #
1743
        } elsif ( m/^--/ ) {
1743
    #   Setup the basic copy options
1744
            Error ("SetFilePerms: Unknown option: $_");
1744
    #       May be altered as we parse user options
1745
 
1745
    #
1746
        } else {
1746
    my %copyOpts;
1747
            push @args, $_;
1747
    $copyOpts{'IgnoreDirs'} = ['.svn', '.git', '.cvs', '.hg'];
1748
 
1748
    $copyOpts{'Ignore'} = ['.gbedir', '_gbedir'];
1749
        }
1749
    $copyOpts{'Log'} = 1 if ( $opt_verbose > 1 );
1750
    }
1750
    $copyOpts{'DeleteFirst'} = 1;
1751
 
1751
 
1752
    $perms = shift @args;
1752
    $dst_dir = $WorkDir . '/' . $dst_dir;
1753
    Error ("SetFilePerms: No Permissions" ) unless ( $perms );
1753
    $dst_dir =~ s~//~/~;
1754
 
1754
 
1755
    foreach my $path ( @args )
1755
    #
1756
    {
1756
    #   Scan and collect user options
1757
        Verbose ("Set permissions; $perms, $path");
1757
    #
1758
        my $full_path = $DebianWorkDir . '/' . $path;
1758
    foreach  ( @opts )
1759
        if ( -f $full_path )
1759
    {
1760
        {
1760
        Verbose2 ("CopyDir: $_");
1761
            System ('chmod', $perms, $full_path );
1761
        if ( m/^--Merge/ ) {
1762
        }
1762
            $copyOpts{'DeleteFirst'} = 0;
1763
        elsif ( -d $full_path )
1763
 
1764
        {
1764
        } elsif ( m/^--Source=(.+)/ ) {
1765
            System ('chmod', '-R', $perms, $full_path ) if ($recurse);
1765
            Error ("Source directory can only be specified once")
1766
            System ('chmod', $perms, $full_path ) unless ($recurse);
1766
                if ( defined $opt_source );
1767
        }
1767
            $opt_source = $1;
1768
        else
1768
 
1769
        {
1769
        } elsif ( m/^--FromPackage/ ) {
1770
            Warning("SetFilePerms: Path not found: $path");
1770
            Error ("FromPackage can only be specified once")
1771
        }
1771
                if ( defined $opt_package );
1772
    }
1772
            $opt_package = 1;
1773
}
1773
 
1774
 
1774
        } elsif ( m/^--NoIgnoreDbgFiles/ ) {
1775
#-------------------------------------------------------------------------------
1775
            $ignoreDbg = 0;
1776
# Function        : SetPermissions 
1776
 
1777
#
1777
        } elsif ( m/^--IfPresent/ ) {
1778
# Description     : Called to set permissions of files/dirs in a directory structure.
1778
            $ignoreNoDir = 1;
1779
#                   With no options sets DirTag and all files/dirs in it to perms
1779
            
1780
#   
1780
        } elsif ( m/^--ConfFile/i ) {
1781
# Inputs          : path        - The directory tag to start setting permissions on
1781
            $copyOpts{'FileList'} = \@fileList;
1782
#                   Options     - See below
1782
           
1783
#       
1783
        } elsif ( m/^--Flatten/i ) {
1784
#   Required Options:
1784
            $copyOpts{'Flatten'} = 1;
1785
#       One or both of
1785
 
1786
#               --FilePerms=    Sets the permissions of files to this permission.
1786
        } elsif ( m/^--FilterOut=(.+)/i ) {
1787
#                               If not supplied then no files have their permissions changed
1787
            push (@{$copyOpts{'Ignore'}}, $1);
1788
#               --DirPerms=     Sets the permissions of directories to this permission
1788
            $isFiltered = 1;
1789
#                               If not supplied then no directories have their permissions changed
1789
 
1790
#       OR
1790
        } elsif ( m/^--FilterOutRe=(.+)/i ) {
1791
#               --Perms=        Sets the permissions of both files and directories to this permissions
1791
            push (@{$copyOpts{'IgnoreRE'}}, $1);
1792
#                               Equivalent to supplying both --FilePerms=X && --DirPerms=X
1792
            $isFiltered = 1;
1793
#               
1793
 
1794
#   Options:                    
1794
        } elsif ( m/^--FilterOutDir=(.+)/i ) {
1795
#               --RootOnly      Only sets the permissions on the 'path' directory/file, 
1795
            push (@{$copyOpts{'IgnoreDirs'}}, $1);
1796
#                               all other options ignored
1796
            $isFiltered = 1;
1797
#               --SkipRoot      Does not set permissions on the 'path' directory/file, 
1797
 
1798
#                               obviously mutually exlusive with --RootOnly
1798
        } elsif ( m/^--FilterOutDirRe=(.+)/i ) {
1799
#   
1799
            push (@{$copyOpts{'IgnoreDirsRE'}}, $1);
1800
#       Any option supported by JatsLocateFiles. 
1800
            $isFiltered = 1;
1801
#       Some of these include:
1801
 
1802
#               
1802
        } elsif ( m/^--FilterIn=(.+)/i ) {
1803
#               --Recurse       Recurse the directory tree.  Does a depth first recurse so that all 
1803
            push (@{$copyOpts{'Match'}}, $1);
1804
#                               dir entries are processed before the dir itself (default)
1804
            $isFiltered = 1;
1805
#               --NoRecurse     Dont recurse
1805
 
1806
#               --FilterIn=     Apply permissions to files/directories that matches this value.
1806
        } elsif ( m/^--FilterInRe=(.+)/i ) {
1807
#               --FilterInRe=   Perl RE's can be used (Not Shell wildcards) and this option
1807
            push (@{$copyOpts{'MatchRE'}}, $1);
1808
#                               can be supplied mulitple times
1808
            $isFiltered = 1;
1809
#               --FilterOut=    Dont apply permissions to any files/directories matching this value
1809
 
1810
#               --FilterOutRe=  Perl RE's can be used (Not Shell wildcards) and this option
1810
        } elsif ( m/^--FilterInDir=(.+)/i ) {
1811
#                               can be supplied mulitple times
1811
            push (@{$copyOpts{'MatchDirs'}}, $1);
1812
#               
1812
            $isFiltered = 1;
1813
#                               FilterIn is applied before FilterOut.  If Recurse is specified 
1813
 
1814
#                               the directory will be recursed regardless of these filters, however
1814
        } elsif ( m/^--FilterInDirRe=(.+)/i ) {
1815
#                               the filter will be applied when it comes time to chmod the dir 
1815
            push (@{$copyOpts{'MatchDirsRE'}}, $1);
1816
#
1816
            $isFiltered = 1;
1817
#------------------------------------------------------------------------------
1817
 
1818
sub SetPermissions
1818
        } elsif ( m/^--SkipTLF$/i ) {
1819
{
1819
            $copyOpts{'SkipTLF'} = 1;
1820
    my ( $path, $filePerms, $dirPerms, $someDone );
1820
 
1821
    my ( $rootOnly, $skipRoot ) = ( 0, 0 );
1821
        } elsif ( m/^--NoRecurse$/i ) {
1822
    
1822
            $copyOpts{'NoSubDirs'} = 1;
1823
    my $search =  JatsLocateFiles->new( '--Recurse', '--DirsToo' );
1823
 
1824
 
1824
        } else {
1825
    foreach ( @_ )
1825
            Error ("CopyDir: Unknown option: $_" );
1826
    {
1826
        }
1827
        if ( m/^--Perms=(.*)/ ) {
1827
    }
1828
            $filePerms = $1;
1828
 
1829
            $dirPerms = $1;
1829
    #
1830
 
1830
    #   All options have been gathered. Now process some of them
1831
        } elsif (m/^--FilePerms=(.*)/ )  {
1831
    #
1832
            $filePerms = $1;
1832
    Error ("CopyDir: Cannot use both --Source and --FromPackage: $src_dir") if ($opt_source && $opt_package);
1833
 
1833
 
1834
        } elsif ( m/^--DirPerms=(.*)/ )  {
1834
    #
1835
            $dirPerms = $1;
1835
    #   Convert a symbolic path into a physical path
1836
 
1836
    #
1837
        }  elsif ( m/^--RootOnly/ ) {
1837
    if ($opt_source)
1838
            $rootOnly = 1;
1838
    {
1839
 
1839
        Verbose2 ("CopyDir: Determine Source: $opt_source");
1840
        } elsif ( m/^--SkipRoot/ )  {
1840
 
1841
            $skipRoot = 1;
1841
        $opt_source = lc($opt_source);
1842
 
1842
        my %CopyDirSymbolic = (
1843
        } elsif ( m/^--Filter/ && $search->option( $_ ) ) {
1843
            'interfaceincdir'   => $opt_interfaceincdir,
1844
            Verbose2 ("Search Option: $_" );
1844
            'interfacelibdir'   => $opt_interfacelibdir,
1845
 
1845
            'interfacebindir'   => $opt_interfacebindir,
1846
        } elsif ( m/^--Recurse|--NoRecurse/ && $search->option( $_ ) ) {
1846
            'libdir'            => $opt_libdir,
1847
            Verbose2 ("Search Option: $_" );
1847
            'bindir'            => $opt_bindir,
1848
 
1848
            'localincdir'       => $opt_localincdir,
1849
        } elsif (m/^--/ ) {
1849
            'locallibdir'       => $opt_locallibdir,
1850
            Error ("SetPermissions: Unknown option: $_");
1850
            'localbindir'       => $opt_localbindir,
1851
 
1851
            'packagebindir'     => $opt_pkgbindir,
1852
        } else  {
1852
            'packagelibdir'     => $opt_pkglibdir,
1853
            Error("SetPermissions 'path' already set", "Path: $_") if ( $path );
1853
            'packagepkgdir'     => $opt_pkgpkgdir,
1854
            $path = $_;
1854
            'packagedir'        => $opt_pkgdir,
1855
        }
1855
        );
1856
    }
1856
 
1857
 
1857
        if ( exists $CopyDirSymbolic{$opt_source} )
1858
    #
1858
        {
1859
    #   Sanity test
1859
            $opt_base = $CopyDirSymbolic{$opt_source};
1860
    #
1860
 
1861
    Error("SetPermissions called with out a 'path' parameter") if ( !defined($path) );
1861
            #
1862
    Error("SetPermissions called with out any Permissions specified") if ( !defined($filePerms) && !defined($dirPerms) );
1862
            #   If sourceing from interface, then follow
1863
    Error("SetPermissions: Options --RootOnly & --SkipRoot are mutually exclusive" ) if ( $rootOnly && $skipRoot );
1863
            #   symlinks in the copy. All files will be links anyway
1864
 
1864
            #
1865
 
1865
            $from_interface = 1
1866
    #   Convert the target directory name into a physical path
1866
                if ( $opt_source =~ m~^interface~ );
1867
    #   User specifies '/' as the root of the image
1867
        }
1868
    #   User specifies 'name' as relateve to the root of the image
1868
        else
1869
    #
1869
        {
1870
    my $topDir = $DebianWorkDir . '/' . $path;
1870
            DebugDumpData ("CopyDirSymbolic", \%CopyDirSymbolic);
1871
    $topDir =~ s~/+$~~;
1871
            Error ("CopyDir: Unknown Source Name: $opt_source" );
1872
 
1872
        }
1873
    Verbose("SetPermissions: Called with options " . join(", ", @_));
1873
    }
1874
 
1874
 
1875
    #
1875
    #
1876
    #   Only set perms on the root directory
1876
    #   Locate the path within an external package
1877
    #       This is a trivial operation
1877
    #
1878
    #
1878
    if ($opt_package)
1879
    if ( $rootOnly )
1879
    {
1880
    {
1880
        Verbose2 ("CopyDir: FromPackage: $src_dir");
1881
        $someDone += chmodItem( $topDir, $filePerms, $dirPerms );
1881
 
1882
    }
1882
        my @path;
1883
    else
1883
        foreach my $entry ( getPackageList() )
1884
    {
1884
        {
1885
        #
1885
            my $base = $entry->getBase(3);
1886
        #   Create a list of files/dirs to process
1886
            next unless ( defined $base );
1887
        #
1887
            if ( -d $base . '/' . $src_dir )
1888
        my @elements = $search->search( $topDir );
1888
            {
1889
 
1889
                push @path, $base;
1890
        foreach my $dirEntry ( @elements )
1890
                $from_interface = 1
1891
        {
1891
                    if ( $entry->{'TYPE'} eq 'interface' );
1892
            my $fullPath = "$topDir/$dirEntry";
1892
            }
1893
 
1893
        }
1894
            # A dir and we dont have dirperms, so skip
1894
 
1895
            if ( -d $fullPath && !defined($dirPerms) )
1895
        if ( $#path < 0 )
1896
            {
1896
        {
1897
                Verbose2("SetPermissions: Skipping dir $fullPath as we have no dir permissions");
1897
            Error ("CopyDir: Cannot find source dir in any package: $user_src_dir") unless ($ignoreNoDir);
1898
                next;
1898
            Message ("CopyDir: Optional path not found: $user_src_dir");
1899
            }
1899
            return;
1900
 
1900
        }
1901
            # A file and we dont have fileperms, so skip
1901
 
1902
            if ( -f $fullPath && !defined($filePerms) )
1902
        Error ("CopyDir: Requested path found in mutiple packages: $user_src_dir",
1903
            {
1903
                @path ) if ( $#path > 0 );
1904
                Verbose2("SetPermissions: Skipping file $fullPath as we have no file permissions");
1904
        $opt_base = pop @path;
1905
                next;
1905
 
1906
            }
1906
        #
1907
 
1907
        #   If sourceing from interface, then follow symlinks in the copy.
1908
            # a file or a dir and have the right permissions and we are not recursing
1908
        #   All files will be links anyway
1909
            if ( -f $fullPath || -d $fullPath )
1909
        #
1910
            {
1910
        #   This is a very ugly test for 'interface'
1911
                $someDone += chmodItem( $fullPath, $filePerms, $dirPerms );
1911
        #
1912
            }
1912
        $from_interface = 1
1913
            else
1913
            if ( $opt_base =~ m~/interface/~ );
1914
            {
1914
 
1915
                Warning("SetPermissions: Skipping $fullPath as its not a file or directory");
1915
    }
1916
            }
1916
 
1917
        }
1917
    #
1918
 
1918
    #   Create the full source path
1919
        #
1919
    #   May be: from a package, from a known directory, from a local directory
1920
        #   Process the topDir
1920
    #
1921
        #   May not be modified if --SkipRoot has been requested
1921
 
1922
        #
1922
    $src_dir = $opt_base . '/' . $src_dir if ( $opt_base );
1923
        if ( !$skipRoot && -e $topDir )
1923
    $src_dir =~ s~//~/~g;
1924
        {
1924
    $src_dir =~ s~/$~~;
1925
            $someDone += chmodItem( $topDir, $filePerms, $dirPerms );
1925
 
1926
        }
1926
    Verbose ("CopyDir: $src_dir, $dst_dir");
1927
    }
1927
    unless ( -d $src_dir )
1928
 
1928
    {
1929
    #   Final warning
1929
        Error ("CopyDir: Directory not found: $user_src_dir") unless ($ignoreNoDir);
1930
    #
1930
        Message ("CopyDir: Optional path not found: $user_src_dir");
1931
    Warning ("SetPermissions: No files located", "Args: @_") unless ( $someDone );
1931
        return;
1932
}
1932
    }
1933
 
1933
 
1934
#************ INTERNAL USE ONLY  **********************************************
1934
    #
1935
# Function        : chmodItem 
1935
    #   Continue to configure the copy options
1936
#
1936
    #
1937
# Description     : Internal
1937
    push (@{$copyOpts{'Ignore'}}, '*.debug', '*.dbg') if $ignoreDbg;
1938
#                   chmod a file or a folder
1938
    $copyOpts{'DuplicateLinks'} = 1 unless ( $from_interface );
1939
#
1939
    $copyOpts{'EmptyDirs'} = 1 unless ($isFiltered);
1940
# Inputs          : item                        - Item to mod
1940
 
1941
#                   filePerms                   - File perms
1941
    #
1942
#                   dirPerms                    - dire perms
1942
    #   Transfer the directory
1943
#
1943
    #
1944
# Returns         : 1   - Item modified
1944
    JatsCopy::CopyDir ( $src_dir, $dst_dir, \%copyOpts );
1945
#                   0   - Item not modified
1945
 
1946
#
1946
    #
1947
#************ INTERNAL USE ONLY  **********************************************
1947
    #   If requested, mark files as config files
1948
sub chmodItem
1948
    #   Must remove the DebianWorkDir prefix
1949
{
1949
    #
1950
    my ($item, $filePerms, $dirPerms) = @_;
1950
    if(@fileList)
1951
 
1951
    {
1952
    if ( -d $item && defined $dirPerms)
1952
        Verbose ("Mark all transfered files as ConfFiles");
1953
    {
1953
        my $removePrefix = length ($WorkDir);
1954
        Verbose("SetPermissions: $dirPerms : $item");
1954
        foreach my $file (@fileList)
1955
        System ('chmod', $dirPerms, $item );
1955
        {
1956
        return 1;
1956
            push @ConfigList, substr($file, $removePrefix);
1957
    }
1957
        }
1958
 
1958
    }
1959
    if ( -f $item  && defined $filePerms)
1959
 
1960
    {
1960
    #
1961
        Verbose("SetPermissions: $filePerms : $item");
1961
    #   Expand link files that may have been copied in
1962
        System ('chmod', $filePerms, $item );
1962
    #
1963
        return 1;
1963
    Verbose ("Locate LINKFILES in $WorkDir");
1964
    }
1964
    ExpandLinkFiles();
1965
 
1965
}
1966
    return 0;
1966
 
1967
}
1967
#-------------------------------------------------------------------------------
1968
 
1968
# Function        : AddInitScript
1969
 
1969
#
1970
#-------------------------------------------------------------------------------
1970
# Description     : Add an Init Script to the target
1971
# Function        : CreateDir
1971
#                   Optionally create start and stop links
1972
#
1972
#
1973
# Description     : Create a directory within the target workspace
1973
# Inputs          : $script     - Name of the init script
1974
#
1974
#                   $start      - Start Number
1975
# Inputs          : $path           - Name of the target directory
1975
#                   $stop       - Stop Number
1976
#
1976
#                   Options:
1977
# Returns         : Nothing
1977
#                       --NoCopy        - Don't copy the script, just add links
1978
#
1978
#                       --Afc           - Place in AFC init area
1979
sub CreateDir
1979
#                       --FromPackage   - Source is in a package
1980
{
1980
#
1981
    my ($path) = @_;
1981
# Returns         : 
1982
 
1982
#
1983
    Verbose ("Create Dir: $path");
1983
sub AddInitScript
1984
    mkpath( $DebianWorkDir . '/' . $path );
1984
{
1985
}
1985
    my $no_copy;
1986
 
1986
    my $basedir = "";
1987
#-------------------------------------------------------------------------------
1987
    my @args;
1988
# Function        : IsProduct
1988
    my $from_package = 0;
1989
#                   IsPlatform
1989
    return 1 unless ($ActiveSection);
1990
#                   IsTarget
1990
 
1991
#                   IsVariant
1991
    # This directive is only available on the VIX platforms
1992
#                   IsAlias
1992
    #   Kludgey test - at the moment
1993
#
1993
    #
1994
# Description     : This function allows some level of control in the
1994
    if ($opt_pkgarch =~ m~i386~)
1995
#                   packaging scripts. It will return true if the current
1995
    {
1996
#                   product is listed.
1996
        Error ("AddInitScript is not supported on this platform"); 
1997
#
1997
    }
1998
#                   Ugly after thought
1998
 
1999
#
1999
    #
2000
#                   Intended use:
2000
    #   Process and Remove options
2001
#                       Xxxxxx(...) if (IsProduct( 'aaa',bbb' );
2001
    #
2002
#
2002
    foreach  ( @_ )
2003
# Inputs          : products    - a list of products to compare against
2003
    {
2004
#
2004
        if ( m/^--NoCopy/ ) {
2005
# Returns         : True if the current build is for one of the listed products
2005
            $no_copy = 1;
2006
#
2006
 
2007
sub IsProduct
2007
        } elsif ( m/^--Afc/ ) {
2008
{
2008
            $basedir = "/afc";
2009
    foreach ( @_ )
2009
 
2010
    {
2010
        } elsif ( m/^--FromPackage/ ) {
2011
        return 1 if ( $opt_product eq $_ );
2011
            $from_package = 1;
2012
    }
2012
 
2013
    return 0;
2013
        } elsif ( m/^--/ ) {
2014
}
2014
            Error ("AddInitScript: Unknown option: $_");
2015
 
2015
 
2016
sub IsPlatform
2016
        } else {
2017
{
2017
            push @args, $_;
2018
    foreach ( @_ )
2018
 
2019
    {
2019
        }
2020
        return 1 if ( $opt_platform eq $_ );
2020
    }
2021
    }
2021
 
2022
    return 0;
2022
    my( $script, $start, $stop ) = @args;
2023
}
2023
    Error ("No script file specified") unless ( $script );
2024
 
2024
    Warning("AddInitScript: No start or stop index specified") unless ( $start || $stop );
2025
sub IsTarget
2025
    Verbose ("AddInitScript: $script, " . ($start || 'No Start') . ", " . ($stop || 'No Stop'));
2026
{
2026
    $script = ResolveFile($from_package, $script );
2027
    foreach ( @_ )
2027
 
2028
    {
2028
    my $tdir = $basedir . "/etc/init.d/init.d";
2029
        return 1 if ( $opt_target eq $_ );
2029
    my $base = StripDir($script);
2030
    }
2030
 
2031
    return 0;
2031
    CopyFile( $script, $tdir ) unless $no_copy;
2032
}
2032
 
2033
 
2033
    my $link;
2034
sub IsVariant
2034
    if ( $start )
2035
{
2035
    {
2036
    foreach ( @_ )
2036
        $link = sprintf ("${basedir}/etc/init.d/S%2.2d%s", $start, $base );
2037
    {
2037
        MakeSymLink( "$tdir/$base", $link);
2038
        return 1 if ( $opt_variant eq $_ );
2038
    }
2039
    }
2039
 
2040
    return 0;
2040
    if ( $stop )
2041
}
2041
    {
2042
 
2042
        $link = sprintf ("${basedir}/etc/init.d/K%2.2d%s", $stop, $base );
2043
sub IsAlias
2043
        MakeSymLink( "$tdir/$base", $link);
2044
{
2044
    }
2045
 
2045
}
2046
    #
2046
 
2047
    #   Get the aliases from the build info
2047
#-------------------------------------------------------------------------------
2048
    #   This function was introduced late so its not always available
2048
# Function        : CatFile
2049
    #
2049
#
2050
    Error("IsAlias not supported in this version of JATS")
2050
# Description     : Copy a file to the end of a file
2051
        unless (defined &ReadBuildConfig::getAliases);
2051
#
2052
    #
2052
# Inputs          : $src
2053
    #   Create an hash of aliases to simplify testing
2053
#                   $dst    - Within the output workspace
2054
    #   Do it onceand cache the results
2054
#
2055
    #
2055
# Returns         :
2056
    unless (%opt_aliases) {
2056
#
2057
        %opt_aliases = map { $_ => 1 } getAliases();
2057
sub CatFile
2058
    }
2058
{
2059
 
2059
    my ($src, $dst) = @_;
2060
    foreach ( @_ )
2060
    return 1 unless ($ActiveSection);
2061
    {
2061
 
2062
        return 1 if ( exists $opt_aliases{$_} );
2062
    $dst = $WorkDir . '/' . $dst;
2063
    }
2063
    $dst =~ s~//~/~;
2064
    return 0;
2064
    Verbose ("CatFile: $src, $dst");
2065
}
2065
    $src = ResolveFile(0, $src );
2066
 
2066
 
2067
 
2067
    open (SF, '<', $src)  || Error ("CatFile: Cannot open $src");
2068
#************ INTERNAL USE ONLY  **********************************************
2068
    open (DF, '>>', $dst) || Error ("CatFile: Cannot create:$dst");
2069
# Function        : FindFiles
2069
    while ( <SF> )
2070
#
2070
    {
2071
# Description     : Locate files within a given dir tree
2071
        print DF $_;
2072
#
2072
    }
2073
# Inputs          : $root           - Base of the search
2073
    close (SF);
2074
#                   $match          - Re to match
2074
    close (DF);
2075
#
2075
}
2076
# Returns         : A list of files that match
2076
 
2077
#
2077
#-------------------------------------------------------------------------------
2078
#************ INTERNAL USE ONLY  **********************************************
2078
# Function        : EchoFile
2079
my @FIND_LIST;
2079
#
2080
my $FIND_NAME;
2080
# Description     : Echo simple text to a file
2081
 
2081
#
2082
sub FindFiles
2082
# Inputs          : $file   - Within the output workspace
2083
{
2083
#                   $text
2084
    my ($root, $match ) = @_;
2084
#
2085
    Verbose2("FindFiles: Root: $root, Match: $match");
2085
# Returns         : 
2086
 
2086
#
2087
    #
2087
sub EchoFile
2088
    #   Becareful of closure, Must use globals
2088
{
2089
    #
2089
    my ($file, $text) = @_;
2090
    @FIND_LIST = ();
2090
    return 1 unless ($ActiveSection);
2091
    $FIND_NAME = $match;
2091
    Verbose ("EchoFile: $file");
2092
    File::Find::find( \&find_files, $root);
2092
 
2093
 
2093
    $file = $WorkDir . '/' . $file;
2094
    #
2094
    $file =~ s~//~/~;
2095
    #   Find callback program
2095
 
2096
    #
2096
    unlink $file;
2097
    sub find_files
2097
    open (DT, ">", $file ) || Error ("Cannot create $file");
2098
    {
2098
    print DT  $text || Error ("Cannot print to $file");
2099
        my $item =  $File::Find::name;
2099
    close DT;
2100
 
2100
}
2101
        return if ( -d $File::Find::name );
2101
 
2102
        return unless ( $_ =~ m~$FIND_NAME~ );
2102
#-------------------------------------------------------------------------------
2103
        push @FIND_LIST, $item;
2103
# Function        : ConvertFiles
2104
    }
2104
#
2105
    return @FIND_LIST;
2105
# Description     : This sub-routine is used to remove all carrage return\line
2106
}
2106
#                   feeds from a line and replace them with the platform
2107
 
2107
#                   specific equivalent chars.
2108
#-------------------------------------------------------------------------------
2108
#
2109
# Function        : CalcRelPath
2109
#                   We let PERL determine what characters are written to the
2110
#
2110
#                   file base on the  platform you are running on.
2111
# Description     : Return the relative path to the current working directory
2111
#
2112
#                   as provided in $Cwd
2112
#                   i.e. LF    for unix
2113
#
2113
#                        CR\LF for win32
2114
# Inputs          : $Cwd - Base dir
2114
#
2115
#                   $base - Path to convert
2115
# Inputs          : outPath                 - Output directory
2116
#
2116
#                   flist                   - List of files in that directory
2117
# Returns         : Relative path from the $Cwd
2117
#                   or
2118
#
2118
#                   SearchOptions           - Search options to find files
2119
sub CalcRelPath
2119
#                                           --Recurse
2120
{
2120
#                                           --NoRecurse
2121
    my ($Cwd, $base) = @_;
2121
#                                           --FilterIn=xxx
2122
 
2122
#                                           --FilterInRe=xxx
2123
    my @base = split ('/', $base );
2123
#                                           --FilterOut=xxx
2124
    my @here = split ('/', $Cwd );
2124
#                                           --FilterOutRe=xxx
2125
    my $result;
2125
#                   Common options
2126
 
2126
#                                           --Dos
2127
    Debug("RelPath: Source: $base");
2127
#                                           --Unix
2128
 
2128
#
2129
    return $base unless ( $base =~ m~^/~ );
2129
#
2130
    
2130
# Returns         : 1
2131
    #
2131
#
2132
    #   Remove common bits from the head of both lists
2132
sub ConvertFiles
2133
    #
2133
{
2134
    while ( $#base >= 0 && $#here >= 0 && $base[0] eq $here[0] )
2134
    my @uargs;
2135
    {
2135
    return 1 unless ($ActiveSection);
2136
        shift @base;
2136
    my $lineEnding = "\n";
2137
        shift @here;
2137
    my ($dosSet, $unixSet);
2138
    }
2138
    my $search =  JatsLocateFiles->new( '--NoRecurse' );
2139
 
2139
 
2140
    #
2140
    #
2141
    #   Need to go up some directories from here and then down into base
2141
    #   Process user arguments extracting options
2142
    #
2142
    #
2143
    $result = '../' x ($#here + 1);
2143
    foreach  ( @_ )
2144
    $result .= join ( '/', @base);
2144
    {
2145
    $result = '.' unless ( $result );
2145
        if ( m~^--Recurse~ ) {
2146
    $result =~ s~//~/~g;
2146
            $search->recurse(1);
2147
    $result =~ s~/$~~;
2147
 
2148
 
2148
        } elsif ( m~^--NoRecurse~) {
2149
    Debug("RelPath: Result: $result");
2149
            $search->recurse(0);
2150
    return $result;
2150
 
2151
}
2151
        } elsif ( /^--FilterOut=(.*)/ ) {
2152
 
2152
            $search->filter_out($1);
2153
#-------------------------------------------------------------------------------
2153
 
2154
# Function        : ExpandLinkFiles
2154
        } elsif ( /^--FilterOutRe=(.*)/ ) {
2155
#
2155
            $search->filter_out_re($1);
2156
# Description     : Look for .LINK files in the output image and expand
2156
 
2157
#                   the links into softlinks
2157
        } elsif ( /^--FilterIn=(.*)/ ) {
2158
#
2158
            $search->filter_in($1);
2159
# Inputs          : None
2159
 
2160
#                   The rouine works on the $DebianWorkDir directory tree
2160
        } elsif ( /^--FilterInRe=(.*)/ ) {
2161
#
2161
            $search->filter_in_re($1);
2162
# Returns         : Nothing
2162
 
2163
#                   Will remove .LINKS files that are processed
2163
        } elsif ( m~^--Dos~) {
2164
#
2164
            $lineEnding = "\r\n";
2165
sub ExpandLinkFiles
2165
            $dosSet = 1;
2166
{
2166
 
2167
    foreach my $linkfile ( FindFiles( $DebianWorkDir, ".LINKS" ))
2167
        } elsif ( m~^--Unix~) {
2168
    {
2168
            $lineEnding = "\n";
2169
        next if ( $linkfile =~ m~/\.svn/~ );
2169
            $unixSet = 1;
2170
        my $BASEDIR = StripFileExt( $linkfile );
2170
 
2171
        $BASEDIR =~ s~^$DebianWorkDir/~~;
2171
        } elsif ( m~^--~) {
2172
        Verbose "Expand links: $BASEDIR";
2172
            Error ("ConvertFiles: Unknown option: $_");
2173
 
2173
 
2174
        open (LF, "<", $linkfile ) || Error ("Cannot open link file: $linkfile" );
2174
        } else {
2175
        while ( <LF> )
2175
            push @uargs, $_;
2176
        {
2176
        }
2177
            chomp;
2177
    }
2178
            next if ( m~^#~ );
2178
 
2179
            next unless ( $_ );
2179
    #
2180
            my ($link, $file) = split;
2180
    #   Process non-option arguments
2181
 
2181
    #       - Base dir
2182
            MakeSymLink($file ,"$BASEDIR/$link", '--NoDotDot' );
2182
    #       - List of files
2183
        }
2183
    #
2184
        close (LF);
2184
    my ($outPath, @flist) = @uargs;
2185
        unlink $linkfile;
2185
    Error ("ConvertFiles: Target Dir must be specified" ) unless ( $outPath );
2186
    }
2186
 
2187
}
2187
    #
2188
 
2188
    #   Sanity Tests
2189
#************ INTERNAL USE ONLY  **********************************************
2189
    #
2190
# Function        : ResolveFile
2190
    Error ("ConvertFiles: --Dos and --Unix are mutually exclusive" ) if ( $dosSet && $unixSet );
2191
#
2191
 
2192
# Description     : Determine where the source for a file is
2192
 
2193
#                   Will look in (default):
2193
    #
2194
#                       Local directory
2194
    # Convert output path to physical path
2195
#                       Local Include
2195
    #
2196
#                   Or  (FromPackage)
2196
    my $topDir = catdir($WorkDir, $outPath);
2197
#                       Our Package directory
2197
    Verbose("ConvertFiles: topDir: $topDir");
2198
#                       Interface directory (BuildPkgArchives)
2198
    Error ("ConvertFiles: Path does not exist", $topDir) unless ( -e $topDir );
2199
#                       Packages (LinkPkgArchive)
2199
    Error ("ConvertFiles: Path is not a directory", $topDir) unless ( -d $topDir );
2200
#
2200
 
2201
#                   Will scan 'parts' subdirs
2201
    #
2202
#
2202
    #   Need to determine if we are searching or simply using a file list
2203
# Inputs          : $from_package       - 0 - Local File
2203
    #   There are two forms of the functions. If any of the search options have
2204
#                   $file
2204
    #   been used then we assume that we are searchine
2205
#
2205
    #
2206
# Returns         : Path
2206
    if ( $search->has_filter() )
2207
#
2207
    {
2208
#************ INTERNAL USE ONLY  **********************************************
2208
        Error ("ConvertFiles: Cannot mix search options with named files") if ( @flist );
2209
sub ResolveFile
2209
        @flist = $search->search($topDir);
2210
{
2210
    }
2211
    my ($from_package, $file) = @_;
2211
    Error ("ConvertFiles: No files specified") unless ( @flist );
2212
    my $wildcard = ($file =~ /[*?]/);
2212
 
2213
    my @path;
2213
    #
2214
 
2214
    #   Process all named files
2215
    #
2215
    #
2216
    #   Determine the paths to search
2216
    foreach my $file ( @flist )
2217
    #
2217
    {
2218
    if ( $from_package )
2218
 
2219
    {
2219
        # this is our file that we want to clean.
2220
        unless ( @ResolveFileList )
2220
        my ($ifileLoc) = "$topDir/$file";
2221
        {
2221
        my ($tfileLoc) = "$topDir/$file\.tmp";
2222
            push @ResolveFileList, $opt_pkgdir;
2222
        Verbose("ConvertFiles: $file");
2223
            foreach my $entry ( getPackageList() )
2223
 
2224
            {
2224
        # we will check to see if the file exists.
2225
                push @ResolveFileList, $entry->getBase(3);
2225
        #
2226
            }
2226
        my $ifile;
2227
        }
2227
        my $tfile;
2228
        @path = @ResolveFileList;
2228
        if ( -f "$ifileLoc" )
2229
    }
2229
        {
2230
    else
2230
            open ($ifile, "< $ifileLoc" ) or
2231
    {
2231
                Error("Failed to open file [$ifileLoc] : $!");
2232
        @path = ('.', $opt_localincdir);
2232
 
2233
    }
2233
            open ($tfile, "> $tfileLoc" ) or
2234
 
2234
                Error("Failed to open file [$tfileLoc] : $!");
2235
    #
2235
            binmode $tfile;
2236
    #   Determine a full list of 'parts' to search
2236
 
2237
    #   This is provided within the build information
2237
            while ( <$ifile> ) 
2238
    #
2238
            {
2239
    my @parts = getPlatformParts ();
2239
                s~[\n\r]+$~~;               # Chomp
2240
    push @parts, '';
2240
                print $tfile "$_" . $lineEnding;
2241
 
2241
            }
2242
    my @done;
2242
        }
2243
    foreach my $root (  @path )
2243
        else
2244
    {
2244
        {
2245
        foreach my $subdir ( @parts )
2245
            Error("ConvertFiles [$ifileLoc] does not exist.");
2246
        {
2246
        }
2247
            my $sfile;
2247
 
2248
            $sfile = "$root/$subdir/$file";
2248
        close $ifile;
2249
            $sfile =~ s~//~/~g;
2249
        close $tfile;
2250
            $sfile =~ s~^./~~g;
2250
 
2251
            Verbose2("LocateFile: $sfile, $root, $subdir");
2251
 
2252
            if ( $wildcard )
2252
        # lets replace our original file with the new one
2253
            {
2253
        #
2254
                push @done, glob ( $sfile );
2254
        if(File::Copy::move("$tfileLoc", "$ifileLoc"))
2255
            }
2255
        {
2256
            else
2256
            Verbose2("ConvertFiles: Renamed [$tfileLoc] to [$ifileLoc] ...");
2257
            {
2257
        }
2258
                push @done, $sfile if ( -f $sfile || -l $sfile )
2258
        else
2259
            }
2259
        {
2260
        }
2260
            Error("ConvertFiles: Failed to rename file [$tfileLoc] to [$ifileLoc]: $!");
2261
    }
2261
        }
2262
 
2262
    }
2263
    Error ("ResolveFile: File not found: $file", "Search Path:", @path)
2263
 
2264
        unless ( @done );
2264
    return 1;
2265
 
2265
}
2266
    Warning ("ResolveFile: Multiple instances of file found. Only first is used", @done)
2266
 
2267
        if ( $#done > 0 && ! $wildcard && !wantarray );
2267
#----------------------------------------------------------------------------
2268
 
2268
# Function        : ReplaceTags
2269
    return wantarray ? @done : $done[0];
2269
#
2270
}
2270
# Description     : This sub-routine is used to replace Tags in one or more files
2271
 
2271
#
2272
#-------------------------------------------------------------------------------
2272
# Inputs          : outPath                 - Output directory
2273
# Function        : ResolveBinFile
2273
#                   flist                   - List of files in that directory
2274
#
2274
#                   or
2275
# Description     : Determine where the source for a BIN file is
2275
#                   SearchOptions           - Search options to find files
2276
#                   Will look in (default):
2276
#                                           --Recurse
2277
#                       Local directory
2277
#                                           --NoRecurse
2278
#                       Local Include
2278
#                                           --FilterIn=xxx
2279
#                   Or  (FromPackage)
2279
#                                           --FilterInRe=xxx
2280
#                       Our Package directory
2280
#                                           --FilterOut=xxx
2281
#                       Interface directory (BuildPkgArchives)
2281
#                                           --FilterOutRe=xxx
2282
#                       Packages (LinkPkgArchive)
2282
#                   Common options
2283
#                   Will scan 'parts' subdirs
2283
#                                           --Tag=Tag,Replace
2284
#
2284
#                                           
2285
# Inputs          : $from_package       - 0 - Local File
2285
#
2286
#                   $file
2286
# Returns         : 1
2287
#
2287
#
2288
# Returns         : Path
2288
sub ReplaceTags
2289
#
2289
{
2290
sub ResolveBinFile
2290
    return 1 unless ($ActiveSection);
2291
{
2291
    my @uargs;
2292
    my ($from_package, $file) = @_;
2292
    my $search =  JatsLocateFiles->new( '--NoRecurse' );
2293
    my @path;
2293
    my @tagsList;
2294
    my @types;
2294
    my $tagSep = ',';
2295
    my $wildcard = ($file =~ /[*?]/);
2295
    my @tagOrder;
2296
 
2296
    my %tagData;
2297
    #
2297
 
2298
    #   Determine the paths to search
2298
    #
2299
    #
2299
    #   Process user arguments extracting options
2300
    if ( $from_package )
2300
    #
2301
    {
2301
    foreach  ( @_ )
2302
        unless ( @ResolveBinFileList )
2302
    {
2303
        {
2303
        if ( m~^--Recurse~ ) {
2304
            push @ResolveBinFileList, $opt_pkgdir . '/bin';
2304
            $search->recurse(1);
2305
            foreach my $entry ( getPackageList() )
2305
 
2306
            {
2306
        } elsif ( m~^--NoRecurse~) {
2307
                if ( my $path = $entry->getBase(3) )
2307
            $search->recurse(0);
2308
                {
2308
 
2309
                    $path .= '/bin';
2309
        } elsif ( /^--FilterOut=(.*)/ ) {
2310
                    push @ResolveBinFileList, $path if ( -d $path );
2310
            $search->filter_out($1);
2311
                }
2311
 
2312
            }
2312
        } elsif ( /^--FilterOutRe=(.*)/ ) {
2313
        }
2313
            $search->filter_out_re($1);
2314
        @path = @ResolveBinFileList;
2314
 
2315
        @types = ($opt_type, '');
2315
        } elsif ( /^--FilterIn=(.*)/ ) {
2316
    }
2316
            $search->filter_in($1);
2317
    else
2317
 
2318
    {
2318
        } elsif ( /^--FilterInRe=(.*)/ ) {
2319
        @path = ($opt_bindir, $opt_localbindir);
2319
            $search->filter_in_re($1);
2320
        @types = '';
2320
 
2321
    }
2321
        } elsif ( m~^--Tag=(.*)~) {
2322
 
2322
            push @tagsList, $1;
2323
    #
2323
 
2324
    #   Determine a full list of 'parts' to search
2324
        } elsif ( m~^--~) {
2325
    #   This is provided within the build information
2325
            Error ("ReplaceTags: Unknown option: $_");
2326
    #
2326
 
2327
    my @parts = getPlatformParts ();
2327
        } else {
2328
    push @parts, '';
2328
            push @uargs, $_;
2329
 
2329
        }
2330
    my @done;
2330
    }
2331
    foreach my $root (  @path )
2331
 
2332
    {
2332
    #
2333
        foreach my $subdir ( @parts )
2333
    #   Process non-option arguments
2334
        {
2334
    #       - Base dir
2335
            foreach my $type ( @types )
2335
    #       - List of files
2336
            {
2336
    #
2337
                my $sfile;
2337
    my ($outPath, @flist) = @uargs;
2338
                $sfile = "$root/$subdir$type/$file";
2338
    Error ("ReplaceTags: Target Dir must be specified" ) unless ( $outPath );
2339
                $sfile =~ s~//~/~g;
2339
 
2340
                Verbose2("LocateBinFile: $sfile");
2340
    #
2341
                if ( $wildcard )
2341
    #   Sanity Tests
2342
                {
2342
    #
2343
                    foreach  ( glob ( $sfile ) )
2343
    Error ("ReplaceTags: No tags specified" ) unless ( @tagsList );
2344
                    {
2344
 
2345
                        # Ignore .dbg (vix) and .debug (qt) files.
2345
    #
2346
                        next if ( m~\.dbg$~ );
2346
    # Convert output path to physical path
2347
                        next if ( m~\.debug$~ );
2347
    #
2348
                        push @done, $_;
2348
    my $topDir = catdir($WorkDir, $outPath);
2349
                    }
2349
    Verbose("ReplaceTags: topDir: $topDir");
2350
                }
2350
    Error ("ReplaceTags: Path does not exist", $topDir) unless ( -e $topDir );
2351
                else
2351
    Error ("ReplaceTags: Path is not a directory", $topDir) unless ( -d $topDir );
2352
                {
2352
 
2353
                    push @done, $sfile if ( -f $sfile || -l $sfile )
2353
    #
2354
                }
2354
    #   Convert Tags into pairs for latter use
2355
            }
2355
    #
2356
        }
2356
    my $sep = quotemeta ($tagSep );
2357
    }
2357
    foreach my $tag ( @tagsList )
2358
 
2358
    {
2359
    Error ("ResolveBinFile: File not found: $file", "Search Path:", @path)
2359
        my ($tname,$tvalue) = split ( $sep, $tag, 2 );
2360
        unless ( @done );
2360
        Error ("No tag value in: $tag" ) unless ( defined $tvalue );
2361
 
2361
        Error ("Duplicate Tag: $tname" ) if ( exists $tagData{$tname} );
2362
    if ( $#done > 0 && ! $wildcard )
2362
        Verbose ("Tag: $tname :: $tvalue");
2363
    {
2363
        push @tagOrder, $tname;
2364
        Warning ("ResolveBinFile: Multiple instances of file found. Only first is used", @done);
2364
        $tagData{$tname} = $tvalue;
2365
        splice (@done, 1);
2365
    }
2366
    }
2366
 
2367
 
2367
    #
2368
    return wantarray ? @done : $done[0];
2368
    #   Need to determine if we are searching or simply using a file list
2369
}
2369
    #   There are two forms of the functions. If any of the search options have
2370
 
2370
    #   been used then we assume that we are searchine
2371
#-------------------------------------------------------------------------------
2371
    #
2372
# Function        : ResolveLibFile
2372
    if ( $search->has_filter() )
2373
#
2373
    {
2374
# Description     : Determine where the source for a LIB file is
2374
        Error ("ReplaceTags: Cannot mix search options with named files") if ( @flist );
2375
#                   Will look in (default):
2375
        @flist = $search->search($topDir);
2376
#                       Local directory
2376
    }
2377
#                       Local Include
2377
    Error ("ReplaceTags: No files specified") unless ( @flist );
2378
#                   Or  (FromPackage)
2378
 
2379
#                       Our Package directory
2379
    #
2380
#                       Interface directory (BuildPkgArchives)
2380
    #   Process all named files
2381
#                       Packages (LinkPkgArchive)
2381
    #
2382
#                   Will scan 'parts' subdirs
2382
    foreach my $file ( @flist )
2383
#
2383
    {
2384
# Inputs          : $from_package   - 0:Local File
2384
 
2385
#                   $file           - Basename for a 'realname'
2385
        # this is our file that we want to clean.
2386
#                                     Do not provide 'lib' or '.so' or version info
2386
        my ($ifileLoc) = "$topDir/$file";
2387
#                                     May contain embedded options
2387
        my ($tfileLoc) = "$topDir/$file\.tmp";
2388
#                                       --Dll           - Use Windows style versioned DLL
2388
        Verbose("ReplaceTags: $file");
2389
#                                       --VersionDll    - Use the versioned DLL
2389
 
2390
#                                       --3rdParty      - Use exact name provided
2390
        # we will check to see if the file exists.
2391
#
2391
        #
2392
# Returns         : Path
2392
        my $ifile;
2393
#
2393
        my $tfile;
2394
sub ResolveLibFile
2394
        if ( -f "$ifileLoc" )
2395
{
2395
        {
2396
    my ($from_package, $file) = @_;
2396
            open ($ifile, "< $ifileLoc" ) or
2397
    my $wildcard = ($file =~ /[*?]/);
2397
                Error("Failed to open file [$ifileLoc] : $!");
2398
    my @options;
2398
 
2399
    my $num_dll;
2399
            open ($tfile, "> $tfileLoc" ) or
2400
    my @path;
2400
                Error("Failed to open file [$tfileLoc] : $!");
2401
    #
2401
 
2402
    #   Extract options from file
2402
            while ( <$ifile> ) 
2403
    #
2403
            {
2404
    $num_dll = 0;
2404
                s~[\n\r]+$~~;               # Chomp
2405
    ($file, @options) = split ( ',', $file);
2405
 
2406
    foreach ( @options )
2406
                #
2407
    {
2407
                #   Perform tag replacement
2408
        if ( m/^--Dll/ ) {
2408
                #
2409
            $num_dll = 1;
2409
                foreach my $tag ( @tagOrder )
2410
        } elsif ( m/^--VersionDll/ ) {
2410
                {
2411
            $num_dll = 2;
2411
                    my $value = $tagData{$tag};
2412
        } elsif ( m/^--3rdParty/ ) {
2412
                    if ( s~$tag~$value~g )
2413
            $num_dll = 3;
2413
                    {
2414
        } else {
2414
                        Verbose2("Replaced: $tag with $value");
2415
            Error ("Unknown suboption to ResolveLibFile: $_" );
2415
                    }
2416
        }
2416
                }
2417
    }
2417
 
2418
 
2418
                print $tfile "$_\n";
2419
    #
2419
            }
2420
    #   Determine the paths to search
2420
        }
2421
    #
2421
        else
2422
    if ( $from_package )
2422
        {
2423
    {
2423
            Error("ReplaceTags [$ifileLoc] does not exist.");
2424
        unless ( @ResolveLibFileList )
2424
        }
2425
        {
2425
 
2426
            push @ResolveLibFileList, $opt_pkgdir . '/lib';
2426
        close $ifile;
2427
            foreach my $entry ( getPackageList() )
2427
        close $tfile;
2428
            {
2428
 
2429
                push @ResolveLibFileList, $entry->getLibDirs(3);
2429
 
2430
            }
2430
        # lets replace our original file with the new one
2431
        }
2431
        #
2432
        @path = @ResolveLibFileList;
2432
        if(File::Copy::move("$tfileLoc", "$ifileLoc"))
2433
    }
2433
        {
2434
    else
2434
            Verbose2("ReplaceTags: Renamed [$tfileLoc] to [$ifileLoc] ...");
2435
    {
2435
        }
2436
        @path = ($opt_libdir, $opt_locallibdir);
2436
        else
2437
    }
2437
        {
2438
 
2438
            Error("ReplaceTags: Failed to rename file [$tfileLoc] to [$ifileLoc]: $!");
2439
    #
2439
        }
2440
    #   Determine a full list of 'parts' to search
2440
    }
2441
    #   This is provided within the build information
2441
 
2442
    #
2442
    return 1;
2443
    my @parts = getPlatformParts ();
2443
}
2444
    push @parts, '';
2444
 
2445
 
2445
#-------------------------------------------------------------------------------
2446
    my @done;
2446
# Function        : SetFilePerms
2447
    foreach my $root (  @path )
2447
#
2448
    {
2448
# Description     : Set file permissions on one or more files or directories
2449
        foreach my $type ( $opt_type, '' )
2449
#                   Use SetPermissions
2450
        {
2450
#
2451
            foreach my $subdir ( @parts )
2451
# Inputs          : $perm           - Perm Mask
2452
            {
2452
#                   @paths          - List of paths/files to process
2453
                my $sfile;
2453
#                   Options
2454
                my $exact;
2454
#                       --Recurse   - Recurse subdirs
2455
                if ( $num_dll == 2 ) {
2455
#
2456
                    $sfile = $file . $type . '.*.dll' ;
2456
# Returns         : 
2457
                } elsif ( $num_dll == 1 ) {
2457
#
2458
                    $sfile = $file . $type . '.dll' ;
2458
sub SetFilePerms
2459
                    $exact = 1;
2459
{
2460
                } elsif ( $num_dll == 3 ) {
2460
 
2461
                    $sfile = $file;
2461
    return 1 unless ($ActiveSection);
2462
                    $exact = 1;
2462
    my @args;
2463
                } else {
2463
    my $perms;
2464
                    $sfile = "lib" . $file . $type . '.so.*';
2464
    my $recurse = 0;
2465
                }
2465
 
2466
 
2466
    #
2467
                $sfile = "$root/$subdir/$sfile";
2467
    #   Process and Remove options
2468
                $sfile =~ s~//~/~g;
2468
    #
2469
                Verbose2("LocateLibFile: $sfile");
2469
    foreach  ( @_ )
2470
                if ( $exact )
2470
    {
2471
                {
2471
        if ( m/^--Recurse/ ) {
2472
                    push @done, $sfile if ( -f $sfile || -l $sfile );
2472
            $recurse = 1;
2473
                }
2473
 
2474
                elsif ($num_dll)
2474
        } elsif ( m/^--/ ) {
2475
                {
2475
            Error ("SetFilePerms: Unknown option: $_");
2476
                    push @done, glob ( $sfile );
2476
 
2477
                }
2477
        } else {
2478
                else
2478
            push @args, $_;
2479
                {
2479
 
2480
                    #
2480
        }
2481
                    #   Looking for .so files
2481
    }
2482
                    #   Filter out the soname so files
2482
 
2483
                    #   Assume that the soname is shorter than the realname
2483
    $perms = shift @args;
2484
                    #       Ignore .dbg (vix) and .debug (qt) files.
2484
    Error ("SetFilePerms: No Permissions" ) unless ( $perms );
2485
                    #
2485
 
2486
                    my %sieve;
2486
    foreach my $path ( @args )
2487
                    foreach ( glob ( $sfile )  )
2487
    {
2488
                    {
2488
        Verbose ("Set permissions; $perms, $path");
2489
                        next if ( m~\.dbg$~ );
2489
        my $full_path = $WorkDir . '/' . $path;
2490
                        next if ( m~\.debug$~ );
2490
        if ( -f $full_path )
2491
                        m~(.*\.so\.)([\d\.]*\d)$~;
2491
        {
2492
                        if ( $1 )
2492
            System ('chmod', $perms, $full_path );
2493
                        {
2493
        }
2494
                            my $file = $1;
2494
        elsif ( -d $full_path )
2495
                            my $len = exists $sieve{$file} ? length($sieve{$file}) : 0;
2495
        {
2496
                            $sieve{$file} = $_
2496
            System ('chmod', '-R', $perms, $full_path ) if ($recurse);
2497
                                if ( $len == 0 || length($_) > $len );
2497
            System ('chmod', $perms, $full_path ) unless ($recurse);
2498
                        }                                
2498
        }
2499
                    }
2499
        else
2500
 
2500
        {
2501
                    push @done, values %sieve;
2501
            Warning("SetFilePerms: Path not found: $path");
2502
                }
2502
        }
2503
            }
2503
    }
2504
        }
2504
    return 1;
2505
    }
2505
}
2506
 
2506
 
2507
    Error ("ResolveLibFile: File not found: $file", "Search Path:", @path)
2507
#-------------------------------------------------------------------------------
2508
        unless ( @done );
2508
# Function        : SetPermissions 
2509
 
2509
#
2510
    if ( $#done > 0 && ! $wildcard )
2510
# Description     : Called to set permissions of files/dirs in a directory structure.
2511
    {
2511
#                   With no options sets DirTag and all files/dirs in it to perms
2512
        Warning ("ResolveLibFile: Multiple instances of file found. Only first is used", @done);
2512
#   
2513
        splice (@done, 1);
2513
# Inputs          : path        - The directory tag to start setting permissions on
2514
    }
2514
#                   Options     - See below
2515
    return wantarray ? @done : $done[0];
2515
#       
2516
}
2516
#   Required Options:
2517
 
2517
#       One or both of
2518
#-------------------------------------------------------------------------------
2518
#               --FilePerms=    Sets the permissions of files to this permission.
2519
# Function        : ResolveDebPackage
2519
#                               If not supplied then no files have their permissions changed
2520
#
2520
#               --DirPerms=     Sets the permissions of directories to this permission
2521
# Description     : Determine where the source for a Debian Package is
2521
#                               If not supplied then no directories have their permissions changed
2522
#                   Will look in (default):
2522
#       OR
2523
#                       Local directory
2523
#               --Perms=        Sets the permissions of both files and directories to this permissions
2524
#                       Local Include
2524
#                               Equivalent to supplying both --FilePerms=X && --DirPerms=X
2525
#                   Or  (FromPackage)
2525
#               
2526
#                       Our Package directory
2526
#   Options:                    
2527
#                       Interface directory (BuildPkgArchives)
2527
#               --RootOnly      Only sets the permissions on the 'path' directory/file, 
2528
#                       Packages (LinkPkgArchive)
2528
#                               all other options ignored
2529
#
2529
#               --SkipRoot      Does not set permissions on the 'path' directory/file, 
2530
# Inputs          : $from_package   - 0:Local File
2530
#                               obviously mutually exlusive with --RootOnly
2531
#                   $baseName       - Basename for a 'DebianPackage'
2531
#   
2532
#                                     Do not provide version info, architecture or suffix
2532
#       Any option supported by JatsLocateFiles. 
2533
#                                     May contain embedded options
2533
#       Some of these include:
2534
#                                       --Arch=XXX      - Specify alternate architcute
2534
#               
2535
#                                       --Product=YYYY  - Specify product family
2535
#               --Recurse       Recurse the directory tree.  Does a depth first recurse so that all 
2536
#                                       --Debug         - Use alternate build type
2536
#                               dir entries are processed before the dir itself (default)
2537
#                                       --Prod          - Use alternate build type
2537
#               --NoRecurse     Dont recurse
2538
#
2538
#               --FilterIn=     Apply permissions to files/directories that matches this value.
2539
# Returns         : Path
2539
#               --FilterInRe=   Perl RE's can be used (Not Shell wildcards) and this option
2540
#
2540
#                               can be supplied mulitple times
2541
sub ResolveDebPackage
2541
#               --FilterOut=    Dont apply permissions to any files/directories matching this value
2542
{
2542
#               --FilterOutRe=  Perl RE's can be used (Not Shell wildcards) and this option
2543
    my ($from_package, $file) = @_;
2543
#                               can be supplied mulitple times
2544
    my @path;
2544
#               
2545
    my $arch;
2545
#                               FilterIn is applied before FilterOut.  If Recurse is specified 
2546
    my $product;
2546
#                               the directory will be recursed regardless of these filters, however
2547
    my $buildType;
2547
#                               the filter will be applied when it comes time to chmod the dir 
2548
    my @types;
2548
#
2549
    my $baseName;
2549
#------------------------------------------------------------------------------
2550
    my @options;
2550
sub SetPermissions
2551
 
2551
{
2552
    #
2552
    return 1 unless ($ActiveSection);
2553
    #   Extract options from file
2553
    my ( $path, $filePerms, $dirPerms, $someDone );
2554
    #
2554
    my ( $rootOnly, $skipRoot ) = ( 0, 0 );
2555
    ($baseName, @options) = split ( ',', $file);
2555
    
2556
    foreach ( @options )
2556
    my $search =  JatsLocateFiles->new( '--Recurse', '--DirsToo' );
2557
    {
2557
 
2558
        if ( m/^--Arch=(.+)/ ) {
2558
    foreach ( @_ )
2559
            $arch=$1;
2559
    {
2560
        } elsif ( m/^--Product=(.+)/ ) {
2560
        if ( m/^--Perms=(.*)/ ) {
2561
            $product = $1;
2561
            $filePerms = $1;
2562
        } elsif ( m/^--Debug/ ) {
2562
            $dirPerms = $1;
2563
            Error ("ResolveDebPackage: Cannot specify --Prod and --Debug") if defined $buildType;
2563
 
2564
            $buildType = 'D';
2564
        } elsif (m/^--FilePerms=(.*)/ )  {
2565
        } elsif ( m/^--Prod/ ) {
2565
            $filePerms = $1;
2566
            Error ("ResolveDebPackage: Cannot specify --Prod and --Debug") if defined $buildType;
2566
 
2567
            $buildType = 'P';
2567
        } elsif ( m/^--DirPerms=(.*)/ )  {
2568
        } else {
2568
            $dirPerms = $1;
2569
            Error ("Unknown suboption to ResolveDebPackage: $_" );
2569
 
2570
        }
2570
        }  elsif ( m/^--RootOnly/ ) {
2571
    }
2571
            $rootOnly = 1;
2572
 
2572
 
2573
    #
2573
        } elsif ( m/^--SkipRoot/ )  {
2574
    #   Insert defaults
2574
            $skipRoot = 1;
2575
    #
2575
 
2576
    $buildType = $opt_type unless ($buildType);
2576
        } elsif ( m/^--Filter/ && $search->option( $_ ) ) {
2577
    $arch = $opt_target unless ($arch);
2577
            Verbose2 ("Search Option: $_" );
2578
 
2578
 
2579
    #
2579
        } elsif ( m/^--Recurse|--NoRecurse/ && $search->option( $_ ) ) {
2580
    #   Determine the paths to search
2580
            Verbose2 ("Search Option: $_" );
2581
    #
2581
 
2582
    if ( $from_package )
2582
        } elsif (m/^--/ ) {
2583
    {
2583
            Error ("SetPermissions: Unknown option: $_");
2584
        unless ( @ResolveDebFileList )
2584
 
2585
        {
2585
        } else  {
2586
            push @ResolveDebFileList,  $opt_pkgdir, $opt_pkgdir . '/bin';
2586
            Error("SetPermissions 'path' already set", "Path: $_") if ( $path );
2587
            foreach my $entry ( getPackageList() )
2587
            $path = $_;
2588
            {
2588
        }
2589
                if ( my $path = $entry->getBase(3) )
2589
    }
2590
                {
2590
 
2591
                    push @ResolveDebFileList, $path if ( -d $path );
2591
    #
2592
 
2592
    #   Sanity test
2593
                    $path .= '/bin';
2593
    #
2594
                    push @ResolveDebFileList, $path if ( -d $path );
2594
    Error("SetPermissions called with out a 'path' parameter") if ( !defined($path) );
2595
                }
2595
    Error("SetPermissions called with out any Permissions specified") if ( !defined($filePerms) && !defined($dirPerms) );
2596
            }
2596
    Error("SetPermissions: Options --RootOnly & --SkipRoot are mutually exclusive" ) if ( $rootOnly && $skipRoot );
2597
        }
2597
 
2598
        @path = @ResolveDebFileList;
2598
 
2599
        @types = ($buildType, '');
2599
    #   Convert the target directory name into a physical path
2600
    }
2600
    #   User specifies '/' as the root of the image
2601
    else
2601
    #   User specifies 'name' as relateve to the root of the image
2602
    {
2602
    #
2603
        @path = ($opt_bindir, $opt_localbindir);
2603
    my $topDir = $WorkDir . '/' . $path;
2604
        @types = ($buildType, '');
2604
    $topDir =~ s~/+$~~;
2605
    }
2605
 
2606
 
2606
    Verbose("SetPermissions: Called with options " . join(", ", @_));
2607
    #
2607
 
2608
    #   The debian  package name is
2608
    #
2609
    #   In packages BIN dir
2609
    #   Only set perms on the root directory
2610
    #       (BaseName)_VersionString(_Product)(_Arch).deb
2610
    #       This is a trivial operation
2611
    #       
2611
    #
2612
    #   In root of package
2612
    if ( $rootOnly )
2613
    #       (BaseName)_VersionString(_Product)(_Arch)(_Type).deb
2613
    {
2614
    #
2614
        $someDone += chmodItem( $topDir, $filePerms, $dirPerms );
2615
    #       
2615
    }
2616
    #   The package may be found in
2616
    else
2617
    #       Package Root
2617
    {
2618
    #       Package bin directory
2618
        #
2619
    #       
2619
        #   Create a list of files/dirs to process
2620
    $file = $baseName . '_*';
2620
        #
2621
    if (defined $product) {
2621
        my @elements = $search->search( $topDir );
2622
        $file .= ( '_' . $product)
2622
 
2623
        }
2623
        foreach my $dirEntry ( @elements )
2624
    $file .= '_' . $arch;
2624
        {
2625
 
2625
            my $fullPath = "$topDir/$dirEntry";
2626
    #
2626
 
2627
    #   Determine a full list of 'parts' to search
2627
            # A dir and we dont have dirperms, so skip
2628
    #   This is provided within the build information
2628
            if ( -d $fullPath && !defined($dirPerms) )
2629
    #
2629
            {
2630
    my @parts = getPlatformParts ();
2630
                Verbose2("SetPermissions: Skipping dir $fullPath as we have no dir permissions");
2631
    push @parts, '';
2631
                next;
2632
 
2632
            }
2633
    my @done;
2633
 
2634
    foreach my $root (  @path )
2634
            # A file and we dont have fileperms, so skip
2635
    {
2635
            if ( -f $fullPath && !defined($filePerms) )
2636
        foreach my $subdir ( @parts )
2636
            {
2637
        {
2637
                Verbose2("SetPermissions: Skipping file $fullPath as we have no file permissions");
2638
            foreach my $type ( @types )
2638
                next;
2639
            {
2639
            }
2640
                my $sfile;
2640
 
2641
                $sfile = "$root/$subdir$type/$file";
2641
            # a file or a dir and have the right permissions and we are not recursing
2642
                $sfile =~ s~//~/~g;
2642
            if ( -f $fullPath || -d $fullPath )
2643
                foreach my $type2 ( @types )
2643
            {
2644
                {
2644
                $someDone += chmodItem( $fullPath, $filePerms, $dirPerms );
2645
                    my $tfile = $sfile;
2645
            }
2646
                    $tfile .= '_' . $type2 if $type2;
2646
            else
2647
                    $tfile .= '.deb';
2647
            {
2648
                    Verbose2("ResolveDebPackage: $tfile");
2648
                Warning("SetPermissions: Skipping $fullPath as its not a file or directory");
2649
                    foreach  ( glob ( $tfile ) )
2649
            }
2650
                    {
2650
        }
2651
                        push @done, $_;
2651
 
2652
                    }
2652
        #
2653
                }
2653
        #   Process the topDir
2654
            }
2654
        #   May not be modified if --SkipRoot has been requested
2655
        }
2655
        #
2656
    }
2656
        if ( !$skipRoot && -e $topDir )
2657
 
2657
        {
2658
    Error ("ResolveDebPackage: Package not found: $file", "Search Path:", @path)
2658
            $someDone += chmodItem( $topDir, $filePerms, $dirPerms );
2659
        unless ( @done );
2659
        }
2660
 
2660
    }
2661
    if ( $#done > 0 )
2661
 
2662
    {
2662
    #   Final warning
2663
        Error ("ResolveDebPackage: Multiple instances of Package found.", @done);
2663
    #
2664
    }
2664
    Warning ("SetPermissions: No files located", "Args: @_") unless ( $someDone );
2665
    return wantarray ? @done : $done[0];
2665
}
2666
}
2666
 
2667
 
2667
#************ INTERNAL USE ONLY  **********************************************
2668
 
2668
# Function        : chmodItem 
2669
 
2669
#
2670
#-------------------------------------------------------------------------------
2670
# Description     : Internal
2671
# Function        : AUTOLOAD
2671
#                   chmod a file or a folder
2672
#
2672
#
2673
# Description     : Intercept bad user directives and issue a nice error message
2673
# Inputs          : item                        - Item to mod
2674
#                   This is a simple routine to report unknown user directives
2674
#                   filePerms                   - File perms
2675
#                   It does not attempt to distinguish between user errors and
2675
#                   dirPerms                    - dire perms
2676
#                   programming errors. It assumes that the program has been
2676
#
2677
#                   tested. The function simply report filename and line number
2677
# Returns         : 1   - Item modified
2678
#                   of the bad directive.
2678
#                   0   - Item not modified
2679
#
2679
#
2680
# Inputs          : Original function arguments ( not used )
2680
#************ INTERNAL USE ONLY  **********************************************
2681
#
2681
sub chmodItem
2682
# Returns         : This function does not return
2682
{
2683
#
2683
    my ($item, $filePerms, $dirPerms) = @_;
2684
our $AUTOLOAD;
2684
 
2685
sub AUTOLOAD
2685
    if ( -d $item && defined $dirPerms)
2686
{
2686
    {
2687
    my $fname = $AUTOLOAD;
2687
        Verbose("SetPermissions: $dirPerms : $item");
2688
    $fname =~ s~^main::~~;
2688
        System ('chmod', $dirPerms, $item );
2689
    my ($package, $filename, $line) = caller;
2689
        return 1;
2690
 
2690
    }
2691
    Error ("Directive not known or not allowed in this context: $fname",
2691
 
2692
           "Directive: $fname( @_ );",
2692
    if ( -f $item  && defined $filePerms)
2693
           "File: $filename, Line: $line" );
2693
    {
2694
}
2694
        Verbose("SetPermissions: $filePerms : $item");
2695
 
2695
        System ('chmod', $filePerms, $item );
2696
 
2696
        return 1;
2697
1;
2697
    }
2698
 
2698
 
-
 
2699
    return 0;
-
 
2700
}
-
 
2701
 
-
 
2702
 
-
 
2703
#-------------------------------------------------------------------------------
-
 
2704
# Function        : CreateDir
-
 
2705
#
-
 
2706
# Description     : Create a directory within the target workspace
-
 
2707
#
-
 
2708
# Inputs          : $path           - Name of the target directory
-
 
2709
#                   @opts           - Options
-
 
2710
#                     --Owner       - Tells RPM Builder that this package. Owns this directory
-
 
2711
#
-
 
2712
# Returns         : Nothing
-
 
2713
#
-
 
2714
sub CreateDir
-
 
2715
{
-
 
2716
    my ($path, @opts) = @_;
-
 
2717
    return 1 unless ($ActiveSection);
-
 
2718
    Verbose ("Create Dir: $path");
-
 
2719
    my $owner  = 0;
-
 
2720
    foreach ( @opts) {
-
 
2721
        if (m~^--Owner~i ) {
-
 
2722
            $owner = 1;
-
 
2723
        } else {
-
 
2724
            ReportError ("SetBaseDir: Unknown option: $_");
-
 
2725
        }
-
 
2726
    }
-
 
2727
    ErrorDoExit();
-
 
2728
 
-
 
2729
    $path =~ s~^/+~~;
-
 
2730
    $path = '/' . $path;
-
 
2731
    $OwnedDirs{$path} = $owner if $owner;
-
 
2732
    mkpath( $WorkDir . $path );
-
 
2733
}
-
 
2734
 
-
 
2735
#-------------------------------------------------------------------------------
-
 
2736
# Function        : RpmSetDefAttr 
-
 
2737
#
-
 
2738
# Description     : RPM only: Set the defAttr values 
-
 
2739
#
-
 
2740
# Inputs          : Expect 4 or less argument
-
 
2741
#                       The default permissions, or "mode" for files.
-
 
2742
#                       The default user id.
-
 
2743
#                       The default group id.
-
 
2744
#                       The default permissions, or "mode" for directories.
-
 
2745
#                   
-
 
2746
sub RpmSetDefAttr
-
 
2747
{
-
 
2748
    return 1 unless ($ActiveSection);
-
 
2749
    return 1 unless $opt_rpm;
-
 
2750
    my @args = @_;
-
 
2751
    Error ("RpmSetDefAttr: Expecting 4 arguments") if (scalar @args ne 4);
-
 
2752
    @RpmDefAttr = @_;
-
 
2753
    return 1;
-
 
2754
}
-
 
2755
 
-
 
2756
#-------------------------------------------------------------------------------
-
 
2757
# Function        : RpmSetAttr 
-
 
2758
#
-
 
2759
# Description     : RPM Only : Specify specific file attributes
-
 
2760
#
-
 
2761
# Inputs          : $file - file to target
-
 
2762
#                   $mode - File mode to place on the file (optional)
-
 
2763
#                   $user - user name to place on the file  (optional)
-
 
2764
#                   $group  - group name to place eon the file (optional)
-
 
2765
#
-
 
2766
sub RpmSetAttr
-
 
2767
{
-
 
2768
    return 1 unless ($ActiveSection);
-
 
2769
    return 1 unless $opt_rpm;
-
 
2770
    my ($file, $mode, $user, $group, @extra) = @_;
-
 
2771
    Error ("RpmSetAttr: Too many arguments") if @extra;
-
 
2772
 
-
 
2773
    #
-
 
2774
    #   Validate the file
-
 
2775
    #
-
 
2776
    $file = '/' . $file;
-
 
2777
    $file =~ s~//~/~g;
-
 
2778
    my $full_path = $WorkDir . $file;
-
 
2779
    Error ("RpmSetAttr: File not found: $WorkSubDir$file") unless (-x $full_path );
-
 
2780
 
-
 
2781
    my @data;
-
 
2782
    $data[0] = $WorkSubDir . $file;
-
 
2783
    $data[1] = $mode || '-';
-
 
2784
    $data[2] = $user || '-';
-
 
2785
    $data[3] = $group ||'-';
-
 
2786
    push @RpmAttrList, \@data;
-
 
2787
    return 1;
-
 
2788
}
-
 
2789
 
-
 
2790
 
-
 
2791
#-------------------------------------------------------------------------------
-
 
2792
# Function        : IsProduct
-
 
2793
#                   IsPlatform
-
 
2794
#                   IsTarget
-
 
2795
#                   IsVariant
-
 
2796
#                   IsAlias
-
 
2797
#                   IsDebian
-
 
2798
#                   IsRpm
-
 
2799
#                   IsTar
-
 
2800
#
-
 
2801
# Description     : This function allows some level of control in the
-
 
2802
#                   packaging scripts. It will return true if the current
-
 
2803
#                   product is listed.
-
 
2804
#
-
 
2805
#                   Ugly after thought
-
 
2806
#
-
 
2807
#                   Intended use:
-
 
2808
#                       Xxxxxx(...) if (IsProduct( 'aaa',bbb' );
-
 
2809
#
-
 
2810
# Inputs          : products    - a list of products to compare against
-
 
2811
#
-
 
2812
# Returns         : True if the current build is for one of the listed products
-
 
2813
#
-
 
2814
sub IsProduct
-
 
2815
{
-
 
2816
    foreach ( @_ )
-
 
2817
    {
-
 
2818
        return 1 if ( $opt_product eq $_ );
-
 
2819
    }
-
 
2820
    return 0;
-
 
2821
}
-
 
2822
 
-
 
2823
sub IsPlatform
-
 
2824
{
-
 
2825
    foreach ( @_ )
-
 
2826
    {
-
 
2827
        return 1 if ( $opt_platform eq $_ );
-
 
2828
    }
-
 
2829
    return 0;
-
 
2830
}
-
 
2831
 
-
 
2832
sub IsTarget
-
 
2833
{
-
 
2834
    foreach ( @_ )
-
 
2835
    {
-
 
2836
        return 1 if ( $opt_target eq $_ );
-
 
2837
    }
-
 
2838
    return 0;
-
 
2839
}
-
 
2840
 
-
 
2841
sub IsVariant
-
 
2842
{
-
 
2843
    foreach ( @_ )
-
 
2844
    {
-
 
2845
        return 1 if ( $opt_variant eq $_ );
-
 
2846
    }
-
 
2847
    return 0;
-
 
2848
}
-
 
2849
 
-
 
2850
sub IsAlias
-
 
2851
{
-
 
2852
 
-
 
2853
    #
-
 
2854
    #   Get the aliases from the build info
-
 
2855
    #   This function was introduced late so its not always available
-
 
2856
    #
-
 
2857
    Error("IsAlias not supported in this version of JATS")
-
 
2858
        unless (defined &ReadBuildConfig::getAliases);
-
 
2859
    #
-
 
2860
    #   Create an hash of aliases to simplify testing
-
 
2861
    #   Do it once and cache the results
-
 
2862
    #
-
 
2863
    unless (%opt_aliases) {
-
 
2864
        %opt_aliases = map { $_ => 1 } getAliases();
-
 
2865
    }
-
 
2866
 
-
 
2867
    foreach ( @_ )
-
 
2868
    {
-
 
2869
        return 1 if ( exists $opt_aliases{$_} );
-
 
2870
    }
-
 
2871
    return 0;
-
 
2872
}
-
 
2873
 
-
 
2874
sub IsDebian()
-
 
2875
{
-
 
2876
    return $opt_debian ? 1 : 0;
-
 
2877
}
-
 
2878
 
-
 
2879
sub IsRpm()
-
 
2880
{
-
 
2881
    return $opt_rpm ? 1 : 0;
-
 
2882
}
-
 
2883
 
-
 
2884
sub IsTar()
-
 
2885
{
-
 
2886
    return $opt_tarFile ? 1 : 0;
-
 
2887
}
-
 
2888
 
-
 
2889
#-------------------------------------------------------------------------------
-
 
2890
# Function        : PackageVersion 
-
 
2891
#
-
 
2892
# Description     : Return the version of the named package 
-
 
2893
#
-
 
2894
# Inputs          : pkgName - Name of the package 
-
 
2895
#                   Options
-
 
2896
#                       --format=SomeString. The text replacements
-
 
2897
#                           {VERSION}
-
 
2898
#                           {VERSIONNUMVER}
-
 
2899
#                           {PROJECT}
-
 
2900
#                           {NAME}
-
 
2901
#                           {TYPE}
-
 
2902
#                           {ARCH}
-
 
2903
#
-
 
2904
# Returns         : A string 
-
 
2905
#
-
 
2906
sub PackageVersion
-
 
2907
{
-
 
2908
    my ($pkgName, @args) = @_;
-
 
2909
    my ($version, $versionNumber, $project, $format);
-
 
2910
 
-
 
2911
    foreach ( @args)
-
 
2912
    {
-
 
2913
        if (m~^--format=(.+)~i) {
-
 
2914
            $format = $1
-
 
2915
        } else {
-
 
2916
            Error ("PackageVersion: Unknown option: $_")
-
 
2917
        }
-
 
2918
    }
-
 
2919
    
-
 
2920
    foreach my $entry ( getPackageList() )
-
 
2921
    {
-
 
2922
        if ($entry->getName() eq $pkgName ) {
-
 
2923
            $version = $entry->getVersion();
-
 
2924
            ($versionNumber = $version ) =~ s~\.[^.]+$~~;
-
 
2925
            ($project = $version ) =~ s~.*\.~~;
-
 
2926
            last;
-
 
2927
        }
-
 
2928
    }
-
 
2929
 
-
 
2930
    Error ("PackageVersion: $pkgName is not a dependent package") unless defined $version;
-
 
2931
 
-
 
2932
    #
-
 
2933
    #   Format the string
-
 
2934
    #
-
 
2935
    if ($format) {
-
 
2936
        $format =~ s~{NAME}~$pkgName~g;
-
 
2937
        $format =~ s~{VERSION}~$version~g;
-
 
2938
        $format =~ s~{VERSIONNUMBER}~$versionNumber~g;
-
 
2939
        $format =~ s~{PROJECT}~$project~g;
-
 
2940
        $format =~ s~{TYPE}~$opt_type~g;
-
 
2941
        $format =~ s~{ARCH}~$opt_pkgarch~g;
-
 
2942
        
-
 
2943
        $version = $format;
-
 
2944
    }
-
 
2945
 
-
 
2946
    return $version;
-
 
2947
}
-
 
2948
 
-
 
2949
 
-
 
2950
#************ INTERNAL USE ONLY  **********************************************
-
 
2951
# Function        : FindFiles
-
 
2952
#
-
 
2953
# Description     : Locate files within a given dir tree
-
 
2954
#
-
 
2955
# Inputs          : $root           - Base of the search
-
 
2956
#                   $match          - Re to match
-
 
2957
#
-
 
2958
# Returns         : A list of files that match
-
 
2959
#
-
 
2960
#************ INTERNAL USE ONLY  **********************************************
-
 
2961
my @FIND_LIST;
-
 
2962
my $FIND_NAME;
-
 
2963
 
-
 
2964
sub FindFiles
-
 
2965
{
-
 
2966
    my ($root, $match ) = @_;
-
 
2967
    Verbose2("FindFiles: Root: $root, Match: $match");
-
 
2968
 
-
 
2969
    #
-
 
2970
    #   Becareful of closure, Must use globals
-
 
2971
    #
-
 
2972
    @FIND_LIST = ();
-
 
2973
    $FIND_NAME = $match;
-
 
2974
    File::Find::find( \&find_files, $root);
-
 
2975
 
-
 
2976
    #
-
 
2977
    #   Find callback program
-
 
2978
    #
-
 
2979
    sub find_files
-
 
2980
    {
-
 
2981
        my $item =  $File::Find::name;
-
 
2982
 
-
 
2983
        return if ( -d $File::Find::name );
-
 
2984
        return unless ( $_ =~ m~$FIND_NAME~ );
-
 
2985
        push @FIND_LIST, $item;
-
 
2986
    }
-
 
2987
    return @FIND_LIST;
-
 
2988
}
-
 
2989
 
-
 
2990
#-------------------------------------------------------------------------------
-
 
2991
# Function        : CalcRelPath
-
 
2992
#
-
 
2993
# Description     : Return the relative path to the current working directory
-
 
2994
#                   as provided in $Cwd
-
 
2995
#
-
 
2996
# Inputs          : $Cwd - Base dir
-
 
2997
#                   $base - Path to convert
-
 
2998
#
-
 
2999
# Returns         : Relative path from the $Cwd
-
 
3000
#
-
 
3001
sub CalcRelPath
-
 
3002
{
-
 
3003
    my ($Cwd, $base) = @_;
-
 
3004
 
-
 
3005
    my @base = split ('/', $base );
-
 
3006
    my @here = split ('/', $Cwd );
-
 
3007
    my $result;
-
 
3008
 
-
 
3009
    Debug("RelPath: Source: $base");
-
 
3010
 
-
 
3011
    return $base unless ( $base =~ m~^/~ );
-
 
3012
    
-
 
3013
    #
-
 
3014
    #   Remove common bits from the head of both lists
-
 
3015
    #
-
 
3016
    while ( $#base >= 0 && $#here >= 0 && $base[0] eq $here[0] )
-
 
3017
    {
-
 
3018
        shift @base;
-
 
3019
        shift @here;
-
 
3020
    }
-
 
3021
 
-
 
3022
    #
-
 
3023
    #   Need to go up some directories from here and then down into base
-
 
3024
    #
-
 
3025
    $result = '../' x ($#here + 1);
-
 
3026
    $result .= join ( '/', @base);
-
 
3027
    $result = '.' unless ( $result );
-
 
3028
    $result =~ s~//~/~g;
-
 
3029
    $result =~ s~/$~~;
-
 
3030
 
-
 
3031
    Debug("RelPath: Result: $result");
-
 
3032
    return $result;
-
 
3033
}
-
 
3034
 
-
 
3035
#-------------------------------------------------------------------------------
-
 
3036
# Function        : ExpandLinkFiles
-
 
3037
#
-
 
3038
# Description     : Look for .LINK files in the output image and expand
-
 
3039
#                   the links into softlinks
-
 
3040
#
-
 
3041
# Inputs          : None
-
 
3042
#                   The routine works on the $WorkDir directory tree
-
 
3043
#
-
 
3044
# Returns         : Nothing
-
 
3045
#                   Will remove .LINKS files that are processed
-
 
3046
#
-
 
3047
sub ExpandLinkFiles
-
 
3048
{
-
 
3049
    return 1 unless ($ActiveSection);
-
 
3050
    foreach my $linkfile ( FindFiles( $WorkDir, ".LINKS" ))
-
 
3051
    {
-
 
3052
        next if ( $linkfile =~ m~/\.svn/~ );
-
 
3053
        my $BASEDIR = StripFileExt( $linkfile );
-
 
3054
        $BASEDIR =~ s~^$WorkDir/~~;
-
 
3055
        Verbose "Expand links: $BASEDIR";
-
 
3056
 
-
 
3057
        open (LF, "<", $linkfile ) || Error ("Cannot open link file: $linkfile" );
-
 
3058
        while ( <LF> )
-
 
3059
        {
-
 
3060
            chomp;
-
 
3061
            next if ( m~^#~ );
-
 
3062
            next unless ( $_ );
-
 
3063
            my ($link, $file) = split;
-
 
3064
 
-
 
3065
            MakeSymLink($file ,"$BASEDIR/$link", '--NoDotDot' );
-
 
3066
        }
-
 
3067
        close (LF);
-
 
3068
        unlink $linkfile;
-
 
3069
    }
-
 
3070
}
-
 
3071
 
-
 
3072
#************ INTERNAL USE ONLY  **********************************************
-
 
3073
# Function        : ResolveFile
-
 
3074
#
-
 
3075
# Description     : Determine where the source for a file is
-
 
3076
#                   Will look in (default):
-
 
3077
#                       Local directory
-
 
3078
#                       Local Include
-
 
3079
#                   Or  (FromPackage)
-
 
3080
#                       Our Package directory
-
 
3081
#                       Interface directory (BuildPkgArchives)
-
 
3082
#                       Packages (LinkPkgArchive)
-
 
3083
#
-
 
3084
#                   Will scan 'parts' subdirs
-
 
3085
#
-
 
3086
# Inputs          : $from_package       - 0 - Local File
-
 
3087
#                   $file
-
 
3088
#                   $refPlatforms       - Not used
-
 
3089
#
-
 
3090
# Returns         : Path
-
 
3091
#
-
 
3092
#************ INTERNAL USE ONLY  **********************************************
-
 
3093
sub ResolveFile
-
 
3094
{
-
 
3095
    my ($from_package, $file,$refPlatforms) = @_;
-
 
3096
    my $wildcard = ($file =~ /[*?]/);
-
 
3097
    my @path;
-
 
3098
 
-
 
3099
    #
-
 
3100
    #   Determine the paths to search
-
 
3101
    #
-
 
3102
    if ( $from_package )
-
 
3103
    {
-
 
3104
        unless ( @ResolveFileList )
-
 
3105
        {
-
 
3106
            push @ResolveFileList, $opt_pkgdir;
-
 
3107
            foreach my $entry ( getPackageList() )
-
 
3108
            {
-
 
3109
                push @ResolveFileList, $entry->getBase(3);
-
 
3110
            }
-
 
3111
        }
-
 
3112
        @path = @ResolveFileList;
-
 
3113
    }
-
 
3114
    else
-
 
3115
    {
-
 
3116
        @path = ('.', $opt_localincdir);
-
 
3117
    }
-
 
3118
 
-
 
3119
    #   Determine a full list of 'parts' to search
-
 
3120
    #       Default: Provided within the build information
-
 
3121
    #       User   : Can provide a list
-
 
3122
    my @parts = getPlatformPartsList($refPlatforms);
-
 
3123
 
-
 
3124
    my @done;
-
 
3125
    foreach my $root (  @path )
-
 
3126
    {
-
 
3127
        foreach my $subdir ( @parts )
-
 
3128
        {
-
 
3129
            my $sfile;
-
 
3130
            $sfile = "$root/$subdir/$file";
-
 
3131
            $sfile =~ s~//~/~g;
-
 
3132
            $sfile =~ s~^./~~g;
-
 
3133
            Verbose2("LocateFile: $sfile, $root, $subdir");
-
 
3134
            if ( $wildcard )
-
 
3135
            {
-
 
3136
                push @done, glob ( $sfile );
-
 
3137
            }
-
 
3138
            else
-
 
3139
            {
-
 
3140
                push @done, $sfile if ( -f $sfile || -l $sfile )
-
 
3141
            }
-
 
3142
        }
-
 
3143
    }
-
 
3144
 
-
 
3145
    DisplaySearchPath('ResolveFile', $file, \@parts, undef, \@path) unless (@done) ;
-
 
3146
 
-
 
3147
    Warning ("ResolveFile: Multiple instances of file found. Only first is used", @done)
-
 
3148
        if ( $#done > 0 && ! $wildcard && !wantarray );
-
 
3149
 
-
 
3150
    return wantarray ? @done : $done[0];
-
 
3151
}
-
 
3152
 
-
 
3153
#-------------------------------------------------------------------------------
-
 
3154
# Function        : ResolveBinFile
-
 
3155
#
-
 
3156
# Description     : Determine where the source for a BIN file is
-
 
3157
#                   Will look in (default):
-
 
3158
#                       Local directory
-
 
3159
#                       Local Include
-
 
3160
#                   Or  (FromPackage)
-
 
3161
#                       Our Package directory
-
 
3162
#                       Interface directory (BuildPkgArchives)
-
 
3163
#                       Packages (LinkPkgArchive)
-
 
3164
#                   Will scan 'parts' subdirs (default)
-
 
3165
#                   May scan user-provided parts (cross platform packaging)
-
 
3166
#
-
 
3167
# Inputs          : $from_package       - 0 - Local File
-
 
3168
#                   $file
-
 
3169
#                   $refPlatforms       - (optional) Ref to an array of platforms to scan
-
 
3170
#
-
 
3171
# Returns         : Path
-
 
3172
#
-
 
3173
sub ResolveBinFile
-
 
3174
{
-
 
3175
    my ($from_package, $file, $refPlatforms) = @_;
-
 
3176
    my @path;
-
 
3177
    my @types;
-
 
3178
    my $wildcard = ($file =~ /[*?]/);
-
 
3179
 
-
 
3180
    #
-
 
3181
    #   Determine the paths to search
-
 
3182
    #
-
 
3183
    if ( $from_package )
-
 
3184
    {
-
 
3185
        unless ( @ResolveBinFileList )
-
 
3186
        {
-
 
3187
            push @ResolveBinFileList, $opt_pkgdir . '/bin';
-
 
3188
            foreach my $entry ( getPackageList() )
-
 
3189
            {
-
 
3190
                if ( my $path = $entry->getBase(3) )
-
 
3191
                {
-
 
3192
                    $path .= '/bin';
-
 
3193
                    push @ResolveBinFileList, $path if ( -d $path );
-
 
3194
                }
-
 
3195
            }
-
 
3196
        }
-
 
3197
        @path = @ResolveBinFileList;
-
 
3198
        @types = ($opt_type, '');
-
 
3199
    }
-
 
3200
    else
-
 
3201
    {
-
 
3202
        @path = ($opt_bindir, $opt_localbindir);
-
 
3203
        @types = '';
-
 
3204
    }
-
 
3205
 
-
 
3206
    #
-
 
3207
    #   Determine a full list of 'parts' to search
-
 
3208
    #       Default: Provided within the build information
-
 
3209
    #       User   : Can provide a list
-
 
3210
    #
-
 
3211
    my @parts = getPlatformPartsList($refPlatforms);
-
 
3212
 
-
 
3213
    my @done;
-
 
3214
    foreach my $root (  @path )
-
 
3215
    {
-
 
3216
        foreach my $subdir ( @parts )
-
 
3217
        {
-
 
3218
            foreach my $type ( @types )
-
 
3219
            {
-
 
3220
                my $sfile;
-
 
3221
                $sfile = "$root/$subdir$type/$file";
-
 
3222
                $sfile =~ s~//~/~g;
-
 
3223
                Verbose2("LocateBinFile: $sfile");
-
 
3224
                if ( $wildcard )
-
 
3225
                {
-
 
3226
                    foreach  ( glob ( $sfile ) )
-
 
3227
                    {
-
 
3228
                        # Ignore .dbg (vix) and .debug (qt) files.
-
 
3229
                        next if ( m~\.dbg$~ );
-
 
3230
                        next if ( m~\.debug$~ );
-
 
3231
                        push @done, $_;
-
 
3232
                    }
-
 
3233
                }
-
 
3234
                else
-
 
3235
                {
-
 
3236
                    push @done, $sfile if ( -f $sfile || -l $sfile )
-
 
3237
                }
-
 
3238
            }
-
 
3239
        }
-
 
3240
    }
-
 
3241
 
-
 
3242
    #
-
 
3243
    #   Pretty display the search path - on error
-
 
3244
    #       Will not return.
-
 
3245
    #
-
 
3246
    DisplaySearchPath('ResolveBinFile', $file, \@parts, \@types, \@path) unless (@done) ;
-
 
3247
 
-
 
3248
    if ( $#done > 0 && ! $wildcard )
-
 
3249
    {
-
 
3250
        Warning ("ResolveBinFile: Multiple instances of file found. Only first is used", @done);
-
 
3251
        splice (@done, 1);
-
 
3252
    }
-
 
3253
 
-
 
3254
    return wantarray ? @done : $done[0];
-
 
3255
}
-
 
3256
 
-
 
3257
#-------------------------------------------------------------------------------
-
 
3258
# Function        : ResolveLibFile
-
 
3259
#
-
 
3260
# Description     : Determine where the source for a LIB file is
-
 
3261
#                   Will look in (default):
-
 
3262
#                       Local directory
-
 
3263
#                       Local Include
-
 
3264
#                   Or  (FromPackage)
-
 
3265
#                       Our Package directory
-
 
3266
#                       Interface directory (BuildPkgArchives)
-
 
3267
#                       Packages (LinkPkgArchive)
-
 
3268
#                   Will scan 'parts' subdirs
-
 
3269
#
-
 
3270
# Inputs          : $from_package   - 0:Local File
-
 
3271
#                   $file           - Basename for a 'realname'
-
 
3272
#                                     Do not provide 'lib' or '.so' or version info
-
 
3273
#                                     May contain embedded options
-
 
3274
#                                       --Dll           - Use Windows style versioned DLL
-
 
3275
#                                       --VersionDll    - Use the versioned DLL
-
 
3276
#                                       --3rdParty      - Use exact name provided
-
 
3277
#                   $refPlatforms       - Ref to an array of platforms to scan
-
 
3278
#
-
 
3279
# Returns         : Path
-
 
3280
#
-
 
3281
sub ResolveLibFile
-
 
3282
{
-
 
3283
    my ($from_package, $file, $refPlatforms) = @_;
-
 
3284
    my $wildcard = ($file =~ /[*?]/);
-
 
3285
    my @options;
-
 
3286
    my $num_dll;
-
 
3287
    my @types;
-
 
3288
    my @path;
-
 
3289
    #
-
 
3290
    #   Extract options from file
-
 
3291
    #
-
 
3292
    $num_dll = 0;
-
 
3293
    ($file, @options) = split ( ',', $file);
-
 
3294
    foreach ( @options )
-
 
3295
    {
-
 
3296
        if ( m/^--Dll/ ) {
-
 
3297
            $num_dll = 1;
-
 
3298
        } elsif ( m/^--VersionDll/ ) {
-
 
3299
            $num_dll = 2;
-
 
3300
        } elsif ( m/^--3rdParty/ ) {
-
 
3301
            $num_dll = 3;
-
 
3302
        } else {
-
 
3303
            Error ("Unknown suboption to ResolveLibFile: $_" );
-
 
3304
        }
-
 
3305
    }
-
 
3306
 
-
 
3307
    #
-
 
3308
    #   Determine the paths to search
-
 
3309
    #
-
 
3310
    if ( $from_package )
-
 
3311
    {
-
 
3312
        unless ( @ResolveLibFileList )
-
 
3313
        {
-
 
3314
            push @ResolveLibFileList, $opt_pkgdir . '/lib';
-
 
3315
            foreach my $entry ( getPackageList() )
-
 
3316
            {
-
 
3317
                push @ResolveLibFileList, $entry->getLibDirs(3);
-
 
3318
            }
-
 
3319
        }
-
 
3320
        @path = @ResolveLibFileList;
-
 
3321
    }
-
 
3322
    else
-
 
3323
    {
-
 
3324
        @path = ($opt_libdir, $opt_locallibdir);
-
 
3325
    }
-
 
3326
 
-
 
3327
    #   Determine a full list of 'parts' to search
-
 
3328
    #       Default: Provided within the build information
-
 
3329
    #       User   : Can provide a list
-
 
3330
    my @parts = getPlatformPartsList($refPlatforms);
-
 
3331
 
-
 
3332
    @types = ( $opt_type, '');
-
 
3333
 
-
 
3334
    my @done;
-
 
3335
    foreach my $root (  @path )
-
 
3336
    {
-
 
3337
        foreach my $type ( @types )
-
 
3338
        {
-
 
3339
            foreach my $subdir ( @parts )
-
 
3340
            {
-
 
3341
                my $sfile;
-
 
3342
                my $exact;
-
 
3343
                if ( $num_dll == 2 ) {
-
 
3344
                    $sfile = $file . $type . '.*.dll' ;
-
 
3345
                } elsif ( $num_dll == 1 ) {
-
 
3346
                    $sfile = $file . $type . '.dll' ;
-
 
3347
                    $exact = 1;
-
 
3348
                } elsif ( $num_dll == 3 ) {
-
 
3349
                    $sfile = $file;
-
 
3350
                    $exact = 1;
-
 
3351
                } else {
-
 
3352
                    $sfile = "lib" . $file . $type . '.so.*';
-
 
3353
                }
-
 
3354
 
-
 
3355
                $sfile = "$root/$subdir/$sfile";
-
 
3356
                $sfile =~ s~//~/~g;
-
 
3357
                Verbose2("LocateLibFile: $sfile");
-
 
3358
                if ( $exact )
-
 
3359
                {
-
 
3360
                    push @done, $sfile if ( -f $sfile || -l $sfile );
-
 
3361
                }
-
 
3362
                elsif ($num_dll)
-
 
3363
                {
-
 
3364
                    push @done, glob ( $sfile );
-
 
3365
                }
-
 
3366
                else
-
 
3367
                {
-
 
3368
                    #
-
 
3369
                    #   Looking for .so files
-
 
3370
                    #   Filter out the soname so files
-
 
3371
                    #   Assume that the soname is shorter than the realname
-
 
3372
                    #       Ignore .dbg (vix) and .debug (qt) files.
-
 
3373
                    #
-
 
3374
                    my %sieve;
-
 
3375
                    foreach ( glob ( $sfile )  )
-
 
3376
                    {
-
 
3377
                        next if ( m~\.dbg$~ );
-
 
3378
                        next if ( m~\.debug$~ );
-
 
3379
                        m~(.*\.so\.)([\d\.]*\d)$~;
-
 
3380
                        if ( $1 )
-
 
3381
                        {
-
 
3382
                            my $file = $1;
-
 
3383
                            my $len = exists $sieve{$file} ? length($sieve{$file}) : 0;
-
 
3384
                            $sieve{$file} = $_
-
 
3385
                                if ( $len == 0 || length($_) > $len );
-
 
3386
                        }                                
-
 
3387
                    }
-
 
3388
 
-
 
3389
                    push @done, values %sieve;
-
 
3390
                }
-
 
3391
            }
-
 
3392
        }
-
 
3393
    }
-
 
3394
 
-
 
3395
    DisplaySearchPath('ResolveLibFile', $file, \@parts, \@types, \@path) unless (@done) ;
-
 
3396
 
-
 
3397
    if ( $#done > 0 && ! $wildcard )
-
 
3398
    {
-
 
3399
        Warning ("ResolveLibFile: Multiple instances of file found. Only first is used", @done);
-
 
3400
        splice (@done, 1);
-
 
3401
    }
-
 
3402
    return wantarray ? @done : $done[0];
-
 
3403
}
-
 
3404
 
-
 
3405
#-------------------------------------------------------------------------------
-
 
3406
# Function        : ResolveDebPackage
-
 
3407
#
-
 
3408
# Description     : Determine where the source for a Debian Package is
-
 
3409
#                   Will look in (default):
-
 
3410
#                       Local directory
-
 
3411
#                       Local Include
-
 
3412
#                   Or  (FromPackage)
-
 
3413
#                       Our Package directory
-
 
3414
#                       Interface directory (BuildPkgArchives)
-
 
3415
#                       Packages (LinkPkgArchive)
-
 
3416
#
-
 
3417
# Inputs          : $from_package   - 0:Local File
-
 
3418
#                   $baseName       - Basename for a 'DebianPackage'
-
 
3419
#                                     Do not provide version info, architecture or suffix
-
 
3420
#                                     May contain embedded options
-
 
3421
#                                       --Arch=XXX      - Specify alternate architcuture
-
 
3422
#                                       --Product=YYYY  - Specify product family
-
 
3423
#                                       --Debug         - Use alternate build type
-
 
3424
#                                       --Prod          - Use alternate build type
-
 
3425
#                   $refPlatforms       - Ref to an array of platforms to scan
-
 
3426
#
-
 
3427
# Returns         : Path
-
 
3428
#
-
 
3429
sub ResolveDebPackage
-
 
3430
{
-
 
3431
    my ($from_package, $file, $refPlatforms) = @_;
-
 
3432
    my @path;
-
 
3433
    my $arch;
-
 
3434
    my $product;
-
 
3435
    my $buildType;
-
 
3436
    my @types;
-
 
3437
    my $baseName;
-
 
3438
    my @options;
-
 
3439
 
-
 
3440
    #
-
 
3441
    #   Extract options from file
-
 
3442
    #
-
 
3443
    ($baseName, @options) = split ( ',', $file);
-
 
3444
    foreach ( @options )
-
 
3445
    {
-
 
3446
        if ( m/^--Arch=(.+)/ ) {
-
 
3447
            $arch=$1;
-
 
3448
        } elsif ( m/^--Product=(.+)/ ) {
-
 
3449
            $product = $1;
-
 
3450
        } elsif ( m/^--Debug/ ) {
-
 
3451
            Error ("ResolveDebPackage: Cannot specify --Prod and --Debug") if defined $buildType;
-
 
3452
            $buildType = 'D';
-
 
3453
        } elsif ( m/^--Prod/ ) {
-
 
3454
            Error ("ResolveDebPackage: Cannot specify --Prod and --Debug") if defined $buildType;
-
 
3455
            $buildType = 'P';
-
 
3456
        } else {
-
 
3457
            Error ("Unknown suboption to ResolveDebPackage: $_" );
-
 
3458
        }
-
 
3459
    }
-
 
3460
 
-
 
3461
    #
-
 
3462
    #   Insert defaults
-
 
3463
    #
-
 
3464
    $buildType = $opt_type unless ($buildType);
-
 
3465
    $arch = $opt_target unless ($arch);
-
 
3466
 
-
 
3467
    #
-
 
3468
    #   Determine the paths to search
-
 
3469
    #
-
 
3470
    if ( $from_package )
-
 
3471
    {
-
 
3472
        unless ( @ResolveDebFileList )
-
 
3473
        {
-
 
3474
            push @ResolveDebFileList,  $opt_pkgdir, $opt_pkgdir . '/bin';
-
 
3475
            foreach my $entry ( getPackageList() )
-
 
3476
            {
-
 
3477
                if ( my $path = $entry->getBase(3) )
-
 
3478
                {
-
 
3479
                    push @ResolveDebFileList, $path if ( -d $path );
-
 
3480
 
-
 
3481
                    $path .= '/bin';
-
 
3482
                    push @ResolveDebFileList, $path if ( -d $path );
-
 
3483
                }
-
 
3484
            }
-
 
3485
        }
-
 
3486
        @path = @ResolveDebFileList;
-
 
3487
        @types = ($buildType, '');
-
 
3488
    }
-
 
3489
    else
-
 
3490
    {
-
 
3491
        @path = ($opt_bindir, $opt_localbindir);
-
 
3492
        @types = ($buildType, '');
-
 
3493
    }
-
 
3494
 
-
 
3495
    #
-
 
3496
    #   The debian  package name is
-
 
3497
    #   In packages BIN dir
-
 
3498
    #       (BaseName)_VersionString(_Product)(_Arch).deb
-
 
3499
    #       
-
 
3500
    #   In root of package
-
 
3501
    #       (BaseName)_VersionString(_Product)(_Arch)(_Type).deb
-
 
3502
    #
-
 
3503
    #       
-
 
3504
    #   The package may be found in
-
 
3505
    #       Package Root
-
 
3506
    #       Package bin directory
-
 
3507
    #       
-
 
3508
    $file = $baseName . '_*';
-
 
3509
    if (defined $product) {
-
 
3510
        $file .= ( '_' . $product)
-
 
3511
        }
-
 
3512
    $file .= '_' . $arch;
-
 
3513
 
-
 
3514
    #   Determine a full list of 'parts' to search
-
 
3515
    #       Default: Provided within the build information
-
 
3516
    #       User   : Can provide a list
-
 
3517
    my @parts = getPlatformPartsList($refPlatforms);
-
 
3518
 
-
 
3519
    my @done;
-
 
3520
    foreach my $root (  @path )
-
 
3521
    {
-
 
3522
        foreach my $subdir ( @parts )
-
 
3523
        {
-
 
3524
            foreach my $type ( @types )
-
 
3525
            {
-
 
3526
                my $sfile;
-
 
3527
                $sfile = "$root/$subdir$type/$file";
-
 
3528
                $sfile =~ s~//~/~g;
-
 
3529
                foreach my $type2 ( @types )
-
 
3530
                {
-
 
3531
                    my $tfile = $sfile;
-
 
3532
                    $tfile .= '_' . $type2 if $type2;
-
 
3533
                    $tfile .= '.deb';
-
 
3534
                    Verbose2("ResolveDebPackage: $tfile");
-
 
3535
                    foreach  ( glob ( $tfile ) )
-
 
3536
                    {
-
 
3537
                        push @done, $_;
-
 
3538
                    }
-
 
3539
                }
-
 
3540
            }
-
 
3541
        }
-
 
3542
    }
-
 
3543
 
-
 
3544
    DisplaySearchPath('ResolveDebPackage', $file, \@parts, \@types, \@path) unless (@done) ;
-
 
3545
 
-
 
3546
    if ( $#done > 0 )
-
 
3547
    {
-
 
3548
        Error ("ResolveDebPackage: Multiple instances of Package found.", @done);
-
 
3549
    }
-
 
3550
    return wantarray ? @done : $done[0];
-
 
3551
}
-
 
3552
 
-
 
3553
#-------------------------------------------------------------------------------
-
 
3554
# Function        : prettyArray 
-
 
3555
#
-
 
3556
# Description     : Generate a quoted string from an array
-
 
3557
#
-
 
3558
# Inputs          : Array Ref
-
 
3559
#
-
 
3560
# Returns         : A string
-
 
3561
#
-
 
3562
sub prettyArray
-
 
3563
{
-
 
3564
    my ($arrayRef) = @_;
-
 
3565
    return join(',', map { qq!"$_"! }  @{$arrayRef})
-
 
3566
}
-
 
3567
 
-
 
3568
#-------------------------------------------------------------------------------
-
 
3569
# Function        : DisplaySearchPath 
-
 
3570
#
-
 
3571
# Description     : Pretty display of the search path
-
 
3572
#                   Error display
-
 
3573
#
-
 
3574
# Inputs          : $name   - Function Name
-
 
3575
#                   $file   - Base filename being searched
-
 
3576
#                   $parts  - Ref to array of parts searched
-
 
3577
#                   $types  - Ref to array of types searched - may be undef
-
 
3578
#                   $path   - Ref to array of paths searched
-
 
3579
#
-
 
3580
# Returns         : Will not return
-
 
3581
#
-
 
3582
sub DisplaySearchPath
-
 
3583
{
-
 
3584
    my ($name, $file, $parts, $types, $path) = @_;
-
 
3585
    my @text;
-
 
3586
 
-
 
3587
    push @text, $name . ': File not found: ' . $file;
-
 
3588
    push @text, 'Search Platforms: ' . prettyArray($parts);
-
 
3589
    push @text, 'Search Types: ' . prettyArray($types) if defined $types;
-
 
3590
    push @text, 'Search Path:', @$path;
-
 
3591
    Error (@text);
-
 
3592
}
-
 
3593
 
-
 
3594
#-------------------------------------------------------------------------------
-
 
3595
# Function        : getPlatformPartsList  
-
 
3596
#
-
 
3597
# Description     : Determine a full list of 'parts' to search
-
 
3598
#                       Default: Provided within the build information
-
 
3599
#                       User   : Can provide a list
-
 
3600
#
-
 
3601
# Inputs          : $refPlatforms - Ref to an array of user provided platforms
-
 
3602
#                                   If provided will override the internal list
-
 
3603
#
-
 
3604
# Returns         : An array 
-
 
3605
#
-
 
3606
sub getPlatformPartsList
-
 
3607
{
-
 
3608
    my ($refPlatforms) = @_;
-
 
3609
    my @parts;
-
 
3610
 
-
 
3611
    if ($refPlatforms && scalar @{$refPlatforms}) {
-
 
3612
        @parts = @{$refPlatforms};
-
 
3613
 
-
 
3614
    } else {
-
 
3615
        @parts = getPlatformParts ();
-
 
3616
    }
-
 
3617
    push @parts, '';
-
 
3618
    return @parts;
-
 
3619
}
-
 
3620
 
-
 
3621
#-------------------------------------------------------------------------------
-
 
3622
# Function        : AUTOLOAD
-
 
3623
#
-
 
3624
# Description     : Intercept unknown user directives and issue a nice error message
-
 
3625
#                   This is a simple routine to report unknown user directives
-
 
3626
#                   It does not attempt to distinguish between user errors and
-
 
3627
#                   programming errors. It assumes that the program has been
-
 
3628
#                   tested. The function simply report filename and line number
-
 
3629
#                   of the bad directive.
-
 
3630
#
-
 
3631
# Inputs          : Original function arguments ( not used )
-
 
3632
#
-
 
3633
# Returns         : This function does not return
-
 
3634
#
-
 
3635
our $AUTOLOAD;
-
 
3636
sub AUTOLOAD
-
 
3637
{
-
 
3638
    my $fname = $AUTOLOAD;
-
 
3639
    $fname =~ s~^main::~~;
-
 
3640
    my ($package, $filename, $line) = caller;
-
 
3641
    my $prefix;
-
 
3642
 
-
 
3643
    #
-
 
3644
    #   Some directives are applicable to Rpm and/or Debian only
-
 
3645
    #   If a directive starts with Rpm, Debian or All, then invoke
-
 
3646
    #   the underlying directive iff we are process a Debian/Rpm file
-
 
3647
    #   
-
 
3648
    #   The underlying directive will start with MULTI_
-
 
3649
    #   It will be called with the first argument being the name of the function
-
 
3650
    #   that it is being called as.
-
 
3651
    #
-
 
3652
    $fname =~ m~^(Rpm|Debian|All)(.*)~;
-
 
3653
    if (defined $1) {
-
 
3654
        my $type = $1;
-
 
3655
        my $tfname = 'MULTI_' . $2;
-
 
3656
        my $fRef = \&{$tfname}; 
-
 
3657
 
-
 
3658
        if (defined &{$tfname}) {
-
 
3659
            if ($type eq 'Rpm') {
-
 
3660
                $fRef->($fname, @_) if $opt_rpm;
-
 
3661
 
-
 
3662
            } elsif ($type eq 'Debian') {
-
 
3663
                $fRef->($fname, @_) if $opt_debian;
-
 
3664
 
-
 
3665
            } elsif ($type eq 'All') {
-
 
3666
                $fRef->($fname, @_);
-
 
3667
            }
-
 
3668
            return 1;
-
 
3669
        }
-
 
3670
    }
-
 
3671
 
-
 
3672
    Error ("Directive not known or not allowed in this context: $fname",
-
 
3673
           "Directive: $fname( @_ );",
-
 
3674
           "File: " . RelPath($filename) . ", Line: $line" );
-
 
3675
}
-
 
3676
 
-
 
3677
1;
-
 
3678