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

Generated by cgit