summaryrefslogtreecommitdiff
path: root/src/prtget.cpp
blob: 01af812473082d4b425431dfd6815d7b5fb1cb2d (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& version1,
  839                                     const string& version2,
  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 << version1;
  850 
  851     string locked = "";
  852     if ( isLocked ) {
  853         locked = "locked";
  854     }
  855     cout.width( 20 );
  856     cout.fill( ' ' );
  857     cout << version2 << 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         cout << "\n\n" << "Undecidable version differences (use --strict-diff)"
  936              << endl << endl;
  937         printFormattedDiffLine("Port",
  938                                "Installed",
  939                                "Available in the ports tree",
  940                                false);
  941         cout << endl;
  942 
  943         list< pair< const Package*, string > >::iterator it =
  944             m_undefinedVersionComp.begin();
  945         const Package* p;
  946         for (; it != m_undefinedVersionComp.end(); ++it) {
  947             p = it->first;
  948             printFormattedDiffLine(p->name(),
  949                                    p->versionReleaseString(),
  950                                    it->second,
  951                                    false);
  952         }
  953     }
  954 
  955 
  956     if ( count == 0 ) {
  957         cout << "No differences found" << endl;
  958     }
  959 }
  960 
  961 /*! print path to a port */
  962 void PrtGet::printPath()
  963 {
  964     assertExactArgCount(1);
  965 
  966     initRepo();
  967     string arg = *(m_parser->otherArgs().begin());
  968     const Package* p = m_repo->getPackage( arg );
  969     if ( p ) {
  970         cout << p->path() << "/" << p->name() << endl;
  971     } else {
  972         cerr << "Package '" << arg << "' not found" << endl;
  973         m_returnValue = PG_GENERAL_ERROR;
  974         return;
  975     }
  976 }
  977 
  978 
  979 /*! helper method to print the result of an InstallTransaction */
  980 void PrtGet::evaluateResult( InstallTransaction& transaction,
  981                              bool update,
  982                              bool interrupted )
  983 {
  984     int errors = 0;
  985 
  986     // TODO: this is a duplicate, it's in install() as well
  987     string command[] = { "install", "installed" };
  988     if ( update ) {
  989         command[0] = "update";
  990         command[1] = "updated";
  991     }
  992 
  993     const list<string>& ignored = transaction.ignoredPackages();
  994     if ( ignored.size() ) {
  995         cout << endl << "-- Packages ignored" << endl;
  996         list<string>::const_iterator iit = ignored.begin();
  997 
  998         for ( ; iit != ignored.end(); ++iit ) {
  999             cout << *iit << endl;
 1000         }
 1001     }
 1002 
 1003     const list< pair<string, string> >& missing = transaction.missing();
 1004     if ( missing.size() ) {
 1005         ++errors;
 1006         cout << endl << "-- Packages not found" << endl;
 1007         list< pair<string, string> >::const_iterator mit = missing.begin();
 1008 
 1009         for ( ; mit != missing.end(); ++mit ) {
 1010             cout << mit->first;
 1011             if ( mit->second != "" ) {
 1012                 cout << " from " << mit->second;
 1013             }
 1014             cout << endl;
 1015         }
 1016     }
 1017 
 1018     const list< pair<string, InstallTransaction::InstallInfo> >& error =
 1019         transaction.installError();
 1020     if ( error.size() ) {
 1021         ++errors;
 1022         cout << endl << "-- Packages where "
 1023              << command[0] << " failed" << endl;
 1024         list< pair<string, InstallTransaction::InstallInfo> >::const_iterator
 1025             eit = error.begin();
 1026 
 1027         for ( ; eit != error.end(); ++eit ) {
 1028             cout << eit->first;
 1029             reportPrePost(eit->second);
 1030             cout << endl;
 1031         }
 1032     }
 1033 
 1034     const list<string>& already = transaction.alreadyInstalledPackages();
 1035     if ( already.size() ) {
 1036         cout << endl << "-- Packages installed before this run (ignored)"
 1037              << endl;
 1038         list<string>::const_iterator ait = already.begin();
 1039 
 1040         bool isAlias;
 1041         string provider;
 1042         for ( ; ait != already.end(); ++ait ) {
 1043             isAlias = false;
 1044             cout << *ait;
 1045             m_pkgDB->isInstalled(*ait, true, &isAlias, &provider);
 1046 
 1047             if (isAlias) {
 1048                 cout << " (provided by " << provider << ")";
 1049             }
 1050             cout << endl;
 1051         }
 1052     }
 1053 
 1054 
 1055     const list< pair<string, InstallTransaction::InstallInfo> >& inst =
 1056         transaction.installedPackages();
 1057     if ( inst.size() ) {
 1058         cout << endl << "-- Packages " << command[1] << endl;
 1059         list< pair<string, InstallTransaction::InstallInfo> >::const_iterator
 1060             iit = inst.begin();
 1061 
 1062         bool atLeastOnePackageHasReadme = false;
 1063 
 1064         for ( ; iit != inst.end(); ++iit ) {
 1065             cout << iit->first;
 1066             if ( iit->second.hasReadme ) {
 1067                 if ( m_config->readmeMode() ==
 1068                      Configuration::COMPACT_README ) {
 1069                     cout << " (README)";
 1070                 }
 1071                 atLeastOnePackageHasReadme = true;
 1072             }
 1073             reportPrePost(iit->second);
 1074             cout << endl;
 1075         }
 1076 
 1077 
 1078         // readme's
 1079         if ( atLeastOnePackageHasReadme ) {
 1080             if ( m_config->readmeMode() == Configuration::VERBOSE_README ) {
 1081                 cout << endl << "-- " << command[1]
 1082                      << " packages with README files:" << endl;
 1083                 iit = inst.begin();
 1084                 for ( ; iit != inst.end(); ++iit ) {
 1085                     if ( iit->second.hasReadme ) {
 1086                         cout << iit->first;
 1087                         cout << endl;
 1088                     }
 1089                 }
 1090             }
 1091         }
 1092     }
 1093     if ( m_undefinedVersionComp.size() ) {
 1094         cout << endl
 1095              << "-- Packages with undecidable version "
 1096              << "difference (use --strict-diff)"
 1097              << endl;
 1098         list< pair<const Package*, string> >::const_iterator uit =
 1099             m_undefinedVersionComp.begin();
 1100         const Package * p;
 1101         for ( ; uit != m_undefinedVersionComp.end(); ++uit ) {
 1102             p = uit->first;
 1103             cout << p->name() << " ("
 1104                  << p->versionReleaseString()
 1105                  << " vs "
 1106                  << uit->second << ")" << endl;
 1107         }
 1108     }
 1109 
 1110     cout << endl;
 1111 
 1112     if ( errors == 0 && !interrupted ) {
 1113         cout << "prt-get: " << command[1] << " successfully" << endl;
 1114     } else {
 1115         m_returnValue = PG_PARTIAL_INSTALL_ERROR;
 1116     }
 1117 }
 1118 
 1119 void PrtGet::reportPrePost(const InstallTransaction::InstallInfo& info) {
 1120     if (info.preState != InstallTransaction::NONEXISTENT) {
 1121         string preString = "failed";
 1122         if (info.preState == InstallTransaction::EXEC_SUCCESS) {
 1123             preString = "ok";
 1124         }
 1125         cout << " [pre: " << preString << "]";
 1126     }
 1127     if ( info.postState != InstallTransaction::NONEXISTENT) {
 1128         string postString = "failed";
 1129         if (info.postState == InstallTransaction::EXEC_SUCCESS){
 1130             postString = "ok";
 1131         }
 1132         cout << " [post: " << postString << "]";
 1133     }
 1134 
 1135 }
 1136 
 1137 /*! create a cache */
 1138 void PrtGet::createCache()
 1139 {
 1140     if ( m_parser->wasCalledAsPrtCached() ) {
 1141         cerr << m_appName << ": Can't create cache from cache. "
 1142              << "Use prt-get instead" << endl;
 1143         m_returnValue = PG_GENERAL_ERROR;
 1144         return;
 1145     }
 1146 
 1147     initRepo();
 1148     if (m_config->cacheFile() != "") {
 1149         m_cacheFile = m_config->cacheFile();
 1150     }
 1151 
 1152     Repository::WriteResult result = m_repo->writeCache( m_cacheFile );
 1153     if ( result == Repository::DIR_ERR ) {
 1154         cerr << "Can't create cache directory " << m_cacheFile << endl;
 1155         m_returnValue = PG_GENERAL_ERROR;
 1156         return;
 1157     }
 1158     if ( result == Repository::FILE_ERR ) {
 1159         cerr << "Can't open cache file " << m_cacheFile << " for writing"
 1160              << endl;
 1161         m_returnValue = PG_GENERAL_ERROR;
 1162         return;
 1163     }
 1164 
 1165 }
 1166 
 1167 /*!
 1168   \return true if v1 is greater than v2
 1169  */
 1170 COMP_RESULT PrtGet::compareVersions( const string& v1, const string& v2 )
 1171 {
 1172     if (v1 == v2) {
 1173         return EQUAL;
 1174     }
 1175 
 1176 
 1177     if (m_parser->preferHigher() ||
 1178         (m_config->preferHigher() && !m_parser->strictDiff())) {
 1179 
 1180         COMP_RESULT result = VersionComparator::compareVersions(v1, v2);
 1181         return result;
 1182     }
 1183 
 1184     if (v1 != v2)
 1185         return GREATER;
 1186     return LESS;
 1187 }
 1188 
 1189 int PrtGet::returnValue() const
 1190 {
 1191     return m_returnValue;
 1192 }
 1193 
 1194 
 1195 /*! print a list of packages available in the repository */
 1196 void PrtGet::printf()
 1197 {
 1198     map<string, string> sortedOutput;
 1199 
 1200     assertExactArgCount(1);
 1201 
 1202     initRepo();
 1203     string filter = "*";
 1204     if ( m_parser->hasFilter() ) {
 1205         filter = m_parser->filter();
 1206     }
 1207     list<Package*> packages;
 1208     m_repo->getMatchingPackages( filter, packages );
 1209     list<Package*>::const_iterator it = packages.begin();
 1210 
 1211     const string formatString = *(m_parser->otherArgs().begin());
 1212     string sortString =
 1213         StringHelper::stripWhiteSpace( m_parser->sortArgs() );
 1214     sortString += "%n"; // make it unique
 1215 
 1216     for ( ; it != packages.end(); ++it ) {
 1217         string output = formatString;
 1218         string sortkey = sortString;
 1219 
 1220         const Package* p = *it;
 1221 
 1222         StringHelper::replaceAll( output, "%n", p->name() );
 1223         StringHelper::replaceAll( output, "%u", p->url() );
 1224         StringHelper::replaceAll( output, "%p", p->path() );
 1225         StringHelper::replaceAll( output, "%v", p->version() );
 1226         StringHelper::replaceAll( output, "%r", p->release() );
 1227         StringHelper::replaceAll( output, "%d", p->description() );
 1228         StringHelper::replaceAll( output, "%e", p->dependencies() );
 1229         StringHelper::replaceAll( output, "%P", p->packager() );
 1230         StringHelper::replaceAll( output, "%M", p->maintainer() );
 1231 
 1232         StringHelper::replaceAll( output, "\\t", "\t" );
 1233         StringHelper::replaceAll( output, "\\n", "\n" );
 1234 
 1235         StringHelper::replaceAll( sortkey, "%n", p->name() );
 1236         StringHelper::replaceAll( sortkey, "%u", p->url() );
 1237         StringHelper::replaceAll( sortkey, "%p", p->path() );
 1238         StringHelper::replaceAll( sortkey, "%v", p->version() );
 1239         StringHelper::replaceAll( sortkey, "%r", p->release() );
 1240         StringHelper::replaceAll( sortkey, "%d", p->description() );
 1241         StringHelper::replaceAll( sortkey, "%e", p->dependencies() );
 1242         StringHelper::replaceAll( sortkey, "%P", p->packager() );
 1243         StringHelper::replaceAll( sortkey, "%M", p->maintainer() );
 1244 
 1245         string isInst = "no";
 1246         if ( m_pkgDB->isInstalled( p->name() ) ) {
 1247             string ip = p->name() + "-" +
 1248                 m_pkgDB->getPackageVersion( p->name() );
 1249             if ( ip == p->name() + "-" + p->versionReleaseString() ) {
 1250                 isInst = "yes";
 1251             } else {
 1252                 isInst = "diff";
 1253             }
 1254         }
 1255         StringHelper::replaceAll( output, "%i", isInst );
 1256         StringHelper::replaceAll( sortkey, "%i", isInst );
 1257 
 1258         string isLocked = m_locker.isLocked( p->name() ) ? "yes" : "no";
 1259         StringHelper::replaceAll( output, "%l", isLocked );
 1260         StringHelper::replaceAll( sortkey, "%l", isLocked );
 1261 
 1262         string hasReadme = p->hasReadme() ? "yes" : "no";
 1263         StringHelper::replaceAll( output, "%R", hasReadme );
 1264         StringHelper::replaceAll( sortkey, "%R", hasReadme );
 1265 
 1266         string hasPreInstall = p->hasPreInstall() ? "yes" : "no";
 1267         StringHelper::replaceAll( output, "%E", hasPreInstall );
 1268         StringHelper::replaceAll( sortkey, "%E", hasPreInstall );
 1269 
 1270         string hasPostInstall = p->hasPostInstall() ? "yes" : "no";
 1271         StringHelper::replaceAll( output, "%O", hasPostInstall );
 1272         StringHelper::replaceAll( sortkey, "%O", hasPostInstall );
 1273 
 1274         sortedOutput[sortkey] = output;
 1275     }
 1276 
 1277     map<string, string>::iterator sortIt = sortedOutput.begin();
 1278     for ( ; sortIt != sortedOutput.end(); ++sortIt ) {
 1279         if ( StringHelper::stripWhiteSpace(sortIt->second).length() > 0) {
 1280             cout << sortIt->second;
 1281         }
 1282     }
 1283 }
 1284 
 1285 void PrtGet::readme()
 1286 {
 1287     assertExactArgCount(1);
 1288 
 1289     initRepo();
 1290     string arg = *(m_parser->otherArgs().begin());
 1291     const Package* p = m_repo->getPackage( arg );
 1292     if ( p ) {
 1293         string file = p->path() + "/" + p->name() + "/README";
 1294         printFile(file);
 1295     } else {
 1296         cerr << "Package '" << arg << "' not found" << endl;
 1297         m_returnValue = PG_GENERAL_ERROR;
 1298         return;
 1299     }
 1300 }
 1301 
 1302 bool PrtGet::printFile(const string& file)
 1303 {
 1304     if (!File::fileExists(file)) {
 1305         return false;
 1306     }
 1307 
 1308     char* pager = getenv("PAGER");
 1309     if (pager) {
 1310         Process proc(pager, file);
 1311         proc.executeShell();
 1312     } else {
 1313         FILE* fp = fopen( file.c_str(), "r" );
 1314         char buf[255];
 1315         if ( fp ) {
 1316             while ( fgets( buf, 255, fp ) ) {
 1317                 cout << buf;
 1318             }
 1319             fclose( fp );
 1320         }
 1321     }
 1322 
 1323     return true;
 1324 }
 1325 
 1326 void PrtGet::printDependent()
 1327 {
 1328     assertExactArgCount(1);
 1329 
 1330     initRepo();
 1331     string arg = *(m_parser->otherArgs().begin());
 1332 
 1333     if (m_parser->printTree()) {
 1334         cout << arg << endl;
 1335         printDependent(arg, 2);
 1336     } else {
 1337         printDependent(arg, 0);
 1338     }
 1339 }
 1340 
 1341 void PrtGet::printDependent(const string& dep, int level)
 1342 {
 1343     map<string, Package*>::const_iterator it = m_repo->packages().begin();
 1344     static map<string, bool> shownMap;
 1345 
 1346     set<const Package*> dependent;
 1347     for ( ; it != m_repo->packages().end(); ++it ) {
 1348 
 1349         // TODO: is the following line needed?
 1350         const Package* p = it->second;
 1351         if ( p && p->dependencies().find( dep ) != string::npos ) {
 1352             list<string> tokens;
 1353             StringHelper::split( p->dependencies(), ',', tokens );
 1354             list<string>::iterator it = find( tokens.begin(),
 1355                                               tokens.end(),
 1356                                               dep );
 1357             if ( it != tokens.end() ) {
 1358                 dependent.insert( p );
 1359             }
 1360         }
 1361     }
 1362 
 1363     // - there are two modes, tree and non-tree recursive mode; in
 1364     // tree mode, packages are shown multiple times, in non tree
 1365     // recursive mode they're only printed the first time; this is not
 1366     // necessarily optimal for rebuilding:
 1367     //
 1368     // a -> b -> d
 1369     //  \     ^
 1370     //   > c /
 1371     //
 1372     // trying to rebuild 'd' before 'c' might possibly fail
 1373     string indent = "";
 1374     if (m_parser->printTree()) {
 1375         for (int i = 0; i < level; ++i) {
 1376             indent += " ";
 1377         }
 1378     }
 1379     set<const Package*>::iterator it2 = dependent.begin();
 1380     for ( ; it2 != dependent.end(); ++it2 ) {
 1381         const Package* p = *it2;
 1382 
 1383         if (m_parser->recursive() && !m_parser->printTree()) {
 1384             if (shownMap[p->name()]) {
 1385                 continue;
 1386             }
 1387             shownMap[p->name()] = true;
 1388         }
 1389 
 1390         if ( m_parser->all() || m_pkgDB->isInstalled( p->name() ) ) {
 1391 
 1392             cout << indent << p->name();
 1393             if ( m_parser->verbose() > 0 ) {
 1394                 cout << " " << p->versionReleaseString();
 1395             }
 1396             if ( m_parser->verbose() > 1 ) {
 1397                 cout << ":  " << p->description();
 1398             }
 1399 
 1400             cout << endl;
 1401 
 1402             if (m_parser->recursive()) {
 1403                 printDependent( p->name(), level+2 );
 1404             }
 1405         }
 1406     }
 1407 }
 1408 
 1409 void PrtGet::listOrphans()
 1410 {
 1411     initRepo();
 1412     map<string, string> installed = m_pkgDB->installedPackages();
 1413     map<string, bool> required;
 1414     map<string, string>::iterator it = installed.begin();
 1415 
 1416     for (; it != installed.end(); ++it) {
 1417         list<string> tokens;
 1418         const Package* p = m_repo->getPackage(it->first);
 1419         if (p) {
 1420             StringHelper::split( p->dependencies(), ',', tokens );
 1421             list<string>::iterator lit = tokens.begin();
 1422             for (; lit != tokens.end(); ++lit) {
 1423                 required[*lit] = true;
 1424             }
 1425         }
 1426     }
 1427 
 1428     // - we could store the package pointer in another map to avoid
 1429     // another getPackage lockup, but it seems better to optimized for
 1430     // memory since it's only used when called with -vv
 1431 
 1432     it = installed.begin();
 1433     for (; it != installed.end(); ++it) {
 1434         if (!required[it->first]) {
 1435             cout << it->first;
 1436             if ( m_parser->verbose() > 0 ) {
 1437                 cout << " " << it->second;
 1438             }
 1439             if ( m_parser->verbose() > 1 ) {
 1440                 const Package* p = m_repo->getPackage(it->first);
 1441                 if (p) {
 1442                     cout << ":  " << p->description();
 1443                 }
 1444             }
 1445             cout << endl;
 1446         }
 1447     }
 1448 }
 1449 
 1450 
 1451 void PrtGet::warnPackageNotFound(InstallTransaction& transaction)
 1452 {
 1453     cerr << "The package '";
 1454     cerr << transaction.missing().begin()->first;
 1455     cerr << "' could not be found: " << endl;
 1456 }
 1457 
 1458 void PrtGet::sysup()
 1459 {
 1460     // TODO: refactor getDifferentPackages from diff/quickdiff
 1461     initRepo();
 1462 
 1463     list<string>* target;
 1464     list<string> packagesToUpdate;
 1465     list<string> sortedList;
 1466 
 1467     const map<string, string>& installed = m_pkgDB->installedPackages();
 1468     map<string, string>::const_iterator it = installed.begin();
 1469     const Package* p = 0;
 1470     COMP_RESULT result;
 1471     for ( ; it != installed.end(); ++it ) {
 1472         if ( !m_locker.isLocked( it->first ) ) {
 1473             p = m_repo->getPackage( it->first );
 1474             if ( p ) {
 1475                 result = compareVersions( p->versionReleaseString(),
 1476                                           it->second );
 1477                 if (result  == GREATER ) {
 1478                     packagesToUpdate.push_back( it->first );
 1479                 } else if (result  == UNDEFINED ) {
 1480                     m_undefinedVersionComp.push_back(make_pair(p, it->second));
 1481                 }
 1482             }
 1483         }
 1484     }
 1485 
 1486     if ( packagesToUpdate.empty() ) {
 1487         cout << "System is up to date" << endl;
 1488         return;
 1489     }
 1490 
 1491     if ( m_parser->nodeps() ) {
 1492         target = &packagesToUpdate;
 1493     } else {
 1494         // sort by dependency
 1495 
 1496         // TODO: refactor code from printDepends
 1497         InstallTransaction depTrans( packagesToUpdate,
 1498                                      m_repo, m_pkgDB, m_config );
 1499         InstallTransaction::InstallResult result = depTrans.calcDependencies();
 1500         if ( result == InstallTransaction::CYCLIC_DEPEND ) {
 1501             cerr << "cyclic dependencies" << endl;
 1502             m_returnValue = PG_GENERAL_ERROR;
 1503             return;
 1504         } else if ( result == InstallTransaction::PACKAGE_NOT_FOUND ) {
 1505             warnPackageNotFound(depTrans);
 1506             m_returnValue = PG_GENERAL_ERROR;
 1507             return;
 1508         }
 1509 
 1510         const list<string>& deps = depTrans.dependencies();
 1511         if ( deps.size() > 0 ) {
 1512             list<string>::const_iterator it = deps.begin();
 1513             for ( ; it != deps.end(); ++it ) {
 1514                 if ( find( packagesToUpdate.begin(),
 1515                            packagesToUpdate.end(), *it ) !=
 1516                      packagesToUpdate.end() ) {;
 1517                      sortedList.push_back( *it );
 1518                 }
 1519             }
 1520         }
 1521 
 1522         target = &sortedList;
 1523     }
 1524 
 1525     InstallTransaction transaction( *target,
 1526                                     m_repo, m_pkgDB, m_config );
 1527     executeTransaction( transaction, true, false );
 1528 }
 1529 
 1530 
 1531 void PrtGet::expandWildcardsPkgDB( const list<char*>& in,
 1532                                    map<string, string>& target )
 1533 {
 1534     list<char*>::const_iterator it = in.begin();
 1535     for ( ; it != in.end(); ++it ) {
 1536         map<string, string> l;
 1537         m_pkgDB->getMatchingPackages( *it, l, m_useRegex );
 1538         map<string, string>::iterator iit = l.begin();
 1539         for ( ; iit != l.end(); ++iit ) {
 1540             target[iit->first] = iit->second;
 1541         }
 1542     }
 1543 }
 1544 
 1545 void PrtGet::expandWildcardsRepo( const list<char*>& in, list<string>& target )
 1546 {
 1547     list<char*>::const_iterator it = in.begin();
 1548 
 1549     for ( ; it != in.end(); ++it ) {
 1550         list<Package*> l;
 1551         m_repo->getMatchingPackages( *it, l );
 1552         list<Package*>::iterator iit = l.begin();
 1553         for ( ; iit != l.end(); ++iit ) {
 1554             target.push_back( (*iit)->name() );
 1555         }
 1556     }
 1557 }
 1558 
 1559 
 1560 void PrtGet::current()
 1561 {
 1562     assertExactArgCount(1);
 1563 
 1564     const map<string, string>& installed = m_pkgDB->installedPackages();
 1565     map<string, string>::const_iterator it = installed.begin();
 1566     string search = *(m_parser->otherArgs().begin());
 1567 
 1568     for ( ; it != installed.end(); ++it ) {
 1569         if ( it->first == search ) {
 1570             cout << it->second.c_str() << endl;
 1571             return;
 1572         }
 1573     }
 1574 
 1575     cout << "Package " << search << " not installed" << endl;
 1576     m_returnValue = 1;
 1577 }
 1578 
 1579 SignalHandler::HandlerResult PrtGet::handleSignal( int signal )
 1580 {
 1581     // TODO: second argument could also be true:
 1582     // TODO: kill installtransaction
 1583 
 1584     cout << "prt-get: interrupted" << endl;
 1585     if ( m_currentTransaction ) {
 1586         evaluateResult( *m_currentTransaction, false, true );
 1587     }
 1588 }
 1589 
 1590 /*!
 1591   find files matching a pattern in repository
 1592 
 1593   \sa Repository::getMatchingPackages()
 1594 */
 1595 void PrtGet::fsearch()
 1596 {
 1597     assertMinArgCount(1);
 1598 
 1599     string arg = "*";
 1600     if ( m_parser->otherArgs().size() == 1 ) {
 1601         arg = *(m_parser->otherArgs().begin());
 1602     }
 1603 
 1604     initRepo();
 1605     const map<string, Package*>& packages = m_repo->packages();
 1606     map<string, Package*>::const_iterator it = packages.begin();
 1607     bool first = true;
 1608     for ( ; it != packages.end(); ++it ) {
 1609         list<string> matches;
 1610         string fp =
 1611             it->second->path() + "/" +
 1612             it->second->name() + "/" + ".footprint";
 1613         if ( File::grep( fp, arg, matches,
 1614                          m_parser->fullPath(),
 1615                          m_useRegex)) {
 1616             if ( matches.size() > 0 ) {
 1617                 if ( first ) {
 1618                     first = false;
 1619                 } else {
 1620                     cout << endl;
 1621                 }
 1622                 cout << "Found in "
 1623                      << it->second->path() << "/"
 1624                      << it->first << ":" << endl;
 1625                 list<string>::iterator it = matches.begin();
 1626                 for ( ; it != matches.end(); ++it ) {
 1627                     cout << "  " << *it << endl;
 1628                 }
 1629             }
 1630         }
 1631     }
 1632 
 1633     if ( first ) {
 1634         m_returnValue = PG_GENERAL_ERROR;
 1635     }
 1636 }
 1637 
 1638 void PrtGet::setLock( bool lock )
 1639 {
 1640     assertMinArgCount(1);
 1641 
 1642     if ( lock ) {
 1643         initRepo();
 1644     }
 1645 
 1646     const list<char*>& args = m_parser->otherArgs();
 1647     list<char*>::const_iterator it = args.begin();
 1648     for ( ; it != args.end(); ++it ) {
 1649         if ( lock ) {
 1650             if (m_pkgDB->isInstalled( *it )) {
 1651                 if (!m_locker.lock( *it )) {
 1652                     cerr << "Already locked: " << *it << endl;
 1653                     m_returnValue = PG_GENERAL_ERROR;
 1654                 }
 1655             } else {
 1656                 cerr << "Package '" << *it << "' not found" << endl;
 1657                 m_returnValue = PG_GENERAL_ERROR;
 1658                 return;
 1659             }
 1660 
 1661         } else {
 1662             if ( !m_locker.unlock( *it ) ) {
 1663                 cerr << "Not locked previously: " << *it << endl;
 1664                 m_returnValue = PG_GENERAL_ERROR;
 1665                 return;
 1666             }
 1667         }
 1668     }
 1669 								
 1670     if (!m_locker.store()) {
 1671         cerr << "Failed to write lock data" << endl;
 1672         m_returnValue = PG_GENERAL_ERROR;
 1673     }
 1674 }
 1675 
 1676 void PrtGet::listLocked()
 1677 {
 1678     // shares some code with listInstalled
 1679     if ( m_locker.openFailed() ) {
 1680         cerr << "Failed to open lock data file" << endl;
 1681         m_returnValue = PG_GENERAL_ERROR;
 1682     }
 1683 
 1684     const map<string, string>& l = m_pkgDB->installedPackages();
 1685 
 1686     if ( l.empty() ) {
 1687         return;
 1688     }
 1689 
 1690     if ( m_parser->verbose() > 1 ) {
 1691         // warning: will slow down the process...
 1692         initRepo();
 1693     }
 1694 
 1695 
 1696     const vector<string>& lockedPackages = m_locker.lockedPackages();
 1697     vector<string>::const_iterator it = lockedPackages.begin();
 1698     for ( ; it != lockedPackages.end(); ++it ) {
 1699         cout << *it;
 1700         if ( m_parser->verbose() > 0 ) {
 1701             cout << " " << m_pkgDB->getPackageVersion(*it);
 1702         }
 1703         if ( m_parser->verbose() > 1 ) {
 1704             const Package* p = m_repo->getPackage( *it );
 1705             if ( p ) {
 1706                 cout << ": " << p->description();
 1707             }
 1708         }
 1709 
 1710         cout << endl;
 1711 
 1712     }
 1713 }
 1714 
 1715 
 1716 void PrtGet::edit()
 1717 {
 1718     assertMinArgCount(1);
 1719     assertMaxArgCount(2);
 1720 
 1721     char* editor = getenv("EDITOR");
 1722     if (editor) {
 1723         initRepo();
 1724 
 1725         list<char*>::const_iterator it = m_parser->otherArgs().begin();
 1726         string arg = *it;
 1727         const Package* p = m_repo->getPackage( arg );
 1728         if ( p ) {
 1729             string fileName = "Pkgfile";
 1730             if (++it != m_parser->otherArgs().end()) {
 1731                 fileName = *it;
 1732             }
 1733             string file = p->path() + "/" + p->name() + "/" + fileName;
 1734             Process proc(editor, file);
 1735             m_returnValue = proc.executeShell();
 1736             if (m_returnValue) {
 1737                 cerr << "error while execution the editor" << endl;
 1738             }
 1739         } else {
 1740             cerr << "Package '" << arg << "' not found" << endl;
 1741             m_returnValue = PG_GENERAL_ERROR;
 1742             return;
 1743         }
 1744 
 1745     } else {
 1746         cerr << "Environment variable EDITOR not set" << endl;;
 1747         m_returnValue = PG_GENERAL_ERROR;
 1748         return;
 1749     }
 1750 
 1751 }
 1752 
 1753 void PrtGet::ls()
 1754 {
 1755     assertExactArgCount(1);
 1756 
 1757     initRepo();
 1758 
 1759     list<char*>::const_iterator it = m_parser->otherArgs().begin();
 1760     string arg = *it;
 1761     const Package* p = m_repo->getPackage( arg );
 1762     if ( p ) {
 1763         string dirname = p->path() + "/" + p->name();
 1764         DIR* dir = opendir(dirname.c_str());
 1765         struct dirent* entry;
 1766         vector<string> files;
 1767         while (entry = readdir(dir)) {
 1768             string dName = entry->d_name;
 1769             if (dName != "." && dName != "..") {
 1770                 files.push_back(dName);
 1771             }
 1772         }
 1773         closedir(dir);
 1774 
 1775         sort(files.begin(), files.end());
 1776         vector<string>::iterator fit = files.begin();
 1777         for (; fit != files.end(); ++fit) {
 1778             if (m_parser->printPath()) {
 1779                 cout << p->path() + "/" +p->name() + "/";
 1780             }
 1781             cout << *fit << endl;
 1782         }
 1783     } else {
 1784         cerr << "Package '" << arg << "' not found" << endl;
 1785         m_returnValue = PG_GENERAL_ERROR;
 1786         return;
 1787     }
 1788 }
 1789 
 1790 void PrtGet::cat()
 1791 {
 1792     assertMinArgCount(1);
 1793     assertMaxArgCount(2);
 1794 
 1795     initRepo();
 1796 
 1797     list<char*>::const_iterator it = m_parser->otherArgs().begin();
 1798     string arg = *it;
 1799     const Package* p = m_repo->getPackage( arg );
 1800     if ( p ) {
 1801         string fileName = "Pkgfile";
 1802         if (++it != m_parser->otherArgs().end()) {
 1803             fileName = *it;
 1804         }
 1805         string file = p->path() + "/" + p->name() + "/" + fileName;
 1806         if (!printFile(file)) {
 1807             cerr << "File '" << *it << "' not found" << endl;
 1808             m_returnValue = PG_GENERAL_ERROR;
 1809             return;
 1810         }
 1811     } else {
 1812         cerr << "Package '" << arg << "' not found" << endl;
 1813         m_returnValue = PG_GENERAL_ERROR;
 1814         return;
 1815     }
 1816 }
 1817 
 1818 void PrtGet::remove()
 1819 {
 1820     assertMinArgCount(1);
 1821 
 1822     list<string> removed;
 1823     list<string> failed;
 1824     list<string> notInstalled;
 1825 
 1826     if ( m_parser->isTest() ) {
 1827         cout << "*** " << m_appName << ": test mode" << endl;
 1828     }
 1829 
 1830     string command = InstallTransaction::PKGRM_DEFAULT_COMMAND;
 1831     if (m_config->removeCommand() != "") {
 1832         command = m_config->removeCommand();
 1833     }
 1834 
 1835     const list<char*>& args = m_parser->otherArgs();
 1836     list<char*>::const_iterator it = args.begin();
 1837     for ( ; it != args.end(); ++it ) {
 1838         if (m_pkgDB->isInstalled(*it)) {
 1839             // TODO: prettify
 1840             string args = "";
 1841             if (m_parser->installRoot() != "") {
 1842                 args = "-r " + m_parser->installRoot() + " ";
 1843             }
 1844             args += (m_parser->pkgrmArgs() + " " + *it);
 1845 
 1846             Process proc(command, args);
 1847             if (m_parser->isTest() || proc.executeShell() == 0) {
 1848                 removed.push_back(*it);
 1849                 if (m_locker.isLocked(*it)) {
 1850                     m_locker.unlock(*it);
 1851                     m_locker.store();
 1852                 }
 1853             } else {
 1854                 failed.push_back(*it);
 1855             }
 1856         } else {
 1857             notInstalled.push_back(*it);
 1858         }
 1859     }
 1860 
 1861     if ( removed.size() ) {
 1862         cout << endl << "-- Packages removed"
 1863              << endl;
 1864         list<string>::const_iterator it = removed.begin();
 1865 
 1866         for ( ; it != removed.end(); ++it ) {
 1867             cout << *it << endl;
 1868         }
 1869     }
 1870 
 1871     if ( failed.size() ) {
 1872         cout << endl << "-- Packages where removal failed"
 1873              << endl;
 1874         list<string>::const_iterator it = failed.begin();
 1875 
 1876         for ( ; it != failed.end(); ++it ) {
 1877             cout << *it << endl;
 1878         }
 1879     }
 1880 
 1881     if ( notInstalled.size() ) {
 1882         cout << endl << "-- Packages which were not installed"
 1883              << endl;
 1884         list<string>::const_iterator it = notInstalled.begin();
 1885 
 1886         for ( ; it != notInstalled.end(); ++it ) {
 1887             cout << *it << endl;
 1888         }
 1889     }
 1890 
 1891     if ( m_parser->isTest() ) {
 1892         cout << "*** " << m_appName << ": test mode end" << endl;
 1893     }
 1894 
 1895 
 1896 
 1897 }
 1898 
 1899 void PrtGet::assertMaxArgCount(int count)
 1900 {
 1901     if ( m_parser->otherArgs().size() > count ) {
 1902         argCountFailure(count, "at most");
 1903     }
 1904 }
 1905 
 1906 void PrtGet::assertExactArgCount(int count)
 1907 {
 1908     if ( m_parser->otherArgs().size() != count ) {
 1909         argCountFailure(count, "exactly");
 1910     }
 1911 }
 1912 
 1913 void PrtGet::assertMinArgCount(int count)
 1914 {
 1915      if ( m_parser->otherArgs().size() < count ) {
 1916          argCountFailure(count, "at least");
 1917      }
 1918 }
 1919 
 1920 void PrtGet::argCountFailure(int count, const string& specifier)
 1921 {
 1922     cerr << m_appName << " "
 1923          << m_parser->commandName() << " takes " << specifier << " "
 1924          << count << (count > 1 ? " arguments" : " argument") << endl;
 1925     exit(PG_ARG_ERROR);
 1926 }
 1927 
 1928 
 1929 void PrtGet::printDependTree()
 1930 {
 1931     assertExactArgCount(1);
 1932 
 1933     initRepo();
 1934 
 1935     list<char*>::const_iterator it = m_parser->otherArgs().begin();
 1936     string arg = *it;
 1937     const Package* p = m_repo->getPackage( arg );
 1938     if (!p) {
 1939         cerr << "Package '" << arg << "' not found" << endl;
 1940         m_returnValue = PG_GENERAL_ERROR;
 1941         return;
 1942     }
 1943 
 1944     if (p->dependencies().length() > 0) {
 1945 
 1946         cout << "-- dependencies ([i] = installed";
 1947         if (!m_parser->all()) {
 1948             cout << ", '-->' = seen before";
 1949         }
 1950         cout << ")" << endl;
 1951         if ( m_pkgDB->isInstalled( *it ) ) {
 1952             cout << "[i] ";
 1953         } else {
 1954             cout << "[ ] ";
 1955         }
 1956         cout << p->name() << endl;
 1957         printDepsLevel(2, p);
 1958     }
 1959 
 1960 }
 1961 
 1962 void PrtGet::printDepsLevel(int indent, const Package* package)
 1963 {
 1964     static map<string, bool> shownMap;
 1965 
 1966     list<string> deps;
 1967     StringHelper::split(package->dependencies(), ',', deps);
 1968     list<string>::iterator it = deps.begin();
 1969     bool isAlias = false;
 1970     string aliasName = "";
 1971 
 1972     for (; it != deps.end(); ++it) {
 1973         if ( m_pkgDB->isInstalled( *it, true, &isAlias, &aliasName ) ) {
 1974             cout << "[i] ";
 1975         } else {
 1976             cout << "[ ] ";
 1977         }
 1978         for (int i = 0; i < indent; ++i) {
 1979             cout << " ";
 1980         }
 1981         cout << *it;
 1982         if (isAlias) {
 1983             cout << " (provided by " << aliasName << ")";
 1984         }
 1985         const Package* p = m_repo->getPackage( *it );
 1986         if (p) {
 1987             if (p->dependencies().length() > 0) {
 1988                 map<string, bool>::iterator shownIt = shownMap.find(*it);
 1989                 if (shownIt != shownMap.end()) {
 1990                     cout << " -->" << endl;;
 1991                 } else {
 1992                     cout << endl;
 1993                     printDepsLevel(indent+2, p);
 1994                     if (!m_parser->all()) {
 1995                         shownMap[*it] = true;
 1996                     }
 1997                 }
 1998             } else {
 1999                 cout << endl;
 2000             }
 2001         } else {
 2002             cout << " (not found in ports tree)" << endl;
 2003         }
 2004     }
 2005 }
 2006 
 2007 void PrtGet::dumpConfig()
 2008 {
 2009 
 2010     cout.setf( ios::left, ios::adjustfield );
 2011     cout.width( 20 );
 2012     cout.fill( ' ' );
 2013     cout << "Alias file: " << PkgDB::ALIAS_STORE << endl;
 2014 
 2015     cout.setf( ios::left, ios::adjustfield );
 2016     cout.width( 20 );
 2017     cout.fill( ' ' );
 2018     cout << "Ext. dep. file: "
 2019          << Repository::EXTERNAL_DEPENDENCY_FILE << endl;
 2020 
 2021 
 2022     if (!m_parser->noStdConfig()) {
 2023         string fName = CONF_FILE;
 2024         if ( m_parser->isAlternateConfigGiven() ) {
 2025             fName = m_parser->alternateConfigFile();
 2026         }
 2027         cout.setf( ios::left, ios::adjustfield );
 2028         cout.width( 20 );
 2029         cout.fill( ' ' );
 2030         cout << "Configuration file: " << fName << endl;
 2031     }
 2032 
 2033     if (m_config->cacheFile() != "") {
 2034         cout.setf( ios::left, ios::adjustfield );
 2035         cout.width( 20 );
 2036         cout.fill( ' ' );
 2037         cout << "Cache file: " << m_config->cacheFile() << endl;
 2038     }
 2039     if (m_config->makeCommand() != "") {
 2040         cout.setf( ios::left, ios::adjustfield );
 2041         cout.width( 20 );
 2042         cout.fill( ' ' );
 2043         cout << "Make command file: " << m_config->makeCommand() << endl;
 2044     }
 2045     if (m_config->addCommand() != "") {
 2046         cout.setf( ios::left, ios::adjustfield );
 2047         cout.width( 20 );
 2048         cout.fill( ' ' );
 2049         cout << "Add command: " << m_config->addCommand() << endl;
 2050     }
 2051     if (m_config->removeCommand() != "") {
 2052         cout.setf( ios::left, ios::adjustfield );
 2053         cout.width( 20 );
 2054         cout.fill( ' ' );
 2055         cout << "Remove command: " << m_config->removeCommand() << endl;
 2056     }
 2057     if (m_config->runscriptCommand() != "") {
 2058         cout.setf( ios::left, ios::adjustfield );
 2059         cout.width( 20 );
 2060         cout.fill( ' ' );
 2061         cout << "Runscript command: " << m_config->runscriptCommand() << endl;
 2062     }
 2063 
 2064     cout.setf( ios::left, ios::adjustfield );
 2065     cout.width( 20 );
 2066     cout.fill( ' ' );
 2067     cout << "Run scripts: " <<(m_config->runScripts() ? "yes" : "no" )
 2068          << endl;
 2069 
 2070     cout.setf( ios::left, ios::adjustfield );
 2071     cout.width( 20 );
 2072     cout.fill( ' ' );
 2073     cout << "Keep higher version:" <<(m_config->preferHigher() ? "yes" : "no" )
 2074          << endl;
 2075 
 2076     cout.setf( ios::left, ios::adjustfield );
 2077     cout.width( 20 );
 2078     cout.fill( ' ' );
 2079     cout << "Readme mode:  ";
 2080     switch (m_config->readmeMode()) {
 2081         case Configuration::VERBOSE_README:
 2082             cout << "verbose";
 2083             break;
 2084         case Configuration::COMPACT_README:
 2085             cout << "compact";
 2086             break;
 2087         case Configuration::NO_README:
 2088             cout << "off";
 2089             break;
 2090     }
 2091     cout << endl;
 2092 
 2093     cout << endl;
 2094 
 2095     if (m_config->logFilePattern() != "") {
 2096         cout.setf( ios::left, ios::adjustfield );
 2097         cout.width( 20 );
 2098         cout.fill( ' ' );
 2099         cout << "Log file: " << m_config->logFilePattern() << endl;
 2100     }
 2101     cout.setf( ios::left, ios::adjustfield );
 2102     cout.width( 20 );
 2103     cout.fill( ' ' );
 2104     cout << "  Write log: " << (m_config->writeLog() ? "yes" : "no" ) << endl;
 2105     cout.setf( ios::left, ios::adjustfield );
 2106     cout.width( 20 );
 2107     cout.fill( ' ' );
 2108     cout << "  Append log: " <<(m_config->appendLog() ? "yes" : "no" ) << endl;
 2109 
 2110 
 2111 
 2112     cout << endl;
 2113     list< pair<string, string> >::const_iterator it =
 2114         m_config->rootList().begin();
 2115     cout << "Port "
 2116          << (m_config->rootList().size() == 1 ? "directory" : "directories")
 2117          << ": " << endl;
 2118     for (; it != m_config->rootList().end(); ++it) {
 2119         cout << " " << it->first;
 2120         if (it->second != "") {
 2121             cout << " (" << it->second << ")";
 2122         }
 2123         cout << endl;
 2124     }
 2125 }

Generated by cgit