1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/zypp_detail/ZYppImpl.cc
13 #include <sys/utsname.h>
16 #include "zypp/base/Logger.h"
18 #include "zypp/zypp_detail/ZYppImpl.h"
19 #include "zypp/detail/ResImplTraits.h"
20 #include "zypp/solver/detail/Helper.h"
21 #include "zypp/target/TargetImpl.h"
22 #include "zypp/ZYpp.h"
23 #include "zypp/NVRAD.h"
24 #include "zypp/Language.h"
25 #include "zypp/DiskUsageCounter.h"
26 #include "zypp/NameKindProxy.h"
30 ///////////////////////////////////////////////////////////////////
32 { /////////////////////////////////////////////////////////////////
33 ///////////////////////////////////////////////////////////////////
35 { /////////////////////////////////////////////////////////////////
37 inline Locale defaultTextLocale()
40 char * envlist[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL };
41 for ( char ** envvar = envlist; *envvar; ++envvar )
43 char * envlang = getenv( *envvar );
46 std::string envstr( envlang );
47 if ( envstr != "POSIX" && envstr != "C" )
49 Locale lang( envlang );
50 if ( lang != Locale::noCode )
61 ///////////////////////////////////////////////////////////////////
63 // METHOD NAME : ZYppImpl::ZYppImpl
64 // METHOD TYPE : Constructor
67 : _textLocale( defaultTextLocale() )
69 , _sourceFeed( _pool )
71 , _resolver( new Resolver(_pool.accessor()) )
74 MIL << "defaultTextLocale: '" << _textLocale << "'" << endl;
76 MIL << "initializing keyring..." << std::endl;
77 //_keyring = new KeyRing(homePath() + Pathname("/keyring/all"), homePath() + Pathname("/keyring/trusted"));
78 _keyring = new KeyRing();
81 if (uname (&buf) < 0) {
82 ERR << "Can't determine system architecture" << endl;
85 _architecture = Arch( buf.machine );
87 MIL << "uname architecture is '" << buf.machine << "'" << endl;
89 // some CPUs report i686 but dont implement cx8 and cmov
90 // check for both flags in /proc/cpuinfo and downgrade
91 // to i586 if either is missing (cf bug #18885)
93 if (_architecture == Arch_i686)
95 std::ifstream cpuinfo ("/proc/cpuinfo");
98 ERR << "Cant open /proc/cpuinfo" << endl;
103 while (cpuinfo.good())
105 if (!cpuinfo.getline (infoline, 1024, '\n'))
110 if (strncmp (infoline, "flags", 5) == 0)
112 std::string flagsline (infoline);
113 if ((flagsline.find( "cx8" ) == std::string::npos)
114 || (flagsline.find( "cmov" ) == std::string::npos))
116 _architecture = Arch_i586;
120 } // read proc/cpuinfo
121 } // proc/cpuinfo opened
122 } // i686 extra flags check
124 MIL << "System architecture is '" << _architecture << "'" << endl;
129 ///////////////////////////////////////////////////////////////////
131 // METHOD NAME : ZYppImpl::~ZYppImpl
132 // METHOD TYPE : Destructor
134 ZYppImpl::~ZYppImpl()
137 //------------------------------------------------------------------------
138 // add/remove resolvables
140 void ZYppImpl::addResolvables (const ResStore& store, bool installed)
142 _pool.insert(store.begin(), store.end(), installed);
145 void ZYppImpl::removeResolvables (const ResStore& store)
147 for (ResStore::iterator it = store.begin(); it != store.end(); ++it)
153 void ZYppImpl::removeInstalledResolvables ()
155 for (ResPool::const_iterator it = pool().begin(); it != pool().end();)
157 ResPool::const_iterator next = it; ++next;
158 if (it->status().isInstalled())
164 DiskUsageCounter::MountPointSet ZYppImpl::diskUsage()
165 { return _disk_usage.disk_usage(pool()); }
167 void ZYppImpl::setPartitions(const DiskUsageCounter::MountPointSet &mp)
168 { _disk_usage.setMountPoints(mp); }
170 //------------------------------------------------------------------------
173 Target_Ptr ZYppImpl::target() const
176 ZYPP_THROW(Exception("Target not initialized."));
180 void ZYppImpl::initTarget(const Pathname & root, bool commit_only)
182 MIL << "initTarget( " << root << ", " << commit_only << ")" << endl;
184 if (_target->root() == root) {
185 MIL << "Repeated call to initTarget()" << endl;
188 removeInstalledResolvables( );
190 _target = new Target( root );
193 _target->enableStorage( root );
194 addResolvables( _target->resolvables(), true );
198 void ZYppImpl::finishTarget()
201 removeInstalledResolvables();
205 //------------------------------------------------------------------------
208 /** \todo Remove workflow from target, lot's of it could be done here,
209 * and target used for transact. */
210 ZYppCommitResult ZYppImpl::commit( const ZYppCommitPolicy & policy_r )
212 MIL << "Attempt to commit (" << policy_r << ")" << endl;
214 ZYPP_THROW( Exception("Target not initialized.") );
216 ZYppCommitResult res = _target->_pimpl->commit( pool(), policy_r );
218 if (! policy_r.dryRun() ) {
219 // reload new status from target
220 removeInstalledResolvables();
221 addResolvables( _target->resolvables(), true );
224 MIL << "Commit (" << policy_r << ") returned: "
230 //------------------------------------------------------------------------
234 void ZYppImpl::setRequestedLocales( const LocaleSet & locales_r )
236 ResPool mpool( pool() );
237 // assert all requested are available
238 for ( LocaleSet::const_iterator it = locales_r.begin();
239 it != locales_r.end(); ++it )
241 NameKindProxy select( nameKindProxy<Language>( mpool, it->code() ) );
242 if ( select.installedEmpty() && select.availableEmpty() )
243 _pool.insert( Language::availableInstance( *it ) );
247 for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
248 it != mpool.byKindEnd<Language>(); ++it )
250 NameKindProxy select( nameKindProxy<Language>( mpool, (*it)->name() ) );
251 if ( locales_r.find( Locale( (*it)->name() ) ) != locales_r.end() )
253 // Language is requested
254 if ( select.installedEmpty() )
256 if ( select.availableEmpty() )
258 // no item ==> provide available to install
259 _pool.insert( Language::availableInstance( Locale((*it)->name()) ) );
260 select = nameKindProxy<Language>( mpool, (*it)->name() );
262 // available only ==> to install
263 select.availableBegin()->status().setTransactValue( ResStatus::TRANSACT, ResStatus::USER );
267 // installed ==> keep it
268 select.installedBegin()->status().setTransactValue( ResStatus::KEEP_STATE, ResStatus::USER );
269 if ( ! select.availableEmpty() )
271 // both items ==> keep
272 select.availableBegin()->status().setTransactValue( ResStatus::KEEP_STATE, ResStatus::USER );
278 // Language is NOT requested
279 if ( ! select.installedEmpty() )
280 select.installedBegin()->status().setTransactValue( ResStatus::TRANSACT, ResStatus::USER );
281 if ( ! select.availableEmpty() )
282 select.availableBegin()->status().setTransactValue( ResStatus::KEEP_STATE, ResStatus::USER );
288 ZYppImpl::LocaleSet ZYppImpl::getAvailableLocales() const
291 ResPool mpool( pool() );
292 for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
293 it != mpool.byKindEnd<Language>(); ++it )
295 if ( (*it).status().isUninstalled() ) // available!
296 ret.insert( Locale( (*it)->name() ) );
302 ZYppImpl::LocaleSet ZYppImpl::getRequestedLocales() const
305 ResPool mpool( pool() );
306 for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
307 it != mpool.byKindEnd<Language>(); ++it )
309 NameKindProxy select( nameKindProxy<Language>( mpool, (*it)->name() ) );
310 if ( ! select.installedEmpty()
311 && select.installedBegin()->status().getTransactValue() != ResStatus::TRANSACT )
312 ret.insert( Locale( (*it)->name() ) );
313 else if ( ! select.availableEmpty()
314 && select.availableBegin()->status().getTransactValue() == ResStatus::TRANSACT )
315 ret.insert( Locale( (*it)->name() ) );
320 void ZYppImpl::availableLocale( const Locale & locale_r )
322 _pool.insert( Language::availableInstance( locale_r ) );
325 //------------------------------------------------------------------------
328 void ZYppImpl::setArchitecture( const Arch & arch )
330 _architecture = arch;
331 if (_resolver) _resolver->setArchitecture( arch );
334 //------------------------------------------------------------------------
337 Pathname ZYppImpl::homePath() const
338 { return _home_path.empty() ? Pathname("/var/lib/zypp") : _home_path; }
340 void ZYppImpl::setHomePath( const Pathname & path )
341 { _home_path = path; }
343 /******************************************************************
345 ** FUNCTION NAME : operator<<
346 ** FUNCTION TYPE : std::ostream &
348 std::ostream & operator<<( std::ostream & str, const ZYppImpl & obj )
350 return str << "ZYppImpl";
353 /////////////////////////////////////////////////////////////////
354 } // namespace zypp_detail
355 ///////////////////////////////////////////////////////////////////
356 /////////////////////////////////////////////////////////////////
358 ///////////////////////////////////////////////////////////////////