libzypp  11.13.5
ZConfig.cc
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
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 
40 namespace zypp
41 {
42 
51 
52  namespace
53  {
54 
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)
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  }
144  }
145  }
146  return architecture;
147  }
148 
166  Locale _autodetectTextLocale()
167  {
168  Locale ret( "en" );
169  const char * envlist[] = { "LC_ALL", "LC_MESSAGES", "LANG", NULL };
170  for ( const char ** envvar = envlist; *envvar; ++envvar )
171  {
172  const char * envlang = getenv( *envvar );
173  if ( envlang )
174  {
175  std::string envstr( envlang );
176  if ( envstr != "POSIX" && envstr != "C" )
177  {
178  Locale lang( envstr );
179  if ( ! lang.code().empty() )
180  {
181  MIL << "Found " << *envvar << "=" << envstr << endl;
182  ret = lang;
183  break;
184  }
185  }
186  }
187  }
188  MIL << "Default text locale is '" << ret << "'" << endl;
189 #warning HACK AROUND BOOST_TEST_CATCH_SYSTEM_ERRORS
190  setenv( "BOOST_TEST_CATCH_SYSTEM_ERRORS", "no", 1 );
191  return ret;
192  }
193 
195  } // namespace zypp
197 
199  template<class _Tp>
200  struct Option
201  {
202  typedef _Tp value_type;
203 
205  Option( const value_type & initial_r )
206  : _val( initial_r )
207  {}
208 
210  const value_type & get() const
211  { return _val; }
212 
214  operator const value_type &() const
215  { return _val; }
216 
218  void set( const value_type & newval_r )
219  { _val = newval_r; }
220 
222  value_type & ref()
223  { return _val; }
224 
225  private:
227  };
228 
230  template<class _Tp>
231  struct DefaultOption : public Option<_Tp>
232  {
233  typedef _Tp value_type;
235 
236  DefaultOption( const value_type & initial_r )
237  : Option<_Tp>( initial_r ), _default( initial_r )
238  {}
239 
241  void restoreToDefault()
242  { this->set( _default.get() ); }
243 
245  void restoreToDefault( const value_type & newval_r )
246  { setDefault( newval_r ); restoreToDefault(); }
247 
249  const value_type & getDefault() const
250  { return _default.get(); }
251 
253  void setDefault( const value_type & newval_r )
254  { _default.set( newval_r ); }
255 
256  private:
258  };
259 
261  //
262  // CLASS NAME : ZConfig::Impl
263  //
270  {
271  public:
272  Impl( const Pathname & override_r = Pathname() )
273  : _parsedZyppConf ( override_r )
274  , cfg_arch ( defaultSystemArchitecture() )
275  , cfg_textLocale ( defaultTextLocale() )
276  , updateMessagesNotify ( "single | /usr/lib/zypp/notify-message -p %p" )
277  , repo_add_probe ( false )
278  , repo_refresh_delay ( 10 )
279  , repoLabelIsAlias ( false )
280  , download_use_deltarpm ( true )
281  , download_use_deltarpm_always ( false )
282  , download_media_prefer_download( true )
283  , download_max_concurrent_connections( 5 )
284  , download_min_download_speed ( 0 )
285  , download_max_download_speed ( 0 )
286  , download_max_silent_tries ( 5 )
287  , download_transfer_timeout ( 180 )
288  , commit_downloadMode ( DownloadDefault )
289  , solver_onlyRequires ( false )
290  , solver_allowVendorChange ( false )
291  , solver_cleandepsOnRemove ( false )
292  , solver_upgradeTestcasesToKeep ( 2 )
293  , solverUpgradeRemoveDroppedPackages( true )
294  , apply_locks_file ( true )
295  , pluginsPath ( "/usr/lib/zypp/plugins" )
296  {
297  MIL << "libzypp: " << VERSION << " built " << __DATE__ << " " << __TIME__ << endl;
298  // override_r has higest prio
299  // ZYPP_CONF might override /etc/zypp/zypp.conf
300  if ( _parsedZyppConf.empty() )
301  {
302  const char *env_confpath = getenv( "ZYPP_CONF" );
303  _parsedZyppConf = env_confpath ? env_confpath : "/etc/zypp/zypp.conf";
304  }
305  else
306  {
307  // Inject this into ZConfig. Be shure this is
308  // allocated via new. See: reconfigureZConfig
309  INT << "Reconfigure to " << _parsedZyppConf << endl;
310  ZConfig::instance()._pimpl.reset( this );
311  }
312  if ( PathInfo(_parsedZyppConf).isExist() )
313  {
314  parser::IniDict dict( _parsedZyppConf );
316  sit != dict.sectionsEnd();
317  ++sit )
318  {
319  string section(*sit);
320  //MIL << section << endl;
321  for ( IniDict::entry_const_iterator it = dict.entriesBegin(*sit);
322  it != dict.entriesEnd(*sit);
323  ++it )
324  {
325  string entry(it->first);
326  string value(it->second);
327  //DBG << (*it).first << "=" << (*it).second << endl;
328  if ( section == "main" )
329  {
330  if ( entry == "arch" )
331  {
332  Arch carch( value );
333  if ( carch != cfg_arch )
334  {
335  WAR << "Overriding system architecture (" << cfg_arch << "): " << carch << endl;
336  cfg_arch = carch;
337  }
338  }
339  else if ( entry == "cachedir" )
340  {
341  cfg_cache_path = Pathname(value);
342  }
343  else if ( entry == "metadatadir" )
344  {
345  cfg_metadata_path = Pathname(value);
346  }
347  else if ( entry == "solvfilesdir" )
348  {
349  cfg_solvfiles_path = Pathname(value);
350  }
351  else if ( entry == "packagesdir" )
352  {
353  cfg_packages_path = Pathname(value);
354  }
355  else if ( entry == "configdir" )
356  {
357  cfg_config_path = Pathname(value);
358  }
359  else if ( entry == "reposdir" )
360  {
361  cfg_known_repos_path = Pathname(value);
362  }
363  else if ( entry == "servicesdir" )
364  {
365  cfg_known_services_path = Pathname(value);
366  }
367  else if ( entry == "repo.add.probe" )
368  {
369  repo_add_probe = str::strToBool( value, repo_add_probe );
370  }
371  else if ( entry == "repo.refresh.delay" )
372  {
373  str::strtonum(value, repo_refresh_delay);
374  }
375  else if ( entry == "repo.refresh.locales" )
376  {
377  std::vector<std::string> tmp;
378  str::split( value, back_inserter( tmp ), ", \t" );
379 
380  boost::function<Locale(const std::string &)> transform(
381  [](const std::string & str_r)->Locale{ return Locale(str_r); }
382  );
383  repoRefreshLocales.insert( make_transform_iterator( tmp.begin(), transform ),
384  make_transform_iterator( tmp.end(), transform ) );
385  }
386  else if ( entry == "download.use_deltarpm" )
387  {
388  download_use_deltarpm = str::strToBool( value, download_use_deltarpm );
389  }
390  else if ( entry == "download.use_deltarpm.always" )
391  {
392  download_use_deltarpm_always = str::strToBool( value, download_use_deltarpm_always );
393  }
394  else if ( entry == "download.media_preference" )
395  {
396  download_media_prefer_download.restoreToDefault( str::compareCI( value, "volatile" ) != 0 );
397  }
398  else if ( entry == "download.max_concurrent_connections" )
399  {
400  str::strtonum(value, download_max_concurrent_connections);
401  }
402  else if ( entry == "download.min_download_speed" )
403  {
404  str::strtonum(value, download_min_download_speed);
405  }
406  else if ( entry == "download.max_download_speed" )
407  {
408  str::strtonum(value, download_max_download_speed);
409  }
410  else if ( entry == "download.max_silent_tries" )
411  {
412  str::strtonum(value, download_max_silent_tries);
413  }
414  else if ( entry == "download.transfer_timeout" )
415  {
416  str::strtonum(value, download_transfer_timeout);
417  if ( download_transfer_timeout < 0 ) download_transfer_timeout = 0;
418  else if ( download_transfer_timeout > 3600 ) download_transfer_timeout = 3600;
419  }
420  else if ( entry == "commit.downloadMode" )
421  {
422  commit_downloadMode.set( deserializeDownloadMode( value ) );
423  }
424  else if ( entry == "vendordir" )
425  {
426  cfg_vendor_path = Pathname(value);
427  }
428  else if ( entry == "multiversiondir" )
429  {
430  cfg_multiversion_path = Pathname(value);
431  }
432  else if ( entry == "solver.onlyRequires" )
433  {
434  solver_onlyRequires.set( str::strToBool( value, solver_onlyRequires ) );
435  }
436  else if ( entry == "solver.allowVendorChange" )
437  {
438  solver_allowVendorChange.set( str::strToBool( value, solver_allowVendorChange ) );
439  }
440  else if ( entry == "solver.cleandepsOnRemove" )
441  {
442  solver_cleandepsOnRemove.set( str::strToBool( value, solver_cleandepsOnRemove ) );
443  }
444  else if ( entry == "solver.upgradeTestcasesToKeep" )
445  {
446  solver_upgradeTestcasesToKeep.set( str::strtonum<unsigned>( value ) );
447  }
448  else if ( entry == "solver.upgradeRemoveDroppedPackages" )
449  {
450  solverUpgradeRemoveDroppedPackages.restoreToDefault( str::strToBool( value, solverUpgradeRemoveDroppedPackages.getDefault() ) );
451  }
452  else if ( entry == "solver.checkSystemFile" )
453  {
454  solver_checkSystemFile = Pathname(value);
455  }
456  else if ( entry == "multiversion" )
457  {
458  str::split( value, inserter( _multiversion, _multiversion.end() ), ", \t" );
459  }
460  else if ( entry == "locksfile.path" )
461  {
462  locks_file = Pathname(value);
463  }
464  else if ( entry == "locksfile.apply" )
465  {
466  apply_locks_file = str::strToBool( value, apply_locks_file );
467  }
468  else if ( entry == "update.datadir" )
469  {
470  update_data_path = Pathname(value);
471  }
472  else if ( entry == "update.scriptsdir" )
473  {
474  update_scripts_path = Pathname(value);
475  }
476  else if ( entry == "update.messagessdir" )
477  {
478  update_messages_path = Pathname(value);
479  }
480  else if ( entry == "update.messages.notify" )
481  {
482  updateMessagesNotify.set( value );
483  }
484  else if ( entry == "rpm.install.excludedocs" )
485  {
486  rpmInstallFlags.setFlag( target::rpm::RPMINST_EXCLUDEDOCS,
487  str::strToBool( value, false ) );
488  }
489  else if ( entry == "history.logfile" )
490  {
491  history_log_path = Pathname(value);
492  }
493  else if ( entry == "credentials.global.dir" )
494  {
495  credentials_global_dir_path = Pathname(value);
496  }
497  else if ( entry == "credentials.global.file" )
498  {
499  credentials_global_file_path = Pathname(value);
500  }
501  }
502  }
503  }
504  }
505  else
506  {
507  MIL << _parsedZyppConf << " not found, using defaults instead." << endl;
508  _parsedZyppConf = _parsedZyppConf.extend( " (NOT FOUND)" );
509  }
510 
511  // legacy:
512  if ( getenv( "ZYPP_TESTSUITE_FAKE_ARCH" ) )
513  {
514  Arch carch( getenv( "ZYPP_TESTSUITE_FAKE_ARCH" ) );
515  if ( carch != cfg_arch )
516  {
517  WAR << "ZYPP_TESTSUITE_FAKE_ARCH: Overriding system architecture (" << cfg_arch << "): " << carch << endl;
518  cfg_arch = carch;
519  }
520  }
521  MIL << "ZConfig singleton created." << endl;
522  }
523 
524  ~Impl()
525  {}
526 
527  public:
529  Pathname _parsedZyppConf;
530 
533 
534  Pathname cfg_cache_path;
538 
539  Pathname cfg_config_path;
542 
543  Pathname cfg_vendor_path;
545  Pathname locks_file;
546 
551 
556 
560 
566 
568 
574 
576 
577  std::set<std::string> & multiversion() { return getMultiversion(); }
578  const std::set<std::string> & multiversion() const { return getMultiversion(); }
579 
581 
582  target::rpm::RpmInstFlags rpmInstallFlags;
583 
587 
589 
590  private:
591  std::set<std::string> & getMultiversion() const
592  {
593  if ( ! _multiversionInitialized )
594  {
595  Pathname multiversionDir( cfg_multiversion_path );
596  if ( multiversionDir.empty() )
597  multiversionDir = ( cfg_config_path.empty() ? Pathname("/etc/zypp") : cfg_config_path ) / "multiversion.d";
598 
599  filesystem::dirForEach( multiversionDir,
600  [this]( const Pathname & dir_r, const char *const & name_r )->bool
601  {
602  MIL << "Parsing " << dir_r/name_r << endl;
603  iostr::simpleParseFile( InputStream( dir_r/name_r ),
604  [this]( int num_r, std::string line_r )->bool
605  {
606  DBG << " found " << line_r << endl;
607  _multiversion.insert( line_r );
608  return true;
609  } );
610  return true;
611  } );
612  _multiversionInitialized = true;
613  }
614  return _multiversion;
615  }
616  mutable std::set<std::string> _multiversion;
618  };
620 
621  // Backdoor to redirect ZConfig from within the running
622  // TEST-application. HANDLE WITH CARE!
623  void reconfigureZConfig( const Pathname & override_r )
624  {
625  // ctor puts itself unter smart pointer control.
626  new ZConfig::Impl( override_r );
627  }
628 
630  //
631  // METHOD NAME : ZConfig::instance
632  // METHOD TYPE : ZConfig &
633  //
634  ZConfig & ZConfig::instance()
635  {
636  static ZConfig _instance; // The singleton
637  return _instance;
638  }
639 
641  //
642  // METHOD NAME : ZConfig::ZConfig
643  // METHOD TYPE : Ctor
644  //
645  ZConfig::ZConfig()
646  : _pimpl( new Impl )
647  {
648  about( MIL );
649  }
650 
652  //
653  // METHOD NAME : ZConfig::~ZConfig
654  // METHOD TYPE : Dtor
655  //
657  {}
658 
659  Pathname ZConfig::systemRoot() const
660  {
661  Target_Ptr target( getZYpp()->getTarget() );
662  return target ? target->root() : Pathname();
663  }
664 
666  //
667  // system architecture
668  //
670 
672  {
673  static Arch _val( _autodetectSystemArchitecture() );
674  return _val;
675  }
676 
678  { return _pimpl->cfg_arch; }
679 
680  void ZConfig::setSystemArchitecture( const Arch & arch_r )
681  {
682  if ( arch_r != _pimpl->cfg_arch )
683  {
684  WAR << "Overriding system architecture (" << _pimpl->cfg_arch << "): " << arch_r << endl;
685  _pimpl->cfg_arch = arch_r;
686  }
687  }
688 
690  //
691  // text locale
692  //
694 
696  {
697  static Locale _val( _autodetectTextLocale() );
698  return _val;
699  }
700 
702  { return _pimpl->cfg_textLocale; }
703 
704  void ZConfig::setTextLocale( const Locale & locale_r )
705  {
706  if ( locale_r != _pimpl->cfg_textLocale )
707  {
708  WAR << "Overriding text locale (" << _pimpl->cfg_textLocale << "): " << locale_r << endl;
709  _pimpl->cfg_textLocale = locale_r;
710 #warning prefer signal
711  sat::Pool::instance().setTextLocale( locale_r );
712  }
713  }
714 
716 
717  Pathname ZConfig::repoCachePath() const
718  {
719  return ( _pimpl->cfg_cache_path.empty()
720  ? Pathname("/var/cache/zypp") : _pimpl->cfg_cache_path );
721  }
722 
723  Pathname ZConfig::repoMetadataPath() const
724  {
725  return ( _pimpl->cfg_metadata_path.empty()
726  ? (repoCachePath()/"raw") : _pimpl->cfg_metadata_path );
727  }
728 
729  Pathname ZConfig::repoSolvfilesPath() const
730  {
731  return ( _pimpl->cfg_solvfiles_path.empty()
732  ? (repoCachePath()/"solv") : _pimpl->cfg_solvfiles_path );
733  }
734 
735  Pathname ZConfig::repoPackagesPath() const
736  {
737  return ( _pimpl->cfg_packages_path.empty()
738  ? (repoCachePath()/"packages") : _pimpl->cfg_packages_path );
739  }
740 
742 
743  Pathname ZConfig::configPath() const
744  {
745  return ( _pimpl->cfg_config_path.empty()
746  ? Pathname("/etc/zypp") : _pimpl->cfg_config_path );
747  }
748 
749  Pathname ZConfig::knownReposPath() const
750  {
751  return ( _pimpl->cfg_known_repos_path.empty()
752  ? (configPath()/"repos.d") : _pimpl->cfg_known_repos_path );
753  }
754 
755  Pathname ZConfig::knownServicesPath() const
756  {
757  return ( _pimpl->cfg_known_services_path.empty()
758  ? (configPath()/"services.d") : _pimpl->cfg_known_services_path );
759  }
760 
761  Pathname ZConfig::vendorPath() const
762  {
763  return ( _pimpl->cfg_vendor_path.empty()
764  ? (configPath()/"vendors.d") : _pimpl->cfg_vendor_path );
765  }
766 
767  Pathname ZConfig::locksFile() const
768  {
769  return ( _pimpl->locks_file.empty()
770  ? (configPath()/"locks") : _pimpl->locks_file );
771  }
772 
774 
776  { return _pimpl->repo_add_probe; }
777 
779  { return _pimpl->repo_refresh_delay; }
780 
783 
785  { return _pimpl->repoLabelIsAlias; }
786 
787  void ZConfig::repoLabelIsAlias( bool yesno_r )
788  { _pimpl->repoLabelIsAlias = yesno_r; }
789 
791  { return _pimpl->download_use_deltarpm; }
792 
795 
798 
800  { _pimpl->download_media_prefer_download.set( yesno_r ); }
801 
804 
807 
810 
813 
815  { return _pimpl->download_max_silent_tries; }
816 
818  { return _pimpl->download_transfer_timeout; }
819 
821  { return _pimpl->commit_downloadMode; }
822 
824  { return _pimpl->solver_onlyRequires; }
825 
827  { return _pimpl->solver_allowVendorChange; }
828 
830  { return _pimpl->solver_cleandepsOnRemove; }
831 
833  { return ( _pimpl->solver_checkSystemFile.empty()
834  ? (configPath()/"systemCheck") : _pimpl->solver_checkSystemFile ); }
835 
838 
842 
843  const std::set<std::string> & ZConfig::multiversionSpec() const { return _pimpl->multiversion(); }
844  void ZConfig::addMultiversionSpec( const std::string & name_r ) { _pimpl->multiversion().insert( name_r ); }
845  void ZConfig::removeMultiversionSpec( const std::string & name_r ) { _pimpl->multiversion().erase( name_r ); }
846 
848  { return _pimpl->apply_locks_file; }
849 
850  Pathname ZConfig::update_dataPath() const
851  {
852  return ( _pimpl->update_data_path.empty()
853  ? Pathname("/var/adm") : _pimpl->update_data_path );
854  }
855 
857  {
858  return ( _pimpl->update_messages_path.empty()
859  ? Pathname(update_dataPath()/"update-messages") : _pimpl->update_messages_path );
860  }
861 
863  {
864  return ( _pimpl->update_scripts_path.empty()
865  ? Pathname(update_dataPath()/"update-scripts") : _pimpl->update_scripts_path );
866  }
867 
868  std::string ZConfig::updateMessagesNotify() const
869  { return _pimpl->updateMessagesNotify; }
870 
871  void ZConfig::setUpdateMessagesNotify( const std::string & val_r )
872  { _pimpl->updateMessagesNotify.set( val_r ); }
873 
876 
878 
879  target::rpm::RpmInstFlags ZConfig::rpmInstallFlags() const
880  { return _pimpl->rpmInstallFlags; }
881 
882 
883  Pathname ZConfig::historyLogFile() const
884  {
885  return ( _pimpl->history_log_path.empty() ?
886  Pathname("/var/log/zypp/history") : _pimpl->history_log_path );
887  }
888 
890  {
891  return ( _pimpl->credentials_global_dir_path.empty() ?
892  Pathname("/etc/zypp/credentials.d") : _pimpl->credentials_global_dir_path );
893  }
894 
896  {
897  return ( _pimpl->credentials_global_file_path.empty() ?
898  Pathname("/etc/zypp/credentials.cat") : _pimpl->credentials_global_file_path );
899  }
900 
902 
903  std::string ZConfig::distroverpkg() const
904  { return "redhat-release"; }
905 
907 
908  Pathname ZConfig::pluginsPath() const
909  { return _pimpl->pluginsPath.get(); }
910 
912 
913  std::ostream & ZConfig::about( std::ostream & str ) const
914  {
915  str << "libzypp: " << VERSION << " built " << __DATE__ << " " << __TIME__ << endl;
916 
917  str << "libsolv: " << solv_version;
918  if ( ::strcmp( solv_version, LIBSOLV_VERSION_STRING ) )
919  str << " (built against " << LIBSOLV_VERSION_STRING << ")";
920  str << endl;
921 
922  str << "zypp.conf: '" << _pimpl->_parsedZyppConf << "'" << endl;
923  str << "TextLocale: '" << textLocale() << "' (" << defaultTextLocale() << ")" << endl;
924  str << "SystemArchitecture: '" << systemArchitecture() << "' (" << defaultSystemArchitecture() << ")" << endl;
925  return str;
926  }
927 
929 } // namespace zypp