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

Generated by cgit