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

Generated by cgit