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

Generated by cgit