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

Generated by cgit