diff options
-rw-r--r-- | apt-pkg/policy.cc | 19 | ||||
-rw-r--r-- | apt-pkg/sourcelist.cc | 228 | ||||
-rw-r--r-- | apt-pkg/sourcelist.h | 16 | ||||
-rw-r--r-- | apt-pkg/tagfile.cc | 8 | ||||
-rw-r--r-- | apt-pkg/tagfile.h | 8 | ||||
-rw-r--r-- | doc/sources.list.5.xml | 337 | ||||
-rwxr-xr-x | test/integration/test-apt-sources-deb822 | 75 | ||||
-rw-r--r-- | test/libapt/file-helpers.cc | 11 | ||||
-rw-r--r-- | test/libapt/sourcelist_test.cc | 15 | ||||
-rw-r--r-- | vendor/README | 8 | ||||
-rw-r--r-- | vendor/blankon/apt-vendor.ent | 9 | ||||
-rw-r--r-- | vendor/debian/apt-vendor.ent | 12 | ||||
-rw-r--r-- | vendor/debian/sources.list.in | 3 | ||||
-rw-r--r-- | vendor/raspbian/apt-vendor.ent | 6 | ||||
-rw-r--r-- | vendor/steamos/apt-vendor.ent | 7 | ||||
-rw-r--r-- | vendor/steamos/sources.list.in | 4 | ||||
-rw-r--r-- | vendor/tanglu/apt-vendor.ent | 6 | ||||
-rw-r--r-- | vendor/ubuntu/apt-vendor.ent | 13 |
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 ¤t-codename; is yours and can be set in apt-vendor.ent @@ -63,4 +68,5 @@ The placeholder ¤t-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 ¤t-codename; main restricted +deb http://arsip.blankonlinux.or.id/blankon ¤t-codename;-security main restricted +deb http://arsip.blankonlinux.or.id/blankon ¤t-codename;-updates main restricted"> + +<!ENTITY sourceslist-sources-format "Types: deb +URIs: http://arsip.blankonlinux.or.id/blankon +Suites: ¤t-codename; ¤t-codename;-security ¤t-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 ¤t-codename; main contrib non-free +deb-src http://repo.steampowered.com/steamos ¤t-codename; main contrib non-free"> +<!ENTITY sourceslist-sources-format "Types: deb deb-src +URIs: http://repo.steampowered.com/steamos +Suites: ¤t-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 ¤t-codename; main contrib non-free -deb-src http://repo.steampowered.com/steamos ¤t-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 ¤t-codename; main contrib non-free"> +<!ENTITY sourceslist-sources-format "Types: deb +URIs: http://archive.tanglu.org/tanglu +Suites: ¤t-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"> |