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

Generated by cgit