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 / CXSunpkg.pm

# (c) Copyright 2006-2010. CodeWeavers, Inc.
package CXSunpkg;
use warnings;
use strict;
use CXLog;
use CXUtils;



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

sub pkg_sum($)
{
    my ($filename)=@_;
    my $fh;
    if (!open($fh, "<", $filename))
    {
        cxerr("unable to open '$filename' for reading: $!\n");
        return "";
    }

    my $rs=$/;
    $/=undef;
    my $checksum = unpack("%32C*", <$fh>) % 65535;
    close($fh);
    $/=$rs;
    return $checksum;
}

sub compute_package_name($$)
{
    my ($prefix, $name)=@_;

    # Some Solaris 10 has a 32 character limit on package names.
    # (For Solaris 8 and older the limit is 9 characters!)
    my $max=32-length($prefix);

    my $pkg=$name;
    $pkg =~ s/^managed_//;
    if (length($pkg) > $max or $pkg =~ /^clientp?$/)
    {
        $pkg=substr($pkg, 0, $max-2) . CXUtils::base32(CXUtils::hash_string($name), 2);
    }
    return "$prefix$pkg";
}

sub is_valid_zip_format($)
{
    my ($format)=@_;
    return ($format =~ /^(?:none|bzip2|gzip|7z)$/);
}


#####
#
# The CXSunpkg class
#
#####

sub new($$$)
{
    my ($class, $pkgdir, $compress)=@_;
    return if (!is_valid_zip_format($compress));

    if (!cxmkpath("$pkgdir/install", 0755))
    {
        cxerr("unable to create the '$pkgdir/install' directory: $@\n");
        return;
    }

    my $self={pkgmap   => ["13"],
              pkgdir   => $pkgdir,
              compress => $compress
             };

    bless $self, $class;
    return $self;
}

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

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

sub add_symlink($$$)
{
    my ($self, $rlink, $rdst)=@_;
    $rlink=~s!^reloc/!!;
    push @{$self->{pkgmap}}, "1 s none $rlink=$rdst";
    return 1;
}

sub add_file($$$;$$)
{
    my ($self, $type, $rfile, $src, $mode)=@_;
    my $pkgmap=$self->{pkgmap};

    my $dst="$self->{pkgdir}/$rfile";
    if (defined $src)
    {
        require File::Copy;
        if (!File::Copy::copy($src, $dst))
        {
            cxerr("unable to copy '$src' to '$dst': $!\n");
            return 0;
        }
        # No need to set the mode here, it will be set
        # at install time based on pkgmap
    }

    my ($size, $mtime)=(stat($dst))[7,9];
    my $chksum=pkg_sum($dst);
    if ($type eq "i")
    {
        $rfile =~ s!install/!!;
        push @$pkgmap, "1 i $rfile $size $chksum $mtime";
    }
    else
    {
        $rfile=~s!^reloc/!!;
        $mode=sprintf "%04o", $mode & 07777;
        push @$pkgmap, "1 f none $rfile $mode root bin $size $chksum $mtime";
    }
    @$pkgmap[0]+=1+($size >> 9);
    return 1;
}

sub add_dir($$$)
{
    my ($self, $rdir, $mode)=@_;
    my $pkgmap=$self->{pkgmap};

    my $dir="$self->{pkgdir}/$rdir";
    if (!cxmkpath($dir, $mode))
    {
        cxerr("unable to create the '$dir' directory: $@\n");
        return 0;
    }

    $rdir=~s!^reloc/!!;
    $mode=sprintf "%04o", $mode & 07777;
    push @{$self->{pkgmap}}, "1 d none $rdir $mode root bin";
    return 1;
}

sub add_tree($$$$)
{
    my ($self, $rdir, $srcdir, $mode)=@_;

    my @dirs=("", $mode);
    while (@dirs)
    {
        my $dir=shift @dirs;
        $mode=shift @dirs;
        cxlog("dir=$dir\n");
        return 0 if (!$self->add_dir("$rdir/$dir", $mode));

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

            $mode=(lstat("$srcdir/$dentry"))[2];
            if (-l _)
            {
                my $dmode=$self->package_file($srcdir, $dentry, $mode);
                next if (!defined $dmode);
                my $dst=readlink "$srcdir/$dentry";
                $rc=$self->add_symlink("$rdir/$dentry", $dst);
            }
            elsif (-d _)
            {
                my $dmode=$self->package_directory($srcdir, $dentry, $mode);
                next if (!defined $dmode);
                push @dirs, $dentry, $dmode;
            }
            else
            {
                my $dmode=$self->package_file($srcdir, $dentry, $mode);
                next if (!defined $dmode);
                $rc=$self->add_file("f", "$rdir/$dentry", "$srcdir/$dentry", $dmode);
            }
            last if (!$rc);

            if ($dentry =~ /[ =]/)
            {
                $dentry=~ s!^/!!;
                cxerr("cannot package '$dentry'\n");
                cxerr("Solaris packages cannot handle paths containing spaces or equal signs\n");
                return 0;
            }
        }
        closedir($dh);
        return 0 if (!$rc);
    }
    return 1;
}

sub generate_install_files($$$$)
{
    my ($self, $template, $files, $variables)=@_;

    push @$files, "install/i.none" if ($self->{compress} ne "none");
    foreach my $file (@$files)
    {
        my $rc=CXUtils::generate_from_template("$self->{pkgdir}/$file",
                                               $template . cxbasename($file),
                                               $variables);
        return 0 if ($rc);
        return 0 if (!$self->add_file("i", $file));
    }
    return 1;
}

sub finalize($$)
{
    my ($self, $relocdir)=@_;
    my $pkgmap=$self->{pkgmap};
    @$pkgmap[0]=": 1 @$pkgmap[0]";

    my $fh;
    if (!open($fh, ">", "$self->{pkgdir}/pkgmap"))
    {
        cxerr("unable to open '$self->{pkgdir}/pkgmap' for writing: $!\n");
        return 0;
    }
    print $fh join("\n", @$pkgmap), "\n";
    close($fh);

    if ($self->{compress} ne "none")
    {
        my $archive="$self->{pkgdir}/archive";
        if (!cxmkpath($archive, 0755))
        {
            cxerr("unable to create the '$archive' directory: $!\n");
            return 0;
        }

        $relocdir="$self->{pkgdir}/reloc/$relocdir";
        my $cmd=[["cd", $relocdir], "&&",
                 [["find", ".", "-print"],
                  "|",
                  [[CXUtils::get_cpio_o()], "2>"] # cpio pollutes stderr
                 ]];
        if ($self->{compress} eq "gzip")
        {
            $cmd=[$cmd, "|", [[CXUtils::get_gzip(), "-9"], ">", "$archive/none.gz"]];
        }
        elsif ($self->{compress} eq "bzip2")
        {
            $cmd=[$cmd, "|", [[CXUtils::get_bzip2(), "-9"], ">", "$archive/none.bz2"]];
        }
        elsif ($self->{compress} eq "7z")
        {
            # 7za -si pollutes stderr
            $cmd=[$cmd, "|", [["7za", "a", "-mx=9", "-si", "$archive/none.7z"], "2>"]];
        }

        my $shcmd=new_shell_command({cmd => $cmd, capture_output => 1});
        if ($shcmd->run())
        {
            print STDERR $shcmd->get_error_report();
            cxerr("the package compression failed\n");
            return 0;
        }

        require File::Path;
        if (!File::Path::rmtree($relocdir))
        {
            cxerr("unable to delete the '$relocdir' directory: $!\n");
            return 0;
        }
    }
    return 1;
}

return 1;