1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
|
/*
* apt.c: parsing apt configuration files
*/
#include <std.h>
#include <interface/coreui.h>
#include <interface/acquire_status.h>
#include <interface/dialogs.h>
#include <interface/init_status.h>
#include <list/colors.h>
#include <list/screens.h>
#include <sys/wait.h>
#include "apt.h"
pkgCacheFile *CacheFile = NULL;
pkgDepCache *Cache = NULL;
pkgProblemResolver *Fix = NULL;
pkgRecords *Recs = NULL;
void initialize_cache(void)
{
delete CacheFile;
CacheFile = new pkgCacheFile;
// This is our special ncurses progress indicator
InitStatus Progress(*_config);
// Read the sources list
pkgSourceList List;
List.ReadMainList();
// Parse (if necessary) the package files
pkgMakeStatusCache(List, Progress);
Progress.Done();
bool WithLock;
if (getuid() == 0)
WithLock = true;
else
WithLock = false;
CacheFile->Open(Progress, WithLock);
// This makes things a lot easier
Cache = *CacheFile;
// If there are errors we certainly need to know about them
if (_error->PendingError() == true)
{
string Text;
clear();
refresh();
while (_error->PopMessage(Text) == true)
{
ui_dialog(Pair(COLOR_WHITE, COLOR_BLUE) | A_BOLD, "Error", (char *) Text.c_str());
refresh();
}
capt_clean_exit();
exit(-1);
}
delete Recs;
Recs = new pkgRecords(*Cache);
delete Fix;
Fix = new pkgProblemResolver(*Cache);
check_dependencies(true);
}
void global_cache_reinit()
{
initialize_cache();
for (ScreenList::Screen * s = screen.Head(); s != NULL; s = s->next)
{
s->Packages->reinitialize();
screen.boundreset(s);
}
}
bool check_dependencies(bool AllowBroken)
{
if (_error->PendingError() == true)
return false;
// Check that the system is OK
if ((*Cache).DelCount() != 0 || (*Cache).InstCount() != 0)
return _error->Error("Internal Error, non-zero counts");
// Apply corrections for half-installed packages
if (pkgApplyStatus(*Cache) == false)
return false;
// Nothing is broken
if ((*Cache).BrokenCount() == 0 || AllowBroken == true)
return true;
string s;
// Attempt to fix broken things
if (_config->FindB("APT::Console::Fix-Broken", false) == true)
{
cout << "Correcting dependencies..." << flush;
if (pkgFixBroken(*Cache) == false || (*Cache).BrokenCount() != 0)
{
cout << " failed." << endl;
capt_show_broken(*Cache);
return _error->Error("Unable to correct dependencies");
}
if (pkgMinimizeUpgrade(*Cache) == false)
return _error->Error("Unable to minimize the upgrade set");
cout << " Done" << endl;
}
else
{
cout << "You might want to run `apt-get -f install' to correct these." << endl;
capt_show_broken(*Cache);
return _error->Error("Unmet dependencies. Try using -f.");
}
return true;
}
void capt_show_broken(pkgDepCache & Cache)
{
string s = "\n"
" Some packages could not be installed. This may mean that you have \n"
" requested an impossible situation or if you are using the unstable \n"
" distribution that some required packages have not yet been created \n" " or been moved out of Incoming. \n\n";
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() != true; I++)
{
if (Cache[I].InstBroken() == false)
continue;
// Print out each package and the failed dependencies
s += " $7#";
s += I.Name();
s += "$!:";
int Indent = strlen(I.Name()) + 3;
bool First = true;
if (Cache[I].InstVerIter(Cache).end() == true)
{
s += "\n";
continue;
}
for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;)
{
// Compute a single dependency element (glob or)
pkgCache::DepIterator Start;
pkgCache::DepIterator End;
D.GlobOr(Start, End);
if (Cache.IsImportantDep(End) == false || (Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
continue;
if (First == false)
for (int J = 0; J != Indent; J++)
s += " ";
First = false;
s += " ";
s += End.DepType();
s += ": ";
s += End.TargetPkg().Name();
// Show a quick summary of the version requirements
if (End.TargetVer() != 0)
{
s += " ($3#";
s += End.CompType();
s += " $2#";
s += End.TargetVer();
s += "$!)";
}
/* Show a summary of the target package if possible. In the case
of virtual packages we show nothing */
pkgCache::PkgIterator Targ = End.TargetPkg();
if (Targ->ProvidesList == 0)
{
s += " but ";
pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
if (Ver.end() == false)
{
s += Ver.VerStr();
s += " $7#is installed$! ";
}
else
{
if (Cache[Targ].CandidateVerIter(Cache).end() == true)
{
if (Targ->ProvidesList == 0)
s += "it is $7#not installable$! ";
else
s += "it is a $7#virtual package$! ";
}
else
s += "it is $7#not installed$! ";
}
}
s += "\n";
}
}
ui_dialog(Pair(COLOR_BLACK, COLOR_WHITE), "Unmet Dependencies", (char *) s.c_str());
}
|