1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/zypp_detail/ZYppImpl.cc
13 #include <sys/utsname.h>
15 //#include "zypp/base/Logger.h"
17 #include "zypp/zypp_detail/ZYppImpl.h"
18 #include "zypp/detail/LanguageImpl.h"
19 #include "zypp/detail/ResImplTraits.h"
20 #include "zypp/solver/detail/Helper.h"
21 #include "zypp/NVRAD.h"
22 #include "zypp/Language.h"
26 ///////////////////////////////////////////////////////////////////
28 { /////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////
31 { /////////////////////////////////////////////////////////////////
33 inline Locale defaultTextLocale()
36 char * envlist[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL };
37 for ( char ** envvar = envlist; *envvar; ++envvar )
39 char * envlang = getenv( *envvar );
42 std::string envstr( envlang );
43 if ( envstr != "POSIX" && envstr != "C" )
45 Locale lang( envlang );
46 if ( lang != Locale::noCode )
57 ///////////////////////////////////////////////////////////////////
59 // METHOD NAME : ZYppImpl::ZYppImpl
60 // METHOD TYPE : Constructor
63 : _textLocale( defaultTextLocale() )
65 , _sourceFeed( _pool )
66 , _resolver( new Resolver(_pool.accessor()) )
68 MIL << "defaultTextLocale: '" << _textLocale << "'" << endl;
71 if (uname (&buf) < 0) {
72 ERR << "Can't determine system architecture" << endl;
75 MIL << "System architecture is '" << buf.machine << "'" << endl;
76 _architecture = Arch(buf.machine);
81 ///////////////////////////////////////////////////////////////////
83 // METHOD NAME : ZYppImpl::~ZYppImpl
84 // METHOD TYPE : Destructor
90 //------------------------------------------------------------------------
91 // add/remove resolvables
93 void ZYppImpl::addResolvables (const ResStore& store, bool installed)
95 _pool.insert(store.begin(), store.end(), installed);
98 void ZYppImpl::removeResolvables (const ResStore& store)
100 for (ResStore::iterator it = store.begin(); it != store.end(); ++it)
106 void ZYppImpl::removeInstalledResolvables ()
108 for (ResPool::const_iterator it = pool().begin(); it != pool().end();)
110 ResPool::const_iterator next = it; ++next;
111 if (it->status().isInstalled())
117 //------------------------------------------------------------------------
120 Target_Ptr ZYppImpl::target() const
123 ZYPP_THROW(Exception("Target not initialized."));
127 void ZYppImpl::initTarget(const Pathname & root, bool commit_only)
129 MIL << "initTarget( " << root << ", " << commit_only << ")" << endl;
131 if (_target->root() == root) {
132 MIL << "Repeated call to initTarget()" << endl;
135 removeInstalledResolvables( );
137 _target = new Target( root );
140 _target->enableStorage( root );
141 addResolvables( _target->resolvables(), true );
145 void ZYppImpl::finishTarget()
148 removeInstalledResolvables();
152 //------------------------------------------------------------------------
155 /** \todo Remove workflow from target, lot's of it could be done here,
156 * and target used for transact. */
157 ZYpp::CommitResult ZYppImpl::commit( int medianr_r )
159 MIL << "Attempt to commit (medianr " << medianr_r << ")" << endl;
161 ZYPP_THROW( Exception("Target not initialized.") );
163 ZYpp::CommitResult res;
165 // must redirect to Target::Impl. This kind of commit should not be
166 // in the Target interface.
168 res._result = _target->commit( pool(), medianr_r,
169 res._errors, res._remaining, res._srcremaining );
171 // reload new status from target
173 removeInstalledResolvables();
174 addResolvables( _target->resolvables(), true );
176 MIL << "Commit (medianr " << medianr_r << ") returned: "
178 << " (errors " << res._errors.size()
179 << ", remaining " << res._remaining.size()
180 << ", srcremaining " << res._srcremaining.size()
187 //------------------------------------------------------------------------
191 void ZYppImpl::setRequestedLocales( const LocaleSet & locales_r )
193 // check if each requested is also possible.
195 LocaleSet possible = getPossibleLocales();
196 bool changed = false;
197 for (LocaleSet::const_iterator it = locales_r.begin(); it != locales_r.end(); ++it) {
198 changed = possible.insert( *it ).second;
199 if ( (it->code() != it->language().code()) ) {
200 changed = possible.insert( Locale( it->language().code() ) ).second;
204 // oops, some requested are not possbile, make them possible
205 // this will actually generate 'uninstalled' language items we need below
208 setPossibleLocales( possible );
211 // now select the requested items for selection
213 for (LocaleSet::const_iterator it = locales_r.begin(); it != locales_r.end(); ++it) {
214 MIL << "Requested locale '" << *it << "'" << endl;
216 // remove unwanted ? PoolItem installed( Helper::findInstalledByNameAndKind( _pool.accessor(), it->code(), ResTraits<Language>::kind ) );
217 PoolItem uninstalled( solver::detail::Helper::findUninstalledByNameAndKind( _pool.accessor(), it->code(), ResTraits<Language>::kind ) );
219 if (!uninstalled.status().isLocked()) {
220 uninstalled.status().setTransact( true, ResStatus::USER );
224 // if lang_country is given, also enable lang (i.e. if "de_DE" is given, also enable "de")
225 if ( (it->code() != it->language().code()) ) {
226 MIL << "Auto requesting locale '" << it->language().code() << "'" << endl;
227 uninstalled = solver::detail::Helper::findUninstalledByNameAndKind( _pool.accessor(), it->language().code(), ResTraits<Language>::kind );
229 if (!uninstalled.status().isLocked()) {
230 uninstalled.status().setTransact( true, ResStatus::USER );
236 _requested_locales = locales_r;
241 void ZYppImpl::setPossibleLocales( const LocaleSet & locales_r )
243 removeResolvables( _possible_locales );
244 _possible_locales.clear();
246 for (LocaleSet::const_iterator it = locales_r.begin(); it != locales_r.end(); ++it) {
247 NVRA nvra( it->code(), Edition(), Arch_noarch );
248 NVRAD ldata( nvra, Dependencies() );
249 detail::ResImplTraits<detail::LanguageImpl>::Ptr limpl = new detail::LanguageImpl();
250 Language::Ptr language = detail::makeResolvableFromImpl( ldata, limpl );
251 _possible_locales.insert( language );
253 addResolvables( _possible_locales, false );
257 ZYppImpl::LocaleSet ZYppImpl::getPossibleLocales() const
260 for (ResStore::const_iterator it = _possible_locales.begin(); it != _possible_locales.end(); ++it) {
261 lset.insert( Locale( (*it)->name() ) );
267 ZYppImpl::LocaleSet ZYppImpl::getAvailableLocales() const
269 return _available_locales;
272 void ZYppImpl::availableLocale( const Locale & locale_r )
274 _available_locales.insert( locale_r );
277 //------------------------------------------------------------------------
280 void ZYppImpl::setArchitecture( const Arch & arch )
282 _architecture = arch;
283 if (_resolver) _resolver->setArchitecture( arch );
286 //------------------------------------------------------------------------
289 Pathname ZYppImpl::homePath() const
290 { return _home_path.empty() ? Pathname("/var/lib/zypp") : _home_path; }
292 void ZYppImpl::setHomePath( const Pathname & path )
293 { _home_path = path; }
295 /******************************************************************
297 ** FUNCTION NAME : operator<<
298 ** FUNCTION TYPE : std::ostream &
300 std::ostream & operator<<( std::ostream & str, const ZYppImpl & obj )
302 return str << "ZYppImpl";
305 /////////////////////////////////////////////////////////////////
306 } // namespace zypp_detail
307 ///////////////////////////////////////////////////////////////////
308 /////////////////////////////////////////////////////////////////
310 ///////////////////////////////////////////////////////////////////