Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

beebox / crossover   deb

Repository URL to install this package:

Version: 18.5.0-1 

/ opt / cxoffice / lib / cxupgrade

#!/usr/bin/perl
# (c) Copyright 2002-2010. 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;

my $builtin_product_id=CXUtils::get_builtin_product_id();


#####
#
# Configuration file creation / upgrade
#
#####

sub detect_shortcutdirs($)
{
    my ($section)=@_;
    my $dirs=$section->get("ManagedShortcutDirs");
    if (!defined $dirs and $> == 0)
    {
        my @list;
        push @list, "/usr/bin" if (-d "/usr/bin" and -w "/usr/bin");
        push @list, "\${CX_ROOT}/bin";
        $section->set("ManagedShortcutDirs", join(":", @list)) if (@list);
    }

    $dirs=$section->get("PrivateShortcutDirs");
    if (!defined $dirs)
    {
        my @list;
        push @list, "\${HOME}/bin";
        push @list, "\${CX_ROOT}/bin" if ($> != 0);
        $section->set("PrivateShortcutDirs", join(":", @list)) if (@list);
    }
}

sub detect_plugindirs($)
{
    my ($section)=@_;

    # 64 bit systems tend to have a mix of 32bit and 64bit browsers
    # all using the same plugin directories. So in this case simply
    # replicate the directory settings
    my $setup_plugins64=(`uname -m` =~ /64/);
    my $platform="Linux";

    # Detect the plugin directories
    my $dirs=$section->get("Managed${platform}NSPluginDirs");
    my $dirs64=($setup_plugins64 ? $section->get("Managed${platform}64NSPluginDirs") : "");
    if ((!defined $dirs or !defined $dirs64) and $> == 0)
    {
        # These directories may contain either 32bit or 64bit plugins
        my @list;
        foreach my $known_dir ("opt/mozilla*/plugins",
                               "opt/mozilla*/lib/plugins",
                               "opt/netscape*/plugins",
                               "usr/lib/browser-plugins",
                               "usr/lib/firefox*/plugins",
                               "usr/lib/mozilla*/plugins",
                               "usr/lib/netscape*/plugins",
                               "usr/lib/seamonkey*/plugins",
                               "usr/local/firefox*/plugins",
                               "usr/local/mozilla*/plugins",
                               "usr/local/netscape*/plugins")
        {
            foreach my $dir (CXUtils::cxglob("", $known_dir))
            {
                push @list, $dir if (-d $dir and -w _);
            }
        }

        # The older Mozillas use NS600_PLUGIN_PATH
        if (defined $ENV{NS600_PLUGIN_PATH})
        {
            push @list, "\${NS600_PLUGIN_PATH}";
        }

        # The newer Mozillas use MOZ_PLUGIN_PATH
        if (defined $ENV{MOZ_PLUGIN_PATH})
        {
            push @list, "\${MOZ_PLUGIN_PATH}";
        }

        # These directories only contain 64bit plugins
        my @list64=@list;
        foreach my $known_dir ("usr/lib64/firefox*/plugins",
                               "usr/lib64/mozilla*/plugins")
        {
            foreach my $dir (CXUtils::cxglob("", $known_dir))
            {
                push @list64, $dir if (-d $dir and -w _);
            }
        }

        if (@list and !defined $dirs)
        {
            $section->set("Managed${platform}NSPluginDirs", join(":", @list));
        }
        if (@list64 and !defined $dirs64)
        {
            $section->set("Managed${platform}64NSPluginDirs", join(":", @list64));
        }
    }
    $dirs=$section->get("Private${platform}NSPluginDirs");
    $dirs64=($setup_plugins64 ? $section->get("Private${platform}64NSPluginDirs") : "");
    if (!defined $dirs or !defined $dirs64)
    {
        my @list;
        my %create;
        foreach my $entry (split /:+/, $section->get("CreateNSPluginDirs", ""))
        {
            $create{$entry}=1;
        }
        # The older Mozillas use NS600_PLUGIN_PATH
        if (defined $ENV{NS600_PLUGIN_PATH})
        {
            push @list, "\${NS600_PLUGIN_PATH}";
        }
        # The newer Mozillas use MOZ_PLUGIN_PATH
        if (defined $ENV{MOZ_PLUGIN_PATH})
        {
            push @list, "\${MOZ_PLUGIN_PATH}";
        }
        if (!@list)
        {
            # And the current versions of Mozilla use this directory
            # by default
            $create{"\${HOME}/.mozilla/plugins"}=1;
            push @list, "\${HOME}/.mozilla/plugins";

            # Also add ~/.netscape/plugins because this is the only place
            # many browsers (e.g. Konqueror) look at for per-user plugins
            $create{"\${HOME}/.netscape/plugins"}=1;
            push @list, "\${HOME}/.netscape/plugins";
        }
        if (@list)
        {
            my $pdirs=join(":", @list);
            if (!defined $dirs)
            {
                $section->set("Private${platform}NSPluginDirs", $pdirs);
            }
            if (!defined $dirs64)
            {
                $section->set("Private${platform}64NSPluginDirs", $pdirs);
            }
        }
        $section->set("CreateNSPluginDirs", join(":", sort keys %create)) if (%create);
    }
}

