Support solver option cleandepsOnRemove: Cleanup when deleting packages
[platform/upstream/libzypp.git] / zypp / ZConfig.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ZConfig.cc
10  *
11 */
12 extern "C"
13 {
14 #include <sys/utsname.h>
15 #include <unistd.h>
16 #include <satsolver/satversion.h>
17 }
18 #include <iostream>
19 #include <fstream>
20 #include "zypp/base/Logger.h"
21 #include "zypp/base/IOStream.h"
22 #include "zypp/base/InputStream.h"
23 #include "zypp/base/String.h"
24
25 #include "zypp/ZConfig.h"
26 #include "zypp/ZYppFactory.h"
27 #include "zypp/PathInfo.h"
28 #include "zypp/parser/IniDict.h"
29
30 #include "zypp/sat/Pool.h"
31
32 using namespace std;
33 using namespace zypp::filesystem;
34 using namespace zypp::parser;
35
36 #undef ZYPP_BASE_LOGGER_LOGGROUP
37 #define ZYPP_BASE_LOGGER_LOGGROUP "zconfig"
38
39 ///////////////////////////////////////////////////////////////////
40 namespace zypp
41 { /////////////////////////////////////////////////////////////////
42
43   ///////////////////////////////////////////////////////////////////
44   namespace
45   { /////////////////////////////////////////////////////////////////
46
47     /** Determine system architecture evaluating \c uname and \c /proc/cpuinfo.
48     */
49     Arch _autodetectSystemArchitecture()
50     {
51       struct ::utsname buf;
52       if ( ::uname( &buf ) < 0 )
53       {
54         ERR << "Can't determine system architecture" << endl;
55         return Arch_noarch;
56       }
57
58       Arch architecture( buf.machine );
59       MIL << "Uname architecture is '" << buf.machine << "'" << endl;
60
61       // some CPUs report i686 but dont implement cx8 and cmov
62       // check for both flags in /proc/cpuinfo and downgrade
63       // to i586 if either is missing (cf bug #18885)
64       if ( architecture == Arch_i686 )
65       {
66         std::ifstream cpuinfo( "/proc/cpuinfo" );
67         if ( cpuinfo )
68         {
69           for( iostr::EachLine in( cpuinfo ); in; in.next() )
70           {
71             if ( str::hasPrefix( *in, "flags" ) )
72             {
73               if (    in->find( "cx8" ) == std::string::npos
74                    || in->find( "cmov" ) == std::string::npos )
75               {
76                 architecture = Arch_i586;
77                 WAR << "CPU lacks 'cx8' or 'cmov': architecture downgraded to '" << architecture << "'" << endl;
78               }
79               break;
80             }
81           }
82         }
83         else
84         {
85           ERR << "Cant open " << PathInfo("/proc/cpuinfo") << endl;
86         }
87       }
88       return architecture;
89     }
90
91      /** The locale to be used for texts and messages.
92      *
93      * For the encoding to be used the preference is
94      *
95      *    LC_ALL, LC_CTYPE, LANG
96      *
97      * For the language of the messages to be used, the preference is
98      *
99      *    LANGUAGE, LC_ALL, LC_MESSAGES, LANG
100      *
101      * Note that LANGUAGE can contain more than one locale name, it can be
102      * a list of locale names like for example
103      *
104      *    LANGUAGE=ja_JP.UTF-8:de_DE.UTF-8:fr_FR.UTF-8
105
106      * \todo Support dynamic fallbacklists defined by LANGUAGE
107      */
108     Locale _autodetectTextLocale()
109     {
110       Locale ret( "en" );
111       const char * envlist[] = { "LC_ALL", "LC_MESSAGES", "LANG", NULL };
112       for ( const char ** envvar = envlist; *envvar; ++envvar )
113       {
114         const char * envlang = getenv( *envvar );
115         if ( envlang )
116         {
117           std::string envstr( envlang );
118           if ( envstr != "POSIX" && envstr != "C" )
119           {
120             Locale lang( envstr );
121             if ( ! lang.code().empty() )
122             {
123               MIL << "Found " << *envvar << "=" << envstr << endl;
124               ret = lang;
125               break;
126             }
127           }
128         }
129       }
130       MIL << "Default text locale is '" << ret << "'" << endl;
131 #warning HACK AROUND BOOST_TEST_CATCH_SYSTEM_ERRORS
132       setenv( "BOOST_TEST_CATCH_SYSTEM_ERRORS", "no", 1 );
133       return ret;
134     }
135
136    /////////////////////////////////////////////////////////////////
137   } // namespace zypp
138   ///////////////////////////////////////////////////////////////////
139
140   /** Mutable option. */
141   template<class _Tp>
142       struct Option
143       {
144         typedef _Tp value_type;
145
146         /** No default ctor, explicit initialisation! */
147         Option( const value_type & initial_r )
148           : _val( initial_r )
149         {}
150
151         /** Get the value.  */
152         const value_type & get() const
153         { return _val; }
154
155         /** Autoconversion to value_type.  */
156         operator const value_type &() const
157         { return _val; }
158
159         /** Set a new value.  */
160         void set( const value_type & newval_r )
161         { _val = newval_r; }
162
163         /** Non-const reference to set a new value. */
164         value_type & ref()
165         { return _val; }
166
167         private:
168           value_type _val;
169       };
170
171   /** Mutable option with initial value also remembering a config value. */
172   template<class _Tp>
173       struct DefaultOption : public Option<_Tp>
174       {
175         typedef _Tp         value_type;
176         typedef Option<_Tp> option_type;
177
178         DefaultOption( const value_type & initial_r )
179           : Option<_Tp>( initial_r ), _default( initial_r )
180         {}
181
182         /** Reset value to the current default. */
183         void restoreToDefault()
184         { this->set( _default.get() ); }
185
186         /** Reset value to a new default. */
187         void restoreToDefault( const value_type & newval_r )
188         { setDefault( newval_r ); restoreToDefault(); }
189
190         /** Get the current default value. */
191         const value_type & getDefault() const
192         { return _default.get(); }
193
194         /** Set a new default value. */
195         void setDefault( const value_type & newval_r )
196         { _default.set( newval_r ); }
197
198         private:
199           option_type _default;
200       };
201
202   ///////////////////////////////////////////////////////////////////
203   //
204   //    CLASS NAME : ZConfig::Impl
205   //
206   /** ZConfig implementation.
207    * \todo Enrich section and entry definition by some comment
208    * (including the default setting and provide some method to
209    * write this into a sample zypp.conf.
210   */
211   class ZConfig::Impl
212   {
213     public:
214       Impl( const Pathname & override_r = Pathname() )
215         : _parsedZyppConf               ( override_r )
216         , cfg_arch                      ( defaultSystemArchitecture() )
217         , cfg_textLocale                ( defaultTextLocale() )
218         , updateMessagesNotify          ( "single | /usr/lib/zypp/notify-message -p %p" )
219         , repo_add_probe                ( false )
220         , repo_refresh_delay            ( 10 )
221         , repoLabelIsAlias              ( false )
222         , download_use_deltarpm         ( true )
223         , download_use_deltarpm_always  ( false )
224         , download_media_prefer_download( true )
225         , download_max_concurrent_connections( 2 )
226         , download_min_download_speed   ( 0 )
227         , download_max_download_speed   ( 0 )
228         , download_max_silent_tries     ( 5 )
229         , commit_downloadMode           ( DownloadDefault )
230         , solver_onlyRequires           ( false )
231         , solver_allowVendorChange      ( false )
232         , solver_cleandepsOnRemove      ( false )
233         , solver_upgradeTestcasesToKeep ( 2 )
234         , solverUpgradeRemoveDroppedPackages( true )
235         , apply_locks_file              ( true )
236
237       {
238         MIL << "libzypp: " << VERSION << " built " << __DATE__ << " " <<  __TIME__ << endl;
239         // override_r has higest prio
240         // ZYPP_CONF might override /etc/zypp/zypp.conf
241         if ( _parsedZyppConf.empty() )
242         {
243           const char *env_confpath = getenv( "ZYPP_CONF" );
244           _parsedZyppConf = env_confpath ? env_confpath : "/etc/zypp/zypp.conf";
245         }
246         else
247         {
248           // Inject this into ZConfig. Be shure this is
249           // allocated via new. See: reconfigureZConfig
250           INT << "Reconfigure to " << _parsedZyppConf << endl;
251           ZConfig::instance()._pimpl.reset( this );
252         }
253         if ( PathInfo(_parsedZyppConf).isExist() )
254         {
255           parser::IniDict dict( _parsedZyppConf );
256           for ( IniDict::section_const_iterator sit = dict.sectionsBegin();
257                 sit != dict.sectionsEnd();
258                 ++sit )
259           {
260             string section(*sit);
261             //MIL << section << endl;
262             for ( IniDict::entry_const_iterator it = dict.entriesBegin(*sit);
263                   it != dict.entriesEnd(*sit);
264                   ++it )
265             {
266               string entry(it->first);
267               string value(it->second);
268               //DBG << (*it).first << "=" << (*it).second << endl;
269               if ( section == "main" )
270               {
271                 if ( entry == "arch" )
272                 {
273                   Arch carch( value );
274                   if ( carch != cfg_arch )
275                   {
276                     WAR << "Overriding system architecture (" << cfg_arch << "): " << carch << endl;
277                     cfg_arch = carch;
278                   }
279                 }
280                 else if ( entry == "cachedir" )
281                 {
282                   cfg_cache_path = Pathname(value);
283                 }
284                 else if ( entry == "metadatadir" )
285                 {
286                   cfg_metadata_path = Pathname(value);
287                 }
288                 else if ( entry == "solvfilesdir" )
289                 {
290                   cfg_solvfiles_path = Pathname(value);
291                 }
292                 else if ( entry == "packagesdir" )
293                 {
294                   cfg_packages_path = Pathname(value);
295                 }
296                 else if ( entry == "configdir" )
297                 {
298                   cfg_config_path = Pathname(value);
299                 }
300                 else if ( entry == "reposdir" )
301                 {
302                   cfg_known_repos_path = Pathname(value);
303                 }
304                 else if ( entry == "servicesdir" )
305                 {
306                   cfg_known_services_path = Pathname(value);
307                 }
308                 else if ( entry == "repo.add.probe" )
309                 {
310                   repo_add_probe = str::strToBool( value, repo_add_probe );
311                 }
312                 else if ( entry == "repo.refresh.delay" )
313                 {
314                   str::strtonum(value, repo_refresh_delay);
315                 }
316                 else if ( entry == "download.use_deltarpm" )
317                 {
318                   download_use_deltarpm = str::strToBool( value, download_use_deltarpm );
319                 }
320                 else if ( entry == "download.use_deltarpm.always" )
321                 {
322                   download_use_deltarpm_always = str::strToBool( value, download_use_deltarpm_always );
323                 }
324                 else if ( entry == "download.media_preference" )
325                 {
326                   download_media_prefer_download.restoreToDefault( str::compareCI( value, "volatile" ) != 0 );
327                 }
328                 else if ( entry == "download.max_concurrent_connections" )
329                 {
330                   str::strtonum(value, download_max_concurrent_connections);
331                 }
332                 else if ( entry == "download.min_download_speed" )
333                 {
334                   str::strtonum(value, download_min_download_speed);
335                 }
336                 else if ( entry == "download.max_download_speed" )
337                 {
338                   str::strtonum(value, download_max_download_speed);
339                 }
340                 else if ( entry == "download.max_silent_tries" )
341                 {
342                   str::strtonum(value, download_max_silent_tries);
343                 }
344                 else if ( entry == "commit.downloadMode" )
345                 {
346                   commit_downloadMode.set( deserializeDownloadMode( value ) );
347                 }
348                 else if ( entry == "vendordir" )
349                 {
350                   cfg_vendor_path = Pathname(value);
351                 }
352                 else if ( entry == "solver.onlyRequires" )
353                 {
354                   solver_onlyRequires.set( str::strToBool( value, solver_onlyRequires ) );
355                 }
356                 else if ( entry == "solver.allowVendorChange" )
357                 {
358                   solver_allowVendorChange.set( str::strToBool( value, solver_allowVendorChange ) );
359                 }
360                 else if ( entry == "solver.cleandepsOnRemove" )
361                 {
362                   solver_cleandepsOnRemove.set( str::strToBool( value, solver_cleandepsOnRemove ) );
363                 }
364                 else if ( entry == "solver.upgradeTestcasesToKeep" )
365                 {
366                   solver_upgradeTestcasesToKeep.set( str::strtonum<unsigned>( value ) );
367                 }
368                 else if ( entry == "solver.upgradeRemoveDroppedPackages" )
369                 {
370                   solverUpgradeRemoveDroppedPackages.restoreToDefault( str::strToBool( value, solverUpgradeRemoveDroppedPackages.getDefault() ) );
371                 }
372                 else if ( entry == "solver.checkSystemFile" )
373                 {
374                   solver_checkSystemFile = Pathname(value);
375                 }
376                 else if ( entry == "multiversion" )
377                 {
378                   str::split( value, inserter( multiversion, multiversion.end() ), ", \t" );
379                 }
380                 else if ( entry == "locksfile.path" )
381                 {
382                   locks_file = Pathname(value);
383                 }
384                 else if ( entry == "locksfile.apply" )
385                 {
386                   apply_locks_file = str::strToBool( value, apply_locks_file );
387                 }
388                 else if ( entry == "update.datadir" )
389                 {
390                   update_data_path = Pathname(value);
391                 }
392                 else if ( entry == "update.scriptsdir" )
393                 {
394                   update_scripts_path = Pathname(value);
395                 }
396                 else if ( entry == "update.messagessdir" )
397                 {
398                   update_messages_path = Pathname(value);
399                 }
400                 else if ( entry == "update.messages.notify" )
401                 {
402                   updateMessagesNotify.set( value );
403                 }
404                 else if ( entry == "rpm.install.excludedocs" )
405                 {
406                   rpmInstallFlags.setFlag( target::rpm::RPMINST_EXCLUDEDOCS,
407                                            str::strToBool( value, false ) );
408                 }
409                 else if ( entry == "history.logfile" )
410                 {
411                   history_log_path = Pathname(value);
412                 }
413                 else if ( entry == "credentials.global.dir" )
414                 {
415                   credentials_global_dir_path = Pathname(value);
416                 }
417                 else if ( entry == "credentials.global.file" )
418                 {
419                   credentials_global_file_path = Pathname(value);
420                 }
421               }
422             }
423           }
424         }
425         else
426         {
427           MIL << _parsedZyppConf << " not found, using defaults instead." << endl;
428           _parsedZyppConf = _parsedZyppConf.extend( " (NOT FOUND)" );
429         }
430
431         // legacy:
432         if ( getenv( "ZYPP_TESTSUITE_FAKE_ARCH" ) )
433         {
434           Arch carch( getenv( "ZYPP_TESTSUITE_FAKE_ARCH" ) );
435           if ( carch != cfg_arch )
436           {
437             WAR << "ZYPP_TESTSUITE_FAKE_ARCH: Overriding system architecture (" << cfg_arch << "): " << carch << endl;
438             cfg_arch = carch;
439           }
440         }
441         MIL << "ZConfig singleton created." << endl;
442       }
443
444       ~Impl()
445       {}
446
447     public:
448     /** Remember any parsed zypp.conf. */
449     Pathname _parsedZyppConf;
450
451     Arch     cfg_arch;
452     Locale   cfg_textLocale;
453
454     Pathname cfg_cache_path;
455     Pathname cfg_metadata_path;
456     Pathname cfg_solvfiles_path;
457     Pathname cfg_packages_path;
458
459     Pathname cfg_config_path;
460     Pathname cfg_known_repos_path;
461     Pathname cfg_known_services_path;
462     Pathname cfg_vendor_path;
463     Pathname locks_file;
464
465     Pathname update_data_path;
466     Pathname update_scripts_path;
467     Pathname update_messages_path;
468     DefaultOption<std::string> updateMessagesNotify;
469
470     bool repo_add_probe;
471     unsigned repo_refresh_delay;
472     bool repoLabelIsAlias;
473
474     bool download_use_deltarpm;
475     bool download_use_deltarpm_always;
476     DefaultOption<bool> download_media_prefer_download;
477
478     int download_max_concurrent_connections;
479     int download_min_download_speed;
480     int download_max_download_speed;
481     int download_max_silent_tries;
482
483     Option<DownloadMode> commit_downloadMode;
484
485     Option<bool>        solver_onlyRequires;
486     Option<bool>        solver_allowVendorChange;
487     Option<bool>        solver_cleandepsOnRemove;
488     Option<unsigned>    solver_upgradeTestcasesToKeep;
489     DefaultOption<bool> solverUpgradeRemoveDroppedPackages;
490
491     Pathname solver_checkSystemFile;
492
493     std::set<std::string> multiversion;
494
495     bool apply_locks_file;
496
497     target::rpm::RpmInstFlags rpmInstallFlags;
498
499     Pathname history_log_path;
500     Pathname credentials_global_dir_path;
501     Pathname credentials_global_file_path;
502   };
503   ///////////////////////////////////////////////////////////////////
504
505   // Backdoor to redirect ZConfig from within the running
506   // TEST-application. HANDLE WITH CARE!
507   void reconfigureZConfig( const Pathname & override_r )
508   {
509     // ctor puts itself unter smart pointer control.
510     new ZConfig::Impl( override_r );
511   }
512
513   ///////////////////////////////////////////////////////////////////
514   //
515   //    METHOD NAME : ZConfig::instance
516   //    METHOD TYPE : ZConfig &
517   //
518   ZConfig & ZConfig::instance()
519   {
520     static ZConfig _instance; // The singleton
521     return _instance;
522   }
523
524   ///////////////////////////////////////////////////////////////////
525   //
526   //    METHOD NAME : ZConfig::ZConfig
527   //    METHOD TYPE : Ctor
528   //
529   ZConfig::ZConfig()
530   : _pimpl( new Impl )
531   {
532     about( MIL );
533   }
534
535   ///////////////////////////////////////////////////////////////////
536   //
537   //    METHOD NAME : ZConfig::~ZConfig
538   //    METHOD TYPE : Dtor
539   //
540   ZConfig::~ZConfig( )
541   {}
542
543   Pathname ZConfig::systemRoot() const
544   {
545     Target_Ptr target( getZYpp()->getTarget() );
546     return target ? target->root() : Pathname();
547   }
548
549   ///////////////////////////////////////////////////////////////////
550   //
551   // system architecture
552   //
553   ///////////////////////////////////////////////////////////////////
554
555   Arch ZConfig::defaultSystemArchitecture()
556   {
557     static Arch _val( _autodetectSystemArchitecture() );
558     return _val;
559   }
560
561   Arch ZConfig::systemArchitecture() const
562   { return _pimpl->cfg_arch; }
563
564   void ZConfig::setSystemArchitecture( const Arch & arch_r )
565   {
566     if ( arch_r != _pimpl->cfg_arch )
567     {
568       WAR << "Overriding system architecture (" << _pimpl->cfg_arch << "): " << arch_r << endl;
569       _pimpl->cfg_arch = arch_r;
570     }
571   }
572
573   ///////////////////////////////////////////////////////////////////
574   //
575   // text locale
576   //
577   ///////////////////////////////////////////////////////////////////
578
579   Locale ZConfig::defaultTextLocale()
580   {
581     static Locale _val( _autodetectTextLocale() );
582     return _val;
583   }
584
585   Locale ZConfig::textLocale() const
586   { return _pimpl->cfg_textLocale; }
587
588   void ZConfig::setTextLocale( const Locale & locale_r )
589   {
590     if ( locale_r != _pimpl->cfg_textLocale )
591     {
592       WAR << "Overriding text locale (" << _pimpl->cfg_textLocale << "): " << locale_r << endl;
593       _pimpl->cfg_textLocale = locale_r;
594 #warning prefer signal
595       sat::Pool::instance().setTextLocale( locale_r );
596     }
597   }
598
599   ///////////////////////////////////////////////////////////////////
600
601   Pathname ZConfig::repoCachePath() const
602   {
603     return ( _pimpl->cfg_cache_path.empty()
604         ? Pathname("/var/cache/zypp") : _pimpl->cfg_cache_path );
605   }
606
607   Pathname ZConfig::repoMetadataPath() const
608   {
609     return ( _pimpl->cfg_metadata_path.empty()
610         ? (repoCachePath()/"raw") : _pimpl->cfg_metadata_path );
611   }
612
613   Pathname ZConfig::repoSolvfilesPath() const
614   {
615     return ( _pimpl->cfg_solvfiles_path.empty()
616         ? (repoCachePath()/"solv") : _pimpl->cfg_solvfiles_path );
617   }
618
619   Pathname ZConfig::repoPackagesPath() const
620   {
621     return ( _pimpl->cfg_packages_path.empty()
622         ? (repoCachePath()/"packages") : _pimpl->cfg_packages_path );
623   }
624
625   ///////////////////////////////////////////////////////////////////
626
627   Pathname ZConfig::configPath() const
628   {
629     return ( _pimpl->cfg_config_path.empty()
630         ? Pathname("/etc/zypp") : _pimpl->cfg_config_path );
631   }
632
633   Pathname ZConfig::knownReposPath() const
634   {
635     return ( _pimpl->cfg_known_repos_path.empty()
636         ? (configPath()/"repos.d") : _pimpl->cfg_known_repos_path );
637   }
638
639   Pathname ZConfig::knownServicesPath() const
640   {
641     return ( _pimpl->cfg_known_services_path.empty()
642         ? (configPath()/"services.d") : _pimpl->cfg_known_repos_path );
643   }
644
645   Pathname ZConfig::vendorPath() const
646   {
647     return ( _pimpl->cfg_vendor_path.empty()
648         ? (configPath()/"vendors.d") : _pimpl->cfg_vendor_path );
649   }
650
651   Pathname ZConfig::locksFile() const
652   {
653     return ( _pimpl->locks_file.empty()
654         ? (configPath()/"locks") : _pimpl->locks_file );
655   }
656
657   ///////////////////////////////////////////////////////////////////
658
659   bool ZConfig::repo_add_probe() const
660   {
661     return _pimpl->repo_add_probe;
662   }
663
664   unsigned ZConfig::repo_refresh_delay() const
665   {
666     return _pimpl->repo_refresh_delay;
667   }
668
669   bool ZConfig::repoLabelIsAlias() const
670   { return _pimpl->repoLabelIsAlias; }
671
672   void ZConfig::repoLabelIsAlias( bool yesno_r )
673   { _pimpl->repoLabelIsAlias = yesno_r; }
674
675   bool ZConfig::download_use_deltarpm() const
676   { return _pimpl->download_use_deltarpm; }
677
678   bool ZConfig::download_use_deltarpm_always() const
679   { return download_use_deltarpm() && _pimpl->download_use_deltarpm_always; }
680
681   bool ZConfig::download_media_prefer_download() const
682   { return _pimpl->download_media_prefer_download; }
683
684   void ZConfig::set_download_media_prefer_download( bool yesno_r )
685   { _pimpl->download_media_prefer_download.set( yesno_r ); }
686
687   void ZConfig::set_default_download_media_prefer_download()
688   { _pimpl->download_media_prefer_download.restoreToDefault(); }
689
690   long ZConfig::download_max_concurrent_connections() const
691   { return _pimpl->download_max_concurrent_connections; }
692
693   long ZConfig::download_min_download_speed() const
694   { return _pimpl->download_min_download_speed; }
695
696   long ZConfig::download_max_download_speed() const
697   { return _pimpl->download_max_download_speed; }
698
699   long ZConfig::download_max_silent_tries() const
700   { return _pimpl->download_max_silent_tries; }
701
702   DownloadMode ZConfig::commit_downloadMode() const
703   { return _pimpl->commit_downloadMode; }
704
705   bool ZConfig::solver_onlyRequires() const
706   { return _pimpl->solver_onlyRequires; }
707
708   bool ZConfig::solver_allowVendorChange() const
709   { return _pimpl->solver_allowVendorChange; }
710
711   bool ZConfig::solver_cleandepsOnRemove() const
712   { return _pimpl->solver_cleandepsOnRemove; }
713
714   Pathname ZConfig::solver_checkSystemFile() const
715   { return ( _pimpl->solver_checkSystemFile.empty()
716       ? (configPath()/"systemCheck") : _pimpl->solver_checkSystemFile ); }
717
718   unsigned ZConfig::solver_upgradeTestcasesToKeep() const
719   { return _pimpl->solver_upgradeTestcasesToKeep; }
720
721   bool ZConfig::solverUpgradeRemoveDroppedPackages() const              { return _pimpl->solverUpgradeRemoveDroppedPackages; }
722   void ZConfig::setSolverUpgradeRemoveDroppedPackages( bool val_r )     { _pimpl->solverUpgradeRemoveDroppedPackages.set( val_r ); }
723   void ZConfig::resetSolverUpgradeRemoveDroppedPackages()               { _pimpl->solverUpgradeRemoveDroppedPackages.restoreToDefault(); }
724
725   const std::set<std::string> & ZConfig::multiversionSpec() const       { return _pimpl->multiversion; }
726   void ZConfig::addMultiversionSpec( const std::string & name_r )       { _pimpl->multiversion.insert( name_r ); }
727   void ZConfig::removeMultiversionSpec( const std::string & name_r )    { _pimpl->multiversion.erase( name_r ); }
728
729   bool ZConfig::apply_locks_file() const
730   { return _pimpl->apply_locks_file; }
731
732   Pathname ZConfig::update_dataPath() const
733   {
734     return ( _pimpl->update_data_path.empty()
735         ? Pathname("/var/adm") : _pimpl->update_data_path );
736   }
737
738   Pathname ZConfig::update_messagesPath() const
739   {
740     return ( _pimpl->update_messages_path.empty()
741              ? Pathname(update_dataPath()/"update-messages") : _pimpl->update_messages_path );
742   }
743
744   Pathname ZConfig::update_scriptsPath() const
745   {
746     return ( _pimpl->update_scripts_path.empty()
747              ? Pathname(update_dataPath()/"update-scripts") : _pimpl->update_scripts_path );
748   }
749
750   std::string ZConfig::updateMessagesNotify() const
751   { return _pimpl->updateMessagesNotify; }
752
753   void ZConfig::setUpdateMessagesNotify( const std::string & val_r )
754   { _pimpl->updateMessagesNotify.set( val_r ); }
755
756   void ZConfig::resetUpdateMessagesNotify()
757   { _pimpl->updateMessagesNotify.restoreToDefault(); }
758
759   ///////////////////////////////////////////////////////////////////
760
761   target::rpm::RpmInstFlags ZConfig::rpmInstallFlags() const
762   { return _pimpl->rpmInstallFlags; }
763
764
765   Pathname ZConfig::historyLogFile() const
766   {
767     return ( _pimpl->history_log_path.empty() ?
768         Pathname("/var/log/zypp/history") : _pimpl->history_log_path );
769   }
770
771
772   Pathname ZConfig::credentialsGlobalDir() const
773   {
774     return ( _pimpl->credentials_global_dir_path.empty() ?
775         Pathname("/etc/zypp/credentials.d") : _pimpl->credentials_global_dir_path );
776   }
777
778   Pathname ZConfig::credentialsGlobalFile() const
779   {
780     return ( _pimpl->credentials_global_file_path.empty() ?
781         Pathname("/etc/zypp/credentials.cat") : _pimpl->credentials_global_file_path );
782   }
783
784   ///////////////////////////////////////////////////////////////////
785
786   std::string ZConfig::distroverpkg() const
787   { return "redhat-release"; }
788
789   ///////////////////////////////////////////////////////////////////
790
791   std::ostream & ZConfig::about( std::ostream & str ) const
792   {
793     str << "libzypp: " << VERSION << " built " << __DATE__ << " " <<  __TIME__ << endl;
794
795     str << "satsolver: " << sat_version;
796     if ( ::strcmp( sat_version, SATSOLVER_VERSION_STRING ) )
797       str << " (built against " << SATSOLVER_VERSION_STRING << ")";
798     str << endl;
799
800     str << "zypp.conf: '" << _pimpl->_parsedZyppConf << "'" << endl;
801     str << "TextLocale: '" << textLocale() << "' (" << defaultTextLocale() << ")" << endl;
802     str << "SystemArchitecture: '" << systemArchitecture() << "' (" << defaultSystemArchitecture() << ")" << endl;
803     return str;
804   }
805
806   /////////////////////////////////////////////////////////////////
807 } // namespace zypp
808 ///////////////////////////////////////////////////////////////////