#!/usr/bin/perl
# (c) Copyright 2006-2013. CodeWeavers, Inc.
use warnings;
use strict;
# Portable which(1) implementation
sub cxwhich($$;$)
{
my ($dirs, $app, $noexec)=@_;
if ($app =~ /^\//)
{
return $app if ((-x $app or $noexec) and -f $app);
}
elsif ($app =~ /\//)
{
require Cwd;
my $path=Cwd::cwd() . "/$app";
return $path if ((-x $path or $noexec) and -f $path);
}
else
{
foreach my $dir (split /:/, $dirs)
{
return "$dir/$app" if ($dir ne "" and (-x "$dir/$app" or $noexec) and -f "$dir/$app");
}
}
return undef;
}
# Fast dirname() implementation
sub _cxdirname($)
{
my ($path)=@_;
return undef if (!defined $path);
return "." if ($path !~ s!/+[^/]+/*$!!s);
return "/" if ($path eq "");
return $path;
}
# Locate where CrossOver is installed by looking for the directory
# where the cxmenu script is located, unwinding symlinks on the way
sub locate_cx_root(;$)
{
my ($fallback)=@_;
my $argv0=cxwhich($ENV{PATH},$0);
$argv0=$0 if (!defined $argv0);
if ($argv0 !~ m+^/+)
{
require Cwd;
$argv0=Cwd::cwd() . "/$argv0";
}
my $dir=_cxdirname($argv0);
my $bindir=$dir;
$bindir =~ s%/lib$%/bin%;
while (!-x "$bindir/cxmenu" or !-f "$bindir/cxmenu")
{
last if (!-l $argv0);
$argv0=readlink($argv0);
$argv0="$dir/$argv0" if ($argv0 !~ m+^/+);
$dir=_cxdirname($argv0);
$bindir=$dir;
$bindir =~ s%/lib$%/bin%;
}
$bindir =~ s%/(?:\./)+%/%g;
$bindir =~ s%/\.$%%;
$ENV{CX_ROOT}=_cxdirname($bindir);
if ((!-x "$ENV{CX_ROOT}/bin/cxmenu" or !-f "$ENV{CX_ROOT}/bin/cxmenu") and
$fallback)
{
$ENV{CX_ROOT}=$fallback;
}
if (!-x "$ENV{CX_ROOT}/bin/cxmenu" or !-f "$ENV{CX_ROOT}/bin/cxmenu")
{
my $name0=$0;
$name0 =~ s+^.*/++;
print STDERR "$name0:error: could not find CrossOver in '$ENV{CX_ROOT}'\n";
exit 1;
}
return $ENV{CX_ROOT};
}
BEGIN {
unshift @INC, locate_cx_root() . "/lib/perl";
}
use CXLog;
use CXUtils;
{
package CXLinuxDebian;
use CXDebian;
use base "CXDebian";
sub new($$$$$)
{
my ($class, $deb_package, $productid, $buildroot, $installroot)=@_;
my $self=CXDebian::new($class, $buildroot);
if ($self)
{
$self->{deb_package}=$deb_package;
$self->{conf_filter}=join("|", $productid, CXUtils::get_product_id(), CXUtils::get_builtin_product_id());
$self->{installroot}=$installroot;
$self->{docdir}="/usr/share/doc/$deb_package";
}
return $self;
}
sub map_directory($$$)
{
my ($self, $root, $dir)=@_;
if ($self->{doc})
{
return "$self->{docdir}/$dir";
}
return undef if ($dir eq ".mojosetup"); # MojoSetup
return "" if ($dir eq "bin");
return "" if ($dir eq "doc"); # Non-Debian doc directory
return "$self->{docdir}/$dir" if ($dir =~ s!^doc/!!);
return "" if ($dir eq "etc");
return "" if ($dir eq "lib" or $dir eq "lib/python");
return undef if ($dir eq "support");
return "$self->{installroot}/$dir";
}
sub map_file($$$)
{
my ($self, $root, $file)=@_;
if ($self->{doc})
{
return undef if ($file eq "changelog.Debian.gz");
return undef if ($file eq "copyright");
return "$self->{docdir}/$file";
}
return undef if ($file eq ".uninstall"); # MojoSetup
if ($file =~ m!^bin/[^/]+$! and -l "$root/$file")
{
# Don't package cxmenu's shortcut files
my $dst=readlink "$root/$file";
return undef if ($dst =~ m%/desktopdata/cxmenu/Shortcuts/%);
}
return undef if ($file =~ m%^etc/(?:$self->{conf_filter})\.conf%);
return undef if ($file =~ m%^lib/python/.*\.pyc$%);
return undef if ($file eq "doc"); # Debian's doc symlink
return "$self->{docdir}/$file" if ($file =~ s!^doc/!!);
return "$self->{docdir}/changelog" if ($file eq "changelog.txt");
return "$self->{docdir}/changelog.html" if ($file eq "changelog.html");
return "$self->{docdir}/license.txt" if ($file eq "license.txt");
return "$self->{docdir}/README" if ($file eq "README");
return "$self->{installroot}/$file";
}
}
{
package CXLinuxRPM;
use CXRPM;
use base "CXRPM";
sub new($$)
{
my ($class, $productid)=@_;
my $self=$class->SUPER::new();
$self->{conf_filter}=join("|", $productid, CXUtils::get_product_id(), CXUtils::get_builtin_product_id());
return $self;
}
sub map_directory($$$$)
{
my ($self, $root, $dir, $mode)=@_;
if ($self->{doc})
{
push @{$self->{dirs}}, "doc/$dir";
return ("doc/$dir", $mode);
}
return undef if ($dir eq ".mojosetup"); # MojoSetup
return undef if ($dir eq "support");
push @{$self->{dirs}}, $dir;
return ($dir, $mode);
}
sub map_file($$$$)
{
my ($self, $root, $file, $mode)=@_;
if ($self->{doc})
{
# Debian specific
return undef if ($file =~ /^(?:changelog\.Debian(?:\.gz)?|copyright)$/);
if ($file =~ /^changelog(\.gz)?$/)
{
push @{$self->{docfiles}}, "changelog.txt";
return ("changelog.txt.gz", $mode, 1) if (defined $1);
return ("changelog.txt", $mode);
}
if ($file =~ /^changelog\.html(\.gz)?$/)
{
push @{$self->{docfiles}}, "changelog.html";
return ("changelog.html.gz", $mode, 1) if (defined $1);
return ("changelog.html", $mode);
}
if ($file =~ /^README(\.gz)?$/)
{
push @{$self->{docfiles}}, "README";
return ($file, $mode, defined $1);
}
if ($file =~ /^license\.txt(\.gz)?$/)
{
push @{$self->{files}}, "license.txt";
return ($file, $mode, defined $1);
}
push @{$self->{files}}, "doc/$file";
return ("doc/$file", $mode);
}
# MojoSetup
return undef if ($file eq ".uninstall");
# Debian's doc link
return undef if ($file eq "doc" and -l "$root/$file");
return undef if ($file =~ m%^etc/(?:$self->{conf_filter})\.conf%);
if ($file =~ m!^bin/[^/]+$! and -l "$root/$file")
{
# Don't package cxmenu's shortcut files
my $dst=readlink "$root/$file";
return undef if ($dst =~ m%/desktopdata/cxmenu/Shortcuts/%);
}
elsif ($file =~ m%^(?:README|changelog\.txt|changelog\.html)$%)
{
push @{$self->{docfiles}}, $file;
return ($file, $mode);
}
push @{$self->{files}}, $file;
return ($file, $mode);
}
}
{
package CXRSunpkg;
use CXSunpkg;
use base "CXSunpkg";
sub new($$$$)
{
my ($class, $pkgdir, $productid, $compress)=@_;
my $self=$class->SUPER::new($pkgdir, $compress);
$self->{conf_filter}=join("|", $productid, CXUtils::get_product_id(), CXUtils::get_builtin_product_id()) if ($self);
return $self;
}
sub package_directory($$$$)
{
my ($self, $root, $dir, $mode)=@_;
# Note: No need to handle Debian's special documentation directory here
return undef if ($dir eq ".mojosetup"); # MojoSetup
return undef if ($dir eq "support");
return $mode;
}
sub package_file($$$$)
{
my ($self, $root, $file, $mode)=@_;
# Note: No need to handle Debian's special documentation directory here
return undef if ($file eq ".uninstall"); # MojoSetup
return undef if ($file =~ m%^etc/(?:$self->{conf_filter})\.conf%);
if ($file =~ m!^bin/[^/]+$! and -l "$root/$file")
{
# Don't package cxmenu's shortcut files
my $dst=readlink "$root/$file";
return undef if ($dst =~ m%/desktopdata/cxmenu/Shortcuts/%);
}
return $mode;
}
}
sub create_tmpdir()
{
my $tmpdir;
if (-w $ENV{CX_ROOT})
{
$tmpdir="$ENV{CX_ROOT}/support/desktopdata";
if ($> == 0)
{
# Make sure desktopdata is created with the proper permissions
my $umask=umask 0022;
my $rc=!cxmkpath($tmpdir);
umask $umask;
if ($rc)
{
cxerr("unable to create the '$tmpdir' directory: $@\n");
return undef;
}
}
}
else
{
require CXBottle;
$tmpdir=CXBottle::get_user_dir() . "/desktopdata";
}
return "$tmpdir/cxrepackage-$$";
}
sub move_package($$$$)
{
my ($dir, $pattern, $label, $name)=@_;
my @files=CXUtils::cxglob($dir, $pattern);
if (!@files)
{
cxerr("unable to find the $name package\n");
return 0;
}
if (@files > 1)
{
cxerr("found more than one $name package: @files\n");
return 0;
}
my $filename=cxbasename($files[0]);
if (!defined cxmv($files[0], $filename))
{
cxerr("unable to move '$files[0]' to the current directory: $!\n");
return 0;
}
rmdir cxdirname($files[0]);
print "$label: $filename\n";
return 1;
}
# Process command-line options
my $opt_release;
my $opt_deb;
my $opt_deb32;
my $opt_deb64;
my $opt_rpm;
my $opt_sunpkg;
my $opt_sunzip;
my $opt_productid;
my $opt_verbose;
my $opt_help;
require CXOpts;
my $cxopts=CXOpts->new();
$cxopts->add_options(["release=s" => \$opt_release,
"deb" => \$opt_deb,
"deb32" => \$opt_deb32,
"deb64" => \$opt_deb64,
"rpm" => \$opt_rpm,
"sunpkg" => \$opt_sunpkg,
Loading ...