sub create_crossover_config($$$)
{
    my ($filename, $package, $productid)=@_;

    my $template="$ENV{CX_ROOT}/share/crossover/data/$builtin_product_id.conf";
    if (!-e $template)
    {
        cxerr("unable to find '$template'\n");
        exit 1;
    }
    require CXRWConfig;
    my $cxconfig=CXRWConfig->new($template);

    my $s=$cxconfig->get_section("CrossOver");
    return if (!$s);

    detect_shortcutdirs($s);
    detect_plugindirs($s);

    my $libpath=$cxconfig->get("Wine", "LibPath");
    if (!$libpath and `uname -s` eq "SunOS\n" and -d "/usr/X11/lib")
    {
        $cxconfig->set("Wine", "LibPath", "\${CX_ROOT}/lib:/usr/X11/lib:\${LD_LIBRARY_PATH}");
        my $dllpath=$cxconfig->get("Wine", "DllPath");
        $cxconfig->set("Wine", "DllPath", "\${CX_ROOT}/lib/wine") if (!$dllpath);
    }
    $s->set("ProductPackage", $package) if ($package);

    $cxconfig->set_filename($filename);
    if (!$cxconfig->save())
    {
        cxwarn("unable to save '$filename': $!\n");
    }
}

sub upgrade_crossover_config($$$$)
{
    my ($filename, $package, $productid, $opt_old_version)=@_;

    require CXUpgrade;
    cxlog("\nUpgrading '$filename'\n\n");
    my $src=CXUpgrade->new($filename);
    if (!$src)
    {
        cxlog("unable to read '$filename': $!\n");
        $src=CXUpgrade->new(undef);
    }
    my $s=$src->get_section("CrossOver");
    my $old_version;
    $old_version=$s->get("ProductVersion") if (defined $s);
    $old_version=$opt_old_version || "1.3.1" if (!defined $old_version);
    cxlog("Old Version=$old_version\n");
    $old_version=~s/[^0-9.].*$//;
    $old_version=~s/^([0-9]\.)/0$1/;

    my $template="$ENV{CX_ROOT}/share/crossover/data/$builtin_product_id.conf";
    my $dst=CXUpgrade->new($template);
    if (!defined $dst)
    {
        cxerr("unable to read '$template': $!\n");
        return $old_version;
    }


    # Tweak the configuration values
    my $bottle=$src->add_section("BottleDefaults");
    $s=$src->get_section("CrossOver");
    if (defined $s)
    {
        # We never keep these settings from the old file
        $s->remove_field("Product");
        $s->remove_field("ProductID");
        $s->remove_field("ProductName");
        $s->remove_field("ProductVersion");
        $s->remove_field("BuildTag");
        $s->remove_field("BuildTimestamp");

        # ConfigFileVersion has been removed
        $s->remove_field("ConfigFileVersion");

        if ($old_version lt "05.0")
        {
            detect_shortcutdirs($s);

            my $plugindirs=$s->get("LinuxNSPluginDirs");
            if ($plugindirs)
            {
                my $scope=($> == 0 ? "Managed" : "Private");
                $s->set("${scope}LinuxNSPluginDirs", $plugindirs);
                $s->remove_field("LinuxNSPluginDirs");
            }
            detect_plugindirs($s);
        }

        # LinuxBrowser -> PreferredBrowser
        my $value=$s->get("LinuxBrowser");
        if (defined $value)
        {
            $s->set("PreferredBrowser",$value);
        }
        $s->remove_field("LinuxBrowser");

        # Update MIMEIgnoreList
        my $d=$s->get("MIMEIgnoreList", "");
        if ($d =~ m!^text/html(?::text/plain:application/x-crossover-doc)?$!)
        {
            $s->remove_field("MIMEIgnoreList");
        }
    }
    else
    {
        $s=$src->add_section("CrossOver");
    }
    $s->set("ProductPackage", $package) if ($package);

    # [BottleDefaults] / MyDocumentsDir has been removed
    $bottle->remove_field("MyDocumentsDir");

    $s=$src->get_section("MIMEAliases");
    if (defined $s)
    {
        my $d;
        $d=$s->get("application/msexcel", "");
        $s->remove_field("application/msexcel") if ($d eq "application/vnd.ms-excel");

        $d=$s->get("application/mspowerpoint", "");
        $s->remove_field("application/mspowerpoint") if ($d eq "application/vnd.ms-powerpoint");

        $d=$s->get("video/x-ms-asf", "");
        $s->remove_field("video/x-ms-asf") if ($d eq "video/x-ms-wmv");
    }

    $s=$src->get_section("OfficeSetup");
    if (defined $s)
    {
        # UrlOnlineUpdate does not exist anymore
        $s->remove_field("UrlOnlineUpdate");

        # MIMEIgnoreList moved to [CrossOver]
        my $field=$s->get_field("MIMEIgnoreList");
        my $d=$src->get_section("CrossOver");
        if (defined $field and defined $d)
        {
            $d->add_field($field);
        }
        $s->remove_field("MIMEIgnoreList");

        # MyDocsDir, HttpProxyHost and HttpProxyPort don't exist anymore
        $s->remove_field("MyDocsDir");
        $s->remove_field("HttpProxyHost");
        $s->remove_field("HttpProxyPort");

        # OutlookSecurity & BlockedExtensions moved to [BottleDefaults]
        $field=$s->get_field("OutlookSecurity");
        if (defined $field)
        {
            $s->remove_field("OutlookSecurity");
            $bottle->add_field($field);
        }
        $field=$s->get_field("BlockedExtensions");
        if (defined $field)
        {
            $s->remove_field("BlockedExtensions");
            $bottle->add_field($field);
        }
    }

    $s=$src->get_section("Default");
    if (defined $s)
    {
        # MainPath, WinePrefix, RootMode & SkipDebianMenus do not exist anymore
        $s->remove_field("MainPath");
        $s->remove_field("WinePrefix");
        $s->remove_field("RootMode");
        $s->remove_field("SkipDebianMenus");

        # WinePrefixCreate moved to cxbottle.conf
        $s->remove_field("WinePrefixCreate");

        # LDAssumeKernel and WineDebugLevel have been removed
        $s->remove_field("LDAssumeKernel");
        $s->remove_field("WineDebugLevel");

        # Update the LDPreload field
        my $value=$s->get("LDPreload");
        if (defined $value)
        {
            # LDPreload="" is now what ';LDPreload' does
            $s->remove_field("LDPreload") if ($value eq "");
        }
        elsif (defined $s->get_field("LDPreload"))
        {
            # ';LDPreload' now should be written as follows
            $s->set("LDPreload","\${LD_PRELOAD}");
        }

        # MenuPrefix moved to [BottleDefaults] and cxbottle.conf
        $value=$s->get("MenuPrefix");
        $bottle->set("MenuRoot",$value) if (defined $value);
        $s->remove_field("MenuPrefix");

        # And finally, rename this section to [Wine]
        $src->rename_section($s, "Wine");
    }

    my $blocked=$bottle->get("BlockedExtensions", "");
    if (# versions <= 3.0.0
        $blocked eq "bat;com;exe;hta;lnk;pif;scr;vbe;vbs;wsf;wsh" or
        # versions < 2.0.0
        $blocked eq "vbs;wsf;vbe;wsh;hta;bat;pif;exe;scr;lnk")
    {
        $bottle->remove_field("BlockedExtensions");
    }

    # Do the final merge and write the new configuration file
    $dst->merge($src);
    $dst->write($filename);

    return $old_version;
}



