1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/ZConfig.cc
14 #include <sys/utsname.h>
19 #include "zypp/base/Logger.h"
20 #include "zypp/base/IOStream.h"
21 #include "zypp/base/InputStream.h"
22 #include "zypp/base/String.h"
24 #include "zypp/ZConfig.h"
25 #include "zypp/ZYppFactory.h"
26 #include "zypp/PathInfo.h"
27 #include "zypp/parser/IniDict.h"
30 using namespace zypp::filesystem;
31 using namespace zypp::parser;
33 ///////////////////////////////////////////////////////////////////
35 { /////////////////////////////////////////////////////////////////
37 ///////////////////////////////////////////////////////////////////
39 { /////////////////////////////////////////////////////////////////
41 /** Determine system architecture evaluating \c uname and \c /proc/cpuinfo.
43 Arch _autodetectSystemArchitecture()
46 if ( ::uname( &buf ) < 0 )
48 ERR << "Can't determine system architecture" << endl;
52 Arch architecture( buf.machine );
53 MIL << "Uname architecture is '" << buf.machine << "'" << endl;
55 // some CPUs report i686 but dont implement cx8 and cmov
56 // check for both flags in /proc/cpuinfo and downgrade
57 // to i586 if either is missing (cf bug #18885)
58 if ( architecture == Arch_i686 )
60 std::ifstream cpuinfo( "/proc/cpuinfo" );
63 for( iostr::EachLine in( cpuinfo ); in; in.next() )
65 if ( str::hasPrefix( *in, "flags" ) )
67 if ( in->find( "cx8" ) == std::string::npos
68 || in->find( "cmov" ) == std::string::npos )
70 architecture = Arch_i586;
71 WAR << "CPU lacks 'cx8' or 'cmov': architecture downgraded to '" << architecture << "'" << endl;
79 ERR << "Cant open " << PathInfo("/proc/cpuinfo") << endl;
85 /** The locale to be used for texts and messages.
87 * For the encoding to be used the preference is
89 * LC_ALL, LC_CTYPE, LANG
91 * For the language of the messages to be used, the preference is
93 * LANGUAGE, LC_ALL, LC_MESSAGES, LANG
95 * Note that LANGUAGE can contain more than one locale name, it can be
96 * a list of locale names like for example
98 * LANGUAGE=ja_JP.UTF-8:de_DE.UTF-8:fr_FR.UTF-8
100 * \todo Support dynamic fallbacklists defined by LANGUAGE
102 Locale _autodetectTextLocale()
105 const char * envlist[] = { "LC_ALL", "LC_MESSAGES", "LANG", NULL };
106 for ( const char ** envvar = envlist; *envvar; ++envvar )
108 const char * envlang = getenv( *envvar );
111 std::string envstr( envlang );
112 if ( envstr != "POSIX" && envstr != "C" )
114 Locale lang( envstr );
115 if ( ! lang.code().empty() )
117 MIL << "Found " << *envvar << "=" << envstr << endl;
124 MIL << "Default text locale is '" << ret << "'" << endl;
128 /////////////////////////////////////////////////////////////////
130 ///////////////////////////////////////////////////////////////////
132 ///////////////////////////////////////////////////////////////////
134 // CLASS NAME : ZConfig::Impl
136 /** ZConfig implementation.
137 * \todo Enrich section and entry definition by some comment
138 * (including the default setting and provide some method to
139 * write this into a sample zypp.conf.
144 Impl( const Pathname & override_r = Pathname() )
145 : cfg_arch ( defaultSystemArchitecture() )
146 , cfg_textLocale ( defaultTextLocale() )
147 , repo_add_probe ( false )
148 , repo_refresh_delay ( 10 )
149 , download_use_deltarpm ( true )
150 , solver_onlyRequires ( false )
151 , apply_locks_file ( true )
154 MIL << "libzypp: " << VERSION << " built " << __DATE__ << " " << __TIME__ << endl;
156 // override_r has higest prio
157 // ZYPP_CONF might override /etc/zypp/zypp.conf
158 Pathname confpath( override_r );
159 if ( confpath.empty() )
161 const char *env_confpath = getenv( "ZYPP_CONF" );
162 confpath = env_confpath ? env_confpath : "/etc/zypp/zypp.conf";
166 // Inject this into ZConfig. Be shure this is
167 // allocated via new. See: reconfigureZConfig
168 INT << "Reconfigure to " << confpath << endl;
169 ZConfig::instance()._pimpl.reset( this );
171 if ( PathInfo(confpath).isExist() )
173 parser::IniDict dict( confpath );
174 //InputStream is(confpath);
176 for ( IniDict::section_const_iterator sit = dict.sectionsBegin();
177 sit != dict.sectionsEnd();
180 string section(*sit);
181 //MIL << section << endl;
182 for ( IniDict::entry_const_iterator it = dict.entriesBegin(*sit);
183 it != dict.entriesEnd(*sit);
186 string entry(it->first);
187 string value(it->second);
188 //DBG << (*it).first << "=" << (*it).second << endl;
189 if ( section == "main" )
191 if ( entry == "arch" )
194 if ( carch != cfg_arch )
196 WAR << "Overriding system architecture (" << cfg_arch << "): " << carch << endl;
200 else if ( entry == "cachedir" )
202 cfg_cache_path = Pathname(value);
204 else if ( entry == "metadatadir" )
206 cfg_metadata_path = Pathname(value);
208 else if ( entry == "solvfilesdir" )
210 cfg_solvfiles_path = Pathname(value);
212 else if ( entry == "packagesdir" )
214 cfg_packages_path = Pathname(value);
216 else if ( entry == "configdir" )
218 cfg_config_path = Pathname(value);
220 else if ( entry == "reposdir" )
222 cfg_known_repos_path = Pathname(value);
224 else if ( entry == "repo.add.probe" )
226 repo_add_probe = str::strToBool( value, repo_add_probe );
228 else if ( entry == "repo.refresh.delay" )
230 str::strtonum(value, repo_refresh_delay);
232 else if ( entry == "download.use_deltarpm" )
234 download_use_deltarpm = str::strToBool( value, download_use_deltarpm );
236 else if ( entry == "vendordir" )
238 cfg_vendor_path = Pathname(value);
240 else if ( entry == "productsdir" )
242 cfg_products_path = Pathname(value);
244 else if ( entry == "solver.onlyRequires" )
246 solver_onlyRequires = str::strToBool( value, solver_onlyRequires );
248 else if ( entry == "solver.checkSystemFile" )
250 solver_checkSystemFile = Pathname(value);
252 else if ( entry == "multiversion" )
254 std::list<std::string> multi;
255 str::split( value, back_inserter(multi), ", \t" );
256 for ( std::list<string>::const_iterator it = multi.begin();
257 it != multi.end(); it++) {
258 multiversion.insert (IdString(*it));
261 else if ( entry == "locksfile.path" )
263 locks_file = Pathname(value);
265 else if ( entry == "locksfile.apply" )
267 apply_locks_file = str::strToBool( value, apply_locks_file );
269 else if ( entry == "update.datadir" )
271 update_data_path = Pathname(value);
273 else if ( entry == "update.scriptsdir" )
275 update_scripts_path = Pathname(value);
277 else if ( entry == "update.messagessdir" )
279 update_messages_path = Pathname(value);
281 else if ( entry == "rpm.install.excludedocs" )
283 rpmInstallFlags.setFlag( target::rpm::RPMINST_EXCLUDEDOCS );
285 else if ( entry == "history.logfile" )
287 history_log_path = Pathname(value);
295 MIL << confpath << " not found, using defaults instead." << endl;
299 if ( getenv( "ZYPP_TESTSUITE_FAKE_ARCH" ) )
301 Arch carch( getenv( "ZYPP_TESTSUITE_FAKE_ARCH" ) );
302 if ( carch != cfg_arch )
304 WAR << "ZYPP_TESTSUITE_FAKE_ARCH: Overriding system architecture (" << cfg_arch << "): " << carch << endl;
309 MIL << "ZConfig singleton created." << endl;
310 MIL << "defaultTextLocale: '" << cfg_textLocale << "'" << endl;
311 MIL << "System architecture is '" << cfg_arch << "'" << endl;
319 Locale cfg_textLocale;
321 Pathname cfg_cache_path;
322 Pathname cfg_metadata_path;
323 Pathname cfg_solvfiles_path;
324 Pathname cfg_packages_path;
326 Pathname cfg_config_path;
327 Pathname cfg_known_repos_path;
328 Pathname cfg_known_services_path;
329 Pathname cfg_vendor_path;
330 Pathname cfg_products_path;
333 Pathname update_data_path;
334 Pathname update_scripts_path;
335 Pathname update_messages_path;
338 unsigned repo_refresh_delay;
340 bool download_use_deltarpm;
342 bool solver_onlyRequires;
343 Pathname solver_checkSystemFile;
345 std::set<IdString> multiversion;
347 bool apply_locks_file;
349 target::rpm::RpmInstFlags rpmInstallFlags;
351 Pathname history_log_path;
353 ///////////////////////////////////////////////////////////////////
355 // Backdoor to redirect ZConfig from within the running
356 // TEST-application. HANDLE WITH CARE!
357 void reconfigureZConfig( const Pathname & override_r )
359 // ctor puts itself unter smart pointer control.
360 new ZConfig::Impl( override_r );
363 ///////////////////////////////////////////////////////////////////
365 // METHOD NAME : ZConfig::instance
366 // METHOD TYPE : ZConfig &
368 ZConfig & ZConfig::instance()
370 static ZConfig _instance; // The singleton
374 ///////////////////////////////////////////////////////////////////
376 // METHOD NAME : ZConfig::ZConfig
377 // METHOD TYPE : Ctor
383 ///////////////////////////////////////////////////////////////////
385 // METHOD NAME : ZConfig::~ZConfig
386 // METHOD TYPE : Dtor
391 ///////////////////////////////////////////////////////////////////
393 // system architecture
395 ///////////////////////////////////////////////////////////////////
397 Arch ZConfig::defaultSystemArchitecture()
399 static Arch _val( _autodetectSystemArchitecture() );
403 Arch ZConfig::systemArchitecture() const
404 { return _pimpl->cfg_arch; }
406 void ZConfig::setSystemArchitecture( const Arch & arch_r )
408 if ( arch_r != _pimpl->cfg_arch )
410 WAR << "Overriding system architecture (" << _pimpl->cfg_arch << "): " << arch_r << endl;
411 _pimpl->cfg_arch = arch_r;
415 ///////////////////////////////////////////////////////////////////
419 ///////////////////////////////////////////////////////////////////
421 Locale ZConfig::defaultTextLocale()
423 static Locale _val( _autodetectTextLocale() );
427 Locale ZConfig::textLocale() const
428 { return _pimpl->cfg_textLocale; }
430 void ZConfig::setTextLocale( const Locale & locale_r )
432 if ( locale_r != _pimpl->cfg_textLocale )
434 WAR << "Overriding text locale (" << _pimpl->cfg_textLocale << "): " << locale_r << endl;
435 _pimpl->cfg_textLocale = locale_r;
439 ///////////////////////////////////////////////////////////////////
441 Pathname ZConfig::repoCachePath() const
443 return ( _pimpl->cfg_cache_path.empty()
444 ? Pathname("/var/cache/zypp") : _pimpl->cfg_cache_path );
447 Pathname ZConfig::repoMetadataPath() const
449 return ( _pimpl->cfg_metadata_path.empty()
450 ? (repoCachePath()/"raw") : _pimpl->cfg_metadata_path );
453 Pathname ZConfig::repoSolvfilesPath() const
455 return ( _pimpl->cfg_solvfiles_path.empty()
456 ? (repoCachePath()/"solv") : _pimpl->cfg_solvfiles_path );
459 Pathname ZConfig::repoPackagesPath() const
461 return ( _pimpl->cfg_packages_path.empty()
462 ? (repoCachePath()/"packages") : _pimpl->cfg_packages_path );
465 ///////////////////////////////////////////////////////////////////
467 Pathname ZConfig::configPath() const
469 return ( _pimpl->cfg_config_path.empty()
470 ? Pathname("/etc/zypp") : _pimpl->cfg_config_path );
473 Pathname ZConfig::knownReposPath() const
475 return ( _pimpl->cfg_known_repos_path.empty()
476 ? (configPath()/"repos.d") : _pimpl->cfg_known_repos_path );
479 Pathname ZConfig::knownServicesPath() const
481 return ( _pimpl->cfg_known_services_path.empty()
482 ? (configPath()/"services.d") : _pimpl->cfg_known_repos_path );
485 Pathname ZConfig::vendorPath() const
487 return ( _pimpl->cfg_vendor_path.empty()
488 ? (configPath()/"vendors.d") : _pimpl->cfg_vendor_path );
491 Pathname ZConfig::productsPath() const
493 return ( _pimpl->cfg_products_path.empty()
494 ? (configPath()/"products.d") : _pimpl->cfg_products_path );
497 Pathname ZConfig::locksFile() const
499 return ( _pimpl->locks_file.empty()
500 ? (configPath()/"locks") : _pimpl->locks_file );
503 ///////////////////////////////////////////////////////////////////
505 bool ZConfig::repo_add_probe() const
507 return _pimpl->repo_add_probe;
510 unsigned ZConfig::repo_refresh_delay() const
512 return _pimpl->repo_refresh_delay;
515 bool ZConfig::download_use_deltarpm() const
516 { return _pimpl->download_use_deltarpm; }
519 bool ZConfig::solver_onlyRequires() const
520 { return _pimpl->solver_onlyRequires; }
522 Pathname ZConfig::solver_checkSystemFile() const
523 { return _pimpl->solver_checkSystemFile; }
526 std::set<IdString> ZConfig::multiversion() const
527 { return _pimpl->multiversion; }
529 void ZConfig::addMultiversion(std::string &name)
530 { _pimpl->multiversion.insert(IdString(name)); }
532 bool ZConfig::removeMultiversion(std::string &name)
533 { return _pimpl->multiversion.erase(IdString(name)); }
535 bool ZConfig::apply_locks_file() const
537 return _pimpl->apply_locks_file;
540 Pathname ZConfig::update_dataPath() const
542 return ( _pimpl->update_data_path.empty()
543 ? Pathname("/var/adm") : _pimpl->update_data_path );
546 Pathname ZConfig::update_messagesPath() const
548 return ( _pimpl->update_messages_path.empty()
549 ? Pathname(update_dataPath()/"update-messages") : _pimpl->update_messages_path );
553 Pathname ZConfig::update_scriptsPath() const
555 return ( _pimpl->update_scripts_path.empty()
556 ? Pathname(update_dataPath()/"update-scripts") : _pimpl->update_scripts_path );
559 ///////////////////////////////////////////////////////////////////
561 target::rpm::RpmInstFlags ZConfig::rpmInstallFlags() const
562 { return _pimpl->rpmInstallFlags; }
565 Pathname ZConfig::historyLogFile() const
567 return ( _pimpl->history_log_path.empty() ?
568 Pathname("/var/log/zypp/history") : _pimpl->history_log_path );
572 /////////////////////////////////////////////////////////////////
574 ///////////////////////////////////////////////////////////////////