summaryrefslogtreecommitdiff
path: root/cmdline
diff options
context:
space:
mode:
Diffstat (limited to 'cmdline')
-rw-r--r--cmdline/apt-cache.cc110
-rw-r--r--cmdline/apt-get.cc93
2 files changed, 171 insertions, 32 deletions
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index aea9ebeba..cc4c1559e 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -71,6 +71,12 @@ void LocalitySort(pkgCache::VerFile **begin,
{
qsort(begin,Count,Size,LocalityCompare);
}
+
+void LocalitySort(pkgCache::DescFile **begin,
+ unsigned long Count,size_t Size)
+{
+ qsort(begin,Count,Size,LocalityCompare);
+}
/*}}}*/
// UnMet - Show unmet dependencies /*{{{*/
// ---------------------------------------------------------------------
@@ -96,13 +102,15 @@ bool UnMet(CommandLine &CmdL)
if (End->Type != pkgCache::Dep::PreDepends &&
End->Type != pkgCache::Dep::Depends &&
End->Type != pkgCache::Dep::Suggests &&
- End->Type != pkgCache::Dep::Recommends)
+ End->Type != pkgCache::Dep::Recommends &&
+ End->Type != pkgCache::Dep::DpkgBreaks)
continue;
// Important deps only
if (Important == true)
if (End->Type != pkgCache::Dep::PreDepends &&
- End->Type != pkgCache::Dep::Depends)
+ End->Type != pkgCache::Dep::Depends &&
+ End->Type != pkgCache::Dep::DpkgBreaks)
continue;
// Verify the or group
@@ -182,7 +190,14 @@ bool DumpPackage(CommandLine &CmdL)
{
cout << Cur.VerStr();
for (pkgCache::VerFileIterator Vf = Cur.FileList(); Vf.end() == false; Vf++)
- cout << "(" << Vf.File().FileName() << ")";
+ cout << " (" << Vf.File().FileName() << ")";
+ cout << endl;
+ for (pkgCache::DescIterator D = Cur.DescriptionList(); D.end() == false; D++)
+ {
+ cout << " Description Language: " << D.LanguageCode() << endl
+ << " File: " << D.FileList().File().FileName() << endl
+ << " MD5: " << D.md5() << endl;
+ }
cout << endl;
}
@@ -277,11 +292,15 @@ bool Stats(CommandLine &Cmd)
cout << _("Total distinct versions: ") << Cache.Head().VersionCount << " (" <<
SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl;
+ cout << _("Total Distinct Descriptions: ") << Cache.Head().DescriptionCount << " (" <<
+ SizeToStr(Cache.Head().DescriptionCount*Cache.Head().DescriptionSz) << ')' << endl;
cout << _("Total dependencies: ") << Cache.Head().DependsCount << " (" <<
SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl;
cout << _("Total ver/file relations: ") << Cache.Head().VerFileCount << " (" <<
SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl;
+ cout << _("Total Desc/File relations: ") << Cache.Head().DescFileCount << " (" <<
+ SizeToStr(Cache.Head().DescFileCount*Cache.Head().DescFileSz) << ')' << endl;
cout << _("Total Provides mappings: ") << Cache.Head().ProvidesCount << " (" <<
SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl;
@@ -344,6 +363,12 @@ bool Dump(CommandLine &Cmd)
for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
cout << " Depends: " << D.TargetPkg().Name() << ' ' <<
DeNull(D.TargetVer()) << endl;
+ for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; D++)
+ {
+ cout << " Description Language: " << D.LanguageCode() << endl
+ << " File: " << D.FileList().File().FileName() << endl
+ << " MD5: " << D.md5() << endl;
+ }
}
}
@@ -846,6 +871,7 @@ bool XVcg(CommandLine &CmdL)
then show the relation but do not recurse */
if (Hit == false &&
(D->Type == pkgCache::Dep::Conflicts ||
+ D->Type == pkgCache::Dep::DpkgBreaks ||
D->Type == pkgCache::Dep::Obsoletes))
{
if (Show[D.TargetPkg()->ID] == None &&
@@ -867,6 +893,9 @@ bool XVcg(CommandLine &CmdL)
case pkgCache::Dep::Conflicts:
printf("label: \"conflicts\" color: lightgreen }\n");
break;
+ case pkgCache::Dep::DpkgBreaks:
+ printf("label: \"breaks\" color: lightgreen }\n");
+ break;
case pkgCache::Dep::Obsoletes:
printf("label: \"obsoletes\" color: lightgreen }\n");
break;
@@ -1192,17 +1221,50 @@ bool DisplayRecord(pkgCache::VerIterator V)
if (_error->PendingError() == true)
return false;
- // Read the record and then write it out again.
+ // Read the record
unsigned char *Buffer = new unsigned char[GCache->HeaderP->MaxVerFileSize+1];
Buffer[V.FileList()->Size] = '\n';
if (PkgF.Seek(V.FileList()->Offset) == false ||
- PkgF.Read(Buffer,V.FileList()->Size) == false ||
- fwrite(Buffer,1,V.FileList()->Size+1,stdout) < (size_t)(V.FileList()->Size+1))
+ PkgF.Read(Buffer,V.FileList()->Size) == false)
{
delete [] Buffer;
return false;
}
-
+
+ // Get a pointer to start of Description field
+ const unsigned char *DescP = (unsigned char*)strstr((char*)Buffer, "Description:");
+
+ // Write all but Description
+ if (fwrite(Buffer,1,DescP - Buffer,stdout) < (size_t)(DescP - Buffer))
+ {
+ delete [] Buffer;
+ return false;
+ }
+
+ // Show the right description
+ pkgRecords Recs(*GCache);
+ pkgCache::DescIterator Desc = V.TranslatedDescription();
+ pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
+ cout << "Description" << ( (strcmp(Desc.LanguageCode(),"") != 0) ? "-" : "" ) << Desc.LanguageCode() << ": " << P.LongDesc();
+
+ // Find the first field after the description (if there is any)
+ for(DescP++;DescP != &Buffer[V.FileList()->Size];DescP++)
+ {
+ if(*DescP == '\n' && *(DescP+1) != ' ')
+ {
+ // write the rest of the buffer
+ const unsigned char *end=&Buffer[V.FileList()->Size];
+ if (fwrite(DescP,1,end-DescP,stdout) < (size_t)(end-DescP))
+ {
+ delete [] Buffer;
+ return false;
+ }
+
+ break;
+ }
+ }
+ // write a final newline (after the description)
+ cout<<endl;
delete [] Buffer;
return true;
@@ -1211,9 +1273,9 @@ bool DisplayRecord(pkgCache::VerIterator V)
// Search - Perform a search /*{{{*/
// ---------------------------------------------------------------------
/* This searches the package names and pacakge descriptions for a pattern */
-struct ExVerFile
+struct ExDescFile
{
- pkgCache::VerFile *Vf;
+ pkgCache::DescFile *Df;
bool NameMatch;
};
@@ -1253,35 +1315,35 @@ bool Search(CommandLine &CmdL)
return false;
}
- ExVerFile *VFList = new ExVerFile[Cache.HeaderP->PackageCount+1];
- memset(VFList,0,sizeof(*VFList)*Cache.HeaderP->PackageCount+1);
+ ExDescFile *DFList = new ExDescFile[Cache.HeaderP->PackageCount+1];
+ memset(DFList,0,sizeof(*DFList)*Cache.HeaderP->PackageCount+1);
// Map versions that we want to write out onto the VerList array.
for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
{
- VFList[P->ID].NameMatch = NumPatterns != 0;
+ DFList[P->ID].NameMatch = NumPatterns != 0;
for (unsigned I = 0; I != NumPatterns; I++)
{
if (regexec(&Patterns[I],P.Name(),0,0,0) == 0)
- VFList[P->ID].NameMatch &= true;
+ DFList[P->ID].NameMatch &= true;
else
- VFList[P->ID].NameMatch = false;
+ DFList[P->ID].NameMatch = false;
}
// Doing names only, drop any that dont match..
- if (NamesOnly == true && VFList[P->ID].NameMatch == false)
+ if (NamesOnly == true && DFList[P->ID].NameMatch == false)
continue;
// Find the proper version to use.
pkgCache::VerIterator V = Plcy.GetCandidateVer(P);
if (V.end() == false)
- VFList[P->ID].Vf = V.FileList();
+ DFList[P->ID].Df = V.DescriptionList().FileList();
}
// Include all the packages that provide matching names too
for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
{
- if (VFList[P->ID].NameMatch == false)
+ if (DFList[P->ID].NameMatch == false)
continue;
for (pkgCache::PrvIterator Prv = P.ProvidesList() ; Prv.end() == false; Prv++)
@@ -1289,18 +1351,18 @@ bool Search(CommandLine &CmdL)
pkgCache::VerIterator V = Plcy.GetCandidateVer(Prv.OwnerPkg());
if (V.end() == false)
{
- VFList[Prv.OwnerPkg()->ID].Vf = V.FileList();
- VFList[Prv.OwnerPkg()->ID].NameMatch = true;
+ DFList[Prv.OwnerPkg()->ID].Df = V.DescriptionList().FileList();
+ DFList[Prv.OwnerPkg()->ID].NameMatch = true;
}
}
}
-
- LocalitySort(&VFList->Vf,Cache.HeaderP->PackageCount,sizeof(*VFList));
+
+ LocalitySort(&DFList->Df,Cache.HeaderP->PackageCount,sizeof(*DFList));
// Iterate over all the version records and check them
- for (ExVerFile *J = VFList; J->Vf != 0; J++)
+ for (ExDescFile *J = DFList; J->Df != 0; J++)
{
- pkgRecords::Parser &P = Recs.Lookup(pkgCache::VerFileIterator(Cache,J->Vf));
+ pkgRecords::Parser &P = Recs.Lookup(pkgCache::DescFileIterator(Cache,J->Df));
bool Match = true;
if (J->NameMatch == false)
@@ -1331,7 +1393,7 @@ bool Search(CommandLine &CmdL)
}
}
- delete [] VFList;
+ delete [] DFList;
for (unsigned I = 0; I != NumPatterns; I++)
regfree(&Patterns[I]);
if (ferror(stdout))
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 9b6e36e21..b47c2ec09 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -629,6 +629,8 @@ void CacheFile::Sort()
and verifies that the system is OK. */
bool CacheFile::CheckDeps(bool AllowBroken)
{
+ bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false);
+
if (_error->PendingError() == true)
return false;
@@ -640,12 +642,24 @@ bool CacheFile::CheckDeps(bool AllowBroken)
if (pkgApplyStatus(*DCache) == false)
return false;
+ if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true)
+ {
+ FixBroken = true;
+ if ((DCache->PolicyBrokenCount() > 0))
+ {
+ // upgrade all policy-broken packages with ForceImportantDeps=True
+ for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); I++)
+ if ((*DCache)[I].NowPolicyBroken() == true)
+ DCache->MarkInstall(I,true,0, false, true);
+ }
+ }
+
// Nothing is broken
if (DCache->BrokenCount() == 0 || AllowBroken == true)
return true;
// Attempt to fix broken things
- if (_config->FindB("APT::Get::Fix-Broken",false) == true)
+ if (FixBroken == true)
{
c1out << _("Correcting dependencies...") << flush;
if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
@@ -1146,9 +1160,11 @@ bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
else
ExpectedInst++;
- // Install it with autoinstalling enabled.
- if (State.InstBroken() == true && BrokenFix == false)
+ // Install it with autoinstalling enabled (if we not respect the minial
+ // required deps or the policy)
+ if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false)
Cache.MarkInstall(Pkg,true);
+
return true;
}
/*}}}*/
@@ -1356,20 +1372,29 @@ bool DoUpdate(CommandLine &CmdL)
return false;
bool Failed = false;
+ bool TransientNetworkFailure = false;
for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
{
if ((*I)->Status == pkgAcquire::Item::StatDone)
continue;
(*I)->Finished();
-
+
fprintf(stderr,_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(),
(*I)->ErrorText.c_str());
+
+ if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError)
+ {
+ TransientNetworkFailure = true;
+ continue;
+ }
+
Failed = true;
}
// Clean out any old list files
- if (!Failed && _config->FindB("APT::Get::List-Cleanup",true) == true)
+ if (!TransientNetworkFailure &&
+ _config->FindB("APT::Get::List-Cleanup",true) == true)
{
if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false ||
Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false)
@@ -1381,9 +1406,11 @@ bool DoUpdate(CommandLine &CmdL)
if (Cache.BuildCaches() == false)
return false;
- if (Failed == true)
+ if (TransientNetworkFailure == true)
+ _error->Warning(_("Some index files failed to download, they have been ignored, or old ones used instead."));
+ else if (Failed == true)
return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead."));
-
+
return true;
}
/*}}}*/
@@ -1469,6 +1496,51 @@ bool DoUpgrade(CommandLine &CmdL)
return InstallPackages(Cache,true);
}
/*}}}*/
+// DoInstallTask - Install task from the command line /*{{{*/
+// ---------------------------------------------------------------------
+/* Install named task */
+bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix,
+ bool BrokenFix,
+ unsigned int& ExpectedInst,
+ const char *taskname)
+{
+ const char *start, *end;
+ pkgCache::PkgIterator Pkg;
+ char buf[64*1024];
+ regex_t Pattern;
+
+ // get the records
+ pkgRecords Recs(Cache);
+
+ // build regexp for the task
+ char S[300];
+ snprintf(S, sizeof(S), "^Task:.*[^a-z]%s[^a-z].*\n", taskname);
+ regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
+
+ bool found = false;
+ bool res = true;
+ for (Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
+ {
+ pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache);
+ if(ver.end())
+ continue;
+ pkgRecords::Parser &parser = Recs.Lookup(ver.FileList());
+ parser.GetRec(start,end);
+ strncpy(buf, start, end-start);
+ buf[end-start] = 0x0;
+ if (regexec(&Pattern,buf,0,0,0) != 0)
+ continue;
+ res &= TryToInstall(Pkg,Cache,Fix,false,BrokenFix,ExpectedInst);
+ found = true;
+ }
+
+ if(!found)
+ _error->Error(_("Couldn't find task %s"),taskname);
+
+ regfree(&Pattern);
+ return res;
+}
+
// DoInstall - Install packages from the command line /*{{{*/
// ---------------------------------------------------------------------
/* Install named packages */
@@ -1648,8 +1720,10 @@ bool DoInstall(CommandLine &CmdL)
return _error->Error(_("Broken packages"));
}
}
- if (!DoAutomaticRemove(Cache))
+ if (_config->FindB("APT::Get::AutomaticRemove")) {
+ if (!DoAutomaticRemove(Cache))
return false;
+ }
/* Print out a list of packages that are going to be installed extra
to what the user asked */
@@ -2560,6 +2634,7 @@ void GetInitialize()
_config->Set("APT::Get::Fix-Broken",false);
_config->Set("APT::Get::Force-Yes",false);
_config->Set("APT::Get::List-Cleanup",true);
+ _config->Set("APT::Get::AutomaticRemove",false);
}
/*}}}*/
// SigWinch - Window size change signal handler /*{{{*/
@@ -2617,6 +2692,8 @@ int main(int argc,const char *argv[])
{0,"arch-only","APT::Get::Arch-Only",0},
{0,"auto-remove","APT::Get::AutomaticRemove",0},
{0,"allow-unauthenticated","APT::Get::AllowUnauthenticated",0},
+ {0,"install-recommends","APT::Install-Recommends",CommandLine::Boolean},
+ {0,"fix-policy","APT::Get::Fix-Policy-Broken",0},
{'c',"config-file",0,CommandLine::ConfigFile},
{'o',"option",0,CommandLine::ArbItem},
{0,0,0,0}};