#####
#
# Main
#
#####

# Parse the command line arguments
my $opt_package;
my $opt_productid;
my $opt_old_version;
my $opt_install_bottles;
my $opt_verbose;
my $opt_help;
require CXOpts;
my $cxopts=CXOpts->new();
$cxopts->add_options(["package=s"       => \$opt_package,
                      "productid=s"     => \$opt_productid,
                      "old-version=s"   => \$opt_old_version,
                      "install-bottles" => \$opt_install_bottles,
                      "verbose!"        => \$opt_verbose,
                      "?|h|help"        => \$opt_help
                     ]);
my $err=$cxopts->parse();
CXLog::fdopen(2) if ($opt_verbose);

# Verify command line options
my $usage;
if ($err)
{
    cxerr("$err\n");
    $usage=2;
}
elsif ($opt_help)
{
    $usage=0;
}
else
{
    if (!$opt_productid)
    {
        cxerr("you must specify the product id\n");
        $usage=2;
    }
    $opt_old_version="" if (!defined $opt_old_version);
    $opt_old_version=~s/[^0-9.].*$//;
    $opt_old_version=~s/^([0-9]\.)/0$1/;
}

# Print usage
if (defined $usage)
{
    my $name0=cxname0();
    if ($usage)
    {
        cxerr("try '$name0 --help' for more information\n");
        exit $usage;
    }
    print "Usage: $name0 --productid productid [--old-version oldversion] [--install-bottles] [--verbose]\n";
    exit 0;
}

