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

Generated by cgit