]> git.saurik.com Git - apt-legacy.git/blame - apt-pkg/deb/deblistparser.cc
Attempt to skip and resync any seriously broken semantics in package sections.
[apt-legacy.git] / apt-pkg / deb / deblistparser.cc
CommitLineData
da6ee469
JF
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
3// $Id: deblistparser.cc,v 1.29.2.5 2004/01/06 01:43:44 mdz Exp $
4/* ######################################################################
5
6 Package Cache Generator - Generator for the cache structure.
7
8 This builds the cache structure from the abstract package list parser.
9
10 ##################################################################### */
11 /*}}}*/
12// Include Files /*{{{*/
13#include <apt-pkg/deblistparser.h>
14#include <apt-pkg/error.h>
15#include <apt-pkg/configuration.h>
16#include <apt-pkg/strutl.h>
17#include <apt-pkg/crc-16.h>
00ec24d0 18#include <apt-pkg/md5.h>
0e5943eb 19#include <apt-pkg/macros.h>
da6ee469
JF
20
21#include <ctype.h>
da6ee469
JF
22 /*}}}*/
23
24static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Important},
25 {"required",pkgCache::State::Required},
26 {"standard",pkgCache::State::Standard},
27 {"optional",pkgCache::State::Optional},
28 {"extra",pkgCache::State::Extra},
29 {}};
30
31// ListParser::debListParser - Constructor /*{{{*/
32// ---------------------------------------------------------------------
33/* */
34debListParser::debListParser(FileFd *File) : Tags(File)
35{
36 Arch = _config->Find("APT::architecture");
37}
38 /*}}}*/
39// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/
40// ---------------------------------------------------------------------
41/* */
5022530b
JF
42unsigned long debListParser::FindTagWrite(const char *Tag)
43{
44 const char *Start;
45 const char *Stop;
46 if (Section.Find(Tag,Start,Stop) == false)
47 return 0;
148029df 48 return WriteString(Start,Stop - Start);
5022530b
JF
49}
50 /*}}}*/
51// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/
52// ---------------------------------------------------------------------
53/* */
da6ee469
JF
54unsigned long debListParser::UniqFindTagWrite(const char *Tag)
55{
56 const char *Start;
57 const char *Stop;
58 if (Section.Find(Tag,Start,Stop) == false)
59 return 0;
60 return WriteUniqString(Start,Stop - Start);
61}
62 /*}}}*/
63// ListParser::Package - Return the package name /*{{{*/
64// ---------------------------------------------------------------------
65/* This is to return the name of the package this section describes */
66string debListParser::Package()
67{
68 string Result = Section.FindS("Package");
69 if (Result.empty() == true)
70 _error->Error("Encountered a section with no Package: header");
71 return Result;
72}
73 /*}}}*/
74// ListParser::Version - Return the version string /*{{{*/
75// ---------------------------------------------------------------------
76/* This is to return the string describing the version in debian form,
77 epoch:upstream-release. If this returns the blank string then the
78 entry is assumed to only describe package properties */
79string debListParser::Version()
80{
81 return Section.FindS("Version");
82}
83 /*}}}*/
84// ListParser::NewVersion - Fill in the version structure /*{{{*/
85// ---------------------------------------------------------------------
86/* */
87bool debListParser::NewVersion(pkgCache::VerIterator Ver)
88{
5022530b 89 Ver->Display = FindTagWrite("Name");
acdafb44 90 if (Ver->Display == 0)
5022530b 91 Ver->Display = FindTagWrite("Maemo-Display-Name");
acdafb44 92
da6ee469
JF
93 // Parse the section
94 Ver->Section = UniqFindTagWrite("Section");
95 Ver->Arch = UniqFindTagWrite("Architecture");
96
97 // Archive Size
98 Ver->Size = (unsigned)Section.FindI("Size");
99
100 // Unpacked Size (in K)
101 Ver->InstalledSize = (unsigned)Section.FindI("Installed-Size");
102 Ver->InstalledSize *= 1024;
103
104 // Priority
105 const char *Start;
106 const char *Stop;
107 if (Section.Find("Priority",Start,Stop) == true)
108 {
734f3daf 109 if (GrabWord(srkString(Start,Stop-Start),PrioList,Ver->Priority) == false)
da6ee469
JF
110 Ver->Priority = pkgCache::State::Extra;
111 }
112
113 if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false)
114 return false;
115 if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false)
116 return false;
117 if (ParseDepends(Ver,"Suggests",pkgCache::Dep::Suggests) == false)
118 return false;
119 if (ParseDepends(Ver,"Recommends",pkgCache::Dep::Recommends) == false)
120 return false;
121 if (ParseDepends(Ver,"Conflicts",pkgCache::Dep::Conflicts) == false)
122 return false;
00ec24d0
JF
123 if (ParseDepends(Ver,"Breaks",pkgCache::Dep::DpkgBreaks) == false)
124 return false;
da6ee469
JF
125 if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false)
126 return false;
0e5943eb
JF
127 if (ParseDepends(Ver,"Enhances",pkgCache::Dep::Enhances) == false)
128 return false;
da6ee469
JF
129
130 // Obsolete.
131 if (ParseDepends(Ver,"Optional",pkgCache::Dep::Suggests) == false)
132 return false;
133
134 if (ParseProvides(Ver) == false)
135 return false;
136
137 return true;
138}
139 /*}}}*/
00ec24d0
JF
140// ListParser::Description - Return the description string /*{{{*/
141// ---------------------------------------------------------------------
142/* This is to return the string describing the package in debian
143 form. If this returns the blank string then the entry is assumed to
144 only describe package properties */
145string debListParser::Description()
146{
734f3daf
JF
147 srkString description;
148 Description(description);
149 return description;
150}
151
152void debListParser::Description(srkString &Str) {
153 const char *Start, *Stop;
154 if (!Section.Find("Description", Start, Stop))
155 if (!Section.Find(("Description-" + pkgIndexFile::LanguageCode()).c_str(), Start, Stop)) {
156 Start = NULL;
157 Stop = NULL;
158 }
159 Str.assign(Start, Stop);
00ec24d0
JF
160}
161 /*}}}*/
162// ListParser::DescriptionLanguage - Return the description lang string /*{{{*/
163// ---------------------------------------------------------------------
164/* This is to return the string describing the language of
165 description. If this returns the blank string then the entry is
166 assumed to describe original description. */
167string debListParser::DescriptionLanguage()
168{
734f3daf
JF
169 const char *Start, *Stop;
170 return Section.Find("Description", Start, Stop) ? std::string() : pkgIndexFile::LanguageCode();
00ec24d0
JF
171}
172 /*}}}*/
173// ListParser::Description - Return the description_md5 MD5SumValue /*{{{*/
174// ---------------------------------------------------------------------
175/* This is to return the md5 string to allow the check if it is the right
176 description. If no Description-md5 is found in the section it will be
177 calculated.
178 */
179MD5SumValue debListParser::Description_md5()
180{
734f3daf
JF
181 const char *Start;
182 const char *Stop;
183 if (!Section.Find("Description-md5", Start, Stop))
00ec24d0
JF
184 {
185 MD5Summation md5;
734f3daf
JF
186 srkString description;
187 Description(description);
188 md5.Add((const unsigned char *) description.Start, description.Size);
189 md5.Add("\n");
00ec24d0
JF
190 return md5.Result();
191 } else
734f3daf 192 return MD5SumValue(srkString(Start, Stop));
00ec24d0
JF
193}
194 /*}}}*/
da6ee469
JF
195// ListParser::UsePackage - Update a package structure /*{{{*/
196// ---------------------------------------------------------------------
197/* This is called to update the package with any new information
198 that might be found in the section */
199bool debListParser::UsePackage(pkgCache::PkgIterator Pkg,
200 pkgCache::VerIterator Ver)
201{
acdafb44 202 if (Pkg->Display == 0)
5022530b 203 Pkg->Display = FindTagWrite("Name");
acdafb44 204 if (Pkg->Display == 0)
5022530b 205 Pkg->Display = FindTagWrite("Maemo-Display-Name");
da6ee469
JF
206 if (Pkg->Section == 0)
207 Pkg->Section = UniqFindTagWrite("Section");
208 if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false)
209 return false;
210 if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false)
211 return false;
212
213 if (strcmp(Pkg.Name(),"apt") == 0)
214 Pkg->Flags |= pkgCache::Flag::Important;
215
216 if (ParseStatus(Pkg,Ver) == false)
217 return false;
acdafb44
JF
218
219 if (Pkg->TagList == 0)
220 if (ParseTag(Pkg) == false)
221 return false;
222
da6ee469
JF
223 return true;
224}
225 /*}}}*/
226// ListParser::VersionHash - Compute a unique hash for this version /*{{{*/
227// ---------------------------------------------------------------------
228/* */
229unsigned short debListParser::VersionHash()
230{
231 const char *Sections[] ={"Installed-Size",
232 "Depends",
233 "Pre-Depends",
234// "Suggests",
235// "Recommends",
236 "Conflicts",
00ec24d0 237 "Breaks",
da6ee469
JF
238 "Replaces",0};
239 unsigned long Result = INIT_FCS;
240 char S[1024];
241 for (const char **I = Sections; *I != 0; I++)
242 {
243 const char *Start;
244 const char *End;
245 if (Section.Find(*I,Start,End) == false || End - Start >= (signed)sizeof(S))
246 continue;
247
248 /* Strip out any spaces from the text, this undoes dpkgs reformatting
249 of certain fields. dpkg also has the rather interesting notion of
250 reformatting depends operators < -> <= */
251 char *I = S;
252 for (; Start != End; Start++)
253 {
254 if (isspace(*Start) == 0)
0e5943eb 255 *I++ = tolower_ascii(*Start);
da6ee469
JF
256 if (*Start == '<' && Start[1] != '<' && Start[1] != '=')
257 *I++ = '=';
258 if (*Start == '>' && Start[1] != '>' && Start[1] != '=')
259 *I++ = '=';
260 }
261
262 Result = AddCRC16(Result,S,I - S);
263 }
264
265 return Result;
266}
267 /*}}}*/
268// ListParser::ParseStatus - Parse the status field /*{{{*/
269// ---------------------------------------------------------------------
270/* Status lines are of the form,
271 Status: want flag status
272 want = unknown, install, hold, deinstall, purge
273 flag = ok, reinstreq, hold, hold-reinstreq
274 status = not-installed, unpacked, half-configured,
275 half-installed, config-files, post-inst-failed,
276 removal-failed, installed
277
278 Some of the above are obsolete (I think?) flag = hold-* and
279 status = post-inst-failed, removal-failed at least.
280 */
281bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg,
282 pkgCache::VerIterator Ver)
283{
284 const char *Start;
285 const char *Stop;
286 if (Section.Find("Status",Start,Stop) == false)
287 return true;
288
289 // Isolate the first word
290 const char *I = Start;
291 for(; I < Stop && *I != ' '; I++);
292 if (I >= Stop || *I != ' ')
293 return _error->Error("Malformed Status line");
294
295 // Process the want field
296 WordList WantList[] = {{"unknown",pkgCache::State::Unknown},
297 {"install",pkgCache::State::Install},
298 {"hold",pkgCache::State::Hold},
299 {"deinstall",pkgCache::State::DeInstall},
300 {"purge",pkgCache::State::Purge},
301 {}};
734f3daf 302 if (GrabWord(srkString(Start,I-Start),WantList,Pkg->SelectedState) == false)
da6ee469
JF
303 return _error->Error("Malformed 1st word in the Status line");
304
305 // Isloate the next word
306 I++;
307 Start = I;
308 for(; I < Stop && *I != ' '; I++);
309 if (I >= Stop || *I != ' ')
310 return _error->Error("Malformed status line, no 2nd word");
311
312 // Process the flag field
313 WordList FlagList[] = {{"ok",pkgCache::State::Ok},
314 {"reinstreq",pkgCache::State::ReInstReq},
315 {"hold",pkgCache::State::HoldInst},
316 {"hold-reinstreq",pkgCache::State::HoldReInstReq},
317 {}};
734f3daf 318 if (GrabWord(srkString(Start,I-Start),FlagList,Pkg->InstState) == false)
da6ee469
JF
319 return _error->Error("Malformed 2nd word in the Status line");
320
321 // Isloate the last word
322 I++;
323 Start = I;
324 for(; I < Stop && *I != ' '; I++);
325 if (I != Stop)
326 return _error->Error("Malformed Status line, no 3rd word");
327
328 // Process the flag field
329 WordList StatusList[] = {{"not-installed",pkgCache::State::NotInstalled},
330 {"unpacked",pkgCache::State::UnPacked},
331 {"half-configured",pkgCache::State::HalfConfigured},
332 {"installed",pkgCache::State::Installed},
333 {"half-installed",pkgCache::State::HalfInstalled},
334 {"config-files",pkgCache::State::ConfigFiles},
00ec24d0
JF
335 {"triggers-awaited",pkgCache::State::TriggersAwaited},
336 {"triggers-pending",pkgCache::State::TriggersPending},
da6ee469
JF
337 {"post-inst-failed",pkgCache::State::HalfConfigured},
338 {"removal-failed",pkgCache::State::HalfInstalled},
339 {}};
734f3daf 340 if (GrabWord(srkString(Start,I-Start),StatusList,Pkg->CurrentState) == false)
da6ee469
JF
341 return _error->Error("Malformed 3rd word in the Status line");
342
343 /* A Status line marks the package as indicating the current
344 version as well. Only if it is actually installed.. Otherwise
345 the interesting dpkg handling of the status file creates bogus
346 entries. */
347 if (!(Pkg->CurrentState == pkgCache::State::NotInstalled ||
348 Pkg->CurrentState == pkgCache::State::ConfigFiles))
349 {
350 if (Ver.end() == true)
351 _error->Warning("Encountered status field in a non-version description");
352 else
353 Pkg->CurrentVer = Ver.Index();
354 }
355
356 return true;
357}
358
359const char *debListParser::ConvertRelation(const char *I,unsigned int &Op)
360{
361 // Determine the operator
362 switch (*I)
363 {
364 case '<':
365 I++;
366 if (*I == '=')
367 {
368 I++;
369 Op = pkgCache::Dep::LessEq;
370 break;
371 }
372
373 if (*I == '<')
374 {
375 I++;
376 Op = pkgCache::Dep::Less;
377 break;
378 }
379
380 // < is the same as <= and << is really Cs < for some reason
381 Op = pkgCache::Dep::LessEq;
382 break;
383
384 case '>':
385 I++;
386 if (*I == '=')
387 {
388 I++;
389 Op = pkgCache::Dep::GreaterEq;
390 break;
391 }
392
393 if (*I == '>')
394 {
395 I++;
396 Op = pkgCache::Dep::Greater;
397 break;
398 }
399
400 // > is the same as >= and >> is really Cs > for some reason
401 Op = pkgCache::Dep::GreaterEq;
402 break;
403
404 case '=':
405 Op = pkgCache::Dep::Equals;
406 I++;
407 break;
408
409 // HACK around bad package definitions
410 default:
411 Op = pkgCache::Dep::Equals;
412 break;
413 }
414 return I;
415}
416
417 /*}}}*/
418// ListParser::ParseDepends - Parse a dependency element /*{{{*/
419// ---------------------------------------------------------------------
420/* This parses the dependency elements out of a standard string in place,
421 bit by bit. */
422const char *debListParser::ParseDepends(const char *Start,const char *Stop,
423 string &Package,string &Ver,
424 unsigned int &Op, bool ParseArchFlags)
734f3daf
JF
425{
426 srkString cPackage, cVer;
427 const char *Value = ParseDepends(Start, Stop, cPackage, cVer, Op, ParseArchFlags);
428 Package = cPackage;
429 Ver = cVer;
430 return Value;
431}
432
433const char *debListParser::ParseDepends(const char *Start,const char *Stop,
434 srkString &Package,srkString &Ver,
435 unsigned int &Op, bool ParseArchFlags)
da6ee469
JF
436{
437 // Strip off leading space
438 for (;Start != Stop && isspace(*Start) != 0; Start++);
439
440 // Parse off the package name
441 const char *I = Start;
442 for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' &&
443 *I != ',' && *I != '|'; I++);
444
445 // Malformed, no '('
446 if (I != Stop && *I == ')')
447 return 0;
448
449 if (I == Start)
450 return 0;
451
452 // Stash the package name
453 Package.assign(Start,I - Start);
454
455 // Skip white space to the '('
456 for (;I != Stop && isspace(*I) != 0 ; I++);
457
458 // Parse a version
459 if (I != Stop && *I == '(')
460 {
461 // Skip the '('
462 for (I++; I != Stop && isspace(*I) != 0 ; I++);
463 if (I + 3 >= Stop)
464 return 0;
465 I = ConvertRelation(I,Op);
466
467 // Skip whitespace
468 for (;I != Stop && isspace(*I) != 0; I++);
469 Start = I;
470 for (;I != Stop && *I != ')'; I++);
471 if (I == Stop || Start == I)
472 return 0;
473
474 // Skip trailing whitespace
475 const char *End = I;
476 for (; End > Start && isspace(End[-1]); End--);
477
478 Ver.assign(Start,End-Start);
479 I++;
480 }
481 else
482 {
483 Ver.clear();
484 Op = pkgCache::Dep::NoOp;
485 }
486
487 // Skip whitespace
488 for (;I != Stop && isspace(*I) != 0; I++);
489
490 if (ParseArchFlags == true)
491 {
492 string arch = _config->Find("APT::Architecture");
493
494 // Parse an architecture
495 if (I != Stop && *I == '[')
496 {
497 // malformed
498 I++;
499 if (I == Stop)
500 return 0;
501
502 const char *End = I;
503 bool Found = false;
504 bool NegArch = false;
505 while (I != Stop)
506 {
507 // look for whitespace or ending ']'
508 while (End != Stop && !isspace(*End) && *End != ']')
509 End++;
510
511 if (End == Stop)
512 return 0;
513
514 if (*I == '!')
515 {
516 NegArch = true;
517 I++;
518 }
519
520 if (stringcmp(arch,I,End) == 0)
521 Found = true;
522
523 if (*End++ == ']') {
524 I = End;
525 break;
526 }
527
528 I = End;
529 for (;I != Stop && isspace(*I) != 0; I++);
530 }
531
532 if (NegArch)
533 Found = !Found;
534
535 if (Found == false)
734f3daf 536 Package.clear(); /* not for this arch */
da6ee469
JF
537 }
538
539 // Skip whitespace
540 for (;I != Stop && isspace(*I) != 0; I++);
541 }
542
543 if (I != Stop && *I == '|')
544 Op |= pkgCache::Dep::Or;
545
546 if (I == Stop || *I == ',' || *I == '|')
547 {
548 if (I != Stop)
549 for (I++; I != Stop && isspace(*I) != 0; I++);
550 return I;
551 }
552
553 return 0;
554}
555 /*}}}*/
556// ListParser::ParseDepends - Parse a dependency list /*{{{*/
557// ---------------------------------------------------------------------
558/* This is the higher level depends parser. It takes a tag and generates
559 a complete depends tree for the given version. */
560bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
561 const char *Tag,unsigned int Type)
562{
563 const char *Start;
564 const char *Stop;
565 if (Section.Find(Tag,Start,Stop) == false)
566 return true;
567
734f3daf
JF
568 srkString Package;
569 srkString Version;
da6ee469
JF
570 unsigned int Op;
571
572 while (1)
573 {
574 Start = ParseDepends(Start,Stop,Package,Version,Op);
56d724df
JF
575 if (Start == 0) {
576 _error->Warning("Problem parsing dependency %s",Tag);
577 return false;
578 }
da6ee469
JF
579
580 if (NewDepends(Ver,Package,Version,Op,Type) == false)
581 return false;
582 if (Start == Stop)
583 break;
584 }
585 return true;
586}
587 /*}}}*/
588// ListParser::ParseProvides - Parse the provides list /*{{{*/
589// ---------------------------------------------------------------------
590/* */
591bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
592{
593 const char *Start;
594 const char *Stop;
595 if (Section.Find("Provides",Start,Stop) == false)
596 return true;
597
734f3daf
JF
598 srkString Package;
599 srkString Version;
da6ee469
JF
600 unsigned int Op;
601
602 while (1)
603 {
604 Start = ParseDepends(Start,Stop,Package,Version,Op);
56d724df
JF
605 if (Start == 0) {
606 _error->Warning("Problem parsing Provides line");
607 return false;
608 }
609
da6ee469 610 if (Op != pkgCache::Dep::NoOp) {
734f3daf 611 _error->Warning("Ignoring Provides line with DepCompareOp for package %s", std::string(Package).c_str());
da6ee469
JF
612 } else {
613 if (NewProvides(Ver,Package,Version) == false)
614 return false;
615 }
616
617 if (Start == Stop)
618 break;
619 }
620
acdafb44
JF
621 return true;
622}
623 /*}}}*/
624// ListParser::ParseTag - Parse the tag list /*{{{*/
625// ---------------------------------------------------------------------
626/* */
627bool debListParser::ParseTag(pkgCache::PkgIterator Pkg)
628{
629 const char *Start;
630 const char *Stop;
631 if (Section.Find("Tag",Start,Stop) == false)
632 return true;
633
634 while (1) {
635 while (1) {
636 if (Start == Stop)
637 return true;
638 if (Stop[-1] != ' ' && Stop[-1] != '\t')
639 break;
640 --Stop;
641 }
642
643 const char *Begin = Stop - 1;
644 while (Begin != Start && Begin[-1] != ' ' && Begin[-1] != ',')
645 --Begin;
646
647 if (NewTag(Pkg, Begin, Stop - Begin) == false)
648 return false;
649
650 while (1) {
651 if (Begin == Start)
652 return true;
653 if (Begin[-1] == ',')
654 break;
655 --Begin;
656 }
657
658 Stop = Begin - 1;
659 }
660
da6ee469
JF
661 return true;
662}
663 /*}}}*/
664// ListParser::GrabWord - Matches a word and returns /*{{{*/
665// ---------------------------------------------------------------------
666/* Looks for a word in a list of words - for ParseStatus */
667bool debListParser::GrabWord(string Word,WordList *List,unsigned char &Out)
734f3daf
JF
668{
669 return GrabWord(srkString(Word), List, Out);
670}
671
672bool debListParser::GrabWord(const srkString &Word,WordList *List,unsigned char &Out)
da6ee469
JF
673{
674 for (unsigned int C = 0; List[C].Str != 0; C++)
675 {
734f3daf 676 if (strncasecmp(Word.Start,List[C].Str,Word.Size) == 0)
da6ee469
JF
677 {
678 Out = List[C].Val;
679 return true;
680 }
681 }
682 return false;
683}
684 /*}}}*/
685// ListParser::Step - Move to the next section in the file /*{{{*/
686// ---------------------------------------------------------------------
687/* This has to be carefull to only process the correct architecture */
688bool debListParser::Step()
689{
690 iOffset = Tags.Offset();
691 while (Tags.Step(Section) == true)
692 {
d1238c91
JF
693 const char *Start;
694 const char *Stop;
695
696 if (Section.Find("Package",Start,Stop) == false) {
697 _error->Warning("Encountered a section with no Package: header");
698 continue;
699 }
700
da6ee469
JF
701 /* See if this is the correct Architecture, if it isn't then we
702 drop the whole section. A missing arch tag only happens (in theory)
703 inside the Status file, so that is a positive return */
d1238c91 704
da6ee469
JF
705 if (Section.Find("Architecture",Start,Stop) == false)
706 return true;
707
708 if (stringcmp(Arch,Start,Stop) == 0)
709 return true;
710
711 if (stringcmp(Start,Stop,"all") == 0)
712 return true;
713
a9359695
JF
714 if (stringcmp(Start,Stop,"cydia") == 0)
715 return true;
716
da6ee469
JF
717 iOffset = Tags.Offset();
718 }
719 return false;
720}
721 /*}}}*/
722// ListParser::LoadReleaseInfo - Load the release information /*{{{*/
723// ---------------------------------------------------------------------
724/* */
725bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
726 FileFd &File, string component)
727{
728 pkgTagFile Tags(&File, File.Size() + 256); // XXX
729 pkgTagSection Section;
730 if (Tags.Step(Section) == false)
731 return false;
732
733 //mvo: I don't think we need to fill that in (it's unused since apt-0.6)
734 //FileI->Architecture = WriteUniqString(Arch);
735
736 // apt-secure does no longer download individual (per-section) Release
737 // file. to provide Component pinning we use the section name now
738 FileI->Component = WriteUniqString(component);
739
740 const char *Start;
741 const char *Stop;
742 if (Section.Find("Suite",Start,Stop) == true)
743 FileI->Archive = WriteUniqString(Start,Stop - Start);
744 if (Section.Find("Component",Start,Stop) == true)
745 FileI->Component = WriteUniqString(Start,Stop - Start);
746 if (Section.Find("Version",Start,Stop) == true)
747 FileI->Version = WriteUniqString(Start,Stop - Start);
748 if (Section.Find("Origin",Start,Stop) == true)
749 FileI->Origin = WriteUniqString(Start,Stop - Start);
750 if (Section.Find("Label",Start,Stop) == true)
751 FileI->Label = WriteUniqString(Start,Stop - Start);
752 if (Section.Find("Architecture",Start,Stop) == true)
753 FileI->Architecture = WriteUniqString(Start,Stop - Start);
754
755 if (Section.FindFlag("NotAutomatic",FileI->Flags,
756 pkgCache::Flag::NotAutomatic) == false)
757 _error->Warning("Bad NotAutomatic flag");
758
759 return !_error->PendingError();
760}
761 /*}}}*/
762// ListParser::GetPrio - Convert the priority from a string /*{{{*/
763// ---------------------------------------------------------------------
764/* */
765unsigned char debListParser::GetPrio(string Str)
766{
767 unsigned char Out;
768 if (GrabWord(Str,PrioList,Out) == false)
769 Out = pkgCache::State::Extra;
770
771 return Out;
772}
773 /*}}}*/