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

Generated by cgit