~thopiekar/zypper/libzypp-manual-import

« back to all changes in this revision

Viewing changes to zypp/ZConfig.cc

  • Committer: Thomas-Karl Pietrowski
  • Date: 2014-01-29 22:44:28 UTC
  • Revision ID: thopiekar@googlemail.com-20140129224428-gpcqnsdakby362n8
firstĀ import

Show diffs side-by-side

added added

removed removed

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