home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 May / Chip_2000-05_cd1.bin / zkuste / Perl / ActivePerl-5.6.0.613.msi / 䆊䌷䈹䈙䏵-䞅䞆䞀㡆䞃䄦䠥 / _2e08e91ae40309307e82fe672e2447cd < prev    next >
Text File  |  2000-03-24  |  55KB  |  1,521 lines

  1. @rem = '--*-Perl-*--
  2. @echo off
  3. if "%OS%" == "Windows_NT" goto WinNT
  4. perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
  5. goto endofperl
  6. :WinNT
  7. perl -x -S "%0" %*
  8. if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl
  9. if %errorlevel% == 9009 echo You do not have Perl in your PATH.
  10. if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
  11. goto endofperl
  12. @rem ';
  13. #!/usr/bin/perl
  14. #line 15
  15.  
  16. use Getopt::Long;
  17. use File::Basename;
  18. use Config;
  19. use strict;
  20.  
  21. use PPM;
  22.  
  23. $PPM::VERSION = "1.1.3";
  24.  
  25. my $usage = <<'EOT';
  26.     usage: ppm genconfig
  27.            ppm help [command]
  28.            ppm install [--location=location] package1 [... packageN]
  29.            ppm query [--case|nocase] [--searchtag=abstract|author|title] PATTERN
  30.            ppm remove package1 [... packageN]
  31.            ppm search [--case|nocase] [--location=location] [--searchtag=abstract|author|title] PATTERN
  32.            ppm set [option]
  33.            ppm verify [--location=location] [--upgrade] [--force] [package1 ... packageN]
  34.            ppm version
  35.            ppm [--location=location]
  36.  
  37. EOT
  38.  
  39. my %help;
  40.  
  41. $help{'set'} = <<'EOT';
  42.     set
  43.         - Displays current settings.
  44.     set build DIRECTORY
  45.         - Changes the package build directory.
  46.     set case [Yes|No]
  47.         - Set case-sensitive searches.
  48.     set clean [Yes|No]
  49.         - Set removal of temporary files from package's build area
  50.           following successful installation.
  51.     set confirm [Yes|No]
  52.         - Sets confirmation of 'install', 'remove' and 'upgrade'.
  53.     set force_install [Yes|No]
  54.         - Continue installing a package if a dependency cannot be installed.
  55.     set more NUMBER
  56.         - Pause after displaying 'NUMBER' lines.  Specifying '0' turns
  57.           off paging capability.
  58.     set repository /remove NAME
  59.         - Removes the repository 'NAME' from the list of repositories.
  60.     set repository NAME LOCATION
  61.         - Adds a repository to the list of PPD repositories for this session.
  62.           'NAME' is the name by which this repository will be referred;
  63.           'LOCATION' is a URL or directory name.
  64.     set root DIRECTORY
  65.         - Changes install root directory for this session.
  66.     set save
  67.         - Save current options as defaults.
  68.     set trace
  69.         - Tracing level--default is 1, maximum is 4, 0 indicates
  70.           no tracing.
  71.     set tracefile
  72.         - File to contain tracing information, default is 'PPM.LOG'.
  73.     set verbose [Yes|No]
  74.         - Display additional package information for 'query' and
  75.           'search' commands.
  76. EOT
  77.  
  78. # Need to do this here, because the user's config file is probably
  79. # hosed.
  80. if ($#ARGV == 0 && $ARGV[0] eq 'genconfig') {
  81.     &genconfig;
  82.     exit 0;
  83. }
  84.  
  85. my %options = PPM::GetPPMOptions();
  86. use vars qw ($location $Ignorecase $clean $confirm $force_install $root $build_dir $more $trace $tracefile $verbose);
  87. *Ignorecase = \$options{'IGNORECASE'};
  88. *clean = \$options{'CLEAN'};
  89. *confirm = \$options{'CONFIRM'};
  90. *force_install = \$options{'FORCE_INSTALL'};
  91. *root = \$options{'ROOT'};
  92. *build_dir = \$options{'BUILDDIR'};
  93. *more = \$options{'MORE'};
  94. *trace = \$options{'TRACE'};
  95. *tracefile = \$options{'TRACEFILE'};
  96. *verbose = \$options{'VERBOSE'};
  97.  
  98. my $moremsg = "[Press return to continue]";
  99. my $interactive = 0;
  100.  
  101. $help{'help'} = <<'EOT';
  102. Commands:
  103.     exit              - leave the program.
  104.     help [command]    - prints this screen, or help on 'command'.
  105.     install PACKAGES  - installs specified PACKAGES.
  106.     quit              - leave the program.
  107.     query [options]   - query information about installed packages.
  108.     remove PACKAGES   - removes the specified PACKAGES from the system.
  109.     search [options]  - search information about available packages.
  110.     set [options]     - set/display current options.
  111.     verify [options]  - verifies current install is up to date.
  112.  
  113. EOT
  114.  
  115. $help{'search'} = <<'EOT';
  116.     search [PATTERN]
  117.     search /abstract [PATTERN]
  118.     search /author [PATTERN]
  119.     search /title [PATTERN]
  120.     search /location LOCATION [PATTERN]
  121.  
  122.     Searches for available packages.  With no arguments, will display
  123.     a list of all available packages. If a regular expression 'PATTERN'
  124.     is supplied, only packages matching the pattern will be displayed.
  125.     If the '/abstract', '/author' or '/title' argument is specified,
  126.     the respective field of the package will be searched.  If the
  127.     '/location' option is specified, matching packages from that
  128.     URL or directory will be listed.
  129.  
  130. EOT
  131.  
  132. $help{'install'} = <<'EOT';
  133.     install PACKAGE
  134.     install /location LOCATION PACKAGE
  135.  
  136.     Installs the specified 'PACKAGE' onto the system.  If the '/location'
  137.     option is specified, the package will be looked for at that URL
  138.     or directory.
  139.  
  140. EOT
  141.  
  142. $help{'remove'} = <<'EOT';
  143.     remove PACKAGE
  144.  
  145.     Removes the specified 'PACKAGE' from the system.
  146.  
  147. EOT
  148.  
  149. $help{'genconfig'} = <<'EOT';
  150.     genconfig
  151.  
  152.     This command will print a valid PPM config file (ppm.xml) to 
  153.     STDOUT.  This can be useful if the PPM config file ever gets 
  154.     damaged leaving PPM unusable.  If required, this command should 
  155.     be run from a shell prompt:
  156.  
  157.         C:\Perl\site\lib> ppm genconfig > ppm.xml
  158.  
  159. EOT
  160.  
  161. $help{'query'} = <<'EOT';
  162.     query [PATTERN]
  163.     query /abstract [PATTERN]
  164.     query /author [PATTERN]
  165.     query /title [PATTERN]
  166.  
  167.     Queries information about installed packages. With no arguments, will
  168.     display a list of all installed packages. If a regular expression
  169.     'PATTERN' is supplied, only packages matching the pattern will be
  170.     displayed.  If the '/abstract', '/author' or '/title' argument is
  171.     specified, the respective field of the package will be searched.
  172.  
  173. EOT
  174.  
  175. $help{'verify'} = <<'EOT';
  176.     verify [packages]
  177.     verify /upgrade [/force] [packages]
  178.     verify /location LOCATION [packages]
  179.  
  180.     Verifies that the currently installed 'packages' are up to date.
  181.     If 'packages' is not specified, all installed packages are verified.
  182.     If the '/upgrade' option is specified, any packages for which an
  183.     upgrade is available will be upgraded.  If the '/location' option
  184.     is specified, upgrades will be looked for at the specified URL
  185.     or directory.
  186.  
  187. EOT
  188.  
  189. my %repositories = PPM::ListOfRepositories();
  190.  
  191. if ($#ARGV == -1 || ($#ARGV == 0 && $ARGV[0] =~ /^--location/)) {
  192.     my $prompt = 'PPM> ';
  193.     $interactive = 1;
  194.     GetOptions("location=s" => \$location);
  195.  
  196.     print "PPM interactive shell ($PPM::VERSION) - type 'help' for available commands.\n";
  197.     $| = 1;
  198.     while () {
  199.         print $prompt;
  200.         last unless defined ($_ = <> );
  201.         chomp;
  202.         s/^\s+//;
  203.         my @line = split(/\s+/, $_);
  204.         my $cmd = shift @line;
  205.         next if /^$/;
  206.  
  207.         # exit/quit
  208.         if (command($cmd, "qu|it") or command($cmd, "|exit")) {
  209.             print "Quit!\n";
  210.             last;
  211.         }
  212.         # help
  213.         elsif (command($cmd, "|help")) {
  214.             if (defined $line[0] && $help{$line[0]}) {
  215.                 print $help{$line[0]};
  216.             }
  217.             else {
  218.                 print $help{'help'};
  219.             }
  220.         }
  221.         # query
  222.         elsif (command($cmd, "qu|ery")) {
  223.             my $package;
  224.             my %summary = InstalledPackageProperties();
  225.             if (defined $line[0]) {
  226.                 my $searchtag;
  227.                 if ($line[0] =~ /^\/(abstract|author|title)$/i) {
  228.                     $searchtag = uc $1;
  229.                     shift @line;
  230.                 }
  231.                 my $RE = shift @line;
  232.                 eval { $RE =~ /$RE/ };
  233.                 if ($@) {
  234.                     print "'$RE': invalid regular expression.\n";
  235.                     next;
  236.                 }
  237.                 $RE = "(?i)$RE" if $Ignorecase eq "Yes";
  238.                 foreach(keys %summary) {
  239.                     if (defined $searchtag) {
  240.                         delete $summary{$_} unless $summary{$_}{$searchtag} =~ /$RE/;
  241.                     }
  242.                     else {
  243.                         delete $summary{$_} unless /$RE/;
  244.                     }
  245.                 }
  246.             }
  247.             print_formatted(1, %summary);
  248.         }
  249.         # install
  250.         elsif (command($cmd, "in|stall")) {
  251.             my $package;
  252.             local $location = $location;
  253.             if (defined $line[0]) {
  254.                 if ($line[0] =~ /^\/location$/i) {
  255.                     shift @line;
  256.                     $location = shift @line;
  257.                 }
  258.             }
  259.             if (!@line) {
  260.                 print "Package not specified.\n";
  261.                 next;
  262.             }
  263.             foreach $package (@line) {
  264.                 $package =~ s/::/-/g;
  265.                 if ($confirm eq "Yes") {
  266.                     print "Install package \'$package?\' (y/N): ";
  267.                     next if (<> ne "y\n");
  268.                 }
  269.                 print "Retrieving package \'$package\'...\n";
  270.                 if(!InstallPackage("package" => $package, "location" => $location)) {
  271.                     print "Error installing package '$package': $PPM::PPMERR\n";
  272.                 }
  273.             }
  274.         }
  275.         # remove
  276.         elsif (command($cmd, "|remove")) {
  277.             my $package;
  278.             if (!@line) {
  279.                 print "Package not specified.\n";
  280.                 next;
  281.             }
  282.             foreach $package (@line) {
  283.                 if ($confirm eq "Yes") {
  284.                     print "Remove package \'$package?\' (y/N): ";
  285.                     next if (<> ne "y\n");
  286.                 }
  287.                 if (!RemovePackage("package" => $package)) {
  288.                     print "Error removing $package: $PPM::PPMERR\n";
  289.                 }
  290.             }
  291.         }
  292.         # search
  293.         elsif (command($cmd, "se|arch")) {
  294.             my ($package, %summary, $searchtag);
  295.             local $location = $location;
  296.             while (defined $line[0]) {
  297.                 if ($line[0] =~ /^\/(abstract|author|title)$/i) {
  298.                     $searchtag = uc $1;
  299.                     shift @line;
  300.                 }
  301.                 elsif ($line[0] =~ /^\/location$/i) {
  302.                     shift @line;
  303.                     $location = shift @line;
  304.                 }
  305.                 else { last; }
  306.             }
  307.             my $searchRE = $line[0];
  308.             %summary = search_PPDs("location" => $location, "searchtag" => $searchtag, 
  309.                         "searchRE" => $searchRE, "ignorecase" => $Ignorecase);
  310.             foreach (keys %summary) {
  311.                 print "Packages available from $_:\n";
  312.                 print_formatted(2, %{$summary{$_}});
  313.             }
  314.         }
  315.         # set
  316.         elsif (command($cmd, "se|t")) {
  317.             set(@line);
  318.         }
  319.         # verify
  320.         elsif (command($cmd, "|verify")) {
  321.             my $upgrade;
  322.         my $force;
  323.             local $location = $location;
  324.             while (defined $line[0]) {
  325.                 if ($line[0] =~ /^\/upgrade$/i) {
  326.                     $upgrade = 1;
  327.                     shift @line;
  328.                     next;
  329.                 }
  330.                 if ($line[0] =~ /^\/force$/i) {
  331.                     $force = 1;
  332.                     shift @line;
  333.                     next;
  334.                 }
  335.                 if ($line[0] =~ /^\/location$/i) {
  336.                     shift @line;
  337.                     $location = shift @line;
  338.                     next;
  339.                 }
  340.                 last;
  341.             }
  342.             if ($upgrade && $confirm eq "Yes") {
  343.                 print "Upgrade package" . ($#line == 0 ? " $line[0]" : "s") . "? (y/N): ";
  344.                 next if (<> ne "y\n");
  345.             }
  346.             verify_packages("packages" => \@line, "location" => $location, "upgrade" => $upgrade, "force" => $force);
  347.         }
  348.         else {
  349.             print "Unknown or ambiguous command '$cmd'; type 'help' for commands.\n";
  350.         }
  351.     }
  352. }
  353. elsif ($ARGV[0] eq 'help') {
  354. $help{'install'} = <<'EOT';
  355.     install [--location=location] PACKAGE
  356.  
  357.     Installs the specified 'PACKAGE' onto the system.  If 'location' is
  358.     not specified, the default locations in the PPM data file will be
  359.     used to locate the package.
  360.  
  361. EOT
  362.  
  363. $help{'search'} = <<'EOT';
  364.     search [--case|nocase] [--location=location] [PATTERN]
  365.     search [--case|nocase] [--location=location] --searchtag=abstract [PATTERN]
  366.     search [--case|nocase] [--location=location] --searchtag=author [PATTERN]
  367.     search [--case|nocase] [--location=location] --searchtag=title [PATTERN]
  368.  
  369.     Searches for available packages.  With no arguments, will display
  370.     a list of all available packages. If a regular expression 'PATTERN'
  371.     is supplied, only packages matching the pattern will be displayed.
  372.     If the 'abstract', 'author' or 'title' --searchtag argument is
  373.     specified, the respective field of the package will be searched.
  374.     If 'location' is not specified, the repository locations in the PPM
  375.     data file will be searched.  '--case' or '--nocase' may be used to
  376.     request case-sensitive or case-insensitive searches, respectively.
  377.  
  378. EOT
  379.  
  380. $help{'query'} = <<'EOT';
  381.     query [PATTERN]
  382.     query [--case|nocase] --searchtag=abstract [PATTERN]
  383.     query [--case|nocase] --searchtag=author [PATTERN]
  384.     query [--case|nocase] --searchtag=title [PATTERN]
  385.  
  386.     Queries information about installed packages. With no arguments, will
  387.     display a list of all installed packages. If a regular expression
  388.     'PATTERN' is supplied, only packages matching the pattern will
  389.     be displayed.  If the 'abstract', 'author' or 'title' --searchtag
  390.     argument is specified, the respective field of the package will
  391.     be searched.  '--case' or '--nocase' may be used to request
  392.     case-sensitive or case-insensitive searches, respectively.
  393.  
  394. EOT
  395.  
  396. $help{'verify'} = <<'EOT';
  397.     verify [--location=location] [packages]
  398.     verify --upgrade [--force] [--location=location] [packages]
  399.  
  400.     Verifies that the currently installed 'packages' are up to date.
  401.     If 'packages' is not specified, all installed packages are verified.
  402.     If the '--upgrade' option is specified, any packages for which
  403.     an upgrade is available will be upgraded.  If 'location' is not
  404.     specified, the repository locations in the PPM data file will be
  405.     searched. If the '--force' option is specified packages will be 
  406.     reinstalled regardless of whether they are out of date or not.
  407.  
  408. EOT
  409.  
  410.     shift;
  411.     if (defined $ARGV[0] && $help{$ARGV[0]}) {
  412.         print $help{$ARGV[0]};
  413.     }
  414.     else {
  415.         print $usage;
  416.     }
  417. }
  418. elsif ($ARGV[0] eq 'version') {
  419.     print $PPM::VERSION;
  420. }
  421. elsif ($ARGV[0] eq 'set') {
  422.     shift;
  423.     if (set(@ARGV) == 0) {
  424.         PPM::SetPPMOptions("options" => \%options, "save" => 1);
  425.     }
  426. }
  427. elsif ($ARGV[0] eq 'install') {
  428.     my ($package);
  429.  
  430.     shift;
  431.     GetOptions("location=s" => \$location);
  432.  
  433.     $package = shift;
  434.     if (!defined $package && -d "blib" && -f "Makefile") {
  435.         if(!InstallPackage("location" => $location)) {
  436.             print "Error installing blib: $PPM::PPMERR\n";
  437.         }
  438.     }
  439.     while ($package) {
  440.         $package =~ s/::/-/g;
  441.         if(!InstallPackage("package" => $package, "location" => $location)) {
  442.             print "Error installing package '$package': $PPM::PPMERR\n";
  443.         }
  444.         $package = shift;
  445.     }
  446. }
  447. elsif ($ARGV[0] eq 'remove') {
  448.     shift;
  449.  
  450.     my $package = shift;
  451.  
  452.     while ($package) {
  453.         if (!RemovePackage("package" => $package)) {
  454.             print "Error removing $package: $PPM::PPMERR\n";
  455.         }
  456.         $package = shift;
  457.     }
  458. }
  459. elsif ($ARGV[0] eq 'verify') {
  460.     my ($upgrade, $force, $package, @packages);
  461.  
  462.     shift;
  463.     GetOptions("force" => \$force, "location=s" => \$location, "upgrade" => \$upgrade);
  464.  
  465.     verify_packages("packages" => \@ARGV, "location" => $location, "upgrade" => $upgrade, "force" => $force);
  466. }
  467. elsif ($ARGV[0] eq 'query') {
  468.     my ($case, $nocase, $searchtag, $searchRE, $package);
  469.     shift;
  470.     GetOptions("nocase" => \$nocase, "case" => \$case,
  471.                 "searchtag=s" => \$searchtag );
  472.     $searchRE = shift;
  473.     eval { $searchRE =~ /$searchRE/ };
  474.     if ($@) {
  475.         print "'$searchRE': invalid regular expression.\n";
  476.         exit 1;
  477.     }
  478.     if (!defined $nocase) {
  479.         if (!defined $case) {
  480.             $nocase = $Ignorecase;  # use the default setting
  481.         }
  482.     }
  483.     if (defined $searchtag) {
  484.         if (!$searchtag =~ /^(abstract|author|title)$/i) {
  485.             print $usage;
  486.             exit 1;
  487.         }
  488.         $searchtag = uc $searchtag;
  489.     }
  490.     $searchRE = "(?i)$searchRE" if $nocase eq "Yes";
  491.     my %summary = InstalledPackageProperties();
  492.     foreach(keys %summary) {
  493.         if ($searchtag) {
  494.            delete $summary{$_} unless $summary{$_}{$searchtag} =~ /$searchRE/;
  495.         }
  496.         else {
  497.            delete $summary{$_} unless /$searchRE/;
  498.         }
  499.     }
  500.     print_formatted(1, %summary);
  501. }
  502. elsif ($ARGV[0] eq 'search') {
  503.     my ($case, $nocase, $searchtag, $searchRE, %summary);
  504.     shift;
  505.     GetOptions("nocase" => \$nocase, "case" => \$case,
  506.                 "location=s" => \$location, "searchtag=s" => \$searchtag );
  507.     $searchRE = shift;
  508.     eval { $searchRE =~ /$searchRE/ };
  509.     if ($@) {
  510.         print "'$searchRE': invalid regular expression.\n";
  511.         next;
  512.     }
  513.     if (defined $case) {
  514.         $nocase = "No";
  515.     }
  516.     elsif (defined $nocase) {
  517.         $nocase = "Yes";
  518.     }
  519.     else {
  520.         $nocase = $Ignorecase;
  521.     }
  522.     if (defined $searchtag) {
  523.         if ($searchtag !~ /^(abstract|author|title)$/i) {
  524.             print $usage;
  525.             exit 1;
  526.         }
  527.         $searchtag = uc $searchtag;
  528.     }
  529.     %summary = search_PPDs("location" => $location, "searchtag" => $searchtag, 
  530.                 "searchRE" => $searchRE, "ignorecase" => $nocase);
  531.     foreach (keys %summary) {
  532.         print "Packages available from $_:\n";
  533.         print_formatted(2, %{$summary{$_}});
  534.     }
  535. }
  536. else {
  537.     print $usage;
  538.     exit 1;
  539. }
  540.  
  541. exit 0;
  542.  
  543. sub more
  544. {
  545.     my ($lines) = shift @_;
  546.     if (++$$lines >= $more) {
  547.         print $moremsg;
  548.         $_ = <>;
  549.         $$lines = 1;
  550.     }
  551. }
  552.  
  553. # This nasty piece of business splits $pattern into a required prefix 
  554. # and a "match any of this substring" suffix.  E.g. "in|stall" will
  555. # match a $cmd of "ins", "inst", ..., "install".
  556. sub command
  557. {
  558.     my ($cmd, $pattern) = @_;
  559.     my @pattern = split(/\|/, $pattern);
  560.     my @optchars = split(//, $pattern[1]);
  561.     # build up a "foo(b|ba|bar)" string
  562.     $pattern = "$pattern[0](";
  563.     $pattern[1] = shift @optchars;
  564.     $pattern[1] .= "|$pattern[1]$_" foreach @optchars;
  565.     $pattern .= "$pattern[1])";
  566.     return ($cmd =~ /^${pattern}$/i);
  567. }
  568.  
  569. # This routine prints the output for query and search
  570. # in a nicely formatted way, if $verbose is set.
  571. sub print_formatted
  572. {
  573.     my ($lines, %summary) = @_;
  574.     my $package;
  575.  
  576.     if (!$verbose) {
  577.         foreach $package (sort keys %summary) {
  578.             print "$package\n";
  579.             &more(\$lines) if $more;
  580.         }
  581.         return;
  582.     }
  583.  
  584.     my ($maxname, $maxversion) = (0, 0);
  585.     # find the longest package name and version strings, so we can
  586.     # format them nicely
  587.     $maxname < length($_) and $maxname = length($_) for keys %summary;
  588.     foreach $package (keys %summary) {
  589.         $summary{$package}{'VERSION'} =~ s/(,0)*$//;
  590.         $summary{$package}{'VERSION'} =~ tr/,/./;
  591.         $maxversion = length $summary{$package}{'VERSION'} > $maxversion ? length $summary{$package}{'VERSION'} : $maxversion;
  592.     }
  593.     my $columns = $ENV{COLUMNS} ? $ENV{COLUMNS} : 80;
  594.     my $namefield = "@" . "<" x ($maxname - 1);
  595.     my $versionfield = "@" . "<" x ($maxversion - 1);
  596.     my $abstractfield = "^" . "<" x ($columns - (6 + $maxname + $maxversion));
  597.     my $abstractpad = " " x ($maxname + $maxversion + 3);
  598.  
  599.     foreach $package (sort keys %summary) {
  600.         # Avoid "Format STDOUT redefined..." warning in Perl 5.6
  601.         no warnings;
  602.  
  603.         eval "format STDOUT = \n"
  604.                    . "$namefield [$versionfield] $abstractfield\n"
  605.                    . '$package, $summary{$package}{VERSION}, $summary{$package}{ABSTRACT}'
  606.                    . "\n"
  607.                    . "$abstractpad $abstractfield~~\n"
  608.                    . '$summary{$package}{ABSTRACT}' 
  609.                    . "\n"
  610.                    . ".\n";
  611.  
  612.         my $diff = $-;
  613.         write;
  614.         $diff -= $-;
  615.         $lines += ($diff - 1) if $diff > 1;
  616.         &more(\$lines) if $more;
  617.     }
  618. }
  619.  
  620. sub set
  621. {
  622.     my ($option) = shift @_;
  623.     my $rc = 0;
  624.     if (defined $option) {
  625.         my ($value) = shift @_;
  626.         if (command($option, "r|epository")) {
  627.             if ($value =~ /\/remove/i) {
  628.                 $value = shift @_;
  629.                 while (@_) {
  630.                     $value .= " " . shift @_;
  631.                 }
  632.                 if (!defined $value) {
  633.                     print "Location not specified.\n";
  634.                     $rc = 1;
  635.                 }
  636.                 else {
  637.                     PPM::RemoveRepository("repository" => $value);
  638.                     %repositories = PPM::ListOfRepositories();
  639.                 }
  640.             }
  641.             else {
  642.                 my $location = shift @_;
  643.                 if (!defined $value || !defined $location) {
  644.                     print "Repository not specified.\n";
  645.                     $rc = 1;
  646.                 }
  647.                 else {
  648.                     PPM::AddRepository("repository" => $value,
  649.                                        "location" => $location);
  650.                     %repositories = PPM::ListOfRepositories();
  651.                 }
  652.             }
  653.         }
  654.         else {
  655.             if (command($option, "c|onfirm")) {
  656.                 if (defined $value) {
  657.                     if ($value =~ /^Yes$/) { $confirm = $value; }
  658.                     elsif ($value =~ /^No$/) { $confirm = $value; }
  659.                     else {
  660.                         print "Value must be 'Yes' or 'No'.\n";
  661.                         $rc = 1;
  662.                         return $rc;
  663.                     }
  664.                 }
  665.                 else { $confirm = $confirm eq "Yes" ? "No" : "Yes"; }
  666.                 print "Commands will " . ($confirm eq "Yes" ? "" : "not ") . "be confirmed.\n";
  667.             }
  668.             elsif (command($option, "|save")) {
  669.                 PPM::SetPPMOptions("options" => \%options, "save" => 1);
  670.                 return $rc;
  671.             }
  672.             elsif (command($option, "c|ase")) {
  673.                 if (defined $value) {
  674.                     # N.B. These are reversed.
  675.                     if ($value =~ /^Yes$/) { $Ignorecase = "No"; }
  676.                     elsif ($value =~ /^No$/) { $Ignorecase = "Yes"; }
  677.                     else {
  678.                         print "Value must be 'Yes' or 'No'.\n";
  679.                         $rc = 1;
  680.                         return $rc;
  681.                     }
  682.                 }
  683.                 else { $Ignorecase = $Ignorecase eq "Yes" ? "No" : "Yes"; }
  684.                 print "Case-" . ($Ignorecase eq "Yes" ? "in" : "") . "sensitive searches will be performed.\n";
  685.             }
  686.             elsif (command($option, "r|oot")) {
  687.                 my $old_root;
  688.                 if (!defined $value) {
  689.                     print "Directory not specified.\n";
  690.                     $rc = 1;
  691.                 }
  692.                 elsif(!($old_root = PPM::chroot("location" => $value))) {
  693.                     print "$PPM::PPMERR";
  694.                     $rc = 1;
  695.                 }
  696.                 else {
  697.                     $root = $value;
  698.                     print "Root is now $value [was $old_root].\n";
  699.                 }
  700.             }
  701.             elsif (command($option, "|build")) {
  702.                 if (!defined $value) {
  703.                     print "Directory not specified.\n";
  704.                     $rc = 1;
  705.                 }
  706.                 elsif (-d $value) {
  707.                     $build_dir = $value;
  708.                     print "Build directory is now $value.\n";
  709.                 }
  710.                 else {
  711.                     print "Directory '$value' does not exist.\n";
  712.                     $rc = 1;
  713.                 }
  714.             }
  715.             elsif (command($option, "|force_install")) {
  716.                 if (defined $value) {
  717.                     if ($value =~ /^Yes$/) { $force_install = $value; }
  718.                     elsif ($value =~ /^No$/) { $force_install = $value; }
  719.                     else {
  720.                         print "Value must be 'Yes' or 'No'.\n";
  721.                         $rc = 1;
  722.                         return $rc;
  723.                     }
  724.                 }
  725.                 else { $force_install = $force_install eq "Yes" ? "No" : "Yes"; }
  726.                 print "Package installations will " .
  727.                       ($force_install eq "Yes" ? "" : "not ") .
  728.                       "continue if a dependency cannot be installed.\n";
  729.             }
  730.             elsif (command($option, "c|lean")) {
  731.                 if (defined $value) {
  732.                     if ($value =~ /^Yes$/) { $clean = $value; }
  733.                     elsif ($value =~ /^No$/) { $clean = $value; }
  734.                     else {
  735.                         print "Value must be 'Yes' or 'No'.\n";
  736.                         $rc = 1;
  737.                         return $rc;
  738.                     }
  739.                 }
  740.                 else { $clean = $clean eq "Yes" ? "No" : "Yes"; }
  741.                 print "Temporary files will " . ($clean eq "Yes" ? "" : "not ") . "be deleted.\n";
  742.             }
  743.             elsif (command($option, "|more")) {
  744.                 if (defined $value && $value =~ /^\d+$/) {
  745.                     $more = $value;
  746.                 }
  747.                 else {
  748.                     print "Numeric value must be given.\n";
  749.                     $rc = 1;
  750.                     return $rc;
  751.                 }
  752.                 print "Screens will " . ($more > 0 ? "pause after $more lines.\n" : "not pause.\n");
  753.             }
  754.             elsif (command($option, "trace|file")) {
  755.                 if (!defined $value) {
  756.                     print "Filename not specified.\n";
  757.                     $rc = 1;
  758.                 }
  759.                 $tracefile = $value;
  760.                 print "Tracing info will be written to $tracefile.\n";
  761.             }
  762.             elsif (command($option, "trace")) {
  763.                 if (defined $value && $value =~ /^\d+$/ && $value >= 0 && $value <= 4) {
  764.                     $trace = $value;
  765.                 }
  766.                 else {
  767.                     print "Numeric value between 0 and 4 must be given.\n";
  768.                     $rc = 1;
  769.                     return $rc;
  770.                 }
  771.                 print "Tracing info will " . ($trace > 0 ? "be written to $tracefile.\n" : "not be written.\n");
  772.             }
  773.             elsif (command($option, "|verbose")) {
  774.                 if (defined $value) {
  775.                     if ($value =~ /^(Yes|1)$/i) { $verbose = 1; }
  776.                     elsif ($value =~ /^(No|0)$/i) { $verbose = 0; }
  777.                     else {
  778.                         print "Invalid setting: must be 'Yes/No' or '1/0'.\n";
  779.                         $rc = 1;
  780.                         return $rc;
  781.                     }
  782.                 }
  783.                 else { $verbose = $verbose eq "1" ? "0" : "1"; }
  784.                 print "Query/search results will " . ($verbose ? "" : "not ") . "be verbose.\n";
  785.             }
  786.             else {
  787.                 print "Unknown or ambiguous option '$option'; see 'help set' for available options.\n";
  788.                 $rc = 1;
  789.             }
  790.             if (!$rc) {
  791.                 PPM::SetPPMOptions("options" => \%options);
  792.             }
  793.         }
  794.     }
  795.     else {
  796.         print "Commands will " . ($confirm eq "Yes" ? "" : "not ") . "be confirmed.\n";
  797.         print "Temporary files will " . ($clean eq "Yes" ? "" : "not ") . "be deleted.\n";
  798.         print "Case-" . ($Ignorecase eq "Yes" ? "in" : "") . "sensitive searches will be performed.\n";
  799.         print "Package installations will " . ($force_install eq "Yes" ? "" : "not ") . "continue if a dependency cannot be installed.\n";
  800.         print "Tracing info will " . (($trace && $trace > 0 )? "be written to '$tracefile'.\n" : "not be written.\n");
  801.         print "Screens will " . ($more > 0 ? "pause after $more lines.\n" : "not pause.\n");
  802.         print "Query/search results will " . ($verbose ? "" : "not ") . "be verbose.\n";
  803.         if (defined $location) { print "Current PPD repository: $location\n"; }
  804.         else {
  805.             print "Current PPD repository paths:\n";
  806.             my $location;
  807.             foreach $_ (keys %repositories) {
  808.                 print "\t$_: $repositories{$_}\n";
  809.             }
  810.         }
  811.         if (defined $root) { print "Packages will be installed under: $root\n"; }
  812.         if (defined $build_dir) { print "Packages will be built under: $build_dir\n"; }
  813.     }
  814.     return $rc;
  815. }
  816.  
  817. sub search_PPDs
  818. {
  819.     my (%argv) = @_;
  820.     my (%packages, $arg, $ignorecase, $searchtag, $searchRE);
  821.     local $location = $location;
  822.     foreach $arg (keys %argv) {
  823.         if ($arg eq 'location') { $location = $argv{$arg}; }
  824.         if ($arg eq 'searchtag') { $searchtag = $argv{$arg}; }
  825.         if ($arg eq 'ignorecase') { $ignorecase = $argv{$arg}; }
  826.         if ($arg eq 'searchRE' && defined $argv{$arg}) {
  827.             $searchRE = $argv{$arg};
  828.             eval { $searchRE =~ /$searchRE/ };
  829.             if ($@) {
  830.                 print "'$searchRE': invalid regular expression.\n";
  831.                 return;
  832.             }
  833.             $searchRE = "(?i)$searchRE" if $ignorecase eq "Yes";
  834.         }
  835.     }
  836.     if (!defined $ignorecase) {
  837.         $ignorecase = $Ignorecase;
  838.     }
  839.     my (%ppds, $loc, $package);
  840.     %ppds = PPM::RepositoryPackages("location" => $location);
  841.     foreach $loc (keys %ppds) {
  842.         next if $#{$ppds{$loc}} == -1;
  843.         # see if a summary file is available
  844.         my %summary = RepositorySummary("location" => $loc);
  845.         if (%summary) {
  846.             foreach $package (keys %{$summary{$loc}}) {
  847.                 next if (defined $searchtag && $summary{$loc}{$package}{$searchtag} !~ /$searchRE/);
  848.                 next if (!defined $searchtag && defined $searchRE && $package !~ /$searchRE/);
  849.                 $packages{$loc}{$package} = \%{$summary{$loc}{$package}};
  850.             }
  851.         }
  852.         else {
  853.             # No summary: oh my, nothing but 'Net
  854.             foreach $package (@{$ppds{$loc}}) {
  855.                 my %package_details = RepositoryPackageProperties("package" => $package, "location" => $loc);
  856.                 next unless %package_details;
  857.                 next if (defined $searchtag && $package_details{$searchtag} !~ /$searchRE/);
  858.                 next if (!defined $searchtag && defined $searchRE && $package !~ /$searchRE/);
  859.                 $packages{$loc}{$package} = \%package_details;
  860.             }
  861.         }
  862.     }
  863.     return %packages;
  864. }
  865.  
  866. sub verify_packages
  867. {
  868.     my (%argv) = @_;
  869.     my ($arg, @packages, $upgrade, $force);
  870.     local $location = $location;
  871.     foreach $arg (keys %argv) {
  872.         if ($arg eq 'packages') { @packages = @{$argv{$arg}}; }
  873.         if ($arg eq 'location') { $location = $argv{$arg}; }
  874.         if ($arg eq 'upgrade') { $upgrade = $argv{$arg}; }
  875.         if ($arg eq 'force') { $force = $argv{$arg}; }
  876.     }
  877.     my ($package);
  878.  
  879.     if (!defined $packages[0]) {
  880.         my ($i, %info);
  881.  
  882.         @packages = ();
  883.         %info = QueryInstalledPackages();
  884.         foreach $i (keys %info) {
  885.             push @packages, $i;
  886.         }
  887.     }
  888.  
  889.     $package = shift @packages;
  890.  
  891.     # for each specified package
  892.     while ($package) {
  893.         my $status = VerifyPackage("package" => $package, "location" => $location, "upgrade" => $upgrade, "force" => $force);
  894.         if (defined $status) {
  895.             if ($status eq "0") {
  896.                 print "Package \'$package\' is up to date.\n";
  897.             }
  898.             elsif ($upgrade) {
  899.                 print "Package $package upgraded to version $status\n";
  900.             }
  901.             else {
  902.                 print "An upgrade to package \'$package\' is available.\n";
  903.             }
  904.         }
  905.         else {
  906.             print "Error verifying $package: $PPM::PPMERR\n";
  907.         }
  908.         $package = shift @packages;
  909.     }
  910. }
  911.  
  912. sub genconfig
  913. {
  914. my $PerlDir = $Config{'prefix'};
  915. print <<"EOF";
  916. <PPMCONFIG>
  917.     <PPMVER>1,1,3,0</PPMVER>
  918.     <PLATFORM CPU="x86" OSVALUE="$Config{'osname'}" OSVERSION="0,0,0,0" />
  919.     <OPTIONS BUILDDIR="$ENV{'TEMP'}" CLEAN="Yes" CONFIRM="Yes" FORCEINSTALL="Yes" IGNORECASE="Yes" MORE="0" ROOT="$PerlDir" TRACE="0" TRACEFILE="PPM.LOG" VERBOSE="1" />
  920.     <REPOSITORY LOCATION="soap://www.activestate.com/cgibin/SOAP/ppmserver.plex?class=PPM::SOAPServer" NAME="ActiveState Package Repository" SUMMARYFILE="fetch_summary"/>
  921.     <PPMPRECIOUS>PPM;Archive-Tar;Compress-Zlib;libwww-perl;XML-Parser;XML-Element;MIME-Base64;HTML-Parser;libwin32</PPMPRECIOUS>
  922.  
  923. <PACKAGE NAME="PPM">
  924. <LOCATION>http://www.activestate.com/packages</LOCATION>
  925. <INSTPACKLIST>$PerlDir/lib/auto/PPM/.packlist</INSTPACKLIST>
  926. <INSTROOT>$PerlDir</INSTROOT>
  927. <INSTDATE>Fri Oct  2 16:14:32 1998</INSTDATE>
  928. <INSTPPD>
  929. <SOFTPKG NAME="PPM" VERSION="1,1,3,0">
  930. <TITLE>PPM</TITLE>
  931. <ABSTRACT>Perl Package Manager: locate, install, upgrade software packages.</ABSTRACT>
  932. <AUTHOR>Murray Nesbitt <murray\@ActiveState.co></AUTHOR>
  933. <IMPLEMENTATION>
  934. <DEPENDENCY NAME="Compress-Zlib" VERSION="" />
  935. <DEPENDENCY NAME="libwww-perl" VERSION="" />
  936. <DEPENDENCY NAME="Archive-Tar" VERSION="" />
  937. <DEPENDENCY NAME="MIME-Base64" VERSION="" />
  938. <DEPENDENCY NAME="XML-Parser" VERSION="" />
  939. <DEPENDENCY NAME="XML-Element" VERSION="" />
  940. <CODEBASE HREF="x86/PPM.tar.gz" />
  941. <INSTALL />
  942. <UNINSTALL />
  943. </IMPLEMENTATION>
  944. </SOFTPKG>
  945. </INSTPPD>
  946. </PACKAGE>
  947.  
  948. <PACKAGE NAME="Archive-Tar">
  949. <LOCATION>http://www.activestate.com/packages</LOCATION>
  950. <INSTPACKLIST>$PerlDir/site/lib/auto/Archive/Tar/.packlist</INSTPACKLIST>
  951. <INSTROOT>$PerlDir</INSTROOT>
  952. <INSTDATE>Fri Oct  2 16:14:37 1998</INSTDATE>
  953. <INSTPPD>
  954. <SOFTPKG NAME="Archive-Tar" VERSION="0,072,0,0">
  955. <TITLE>Archive-Tar</TITLE>
  956. <ABSTRACT>module for manipulation of tar archives.</ABSTRACT>
  957. <AUTHOR>Stephen Zander <gibreel\@pobox.com></AUTHOR>
  958. <IMPLEMENTATION>
  959. <CODEBASE HREF="x86/Archive-Tar.tar.gz" />
  960. <INSTALL />
  961. <UNINSTALL />
  962. </IMPLEMENTATION>
  963. </SOFTPKG>
  964. </INSTPPD>
  965. </PACKAGE>
  966.  
  967. <PACKAGE NAME="MIME-Base64">
  968. <LOCATION>http://www.ActiveState.com/packages</LOCATION>
  969. <INSTPACKLIST>$PerlDir/site/lib/auto/MIME/Base64/.packlist</INSTPACKLIST>
  970. <INSTROOT>$PerlDir</INSTROOT>
  971. <INSTDATE>Fri Nov 13 14:05:30 1998</INSTDATE>
  972. <INSTPPD>
  973. <SOFTPKG NAME="MIME-Base64" VERSION="2,11,0,0">
  974. <TITLE>MIME-Base64</TITLE>
  975. <ABSTRACT>Encoding and decoding of base64 strings</ABSTRACT>
  976. <AUTHOR>Gisle Aas <gisle\@aas.no></AUTHOR>
  977. <IMPLEMENTATION>
  978. <CODEBASE HREF="x86/MIME-Base64.tar.gz" />
  979. <INSTALL />
  980. <UNINSTALL />
  981. </IMPLEMENTATION>
  982. </SOFTPKG>
  983. </INSTPPD>
  984. </PACKAGE>
  985.  
  986. <PACKAGE NAME="URI">
  987. <LOCATION>http://www.activestate.com/packages</LOCATION>
  988. <INSTPACKLIST>$PerlDir/site/lib/auto/URI/.packlist</INSTPACKLIST>
  989. <INSTROOT>$PerlDir</INSTROOT>
  990. <INSTDATE>Fri Oct  2 16:15:15 1998</INSTDATE>
  991. <INSTPPD>
  992. <SOFTPKG NAME="URI" VERSION="1,04,0,0">
  993. <TITLE>URI</TITLE>
  994. <ABSTRACT>Uniform Resource Identifiers (absolute and relative)</ABSTRACT>
  995. <AUTHOR>Gisle Aas <gisle\@aas.no></AUTHOR>
  996. <IMPLEMENTATION>
  997. <DEPENDENCY NAME="MIME-Base64" VERSION="" />
  998. <CODEBASE HREF="x86/URI.tar.gz" />
  999. <INSTALL />
  1000. <UNINSTALL />
  1001. </IMPLEMENTATION>
  1002. </SOFTPKG>
  1003. </INSTPPD>
  1004. </PACKAGE>
  1005.  
  1006. <PACKAGE NAME="HTML-Parser">
  1007. <LOCATION>http://www.activestate.com/packages</LOCATION>
  1008. <INSTPACKLIST>$PerlDir/site/lib/auto/HTML/Parser/.packlist</INSTPACKLIST>
  1009. <INSTROOT>$PerlDir</INSTROOT>
  1010. <INSTDATE>Fri Oct  2 16:15:15 1998</INSTDATE>
  1011. <INSTPPD>
  1012. <SOFTPKG NAME="HTML-Parser" VERSION="2,23,0,0">
  1013. <TITLE>HTML-Parser</TITLE>
  1014. <ABSTRACT>SGML parser class</ABSTRACT>
  1015. <AUTHOR>Gisle Aas <gisle\@aas.no></AUTHOR>
  1016. <IMPLEMENTATION>
  1017. <CODEBASE HREF="x86/HTML-Parser.tar.gz" />
  1018. <INSTALL />
  1019. <UNINSTALL />
  1020. </IMPLEMENTATION>
  1021. </SOFTPKG>
  1022. </INSTPPD>
  1023. </PACKAGE>
  1024.  
  1025. <PACKAGE NAME="libwww-perl">
  1026. <LOCATION>http://www.activestate.com/packages</LOCATION>
  1027. <INSTPACKLIST>$PerlDir/site/lib/auto/LWP/.packlist</INSTPACKLIST>
  1028. <INSTROOT>$PerlDir</INSTROOT>
  1029. <INSTDATE>Fri Oct  2 16:15:15 1998</INSTDATE>
  1030. <INSTPPD>
  1031. <SOFTPKG NAME="libwww-perl" VERSION="5,45,0,0">
  1032. <TITLE>libwww-perl</TITLE>
  1033. <ABSTRACT>Library for WWW access in Perl</ABSTRACT>
  1034. <AUTHOR>Gisle Aas  <gisle\@aas.no></AUTHOR>
  1035. <IMPLEMENTATION>
  1036. <DEPENDENCY NAME="URI" VERSION="" />
  1037. <DEPENDENCY NAME="HTML-Parser" VERSION="" />
  1038. <CODEBASE HREF="x86/libwww-perl.tar.gz" />
  1039. <INSTALL />
  1040. <UNINSTALL />
  1041. </IMPLEMENTATION>
  1042. </SOFTPKG>
  1043. </INSTPPD>
  1044. </PACKAGE>
  1045.  
  1046. <PACKAGE NAME="XML-Element">
  1047. <LOCATION>http://www.activestate.com/packages</LOCATION>
  1048. <INSTPACKLIST>$PerlDir/site/lib/auto/XML/Element/.packlist</INSTPACKLIST>
  1049. <INSTROOT>$PerlDir</INSTROOT>
  1050. <INSTDATE>Fri Oct  2 16:16:03 1998</INSTDATE>
  1051. <INSTPPD>
  1052. <SOFTPKG NAME="XML-Element" VERSION="0,10,0,0">
  1053. <TITLE>XML-Element</TITLE>
  1054. <ABSTRACT>Base element class for XML elements</ABSTRACT>
  1055. <AUTHOR>ActiveState Tool Corporation</AUTHOR>
  1056. <IMPLEMENTATION>
  1057. <DEPENDENCY NAME="XML-Parser" VERSION="" />
  1058. <CODEBASE HREF="x86/XML-Element.tar.gz" />
  1059. <INSTALL />
  1060. <UNINSTALL />
  1061. </IMPLEMENTATION>
  1062. </SOFTPKG>
  1063. </INSTPPD>
  1064. </PACKAGE>
  1065.  
  1066. <PACKAGE NAME="XML-Parser">
  1067. <LOCATION>http://www.activestate.com/packages</LOCATION>
  1068. <INSTPACKLIST>$PerlDir/site/lib/auto/XML/Parser/.packlist</INSTPACKLIST>
  1069. <INSTROOT>$PerlDir</INSTROOT>
  1070. <INSTDATE>Fri Oct  2 16:16:03 1998</INSTDATE>
  1071. <INSTPPD>
  1072. <SOFTPKG NAME="XML-Parser" VERSION="2,27,0,0">
  1073. <TITLE>XML-Parser</TITLE>
  1074. <ABSTRACT>A Perl module for parsing XML documents</ABSTRACT>
  1075. <AUTHOR>Clark Cooper <coopercl\@sch.ge.com></AUTHOR>
  1076. <IMPLEMENTATION>
  1077. <CODEBASE HREF="x86/XML-Parser.tar.gz" />
  1078. <INSTALL />
  1079. <UNINSTALL />
  1080. </IMPLEMENTATION>
  1081. </SOFTPKG>
  1082. </INSTPPD>
  1083. </PACKAGE>
  1084.  
  1085. <PACKAGE NAME="Compress-Zlib">
  1086. <LOCATION>http://www.activestate.com/packages</LOCATION>
  1087. <INSTPACKLIST>$PerlDir/site/lib/auto/Compress/Zlib/.packlist</INSTPACKLIST>
  1088. <INSTROOT>$PerlDir</INSTROOT>
  1089. <INSTDATE>Fri Oct  2 16:16:03 1998</INSTDATE>
  1090. <INSTPPD>
  1091. <SOFTPKG NAME="Compress-Zlib" VERSION="1,03,0,0">
  1092. <TITLE>Compress-Zlib</TITLE>
  1093. <ABSTRACT>Interface to zlib compression library</ABSTRACT>
  1094. <AUTHOR>Paul Marquess <pmarquess\@bfsec.bt.co.uk></AUTHOR>
  1095. <IMPLEMENTATION>
  1096. <CODEBASE HREF="x86/Compress-Zlib.tar.gz" />
  1097. <INSTALL />
  1098. <UNINSTALL />
  1099. </IMPLEMENTATION>
  1100. </SOFTPKG>
  1101. </INSTPPD>
  1102. </PACKAGE>
  1103.  
  1104. <PACKAGE NAME="libwin32">
  1105. <LOCATION>http://www.activestate.com/packages</LOCATION>
  1106. <INSTPACKLIST>$PerlDir/site/lib/auto/Win32/.packlist</INSTPACKLIST>
  1107. <INSTROOT>$PerlDir</INSTROOT>
  1108. <INSTDATE>Fri Oct  2 16:16:03 1998</INSTDATE>
  1109. <INSTPPD>
  1110. <SOFTPKG NAME="libwin32" VERSION="0,15,1,0">
  1111. <TITLE>libwin32</TITLE>
  1112. <ABSTRACT>Win32-only extensions that provides a quick migration path for people wanting to use the core support for win32 in perl 5.004 and later.</ABSTRACT>
  1113. <AUTHOR>Gurusamy Sarathy <gsar\@activestate.com></AUTHOR>
  1114. <IMPLEMENTATION>
  1115. <CODEBASE HREF="x86/libwin32.tar.gz" />
  1116. <INSTALL />
  1117. <UNINSTALL />
  1118. </IMPLEMENTATION>
  1119. </SOFTPKG>
  1120. </INSTPPD>
  1121. </PACKAGE>
  1122.  
  1123. </PPMCONFIG>
  1124. EOF
  1125. }
  1126.  
  1127. __END__
  1128.  
  1129. =head1 NAME
  1130.  
  1131. PPM - Perl Package Manager: locate, install, upgrade software packages.
  1132.  
  1133. =head1 SYNOPSIS
  1134.  
  1135.  ppm genconfig
  1136.  ppm help [command]
  1137.  ppm install [--location=location] package1 [... packageN]
  1138.  ppm query [--case|nocase] [--searchtag=abstract|author|title] PATTERN
  1139.  ppm remove package1 [... packageN]
  1140.  ppm search [--case|nocase] [--location=location] [--searchtag=abstract|author|title] PATTERN
  1141.  ppm set [option]
  1142.  ppm verify [--location=location] [--upgrade] [--force] [package1 ... packageN]
  1143.  ppm version
  1144.  ppm [--location=location]
  1145.  
  1146. =head1 DESCRIPTION
  1147.  
  1148. ppm is a utility intended to simplify the tasks of locating, installing,
  1149. upgrading and removing software packages.  It is a front-end to the
  1150. functionality provided in PPM.pm.  It can determine if the most recent
  1151. version of a software package is installed on a system, and can install
  1152. or upgrade that package from a local or remote host.
  1153.  
  1154. ppm runs in one of two modes: an interactive shell from which commands
  1155. may be entered; and command-line mode, in which one specific action is
  1156. performed per invocation of the program.
  1157.  
  1158. ppm uses files containing an extended form of the Open Software
  1159. Description (OSD) specification for information about software packages.
  1160. These description files, which are written in Extensible Markup
  1161. Language (XML) code, are referred to as 'PPD' files.  Information about
  1162. OSD can be found at the W3C web site (at the time of this writing,
  1163. http://www.w3.org/TR/NOTE-OSD.html).  The extensions to OSD used by ppm
  1164. are documented in PPM.ppd.
  1165.  
  1166. =head1 COMMAND-LINE MODE
  1167.  
  1168. =over 4
  1169.  
  1170. =item Installing
  1171.  
  1172. ppm install [--location=location] package1 [... packageN]
  1173.  
  1174. Reads information from the PPD file (See the 'Files' section
  1175. below) for the named software package and performs an
  1176. installation.  The 'package' arguments may be either package
  1177. names ('foo'), or pathnames (P:\PACKAGES\FOO.PPD) or URLs
  1178. (HTTP://www.ActiveState.com/packages/foo.ppd) to specific PPD files.
  1179.  
  1180. In the case where a package name is specified, and the '--location'
  1181. option is not used, the function will refer to repository locations stored
  1182. in the PPM data file (see 'Files' section below) to locate the PPD file
  1183. for the requested package.
  1184.  
  1185. =item Removing
  1186.  
  1187. ppm remove package1 [... packageN]
  1188.  
  1189. Reads information from the PPD file for the named software package and
  1190. removes the package from the system.
  1191.  
  1192. =item Verifying
  1193.  
  1194. ppm verify [--location=location] [--upgrade] [--force] [package1 ... packageN]
  1195.  
  1196. Reads a PPD file for the specified package and compares the currently
  1197. installed version of the package to the version available according to
  1198. the PPD.  The PPD file is expected to be on a local directory or remote
  1199. site specified either in the PPM data file or on the command
  1200. line using the '--location' option.  The --location' argument may be
  1201. a directory location or an Internet address.  The '--upgrade' option
  1202. forces an upgrade if the installed package is not up-to-date.
  1203.  
  1204. If no packages are specified, all packages currently installed on the
  1205. system will be verified (and updated if desired).  The PPD file for each
  1206. package will initially be searched for at the location specified with the
  1207. '--location' argument, and if not found will then be searched for using
  1208. the location specified in the PPM data file.
  1209.  
  1210. =item Querying
  1211.  
  1212. ppm query [--case|nocase] PATTERN
  1213.  
  1214. Reports currently installed packages matching 'PATTERN' or all installed
  1215. packages if no 'PATTERN' is specified.
  1216.  
  1217. ppm query [--case|nocase] [--searchtag=abstract|author|title] PATTERN
  1218.  
  1219. Searches for 'PATTERN' (a regular expression) in the <ABSTRACT>, <AUTHOR>
  1220. or <TITLE> tags of all installed packages, according to the value of
  1221. the '--searchtag' option.  If a '--searchtag' value of 'abstract',
  1222. 'author' or 'title' is not provided, any occurence of 'PATTERN' in the
  1223. package name will match successfully.  A case-sensitive search will be
  1224. conducted by default, but this may be overridden by the options set in
  1225. the PPM data file, which may in turn be overridden by the '--nocase' or
  1226. '--case' option.  If a search is successful, information about the 
  1227. matching package(s) is displayed.
  1228.  
  1229. =item Searching
  1230.  
  1231. ppm search [--case|nocase] [--location=location] PATTERN
  1232.  
  1233. Displays a list of all packages matching 'PATTERN', with package
  1234. description (PPD) files available at the specified location.  'location'
  1235. may be either a remote address or a directory path.  If a location is
  1236. not specified, the repository location as specified in the PPM data file
  1237. will be used.
  1238.  
  1239. ppm search [--case|nocase] [--location=location] [--searchtag=abstract|author|title] PATTERN
  1240.  
  1241. Searches for 'PATTERN' (a regular expression) in the <ABSTRACT>, <AUTHOR>
  1242. or <TITLE> tags of all PPD files at 'location', according to the value
  1243. of the '--searchtag' option.  If a '--searchtag' value of 'abstract',
  1244. 'author' or 'title' is not provided, any occurence of 'PATTERN' in
  1245. the package name will match successfully.  'location' may be either a
  1246. remote address or a directory path, and if it is not provided, repository
  1247. locations specified in the PPM data file will be used.  A case-sensitive
  1248. search will be conducted by default, but this may be overridden by the
  1249. options set in the PPM data file, which may in turn be overridden by the
  1250. '--nocase' or '--case' option.  If a search is successful, information 
  1251. about the matching package(s) is displayed.
  1252.  
  1253. =item Summarizing
  1254.  
  1255. =item Error Recovery
  1256.  
  1257. ppm genconfig
  1258.  
  1259. This command will print a valid PPM config file (ppm.xml) to STDOUT.  This 
  1260. can be useful if the PPM config file ever gets damaged leaving PPM
  1261. unusable.
  1262.  
  1263. =back
  1264.  
  1265. =head1 INTERACTIVE MODE
  1266.  
  1267. If ppm is invoked with no command specified, it is started in interactive
  1268. mode.  If the '--location' argument is specified, it is used as the
  1269. search location, otherwise the repositories specified in the PPM data file are 
  1270. used. The available commands, which may be displayed at any time by entering
  1271. 'help', are:
  1272.  
  1273.     exit
  1274.         - Exits the program.
  1275.  
  1276.     help [command]
  1277.         - Prints a screen of available commands, or help on a specific command.
  1278.  
  1279.     install [/location LOCATION] PACKAGES
  1280.         - Installs the specified software PACKAGES.  Attempts to install
  1281.           from the URL or directory 'LOCATION' if the '/location' option
  1282.           is specfied.  See 'Installing' in the 'Command-line mode' 
  1283.           section for details.  See also: 'confirm' option.
  1284.  
  1285.     query [options] PATTERN
  1286.         - Queries information about currently installed packages.
  1287.  
  1288.         Available options:
  1289.         /abstract PATTERN
  1290.             - Searches for the regular expression 'PATTERN' in the 'abstract' section
  1291.               of all installed packages.  See also: 'case' option.
  1292.         /author PATTERN
  1293.             - Searches for the regular expression 'PATTERN' in the 'author' section
  1294.               of all installed packages.  See also: 'case' option.
  1295.         /title PATTERN
  1296.             - Searches for the regular expression 'PATTERN' in the 'title' section
  1297.               of all installed packages.  See also: 'case' option.
  1298.  
  1299.     remove PACKAGES
  1300.         - Removes the specified 'PACKAGES'.  See 'Removing' in the 'Command-line 
  1301.           mode' section for details.  See also: 'confirm' option.
  1302.  
  1303.     search [options] PATTERN
  1304.         - Searches for information about available packages.
  1305.  
  1306.         Available options:
  1307.         /abstract PATTERN
  1308.             - Searches for the regular expression 'PATTERN' in the 'abstract' section
  1309.               of all available PPD files.  See also: 'case' option.
  1310.         /author PATTERN
  1311.             - Searches for the regular expression 'PATTERN' in the 'author' section
  1312.               of all available PPD files.  See also: 'case' option.
  1313.         /title PATTERN
  1314.             - Searches for the regular expression 'PATTERN' in the 'title' section
  1315.               of all available PPD files.  See also: 'case' option.
  1316.         /location LOCATION
  1317.             - Searches for packages available from the URL or directory
  1318.               'LOCATION'.
  1319.  
  1320.     set [option value]
  1321.         - Sets or displays current options.  With no arguments, options are
  1322.           displayed.
  1323.  
  1324.           Available options:
  1325.               build DIRECTORY
  1326.                   - Changes the package build directory.
  1327.               case [Yes|No]
  1328.                   - Sets case-sensitive searches.  If one of 'Yes' or 'No is
  1329.                     not specified, the current setting is toggled.
  1330.               clean [Yes|No]
  1331.                   - Sets removal of temporary files from package's build 
  1332.                     area, on successful installation of a package.  If one of
  1333.                     'Yes' or 'No is not specified, the current setting is
  1334.                     toggled.
  1335.               confirm [Yes|No]
  1336.                   - Sets confirmation of 'install', 'remove' and 'upgrade'.
  1337.                     If one of 'Yes' or 'No is not specified, the current
  1338.                     setting is toggled.
  1339.               force_install [Yes|No]
  1340.                   - Continue installing a package even if a dependency cannot
  1341.                     be installed.
  1342.               more NUMBER
  1343.                   - Causes output to pause after NUMBER lines have been
  1344.                     displayed.  Specifying '0' turns off this capability.
  1345.               set repository /remove NAME
  1346.                   - Removes the repository 'NAME' from the list of repositories.
  1347.               set repository NAME LOCATION
  1348.                   - Adds a repository to the list of PPD repositories for this
  1349.                     session.  'NAME' is the name by which this repository will
  1350.                     be referred; 'LOCATION' is a URL or directory name.
  1351.               root DIRECTORY
  1352.                   - Changes the install root directory.  Packages will be
  1353.                     installed under this new root.
  1354.               save
  1355.                   - Saves the current options as default options for future
  1356.                     sessions.
  1357.               trace
  1358.                   - Tracing level--default is 1, maximum is 4, 0 indicates
  1359.                     no tracing.
  1360.               tracefile
  1361.                   - File to contain tracing information, default is 'PPM.LOG'.
  1362.               verbose [Yes|No]
  1363.                   - Display additional package information for 'query' and
  1364.                     'search' commands.
  1365.  
  1366.     quit
  1367.         - Exits the program.
  1368.  
  1369.     verify [/upgrade] [/force] [/location LOCATION] PACKAGE
  1370.         - Verifies that currently installed 'PACKAGE' is up to date.  If
  1371.           'PACKAGE' is not specified, all installed packages are verified.  If
  1372.           the /upgrade option is specified, any out-dated packages will be
  1373.           upgraded.  If the /location option is specified, upgrades will
  1374.           be looked for at the URL or directory 'LOCATION'.  See also: 'confirm'
  1375.           option.
  1376.  
  1377. =over 4
  1378.  
  1379. =back
  1380.  
  1381. =head1 EXAMPLES
  1382.  
  1383. =over 4
  1384.  
  1385. =item ppm
  1386.  
  1387. Starts ppm in interactive mode, using the repository locations specified
  1388. in the PPM data file.  A session might look like this:
  1389.  
  1390.     [show all available packages]
  1391.     PPM> search
  1392.     Packages available from P:\PACKAGES:
  1393.     bar [2.91 ] supplies bar methods for perl5.
  1394.     bax [0.072] module for manipulation of bax archives.
  1395.     baz [1.03 ] Interface to baz library
  1396.     foo [2.23 ] Foo parser class
  1397.     
  1398.     [list what has already been installed]
  1399.     PPM> query
  1400.     bax [0.071] module for manipulation of bax archives.
  1401.     baz [1.02 ] Interface to baz library
  1402.     
  1403.     [install a package]
  1404.     PPM> install foo
  1405.     Install package foo? (y/N): y
  1406.     [...]
  1407.     
  1408.     [toggle confirmations]
  1409.     PPM> set confirm
  1410.     Commands will not be confirmed.
  1411.     
  1412.     [see if 'baz' is up-to-date]
  1413.     PPM> verify baz
  1414.     An upgrade to package 'baz' is available.
  1415.     
  1416.     [upgrade 'baz']
  1417.     PPM> verify /upgrade baz
  1418.     [...]
  1419.     
  1420.     [forced upgrade of 'baz']
  1421.     PPM> verify /upgrade /force baz
  1422.     [...]
  1423.     
  1424.     [toggle case-sensitive searches]
  1425.     PPM> set case
  1426.     Case-sensitive searches will be performed.
  1427.     
  1428.     [display all available packages beginning with 'b']
  1429.     PPM> search ^b
  1430.     bar [2.91 ] supplies bar methods for perl5.
  1431.     bax [0.072] module for manipulation of bax archives.
  1432.     baz [1.03 ] Interface to baz library
  1433.     
  1434.     [search for installed packages containing 'baz' in the /ABSTRACT tag]
  1435.     PPM> query /abstract baz
  1436.     Matching packages found at P:\PACKAGES:
  1437.     baz [1.03 ] Interface to baz library
  1438.     PPM> quit
  1439.  
  1440. =item ppm install http://www.ActiveState.com/packages/foo.ppd
  1441.  
  1442. Installs the software package 'foo' based on the information in the PPD
  1443. obtained from the specified URL.
  1444.  
  1445. =item ppm verify --upgrade foo
  1446.  
  1447. Compares the currently installed version of the software package 'foo'
  1448. to the one available according to the PPD obtained from the location
  1449. specified for this package in the PPM data file, and upgrades
  1450. to a newer version if available.
  1451.  
  1452. =item ppm verify --location=P:\PACKAGES --upgrade foo
  1453.  
  1454. Compares the currently installed version of the software package 'foo'
  1455. to the one available according to the PPD obtained from the specified
  1456. directory, and upgrades to a newer version if available.
  1457.  
  1458. =item ppm verify --upgrade --force
  1459.  
  1460. Forces verification and reinstalls every installed package on the system, 
  1461. using upgrade locations specified in the PPM data file.
  1462.  
  1463. =item ppm search --location=http://www.ActiveState.com/packages
  1464.  
  1465. Displays the packages with PPD files available at the specified location.
  1466.  
  1467. =item ppm search --location=P:\PACKAGES --searchtag=author ActiveState
  1468.  
  1469. Searches the specified location for any package with an <AUTHOR> tag
  1470. containing the string 'ActiveState'.  On a successful search, the package
  1471. name and the matching string are displayed.
  1472.  
  1473. =back
  1474.  
  1475. =head1 ENVIRONMENT VARIABLES
  1476.  
  1477. =over 4
  1478.  
  1479. =item HTTP_proxy
  1480.  
  1481. If the environment variable 'HTTP_proxy' is set, then it will
  1482. be used as the address of a proxy server for accessing the Internet.
  1483.  
  1484. The value should be of the form: 'http://proxy:port'.
  1485.  
  1486. =back
  1487.  
  1488. =head1 FILES
  1489.  
  1490. These files are fully described in the 'Files' section of PPM:ppm.
  1491.  
  1492. =over 4
  1493.  
  1494. =item package.ppd
  1495.  
  1496. A description of a software package, in extended Open Software Description
  1497. (OSD) format.  More information on this file format can be found in
  1498. PPM::ppd.
  1499.  
  1500. =item ppm.xml - PPM data file.
  1501.  
  1502. This file is specified using the environment variable 'PPM_DAT';  if this
  1503. is not set, the file 'ppm.xml' is expected to be located in the same 
  1504. directory as this script.
  1505.  
  1506. An XML format file containing information about the local system,
  1507. specifics regarding the locations from which PPM obtains PPD files, and
  1508. the installation details for any package installed by ppm.
  1509.  
  1510. =back
  1511.  
  1512. =head1 AUTHOR
  1513.  
  1514. Murray Nesbitt, E<lt>F<murray@activestate.com>E<gt>
  1515.  
  1516. =cut
  1517.  
  1518.  
  1519. __END__
  1520. :endofperl
  1521.