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