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 / perl / CXRPM.pm

# (c) Copyright 2006-2008, 2010. CodeWeavers, Inc.
package CXRPM;
use warnings;
use strict;

use CXLog;
use CXUtils;


#####
#
# Static functions
#
#####

sub compute_package_name($)
{
    my ($name)=@_;
    $name =~ s/[ <>=]/_/g;
    return $name;
}

sub escape_file_path($)
{
    my ($path)=@_;
    # This is the status with rpm 4.4.2.3:
    # - Paths containing a space must be enclosed in quotes. Quoting just the
    #   space or any form of escaping does not work.
    # - '*' must be escaped by enclosing it in square brackets. It will still
    #   trigger a 'file listed twice' warning but it will work regardless.
    # - '!', '#', '$', '%', '&', '(', ')', ';', '<', '>', '[', '\', ']', '`',
    # '{', '|' and '}' also trigger the same warning but don't need escaping.
    # - ''' and '"' must not be quoted and must not be escaped.
    # - If a path contains both a space and a single or double quote...
    #   well, let's hope this does not happen.
    $path =~ s/(\*)/[$1]/g;
    return "\"$path\"" if ($path =~ / /);
    return $path;
}


#####
#
# The CXRPM class
#
#####

sub new($)
{
    my ($class)=@_;
    my $self={ };
    bless $self, $class;

    $self->{rpmbuild}=CXUtils::cxwhich($ENV{PATH}, "rpmbuild");
    if (!defined $self->{rpmbuild})
    {
        $self->{warn}="You may need to install some rpm development " .
                      "packages such as rpm-build";
        $self->{rpmbuild}=CXUtils::cxwhich($ENV{PATH}, "rpm");
        if (!defined $self->{rpmbuild})
        {
            cxerr("unable to find rpmbuild or rpm - $self->{warn}\n");
            cxerr("cannot build the RPM packages\n");
        }
    }

    return $self;
}

sub get_rpm_version($)
{
    my ($self)=@_;
    return cxbackquote(shquote_string($self->{rpmbuild}) . " --version 2>&1");
}

sub map_directory($$$$)
{
    my ($self, $root, $dir, $mode)=@_;
    # Return undef to not package the directory
    # Otherwise return the destination path and desired mode
    return ($dir, $mode);
}

sub map_file($$$$)
{
    my ($self, $root, $file, $mode)=@_;
    # Return undef to not package the file
    # Otherwise return the destination path and desired mode
    return ($file, $mode);
}

sub create_image($$$)
{
    my ($self, $src, $dstroot)=@_;
    # On SuSE 8.0 rpm 3.0.6 has a bug which is triggered
    # by using hardlinks to copy the source directory
    my $nolinks=($self->get_rpm_version() =~ /\s3\./);

    if (!cxmkpath($dstroot, 0700))
    {
        cxerr("unable to create the '$dstroot' directory: $@\n");
        return 0;
    }
    my $mode=(stat($src))[2] & 07777;
    chmod($mode, $dstroot);

    my @dirs=("");
    while (@dirs)
    {
        my $dir=shift @dirs;
        cxlog("$dir\n");

        my $dh;
        if (!opendir($dh, "$src/$dir"))
        {
            cxerr("unable to open the '$src/$dir' directory: $!\n");
            return 0;
        }
        foreach my $dentry (readdir $dh)
        {
            next if ($dentry =~ /^\.\.?$/);
            $dentry="$dir$dentry";

            my $mode=(lstat("$src/$dentry"))[2];
            if (-l _)
            {
                my ($dst, $dmode, $gunzip)=$self->map_file($src, $dentry, $mode);
                if (!defined $dst)
                {
                    cxlog("ignoring $dentry\n");
                    next;
                }
                if ($gunzip)
                {
                    cxerr("not decompressing symbolic links '$dentry'\n");
                    return 0;
                }
                my $lnk=readlink "$src/$dentry";
                if (!symlink $lnk, "$dstroot/$dst")
                {
                    cxerr("unable to symlink '$dstroot/$dst' to '$lnk': $!\n");
                    return 0;
                }
            }
            elsif (-d _)
            {
                my ($dst, $dmode)=$self->map_directory($src, $dentry, $mode);
                next if (!defined $dst);
                if (!mkdir("$dstroot/$dst", 0700))
                {
                    cxerr("unable to create the '$dstroot/$dst' directory: $!\n");
                    return 0;
                }
                chmod($dmode & 07777, "$dstroot/$dst");
                push @dirs, "$dentry/";
            }
            else
            {
                my ($dst, $dmode, $gunzip)=$self->map_file($src, $dentry, $mode);
                next if (!defined $dst);
                if (($dmode != $mode) or $nolinks or $gunzip or
                    !link "$src/$dentry", "$dstroot/$dst")
                {
                    require File::Copy;
                    if (!File::Copy::copy("$src/$dentry", "$dstroot/$dst"))
                    {
                        cxerr("unable to copy '$src/$dentry' to '$dstroot/$dst': $!\n");
                        return 0;
                    }
                    chmod($dmode & 07777, "$dstroot/$dst");
                }
                if ($gunzip and cxsystem(CXUtils::get_gzip(), "-d", "$dstroot/$dst"))
                {
                    cxerr("unable to decompress '$dstroot/$dst'\n");
                    return 0;
                }
            }
        }
        closedir($dh);
    }
    return 1;
}

sub build($$;$)
{
    my ($self, $rpmdir, $arch)=@_;
    return 1 if (!defined $self->{rpmbuild});

    my @cmd=(shquote_string($self->{rpmbuild}), "-bb");
    push @cmd, "--buildroot", shquote_string("$rpmdir/image") if ($self->{rpmbuild} =~ /rpmbuild$/);
    push @cmd, "--target", $arch if ($arch);
    push @cmd, "--define", shquote_string("_rpmdir $rpmdir"),
               shquote_string("$rpmdir/rpm.spec"), "2>&1";
    my $output=cxbackquote(join(" ", @cmd));
    if ($?)
    {
        print STDERR $output;
        cxwarn("$self->{rpmbuild} failed - $self->{warn}\n") if ($self->{warn});
    }
    return $?;
}

return 1;