# Create or upgrade the CrossOver configuration
require CXBottle;
CXBottle::get_crossover_config();
my $filename="$ENV{CX_ROOT}/etc/$opt_productid.conf";
if (!-f $filename)
{
    create_crossover_config($filename, $opt_package, $opt_productid);
}
else
{
    $opt_old_version=upgrade_crossover_config($filename, $opt_package, $opt_productid, $opt_old_version);
}

# Upgrade / install the CrossOver menus and associations
my $uassoc="";
my $umenu="";
if ($opt_old_version ne "")
{
    # For upgrades by default we at least do a removeall to make sure we get
    # rid of obsolete menus and associations before installing the new ones.
    $umenu=$uassoc="removeall";
    if ($opt_old_version lt "05.0")
    {
        if ($opt_productid eq $builtin_product_id)
        {
            # Delete the legacy menus, associations and plugins
            my @scopes=("private");
            push @scopes, "managed" if ($> == 0);
            foreach my $scope (@scopes)
            {
                cxsystem("$ENV{CX_ROOT}/bin/cxmenu", "--removeall",
                         "--pattern", "legacy", "--scope", $scope,
                         "--ignorelist", "");
                cxsystem("$ENV{CX_ROOT}/bin/cxassoc", "--removeall",
                         "--pattern", "legacy", "--scope", $scope,
                         "--ignorelist", "");
                cxsystem("$ENV{CX_ROOT}/bin/cxnsplugin", "--removeall",
                         "--pattern", "legacy", "--scope", $scope);
            }
        }
        # - The above commands also deleted the legacy menus, associations and
        #   plugins of existing bottles. This makes it almost impossible to
        #   use them. So trigger an upgrade of the bottles (letting the wine
        #   script do all the work) which will re-install them too.
        # - Also, always try to trigger an upgrade of the (presumably) managed
        #   bottles as they are mostly used by non-root users and those users
        #   cannot upgrade them.
        $uassoc="";
        $umenu="";
    }
    if ($opt_old_version le "10.0.1")
    {
        $uassoc="nukeall";
    }
}

