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

Generated by cgit