summaryrefslogtreecommitdiff
path: root/src/prtget.cpp
blob: 4537c2689b8e0cfd7bb4a455fb3e3e5c675980f5 (plain)
    1 ////////////////////////////////////////////////////////////////////////
    2 // FILE:        prtget.cpp
    3 // AUTHOR:      Johannes Winkelmann, jw@tks6.net
    4 // COPYRIGHT:   (c) 2002 by Johannes Winkelmann
    5 // ---------------------------------------------------------------------
    6 //  This program is free software; you can redistribute it and/or modify
    7 //  it under the terms of the GNU General Public License as published by
    8 //  the Free Software Foundation; either version 2 of the License, or
    9 //  (at your option) any later version.
   10 ////////////////////////////////////////////////////////////////////////
   11 
   12 #ifdef HAVE_CONFIG_H
   13 #include <config.h>
   14 #endif
   15 
   16 #include <iostream>
   17 #include <algorithm>
   18 #include <set>
   19 #include <iomanip>
   20 #include <cstdio>
   21 #include <cassert>
   22 using namespace std;
   23 
   24 #include <sys/types.h>
   25 #include <sys/stat.h>
   26 #include <dirent.h>
   27 #include <unistd.h>
   28 
   29 #include "prtget.h"
   30 #include "repository.h"
   31 #include "argparser.h"
   32 #include "installtransaction.h"
   33 #include "configuration.h"
   34 
   35 #include "stringhelper.h"
   36 #include "versioncomparator.h"
   37 #include "file.h"
   38 #include "process.h"
   39 #include "datafileparser.h"
   40 using namespace StringHelper;
   41 
   42 
   43 using VersionComparator::COMP_RESULT;
   44 using VersionComparator::GREATER;
   45 using VersionComparator::LESS;
   46 using VersionComparator::EQUAL;
   47 using VersionComparator::UNDEFINED;
   48 
   49 const string PrtGet::CONF_FILE = SYSCONFDIR"/prt-get.conf";
   50 const string PrtGet::DEFAULT_CACHE_FILE = LOCALSTATEDIR"/lib/pkg/prt-get.cache";
   51 
   52 /*!
   53   Create a PrtGet object
   54   \param parser the argument parser to be used
   55 */
   56 PrtGet::PrtGet( const ArgParser* parser )
   57     : m_repo( 0 ),
   58       m_config( 0 ),
   59       m_parser( parser ),
   60       m_cacheFile( DEFAULT_CACHE_FILE ),
   61       m_returnValue( PG_OK ),
   62       m_currentTransaction( 0 )
   63 {
   64     if ( m_parser->wasCalledAsPrtCached() ) {
   65         m_appName = "prt-cache";
   66     } else {
   67         m_appName = "prt-get";
   68     }
   69 
   70 
   71     m_pkgDB = new PkgDB(m_parser->installRoot());
   72     readConfig();
   73 
   74     m_useRegex = m_config->useRegex() || m_parser->useRegex();
   75 }
   76 
   77 /*! destruct PrtGet object */
   78 PrtGet::~PrtGet()
   79 {
   80     if ( m_config ) {
   81         delete m_config;
   82     }
   83     if ( m_repo ) {
   84         delete m_repo;
   85     }
   86 
   87     delete m_pkgDB;
   88 }
   89 
   90 
   91 /*! print version and exit */
   92 void PrtGet::printVersion()
   93 {
   94     cout << m_appName << " " << VERSION
   95          << " by Johannes Winkelmann, jw@tks6.net" << endl;
   96 }
   97 
   98 /*! print version, usage and exit */
   99 void PrtGet::printUsage()
  100 {
  101     printVersion();
  102     cout << "Usage: " << m_appName << " <command> [options]" << endl;
  103 
  104     cout << "where commands are:" << endl;
  105 
  106     cout << "\nINFORMATION" << endl;
  107     cout << "  help                       show this help" << endl;
  108     cout << "  version                    show the current version" << endl;
  109     cout << "  list     [<filter>]        show a list of available ports"
  110          << endl;
  111     cout << "  printf   <format>          print formatted list of available"
  112          << " ports"
  113          << endl;
  114     cout << "  listinst [<filter>]        show a list of installed ports"
  115          << endl;
  116     cout << "  listorphans                list of ports with no "
  117          << "packages depending on them" << endl;
  118     cout << "  info     <port>            show info about a port" << endl;
  119     cout << "  path     <port>            show path of a port" << endl;
  120     cout << "  readme   <port>            show a port's readme file "
  121          << "(if it exists)" << endl;
  122     cout << "  dup                        Find duplicate ports" << endl;
  123     cout << "  isinst   <port1 port2...>  print whether ports are installed"
  124          << endl;
  125     cout << "  current  <port>            print installed version of port"
  126          << endl;
  127 
  128     cout << "\nDIFFERENCES / CHECK FOR UPDATES" << endl;
  129     cout << "  diff     <port1 port2...>  list outdated packages (or check "
  130          << "args for change)" << endl;
  131     cout << "  quickdiff                  same as diff but simple format"
  132          << endl;
  133     cout << "          where opt can be:" << endl;
  134     cout << "    --all            display locked ports too"
  135          << endl;
  136     cout << "    --prefer-higher  prefer higher installed "
  137          << "versions over lower ports"
  138          << endl;
  139     cout << "    --strict-diff    override prefer higher "
  140          << "configuration setting"
  141          << endl;
  142 
  143     cout << "\nDEPENDENCIES" << endl;
  144     cout << "  depends   <port1 port2...>  show dependencies for these ports"
  145          << endl;
  146     cout << "  quickdep  <port1 port2...>  same as 'depends' but simple format"
  147          << endl;
  148     cout << "  deptree   <port>            show dependencies tree for <port>"
  149          << endl;
  150     cout << "  dependent [opt] <port>      show installed packages which "
  151          << "depend on 'port'"
  152          << endl;
  153     cout << "          where opt can be:" << endl;
  154     cout << "                --all    list all dependent packages, not "
  155          << "only installed" << endl;
  156     cout << "                --recursive    print recursive listing" << endl;
  157     cout << "                --tree         print recursive tree listing"
  158          << endl;
  159 
  160     cout << "\nSEARCHING" << endl;
  161     cout << "  search  <expr>     show port names containing 'expr'" << endl;
  162     cout << "  dsearch <expr>     show ports containing 'expr' in the "
  163          << "name or description" << endl;
  164     cout << "  fsearch <pattern>  show file names in footprints matching "
  165          << "'pattern'" << endl;
  166 
  167     cout << "\nINSTALL, UPDATE and REMOVAL" << endl;
  168     cout << "  install [opt] <port1 port2...>    install ports" << endl;
  169     cout << "  update  [opt] <port1 port2...>    update ports" << endl;
  170     cout << "  grpinst [opt] <port1 port2...>    install ports, stop on error"
  171          << endl;
  172     cout << "  depinst [opt] <port1 port2...>    install ports and their dependencies"
  173          << endl;
  174     cout << "  remove [opt] <port1 port2...>     remove ports"
  175          << endl;
  176     cout << "          where opt can be:" << endl;
  177     cout << "                -f, -fi             force installation" << endl;
  178     cout << "                -fr                 force rebuild" << endl;
  179     cout << "                -uf                 update footprint" << endl;
  180     cout << "                -if                 ignore footprint" << endl;
  181     cout << "                -um                 update md5sum" << endl;
  182     cout << "                -im                 ignore md5sum" << endl;
  183     cout << "                --margs=<string>    pass 'string' to pkgmk"
  184          << endl;
  185     cout << "                --aargs=<string>    pass 'string' to pkgadd"
  186          << endl;
  187     cout << "                --rargs=<string>    pass 'string' to pkgrm"
  188          << endl;
  189     cout << "                --test              test mode" << endl;
  190     cout << "                --log               write log file"<< endl;
  191     cout << "                --ignore=<package1,package2,...>" << endl
  192          << "                                    Don't install/update those packages"<< endl;
  193     cout << "                --pre-install       execute pre-install script"
  194          << endl;
  195     cout << "                --post-install      execute post-install script"
  196          << endl;
  197     cout << "                --install-scripts   execute "
  198          << "pre-install and post-install script"
  199          << endl;
  200 
  201     cout << "\nSYSTEM UPDATE " << endl;
  202     cout << "  sysup [opt]                       update all outdated ports"
  203          << endl;
  204     cout << "          where opt can be:" << endl;
  205     cout << "                --nodeps            don't sort by dependencies"
  206          << endl;
  207     cout << "                --test              test mode" << endl;
  208     cout << "                --log               write log file"<< endl;
  209     cout << "                --prefer-higher     prefer higher installed "
  210          << "versions over lower ones in ports tree"
  211          << endl;
  212     cout << "                --strict-diff       override prefer higher "
  213          << "configuration setting"
  214          << endl;
  215 
  216     cout << "  lock <port1 port2...>             lock current version "
  217          << "of packages"
  218          << endl;
  219     cout << "  unlock <port1 port2...>           unlock packages"
  220          << endl;
  221     cout << "  listlocked                        list locked packages"
  222          << endl;
  223 
  224     cout << "\nFILE OPERATIONS " << endl;
  225 
  226     cout << "  ls <port>                         print a listing of the port's"
  227          << " directory" << endl;
  228     cout << "  cat <port> <file>                 print out 'port/file'"
  229          << endl;
  230     cout << "  edit <port> <file>                edit 'port/file'" << endl;
  231 
  232     cout << "\nGENERAL OPTIONS" << endl;
  233     cout << "                -v                 Show version in listing"
  234          << endl;
  235     cout << "                -vv                Show version and decription "          << "in listing\n" << endl;
  236     cout << "                --path             Print path to port if appropriate (search, list, depends)\n" << endl;
  237     cout << "                --cache             Use a cache file" << endl;
  238     cout << "                --config=<file>     Use alternative "
  239          << "configuration file" << endl;
  240     cout << "                --install-root=..   Use alternative "
  241          << "install root directory" << endl;
  242 
  243 
  244 
  245 
  246     cout << "                --no-std-config     Don't parse "
  247          << "default configuration file" << endl;
  248     cout << "                --config-prepend=.. Prepend '..' to"
  249          << " configuration" << endl;
  250     cout << "                --config-append=..  Append '..' "
  251          << "to configuration" << endl;
  252     cout << "                --config-set=..     Set configuration "
  253          << "data '..',\n"
  254          << "                                       overriding config file"
  255          << endl;
  256 
  257 }
  258 
  259 
  260 /*! print list of duplicate packages in the repository */
  261 void PrtGet::listShadowed()
  262 {
  263     if ( m_parser->useCache() ) {
  264         cout << m_appName << ": command 'dup' can't work on a cache" << endl;
  265         m_returnValue = PG_GENERAL_ERROR;
  266         return;
  267     }
  268 
  269     initRepo( true );
  270 
  271     string format = "%p1 %v1 > %p2 %v2\n";
  272     if (m_parser->otherArgs().size() > 0)
  273         format = *(m_parser->otherArgs().begin());
  274     else if (m_parser->verbose() > 0)
  275         format = "* %n\n  %p1 %v1 preceeds over \n  %p2 %v2\n";
  276 
  277     string output;
  278     Package* p1;
  279     Package* p2;
  280 
  281     list<pair<Package*, Package*> >::const_iterator it =
  282         m_repo->shadowedPackages().begin();
  283     for ( ; it != m_repo->shadowedPackages().end(); ++it ) {
  284         output = format;
  285         p1 = it->second;
  286         p2 = it->first;
  287 
  288         StringHelper::replaceAll(output, "%n",  p1->name());
  289         StringHelper::replaceAll(output, "%p1", p1->path() + "/" + p1->name());
  290         StringHelper::replaceAll(output, "%p2", p2->path() + "/" + p2->name());
  291         StringHelper::replaceAll(output, "%v1", p1->versionReleaseString());
  292         StringHelper::replaceAll(output, "%v2", p2->versionReleaseString());
  293 
  294         StringHelper::replaceAll(output, "\\n", "\n");
  295         cout << output;
  296     }
  297 }
  298 
  299 /*!
  300   find ports matching a pattern in repository
  301 
  302   \sa Repository::getMatchingPackages()
  303 */
  304 void PrtGet::listPackages()
  305 {
  306     string arg = "*";
  307     assertMaxArgCount(1);
  308 
  309     if ( m_parser->otherArgs().size() == 1 ) {
  310         arg = *(m_parser->otherArgs().begin());
  311     }
  312 
  313     initRepo();
  314     list<Package*> packages;
  315     m_repo->getMatchingPackages( arg, packages );
  316     if ( packages.size() ) {
  317         list<Package*>::iterator it = packages.begin();
  318         for ( ; it != packages.end(); ++it ) {
  319             if ( m_parser->printPath() ) {
  320                 cout << (*it)->path() << "/";
  321             }
  322             cout << (*it)->name();
  323             if ( m_parser->verbose() > 0 ) {
  324                 cout << " " << (*it)->version() << "-" << (*it)->release();
  325             }
  326             if ( m_parser->verbose() > 1 && !(*it)->description().empty() ) {
  327                 cout << ": " << (*it)->description();
  328             }
  329 
  330             cout << endl;
  331         }
  332     } else {
  333         cout << "No matching packages found"  << endl;
  334     }
  335 }
  336 
  337 /*!
  338   search repository for a certain pattern (which is read by the argument
  339   parser.
  340 
  341   \sa Repository::searchMatchingPackages()
  342 */
  343 void PrtGet::searchPackages( bool searchDesc )
  344 {
  345     assertExactArgCount(1);
  346 
  347     initRepo();
  348     string arg = *(m_parser->otherArgs().begin());
  349     list<Package*> packages;
  350     m_repo->searchMatchingPackages( arg, packages, searchDesc );
  351     if ( packages.size() ) {
  352         list<Package*>::iterator it = packages.begin();
  353         for ( ; it != packages.end(); ++it ) {
  354             if ( m_parser->printPath()) {
  355                 cout << (*it)->path() << "/";
  356             }
  357             cout << (*it)->name();
  358 
  359             if ( m_parser->verbose() > 0 ) {
  360                 cout << " " << (*it)->version() << "-" << (*it)->release();
  361             }
  362             if ( m_parser->verbose() > 1 && !(*it)->description().empty() ) {
  363                 cout << ": " << (*it)->description();
  364             }
  365 
  366 
  367             cout << endl;
  368         }
  369     } else {
  370         m_returnValue = PG_GENERAL_ERROR;
  371         cout << "No matching packages found"  << endl;
  372     }
  373 }
  374 
  375 /*! print info for a package */
  376 void PrtGet::printInfo()
  377 {
  378     assertExactArgCount(1);
  379 
  380     initRepo();
  381     string arg = *(m_parser->otherArgs().begin());
  382     const Package* p = m_repo->getPackage( arg );
  383     if ( p ) {
  384         cout << "Name:         " << p->name() << "\n"
  385              << "Path:         " << p->path() << "\n"
  386              << "Version:      " << p->version() << "\n"
  387              << "Release:      " << p->release() << endl;
  388 
  389         if ( !p->description().empty() ) {
  390             cout << "Description:  " << p->description() << endl;
  391         }
  392         if ( !p->url().empty() ) {
  393             cout << "URL:          " << p->url() << endl;
  394         }
  395         if ( !p->packager().empty() ) {
  396             cout << "Packager:     " << p->packager() << endl;
  397         }
  398         if ( !p->maintainer().empty() ) {
  399             cout << "Maintainer:   " << p->maintainer() << endl;
  400         }
  401 
  402         if ( !p->dependencies().empty() ) {
  403             cout << "Dependencies: " << p->dependencies() << endl;
  404         }
  405 
  406         // TODO: don't hardcode file names
  407         string filesString = "";
  408         if ( p->hasReadme() ) {
  409             filesString += "README ";
  410         }
  411         if ( p->hasPreInstall() ) {
  412             filesString += "pre-install ";
  413         }
  414         if ( p->hasPostInstall() ) {
  415             filesString += "post-install ";
  416         }
  417 
  418         if ( filesString.length() > 0 ) {
  419             filesString = StringHelper::stripWhiteSpace( filesString );
  420             StringHelper::replaceAll( filesString, " ", "," );
  421             cout << "Files:        " << filesString << endl;
  422         }
  423 
  424         if ( m_parser->verbose() > 0 && p->hasReadme()) {
  425             cout << "\n-- README ------" << endl;
  426             readme();
  427         }
  428 
  429     } else {
  430         cerr << "Package '" << arg << "' not found" << endl;
  431         m_returnValue = PG_GENERAL_ERROR;
  432         return;
  433     }
  434 }
  435 
  436 
  437 /*!
  438   initialize repository
  439   \sa Repository::initFromCache()
  440   \sa Repository::initFromFS()
  441  */
  442 void PrtGet::initRepo( bool listDuplicate )
  443 {
  444     if ( !m_repo ) {
  445         m_repo = new Repository(m_useRegex);
  446 
  447         if ( m_parser->useCache() ) {
  448             if (m_config->cacheFile() != "") {
  449                 m_cacheFile = m_config->cacheFile();
  450             }
  451 
  452             Repository::CacheReadResult result =
  453                 m_repo->initFromCache( m_cacheFile );
  454             if ( result == Repository::ACCESS_ERR  ) {
  455                 cerr << "Can't open cache file: " << m_cacheFile << endl;
  456                 m_returnValue = PG_GENERAL_ERROR;
  457                 return;
  458             } else if ( result == Repository::FORMAT_ERR ) {
  459                 cerr << "warning: your cache file "
  460                      << m_cacheFile << " was made with an "
  461                      << "older version "
  462                      << "of prt-get."
  463                      << "\nPlease regenerate it using"
  464                      << "\n  prt-get cache" << endl;
  465                 m_returnValue = PG_GENERAL_ERROR;
  466                 return;
  467             }
  468 
  469             struct stat cacheStat;
  470             struct stat confStat;
  471             stat( m_cacheFile.c_str(), &cacheStat );
  472             stat( CONF_FILE.c_str(), &confStat );
  473             if ( confStat.st_ctime > cacheStat.st_ctime ) {
  474                 cerr << "Error: "
  475                      << "Configuration changed after generating cache"
  476                      << endl;
  477                 cerr << "regenerate cache using 'prt-get cache'" << endl;
  478                 m_returnValue = PG_GENERAL_ERROR;
  479                 return;
  480             }
  481 
  482             if ( !m_parser->wasCalledAsPrtCached() ) {
  483                 cout << m_appName << ": using cache" << endl;
  484             }
  485 
  486         } else {
  487             m_repo->initFromFS( m_config->rootList(), listDuplicate );
  488         }
  489     }
  490 }
  491 
  492 /*! print whether a package is installed or not */
  493 void PrtGet::isInstalled()
  494 {
  495     assertMinArgCount(1);
  496 
  497     const list<char*>& l = m_parser->otherArgs();
  498     list<char*>::const_iterator it = l.begin();
  499     for ( ; it != l.end(); ++it ) {
  500         bool isAlias = false;
  501         string aliasName;
  502 
  503         if ( m_pkgDB->isInstalled( *it, true, &isAlias, &aliasName  ) ) {
  504             if (isAlias) {
  505                 cout << *it << " is provided by package "
  506                      << aliasName
  507                      << endl;
  508             } else {
  509                 cout << "package " << *it << " is installed" << endl;
  510             }
  511         } else {
  512             cout << "package " << *it << " is not installed" << endl;
  513             m_returnValue = PG_GENERAL_ERROR;
  514         }
  515     }
  516 }
  517 
  518 
  519 /*! list installed packages */
  520 void PrtGet::listInstalled()
  521 {
  522     assertMaxArgCount(1);
  523 
  524     string arg = "*";
  525     if ( m_parser->otherArgs().size() == 1 ) {
  526         arg = *(m_parser->otherArgs().begin());
  527     }
  528 
  529     map<string, string> l;
  530     m_pkgDB->getMatchingPackages( arg, l, m_useRegex );
  531     map<string, string>::iterator it = l.begin();
  532 
  533     if ( l.empty() && m_parser->otherArgs().size() > 0 ) {
  534         cerr << m_appName << ": No matching packages found" << endl;
  535         m_returnValue = PG_GENERAL_ERROR;
  536         return;
  537     }
  538 
  539     if ( m_parser->verbose() > 1 ) {
  540         // warning: will slow down the process...
  541         initRepo();
  542     }
  543 
  544     for ( ; it != l.end(); ++it ) {
  545         cout <<  it->first.c_str();
  546         if ( m_parser->verbose() > 0 ) {
  547             cout << " " << it->second.c_str();
  548         }
  549         if ( m_parser->verbose() > 1 ) {
  550             const Package* p = m_repo->getPackage( it->first );
  551             if ( p ) {
  552                 cout << " " << p->description();
  553             }
  554         }
  555 
  556         cout << endl;
  557     }
  558 }
  559 
  560 /*!
  561    install package
  562    \param update whether this is an update operation
  563    \param group whether it's a group install (stop on error)
  564 
  565 */
  566 void PrtGet::install( bool update, bool group, bool dependencies )
  567 {
  568     assertMinArgCount(1);
  569 
  570     // this can be done without initRepo()
  571     const list<char*>& args = m_parser->otherArgs();
  572     list<char*>::const_iterator it = args.begin();
  573 
  574     if ( args.size() == 1 ) {
  575         for ( ; it != args.end(); ++it ) {
  576             string s = *it;
  577             if ( !update && m_pkgDB->isInstalled( s ) ) {
  578                 cout << "package " << s << " is installed" << endl;
  579                 m_returnValue = PG_GENERAL_ERROR;
  580                 return;
  581             } else if ( update && !m_pkgDB->isInstalled( s ) ) {
  582                 // can't upgrade
  583                 cout << "package " << s << " is not installed" << endl;
  584                 m_returnValue = PG_GENERAL_ERROR;
  585                 return;
  586             }
  587         }
  588     }
  589 
  590     initRepo();
  591 
  592     if (dependencies) {
  593         // calc dependencies
  594         InstallTransaction depTransaction( m_parser->otherArgs(),
  595                                            m_repo, m_pkgDB, m_config );
  596         InstallTransaction::InstallResult result =
  597             depTransaction.calcDependencies();
  598 
  599         // TODO: code duplication with printDepends!
  600         if ( result == InstallTransaction::CYCLIC_DEPEND ) {
  601             cerr << "prt-get: cyclic dependencies found" << endl;
  602             m_returnValue = PG_GENERAL_ERROR;
  603             return;
  604         } else if ( result == InstallTransaction::PACKAGE_NOT_FOUND ) {
  605             warnPackageNotFound(depTransaction);
  606             m_returnValue = PG_GENERAL_ERROR;
  607             return;
  608         }
  609         const list<string>& depRef = depTransaction.dependencies();
  610         list<string>::const_iterator it = depRef.begin();
  611 
  612         list<string> deps;
  613         for (; it != depRef.end(); ++it) {
  614             if (!m_pkgDB->isInstalled(*it)) {
  615                 deps.push_back(*it);
  616             }
  617         }
  618 
  619         InstallTransaction transaction( deps, m_repo, m_pkgDB, m_config );
  620         executeTransaction( transaction, update, group );
  621     } else {
  622         InstallTransaction transaction( m_parser->otherArgs(),
  623                                         m_repo, m_pkgDB, m_config );
  624         executeTransaction( transaction, update, group );
  625     }
  626 }
  627 
  628 void PrtGet::executeTransaction( InstallTransaction& transaction,
  629                                  bool update, bool group )
  630 {
  631     m_currentTransaction = &transaction;
  632 
  633     string command[] = { "install", "installed" };
  634     if ( update ) {
  635         command[0] = "update";
  636         command[1] = "updated";
  637     }
  638 
  639     if ( m_parser->isTest() ) {
  640         cout << "*** " << m_appName << ": test mode" << endl;
  641     }
  642 
  643     InstallTransaction::InstallResult result =
  644         transaction.install( m_parser, update, group );
  645     bool failed = false;
  646     // TODO: use switch
  647     if ( result == InstallTransaction::PACKAGE_NOT_FOUND ) {
  648         cout << m_appName << ": package(s) not found" << endl;
  649     } else if ( result == InstallTransaction::PKGMK_EXEC_ERROR ) {
  650         cout << m_appName << " couldn't excecute pkgmk "
  651              << "(or alternative command). "
  652              << "Make sure it's installed properly" << endl;
  653     } else if ( result == InstallTransaction::PKGMK_FAILURE ) {
  654         cout << m_appName << ": error while " << command[0] << endl;
  655     } else if ( result == InstallTransaction::NO_PACKAGE_GIVEN ) {
  656         cout << m_appName << ": no package specified for "
  657              << command[0] << endl;
  658     } else if ( result == InstallTransaction::PKGADD_EXEC_ERROR ) {
  659         cout << m_appName << " couldn't excecute pkgadd. "
  660              << "Make sure it's installed properly" << endl;
  661     } else if ( result == InstallTransaction::PKGDEST_ERROR ) {
  662         cout << m_appName << ": error changing to directory PKGDEST " << endl;
  663         failed = true;
  664     } else if ( result == InstallTransaction::PKGADD_FAILURE ) {
  665         cout << m_appName << ": error while pkgadding " << endl;
  666     } else if ( result == InstallTransaction::LOG_DIR_FAILURE ) {
  667         cout << m_appName << ": can't create log file directory " << endl;
  668     } else if ( result == InstallTransaction::LOG_FILE_FAILURE ) {
  669         cout << m_appName << ": can't create log file" << endl;
  670         failed = true;
  671     } else if ( result == InstallTransaction::NO_LOG_FILE ) {
  672         cout << m_appName << ": no log file specified, but logging enabled"
  673              << endl;
  674         failed = true;
  675     } else if ( result == InstallTransaction::CANT_LOCK_LOG_FILE ) {
  676         cout << m_appName << ": can't create lock file for the log file. "
  677              << "\nMaybe there's another instance of prt-get using the same "
  678              << "file."
  679              << "\nIf this is a stale not, please remove "
  680             // TODO: file name of lock file
  681              << endl;
  682         failed = true;
  683     } else if ( result != InstallTransaction::SUCCESS ) {
  684         cout << m_appName << ": Unknown error " << result << endl;
  685         failed = true;
  686     }
  687 
  688     if ( !failed ) {
  689         evaluateResult( transaction, update );
  690         if ( m_parser->isTest() ) {
  691             cout << "\n*** " << m_appName << ": test mode end" << endl;
  692         }
  693     } else {
  694         m_returnValue = PG_INSTALL_ERROR;
  695     }
  696 
  697     m_currentTransaction = 0;
  698 }
  699 
  700 /*!
  701   print dependency listing
  702   \param simpleListing Whether it should be in a simple format
  703 */
  704 void PrtGet::printDepends( bool simpleListing )
  705 {
  706     assertMinArgCount(1);
  707 
  708     initRepo();
  709 
  710     InstallTransaction transaction( m_parser->otherArgs(),
  711                                     m_repo, m_pkgDB, m_config );
  712     InstallTransaction::InstallResult result = transaction.calcDependencies();
  713     if ( result == InstallTransaction::CYCLIC_DEPEND ) {
  714         cerr << "prt-get: cyclic dependencies found" << endl;
  715         m_returnValue = PG_GENERAL_ERROR;
  716         return;
  717     } else if ( result == InstallTransaction::PACKAGE_NOT_FOUND ) {
  718         warnPackageNotFound(transaction);
  719         m_returnValue = PG_GENERAL_ERROR;
  720         return;
  721     }
  722 
  723     const list<string>& deps = transaction.dependencies();
  724     if ( simpleListing ) {
  725         if ( deps.size() > 0 ) {
  726             list<string>::const_iterator it = deps.begin();
  727             for ( ; it != deps.end(); ++it ) {
  728                 cout << *it << " ";
  729             }
  730             cout << endl;
  731         }
  732     } else {
  733         if ( deps.size() > 0 ) {
  734             cout << "-- dependencies ([i] = installed)" << endl;
  735             list<string>::const_iterator it = deps.begin();
  736 
  737             bool isAlias;
  738             string provider;
  739             for ( ; it != deps.end(); ++it ) {
  740                 isAlias = false;
  741                 if ( m_pkgDB->isInstalled( *it, true, &isAlias, &provider ) ) {
  742                     cout << "[i] ";
  743                 } else {
  744                     cout << "[ ] ";
  745                 }
  746                 if (m_parser->printPath() > 0) {
  747                     cout << m_repo->getPackage(*it)->path() << "/";
  748                 }
  749                 cout << *it;
  750 
  751                 if (isAlias) {
  752                     cout << " (provided by " << provider << ")";
  753                 }
  754                 cout << endl;
  755             }
  756         } else {
  757             cout << "No dependencies found" << endl;
  758         }
  759 
  760         const list< pair<string, string> >& missing = transaction.missing();
  761         if ( missing.size() ) {
  762             list< pair<string, string> >::const_iterator mit = missing.begin();
  763             cout << endl << "-- missing packages" << endl;
  764             for ( ; mit != missing.end(); ++mit ) {
  765                 cout << mit->first;
  766                 if ( !mit->second.empty() ) {
  767                     cout << " from " << mit->second;
  768                 }
  769                 cout << endl;
  770             }
  771         }
  772     }
  773 }
  774 
  775 /*! read the config file */
  776 void PrtGet::readConfig()
  777 {
  778     string fName = CONF_FILE;
  779     if ( m_parser->isAlternateConfigGiven() ) {
  780         fName = m_parser->alternateConfigFile();
  781     }
  782 
  783     if ( m_config ) {
  784         return; // don't initialize twice
  785     }
  786     m_config = new Configuration( fName, m_parser );
  787 
  788     if (!m_parser->noStdConfig()) {
  789         if ( !m_config->parse() ) {
  790             cerr << "Can't read config file " << fName
  791                  << ". Exiting" << endl;
  792             m_returnValue = PG_GENERAL_ERROR;
  793             return;
  794         }
  795     }
  796 
  797     const list< pair<char*, ArgParser::ConfigArgType> >& configData =
  798         m_parser->configData();
  799     list< pair<char*, ArgParser::ConfigArgType> >::const_iterator it =
  800         configData.begin();
  801     for (; it != configData.end(); ++it) {
  802         m_config->addConfig(it->first,
  803                             it->second == ArgParser::CONFIG_SET,
  804                             it->second == ArgParser::CONFIG_PREPEND);
  805     }
  806 }
  807 
  808 /*!
  809   print a simple list of port which are installed in a different version
  810   than they are in the repository
  811 */
  812 void PrtGet::printQuickDiff()
  813 {
  814     initRepo();
  815 
  816     const map<string, string>& installed = m_pkgDB->installedPackages();
  817     map<string, string>::const_iterator it = installed.begin();
  818     const Package* p = 0;
  819     COMP_RESULT result;
  820     for ( ; it != installed.end(); ++it ) {
  821         if ( !m_locker.isLocked( it->first ) ) {
  822             p = m_repo->getPackage( it->first );
  823             if ( p ) {
  824                 result = compareVersions(p->versionReleaseString(),
  825                                          it->second);
  826                 if (result == GREATER) {
  827                     cout <<  it->first.c_str() << " ";
  828                 }
  829                 // we don't care about undefined diffs here
  830             }
  831         }
  832     }
  833     cout << endl;
  834 }
  835 
  836 
  837 void PrtGet::printFormattedDiffLine(const string& name,
  838                                     const string& versionInstalled,
  839                                     const string& versionPortsTree,
  840                                     bool isLocked)
  841 {
  842     cout.setf( ios::left, ios::adjustfield );
  843     cout.width( 20 );
  844     cout.fill( ' ' );
  845     cout <<  name;
  846 
  847     cout.width( 20 );
  848     cout.fill( ' ' );
  849     cout << versionInstalled;
  850 
  851     string locked = "";
  852     if ( isLocked ) {
  853         locked = "locked";
  854     }
  855     cout.width( 20 );
  856     cout.fill( ' ' );
  857     cout << versionPortsTree << locked << endl;
  858 }
  859 /*!
  860   print an overview of port which are installed in a different version
  861   than they are in the repository
  862 */
  863 void PrtGet::printDiff()
  864 {
  865     initRepo();
  866     map< string, string > l;
  867     if ( m_parser->otherArgs().size() > 0 ) {
  868         expandWildcardsPkgDB( m_parser->otherArgs(), l );
  869     }
  870     if ( l.size() < m_parser->otherArgs().size() ) {
  871         cerr << "prt-get: no matching installed packages found" << endl;
  872         m_returnValue = PG_GENERAL_ERROR;
  873         return;
  874     }
  875 
  876 #if 0
  877     // const list<char*>& l = m_parser->otherArgs();
  878     // list<char*>::const_iterator checkIt = l.begin();
  879 
  880     // check whether ports to be checked are installed
  881     list< string >::iterator checkIt = l.begin();
  882     for ( ; checkIt != l.end(); ++checkIt ) {
  883         if ( ! m_pkgDB->isInstalled( *checkIt )  ) {
  884             cerr << "Port not installed: " << *checkIt << endl;
  885             m_returnValue = PG_GENERAL_ERROR;
  886             return;
  887         }
  888     }
  889 #endif
  890 
  891     const map<string, string>& installed = m_pkgDB->installedPackages();
  892     map<string, string>::const_iterator it = installed.begin();
  893     const Package* p = 0;
  894     int count = 0;
  895     COMP_RESULT result;
  896     for ( ; it != installed.end(); ++it ) {
  897 
  898         p = m_repo->getPackage( it->first );
  899         if ( p ) {
  900             if ( l.size() && l.find( it->first ) == l.end() ) {
  901                 continue;
  902             }
  903 
  904             result = compareVersions( p->versionReleaseString(),
  905                                       it->second );
  906             if (result  == GREATER ) {
  907                 if ( !m_locker.isLocked( it->first )  ||
  908                      m_parser->otherArgs().size() > 0 ||
  909                      m_parser->all() ) {
  910 
  911 
  912                     ++count;
  913                     if ( count == 1 ) {
  914                         cout << "Differences between installed packages "
  915                              << "and ports tree:\n" << endl;
  916                         printFormattedDiffLine("Port",
  917                                                "Installed",
  918                                                "Available in the ports tree",
  919                                                false);
  920                         cout << endl;
  921                     }
  922 
  923                     printFormattedDiffLine(it->first,
  924                                            it->second,
  925                                            p->versionReleaseString(),
  926                                            m_locker.isLocked( it->first ));
  927                 }
  928             } else if (result == UNDEFINED) {
  929                 m_undefinedVersionComp.push_back(make_pair(p, it->second));
  930             }
  931         }
  932     }
  933 
  934     if (m_undefinedVersionComp.size() && 
  935         (m_parser->all() || m_parser->verbose()) ) {
  936         cout << "\n\n" << "Undecidable version differences (use --strict-diff)"
  937              << endl << endl;
  938         printFormattedDiffLine("Port",
  939                                "Installed",
  940                                "Available in the ports tree",
  941                                false);
  942         cout << endl;
  943 
  944         list< pair< const Package*, string > >::iterator it =
  945             m_undefinedVersionComp.begin();
  946         const Package* p;
  947         for (; it != m_undefinedVersionComp.end(); ++it) {
  948             p = it->first;
  949             printFormattedDiffLine(p->name(),
  950                                    it->second,
  951                                    p->versionReleaseString(),
  952                                    false);
  953         }
  954     }
  955 
  956 
  957     if ( count == 0 ) {
  958         cout << "No differences found" << endl;
  959     }
  960 }
  961 
  962 /*! print path to a port */
  963 void PrtGet::printPath()
  964 {
  965     assertExactArgCount(1);
  966 
  967     initRepo();
  968     string arg = *(m_parser->otherArgs().begin());
  969     const Package* p = m_repo->getPackage( arg );
  970     if ( p ) {
  971         cout << p->path() << "/" << p->name() << endl;
  972     } else {
  973         cerr << "Package '" << arg << "' not found" << endl;
  974         m_returnValue = PG_GENERAL_ERROR;
  975         return;
  976     }
  977 }
  978 
  979 
  980 /*! helper method to print the result of an InstallTransaction */
  981 void PrtGet::evaluateResult( InstallTransaction& transaction,
  982                              bool update,
  983                              bool interrupted )
  984 {
  985     int errors = 0;
  986 
  987     // TODO: this is a duplicate, it's in install() as well
  988     string command[] = { "install", "installed" };
  989     if ( update ) {
  990         command[0] = "update";
  991         command[1] = "updated";
  992     }
  993 
  994     const list<string>& ignored = transaction.ignoredPackages();
  995     if ( ignored.size() ) {
  996         cout << endl << "-- Packages ignored" << endl;
  997         list<string>::const_iterator iit = ignored.begin();
  998 
  999         for ( ; iit != ignored.end(); ++iit ) {
 1000             cout << *iit << endl;
 1001         }
 1002     }
 1003 
 1004     const list< pair<string, string> >& missing = transaction.missing();
 1005     if ( missing.size() ) {
 1006         ++errors;
 1007         cout << endl << "-- Packages not found" << endl;
 1008         list< pair<string, string> >::const_iterator mit = missing.begin();
 1009 
 1010         for ( ; mit != missing.end(); ++mit ) {
 1011             cout << mit->first;
 1012             if ( mit->second != "" ) {
 1013                 cout << " from " << mit->second;
 1014             }
 1015             cout << endl;
 1016         }
 1017     }
 1018 
 1019     const list< pair<string, InstallTransaction::InstallInfo> >& error =
 1020         transaction.installError();
 1021     if ( error.size() ) {
 1022         ++errors;
 1023         cout << endl << "-- Packages where "
 1024              << command[0] << " failed" << endl;
 1025         list< pair<string, InstallTransaction::InstallInfo> >::const_iterator
 1026             eit = error.begin();
 1027 
 1028         for ( ; eit != error.end(); ++eit ) {
 1029             cout << eit->first;
 1030             reportPrePost(eit->second);
 1031             cout << endl;
 1032         }
 1033     }
 1034 
 1035     const list<string>& already = transaction.alreadyInstalledPackages();
 1036     if ( already.size() ) {
 1037         cout << endl << "-- Packages installed before this run (ignored)"
 1038              << endl;
 1039         list<string>::const_iterator ait = already.begin();
 1040 
 1041         bool isAlias;
 1042         string provider;
 1043         for ( ; ait != already.end(); ++ait ) {
 1044             isAlias = false;
 1045             cout << *ait;
 1046             m_pkgDB->isInstalled(*ait, true, &isAlias, &provider);
 1047 
 1048             if (isAlias) {
 1049                 cout << " (provided by " << provider << ")";
 1050             }
 1051             cout << endl;
 1052         }
 1053     }
 1054 
 1055 
 1056     const list< pair<string, InstallTransaction::InstallInfo> >& inst =
 1057         transaction.installedPackages();
 1058     if ( inst.size() ) {
 1059         cout << endl << "-- Packages " << command[1] << endl;
 1060         list< pair<string, InstallTransaction::InstallInfo> >::const_iterator
 1061             iit = inst.begin();
 1062 
 1063         bool atLeastOnePackageHasReadme = false;
 1064 
 1065         for ( ; iit != inst.end(); ++iit ) {
 1066             cout << iit->first;
 1067             if ( iit->second.hasReadme ) {
 1068                 if ( m_config->readmeMode() ==
 1069                      Configuration::COMPACT_README ) {
 1070                     cout << " (README)";
 1071                 }
 1072                 atLeastOnePackageHasReadme = true;
 1073             }
 1074             reportPrePost(iit->second);
 1075             cout << endl;
 1076         }
 1077 
 1078 
 1079         // readme's
 1080         if ( atLeastOnePackageHasReadme ) {
 1081             if ( m_config->readmeMode() == Configuration::VERBOSE_README ) {
 1082                 cout << endl << "-- " << command[1]
 1083                      << " packages with README files:" << endl;
 1084                 iit = inst.begin();
 1085                 for ( ; iit != inst.end(); ++iit ) {
 1086                     if ( iit->second.hasReadme ) {
 1087                         cout << iit->first;
 1088                         cout << endl;
 1089                     }
 1090                 }
 1091             }
 1092         }
 1093     }
 1094     if ( m_undefinedVersionComp.size() ) {
 1095         cout << endl
 1096              << "-- Packages with undecidable version "
 1097              << "difference (use --strict-diff)"
 1098              << endl;
 1099         list< pair<const Package*, string> >::const_iterator uit =
 1100             m_undefinedVersionComp.begin();
 1101         const Package * p;
 1102         for ( ; uit != m_undefinedVersionComp.end(); ++uit ) {
 1103             p = uit->first;
 1104             cout << p->name() << " ("
 1105                  << uit->second
 1106                  << " vs "
 1107                  << p->versionReleaseString() << ")" << endl;
 1108         }
 1109     }
 1110 
 1111     cout << endl;
 1112 
 1113     if ( errors == 0 && !interrupted ) {
 1114         cout << "prt-get: " << command[1] << " successfully" << endl;
 1115     } else {
 1116         m_returnValue = PG_PARTIAL_INSTALL_ERROR;
 1117     }
 1118 }
 1119 
 1120 void PrtGet::reportPrePost(const InstallTransaction::InstallInfo& info) {
 1121     if (info.preState != InstallTransaction::NONEXISTENT) {
 1122         string preString = "failed";
 1123         if (info.preState == InstallTransaction::EXEC_SUCCESS) {
 1124             preString = "ok";
 1125         }
 1126         cout << " [pre: " << preString << "]";
 1127     }
 1128     if ( info.postState != InstallTransaction::NONEXISTENT) {
 1129         string postString = "failed";
 1130         if (info.postState == InstallTransaction::EXEC_SUCCESS){
 1131             postString = "ok";
 1132         }
 1133         cout << " [post: " << postString << "]";
 1134     }
 1135 
 1136 }
 1137 
 1138 /*! create a cache */
 1139 void PrtGet::createCache()
 1140 {
 1141     if ( m_parser->wasCalledAsPrtCached() ) {
 1142         cerr << m_appName << ": Can't create cache from cache. "
 1143              << "Use prt-get instead" << endl;
 1144         m_returnValue = PG_GENERAL_ERROR;
 1145         return;
 1146     }
 1147 
 1148     initRepo();
 1149     if (m_config->cacheFile() != "") {
 1150         m_cacheFile = m_config->cacheFile();
 1151     }
 1152 
 1153     Repository::WriteResult result = m_repo->writeCache( m_cacheFile );
 1154     if ( result == Repository::DIR_ERR ) {
 1155         cerr << "Can't create cache directory " << m_cacheFile << endl;
 1156         m_returnValue = PG_GENERAL_ERROR;
 1157         return;
 1158     }
 1159     if ( result == Repository::FILE_ERR ) {
 1160         cerr << "Can't open cache file " << m_cacheFile << " for writing"
 1161              << endl;
 1162         m_returnValue = PG_GENERAL_ERROR;
 1163         return;
 1164     }
 1165 
 1166 }
 1167 
 1168 /*!
 1169   \return true if v1 is greater than v2
 1170  */
 1171 COMP_RESULT PrtGet::compareVersions( const string& v1, const string& v2 )
 1172 {
 1173     if (v1 == v2) {
 1174         return EQUAL;
 1175     }
 1176 
 1177 
 1178     if (m_parser->preferHigher() ||
 1179         (m_config->preferHigher() && !m_parser->strictDiff())) {
 1180 
 1181         COMP_RESULT result = VersionComparator::compareVersions(v1, v2);
 1182         return result;
 1183     }
 1184 
 1185     if (v1 != v2)
 1186         return GREATER;
 1187     return LESS;
 1188 }
 1189 
 1190 int PrtGet::returnValue() const
 1191 {
 1192     return m_returnValue;
 1193 }
 1194 
 1195 
 1196 /*! print a list of packages available in the repository */
 1197 void PrtGet::printf()
 1198 {
 1199     map<string, string> sortedOutput;
 1200 
 1201     assertExactArgCount(1);
 1202 
 1203     initRepo();
 1204     string filter = "*";
 1205     if ( m_parser->hasFilter() ) {
 1206         filter = m_parser->filter();
 1207     }
 1208     list<Package*> packages;
 1209     m_repo->getMatchingPackages( filter, packages );
 1210     list<Package*>::const_iterator it = packages.begin();
 1211 
 1212     const string formatString = *(m_parser->otherArgs().begin());
 1213     string sortString =
 1214         StringHelper::stripWhiteSpace( m_parser->sortArgs() );
 1215     sortString += "%n"; // make it unique
 1216 
 1217     for ( ; it != packages.end(); ++it ) {
 1218         string output = formatString;
 1219         string sortkey = sortString;
 1220 
 1221         const Package* p = *it;
 1222 
 1223         StringHelper::replaceAll( output, "%n", p->name() );
 1224         StringHelper::replaceAll( output, "%u", p->url() );
 1225         StringHelper::replaceAll( output, "%p", p->path() );
 1226         StringHelper::replaceAll( output, "%v", p->version() );
 1227         StringHelper::replaceAll( output, "%r", p->release() );
 1228         StringHelper::replaceAll( output, "%d", p->description() );
 1229         StringHelper::replaceAll( output, "%e", p->dependencies() );
 1230         StringHelper::replaceAll( output, "%P", p->packager() );
 1231         StringHelper::replaceAll( output, "%M", p->maintainer() );
 1232 
 1233         StringHelper::replaceAll( output, "\\t", "\t" );
 1234         StringHelper::replaceAll( output, "\\n", "\n" );
 1235 
 1236         StringHelper::replaceAll( sortkey, "%n", p->name() );
 1237         StringHelper::replaceAll( sortkey, "%u", p->url() );
 1238         StringHelper::replaceAll( sortkey, "%p", p->path() );
 1239         StringHelper::replaceAll( sortkey, "%v", p->version() );
 1240         StringHelper::replaceAll( sortkey, "%r", p->release() );
 1241         StringHelper::replaceAll( sortkey, "%d", p->description() );
 1242         StringHelper::replaceAll( sortkey, "%e", p->dependencies() );
 1243         StringHelper::replaceAll( sortkey, "%P", p->packager() );
 1244         StringHelper::replaceAll( sortkey, "%M", p->maintainer() );
 1245 
 1246         string isInst = "no";
 1247         if ( m_pkgDB->isInstalled( p->name() ) ) {
 1248             string ip = p->name() + "-" +
 1249                 m_pkgDB->getPackageVersion( p->name() );
 1250             if ( ip == p->name() + "-" + p->versionReleaseString() ) {
 1251                 isInst = "yes";
 1252             } else {
 1253                 isInst = "diff";
 1254             }
 1255         }
 1256         StringHelper::replaceAll( output, "%i", isInst );
 1257         StringHelper::replaceAll( sortkey, "%i", isInst );
 1258 
 1259         string isLocked = m_locker.isLocked( p->name() ) ? "yes" : "no";
 1260         StringHelper::replaceAll( output, "%l", isLocked );
 1261         StringHelper::replaceAll( sortkey, "%l", isLocked );
 1262 
 1263         string hasReadme = p->hasReadme() ? "yes" : "no";
 1264         StringHelper::replaceAll( output, "%R", hasReadme );
 1265         StringHelper::replaceAll( sortkey, "%R", hasReadme );
 1266 
 1267         string hasPreInstall = p->hasPreInstall() ? "yes" : "no";
 1268         StringHelper::replaceAll( output, "%E", hasPreInstall );
 1269         StringHelper::replaceAll( sortkey, "%E", hasPreInstall );
 1270 
 1271         string hasPostInstall = p->hasPostInstall() ? "yes" : "no";
 1272         StringHelper::replaceAll( output, "%O", hasPostInstall );
 1273         StringHelper::replaceAll( sortkey, "%O", hasPostInstall );
 1274 
 1275         sortedOutput[sortkey] = output;
 1276     }
 1277 
 1278     map<string, string>::iterator sortIt = sortedOutput.begin();
 1279     for ( ; sortIt != sortedOutput.end(); ++sortIt ) {
 1280         if ( StringHelper::stripWhiteSpace(sortIt->second).length() > 0) {
 1281             cout << sortIt->second;
 1282         }
 1283     }
 1284 }
 1285 
 1286 void PrtGet::readme()
 1287 {
 1288     assertExactArgCount(1);
 1289 
 1290     initRepo();
 1291     string arg = *(m_parser->otherArgs().begin());
 1292     const Package* p = m_repo->getPackage( arg );
 1293     if ( p ) {
 1294         string file = p->path() + "/" + p->name() + "/README";
 1295         printFile(file);
 1296     } else {
 1297         cerr << "Package '" << arg << "' not found" << endl;
 1298         m_returnValue = PG_GENERAL_ERROR;
 1299         return;
 1300     }
 1301 }
 1302 
 1303 bool PrtGet::printFile(const string& file)
 1304 {
 1305     if (!File::fileExists(file)) {
 1306         return false;
 1307     }
 1308 
 1309     char* pager = getenv("PAGER");
 1310     if (pager) {
 1311         Process proc(pager, file);
 1312         proc.executeShell();
 1313     } else {
 1314         FILE* fp = fopen( file.c_str(), "r" );
 1315         char buf[255];
 1316         if ( fp ) {
 1317             while ( fgets( buf, 255, fp ) ) {
 1318                 cout << buf;
 1319             }
 1320             fclose( fp );
 1321         }
 1322     }
 1323 
 1324     return true;
 1325 }
 1326 
 1327 void PrtGet::printDependent()
 1328 {
 1329     assertExactArgCount(1);
 1330 
 1331     initRepo();
 1332     string arg = *(m_parser->otherArgs().begin());
 1333 
 1334     if (m_parser->printTree()) {
 1335         cout << arg << endl;
 1336         printDependent(arg, 2);
 1337     } else {
 1338         printDependent(arg, 0);
 1339     }
 1340 }
 1341 
 1342 void PrtGet::printDependent(const string& dep, int level)
 1343 {
 1344     map<string, Package*>::const_iterator it = m_repo->packages().begin();
 1345     static map<string, bool> shownMap;
 1346 
 1347     set<const Package*> dependent;
 1348     for ( ; it != m_repo->packages().end(); ++it ) {
 1349 
 1350         // TODO: is the following line needed?
 1351         const Package* p = it->second;
 1352         if ( p && p->dependencies().find( dep ) != string::npos ) {
 1353             list<string> tokens;
 1354             StringHelper::split( p->dependencies(), ',', tokens );
 1355             list<string>::iterator it = find( tokens.begin(),
 1356                                               tokens.end(),
 1357                                               dep );
 1358             if ( it != tokens.end() ) {
 1359                 dependent.insert( p );
 1360             }
 1361         }
 1362     }
 1363 
 1364     // - there are two modes, tree and non-tree recursive mode; in
 1365     // tree mode, packages are shown multiple times, in non tree
 1366     // recursive mode they're only printed the first time; this is not
 1367     // necessarily optimal for rebuilding:
 1368     //
 1369     // a -> b -> d
 1370     //  \     ^
 1371     //   > c /
 1372     //
 1373     // trying to rebuild 'd' before 'c' might possibly fail
 1374     string indent = "";
 1375     if (m_parser->printTree()) {
 1376         for (int i = 0; i < level; ++i) {
 1377             indent += " ";
 1378         }
 1379     }
 1380     set<const Package*>::iterator it2 = dependent.begin();
 1381     for ( ; it2 != dependent.end(); ++it2 ) {
 1382         const Package* p = *it2;
 1383 
 1384         if (m_parser->recursive() && !m_parser->printTree()) {
 1385             if (shownMap[p->name()]) {
 1386                 continue;
 1387             }
 1388             shownMap[p->name()] = true;
 1389         }
 1390 
 1391         if ( m_parser->all() || m_pkgDB->isInstalled( p->name() ) ) {
 1392 
 1393             cout << indent << p->name();
 1394             if ( m_parser->verbose() > 0 ) {
 1395                 cout << " " << p->versionReleaseString();
 1396             }
 1397             if ( m_parser->verbose() > 1 ) {
 1398                 cout << ":  " << p->description();
 1399             }
 1400 
 1401             cout << endl;
 1402 
 1403             if (m_parser->recursive()) {
 1404                 printDependent( p->name(), level+2 );
 1405             }
 1406         }
 1407     }
 1408 }
 1409 
 1410 void PrtGet::listOrphans()
 1411 {
 1412     initRepo();
 1413     map<string, string> installed = m_pkgDB->installedPackages();
 1414     map<string, bool> required;
 1415     map<string, string>::iterator it = installed.begin();
 1416 
 1417     for (; it != installed.end(); ++it) {
 1418         list<string> tokens;
 1419         const Package* p = m_repo->getPackage(it->first);
 1420         if (p) {
 1421             StringHelper::split( p->dependencies(), ',', tokens );
 1422             list<string>::iterator lit = tokens.begin();
 1423             for (; lit != tokens.end(); ++lit) {
 1424                 required[*lit] = true;
 1425             }
 1426         }
 1427     }
 1428 
 1429     // - we could store the package pointer in another map to avoid
 1430     // another getPackage lockup, but it seems better to optimized for
 1431     // memory since it's only used when called with -vv
 1432 
 1433     it = installed.begin();
 1434     for (; it != installed.end(); ++it) {
 1435         if (!required[it->first]) {
 1436             cout << it->first;
 1437             if ( m_parser->verbose() > 0 ) {
 1438                 cout << " " << it->second;
 1439             }
 1440             if ( m_parser->verbose() > 1 ) {
 1441                 const Package* p = m_repo->getPackage(it->first);
 1442                 if (p) {
 1443                     cout << ":  " << p->description();
 1444                 }
 1445             }
 1446             cout << endl;
 1447         }
 1448     }
 1449 }
 1450 
 1451 
 1452 void PrtGet::warnPackageNotFound(InstallTransaction& transaction)
 1453 {
 1454     cerr << "The package '";
 1455     cerr << transaction.missing().begin()->first;
 1456     cerr << "' could not be found: " << endl;
 1457 }
 1458 
 1459 void PrtGet::sysup()
 1460 {
 1461     // TODO: refactor getDifferentPackages from diff/quickdiff
 1462     initRepo();
 1463 
 1464     list<string>* target;
 1465     list<string> packagesToUpdate;
 1466     list<string> sortedList;
 1467 
 1468     const map<string, string>& installed = m_pkgDB->installedPackages();
 1469     map<string, string>::const_iterator it = installed.begin();
 1470     const Package* p = 0;
 1471     COMP_RESULT result;
 1472     for ( ; it != installed.end(); ++it ) {
 1473         if ( !m_locker.isLocked( it->first ) ) {
 1474             p = m_repo->getPackage( it->first );
 1475             if ( p ) {
 1476                 result = compareVersions( p->versionReleaseString(),
 1477                                           it->second );
 1478                 if (result  == GREATER ) {
 1479                     packagesToUpdate.push_back( it->first );
 1480                 } else if (result  == UNDEFINED ) {
 1481                     m_undefinedVersionComp.push_back(make_pair(p, it->second));
 1482                 }
 1483             }
 1484         }
 1485     }
 1486 
 1487     if ( packagesToUpdate.empty() ) {
 1488         cout << "System is up to date" << endl;
 1489         return;
 1490     }
 1491 
 1492     if ( m_parser->nodeps() ) {
 1493         target = &packagesToUpdate;
 1494     } else {
 1495         // sort by dependency
 1496 
 1497         // TODO: refactor code from printDepends
 1498         InstallTransaction depTrans( packagesToUpdate,
 1499                                      m_repo, m_pkgDB, m_config );
 1500         InstallTransaction::InstallResult result = depTrans.calcDependencies();
 1501         if ( result == InstallTransaction::CYCLIC_DEPEND ) {
 1502             cerr << "cyclic dependencies" << endl;
 1503             m_returnValue = PG_GENERAL_ERROR;
 1504             return;
 1505         } else if ( result == InstallTransaction::PACKAGE_NOT_FOUND ) {
 1506             warnPackageNotFound(depTrans);
 1507             m_returnValue = PG_GENERAL_ERROR;
 1508             return;
 1509         }
 1510 
 1511         const list<string>& deps = depTrans.dependencies();
 1512         if ( deps.size() > 0 ) {
 1513             list<string>::const_iterator it = deps.begin();
 1514             for ( ; it != deps.end(); ++it ) {
 1515                 if ( find( packagesToUpdate.begin(),
 1516                            packagesToUpdate.end(), *it ) !=
 1517                      packagesToUpdate.end() ) {;
 1518                      sortedList.push_back( *it );
 1519                 }
 1520             }
 1521         }
 1522 
 1523         target = &sortedList;
 1524     }
 1525 
 1526     InstallTransaction transaction( *target,
 1527                                     m_repo, m_pkgDB, m_config );
 1528     executeTransaction( transaction, true, false );
 1529 }
 1530 
 1531 
 1532 void PrtGet::expandWildcardsPkgDB( const list<char*>& in,
 1533                                    map<string, string>& target )
 1534 {
 1535     list<char*>::const_iterator it = in.begin();
 1536     for ( ; it != in.end(); ++it ) {
 1537         map<string, string> l;
 1538         m_pkgDB->getMatchingPackages( *it, l, m_useRegex );
 1539         map<string, string>::iterator iit = l.begin();
 1540         for ( ; iit != l.end(); ++iit ) {
 1541             target[iit->first] = iit->second;
 1542         }
 1543     }
 1544 }
 1545 
 1546 void PrtGet::expandWildcardsRepo( const list<char*>& in, list<string>& target )
 1547 {
 1548     list<char*>::const_iterator it = in.begin();
 1549 
 1550     for ( ; it != in.end(); ++it ) {
 1551         list<Package*> l;
 1552         m_repo->getMatchingPackages( *it, l );
 1553         list<Package*>::iterator iit = l.begin();
 1554         for ( ; iit != l.end(); ++iit ) {
 1555             target.push_back( (*iit)->name() );
 1556         }
 1557     }
 1558 }
 1559 
 1560 
 1561 void PrtGet::current()
 1562 {
 1563     assertExactArgCount(1);
 1564 
 1565     const map<string, string>& installed = m_pkgDB->installedPackages();
 1566     map<string, string>::const_iterator it = installed.begin();
 1567     string search = *(m_parser->otherArgs().begin());
 1568 
 1569     for ( ; it != installed.end(); ++it ) {
 1570         if ( it->first == search ) {
 1571             cout << it->second.c_str() << endl;
 1572             return;
 1573         }
 1574     }
 1575 
 1576     cout << "Package " << search << " not installed" << endl;
 1577     m_returnValue = 1;
 1578 }
 1579 
 1580 SignalHandler::HandlerResult PrtGet::handleSignal( int signal )
 1581 {
 1582     // TODO: second argument could also be true:
 1583     // TODO: kill installtransaction
 1584 
 1585     cout << "prt-get: interrupted" << endl;
 1586     if ( m_currentTransaction ) {
 1587         evaluateResult( *m_currentTransaction, false, true );
 1588     }
 1589 }
 1590 
 1591 /*!
 1592   find files matching a pattern in repository
 1593 
 1594   \sa Repository::getMatchingPackages()
 1595 */
 1596 void PrtGet::fsearch()
 1597 {
 1598     assertMinArgCount(1);
 1599 
 1600     string arg = "*";
 1601     if ( m_parser->otherArgs().size() == 1 ) {
 1602         arg = *(m_parser->otherArgs().begin());
 1603     }
 1604 
 1605     initRepo();
 1606     const map<string, Package*>& packages = m_repo->packages();
 1607     map<string, Package*>::const_iterator it = packages.begin();
 1608     bool first = true;
 1609     for ( ; it != packages.end(); ++it ) {
 1610         list<string> matches;
 1611         string fp =
 1612             it->second->path() + "/" +
 1613             it->second->name() + "/" + ".footprint";
 1614         if ( File::grep( fp, arg, matches,
 1615                          m_parser->fullPath(),
 1616                          m_useRegex)) {
 1617             if ( matches.size() > 0 ) {
 1618                 if ( first ) {
 1619                     first = false;
 1620                 } else {
 1621                     cout << endl;
 1622                 }
 1623                 cout << "Found in "
 1624                      << it->second->path() << "/"
 1625                      << it->first << ":" << endl;
 1626                 list<string>::iterator it = matches.begin();
 1627                 for ( ; it != matches.end(); ++it ) {
 1628                     cout << "  " << *it << endl;
 1629                 }
 1630             }
 1631         }
 1632     }
 1633 
 1634     if ( first ) {
 1635         m_returnValue = PG_GENERAL_ERROR;
 1636     }
 1637 }
 1638 
 1639 void PrtGet::setLock( bool lock )
 1640 {
 1641     assertMinArgCount(1);
 1642 
 1643     if ( lock ) {
 1644         initRepo();
 1645     }
 1646 
 1647     const list<char*>& args = m_parser->otherArgs();
 1648     list<char*>::const_iterator it = args.begin();
 1649     for ( ; it != args.end(); ++it ) {
 1650         if ( lock ) {
 1651             if (m_pkgDB->isInstalled( *it )) {
 1652                 if (!m_locker.lock( *it )) {
 1653                     cerr << "Already locked: " << *it << endl;
 1654                     m_returnValue = PG_GENERAL_ERROR;
 1655                 }
 1656             } else {
 1657                 cerr << "Package '" << *it << "' not found" << endl;
 1658                 m_returnValue = PG_GENERAL_ERROR;
 1659                 return;
 1660             }
 1661 
 1662         } else {
 1663             if ( !m_locker.unlock( *it ) ) {
 1664                 cerr << "Not locked previously: " << *it << endl;
 1665                 m_returnValue = PG_GENERAL_ERROR;
 1666                 return;
 1667             }
 1668         }
 1669     }
 1670 								
 1671     if (!m_locker.store()) {
 1672         cerr << "Failed to write lock data" << endl;
 1673         m_returnValue = PG_GENERAL_ERROR;
 1674     }
 1675 }
 1676 
 1677 void PrtGet::listLocked()
 1678 {
 1679     // shares some code with listInstalled
 1680     if ( m_locker.openFailed() ) {
 1681         cerr << "Failed to open lock data file" << endl;
 1682         m_returnValue = PG_GENERAL_ERROR;
 1683     }
 1684 
 1685     const map<string, string>& l = m_pkgDB->installedPackages();
 1686 
 1687     if ( l.empty() ) {
 1688         return;
 1689     }
 1690 
 1691     if ( m_parser->verbose() > 1 ) {
 1692         // warning: will slow down the process...
 1693         initRepo();
 1694     }
 1695 
 1696 
 1697     const vector<string>& lockedPackages = m_locker.lockedPackages();
 1698     vector<string>::const_iterator it = lockedPackages.begin();
 1699     for ( ; it != lockedPackages.end(); ++it ) {
 1700         cout << *it;
 1701         if ( m_parser->verbose() > 0 ) {
 1702             cout << " " << m_pkgDB->getPackageVersion(*it);
 1703         }
 1704         if ( m_parser->verbose() > 1 ) {
 1705             const Package* p = m_repo->getPackage( *it );
 1706             if ( p ) {
 1707                 cout << ": " << p->description();
 1708             }
 1709         }
 1710 
 1711         cout << endl;
 1712 
 1713     }
 1714 }
 1715 
 1716 
 1717 void PrtGet::edit()
 1718 {
 1719     assertMinArgCount(1);
 1720     assertMaxArgCount(2);
 1721 
 1722     char* editor = getenv("EDITOR");
 1723     if (editor) {
 1724         initRepo();
 1725 
 1726         list<char*>::const_iterator it = m_parser->otherArgs().begin();
 1727         string arg = *it;
 1728         const Package* p = m_repo->getPackage( arg );
 1729         if ( p ) {
 1730             string fileName = "Pkgfile";
 1731             if (++it != m_parser->otherArgs().end()) {
 1732                 fileName = *it;
 1733             }
 1734             string file = p->path() + "/" + p->name() + "/" + fileName;
 1735             Process proc(editor, file);
 1736             m_returnValue = proc.executeShell();
 1737             if (m_returnValue) {
 1738                 cerr << "error while execution the editor" << endl;
 1739             }
 1740         } else {
 1741             cerr << "Package '" << arg << "' not found" << endl;
 1742             m_returnValue = PG_GENERAL_ERROR;
 1743             return;
 1744         }
 1745 
 1746     } else {
 1747         cerr << "Environment variable EDITOR not set" << endl;;
 1748         m_returnValue = PG_GENERAL_ERROR;
 1749         return;
 1750     }
 1751 
 1752 }
 1753 
 1754 void PrtGet::ls()
 1755 {
 1756     assertExactArgCount(1);
 1757 
 1758     initRepo();
 1759 
 1760     list<char*>::const_iterator it = m_parser->otherArgs().begin();
 1761     string arg = *it;
 1762     const Package* p = m_repo->getPackage( arg );
 1763     if ( p ) {
 1764         string dirname = p->path() + "/" + p->name();
 1765         DIR* dir = opendir(dirname.c_str());
 1766         struct dirent* entry;
 1767         vector<string> files;
 1768         while (entry = readdir(dir)) {
 1769             string dName = entry->d_name;
 1770             if (dName != "." && dName != "..") {
 1771                 files.push_back(dName);
 1772             }
 1773         }
 1774         closedir(dir);
 1775 
 1776         sort(files.begin(), files.end());
 1777         vector<string>::iterator fit = files.begin();
 1778         for (; fit != files.end(); ++fit) {
 1779             if (m_parser->printPath()) {
 1780                 cout << p->path() + "/" +p->name() + "/";
 1781             }
 1782             cout << *fit << endl;
 1783         }
 1784     } else {
 1785         cerr << "Package '" << arg << "' not found" << endl;
 1786         m_returnValue = PG_GENERAL_ERROR;
 1787         return;
 1788     }
 1789 }
 1790 
 1791 void PrtGet::cat()
 1792 {
 1793     assertMinArgCount(1);
 1794     assertMaxArgCount(2);
 1795 
 1796     initRepo();
 1797 
 1798     list<char*>::const_iterator it = m_parser->otherArgs().begin();
 1799     string arg = *it;
 1800     const Package* p = m_repo->getPackage( arg );
 1801     if ( p ) {
 1802         string fileName = "Pkgfile";
 1803         if (++it != m_parser->otherArgs().end()) {
 1804             fileName = *it;
 1805         }
 1806         string file = p->path() + "/" + p->name() + "/" + fileName;
 1807         if (!printFile(file)) {
 1808             cerr << "File '" << *it << "' not found" << endl;
 1809             m_returnValue = PG_GENERAL_ERROR;
 1810             return;
 1811         }
 1812     } else {
 1813         cerr << "Package '" << arg << "' not found" << endl;
 1814         m_returnValue = PG_GENERAL_ERROR;
 1815         return;
 1816     }
 1817 }
 1818 
 1819 void PrtGet::remove()
 1820 {
 1821     assertMinArgCount(1);
 1822 
 1823     list<string> removed;
 1824     list<string> failed;
 1825     list<string> notInstalled;
 1826 
 1827     if ( m_parser->isTest() ) {
 1828         cout << "*** " << m_appName << ": test mode" << endl;
 1829     }
 1830 
 1831     string command = InstallTransaction::PKGRM_DEFAULT_COMMAND;
 1832     if (m_config->removeCommand() != "") {
 1833         command = m_config->removeCommand();
 1834     }
 1835 
 1836     const list<char*>& args = m_parser->otherArgs();
 1837     list<char*>::const_iterator it = args.begin();
 1838     for ( ; it != args.end(); ++it ) {
 1839         if (m_pkgDB->isInstalled(*it)) {
 1840             // TODO: prettify
 1841             string args = "";
 1842             if (m_parser->installRoot() != "") {
 1843                 args = "-r " + m_parser->installRoot() + " ";
 1844             }
 1845             args += (m_parser->pkgrmArgs() + " " + *it);
 1846 
 1847             Process proc(command, args);
 1848             if (m_parser->isTest() || proc.executeShell() == 0) {
 1849                 removed.push_back(*it);
 1850                 if (m_locker.isLocked(*it)) {
 1851                     m_locker.unlock(*it);
 1852                     m_locker.store();
 1853                 }
 1854             } else {
 1855                 failed.push_back(*it);
 1856             }
 1857         } else {
 1858             notInstalled.push_back(*it);
 1859         }
 1860     }
 1861 
 1862     if ( removed.size() ) {
 1863         cout << endl << "-- Packages removed"
 1864              << endl;
 1865         list<string>::const_iterator it = removed.begin();
 1866 
 1867         for ( ; it != removed.end(); ++it ) {
 1868             cout << *it << endl;
 1869         }
 1870     }
 1871 
 1872     if ( failed.size() ) {
 1873         cout << endl << "-- Packages where removal failed"
 1874              << endl;
 1875         list<string>::const_iterator it = failed.begin();
 1876 
 1877         for ( ; it != failed.end(); ++it ) {
 1878             cout << *it << endl;
 1879         }
 1880     }
 1881 
 1882     if ( notInstalled.size() ) {
 1883         cout << endl << "-- Packages which were not installed"
 1884              << endl;
 1885         list<string>::const_iterator it = notInstalled.begin();
 1886 
 1887         for ( ; it != notInstalled.end(); ++it ) {
 1888             cout << *it << endl;
 1889         }
 1890     }
 1891 
 1892     if ( m_parser->isTest() ) {
 1893         cout << "*** " << m_appName << ": test mode end" << endl;
 1894     }
 1895 
 1896 
 1897 
 1898 }
 1899 
 1900 void PrtGet::assertMaxArgCount(int count)
 1901 {
 1902     if ( m_parser->otherArgs().size() > count ) {
 1903         argCountFailure(count, "at most");
 1904     }
 1905 }
 1906 
 1907 void PrtGet::assertExactArgCount(int count)
 1908 {
 1909     if ( m_parser->otherArgs().size() != count ) {
 1910         argCountFailure(count, "exactly");
 1911     }
 1912 }
 1913 
 1914 void PrtGet::assertMinArgCount(int count)
 1915 {
 1916      if ( m_parser->otherArgs().size() < count ) {
 1917          argCountFailure(count, "at least");
 1918      }
 1919 }
 1920 
 1921 void PrtGet::argCountFailure(int count, const string& specifier)
 1922 {
 1923     cerr << m_appName << " "
 1924          << m_parser->commandName() << " takes " << specifier << " "
 1925          << count << (count > 1 ? " arguments" : " argument") << endl;
 1926     exit(PG_ARG_ERROR);
 1927 }
 1928 
 1929 
 1930 void PrtGet::printDependTree()
 1931 {
 1932     assertExactArgCount(1);
 1933 
 1934     initRepo();
 1935 
 1936     list<char*>::const_iterator it = m_parser->otherArgs().begin();
 1937     string arg = *it;
 1938     const Package* p = m_repo->getPackage( arg );
 1939     if (!p) {
 1940         cerr << "Package '" << arg << "' not found" << endl;
 1941         m_returnValue = PG_GENERAL_ERROR;
 1942         return;
 1943     }
 1944 
 1945     if (p->dependencies().length() > 0) {
 1946 
 1947         cout << "-- dependencies ([i] = installed";
 1948         if (!m_parser->all()) {
 1949             cout << ", '-->' = seen before";
 1950         }
 1951         cout << ")" << endl;
 1952         if ( m_pkgDB->isInstalled( *it ) ) {
 1953             cout << "[i] ";
 1954         } else {
 1955             cout << "[ ] ";
 1956         }
 1957         cout << p->name() << endl;
 1958         printDepsLevel(2, p);
 1959     }
 1960 
 1961 }
 1962 
 1963 void PrtGet::printDepsLevel(int indent, const Package* package)
 1964 {
 1965     static map<string, bool> shownMap;
 1966 
 1967     list<string> deps;
 1968     StringHelper::split(package->dependencies(), ',', deps);
 1969     list<string>::iterator it = deps.begin();
 1970     bool isAlias = false;
 1971     string aliasName = "";
 1972 
 1973     for (; it != deps.end(); ++it) {
 1974         if ( m_pkgDB->isInstalled( *it, true, &isAlias, &aliasName ) ) {
 1975             cout << "[i] ";
 1976         } else {
 1977             cout << "[ ] ";
 1978         }
 1979         for (int i = 0; i < indent; ++i) {
 1980             cout << " ";
 1981         }
 1982         cout << *it;
 1983         if (isAlias) {
 1984             cout << " (provided by " << aliasName << ")";
 1985         }
 1986         const Package* p = m_repo->getPackage( *it );
 1987         if (p) {
 1988             if (p->dependencies().length() > 0) {
 1989                 map<string, bool>::iterator shownIt = shownMap.find(*it);
 1990                 if (shownIt != shownMap.end()) {
 1991                     cout << " -->" << endl;;
 1992                 } else {
 1993                     cout << endl;
 1994                     printDepsLevel(indent+2, p);
 1995                     if (!m_parser->all()) {
 1996                         shownMap[*it] = true;
 1997                     }
 1998                 }
 1999             } else {
 2000                 cout << endl;
 2001             }
 2002         } else {
 2003             cout << " (not found in ports tree)" << endl;
 2004         }
 2005     }
 2006 }
 2007 
 2008 void PrtGet::dumpConfig()
 2009 {
 2010 
 2011     cout.setf( ios::left, ios::adjustfield );
 2012     cout.width( 20 );
 2013     cout.fill( ' ' );
 2014     cout << "Alias file: " << PkgDB::ALIAS_STORE << endl;
 2015 
 2016     if (!m_parser->noStdConfig()) {
 2017         string fName = CONF_FILE;
 2018         if ( m_parser->isAlternateConfigGiven() ) {
 2019             fName = m_parser->alternateConfigFile();
 2020         }
 2021         cout.setf( ios::left, ios::adjustfield );
 2022         cout.width( 20 );
 2023         cout.fill( ' ' );
 2024         cout << "Configuration file: " << fName << endl;
 2025     }
 2026 
 2027     if (m_config->cacheFile() != "") {
 2028         cout.setf( ios::left, ios::adjustfield );
 2029         cout.width( 20 );
 2030         cout.fill( ' ' );
 2031         cout << "Cache file: " << m_config->cacheFile() << endl;
 2032     }
 2033     if (m_config->makeCommand() != "") {
 2034         cout.setf( ios::left, ios::adjustfield );
 2035         cout.width( 20 );
 2036         cout.fill( ' ' );
 2037         cout << "Make command file: " << m_config->makeCommand() << endl;
 2038     }
 2039     if (m_config->addCommand() != "") {
 2040         cout.setf( ios::left, ios::adjustfield );
 2041         cout.width( 20 );
 2042         cout.fill( ' ' );
 2043         cout << "Add command: " << m_config->addCommand() << endl;
 2044     }
 2045     if (m_config->removeCommand() != "") {
 2046         cout.setf( ios::left, ios::adjustfield );
 2047         cout.width( 20 );
 2048         cout.fill( ' ' );
 2049         cout << "Remove command: " << m_config->removeCommand() << endl;
 2050     }
 2051     if (m_config->runscriptCommand() != "") {
 2052         cout.setf( ios::left, ios::adjustfield );
 2053         cout.width( 20 );
 2054         cout.fill( ' ' );
 2055         cout << "Runscript command: " << m_config->runscriptCommand() << endl;
 2056     }
 2057 
 2058     cout.setf( ios::left, ios::adjustfield );
 2059     cout.width( 20 );
 2060     cout.fill( ' ' );
 2061     cout << "Run scripts: " <<(m_config->runScripts() ? "yes" : "no" )
 2062          << endl;
 2063 
 2064     cout.setf( ios::left, ios::adjustfield );
 2065     cout.width( 20 );
 2066     cout.fill( ' ' );
 2067     cout << "Keep higher version:" <<(m_config->preferHigher() ? "yes" : "no" )
 2068          << endl;
 2069 
 2070     cout.setf( ios::left, ios::adjustfield );
 2071     cout.width( 20 );
 2072     cout.fill( ' ' );
 2073     cout << "Readme mode:  ";
 2074     switch (m_config->readmeMode()) {
 2075         case Configuration::VERBOSE_README:
 2076             cout << "verbose";
 2077             break;
 2078         case Configuration::COMPACT_README:
 2079             cout << "compact";
 2080             break;
 2081         case Configuration::NO_README:
 2082             cout << "off";
 2083             break;
 2084     }
 2085     cout << endl;
 2086 
 2087     cout << endl;
 2088 
 2089     if (m_config->logFilePattern() != "") {
 2090         cout.setf( ios::left, ios::adjustfield );
 2091         cout.width( 20 );
 2092         cout.fill( ' ' );
 2093         cout << "Log file: " << m_config->logFilePattern() << endl;
 2094     }
 2095     cout.setf( ios::left, ios::adjustfield );
 2096     cout.width( 20 );
 2097     cout.fill( ' ' );
 2098     cout << "  Write log: " << (m_config->writeLog() ? "yes" : "no" ) << endl;
 2099     cout.setf( ios::left, ios::adjustfield );
 2100     cout.width( 20 );
 2101     cout.fill( ' ' );
 2102     cout << "  Append log: " <<(m_config->appendLog() ? "yes" : "no" ) << endl;
 2103 
 2104 
 2105 
 2106     cout << endl;
 2107     list< pair<string, string> >::const_iterator it =
 2108         m_config->rootList().begin();
 2109     cout << "Port "
 2110          << (m_config->rootList().size() == 1 ? "directory" : "directories")
 2111          << ": " << endl;
 2112     for (; it != m_config->rootList().end(); ++it) {
 2113         cout << " " << it->first;
 2114         if (it->second != "") {
 2115             cout << " (" << it->second << ")";
 2116         }
 2117         cout << endl;
 2118     }
 2119 }

Generated by cgit