summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/policy.cc19
-rw-r--r--apt-pkg/sourcelist.cc228
-rw-r--r--apt-pkg/sourcelist.h16
-rw-r--r--apt-pkg/tagfile.cc8
-rw-r--r--apt-pkg/tagfile.h8
-rw-r--r--doc/sources.list.5.xml337
-rwxr-xr-xtest/integration/test-apt-sources-deb82275
-rw-r--r--test/libapt/file-helpers.cc11
-rw-r--r--test/libapt/sourcelist_test.cc15
-rw-r--r--vendor/README8
-rw-r--r--vendor/blankon/apt-vendor.ent9
-rw-r--r--vendor/debian/apt-vendor.ent12
-rw-r--r--vendor/debian/sources.list.in3
-rw-r--r--vendor/raspbian/apt-vendor.ent6
-rw-r--r--vendor/steamos/apt-vendor.ent7
-rw-r--r--vendor/steamos/sources.list.in4
-rw-r--r--vendor/tanglu/apt-vendor.ent6
-rw-r--r--vendor/ubuntu/apt-vendor.ent13
18 files changed, 500 insertions, 285 deletions
diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc
index cd48e040c..170da7c63 100644
--- a/apt-pkg/policy.cc
+++ b/apt-pkg/policy.cc
@@ -396,21 +396,6 @@ APT_PURE signed short pkgPolicy::GetPriority(pkgCache::PkgFileIterator const &Fi
return PFPriority[File->ID];
}
/*}}}*/
-// PreferenceSection class - Overriding the default TrimRecord method /*{{{*/
-// ---------------------------------------------------------------------
-/* The preference file is a user generated file so the parser should
- therefore be a bit more friendly by allowing comments and new lines
- all over the place rather than forcing a special format */
-class PreferenceSection : public pkgTagSection
-{
- void TrimRecord(bool /*BeforeRecord*/, const char* &End)
- {
- for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r' || Stop[0] == '#'); Stop++)
- if (Stop[0] == '#')
- Stop = (const char*) memchr(Stop,'\n',End-Stop);
- }
-};
- /*}}}*/
// ReadPinDir - Load the pin files from this dir into a Policy /*{{{*/
// ---------------------------------------------------------------------
/* This will load each pin file in the given dir into a Policy. If the
@@ -455,8 +440,8 @@ bool ReadPinFile(pkgPolicy &Plcy,string File)
pkgTagFile TF(&Fd);
if (_error->PendingError() == true)
return false;
-
- PreferenceSection Tags;
+
+ pkgUserTagSection Tags;
while (TF.Step(Tags) == true)
{
// can happen when there are only comments in a record
diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc
index 6ef99863d..69f7ac043 100644
--- a/apt-pkg/sourcelist.cc
+++ b/apt-pkg/sourcelist.cc
@@ -82,15 +82,15 @@ bool pkgSourceList::Type::FixupURI(string &URI) const
return true;
}
/*}}}*/
-bool pkgSourceList::Type::ParseStanza(vector<metaIndex *> &List,
+bool pkgSourceList::Type::ParseStanza(vector<metaIndex *> &List, /*{{{*/
pkgTagSection &Tags,
- int i,
+ unsigned int const i,
FileFd &Fd)
{
map<string, string> Options;
string Enabled = Tags.FindS("Enabled");
- if (Enabled.size() > 0 && StringToBool(Enabled) == false)
+ if (Enabled.empty() == false && StringToBool(Enabled) == false)
return true;
std::map<char const * const, char const * const> mapping;
@@ -115,46 +115,63 @@ bool pkgSourceList::Type::ParseStanza(vector<metaIndex *> &List,
// now create one item per suite/section
string Suite = Tags.FindS("Suites");
Suite = SubstVar(Suite,"$(ARCH)",_config->Find("APT::Architecture"));
- string const Section = Tags.FindS("Sections");
- string URIS = Tags.FindS("URIs");
+ string const Component = Tags.FindS("Components");
+ string const URIS = Tags.FindS("URIs");
+
+ std::vector<std::string> const list_uris = VectorizeString(URIS, ' ');
+ std::vector<std::string> const list_suite = VectorizeString(Suite, ' ');
+ std::vector<std::string> const list_comp = VectorizeString(Component, ' ');
+
+ if (list_uris.empty())
+ // TRANSLATOR: %u is a line number, the first %s is a filename of a file with the extension "second %s" and the third %s is a unique identifier for bugreports
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), i, "sources", Fd.Name().c_str(), "URI");
- std::vector<std::string> list_uris = StringSplit(URIS, " ");
- std::vector<std::string> list_dist = StringSplit(Suite, " ");
- std::vector<std::string> list_section = StringSplit(Section, " ");
-
for (std::vector<std::string>::const_iterator U = list_uris.begin();
U != list_uris.end(); ++U)
{
- std::string URI = (*U);
- if (!FixupURI(URI))
- {
- _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str());
- return false;
- }
+ std::string URI = *U;
+ if (U->empty() || FixupURI(URI) == false)
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), i, "sources", Fd.Name().c_str(), "URI parse");
+
+ if (list_suite.empty())
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), i, "sources", Fd.Name().c_str(), "Suite");
- for (std::vector<std::string>::const_iterator I = list_dist.begin();
- I != list_dist.end(); ++I)
+ for (std::vector<std::string>::const_iterator S = list_suite.begin();
+ S != list_suite.end(); ++S)
{
- for (std::vector<std::string>::const_iterator J = list_section.begin();
- J != list_section.end(); ++J)
- {
- if (CreateItem(List, URI, (*I), (*J), Options) == false)
- {
- return false;
- }
- }
+ if (S->empty() == false && (*S)[S->size() - 1] == '/')
+ {
+ if (list_comp.empty() == false)
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), i, "sources", Fd.Name().c_str(), "absolute Suite Component");
+ if (CreateItem(List, URI, *S, "", Options) == false)
+ return false;
+ }
+ else
+ {
+ if (list_comp.empty())
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), i, "sources", Fd.Name().c_str(), "Component");
+
+ for (std::vector<std::string>::const_iterator C = list_comp.begin();
+ C != list_comp.end(); ++C)
+ {
+ if (CreateItem(List, URI, *S, *C, Options) == false)
+ {
+ return false;
+ }
+ }
+ }
}
}
return true;
}
-
+ /*}}}*/
// Type::ParseLine - Parse a single line /*{{{*/
// ---------------------------------------------------------------------
/* This is a generic one that is the 'usual' format for sources.list
Weird types may override this. */
bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
const char *Buffer,
- unsigned long const &CurLine,
+ unsigned int const CurLine,
string const &File) const
{
for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces
@@ -171,10 +188,10 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
// get one option, e.g. option1=value1
string option;
if (ParseQuoteWord(Buffer,option) == false)
- return _error->Error(_("Malformed line %lu in source list %s ([option] unparseable)"),CurLine,File.c_str());
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "[option] unparseable");
if (option.length() < 3)
- return _error->Error(_("Malformed line %lu in source list %s ([option] too short)"),CurLine,File.c_str());
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "[option] too short");
// accept options even if the last has no space before the ]-end marker
if (option.at(option.length()-1) == ']')
@@ -185,16 +202,16 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
size_t const needle = option.find('=');
if (needle == string::npos)
- return _error->Error(_("Malformed line %lu in source list %s ([%s] is not an assignment)"),CurLine,File.c_str(), option.c_str());
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "[option] not assignment");
string const key = string(option, 0, needle);
string const value = string(option, needle + 1, option.length());
if (key.empty() == true)
- return _error->Error(_("Malformed line %lu in source list %s ([%s] has no key)"),CurLine,File.c_str(), option.c_str());
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "[option] no key");
if (value.empty() == true)
- return _error->Error(_("Malformed line %lu in source list %s ([%s] key %s has no value)"),CurLine,File.c_str(),option.c_str(),key.c_str());
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "[option] no value");
Options[key] = value;
}
@@ -207,33 +224,33 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
string Section;
if (ParseQuoteWord(Buffer,URI) == false)
- return _error->Error(_("Malformed line %lu in source list %s (URI)"),CurLine,File.c_str());
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "URI");
if (ParseQuoteWord(Buffer,Dist) == false)
- return _error->Error(_("Malformed line %lu in source list %s (dist)"),CurLine,File.c_str());
-
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "Suite");
+
if (FixupURI(URI) == false)
- return _error->Error(_("Malformed line %lu in source list %s (URI parse)"),CurLine,File.c_str());
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "URI parse");
// Check for an absolute dists specification.
if (Dist.empty() == false && Dist[Dist.size() - 1] == '/')
{
if (ParseQuoteWord(Buffer,Section) == true)
- return _error->Error(_("Malformed line %lu in source list %s (absolute dist)"),CurLine,File.c_str());
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "absolute Suite Component");
Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture"));
return CreateItem(List, URI, Dist, Section, Options);
}
-
+
// Grab the rest of the dists
if (ParseQuoteWord(Buffer,Section) == false)
- return _error->Error(_("Malformed line %lu in source list %s (dist parse)"),CurLine,File.c_str());
-
+ return _error->Error(_("Malformed entry %u in %s file %s (%s)"), CurLine, "list", File.c_str(), "Component");
+
do
{
if (CreateItem(List, URI, Dist, Section, Options) == false)
return false;
}
while (ParseQuoteWord(Buffer,Section) == true);
-
+
return true;
}
/*}}}*/
@@ -243,11 +260,6 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
pkgSourceList::pkgSourceList() : d(NULL)
{
}
-
-pkgSourceList::pkgSourceList(string File) : d(NULL)
-{
- Read(File);
-}
/*}}}*/
// SourceList::~pkgSourceList - Destructor /*{{{*/
// ---------------------------------------------------------------------
@@ -305,7 +317,7 @@ void pkgSourceList::Reset()
// SourceList::Read - Parse the sourcelist file /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool pkgSourceList::Read(string File)
+bool pkgSourceList::Read(string const &File)
{
Reset();
return ReadAppend(File);
@@ -314,71 +326,63 @@ bool pkgSourceList::Read(string File)
// SourceList::ReadAppend - Parse a sourcelist file /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool pkgSourceList::ReadAppend(string File)
+bool pkgSourceList::ReadAppend(string const &File)
{
- if (_config->FindB("APT::Sources::Use-Deb822", false) == true)
- {
- int lines_parsed =ParseFileDeb822(File);
- if (lines_parsed < 0)
- return false;
- else if (lines_parsed > 0)
- return true;
- // no lines parsed ... fall through and use old style parser
- }
- return ParseFileOldStyle(File);
+ if (flExtension(File) == "sources")
+ return ParseFileDeb822(File);
+ else
+ return ParseFileOldStyle(File);
}
// SourceList::ReadFileOldStyle - Read Traditional style sources.list /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool pkgSourceList::ParseFileOldStyle(string File)
+bool pkgSourceList::ParseFileOldStyle(std::string const &File)
{
// Open the stream for reading
ifstream F(File.c_str(),ios::in /*| ios::nocreate*/);
if (F.fail() == true)
return _error->Errno("ifstream::ifstream",_("Opening %s"),File.c_str());
- // CNC:2003-12-10 - 300 is too short.
- char Buffer[1024];
-
- int CurLine = 0;
- while (F.eof() == false)
+ std::string Buffer;
+ for (unsigned int CurLine = 1; std::getline(F, Buffer); ++CurLine)
{
- F.getline(Buffer,sizeof(Buffer));
- CurLine++;
- _strtabexpand(Buffer,sizeof(Buffer));
- if (F.fail() && !F.eof())
- return _error->Error(_("Line %u too long in source list %s."),
- CurLine,File.c_str());
-
-
- char *I;
- // CNC:2003-02-20 - Do not break if '#' is inside [].
- for (I = Buffer; *I != 0 && *I != '#'; I++)
- if (*I == '[')
- {
- char *b_end = strchr(I + 1, ']');
- if (b_end != NULL)
- I = b_end;
- }
- *I = 0;
-
- const char *C = _strstrip(Buffer);
-
- // Comment or blank
- if (C[0] == '#' || C[0] == 0)
+ // remove comments
+ size_t curpos = 0;
+ while ((curpos = Buffer.find('#', curpos)) != std::string::npos)
+ {
+ size_t const openbrackets = std::count(Buffer.begin(), Buffer.begin() + curpos, '[');
+ size_t const closedbrackets = std::count(Buffer.begin(), Buffer.begin() + curpos, ']');
+ if (openbrackets > closedbrackets)
+ {
+ // a # in an option, unlikely, but oh well, it was supported so stick to it
+ ++curpos;
+ continue;
+ }
+ Buffer.erase(curpos);
+ break;
+ }
+ // remove spaces before/after
+ curpos = Buffer.find_first_not_of(" \t\r");
+ if (curpos != 0)
+ Buffer.erase(0, curpos);
+ curpos = Buffer.find_last_not_of(" \t\r");
+ if (curpos != std::string::npos)
+ Buffer.erase(curpos + 1);
+
+ if (Buffer.empty())
continue;
-
+
// Grok it
- string LineType;
- if (ParseQuoteWord(C,LineType) == false)
+ std::string const LineType = Buffer.substr(0, Buffer.find(' '));
+ if (LineType.empty() || LineType == Buffer)
return _error->Error(_("Malformed line %u in source list %s (type)"),CurLine,File.c_str());
Type *Parse = Type::GetType(LineType.c_str());
if (Parse == 0)
return _error->Error(_("Type '%s' is not known on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
-
- if (Parse->ParseLine(SrcList, C, CurLine, File) == false)
+
+ if (Parse->ParseLine(SrcList, Buffer.c_str() + LineType.length(), CurLine, File) == false)
return false;
}
return true;
@@ -387,30 +391,25 @@ bool pkgSourceList::ParseFileOldStyle(string File)
// SourceList::ParseFileDeb822 - Parse deb822 style sources.list /*{{{*/
// ---------------------------------------------------------------------
/* Returns: the number of stanzas parsed*/
-int pkgSourceList::ParseFileDeb822(string File)
+bool pkgSourceList::ParseFileDeb822(string const &File)
{
- pkgTagSection Tags;
- unsigned int i=0;
+ pkgUserTagSection Tags;
+ unsigned int i = 1;
// see if we can read the file
- _error->PushToStack();
FileFd Fd(File, FileFd::ReadOnly);
pkgTagFile Sources(&Fd);
if (_error->PendingError() == true)
- {
- _error->RevertToStack();
- return 0;
- }
- _error->MergeWithStack();
-
+ return _error->Error(_("Malformed stanza %u in source list %s (type)"),i,File.c_str());
+
// read step by step
while (Sources.Step(Tags) == true)
{
- if(!Tags.Exists("Types"))
- continue;
+ if(Tags.Exists("Types") == false)
+ return _error->Error(_("Malformed stanza %u in source list %s (type)"),i,File.c_str());
string const types = Tags.FindS("Types");
- std::vector<std::string> list_types = StringSplit(types, " ");
+ std::vector<std::string> const list_types = VectorizeString(types, ' ');
for (std::vector<std::string>::const_iterator I = list_types.begin();
I != list_types.end(); ++I)
{
@@ -418,18 +417,16 @@ int pkgSourceList::ParseFileDeb822(string File)
if (Parse == 0)
{
_error->Error(_("Type '%s' is not known on stanza %u in source list %s"), (*I).c_str(),i,Fd.Name().c_str());
- return -1;
+ return false;
}
-
+
if (!Parse->ParseStanza(SrcList, Tags, i, Fd))
- return -1;
+ return false;
- i++;
+ ++i;
}
}
-
- // we are done, return the number of stanzas read
- return i;
+ return true;
}
/*}}}*/
// SourceList::FindIndex - Get the index associated with a file /*{{{*/
@@ -471,9 +468,12 @@ bool pkgSourceList::GetIndexes(pkgAcquire *Owner, bool GetAll) const
// Based on ReadConfigDir() /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool pkgSourceList::ReadSourceDir(string Dir)
+bool pkgSourceList::ReadSourceDir(string const &Dir)
{
- vector<string> const List = GetListOfFilesInDir(Dir, "list", true);
+ std::vector<std::string> ext;
+ ext.push_back("list");
+ ext.push_back("sources");
+ std::vector<std::string> const List = GetListOfFilesInDir(Dir, ext, true);
// Read the files
for (vector<string>::const_iterator I = List.begin(); I != List.end(); ++I)
diff --git a/apt-pkg/sourcelist.h b/apt-pkg/sourcelist.h
index 4f42b3e91..079f3cb3d 100644
--- a/apt-pkg/sourcelist.h
+++ b/apt-pkg/sourcelist.h
@@ -72,11 +72,11 @@ class pkgSourceList
bool FixupURI(std::string &URI) const;
virtual bool ParseStanza(std::vector<metaIndex *> &List,
pkgTagSection &Tags,
- int stanza_n,
+ unsigned int const stanza_n,
FileFd &Fd);
virtual bool ParseLine(std::vector<metaIndex *> &List,
const char *Buffer,
- unsigned long const &CurLine,std::string const &File) const;
+ unsigned int const CurLine,std::string const &File) const;
virtual bool CreateItem(std::vector<metaIndex *> &List,std::string const &URI,
std::string const &Dist,std::string const &Section,
std::map<std::string, std::string> const &Options) const = 0;
@@ -90,18 +90,19 @@ class pkgSourceList
std::vector<metaIndex *> SrcList;
- int ParseFileDeb822(std::string File);
- bool ParseFileOldStyle(std::string File);
+ private:
+ APT_HIDDEN bool ParseFileDeb822(std::string const &File);
+ APT_HIDDEN bool ParseFileOldStyle(std::string const &File);
public:
bool ReadMainList();
- bool Read(std::string File);
+ bool Read(std::string const &File);
// CNC:2003-03-03
void Reset();
- bool ReadAppend(std::string File);
- bool ReadSourceDir(std::string Dir);
+ bool ReadAppend(std::string const &File);
+ bool ReadSourceDir(std::string const &Dir);
// List accessors
inline const_iterator begin() const {return SrcList.begin();};
@@ -117,7 +118,6 @@ class pkgSourceList
time_t GetLastModifiedTime();
pkgSourceList();
- explicit pkgSourceList(std::string File);
virtual ~pkgSourceList();
};
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index 6d7d8185b..cc63b213f 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -775,6 +775,14 @@ bool pkgTagSection::Write(FileFd &File, char const * const * const Order, std::v
}
/*}}}*/
+void pkgUserTagSection::TrimRecord(bool /*BeforeRecord*/, const char* &End)/*{{{*/
+{
+ for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r' || Stop[0] == '#'); Stop++)
+ if (Stop[0] == '#')
+ Stop = (const char*) memchr(Stop,'\n',End-Stop);
+}
+ /*}}}*/
+
#include "tagfile-order.c"
// TFRewrite - Rewrite a control record /*{{{*/
diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h
index d0d0c7a84..81fff89f0 100644
--- a/apt-pkg/tagfile.h
+++ b/apt-pkg/tagfile.h
@@ -142,6 +142,14 @@ class pkgTagSection
bool Write(FileFd &File, char const * const * const Order = NULL, std::vector<Tag> const &Rewrite = std::vector<Tag>()) const;
};
+
+/* For user generated file the parser should be a bit more relaxed in exchange
+ for being a bit slower to allow comments and new lines all over the place */
+class pkgUserTagSection : public pkgTagSection
+{
+ virtual void TrimRecord(bool BeforeRecord, const char* &End);
+};
+
class pkgTagFilePrivate;
class pkgTagFile
{
diff --git a/doc/sources.list.5.xml b/doc/sources.list.5.xml
index 6ebba3528..8506017ad 100644
--- a/doc/sources.list.5.xml
+++ b/doc/sources.list.5.xml
@@ -31,37 +31,99 @@
<refsect1><title>Description</title>
<para>
- The source list <filename>/etc/apt/sources.list</filename> is designed to support
- any number of active sources and a variety of source media. The file lists one
- source per line, with the most preferred source listed first. The information available
- from the configured sources is acquired by <command>apt-get update</command>
- (or by an equivalent command from another APT front-end).
- </para>
- <para>
- Each line specifying a source starts with type (e.g. <literal>deb-src</literal>)
- followed by options and arguments for this type.
- Individual entries cannot be continued onto a following line. Empty lines
- are ignored, and a <literal>#</literal> character anywhere on a line marks
- the remainder of that line as a comment.
+ The source list <filename>/etc/apt/sources.list</filename> and the the
+ files contained in <filename>/etc/apt/sources.list.d/</filename> are
+ designed to support any number of active sources and a variety of source
+ media. The files list one source per line (one line style) or contain multiline
+ stanzas defining one or more sources per stanza (deb822 style), with the
+ most preferred source listed first. The information available from the
+ configured sources is acquired by <command>apt-get update</command> (or
+ by an equivalent command from another APT front-end).
</para>
</refsect1>
<refsect1><title>sources.list.d</title>
- <para>The <filename>/etc/apt/sources.list.d</filename> directory provides
- a way to add sources.list entries in separate files.
- The format is the same as for the regular <filename>sources.list</filename> file.
- File names need to end with
- <filename>.list</filename> and may only contain letters (a-z and A-Z),
- digits (0-9), underscore (_), hyphen (-) and period (.) characters.
- Otherwise APT will print a notice that it has ignored a file, unless that
- file matches a pattern in the <literal>Dir::Ignore-Files-Silently</literal>
- configuration list - in which case it will be silently ignored.</para>
+ <para>The <filename>/etc/apt/sources.list.d</filename> directory provides
+ a way to add sources.list entries in separate files.
+ Two different file formats are allowed as described in the next two sections.
+ Filenames need to have either the extension <filename>.list</filename> or
+ <filename>.sources</filename> depending on the contained format.
+ The filenames may only contain letters (a-z and A-Z),
+ digits (0-9), underscore (_), hyphen (-) and period (.) characters.
+ Otherwise APT will print a notice that it has ignored a file, unless that
+ file matches a pattern in the <literal>Dir::Ignore-Files-Silently</literal>
+ configuration list - in which case it will be silently ignored.</para>
</refsect1>
- <refsect1><title>The deb and deb-src types</title>
+ <refsect1><title>one line style format</title>
+ <para>
+ Files in this format have the extension <filename>.list</filename>.
+ Each line specifying a source starts with a type (e.g. <literal>deb-src</literal>)
+ followed by options and arguments for this type.
+
+ Individual entries cannot be continued onto a following line. Empty lines
+ are ignored, and a <literal>#</literal> character anywhere on a line marks
+ the remainder of that line as a comment. Consequently an entry can be
+ disabled by commenting out the entire line.
+
+ If options should be provided they are separated by spaces and all of
+ them together are enclosed by square brackets (<literal>[]</literal>)
+ included in the line after the type separated from it with a space.
+ If an option allows multiple values these are separated from each other
+ with a comma (<literal>,</literal>). An option name is separated from its
+ value(s) by a equal sign (<literal>=</literal>). Multivalue options have
+ also <literal>-=</literal> and <literal>+=</literal> as separator which
+ instead of replacing the default with the given value(s) modify the default
+ value(s) to remove or include the given values.
+ </para><para>
+ This is the traditional format and supported by all apt versions.
+ Note that not all options as described below are supported by all apt versions.
+ Note also that some older applications parsing this format on its own might not
+ expect to encounter options as they were uncommon before the introduction of
+ multi-architecture support.
+ </para>
+ </refsect1>
+
+ <refsect1><title>deb822 style format</title>
+ <para>
+ Files in this format have the extension <filename>.sources</filename>.
+ The format is similar in syntax to other files used by Debian and its
+ derivatives, like the metadata itself apt will download from the configured
+ sources or the <filename>debian/control</filename> file in a Debian source package.
+
+ Individual entries are separated by an empty line, additional empty
+ lines are ignored, and a <literal>#</literal> character at the start of
+ the line marks the entire line as a comment. An entry can hence be
+ disabled by commenting out each line belonging to the stanza, but it is
+ usually easier to add the field "Enabled: no" to the stanza to disable
+ the entry. Removing the field or setting it to yes reenables it.
+
+ Options have the same syntax as every other field: A fieldname separated by
+ a colon (<literal>:</literal>) and optionally spaces from its value(s).
+ Note especially that multiple values are separated by spaces, not by
+ commas as in the one line format. Multivalue fields like <literal>Architectures</literal>
+ also have <literal>Architectures-Add</literal> and <literal>Architectures-Remove</literal>
+ to modify the default value rather than replacing it.
+ </para><para>
+ This is a new format supported by apt itself since version 1.1. Previous
+ versions ignore such files with a notice message as described earlier.
+ It is intended to make this format gradually the default format and
+ deprecating the previously described one line style format as it is
+ easier to create, extend and modify by humans and machines alike
+ especially if a lot of sources and/or options are involved.
+
+ Developers who are working with and/or parsing apt sources are highly
+ encouraged to add support for this format and to contact the APT team
+ to coordinate and share this work. Users can freely adopt this format
+ already, but could encounter problems with software not supporting
+ the format yet.
+ </para>
+ </refsect1>
+
+ <refsect1><title>The deb and deb-src types: General Format</title>
<para>The <literal>deb</literal> type references a typical two-level Debian
archive, <filename>distribution/component</filename>. The
- <literal>distribution</literal> is generally an archive name like
+ <literal>distribution</literal> is generally a suite name like
<literal>stable</literal> or <literal>testing</literal> or a codename like
<literal>&stable-codename;</literal> or <literal>&testing-codename;</literal>
while component is one of <literal>main</literal>, <literal>contrib</literal> or
@@ -70,42 +132,33 @@
code in the same form as the <literal>deb</literal> type.
A <literal>deb-src</literal> line is required to fetch source indexes.</para>
- <para>The format for a <filename>sources.list</filename> entry using the
+ <para>The format for two one line style entries using the
<literal>deb</literal> and <literal>deb-src</literal> types is:</para>
- <literallayout>deb [ options ] uri suite [component1] [component2] [...]</literallayout>
+ <literallayout>deb [ option1=value1 option2=value2 ] uri suite [component1] [component2] [...]
+deb-src [ option1=value1 option2=value2 ] uri suite [component1] [component2] [...]</literallayout>
- <para>Alternatively a rfc822 style format is also supported:
+ <para>Alternatively the equivalent entry in deb822 style looks like this:
<literallayout>
Types: deb deb-src
- URIs: http://example.com
- Suites: stable testing
- Sections: component1 component2
- Description: short
- long long long
- [option1]: [option1-value]
-
- Types: deb
- URIs: http://another.example.com
- Suites: experimental
- Sections: component1 component2
- Enabled: no
- Description: short
- long long long
- [option1]: [option1-value]
+ URIs: uri
+ Suites: suite
+ Components: [component1] [component2] [...]
+ option1: value1
+ option2: value2
</literallayout>
</para>
<para>The URI for the <literal>deb</literal> type must specify the base of the
- Debian distribution, from which APT will find the information it needs.
- <literal>suite</literal> can specify an exact path, in which case the
+ Debian distribution, from which APT will find the information it needs.
+ <literal>suite</literal> can specify an exact path, in which case the
components must be omitted and <literal>suite</literal> must end with
a slash (<literal>/</literal>). This is useful for the case when only a
- particular sub-section of the archive denoted by the URI is of interest.
+ particular sub-directory of the archive denoted by the URI is of interest.
If <literal>suite</literal> does not specify an exact path, at least
one <literal>component</literal> must be present.</para>
- <para><literal>suite</literal> may also contain a variable,
+ <para><literal>suite</literal> may also contain a variable,
<literal>$(ARCH)</literal>
which expands to the Debian architecture (such as <literal>amd64</literal> or
<literal>armel</literal>) used on the system. This permits architecture-independent
@@ -113,67 +166,80 @@
of interest when specifying an exact path, <literal>APT</literal> will
automatically generate a URI with the current architecture otherwise.</para>
- <para>In the traditional style sources.list format since only one
- distribution can be specified per line it may be necessary to have
- multiple lines for the same URI, if a subset of all available
- distributions or components at that location is desired. APT will
- sort the URI list after it has generated a complete set internally,
- and will collapse multiple references to the same Internet host,
- for instance, into a single connection, so that it does not
- inefficiently establish an FTP connection, close it, do something
- else, and then re-establish a connection to that same host. This
- feature is useful for accessing busy FTP sites with limits on the
- number of simultaneous anonymous users. APT also parallelizes
- connections to different hosts to more effectively deal with sites
- with low bandwidth.</para>
-
- <para><literal>options</literal> is always optional and needs to be surrounded by
- square brackets. It can consist of multiple settings in the form
- <literal><replaceable>setting</replaceable>=<replaceable>value</replaceable></literal>.
- Multiple settings are separated by spaces. The following settings are supported by APT
- (note however that unsupported settings will be ignored silently):
- <itemizedlist>
- <listitem><para><literal>arch=<replaceable>arch1</replaceable>,<replaceable>arch2</replaceable>,…</literal>
- can be used to specify for which architectures information should
- be downloaded. If this option is not set all architectures defined by the
- <literal>APT::Architectures</literal> option will be downloaded.</para></listitem>
-
- <listitem><para><literal>arch+=<replaceable>arch1</replaceable>,<replaceable>arch2</replaceable>,…</literal>
- and <literal>arch-=<replaceable>arch1</replaceable>,<replaceable>arch2</replaceable>,…</literal>
- which can be used to add/remove architectures from the set which will be downloaded.</para></listitem>
-
- <listitem><para><literal>lang=<replaceable>lang1</replaceable>,<replaceable>lang2</replaceable>,…</literal>,
- <literal>lang+=<replaceable>lang1</replaceable>,<replaceable>lang2</replaceable>,…</literal> and
- <literal>lang-=<replaceable>lang1</replaceable>,<replaceable>lang2</replaceable>,…</literal> functioning in
- the same way as the <literal>arch</literal>-options described before. They can be used to specify for
- which languages apt will acquire metadata, like translated package descriptions, for. If not specified, the
- default set is defined by the <literal>Acquire::Languages</literal> config option.</para></listitem>
-
- <listitem><para><literal>target=<replaceable>target1</replaceable>,<replaceable>target2</replaceable>,…</literal>,
- <literal>target+=<replaceable>target1</replaceable>,<replaceable>target2</replaceable>,…</literal> and
- <literal>target-=<replaceable>target1</replaceable>,<replaceable>target2</replaceable>,…</literal> again functioning in
- the same way as the <literal>arch</literal>-options described before. They can be used to specify which
- targets apt will try to acquire from this source. If not specified, the default set is defined by
- the <literal>APT::Acquire::Targets</literal> configuration scope.</para></listitem>
-
- <listitem><para><literal>trusted=yes</literal> can be set to indicate that packages
- from this source are always authenticated even if the <filename>Release</filename> file
- is not signed or the signature can't be checked. This disables parts of &apt-secure;
- and should therefore only be used in a local and trusted context. <literal>trusted=no</literal>
- is the opposite which handles even correctly authenticated sources as not authenticated.</para></listitem>
- </itemizedlist></para>
+ <para>Especially in the one line style format since only one distribution
+ can be specified per line it may be necessary to have multiple lines for
+ the same URI, if a subset of all available distributions or components at
+ that location is desired. APT will sort the URI list after it has
+ generated a complete set internally, and will collapse multiple
+ references to the same Internet host, for instance, into a single
+ connection, so that it does not inefficiently establish a
+ connection, close it, do something else, and then re-establish a
+ connection to that same host. APT also parallelizes connections to
+ different hosts to more effectively deal with sites with low
+ bandwidth.</para>
<para>It is important to list sources in order of preference, with the most
preferred source listed first. Typically this will result in sorting
by speed from fastest to slowest (CD-ROM followed by hosts on a local
network, followed by distant Internet hosts, for example).</para>
- <para>Some examples:</para>
- <literallayout>
-deb http://ftp.debian.org/debian &stable-codename; main contrib non-free
-deb http://security.debian.org/ &stable-codename;/updates main contrib non-free
- </literallayout>
+ <para>As an example, the sources for your distribution could look like this
+ in one line style format:
+ <literallayout>&sourceslist-list-format;</literallayout> or like this in
+ deb822 style format:
+ <literallayout>&sourceslist-sources-format;</literallayout></para>
+ </refsect1>
+ <refsect1><title>The deb and deb-src types: Options</title>
+ <para>Each source entry can have options specified modifying which and how
+ the source is accessed and data acquired from it. Format, syntax and names
+ of the options varies between the two formats one line and deb822 style
+ as described, but they have both the same options available. For simplicity
+ we list the deb822 fieldname and provide the one line name in brackets.
+ Remember that beside setting multivalue options explicitly, there is also
+ the option to modify them based on the default, but we aren't listing those
+ names explicitly here. Unsupported options are silently ignored by all
+ APT versions.
+
+ <itemizedlist>
+ <listitem><para><literal>Architectures</literal>
+ (<literal>arch</literal>) is a multivalue option defining for
+ which architectures information should be downloaded. If this
+ option isn't set the default is all architectures as defined by
+ the <literal>APT::Architectures</literal> config option.
+ </para></listitem>
+
+ <listitem><para><literal>Languages</literal>
+ (<literal>lang</literal>) is a multivalue option defining for
+ which languages information like translated package
+ descriptions should be downloaded. If this option isn't set
+ the default is all languages as defined by the
+ <literal>Acquire::Languages</literal> config option.
+ </para></listitem>
+
+ <listitem><para><literal>Targets</literal>
+ (<literal>target</literal>) is a multivalue option defining
+ which download targets apt will try to acquire from this
+ source. If not specified, the default set is defined by the
+ <literal>APT::Acquire::Targets</literal> configuration scope.
+ </para></listitem>
+
+ <listitem><para><literal>Trusted</literal> (<literal>trusted</literal>)
+ is a tri-state value which defaults to APT deciding if a source
+ is considered trusted or if warnings should be raised before e.g.
+ packages are installed from this source. This option can be used
+ to override this decision either with the value <literal>yes</literal>,
+ which lets APT consider this source always as a trusted source
+ even if it has no or fails authentication checks by disabling parts
+ of &apt-secure; and should therefore only be used in a local and trusted
+ context (if at all) as otherwise security is breached. The opposite
+ can be achieved with the value no, which causes the source to be handled
+ as untrusted even if the authentication checks passed successfully.
+ The default value can't be set explicitly.
+ </para></listitem>
+ </itemizedlist>
+
+ </para>
</refsect1>
<refsect1><title>URI specification</title>
@@ -247,34 +313,70 @@ deb http://security.debian.org/ &stable-codename;/updates main contrib non-free
</refsect1>
<refsect1><title>Examples</title>
- <para>Uses the archive stored locally (or NFS mounted) at /home/jason/debian
+ <para>Uses the archive stored locally (or NFS mounted) at /home/apt/debian
for stable/main, stable/contrib, and stable/non-free.</para>
- <literallayout>deb file:/home/jason/debian stable main contrib non-free</literallayout>
+ <literallayout>deb file:/home/apt/debian stable main contrib non-free</literallayout>
+ <literallayout>Types: deb
+URIs: file:/home/apt/debian
+Suites: stable
+Components: main contrib non-free</literallayout>
<para>As above, except this uses the unstable (development) distribution.</para>
- <literallayout>deb file:/home/jason/debian unstable main contrib non-free</literallayout>
+ <literallayout>deb file:/home/apt/debian unstable main contrib non-free</literallayout>
+ <literallayout>Types: deb
+URIs: file:/home/apt/debian
+Suites: unstable
+Components: main contrib non-free</literallayout>
<para>Source line for the above</para>
- <literallayout>deb-src file:/home/jason/debian unstable main contrib non-free</literallayout>
+ <literallayout>deb-src file:/home/apt/debian unstable main contrib non-free</literallayout>
+ <literallayout>Types: deb-src
+URIs: file:/home/apt/debian
+Suites: unstable
+Components: main contrib non-free</literallayout>
+
<para>The first line gets package information for the architectures in <literal>APT::Architectures</literal>
while the second always retrieves <literal>amd64</literal> and <literal>armel</literal>.</para>
- <literallayout>deb http://ftp.debian.org/debian &stable-codename; main
-deb [ arch=amd64,armel ] http://ftp.debian.org/debian &stable-codename; main</literallayout>
+ <literallayout>deb http://httpredir.debian.org/debian &stable-codename; main
+deb [ arch=amd64,armel ] http://httpredir.debian.org/debian &stable-codename; main</literallayout>
+ <literallayout>Types: deb
+URIs: http://httpredir.debian.org/debian
+Suites: &stable-codename;
+Components: main
+
+Types: deb
+URIs: http://httpredir.debian.org/debian
+Suites: &stable-codename;
+Components: main
+Architectures: amd64 armel
+</literallayout>
<para>Uses HTTP to access the archive at archive.debian.org, and uses only
the hamm/main area.</para>
<literallayout>deb http://archive.debian.org/debian-archive hamm main</literallayout>
+ <literallayout>Types: deb
+URIs: http://archive.debian.org/debian-archive
+Suites: hamm
+Components: main</literallayout>
<para>Uses FTP to access the archive at ftp.debian.org, under the debian
directory, and uses only the &stable-codename;/contrib area.</para>
<literallayout>deb ftp://ftp.debian.org/debian &stable-codename; contrib</literallayout>
+ <literallayout>Types: deb
+URIs: ftp://ftp.debian.org/debian
+Suites: &stable-codename;
+Components: contrib</literallayout>
<para>Uses FTP to access the archive at ftp.debian.org, under the debian
directory, and uses only the unstable/contrib area. If this line appears as
well as the one in the previous example in <filename>sources.list</filename>
a single FTP session will be used for both resource lines.</para>
<literallayout>deb ftp://ftp.debian.org/debian unstable contrib</literallayout>
+ <literallayout>Types: deb
+URIs: ftp://ftp.debian.org/debian
+Suites: unstable
+Components: contrib</literallayout>
<para>Uses HTTP to access the archive at ftp.tlh.debian.org, under the
universe directory, and uses only files found under
@@ -284,15 +386,32 @@ deb [ arch=amd64,armel ] http://ftp.debian.org/debian &stable-codename; main</li
illustrates how to use the substitution variable; official debian
archives are not structured like this]
<literallayout>deb http://ftp.tlh.debian.org/universe unstable/binary-$(ARCH)/</literallayout>
+ <literallayout>Types: deb
+URIs: http://ftp.tlh.debian.org/universe
+Suites: unstable/binary-$(ARCH)/</literallayout>
</para>
+
+ <para>Uses HTTP to get binary packages as well as sources from the stable, testing and unstable
+ suites and the components main and contrib.</para>
+ <literallayout>deb http://httpredir.debian.org/debian stable main contrib
+deb-src http://httpredir.debian.org/debian stable main contrib
+deb http://httpredir.debian.org/debian testing main contrib
+deb-src http://httpredir.debian.org/debian testing main contrib
+deb http://httpredir.debian.org/debian unstable main contrib
+deb-src http://httpredir.debian.org/debian unstable main contrib</literallayout>
+ <literallayout>Types: deb deb-src
+URIs: http://httpredir.debian.org/debian
+Suites: stable testing unstable
+Components: main contrib
+</literallayout>
+
</refsect1>
-
+
<refsect1><title>See Also</title>
- <para>&apt-cache; &apt-conf;
+ <para>&apt-get;, &apt-conf;
</para>
</refsect1>
&manbugs;
-
-</refentry>
+</refentry>
diff --git a/test/integration/test-apt-sources-deb822 b/test/integration/test-apt-sources-deb822
index 51fe7bcfe..adfe0e003 100755
--- a/test/integration/test-apt-sources-deb822
+++ b/test/integration/test-apt-sources-deb822
@@ -7,9 +7,8 @@ TESTDIR=$(readlink -f $(dirname $0))
setupenvironment
configarchitecture 'i386'
-echo 'APT::Sources::Use-Deb822 "true";' > rootdir/etc/apt/apt.conf.d/00enabledeb822
-
-SOURCES='rootdir/etc/apt/sources.list'
+LISTS='rootdir/etc/apt/sources.list.d/test.list'
+SOURCES='rootdir/etc/apt/sources.list.d/test.sources'
BASE='# some comment
# that contains a : as well
#Types: meep
@@ -17,23 +16,48 @@ BASE='# some comment
Types: deb
URIs: http://ftp.debian.org/debian
Suites: stable
-Sections: main
+Components: main
Description: summay
and the long part'
-msgtest 'Test sources.list' 'old style'
-echo "deb http://ftp.debian.org/debian stable main" > $SOURCES
+msgcleantest() {
+ rm -f $LISTS $SOURCES
+ msgtest "$@"
+}
+
+msgcleantest 'Test sources.list' 'old style'
+echo "deb http://ftp.debian.org/debian stable main" > $LISTS
+testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
+'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
+'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris
+
+msgcleantest 'Test sources.list' 'old style with options'
+echo "deb [trusted=yes arch+=armel,powerpc] http://ftp.debian.org/debian stable main" > $LISTS
+testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
+'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
+'http://ftp.debian.org/debian/dists/stable/main/binary-armel/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-armel_Packages 0
+'http://ftp.debian.org/debian/dists/stable/main/binary-powerpc/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-powerpc_Packages 0
+'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris
+
+msgcleantest 'Test sources.list' 'old style with comments'
+echo "deb http://ftp.debian.org/debian stable main # non-free" > $LISTS
+testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
+'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
+'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris
+
+msgcleantest 'Test sources.list' 'old style with option comments'
+echo "deb [trusted=yes#yeahreally] http://ftp.debian.org/debian stable main # non-free" > $LISTS
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris
-msgtest 'Test sources.list' 'simple deb822'
+msgcleantest 'Test sources.list' 'simple deb822'
echo "$BASE" > $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris
-msgtest 'Test deb822 with' 'two entries'
+msgcleantest 'Test deb822 with' 'two entries'
# Two entries
echo "$BASE" > $SOURCES
echo "" >> $SOURCES
@@ -46,7 +70,7 @@ testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.deb
'http://ftp.debian.org/debian/dists/unstable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_unstable_main_i18n_Translation-en 0 " aptget update --print-uris
# two suite entries
-msgtest 'Test deb822 with' 'two Suite entries'
+msgcleantest 'Test deb822 with' 'two Suite entries'
echo "$BASE" | sed -e "s/stable/stable unstable/" > $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-i386_Packages 0
@@ -55,7 +79,7 @@ testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.deb
'http://ftp.debian.org/debian/dists/unstable/main/binary-i386/Packages.bz2' ftp.debian.org_debian_dists_unstable_main_binary-i386_Packages 0
'http://ftp.debian.org/debian/dists/unstable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_unstable_main_i18n_Translation-en 0 " aptget update --print-uris
-msgtest 'Test deb822' 'architecture option'
+msgcleantest 'Test deb822' 'architecture option'
echo "$BASE" > $SOURCES
echo "Architectures: amd64 armel" >> $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
@@ -63,17 +87,30 @@ testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.deb
'http://ftp.debian.org/debian/dists/stable/main/binary-armel/Packages.bz2' ftp.debian.org_debian_dists_stable_main_binary-armel_Packages 0
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris
-
-msgtest 'Test old-style sources.list file which has' 'malformed dist'
-echo "deb http://ftp.debian.org" > $SOURCES
-testequal --nomsg "E: Malformed line 1 in source list $TMPWORKINGDIRECTORY/rootdir/etc/apt/sources.list (dist)
+msgcleantest 'Test old-style' 'suite arch variable'
+echo 'deb http://ftp.tlh.debian.org/universe unstable/binary-$(ARCH)/' > $LISTS
+testequal --nomsg "'http://ftp.tlh.debian.org/universe/unstable/binary-i386/InRelease' ftp.tlh.debian.org_universe_unstable_binary-i386_InRelease 0
+'http://ftp.tlh.debian.org/universe/unstable/binary-i386/Packages.bz2' ftp.tlh.debian.org_universe_unstable_binary-i386_Packages 0
+'http://ftp.tlh.debian.org/universe/unstable/binary-i386/en.bz2' ftp.tlh.debian.org_universe_unstable_binary-i386_en 0 " aptget update --print-uris
+
+msgcleantest 'Test deb822' 'suite arch variable'
+echo 'Types: deb
+URIs: http://ftp.tlh.debian.org/universe
+Suites: stable/binary-$(ARCH)/' > $SOURCES
+testequal --nomsg "'http://ftp.tlh.debian.org/universe/stable/binary-i386/InRelease' ftp.tlh.debian.org_universe_stable_binary-i386_InRelease 0
+'http://ftp.tlh.debian.org/universe/stable/binary-i386/Packages.bz2' ftp.tlh.debian.org_universe_stable_binary-i386_Packages 0
+'http://ftp.tlh.debian.org/universe/stable/binary-i386/en.bz2' ftp.tlh.debian.org_universe_stable_binary-i386_en 0 " aptget update --print-uris
+
+msgcleantest 'Test old-style sources.list file which has' 'malformed dist'
+echo "deb http://ftp.debian.org" > $LISTS
+testequal --nomsg "E: Malformed entry 1 in list file $TMPWORKINGDIRECTORY/$LISTS (Suite)
E: The list of sources could not be read." aptget update --print-uris
-msgtest 'Test deb822 sources.list file which has' 'malformed URI'
+msgcleantest 'Test deb822 sources.list file which has' 'malformed URI'
echo "Types: deb
Suites: stable
" > $SOURCES
-testequal --nomsg "E: Malformed stanza 0 in source list $TMPWORKINGDIRECTORY/rootdir/etc/apt/sources.list (URI parse)
+testequal --nomsg "E: Malformed entry 1 in sources file $TMPWORKINGDIRECTORY/$SOURCES (URI)
E: The list of sources could not be read." aptget update --print-uris
# with Enabled: false
@@ -82,7 +119,7 @@ echo "Enabled: no" >> $SOURCES
testempty aptget update --print-uris
# multiple URIs
-msgtest 'Test deb822 sources.list file which has' 'Multiple URIs work'
+msgcleantest 'Test deb822 sources.list file which has' 'Multiple URIs work'
echo "$BASE" | sed -e 's#http://ftp.debian.org/debian#http://ftp.debian.org/debian http://ftp.de.debian.org/debian#' > $SOURCES
testequal --nomsg "'http://ftp.de.debian.org/debian/dists/stable/InRelease' ftp.de.debian.org_debian_dists_stable_InRelease 0
'http://ftp.de.debian.org/debian/dists/stable/main/binary-i386/Packages.bz2' ftp.de.debian.org_debian_dists_stable_main_binary-i386_Packages 0
@@ -92,7 +129,7 @@ testequal --nomsg "'http://ftp.de.debian.org/debian/dists/stable/InRelease' ftp
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris
# multiple Type in one field
-msgtest 'Test deb822 sources.list file which has' 'Multiple Types work'
+msgcleantest 'Test deb822 sources.list file which has' 'Multiple Types work'
echo "$BASE" | sed -e 's#Types: deb#Types: deb deb-src#' > $SOURCES
testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.debian.org_debian_dists_stable_InRelease 0
'http://ftp.debian.org/debian/dists/stable/main/source/Sources.bz2' ftp.debian.org_debian_dists_stable_main_source_Sources 0
@@ -100,7 +137,7 @@ testequal --nomsg "'http://ftp.debian.org/debian/dists/stable/InRelease' ftp.deb
'http://ftp.debian.org/debian/dists/stable/main/i18n/Translation-en.bz2' ftp.debian.org_debian_dists_stable_main_i18n_Translation-en 0 " aptget update --print-uris
# a Suite
-msgtest 'Test deb822 sources.list file which has' 'a exact path and no sections'
+msgcleantest 'Test deb822 sources.list file which has' 'an exact path and no sections'
cat > $SOURCES <<EOF
Types: deb
URIs: http://emacs.naquadah.org
diff --git a/test/libapt/file-helpers.cc b/test/libapt/file-helpers.cc
index 387192868..6811c4158 100644
--- a/test/libapt/file-helpers.cc
+++ b/test/libapt/file-helpers.cc
@@ -56,10 +56,17 @@ void helperCreateLink(std::string const &dir, std::string const &targetname, std
void helperCreateTemporaryFile(std::string const &id, FileFd &fd, std::string * const filename, char const * const content)
{
std::string name("apt-test-");
- name.append(id).append(".XXXXXXXX");
+ name.append(id);
+ size_t const giventmp = name.find(".XXXXXX.");
+ if (giventmp == std::string::npos)
+ name.append(".XXXXXX");
char * tempfile = strdup(name.c_str());
ASSERT_STRNE(NULL, tempfile);
- int tempfile_fd = mkstemp(tempfile);
+ int tempfile_fd;
+ if (giventmp == std::string::npos)
+ tempfile_fd = mkstemp(tempfile);
+ else
+ tempfile_fd = mkstemps(tempfile, name.length() - (giventmp + 7));
ASSERT_NE(-1, tempfile_fd);
if (filename != NULL)
*filename = tempfile;
diff --git a/test/libapt/sourcelist_test.cc b/test/libapt/sourcelist_test.cc
index 9e6f82213..83c441092 100644
--- a/test/libapt/sourcelist_test.cc
+++ b/test/libapt/sourcelist_test.cc
@@ -12,31 +12,26 @@
#include "file-helpers.h"
-class SourceList : public pkgSourceList {
- public:
- using pkgSourceList::ParseFileDeb822;
-};
-
TEST(SourceListTest,ParseFileDeb822)
{
FileFd fd;
std::string tempfile;
- createTemporaryFile("parsefiledeb822", fd, &tempfile,
+ createTemporaryFile("parsefiledeb822.XXXXXX.sources", fd, &tempfile,
"Types: deb\n"
"URIs: http://ftp.debian.org/debian\n"
"Suites: stable\n"
- "Sections: main\n"
+ "Components: main\n"
"Description: short\n"
" long description that can be very long\n"
"\n"
"Types: deb\n"
"URIs: http://ftp.debian.org/debian\n"
"Suites: unstable\n"
- "Sections: main non-free\n");
+ "Components: main non-free\n");
fd.Close();
- SourceList sources;
- EXPECT_EQ(2, sources.ParseFileDeb822(tempfile));
+ pkgSourceList sources;
+ EXPECT_EQ(true, sources.Read(tempfile));
EXPECT_EQ(2, sources.size());
if (tempfile.empty() == false)
diff --git a/vendor/README b/vendor/README
index c2fabbd4c..6846c8455 100644
--- a/vendor/README
+++ b/vendor/README
@@ -44,6 +44,10 @@ apt-key script and the keyring-package in particular as a dependency for apt.
The field current-codename is optional and can be used in sources.list.in.
+The fields sourceslist-list-format and sourceslist-sources-format are used as
+examples in the sources.list manpage and the first one is additionally
+available in the sources.list.in template.
+They should in general reflect the default sources of your distro.
== sources.list.in
@@ -55,6 +59,7 @@ You can use some placeholders in this file, namely:
* &debian-oldstable-codename;
* &debian-testing-codename;
* &ubuntu-codename;
+* &sourceslist-list-format;
with the value you would expect based on the name.
The placeholder &current-codename; is yours and can be set in apt-vendor.ent
@@ -63,4 +68,5 @@ The placeholder &current-codename; is yours and can be set in apt-vendor.ent
== apt.conf-*
Files in your vendor directory following this naming scheme will be picked up
-by the debian/rules file and installed in /etc/apt/apt.conf.d/ directory.
+by the debian/rules file and installed in /etc/apt/apt.conf.d/ directory, with
+"apt.conf-" removed from the beginning of the filename.
diff --git a/vendor/blankon/apt-vendor.ent b/vendor/blankon/apt-vendor.ent
index 2600eb715..ea7625f90 100644
--- a/vendor/blankon/apt-vendor.ent
+++ b/vendor/blankon/apt-vendor.ent
@@ -6,3 +6,12 @@
<!ENTITY keyring-master-filename "/usr/share/keyrings/blankon-master-keyring.gpg">
<!ENTITY keyring-uri "http://arsip.blankonlinux.or.id/blankon/project/blankon-archive-keyring.gpg">
<!ENTITY current-codename "tambora">
+
+<!ENTITY sourceslist-list-format "deb http://arsip.blankonlinux.or.id/blankon &current-codename; main restricted
+deb http://arsip.blankonlinux.or.id/blankon &current-codename;-security main restricted
+deb http://arsip.blankonlinux.or.id/blankon &current-codename;-updates main restricted">
+
+<!ENTITY sourceslist-sources-format "Types: deb
+URIs: http://arsip.blankonlinux.or.id/blankon
+Suites: &current-codename; &current-codename;-security &current-codename;-updates
+Components: main restricted">
diff --git a/vendor/debian/apt-vendor.ent b/vendor/debian/apt-vendor.ent
index 6cda5995c..8b26da385 100644
--- a/vendor/debian/apt-vendor.ent
+++ b/vendor/debian/apt-vendor.ent
@@ -5,3 +5,15 @@
<!ENTITY keyring-removed-filename "<filename>/usr/share/keyrings/debian-archive-removed-keys.gpg</filename>">
<!ENTITY keyring-master-filename "">
<!ENTITY keyring-uri "">
+
+<!ENTITY sourceslist-list-format "deb http://httpredir.debian.org/debian &stable-codename; main contrib non-free
+deb http://security.debian.org &stable-codename;/updates main contrib non-free">
+<!ENTITY sourceslist-sources-format "Types: deb
+URIs: http://httpredir.debian.org/debian
+Suites: &stable-codename;
+Components: main contrib non-free
+
+Types: deb
+URIs: http://security.debian.org
+Suites: &stable-codename;/updates
+Components: main contrib non-free">
diff --git a/vendor/debian/sources.list.in b/vendor/debian/sources.list.in
index 2e430296a..c36fb16a7 100644
--- a/vendor/debian/sources.list.in
+++ b/vendor/debian/sources.list.in
@@ -1,7 +1,6 @@
# See sources.list(5) manpage for more information
# Remember that CD-ROMs, DVDs and such are managed through the apt-cdrom tool.
-deb http://ftp.us.debian.org/debian &debian-stable-codename; main contrib non-free
-deb http://security.debian.org &debian-stable-codename;/updates main contrib non-free
+&sourceslist-list-format;
# Uncomment if you want the apt-get source function to work
#deb-src http://ftp.us.debian.org/debian &debian-stable-codename; main contrib non-free
diff --git a/vendor/raspbian/apt-vendor.ent b/vendor/raspbian/apt-vendor.ent
index e359d2001..dc69f3c03 100644
--- a/vendor/raspbian/apt-vendor.ent
+++ b/vendor/raspbian/apt-vendor.ent
@@ -5,3 +5,9 @@
<!ENTITY keyring-removed-filename "<filename>/usr/share/keyrings/raspbian-archive-removed-keys.gpg</filename>">
<!ENTITY keyring-master-filename "">
<!ENTITY keyring-uri "">
+
+<!ENTITY sourceslist-list-format "deb http://mirrordirector.raspbian.org/raspbian &stable-codename; main contrib non-free">
+<!ENTITY sourceslist-sources-format "Types: deb
+URIs: http://mirrordirector.raspbian.org/raspbian
+Suites: &stable-codename;
+Components: main contrib non-free">
diff --git a/vendor/steamos/apt-vendor.ent b/vendor/steamos/apt-vendor.ent
index dc1b798e6..7cf100fc4 100644
--- a/vendor/steamos/apt-vendor.ent
+++ b/vendor/steamos/apt-vendor.ent
@@ -6,3 +6,10 @@
<!ENTITY keyring-master-filename "">
<!ENTITY keyring-uri "">
<!ENTITY current-codename "alchemist">
+
+<!ENTITY sourceslist-list-format "deb http://repo.steampowered.com/steamos &current-codename; main contrib non-free
+deb-src http://repo.steampowered.com/steamos &current-codename; main contrib non-free">
+<!ENTITY sourceslist-sources-format "Types: deb deb-src
+URIs: http://repo.steampowered.com/steamos
+Suites: &current-codename;
+Components: main contrib non-free">
diff --git a/vendor/steamos/sources.list.in b/vendor/steamos/sources.list.in
index 69174d090..246d2e336 100644
--- a/vendor/steamos/sources.list.in
+++ b/vendor/steamos/sources.list.in
@@ -1,5 +1,3 @@
# See sources.list(5) manpage for more information
# Remember that CD-ROMs, DVDs and such are managed through the apt-cdrom tool.
-
-deb http://repo.steampowered.com/steamos &current-codename; main contrib non-free
-deb-src http://repo.steampowered.com/steamos &current-codename; main contrib non-free
+&sourceslist-list-format;
diff --git a/vendor/tanglu/apt-vendor.ent b/vendor/tanglu/apt-vendor.ent
index d2442209c..f5cd813bf 100644
--- a/vendor/tanglu/apt-vendor.ent
+++ b/vendor/tanglu/apt-vendor.ent
@@ -6,3 +6,9 @@
<!ENTITY keyring-master-filename "">
<!ENTITY keyring-uri "">
<!ENTITY current-codename "bartholomea">
+
+<!ENTITY sourceslist-list-format "deb http://archive.tanglu.org/tanglu &current-codename; main contrib non-free">
+<!ENTITY sourceslist-sources-format "Types: deb
+URIs: http://archive.tanglu.org/tanglu
+Suites: &current-codename;
+Components: main contrib non-free">
diff --git a/vendor/ubuntu/apt-vendor.ent b/vendor/ubuntu/apt-vendor.ent
index caa532699..dcebc9209 100644
--- a/vendor/ubuntu/apt-vendor.ent
+++ b/vendor/ubuntu/apt-vendor.ent
@@ -5,3 +5,16 @@
<!ENTITY keyring-removed-filename "<filename>/usr/share/keyrings/ubuntu-archive-removed-keys.gpg</filename>">
<!ENTITY keyring-master-filename "/usr/share/keyrings/ubuntu-master-keyring.gpg">
<!ENTITY keyring-uri "http://archive.ubuntu.com/ubuntu/project/ubuntu-archive-keyring.gpg">
+
+<!ENTITY sourceslist-list-format "deb http://us.archive.ubuntu.com/ubuntu &ubuntu-codename; main restricted
+deb http://security.ubuntu.com/ubuntu &ubuntu-codename;-security main restricted
+deb http://us.archive.ubuntu.com/ubuntu &ubuntu-codename;-updates main restricted">
+<!ENTITY sourceslist-sources-format "Types: deb
+URIs: http://us.archive.ubuntu.com/ubuntu
+Suites: &ubuntu-codename; &ubuntu-codename;-updates
+Components: main restricted
+
+Types: deb
+URIs: http://security.ubuntu.com/ubuntu
+Suites: &ubuntu-codename;-security
+Components: main restricted">