>Eric Boutilier wrote:
>> With the availability of the Solaris Express DVD ISO download, I'm 
>> wondering if there's a script (or whatever) anywhere that recursively 
>> identifies, while omitting duplicates, all the dependencies and 
>> sub-dependencies of a given package. In other words, on a system with 
>> the ISO mounted, a script that takes a package name as an argument, 
>> outputs the dependencies listed in that package's "install/depend" file; 
>> followed by the dependencies listed in those packages "install/depend" 
>> files, etc.
>> 
>
>Glenn Brunette sent out something internally yesterday which is 
>approximately this (search for Solaris Package Companion in the mail 
>archives); I was going to ask him to post it here as well, but I'm a 
>little behind on things.  I'll drop him a note, I promise.
>
>> (Seems easy enough to throw something together, but I just thought I'd 
>> try and avoid duplication of effort first.)
>> 
>
>Always a good idea!


I have a script "pkgsort" which sorts package on depenency order (can also
output lists of pkggrm and pkgadd commands)

So if you want to install a package from a DVD, it will allow you
to add it plus all its dependencies.



Casper


#!/bin/perl -w
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
# Sort packages in dependency order; packages are listed after
# the packages that depend on them.
#
# To add pkagages from a CD, use:
# `pkgsort -d /...../Solaris_XX/Product -a -D -c pkg .....`
#
# options
#       -c      output pkgadd/pkgrm command
#       -r      removal order
#       -a      add order
#       -d dir  read dependencies from "dir"
#       -D      when removing, search all packages
#               for dependencies.
#       -i      skip package info check
#
use Getopt::Std;
use strict;
my(%opt, $dir, %dependents, %rdependents, %seen, %printed, @list, @output,
    $output);

getopts("icard:Dp:", \%opt) ||
        die "Usage: pkgsort [-acdir] [-D dir] [-p pkgcmdargs] pkg ....\n";

$dir = $opt{'d'} || "/var/sadm/pkg";

$opt{'c'} = 1 if (defined $opt{'p'});

@list = @ARGV;

if ($opt{'D'}) {
        my ($pkg, $pkgname, $p);
        opendir(PKGDIR, $dir);
        while (defined($pkg = readdir(PKGDIR))) {
                ($pkgname = $pkg) =~ s/\.d+$//;
                open(DEPEND, "<$dir/$pkg/install/depend") || next;
                while (<DEPEND>) {
                        if (/^P\s+(\S+)\s+/) {
                                $dependents{$1}{$pkg} = 1;
                                $rdependents{$pkg}{$1} = 1;
                        } elsif (/^R\s+(\S+)\s+/) {
                                $dependents{$pkg}{$1} = 1;
                                $rdependents{$1}{$pkg} = 1;
                        }
                }
                close(DEPEND);
        }
        closedir(PKGDIR);
        foreach $p (@ARGV) {
                add_deps($p);
        }
} else {
        my $p;
        foreach $p (@ARGV) {
                $seen{$p} = 1;
                open(DEPEND, "<$dir/$p/install/depend") || next;
                while (<DEPEND>) {
                        if (/^P\s+(\S+)\s+/) {
                                $dependents{$1}{$p} = 1;
                        }
                }
                close(DEPEND);
        }
}

if ($opt{'a'} && !$opt{'i'}) {
        open(PINFO, "/usr/bin/pkginfo|");
        while (<PINFO>) {
                /^\S+\s+(\S+)\s+/ || next;
                $printed{$1} = 1;
        }
        close(PINFO);
}

@output = ();
$output = 1;
while ($output)
{
        my ($p, $d);
        $output = 0;
        LIST:
        foreach $p (@list)
        {
                next if (defined $printed{$p});
                #
                # If a package has dependents these need to be removed
                # first/added later.
                #
                if (defined $dependents{$p}) {
                        foreach $d (keys (%{$dependents{$p}})) {
                                next LIST
                                    if (!defined $printed{$d} &&
                                        defined($seen{$d}));
                        }
                }
                if (!$opt{'r'} || $opt{'a'}) {
                        unshift(@output, $p);
                } else {
                        push(@output, $p);
                }
                $printed{$p} = 1;
                $output = 1;
        }
}

if ($opt{'c'} && $#output >= 0) {
        if ($opt{'p'}) {
                unshift(@output, $opt{'p'});
        }
        if ($opt{'d'}) {
                unshift(@output, $dir);
                unshift(@output, "-d");
        }
        if (!$opt{'r'} || $opt{'a'}) {
                unshift(@output, "pkgadd");
        } else {
                unshift(@output, "pkgrm");
        }
}
print "@output\n" if ($#output >= 0);

sub add_deps {
        my($p) = @_;
        my $k;
        my (@add) =
            ($opt{'a'} ? keys %{$rdependents{$p}} : keys %{$dependents{$p}});

        foreach $k (@add) {
                next if (defined $seen{$k});
                $seen{$k} = 1;
                push(@list, $k);
                add_deps($k);
        }
}

Reply via email to