libept
|
00001 // -*- C++ -*- 00002 00003 #include <string> 00004 #include <ept/token.h> 00005 #include <ept/core/apt.h> 00006 #include <apt-pkg/algorithms.h> 00007 00008 #ifndef EPT_APT_ACTION_H 00009 #define EPT_APT_ACTION_H 00010 00011 namespace ept { 00012 namespace core { 00013 namespace package { 00014 00015 struct Action { 00016 enum Type { Install, ReInstall, Remove, Keep, Purge, SystemUpgrade }; 00017 Token m_token; 00018 Type m_type; 00019 00020 Token token() { return m_token; } 00021 Type type() { return m_type; } 00022 00023 void apply( package::Source &pkgs ) 00024 { 00025 Type a = m_type; 00026 pkgDepCache &dc = pkgs.db().state(); 00027 00028 if ( a == SystemUpgrade ) { 00029 pkgDistUpgrade( dc ); 00030 } else { 00031 if ( !pkgs.exists( m_token ) ) 00032 return; 00033 pkgCache::PkgIterator p = pkgs.lookupToken( m_token ); 00034 00035 pkgProblemResolver fix( &dc ); 00036 if ( a == Install || a == ReInstall ) { 00037 fix.Clear( p ); 00038 fix.Protect( p ); 00039 dc.MarkInstall( p, true ); 00040 fix.InstallProtect(); 00041 if ( a == ReInstall ) 00042 dc.SetReInstall( p, true ); 00043 } else if ( a == Remove || a == Purge ) { 00044 fix.Clear( p ); 00045 fix.Protect( p ); 00046 fix.Remove( p ); 00047 dc.MarkDelete( p, a == Purge ? true : false ); 00048 } else if ( a == Keep ) { 00049 fix.Clear( p ); 00050 fix.Protect( p ); 00051 dc.MarkKeep( p, true ); 00052 } 00053 fix.Resolve( true ); 00054 } 00055 } 00056 00057 bool redundant( package::Source &pkgs ) { 00058 if ( m_type == SystemUpgrade ) { 00059 // check whether we have any upgradable packages 00060 return false; 00061 } 00062 if ( !pkgs.exists( m_token ) ) 00063 return true; 00064 PackageState s = pkgs.db().packageState( m_token ); 00065 Type a = m_type; 00066 // if ( a == Keep && !s.upgradable() ) 00067 // return true; 00068 if ( ( a == Install || a == ReInstall ) 00069 && ( !s.upgradable() && s.installed() ) ) 00070 return true; 00071 if ( ( a == Remove || a == Purge ) && !s.installed() ) 00072 return true; 00073 return false; 00074 } 00075 00076 Action( Token t, Type a ) 00077 : m_token( t ), m_type( a ) 00078 {} 00079 }; 00080 00081 struct ActionList { 00082 typedef std::vector< Action > List; 00083 List m_list; 00084 00085 void clear() { 00086 m_list.clear(); 00087 } 00088 00089 bool empty() { 00090 return m_list.empty(); 00091 } 00092 00093 void add( Action a ) { 00094 List::iterator rm = m_list.end(), i; 00095 for ( i = m_list.begin(); i != m_list.end(); ++i ) { 00096 if ( i->token() == a.token() ) { 00097 rm = i; 00098 break; 00099 } 00100 } 00101 if ( rm != m_list.end() ) 00102 m_list.erase( rm ); 00103 // if ( a.type() != Action::Keep ) 00104 m_list.push_back( a ); 00105 } 00106 00107 Action latest() { 00108 return m_list.back(); 00109 } 00110 00111 void replay( package::Source &pkgs ) { 00112 for ( List::iterator i = m_list.begin(); i != m_list.end(); ++i ) { 00113 i->apply( pkgs ); 00114 } 00115 } 00116 00117 void prune( package::Source &pkgs ) { 00118 List l; 00119 std::swap( l, m_list ); 00120 for ( List::iterator i = m_list.begin(); i != m_list.end(); ++i ) { 00121 if ( !i->redundant( pkgs ) ) 00122 m_list.push_back( *i ); 00123 } 00124 /* We want to do but can't bind reference parameters.... (or 00125 maybe use remove_copy_if or whatever ... ugly 00126 std::remove_if( m_list.begin(), m_list.end(), std::bind2nd( 00127 std::mem_fun_ref( &Action::redundant ), pkgs ) ); */ 00128 } 00129 }; 00130 00131 } 00132 } 00133 } 00134 00135 #endif