sourcelist.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: sourcelist.cc,v 1.25 2004/06/07 23:08:00 mdz Exp $
  4. /* ######################################################################
  5. List of Sources
  6. ##################################################################### */
  7. /*}}}*/
  8. // Include Files /*{{{*/
  9. #ifdef __GNUG__
  10. #pragma implementation "apt-pkg/sourcelist.h"
  11. #endif
  12. #include <apt-pkg/sourcelist.h>
  13. #include <apt-pkg/error.h>
  14. #include <apt-pkg/fileutl.h>
  15. #include <apt-pkg/strutl.h>
  16. #include <apt-pkg/configuration.h>
  17. #include <apti18n.h>
  18. #include <fstream>
  19. /*}}}*/
  20. using namespace std;
  21. // Global list of Items supported
  22. static pkgSourceList::Type *ItmList[10];
  23. pkgSourceList::Type **pkgSourceList::Type::GlobalList = ItmList;
  24. unsigned long pkgSourceList::Type::GlobalListLen = 0;
  25. // Type::Type - Constructor /*{{{*/
  26. // ---------------------------------------------------------------------
  27. /* Link this to the global list of items*/
  28. pkgSourceList::Type::Type()
  29. {
  30. ItmList[GlobalListLen] = this;
  31. GlobalListLen++;
  32. }
  33. /*}}}*/
  34. // Type::GetType - Get a specific meta for a given type /*{{{*/
  35. // ---------------------------------------------------------------------
  36. /* */
  37. pkgSourceList::Type *pkgSourceList::Type::GetType(const char *Type)
  38. {
  39. for (unsigned I = 0; I != GlobalListLen; I++)
  40. if (strcmp(GlobalList[I]->Name,Type) == 0)
  41. return GlobalList[I];
  42. return 0;
  43. }
  44. /*}}}*/
  45. // Type::FixupURI - Normalize the URI and check it.. /*{{{*/
  46. // ---------------------------------------------------------------------
  47. /* */
  48. bool pkgSourceList::Type::FixupURI(string &URI) const
  49. {
  50. if (URI.empty() == true)
  51. return false;
  52. if (URI.find(':') == string::npos)
  53. return false;
  54. URI = SubstVar(URI,"$(ARCH)",_config->Find("APT::Architecture"));
  55. // Make sure that the URI is / postfixed
  56. if (URI[URI.size() - 1] != '/')
  57. URI += '/';
  58. return true;
  59. }
  60. /*}}}*/
  61. // Type::ParseLine - Parse a single line /*{{{*/
  62. // ---------------------------------------------------------------------
  63. /* This is a generic one that is the 'usual' format for sources.list
  64. Weird types may override this. */
  65. bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
  66. const char *Buffer,
  67. unsigned long CurLine,
  68. string File) const
  69. {
  70. string URI;
  71. string Dist;
  72. string Section;
  73. if (ParseQuoteWord(Buffer,URI) == false)
  74. return _error->Error(_("Malformed line %lu in source list %s (URI)"),CurLine,File.c_str());
  75. if (ParseQuoteWord(Buffer,Dist) == false)
  76. return _error->Error(_("Malformed line %lu in source list %s (dist)"),CurLine,File.c_str());
  77. if (FixupURI(URI) == false)
  78. return _error->Error(_("Malformed line %lu in source list %s (URI parse)"),CurLine,File.c_str());
  79. // Check for an absolute dists specification.
  80. if (Dist.empty() == false && Dist[Dist.size() - 1] == '/')
  81. {
  82. if (ParseQuoteWord(Buffer,Section) == true)
  83. return _error->Error(_("Malformed line %lu in source list %s (absolute dist)"),CurLine,File.c_str());
  84. Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture"));
  85. return CreateItem(List,URI,Dist,Section);
  86. }
  87. // Grab the rest of the dists
  88. if (ParseQuoteWord(Buffer,Section) == false)
  89. return _error->Error(_("Malformed line %lu in source list %s (dist parse)"),CurLine,File.c_str());
  90. do
  91. {
  92. if (CreateItem(List,URI,Dist,Section) == false)
  93. return false;
  94. }
  95. while (ParseQuoteWord(Buffer,Section) == true);
  96. return true;
  97. }
  98. /*}}}*/
  99. // SourceList::pkgSourceList - Constructors /*{{{*/
  100. // ---------------------------------------------------------------------
  101. /* */
  102. pkgSourceList::pkgSourceList()
  103. {
  104. }
  105. pkgSourceList::pkgSourceList(string File)
  106. {
  107. Read(File);
  108. }
  109. /*}}}*/
  110. // SourceList::~pkgSourceList - Destructor /*{{{*/
  111. // ---------------------------------------------------------------------
  112. /* */
  113. pkgSourceList::~pkgSourceList()
  114. {
  115. for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
  116. delete *I;
  117. }
  118. /*}}}*/
  119. /*}}}*/
  120. // SourceList::ReadMainList - Read the main source list from etc /*{{{*/
  121. // ---------------------------------------------------------------------
  122. /* */
  123. bool pkgSourceList::ReadMainList()
  124. {
  125. return Read(_config->FindFile("Dir::Etc::sourcelist"));
  126. }
  127. /*}}}*/
  128. // SourceList::Read - Parse the sourcelist file /*{{{*/
  129. // ---------------------------------------------------------------------
  130. /* */
  131. bool pkgSourceList::Read(string File)
  132. {
  133. // Open the stream for reading
  134. ifstream F(File.c_str(),ios::in /*| ios::nocreate*/);
  135. if (!F != 0)
  136. return _error->Errno("ifstream::ifstream",_("Opening %s"),File.c_str());
  137. for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
  138. delete *I;
  139. SrcList.erase(SrcList.begin(),SrcList.end());
  140. char Buffer[300];
  141. int CurLine = 0;
  142. while (F.eof() == false)
  143. {
  144. F.getline(Buffer,sizeof(Buffer));
  145. CurLine++;
  146. _strtabexpand(Buffer,sizeof(Buffer));
  147. if (F.fail() && !F.eof())
  148. return _error->Error(_("Line %u too long in source list %s."),
  149. CurLine,File.c_str());
  150. char *I;
  151. for (I = Buffer; *I != 0 && *I != '#'; I++);
  152. *I = 0;
  153. const char *C = _strstrip(Buffer);
  154. // Comment or blank
  155. if (C[0] == '#' || C[0] == 0)
  156. continue;
  157. // Grok it
  158. string LineType;
  159. if (ParseQuoteWord(C,LineType) == false)
  160. return _error->Error(_("Malformed line %u in source list %s (type)"),CurLine,File.c_str());
  161. Type *Parse = Type::GetType(LineType.c_str());
  162. if (Parse == 0)
  163. return _error->Error(_("Type '%s' is not known on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
  164. // Vendor name specified
  165. if (C[0] == '[')
  166. {
  167. string VendorID;
  168. if (ParseQuoteWord(C,VendorID) == false)
  169. return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
  170. if (VendorID.length() < 2 || VendorID.end()[-1] != ']')
  171. return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
  172. VendorID = string(VendorID,1,VendorID.size()-2);
  173. // for (vector<const Vendor *>::const_iterator iter = VendorList.begin();
  174. // iter != VendorList.end(); iter++)
  175. // {
  176. // if ((*iter)->GetVendorID() == VendorID)
  177. // {
  178. // if (_config->FindB("Debug::sourceList", false))
  179. // std::cerr << "Comparing VendorID \"" << VendorID << "\" with \"" << (*iter)->GetVendorID() << '"' << std::endl;
  180. // Verifier = *iter;
  181. // break;
  182. // }
  183. // }
  184. // if (Verifier == 0)
  185. // return _error->Error(_("Unknown vendor ID '%s' in line %u of source list %s"),
  186. // VendorID.c_str(),CurLine,File.c_str());
  187. }
  188. if (Parse->ParseLine(SrcList,C,CurLine,File) == false)
  189. return false;
  190. }
  191. return true;
  192. }
  193. /*}}}*/
  194. // SourceList::FindIndex - Get the index associated with a file /*{{{*/
  195. // ---------------------------------------------------------------------
  196. /* */
  197. bool pkgSourceList::FindIndex(pkgCache::PkgFileIterator File,
  198. pkgIndexFile *&Found) const
  199. {
  200. for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
  201. {
  202. vector<pkgIndexFile *> *Indexes = (*I)->GetIndexFiles();
  203. for (vector<pkgIndexFile *>::const_iterator J = Indexes->begin();
  204. J != Indexes->end(); J++)
  205. {
  206. if ((*J)->FindInCache(*File.Cache()) == File)
  207. {
  208. Found = (*J);
  209. return true;
  210. }
  211. }
  212. }
  213. return false;
  214. }
  215. /*}}}*/
  216. // SourceList::GetIndexes - Load the index files into the downloader /*{{{*/
  217. // ---------------------------------------------------------------------
  218. /* */
  219. bool pkgSourceList::GetIndexes(pkgAcquire *Owner, bool GetAll) const
  220. {
  221. for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
  222. if ((*I)->GetIndexes(Owner,GetAll) == false)
  223. return false;
  224. return true;
  225. }
  226. /*}}}*/