summaryrefslogtreecommitdiff
path: root/cmdline
diff options
context:
space:
mode:
authorMichael Vogt <mvo@debian.org>2013-08-15 09:26:00 +0200
committerMichael Vogt <mvo@debian.org>2013-08-15 09:26:00 +0200
commitd7a4635391d9ff36152603ab6faa6eafa206750a (patch)
treee16a562e3e9a195cae286433c5751a1ab9990635 /cmdline
parent2a49601f69e08f06fb2727d869d420daacdd09d5 (diff)
parent183116d1a64a2610b88fa6b50f2c5199b69d5841 (diff)
Merge branch 'debian/sid' into debian/experimental
Conflicts: apt-pkg/contrib/strutl.cc apt-pkg/deb/dpkgpm.cc configure.ac debian/changelog doc/po/apt-doc.pot po/apt-all.pot po/ar.po po/ast.po po/bg.po po/bs.po po/ca.po po/cs.po po/cy.po po/da.po po/de.po po/dz.po po/el.po po/es.po po/eu.po po/fi.po po/fr.po po/gl.po po/hu.po po/it.po po/ja.po po/km.po po/ko.po po/ku.po po/lt.po po/mr.po po/nb.po po/ne.po po/nl.po po/nn.po po/pl.po po/pt.po po/pt_BR.po po/ro.po po/ru.po po/sk.po po/sl.po po/sv.po po/th.po po/tl.po po/uk.po po/vi.po po/zh_CN.po po/zh_TW.po test/integration/framework test/integration/test-bug-602412-dequote-redirect test/integration/test-ubuntu-bug-346386-apt-get-update-paywall test/interactive-helper/aptwebserver.cc test/interactive-helper/makefile
Diffstat (limited to 'cmdline')
-rw-r--r--cmdline/apt-cache.cc176
-rw-r--r--cmdline/apt-cdrom.cc34
-rw-r--r--cmdline/apt-get.cc49
-rwxr-xr-xcmdline/apt-key192
-rw-r--r--cmdline/apt-mark.cc4
-rw-r--r--cmdline/makefile2
6 files changed, 332 insertions, 125 deletions
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index 0a2c28d23..e847de875 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -1127,6 +1127,24 @@ bool Dotty(CommandLine &CmdL)
// ---------------------------------------------------------------------
/* This displays the package record from the proper package index file.
It is not used by DumpAvail for performance reasons. */
+
+static unsigned char const* skipDescriptionFields(unsigned char const * DescP)
+{
+ char const * const TagName = "\nDescription";
+ size_t const TagLen = strlen(TagName);
+ while ((DescP = (unsigned char*)strchr((char*)DescP, '\n')) != NULL)
+ {
+ if (DescP[1] == ' ')
+ DescP += 2;
+ else if (strncmp((char*)DescP, TagName, TagLen) == 0)
+ DescP += TagLen;
+ else
+ break;
+ }
+ if (DescP != NULL)
+ ++DescP;
+ return DescP;
+}
bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
{
pkgCache *Cache = CacheFile.GetPkgCache();
@@ -1150,21 +1168,27 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
if (PkgF.Open(I.FileName(), FileFd::ReadOnly, FileFd::Extension) == false)
return false;
- // Read the record
- unsigned char *Buffer = new unsigned char[Cache->HeaderP->MaxVerFileSize+1];
- Buffer[V.FileList()->Size] = '\n';
- if (PkgF.Seek(V.FileList()->Offset) == false ||
- PkgF.Read(Buffer,V.FileList()->Size) == false)
+ // Read the record (and ensure that it ends with a newline and NUL)
+ unsigned char *Buffer = new unsigned char[Cache->HeaderP->MaxVerFileSize+2];
+ Buffer[Vf->Size] = '\n';
+ Buffer[Vf->Size+1] = '\0';
+ if (PkgF.Seek(Vf->Offset) == false ||
+ PkgF.Read(Buffer,Vf->Size) == false)
{
delete [] Buffer;
return false;
}
// Get a pointer to start of Description field
- const unsigned char *DescP = (unsigned char*)strstr((char*)Buffer, "Description:");
+ const unsigned char *DescP = (unsigned char*)strstr((char*)Buffer, "\nDescription");
+ if (DescP != NULL)
+ ++DescP;
+ else
+ DescP = Buffer + Vf->Size;
// Write all but Description
- if (fwrite(Buffer,1,DescP - Buffer,stdout) < (size_t)(DescP - Buffer))
+ size_t const length = DescP - Buffer;
+ if (length != 0 && FileFd::Write(STDOUT_FILENO, Buffer, length) == false)
{
delete [] Buffer;
return false;
@@ -1173,29 +1197,44 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
// Show the right description
pkgRecords Recs(*Cache);
pkgCache::DescIterator Desc = V.TranslatedDescription();
- pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
- cout << "Description" << ( (strcmp(Desc.LanguageCode(),"") != 0) ? "-" : "" ) << Desc.LanguageCode() << ": " << P.LongDesc();
+ if (Desc.end() == false)
+ {
+ pkgRecords::Parser &P = Recs.Lookup(Desc.FileList());
+ cout << "Description" << ( (strcmp(Desc.LanguageCode(),"") != 0) ? "-" : "" ) << Desc.LanguageCode() << ": " << P.LongDesc();
+ cout << std::endl << "Description-md5: " << Desc.md5() << std::endl;
+
+ // Find the first field after the description (if there is any)
+ DescP = skipDescriptionFields(DescP);
+ }
+ // else we have no translation, so we found a lonely Description-md5 -> don't skip it
- // Find the first field after the description (if there is any)
- for(DescP++;DescP != &Buffer[V.FileList()->Size];DescP++)
+ // write the rest of the buffer, but skip mixed in Descriptions* fields
+ while (DescP != NULL)
{
- if(*DescP == '\n' && *(DescP+1) != ' ')
+ const unsigned char * const Start = DescP;
+ const unsigned char *End = (unsigned char*)strstr((char*)DescP, "\nDescription");
+ if (End == NULL)
{
- // 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;
+ End = &Buffer[Vf->Size];
+ DescP = NULL;
+ }
+ else
+ {
+ ++End; // get the newline into the output
+ DescP = skipDescriptionFields(End + strlen("Description"));
+ }
+ size_t const length = End - Start;
+ if (length != 0 && FileFd::Write(STDOUT_FILENO, Start, length) == false)
+ {
+ delete [] Buffer;
+ return false;
}
}
- // write a final newline (after the description)
+
+ // write a final newline after the last field
cout<<endl;
- delete [] Buffer;
+ delete [] Buffer;
return true;
}
/*}}}*/
@@ -1203,7 +1242,7 @@ bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
struct ExDescFile
{
pkgCache::DescFile *Df;
- bool NameMatch;
+ map_ptrloc ID;
};
// Search - Perform a search /*{{{*/
@@ -1246,37 +1285,52 @@ bool Search(CommandLine &CmdL)
return false;
}
- ExDescFile *DFList = new ExDescFile[Cache->HeaderP->GroupCount+1];
- memset(DFList,0,sizeof(*DFList)*Cache->HeaderP->GroupCount+1);
+ size_t const descCount = Cache->HeaderP->GroupCount + 1;
+ ExDescFile *DFList = new ExDescFile[descCount];
+ memset(DFList,0,sizeof(*DFList) * descCount);
+
+ bool PatternMatch[descCount * NumPatterns];
+ memset(PatternMatch,false,sizeof(PatternMatch));
// Map versions that we want to write out onto the VerList array.
for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() == false; ++G)
{
- if (DFList[G->ID].NameMatch == true)
- continue;
-
- DFList[G->ID].NameMatch = true;
- for (unsigned I = 0; I != NumPatterns; I++)
+ size_t const PatternOffset = G->ID * NumPatterns;
+ size_t unmatched = 0, matched = 0;
+ for (unsigned I = 0; I < NumPatterns; ++I)
{
- if (regexec(&Patterns[I],G.Name(),0,0,0) == 0)
- continue;
- DFList[G->ID].NameMatch = false;
- break;
+ if (PatternMatch[PatternOffset + I] == true)
+ ++matched;
+ else if (regexec(&Patterns[I],G.Name(),0,0,0) == 0)
+ PatternMatch[PatternOffset + I] = true;
+ else
+ ++unmatched;
}
-
- // Doing names only, drop any that dont match..
- if (NamesOnly == true && DFList[G->ID].NameMatch == false)
+
+ // already dealt with this package?
+ if (matched == NumPatterns)
continue;
-
+
+ // Doing names only, drop any that don't match..
+ if (NamesOnly == true && unmatched == NumPatterns)
+ continue;
+
// Find the proper version to use
pkgCache::PkgIterator P = G.FindPreferredPkg();
if (P.end() == true)
continue;
pkgCache::VerIterator V = Plcy->GetCandidateVer(P);
if (V.end() == false)
- DFList[G->ID].Df = V.TranslatedDescription().FileList();
+ {
+ pkgCache::DescIterator const D = V.TranslatedDescription();
+ //FIXME: packages without a description can't be found
+ if (D.end() == true)
+ continue;
+ DFList[G->ID].Df = D.FileList();
+ DFList[G->ID].ID = G->ID;
+ }
- if (DFList[G->ID].NameMatch == false)
+ if (unmatched == NumPatterns)
continue;
// Include all the packages that provide matching names too
@@ -1287,34 +1341,50 @@ bool Search(CommandLine &CmdL)
continue;
unsigned long id = Prv.OwnerPkg().Group()->ID;
- DFList[id].Df = V.TranslatedDescription().FileList();
- DFList[id].NameMatch = true;
+ pkgCache::DescIterator const D = V.TranslatedDescription();
+ //FIXME: packages without a description can't be found
+ if (D.end() == true)
+ continue;
+ DFList[id].Df = D.FileList();
+ DFList[id].ID = id;
+
+ size_t const PrvPatternOffset = id * NumPatterns;
+ for (unsigned I = 0; I < NumPatterns; ++I)
+ PatternMatch[PrvPatternOffset + I] = PatternMatch[PatternOffset + I];
}
}
-
+
LocalitySort(&DFList->Df,Cache->HeaderP->GroupCount,sizeof(*DFList));
// Create the text record parser
pkgRecords Recs(*Cache);
// Iterate over all the version records and check them
- for (ExDescFile *J = DFList; J->Df != 0; J++)
+ for (ExDescFile *J = DFList; J->Df != 0; ++J)
{
pkgRecords::Parser &P = Recs.Lookup(pkgCache::DescFileIterator(*Cache,J->Df));
+ size_t const PatternOffset = J->ID * NumPatterns;
- if (J->NameMatch == false && NamesOnly == false)
+ if (NamesOnly == false)
{
string const LongDesc = P.LongDesc();
- J->NameMatch = true;
- for (unsigned I = 0; I != NumPatterns; I++)
+ for (unsigned I = 0; I < NumPatterns; ++I)
{
- if (regexec(&Patterns[I],LongDesc.c_str(),0,0,0) == 0)
+ if (PatternMatch[PatternOffset + I] == true)
continue;
- J->NameMatch = false;
- break;
+ else if (regexec(&Patterns[I],LongDesc.c_str(),0,0,0) == 0)
+ PatternMatch[PatternOffset + I] = true;
}
}
-
- if (J->NameMatch == true)
+
+ bool matchedAll = true;
+ for (unsigned I = 0; I < NumPatterns; ++I)
+ if (PatternMatch[PatternOffset + I] == false)
+ {
+ matchedAll = false;
+ break;
+ }
+
+ if (matchedAll == true)
{
if (ShowFull == true)
{
diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc
index 2551f4916..a95970782 100644
--- a/cmdline/apt-cdrom.cc
+++ b/cmdline/apt-cdrom.cc
@@ -39,6 +39,12 @@
#include <apti18n.h>
/*}}}*/
+static const char *W_NO_CDROM_FOUND = \
+ N_("No CD-ROM could be auto-detected or found using "
+ "the default mount point.\n"
+ "You may try the --cdrom option to set the CD-ROM mount point. "
+ "See 'man apt-cdrom' for more "
+ "information about the CD-ROM auto-detection and mount point.");
using namespace std;
@@ -60,7 +66,9 @@ void pkgCdromTextStatus::Prompt(const char *Text)
{
char C;
cout << Text << ' ' << flush;
- read(STDIN_FILENO,&C,1);
+ if (read(STDIN_FILENO,&C,1) < 0)
+ _error->Errno("pkgCdromTextStatus::Prompt",
+ "Failed to read from standard input (not a terminal?)");
if (C != '\n')
cout << endl;
}
@@ -135,7 +143,6 @@ bool AutoDetectCdrom(pkgUdevCdromDevices &UdevCdroms, unsigned int &i)
return true;
}
/*}}}*/
-
// DoAdd - Add a new CDROM /*{{{*/
// ---------------------------------------------------------------------
/* This does the main add bit.. We show some status and things. The
@@ -150,13 +157,15 @@ bool DoAdd(CommandLine &)
bool res = true;
bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect", true);
+ unsigned int count = 0;
if (AutoDetect && UdevCdroms.Dlopen())
- {
- unsigned int count = 0;
while (AutoDetectCdrom(UdevCdroms, count))
res &= cdrom.Add(&log);
- } else {
+ if (count == 0) {
res = cdrom.Add(&log);
+ if (res == false) {
+ _error->Error("%s", _(W_NO_CDROM_FOUND));
+ }
}
if(res)
@@ -178,15 +187,16 @@ bool DoIdent(CommandLine &)
bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect");
+ unsigned int count = 0;
if (AutoDetect && UdevCdroms.Dlopen())
- {
- unsigned int count = 0;
while (AutoDetectCdrom(UdevCdroms, count))
res &= cdrom.Ident(ident, &log);
- } else {
- return cdrom.Ident(ident, &log);
+ if (count == 0) {
+ res = cdrom.Ident(ident, &log);
+ if (res == false) {
+ _error->Error("%s", _(W_NO_CDROM_FOUND));
+ }
}
-
return res;
}
/*}}}*/
@@ -218,7 +228,7 @@ int ShowHelp()
" -m No mounting\n"
" -f Fast mode, don't check package files\n"
" -a Thorough scan mode\n"
- " --auto-detect Auto detect drive and mount point\n"
+ " --no-auto-detect Do not try to auto detect drive and mount point\n"
" -c=? Read this configuration file\n"
" -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
"See fstab(5)\n";
@@ -229,7 +239,7 @@ int main(int argc,const char *argv[]) /*{{{*/
{
CommandLine::Args Args[] = {
{'h',"help","help",0},
- { 0,"auto-detect","Acquire::cdrom::AutoDetect",0},
+ { 0,"auto-detect","Acquire::cdrom::AutoDetect", CommandLine::Boolean},
{'v',"version","version",0},
{'d',"cdrom","Acquire::cdrom::mount",CommandLine::HasArg},
{'r',"rename","APT::CDROM::Rename",0},
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index cce80ccfe..06daca09b 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -130,13 +130,42 @@ class CacheFile : public pkgCacheFile
/* Returns true on a Yes.*/
bool YnPrompt(bool Default=true)
{
+ /* nl_langinfo does not support LANGUAGE setting, so we unset it here
+ to have the help-message (hopefully) match the expected characters */
+ char * language = getenv("LANGUAGE");
+ if (language != NULL)
+ language = strdup(language);
+ if (language != NULL)
+ unsetenv("LANGUAGE");
+
+ if (Default == true)
+ // TRANSLATOR: Yes/No question help-text: defaulting to Y[es]
+ // e.g. "Do you want to continue? [Y/n] "
+ // The user has to answer with an input matching the
+ // YESEXPR/NOEXPR defined in your l10n.
+ c2out << " " << _("[Y/n]") << " " << std::flush;
+ else
+ // TRANSLATOR: Yes/No question help-text: defaulting to N[o]
+ // e.g. "Should this file be removed? [y/N] "
+ // The user has to answer with an input matching the
+ // YESEXPR/NOEXPR defined in your l10n.
+ c2out << " " << _("[y/N]") << " " << std::flush;
+
+ if (language != NULL)
+ {
+ setenv("LANGUAGE", language, 0);
+ free(language);
+ }
+
if (_config->FindB("APT::Get::Assume-Yes",false) == true)
{
+ // TRANSLATOR: "Yes" answer printed for a yes/no question if --assume-yes is set
c1out << _("Y") << endl;
return true;
}
else if (_config->FindB("APT::Get::Assume-No",false) == true)
{
+ // TRANSLATOR: "No" answer printed for a yes/no question if --assume-no is set
c1out << _("N") << endl;
return false;
}
@@ -1076,7 +1105,7 @@ static bool CheckAuth(pkgAcquire& Fetcher)
if (_config->FindI("quiet",0) < 2
&& _config->FindB("APT::Get::Assume-Yes",false) == false)
{
- c2out << _("Install these packages without verification [y/N]? ") << flush;
+ c2out << _("Install these packages without verification?") << flush;
if (!YnPrompt(false))
return _error->Error(_("Some packages could not be authenticated"));
@@ -1281,8 +1310,8 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
if (_config->FindI("quiet",0) < 2 &&
_config->FindB("APT::Get::Assume-Yes",false) == false)
{
- c2out << _("Do you want to continue [Y/n]? ") << flush;
-
+ c2out << _("Do you want to continue?") << flush;
+
if (YnPrompt() == false)
{
c2out << _("Abort.") << endl;
@@ -1965,7 +1994,6 @@ bool DoInstall(CommandLine &CmdL)
if (Fix != NULL)
{
// Call the scored problem resolver
- Fix->InstallProtect();
Fix->Resolve(true);
delete Fix;
}
@@ -2297,9 +2325,10 @@ bool DoClean(CommandLine &CmdL)
FileFd Lock;
if (_config->FindB("Debug::NoLocking",false) == false)
{
- Lock.Fd(GetLock(archivedir + "lock"));
- if (_error->PendingError() == true)
+ int lock_fd = GetLock(archivedir + "lock");
+ if (lock_fd < 0)
return _error->Error(_("Unable to lock the download directory"));
+ Lock.Fd(lock_fd);
}
pkgAcquire Fetcher;
@@ -2333,9 +2362,10 @@ bool DoAutoClean(CommandLine &CmdL)
FileFd Lock;
if (_config->FindB("Debug::NoLocking",false) == false)
{
- Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
- if (_error->PendingError() == true)
+ int lock_fd = GetLock(_config->FindDir("Dir::Cache::Archives") + "lock");
+ if (lock_fd < 0)
return _error->Error(_("Unable to lock the download directory"));
+ Lock.Fd(lock_fd);
}
CacheFile Cache;
@@ -3126,8 +3156,7 @@ bool DoBuildDep(CommandLine &CmdL)
}
}
}
-
- Fix.InstallProtect();
+
if (Fix.Resolve(true) == false)
_error->Discard();
diff --git a/cmdline/apt-key b/cmdline/apt-key
index c184e3e75..713a41c07 100755
--- a/cmdline/apt-key
+++ b/cmdline/apt-key
@@ -3,27 +3,39 @@
set -e
unset GREP_OPTIONS
-# We don't use a secret keyring, of course, but gpg panics and
-# implodes if there isn't one available
-SECRETKEYRING="$(mktemp)"
-trap "rm -f '${SECRETKEYRING}'" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
-GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring ${SECRETKEYRING}"
-
-if [ "$(id -u)" -eq 0 ]; then
- # we could use a tmpfile here too, but creation of this tends to be time-consuming
- eval $(apt-config shell TRUSTDBDIR Dir::Etc/d)
- GPG_CMD="$GPG_CMD --trustdb-name ${TRUSTDBDIR}/trustdb.gpg"
-fi
+GPG_CMD="gpg --ignore-time-conflict --no-options --no-default-keyring"
+
+# gpg needs a trustdb to function, but it can't be invalid (not even empty)
+# so we create a temporary directory to store our fresh readable trustdb in
+TRUSTDBDIR="$(mktemp -d)"
+CURRENTTRAP="${CURRENTTRAP} rm -rf '${TRUSTDBDIR}';"
+trap "${CURRENTTRAP}" 0 HUP INT QUIT ILL ABRT FPE SEGV PIPE TERM
+chmod 700 "$TRUSTDBDIR"
+# We also don't use a secret keyring, of course, but gpg panics and
+# implodes if there isn't one available - and writeable for imports
+SECRETKEYRING="${TRUSTDBDIR}/secring.gpg"
+touch $SECRETKEYRING
+GPG_CMD="$GPG_CMD --secret-keyring $SECRETKEYRING"
+GPG_CMD="$GPG_CMD --trustdb-name ${TRUSTDBDIR}/trustdb.gpg"
+
+# now create the trustdb with an (empty) dummy keyring
+$GPG_CMD --quiet --check-trustdb --keyring $SECRETKEYRING
+# and make sure that gpg isn't trying to update the file
+GPG_CMD="$GPG_CMD --no-auto-check-trustdb --trust-model always"
GPG="$GPG_CMD"
MASTER_KEYRING=""
-ARCHIVE_KEYRING_URI=""
#MASTER_KEYRING=/usr/share/keyrings/debian-master-keyring.gpg
+eval $(apt-config shell MASTER_KEYRING APT::Key::MasterKeyring)
+ARCHIVE_KEYRING_URI=""
#ARCHIVE_KEYRING_URI=http://ftp.debian.org/debian/debian-archive-keyring.gpg
+eval $(apt-config shell ARCHIVE_KEYRING_URI APT::Key::ArchiveKeyringURI)
ARCHIVE_KEYRING=/usr/share/keyrings/debian-archive-keyring.gpg
+eval $(apt-config shell ARCHIVE_KEYRING APT::Key::ArchiveKeyring)
REMOVED_KEYS=/usr/share/keyrings/debian-archive-removed-keys.gpg
+eval $(apt-config shell REMOVED_KEYS APT::Key::RemovedKeys)
requires_root() {
if [ "$(id -u)" -ne 0 ]; then
@@ -32,6 +44,16 @@ requires_root() {
fi
}
+# gpg defaults to mode 0600 for new keyrings. Create one with 0644 instead.
+init_keyring() {
+ for path; do
+ if ! [ -e "$path" ]; then
+ touch -- "$path"
+ chmod 0644 -- "$path"
+ fi
+ done
+}
+
add_keys_with_verify_against_master_keyring() {
ADD_KEYRING=$1
MASTER=$2
@@ -129,6 +151,60 @@ update() {
fi
}
+remove_key_from_keyring() {
+ local GPG="$GPG_CMD --keyring $1"
+ # check if the key is in this keyring: the key id is in the 5 column at the end
+ if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+$2:"; then
+ return
+ fi
+ if [ ! -w "$1" ]; then
+ echo >&2 "Key ${2} is in keyring ${1}, but can't be removed as it is read only."
+ return
+ fi
+ # check if it is the only key in the keyring and if so remove the keyring alltogether
+ if [ '1' = "$($GPG --with-colons --list-keys | grep "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+:" | wc -l)" ]; then
+ mv -f "$1" "${1}~" # behave like gpg
+ return
+ fi
+ # we can't just modify pointed to files as these might be in /usr or something
+ local REALTARGET
+ if [ -L "$1" ]; then
+ REALTARGET="$(readlink -f "$1")"
+ mv -f "$1" "${1}.dpkg-tmp"
+ cp -a "$REALTARGET" "$1"
+ ls "$(dirname $1)"
+ fi
+ # delete the key from the keyring
+ $GPG --batch --delete-key --yes "$2"
+ if [ -n "$REALTARGET" ]; then
+ # the real backup is the old link, not the copy we made
+ mv -f "${1}.dpkg-tmp" "${1}~"
+ fi
+}
+
+remove_key() {
+ requires_root
+
+ # if a --keyring was given, just remove from there
+ if [ -n "$FORCED_KEYRING" ]; then
+ remove_key_from_keyring "$FORCED_KEYRING" "$1"
+ else
+ # otherwise all known keyrings are up for inspection
+ local TRUSTEDFILE="/etc/apt/trusted.gpg"
+ eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
+ eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
+ remove_key_from_keyring "$TRUSTEDFILE" "$1"
+ TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
+ eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
+ if [ -d "$TRUSTEDPARTS" ]; then
+ for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do
+ remove_key_from_keyring "$trusted" "$1"
+ done
+ fi
+ fi
+ echo "OK"
+}
+
usage() {
echo "Usage: apt-key [--keyring file] [command] [arguments]"
@@ -148,39 +224,54 @@ usage() {
echo "If no specific keyring file is given the command applies to all keyring files."
}
-# Determine on which keyring we want to work
-if [ "$1" = "--keyring" ]; then
- #echo "keyfile given"
- shift
- TRUSTEDFILE="$1"
- if [ -r "$TRUSTEDFILE" ] || [ "$2" = 'add' ]; then
- GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE"
- else
- echo >&2 "Error: The specified keyring »$TRUSTEDFILE« is missing or not readable"
- exit 1
- fi
- shift
-# otherwise use the default
-else
- #echo "generate list"
- TRUSTEDFILE="/etc/apt/trusted.gpg"
- eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
- eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
- if [ -r "$TRUSTEDFILE" ]; then
- GPG="$GPG --keyring $TRUSTEDFILE"
- fi
- GPG="$GPG --primary-keyring $TRUSTEDFILE"
- TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
- eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
- if [ -d "$TRUSTEDPARTS" ]; then
- #echo "parts active"
- for trusted in $(run-parts --list $TRUSTEDPARTS --regex '^.*\.gpg$'); do
- #echo "part -> $trusted"
- GPG="$GPG --keyring $trusted"
- done
- fi
+while [ -n "$1" ]; do
+ case "$1" in
+ --keyring)
+ shift
+ TRUSTEDFILE="$1"
+ FORCED_KEYRING="$1"
+ if [ -r "$TRUSTEDFILE" ] || [ "$2" = 'add' ] || [ "$2" = 'adv' ]; then
+ GPG="$GPG --keyring $TRUSTEDFILE --primary-keyring $TRUSTEDFILE"
+ else
+ echo >&2 "Error: The specified keyring »$TRUSTEDFILE« is missing or not readable"
+ exit 1
+ fi
+ shift
+ ;;
+ --fakeroot)
+ requires_root() { true; }
+ shift
+ ;;
+ --*)
+ echo >&2 "Unknown option: $1"
+ usage
+ exit 1;;
+ *)
+ break;;
+ esac
+done
+
+if [ -z "$TRUSTEDFILE" ]; then
+ TRUSTEDFILE="/etc/apt/trusted.gpg"
+ eval $(apt-config shell TRUSTEDFILE Apt::GPGV::TrustedKeyring)
+ eval $(apt-config shell TRUSTEDFILE Dir::Etc::Trusted/f)
+ if [ -r "$TRUSTEDFILE" ]; then
+ GPG="$GPG --keyring $TRUSTEDFILE"
+ fi
+ GPG="$GPG --primary-keyring $TRUSTEDFILE"
+ TRUSTEDPARTS="/etc/apt/trusted.gpg.d"
+ eval $(apt-config shell TRUSTEDPARTS Dir::Etc::TrustedParts/d)
+ if [ -d "$TRUSTEDPARTS" ]; then
+ # strip / suffix as gpg will double-slash in that case (#665411)
+ STRIPPED_TRUSTEDPARTS="${TRUSTEDPARTS%/}"
+ if [ "${STRIPPED_TRUSTEDPARTS}/" = "$TRUSTEDPARTS" ]; then
+ TRUSTEDPARTS="$STRIPPED_TRUSTEDPARTS"
+ fi
+ for trusted in $(run-parts --list "$TRUSTEDPARTS" --regex '^.*\.gpg$'); do
+ GPG="$GPG --keyring $trusted"
+ done
+ fi
fi
-#echo "COMMAND: $GPG"
command="$1"
if [ -z "$command" ]; then
@@ -198,33 +289,40 @@ fi
case "$command" in
add)
requires_root
+ init_keyring "$TRUSTEDFILE"
$GPG --quiet --batch --import "$1"
echo "OK"
;;
del|rm|remove)
- requires_root
- $GPG --quiet --batch --delete-key --yes "$1"
- echo "OK"
+ init_keyring "$TRUSTEDFILE"
+ remove_key "$1"
;;
update)
+ init_keyring "$TRUSTEDFILE"
update
;;
net-update)
+ init_keyring "$TRUSTEDFILE"
net_update
;;
list)
+ init_keyring "$TRUSTEDFILE"
$GPG --batch --list-keys
;;
finger*)
+ init_keyring "$TRUSTEDFILE"
$GPG --batch --fingerprint
;;
export)
+ init_keyring "$TRUSTEDFILE"
$GPG --armor --export "$1"
;;
exportall)
+ init_keyring "$TRUSTEDFILE"
$GPG --armor --export
;;
adv*)
+ init_keyring "$TRUSTEDFILE"
echo "Executing: $GPG $*"
$GPG $*
;;
diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc
index c5b7ca496..4c0fc2893 100644
--- a/cmdline/apt-mark.cc
+++ b/cmdline/apt-mark.cc
@@ -202,13 +202,13 @@ bool DoHold(CommandLine &CmdL)
if (dpkgAssertMultiArch == 0)
{
std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory");
- if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0)
- _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --assert-multi-arch", chrootDir.c_str());
// redirect everything to the ultimate sink as we only need the exit-status
int const nullfd = open("/dev/null", O_RDONLY);
dup2(nullfd, STDIN_FILENO);
dup2(nullfd, STDOUT_FILENO);
dup2(nullfd, STDERR_FILENO);
+ if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0)
+ _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --assert-multi-arch", chrootDir.c_str());
execvp(Args[0], (char**) &Args[0]);
_error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!");
_exit(2);
diff --git a/cmdline/makefile b/cmdline/makefile
index f3712232a..460a71240 100644
--- a/cmdline/makefile
+++ b/cmdline/makefile
@@ -14,7 +14,7 @@ include $(PROGRAM_H)
# The apt-get program
PROGRAM=apt-get
-SLIBS = -lapt-pkg -lutil $(INTLLIBS)
+SLIBS = -lapt-pkg $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
SOURCE = apt-get.cc acqprogress.cc
include $(PROGRAM_H)