use 'best' hash for source authentication
[ntk/apt.git] / apt-pkg / srcrecords.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: srcrecords.cc,v 1.7.2.2 2003/12/26 16:27:34 mdz Exp $
4 /* ######################################################################
5
6 Source Package Records - Allows access to source package records
7
8 Parses and allows access to the list of source records and searching by
9 source name on that list.
10
11 ##################################################################### */
12 /*}}}*/
13 // Include Files /*{{{*/
14 #include<config.h>
15
16 #include <apt-pkg/srcrecords.h>
17 #include <apt-pkg/debsrcrecords.h>
18 #include <apt-pkg/error.h>
19 #include <apt-pkg/sourcelist.h>
20 #include <apt-pkg/metaindex.h>
21 #include <apt-pkg/indexfile.h>
22 #include <apt-pkg/macros.h>
23
24 #include <string.h>
25 #include <string>
26 #include <vector>
27
28 #include <apti18n.h>
29 /*}}}*/
30
31 // SrcRecords::pkgSrcRecords - Constructor /*{{{*/
32 // ---------------------------------------------------------------------
33 /* Open all the source index files */
34 pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : d(NULL), Files(0), Current(0)
35 {
36 for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); ++I)
37 {
38 std::vector<pkgIndexFile *> *Indexes = (*I)->GetIndexFiles();
39 for (std::vector<pkgIndexFile *>::const_iterator J = Indexes->begin();
40 J != Indexes->end(); ++J)
41 {
42 Parser* P = (*J)->CreateSrcParser();
43 if (_error->PendingError() == true)
44 return;
45 if (P != 0)
46 Files.push_back(P);
47 }
48 }
49
50 // Doesn't work without any source index files
51 if (Files.empty() == true)
52 {
53 _error->Error(_("You must put some 'source' URIs"
54 " in your sources.list"));
55 return;
56 }
57
58 Restart();
59 }
60 /*}}}*/
61 // SrcRecords::~pkgSrcRecords - Destructor /*{{{*/
62 // ---------------------------------------------------------------------
63 /* */
64 pkgSrcRecords::~pkgSrcRecords()
65 {
66 // Blow away all the parser objects
67 for(std::vector<Parser*>::iterator I = Files.begin(); I != Files.end(); ++I)
68 delete *I;
69 }
70 /*}}}*/
71 // SrcRecords::Restart - Restart the search /*{{{*/
72 // ---------------------------------------------------------------------
73 /* Return all of the parsers to their starting position */
74 bool pkgSrcRecords::Restart()
75 {
76 Current = Files.begin();
77 for (std::vector<Parser*>::iterator I = Files.begin();
78 I != Files.end(); ++I)
79 if ((*I)->Offset() != 0)
80 (*I)->Restart();
81
82 return true;
83 }
84 /*}}}*/
85 // SrcRecords::Step - Step to the next Source Record /*{{{*/
86 // ---------------------------------------------------------------------
87 /* Step to the next source package record */
88 const pkgSrcRecords::Parser* pkgSrcRecords::Step()
89 {
90 if (Current == Files.end())
91 return 0;
92
93 // Step to the next record, possibly switching files
94 while ((*Current)->Step() == false)
95 {
96 if (_error->PendingError() == true)
97 return 0;
98 ++Current;
99 if (Current == Files.end())
100 return 0;
101 }
102
103 return *Current;
104 }
105 /*}}}*/
106 // SrcRecords::Find - Find the first source package with the given name /*{{{*/
107 // ---------------------------------------------------------------------
108 /* This searches on both source package names and output binary names and
109 returns the first found. A 'cursor' like system is used to allow this
110 function to be called multiple times to get successive entries */
111 pkgSrcRecords::Parser *pkgSrcRecords::Find(const char *Package,bool const &SrcOnly)
112 {
113 while (true)
114 {
115 if(Step() == 0)
116 return 0;
117
118 // IO error somehow
119 if (_error->PendingError() == true)
120 return 0;
121
122 // Source name hit
123 if ((*Current)->Package() == Package)
124 return *Current;
125
126 if (SrcOnly == true)
127 continue;
128
129 // Check for a binary hit
130 const char **I = (*Current)->Binaries();
131 for (; I != 0 && *I != 0; ++I)
132 if (strcmp(Package,*I) == 0)
133 return *Current;
134 }
135 }
136 /*}}}*/
137 // Parser::BuildDepType - Convert a build dep to a string /*{{{*/
138 // ---------------------------------------------------------------------
139 /* */
140 const char *pkgSrcRecords::Parser::BuildDepType(unsigned char const &Type)
141 {
142 const char *fields[] = {"Build-Depends",
143 "Build-Depends-Indep",
144 "Build-Conflicts",
145 "Build-Conflicts-Indep"};
146 if (unlikely(Type >= sizeof(fields)/sizeof(fields[0])))
147 return "";
148 return fields[Type];
149 }
150 /*}}}*/
151 bool pkgSrcRecords::Parser::Files2(std::vector<pkgSrcRecords::File2> &F2)/*{{{*/
152 {
153 debSrcRecordParser * const deb = dynamic_cast<debSrcRecordParser*>(this);
154 if (deb != NULL)
155 return deb->Files2(F2);
156
157 std::vector<pkgSrcRecords::File> F;
158 if (Files(F) == false)
159 return false;
160 for (std::vector<pkgSrcRecords::File>::const_iterator f = F.begin(); f != F.end(); ++f)
161 {
162 pkgSrcRecords::File2 f2;
163 #if __GNUC__ >= 4
164 #pragma GCC diagnostic push
165 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
166 #endif
167 f2.MD5Hash = f->MD5Hash;
168 f2.Size = f->Size;
169 f2.Hashes.push_back(HashString("MD5Sum", f->MD5Hash));
170 f2.FileSize = f->Size;
171 #if __GNUC__ >= 4
172 #pragma GCC diagnostic pop
173 #endif
174 f2.Path = f->Path;
175 f2.Type = f->Type;
176 F2.push_back(f2);
177 }
178 return true;
179 }
180 /*}}}*/