my @cmd;
@cmd=("$ENV{CX_ROOT}/bin/cxassoc", "--crossover");
if ($uassoc eq "nukeall")
{
    # This action must be used when locate_gui.sh's arbitration
    # between association systems changes. Otherwise we risk not
    # removing associations for systems that were used but are now
    # in desktop_assoc_ignore_list. This task must be performed as
    # a separate step because of the --ignorelist parameter.
    cxsystem(@cmd, "--removeall", "--ignorelist", "");
}
push @cmd, "--removeall" if ($uassoc eq "removeall");
cxsystem(@cmd, "--install");

@cmd=("$ENV{CX_ROOT}/bin/cxmenu", "--crossover");
if ($umenu eq "nukeall")
{
    # See the comments for the associations nukeall action.
    cxsystem(@cmd, "--removeall", "--ignorelist", "");
}
push @cmd, "--removeall" if ($umenu eq "removeall");
cxsystem(@cmd, "--install");


# Call get_crossover_config() to get CX_(MANAGED_)BOTTLE_PATH.
CXBottle::get_crossover_config();
foreach my $scope ("managed", "private")
{
    my $path=($scope eq "private" ? $ENV{CX_BOTTLE_PATH} : $ENV{CX_MANAGED_BOTTLE_PATH});
    foreach my $dir (split /:+/, $path)
    {
        next if ($dir eq "");

        my $dh;
        next if (!opendir($dh, $dir));
        foreach my $dentry (readdir $dh)
        {
            next if ($dentry =~ /^(?:\.\.?|default)$/);

            # Note that bottles may not have a cxbottle.conf file yet
            next if (!-f "$dir/$dentry/system.reg");

            if ($opt_install_bottles)
            {
                # Check whether the bottle is meant to be installed
                require CXConfig;
                my $cxbottle=CXConfig->new("$dir/$dentry/cxbottle.conf");
                if (CXBottle::get_bottle_mode($cxbottle, $scope) eq "stub")
                {
                    # Stub bottles are not installed (ever) and don't need to
                    # be upgraded. So skip them.
                    cxlog("not reinstalling '$dir/$dentry' because it is a stub\n");
                    next;
                }

                my $installed;
                # Since cxbottle.conf has not be upgraded yet, use 'install'
                # as the default if the 'XxxMode' setting is missing
                if ($cxbottle->get("Bottle", "MenuMode", "install") =~ /^install$/i)
                {
                    cxsystem("$ENV{CX_ROOT}/bin/cxmenu",
                             "--bottle", $dentry, "--scope", $scope,
                             "--install");
                    $installed=1;
                }
                if ($cxbottle->get("Bottle", "AssocMode", "install") =~ /^install$/i)
                {
                    cxsystem("$ENV{CX_ROOT}/bin/cxassoc",
                             "--bottle", $dentry, "--scope", $scope,
                             "--install");
                    $installed=1;
                }
                if ($cxbottle->get("Bottle", "NSPluginMode", "install") =~ /^install$/i)
                {
                    cxsystem("$ENV{CX_ROOT}/bin/cxnsplugin",
                             "--bottle", $dentry, "--scope", $scope,
                             "--install");
                    $installed=1;
                }
                if (!$installed and $scope eq "managed")
                {
                    # Even if they are not installed, upgrade the managed
                    # bottles as not doing so could require upgrading the RPM
                    # bottle package too
                    cxsystem("$ENV{CX_ROOT}/bin/wine",
                             "--bottle", $dentry, "--scope", $scope,
                             "--ux-app", "true");
                }
            }
            elsif ($scope eq "managed")
            {
                # Upgrade the managed bottles as not doing so
                # could require upgrading the RPM bottle package too
                cxsystem("$ENV{CX_ROOT}/bin/wine",
                         "--bottle", $dentry, "--scope", $scope,
                         "--ux-app", "true");
            }
        }
        closedir($dh);
    }
}

exit 0;