00001
00002
00003
00004
00005
00006
00007
00008
00013 #include <sys/utsname.h>
00014 #include <iostream>
00015 #include <fstream>
00016 #include "zypp/base/Logger.h"
00017
00018 #include "zypp/zypp_detail/ZYppImpl.h"
00019 #include "zypp/detail/ResImplTraits.h"
00020 #include "zypp/solver/detail/Helper.h"
00021 #include "zypp/target/TargetImpl.h"
00022 #include "zypp/ZYpp.h"
00023 #include "zypp/NVRAD.h"
00024 #include "zypp/Language.h"
00025 #include "zypp/DiskUsageCounter.h"
00026 #include "zypp/NameKindProxy.h"
00027
00028 using std::endl;
00029
00031 namespace zypp
00032 {
00033
00034 namespace zypp_detail
00035 {
00036
00037 inline Locale defaultTextLocale()
00038 {
00039 Locale ret( "en" );
00040 char * envlist[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL };
00041 for ( char ** envvar = envlist; *envvar; ++envvar )
00042 {
00043 char * envlang = getenv( *envvar );
00044 if ( envlang )
00045 {
00046 std::string envstr( envlang );
00047 if ( envstr != "POSIX" && envstr != "C" )
00048 {
00049 Locale lang( envlang );
00050 if ( lang != Locale::noCode )
00051 {
00052 ret = lang;
00053 break;
00054 }
00055 }
00056 }
00057 }
00058 return ret;
00059 }
00060
00062
00063
00064
00065
00066 ZYppImpl::ZYppImpl()
00067 : _textLocale( defaultTextLocale() )
00068 , _pool()
00069 , _sourceFeed( _pool )
00070 , _target(0)
00071 , _resolver( new Resolver(_pool.accessor()) )
00072 , _disk_usage()
00073 {
00074 MIL << "defaultTextLocale: '" << _textLocale << "'" << endl;
00075
00076 MIL << "initializing keyring..." << std::endl;
00077
00078 _keyring = new KeyRing();
00079
00080 struct utsname buf;
00081 if (uname (&buf) < 0) {
00082 ERR << "Can't determine system architecture" << endl;
00083 }
00084 else {
00085 _architecture = Arch( buf.machine );
00086
00087 MIL << "uname architecture is '" << buf.machine << "'" << endl;
00088
00089
00090
00091
00092
00093 if (_architecture == Arch_i686)
00094 {
00095 std::ifstream cpuinfo ("/proc/cpuinfo");
00096 if (!cpuinfo)
00097 {
00098 ERR << "Cant open /proc/cpuinfo" << endl;
00099 }
00100 else
00101 {
00102 char infoline[1024];
00103 while (cpuinfo.good())
00104 {
00105 if (!cpuinfo.getline (infoline, 1024, '\n'))
00106 {
00107 if (cpuinfo.eof())
00108 break;
00109 }
00110 if (strncmp (infoline, "flags", 5) == 0)
00111 {
00112 std::string flagsline (infoline);
00113 if ((flagsline.find( "cx8" ) == std::string::npos)
00114 || (flagsline.find( "cmov" ) == std::string::npos))
00115 {
00116 _architecture = Arch_i586;
00117 }
00118 break;
00119 }
00120 }
00121 }
00122 }
00123
00124 MIL << "System architecture is '" << _architecture << "'" << endl;
00125 }
00126
00127 }
00128
00130
00131
00132
00133
00134 ZYppImpl::~ZYppImpl()
00135 {}
00136
00137
00138
00139
00140 void ZYppImpl::addResolvables (const ResStore& store, bool installed)
00141 {
00142 _pool.insert(store.begin(), store.end(), installed);
00143 }
00144
00145 void ZYppImpl::removeResolvables (const ResStore& store)
00146 {
00147 for (ResStore::iterator it = store.begin(); it != store.end(); ++it)
00148 {
00149 _pool.erase(*it);
00150 }
00151 }
00152
00153 void ZYppImpl::removeInstalledResolvables ()
00154 {
00155 for (ResPool::const_iterator it = pool().begin(); it != pool().end();)
00156 {
00157 ResPool::const_iterator next = it; ++next;
00158 if (it->status().isInstalled())
00159 _pool.erase( *it );
00160 it = next;
00161 }
00162 }
00163
00164 DiskUsageCounter::MountPointSet ZYppImpl::diskUsage()
00165 { return _disk_usage.disk_usage(pool()); }
00166
00167 void ZYppImpl::setPartitions(const DiskUsageCounter::MountPointSet &mp)
00168 { _disk_usage.setMountPoints(mp); }
00169
00170
00171
00172
00173 Target_Ptr ZYppImpl::target() const
00174 {
00175 if (! _target)
00176 ZYPP_THROW(Exception("Target not initialized."));
00177 return _target;
00178 }
00179
00180 void ZYppImpl::initTarget(const Pathname & root, bool commit_only)
00181 {
00182 MIL << "initTarget( " << root << ", " << commit_only << ")" << endl;
00183 if (_target) {
00184 if (_target->root() == root) {
00185 MIL << "Repeated call to initTarget()" << endl;
00186 return;
00187 }
00188 removeInstalledResolvables( );
00189 }
00190 _target = new Target( root );
00191 if (!commit_only)
00192 {
00193 _target->enableStorage( root );
00194 addResolvables( _target->resolvables(), true );
00195 }
00196 }
00197
00198 void ZYppImpl::finishTarget()
00199 {
00200 if (_target)
00201 removeInstalledResolvables();
00202 _target = 0;
00203 }
00204
00205
00206
00207
00210 ZYppCommitResult ZYppImpl::commit( const ZYppCommitPolicy & policy_r )
00211 {
00212 MIL << "Attempt to commit (" << policy_r << ")" << endl;
00213 if (! _target)
00214 ZYPP_THROW( Exception("Target not initialized.") );
00215
00216 ZYppCommitResult res = _target->_pimpl->commit( pool(), policy_r );
00217
00218 if (! policy_r.dryRun() ) {
00219
00220 removeInstalledResolvables();
00221 addResolvables( _target->resolvables(), true );
00222 }
00223
00224 MIL << "Commit (" << policy_r << ") returned: "
00225 << res << endl;
00226 return res;
00227 }
00228
00229
00230
00231
00232
00234 void ZYppImpl::setRequestedLocales( const LocaleSet & locales_r )
00235 {
00236 ResPool mpool( pool() );
00237
00238 for ( LocaleSet::const_iterator it = locales_r.begin();
00239 it != locales_r.end(); ++it )
00240 {
00241 NameKindProxy select( nameKindProxy<Language>( mpool, it->code() ) );
00242 if ( select.installedEmpty() && select.availableEmpty() )
00243 _pool.insert( Language::availableInstance( *it ) );
00244 }
00245
00246
00247 for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
00248 it != mpool.byKindEnd<Language>(); ++it )
00249 {
00250 NameKindProxy select( nameKindProxy<Language>( mpool, (*it)->name() ) );
00251 if ( locales_r.find( Locale( (*it)->name() ) ) != locales_r.end() )
00252 {
00253
00254 if ( select.installedEmpty() )
00255 {
00256 if ( select.availableEmpty() )
00257 {
00258
00259 _pool.insert( Language::availableInstance( Locale((*it)->name()) ) );
00260 select = nameKindProxy<Language>( mpool, (*it)->name() );
00261 }
00262
00263 select.availableBegin()->status().setTransactValue( ResStatus::TRANSACT, ResStatus::USER );
00264 }
00265 else
00266 {
00267
00268 select.installedBegin()->status().setTransactValue( ResStatus::KEEP_STATE, ResStatus::USER );
00269 if ( ! select.availableEmpty() )
00270 {
00271
00272 select.availableBegin()->status().resetTransact( ResStatus::USER );
00273 }
00274 }
00275 }
00276 else
00277 {
00278
00279 if ( ! select.installedEmpty() )
00280 select.installedBegin()->status().setTransactValue( ResStatus::TRANSACT, ResStatus::USER );
00281 if ( ! select.availableEmpty() )
00282 select.availableBegin()->status().resetTransact( ResStatus::USER );
00283 }
00284 }
00285 }
00286
00288 ZYppImpl::LocaleSet ZYppImpl::getAvailableLocales() const
00289 {
00290 ZYpp::LocaleSet ret;
00291 ResPool mpool( pool() );
00292 for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
00293 it != mpool.byKindEnd<Language>(); ++it )
00294 {
00295 if ( (*it).status().isUninstalled() )
00296 ret.insert( Locale( (*it)->name() ) );
00297 }
00298 return ret;
00299 }
00300
00302 ZYppImpl::LocaleSet ZYppImpl::getRequestedLocales() const
00303 {
00304 ZYpp::LocaleSet ret;
00305 ResPool mpool( pool() );
00306 for ( ResPool::byKind_iterator it = mpool.byKindBegin<Language>();
00307 it != mpool.byKindEnd<Language>(); ++it )
00308 {
00309 NameKindProxy select( nameKindProxy<Language>( mpool, (*it)->name() ) );
00310 if ( ! select.installedEmpty()
00311 && select.installedBegin()->status().getTransactValue() != ResStatus::TRANSACT )
00312 ret.insert( Locale( (*it)->name() ) );
00313 else if ( ! select.availableEmpty()
00314 && select.availableBegin()->status().getTransactValue() == ResStatus::TRANSACT )
00315 ret.insert( Locale( (*it)->name() ) );
00316 }
00317 return ret;
00318 }
00319
00320 void ZYppImpl::availableLocale( const Locale & locale_r )
00321 {
00322 _pool.insert( Language::availableInstance( locale_r ) );
00323 }
00324
00325
00326
00327
00328 void ZYppImpl::setArchitecture( const Arch & arch )
00329 {
00330 _architecture = arch;
00331 if (_resolver) _resolver->setArchitecture( arch );
00332 }
00333
00334
00335
00336
00337 Pathname ZYppImpl::homePath() const
00338 { return _home_path.empty() ? Pathname("/var/lib/zypp") : _home_path; }
00339
00340 void ZYppImpl::setHomePath( const Pathname & path )
00341 { _home_path = path; }
00342
00343
00344
00345
00346
00347
00348 std::ostream & operator<<( std::ostream & str, const ZYppImpl & obj )
00349 {
00350 return str << "ZYppImpl";
00351 }
00352
00354 }
00357 }