Add bunch of missing includes to fix build with gcc 4.7
[apt.git] / cmdline / apt-cache.cc
1 // -*- mode: c++; mode: fold -*-
2 // Description                                                          /*{{{*/
3 // $Id: apt-cache.cc,v 1.67 2003/08/02 19:53:23 mdz Exp $
4 /* ######################################################################
5    
6    apt-cache - Manages the cache files
7    
8    apt-cache provides some functions fo manipulating the cache files.
9    It uses the command line interface common to all the APT tools. 
10    
11    Returns 100 on failure, 0 on success.
12    
13    ##################################################################### */
14                                                                         /*}}}*/
15 // Include Files                                                        /*{{{*/
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/pkgcachegen.h>
18 #include <apt-pkg/init.h>
19 #include <apt-pkg/progress.h>
20 #include <apt-pkg/sourcelist.h>
21 #include <apt-pkg/cmndline.h>
22 #include <apt-pkg/strutl.h>
23 #include <apt-pkg/pkgrecords.h>
24 #include <apt-pkg/srcrecords.h>
25 #include <apt-pkg/version.h>
26 #include <apt-pkg/policy.h>
27 #include <apt-pkg/tagfile.h>
28 #include <apt-pkg/algorithms.h>
29 #include <apt-pkg/sptr.h>
30
31 #include <config.h>
32 #include <apti18n.h>
33
34 // CNC:2003-02-14 - apti18n.h includes libintl.h which includes locale.h,
35 //                  as reported by Radu Greab.
36 //#include <locale.h>
37 #include <iostream>
38 #include <unistd.h>
39 #include <errno.h>
40 #include <regex.h>
41 #include <stdio.h>
42
43 // CNC:2003-11-23
44 #include <apt-pkg/luaiface.h>
45     
46 #include "cmdline.h"
47                                                                         /*}}}*/
48
49 using namespace std;
50
51 ostream c0out(0);
52 ostream c1out(0);
53 ostream c2out(0);
54 ofstream devnull("/dev/null");
55 unsigned int ScreenWidth = 80;
56
57 pkgCache *GCache = 0;
58 pkgSourceList *SrcList = 0;
59
60 // CNC:2003-11-23
61 // Script - Scripting stuff.                                            /*{{{*/
62 // ---------------------------------------------------------------------
63 /* */
64 #ifdef APT_WITH_LUA
65 bool Script(CommandLine &CmdL)
66 {
67    for (const char **I = CmdL.FileList+1; *I != 0; I++)
68       _config->Set("Scripts::AptCache::Script::", *I);
69
70    _lua->SetCache(GCache);
71    _lua->RunScripts("Scripts::AptCache::Script");
72    _lua->ResetGlobals();
73
74    return true;
75 }
76 #endif
77                                                                         /*}}}*/
78 // UnMet - Show unmet dependencies                                      /*{{{*/
79 // ---------------------------------------------------------------------
80 /* */
81 bool UnMet(CommandLine &CmdL)
82 {
83    return cmdUnMet(CmdL, *GCache);
84 }
85                                                                         /*}}}*/
86 // DumpPackage - Show a dump of a package record                        /*{{{*/
87 // ---------------------------------------------------------------------
88 /* */
89 bool DumpPackage(CommandLine &CmdL)
90 {   
91    return cmdDumpPackage(CmdL, *GCache);
92 }
93                                                                         /*}}}*/
94 // Stats - Dump some nice statistics                                    /*{{{*/
95 // ---------------------------------------------------------------------
96 /* */
97 bool Stats(CommandLine &Cmd)
98 {
99    pkgCache &Cache = *GCache;
100    cout << _("Total Package Names : ") << Cache.Head().PackageCount << " (" <<
101       SizeToStr(Cache.Head().PackageCount*Cache.Head().PackageSz) << ')' << endl;
102
103    int Normal = 0;
104    int Virtual = 0;
105    int NVirt = 0;
106    int DVirt = 0;
107    int Missing = 0;
108    pkgCache::PkgIterator I = Cache.PkgBegin();
109    for (;I.end() != true; I++)
110    {
111       if (I->VersionList != 0 && I->ProvidesList == 0)
112       {
113          Normal++;
114          continue;
115       }
116
117       if (I->VersionList != 0 && I->ProvidesList != 0)
118       {
119          NVirt++;
120          continue;
121       }
122       
123       if (I->VersionList == 0 && I->ProvidesList != 0)
124       {
125          // Only 1 provides
126          if (I.ProvidesList()->NextProvides == 0)
127          {
128             DVirt++;
129          }
130          else
131             Virtual++;
132          continue;
133       }
134       if (I->VersionList == 0 && I->ProvidesList == 0)
135       {
136          Missing++;
137          continue;
138       }
139    }
140    cout << _("  Normal Packages: ") << Normal << endl;
141    cout << _("  Pure Virtual Packages: ") << Virtual << endl;
142    cout << _("  Single Virtual Packages: ") << DVirt << endl;
143    cout << _("  Mixed Virtual Packages: ") << NVirt << endl;
144    cout << _("  Missing: ") << Missing << endl;
145    
146    cout << _("Total Distinct Versions: ") << Cache.Head().VersionCount << " (" <<
147       SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl;
148    cout << _("Total Dependencies: ") << Cache.Head().DependsCount << " (" << 
149       SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl;
150    
151    cout << _("Total Ver/File relations: ") << Cache.Head().VerFileCount << " (" <<
152       SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl;
153    cout << _("Total Provides Mappings: ") << Cache.Head().ProvidesCount << " (" <<
154       SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl;
155    
156    // String list stats
157    size_t Size = 0;
158    unsigned long Count = 0;
159    for (pkgCache::StringItem *I = Cache.StringItemP + Cache.Head().StringList;
160         I!= Cache.StringItemP; I = Cache.StringItemP + I->NextItem)
161    {
162       Count++;
163       Size += strlen(Cache.StrP + I->String) + 1;
164    }
165    cout << _("Total Globbed Strings: ") << Count << " (" << SizeToStr(Size) << ')' << endl;
166
167    size_t DepVerSize = 0;
168    for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
169    {
170       for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
171       {
172          for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
173          {
174             if (D->Version != 0)
175                DepVerSize += strlen(D.TargetVer()) + 1;
176          }
177       }
178    }
179    cout << _("Total Dependency Version space: ") << SizeToStr(DepVerSize) << endl;
180    
181    unsigned long Slack = 0;
182    for (int I = 0; I != 7; I++)
183       Slack += Cache.Head().Pools[I].ItemSize*Cache.Head().Pools[I].Count;
184    cout << _("Total Slack space: ") << SizeToStr(Slack) << endl;
185    
186    unsigned long Total = 0;
187    Total = Slack + Size + Cache.Head().DependsCount*Cache.Head().DependencySz + 
188            Cache.Head().VersionCount*Cache.Head().VersionSz +
189            Cache.Head().PackageCount*Cache.Head().PackageSz + 
190            Cache.Head().VerFileCount*Cache.Head().VerFileSz +
191            Cache.Head().ProvidesCount*Cache.Head().ProvidesSz;
192    cout << _("Total Space Accounted for: ") << SizeToStr(Total) << endl;
193    
194    return true;
195 }
196                                                                         /*}}}*/
197 // Dump - show everything                                               /*{{{*/
198 // ---------------------------------------------------------------------
199 /* This is worthless except fer debugging things */
200 bool Dump(CommandLine &Cmd)
201 {
202    pkgCache &Cache = *GCache;
203    cout << "Using Versioning System: " << Cache.VS->Label << endl;
204    
205    for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
206    {
207       cout << "Package: " << P.Name() << endl;
208       for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
209       {
210          cout << " Version: " << V.VerStr() << endl;
211          cout << "     File: " << V.FileList().File().FileName() << endl;
212          for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
213             cout << "  Depends: " << D.TargetPkg().Name() << ' ' << 
214                              DeNull(D.TargetVer()) << endl;
215       }      
216    }
217
218    for (pkgCache::PkgFileIterator F = Cache.FileBegin(); F.end() == false; F++)
219    {
220       cout << "File: " << F.FileName() << endl;
221       cout << " Type: " << F.IndexType() << endl;
222       cout << " Size: " << F->Size << endl;
223       cout << " ID: " << F->ID << endl;
224       cout << " Flags: " << F->Flags << endl;
225       cout << " Time: " << TimeRFC1123(F->mtime) << endl;
226       cout << " Archive: " << DeNull(F.Archive()) << endl;
227       cout << " Component: " << DeNull(F.Component()) << endl;
228       cout << " Version: " << DeNull(F.Version()) << endl;
229       cout << " Origin: " << DeNull(F.Origin()) << endl;
230       cout << " Site: " << DeNull(F.Site()) << endl;
231       cout << " Label: " << DeNull(F.Label()) << endl;
232       cout << " Architecture: " << DeNull(F.Architecture()) << endl;
233    }
234
235    return true;
236 }
237                                                                         /*}}}*/
238 // DumpAvail - Print out the available list                             /*{{{*/
239 // ---------------------------------------------------------------------
240 /* This is needed to make dpkg --merge happy.. I spent a bit of time to 
241    make this run really fast, perhaps I went a little overboard.. */
242 bool DumpAvail(CommandLine &Cmd)
243 {
244    pkgCache &Cache = *GCache;
245
246    pkgPolicy Plcy(&Cache);
247    if (ReadPinFile(Plcy) == false)
248       return false;
249    
250    unsigned long Count = Cache.HeaderP->PackageCount+1;
251    pkgCache::VerFile **VFList = new pkgCache::VerFile *[Count];
252    memset(VFList,0,sizeof(*VFList)*Count);
253    
254    // Map versions that we want to write out onto the VerList array.
255    for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
256    {    
257       if (P->VersionList == 0)
258          continue;
259       
260       /* Find the proper version to use. If the policy says there are no
261          possible selections we return the installed version, if available..
262          This prevents dselect from making it obsolete. */
263       pkgCache::VerIterator V = Plcy.GetCandidateVer(P);
264       if (V.end() == true)
265       {
266          if (P->CurrentVer == 0)
267             continue;
268          V = P.CurrentVer();
269       }
270       
271       pkgCache::VerFileIterator VF = V.FileList();
272       for (; VF.end() == false ; VF++)
273          if ((VF.File()->Flags & pkgCache::Flag::NotSource) == 0)
274             break;
275       
276       /* Okay, here we have a bit of a problem.. The policy has selected the
277          currently installed package - however it only exists in the
278          status file.. We need to write out something or dselect will mark
279          the package as obsolete! Thus we emit the status file entry, but
280          below we remove the status line to make it valid for the 
281          available file. However! We only do this if their do exist *any*
282          non-source versions of the package - that way the dselect obsolete
283          handling works OK. */
284       if (VF.end() == true)
285       {
286          for (pkgCache::VerIterator Cur = P.VersionList(); Cur.end() != true; Cur++)
287          {
288             for (VF = Cur.FileList(); VF.end() == false; VF++)
289             {    
290                if ((VF.File()->Flags & pkgCache::Flag::NotSource) == 0)
291                {
292                   VF = V.FileList();
293                   break;
294                }
295             }
296             
297             if (VF.end() == false)
298                break;
299          }
300       }
301       
302 // CNC:2002-07-24
303 #if HAVE_RPM
304       if (VF.end() == false)
305       {
306          pkgRecords Recs(Cache);
307          pkgRecords::Parser &P = Recs.Lookup(VF);
308          const char *Start;
309          const char *End;
310          P.GetRec(Start,End);
311          cout << string(Start,End-Start) << endl;
312       }
313    }
314    return !_error->PendingError();
315 #else
316       VFList[P->ID] = VF;
317    }
318 #endif
319    
320    LocalitySort(VFList,Count,sizeof(*VFList));
321
322    // Iterate over all the package files and write them out.
323    char *Buffer = new char[Cache.HeaderP->MaxVerFileSize+10];
324    for (pkgCache::VerFile **J = VFList; *J != 0;)
325    {
326       pkgCache::PkgFileIterator File(Cache,(*J)->File + Cache.PkgFileP);
327       if (File.IsOk() == false)
328       {
329          _error->Error(_("Package file %s is out of sync."),File.FileName());
330          break;
331       }
332
333       FileFd PkgF(File.FileName(),FileFd::ReadOnly);
334       if (_error->PendingError() == true)
335          break;
336       
337       /* Write all of the records from this package file, since we
338          already did locality sorting we can now just seek through the
339          file in read order. We apply 1 more optimization here, since often
340          there will be < 1 byte gaps between records (for the \n) we read that
341          into the next buffer and offset a bit.. */
342       unsigned long Pos = 0;
343       for (; *J != 0; J++)
344       {
345          if ((*J)->File + Cache.PkgFileP != File)
346             break;
347          
348          const pkgCache::VerFile &VF = **J;
349
350          // Read the record and then write it out again.
351          unsigned long Jitter = VF.Offset - Pos;
352          if (Jitter > 8)
353          {
354             if (PkgF.Seek(VF.Offset) == false)
355                break;
356             Jitter = 0;
357          }
358          
359          if (PkgF.Read(Buffer,VF.Size + Jitter) == false)
360             break;
361          Buffer[VF.Size + Jitter] = '\n';
362          
363          // See above..
364          if ((File->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource)
365          {
366             pkgTagSection Tags;
367             TFRewriteData RW[] = {{"Status",0,0},{"Config-Version",0,0},{0,0,0}};
368             const char *Zero = 0;
369             if (Tags.Scan(Buffer+Jitter,VF.Size+1) == false ||
370                 TFRewrite(stdout,Tags,&Zero,RW) == false)
371             {
372                _error->Error("Internal Error, Unable to parse a package record");
373                break;
374             }
375             fputc('\n',stdout);
376          }
377          else
378          {
379             if (fwrite(Buffer+Jitter,VF.Size+1,1,stdout) != 1)
380                break;
381          }
382          
383          Pos = VF.Offset + VF.Size;
384       }
385
386       fflush(stdout);
387       if (_error->PendingError() == true)
388          break;
389    }
390    
391    delete [] Buffer;
392    delete [] VFList;
393    return !_error->PendingError();
394 }
395                                                                         /*}}}*/
396 bool Depends(CommandLine &CmdL)
397 {
398    return cmdDepends(CmdL, *GCache);
399 }
400
401 bool RDepends(CommandLine &CmdL)
402 {
403    return cmdRDepends(CmdL, *GCache);
404 }
405
406 bool WhatDepends(CommandLine &CmdL)
407 {
408    return cmdWhatDepends(CmdL, *GCache);
409 }
410
411 bool WhatProvides(CommandLine &CmdL)
412 {
413    return cmdWhatProvides(CmdL, *GCache);
414 }
415
416 // xvcg - Generate a graph for xvcg                                     /*{{{*/
417 // ---------------------------------------------------------------------
418 // Code contributed from Junichi Uekawa <dancer@debian.org> on 20 June 2002.
419
420 bool XVcg(CommandLine &CmdL)
421 {
422    pkgCache &Cache = *GCache;
423    bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false);
424    
425    /* Normal packages are boxes
426       Pure Provides are triangles
427       Mixed are diamonds
428       rhomb are missing packages*/
429    const char *Shapes[] = {"ellipse","triangle","box","rhomb"};
430    
431    /* Initialize the list of packages to show.
432       1 = To Show
433       2 = To Show no recurse
434       3 = Emitted no recurse
435       4 = Emitted
436       0 = None */
437    enum States {None=0, ToShow, ToShowNR, DoneNR, Done};
438    enum TheFlags {ForceNR=(1<<0)};
439    unsigned char *Show = new unsigned char[Cache.Head().PackageCount];
440    unsigned char *Flags = new unsigned char[Cache.Head().PackageCount];
441    unsigned char *ShapeMap = new unsigned char[Cache.Head().PackageCount];
442    
443    // Show everything if no arguments given
444    if (CmdL.FileList[1] == 0)
445       for (unsigned long I = 0; I != Cache.Head().PackageCount; I++)
446          Show[I] = ToShow;
447    else
448       for (unsigned long I = 0; I != Cache.Head().PackageCount; I++)
449          Show[I] = None;
450    memset(Flags,0,sizeof(*Flags)*Cache.Head().PackageCount);
451    
452    // Map the shapes
453    for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
454    {   
455       if (Pkg->VersionList == 0)
456       {
457          // Missing
458          if (Pkg->ProvidesList == 0)
459             ShapeMap[Pkg->ID] = 0;
460          else
461             ShapeMap[Pkg->ID] = 1;
462       }
463       else
464       {
465          // Normal
466          if (Pkg->ProvidesList == 0)
467             ShapeMap[Pkg->ID] = 2;
468          else
469             ShapeMap[Pkg->ID] = 3;
470       }
471    }
472    
473    // Load the list of packages from the command line into the show list
474    for (const char **I = CmdL.FileList + 1; *I != 0; I++)
475    {
476       // Process per-package flags
477       string P = *I;
478       bool Force = false;
479       if (P.length() > 3)
480       {
481          if (P.end()[-1] == '^')
482          {
483             Force = true;
484             P.erase(P.end()-1);
485          }
486          
487          if (P.end()[-1] == ',')
488             P.erase(P.end()-1);
489       }
490       
491       // Locate the package
492       pkgCache::PkgIterator Pkg = Cache.FindPkg(P);
493       if (Pkg.end() == true)
494       {
495          _error->Warning(_("Unable to locate package %s"),*I);
496          continue;
497       }
498       Show[Pkg->ID] = ToShow;
499       
500       if (Force == true)
501          Flags[Pkg->ID] |= ForceNR;
502    }
503    
504    // Little header
505    cout << "graph: { title: \"packages\"" << endl <<
506      "xmax: 700 ymax: 700 x: 30 y: 30" << endl <<
507      "layout_downfactor: 8" << endl;
508
509    bool Act = true;
510    while (Act == true)
511    {
512       Act = false;
513       for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
514       {
515          // See we need to show this package
516          if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR)
517             continue;
518
519          //printf ("node: { title: \"%s\" label: \"%s\" }\n", Pkg.Name(), Pkg.Name());
520          
521          // Colour as done
522          if (Show[Pkg->ID] == ToShowNR || (Flags[Pkg->ID] & ForceNR) == ForceNR)
523          {
524             // Pure Provides and missing packages have no deps!
525             if (ShapeMap[Pkg->ID] == 0 || ShapeMap[Pkg->ID] == 1)
526                Show[Pkg->ID] = Done;
527             else
528                Show[Pkg->ID] = DoneNR;
529          }       
530          else
531             Show[Pkg->ID] = Done;
532          Act = true;
533
534          // No deps to map out
535          if (Pkg->VersionList == 0 || Show[Pkg->ID] == DoneNR)
536             continue;
537          
538          pkgCache::VerIterator Ver = Pkg.VersionList();
539          for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++)
540          {
541             // See if anything can meet this dep
542             // Walk along the actual package providing versions
543             bool Hit = false;
544             pkgCache::PkgIterator DPkg = D.TargetPkg();
545             for (pkgCache::VerIterator I = DPkg.VersionList();
546                       I.end() == false && Hit == false; I++)
547             {
548                if (Cache.VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true)
549                   Hit = true;
550             }
551             
552             // Follow all provides
553             for (pkgCache::PrvIterator I = DPkg.ProvidesList(); 
554                       I.end() == false && Hit == false; I++)
555             {
556                if (Cache.VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false)
557                   Hit = true;
558             }
559             
560
561             // Only graph critical deps     
562             if (D.IsCritical() == true)
563             {
564                printf ("edge: { sourcename: \"%s\" targetname: \"%s\" class: 2 ",Pkg.Name(), D.TargetPkg().Name() );
565                
566                // Colour the node for recursion
567                if (Show[D.TargetPkg()->ID] <= DoneNR)
568                {
569                   /* If a conflicts does not meet anything in the database
570                      then show the relation but do not recurse */
571                   if (Hit == false && 
572                       (D->Type == pkgCache::Dep::Conflicts ||
573                        D->Type == pkgCache::Dep::Obsoletes))
574                   {
575                      if (Show[D.TargetPkg()->ID] == None && 
576                          Show[D.TargetPkg()->ID] != ToShow)
577                         Show[D.TargetPkg()->ID] = ToShowNR;
578                   }               
579                   else
580                   {
581                      if (GivenOnly == true && Show[D.TargetPkg()->ID] != ToShow)
582                         Show[D.TargetPkg()->ID] = ToShowNR;
583                      else
584                         Show[D.TargetPkg()->ID] = ToShow;
585                   }
586                }
587                
588                // Edge colour
589                switch(D->Type)
590                {
591                   case pkgCache::Dep::Conflicts:
592                     printf("label: \"conflicts\" color: lightgreen }\n");
593                     break;
594                   case pkgCache::Dep::Obsoletes:
595                     printf("label: \"obsoletes\" color: lightgreen }\n");
596                     break;
597                   
598                   case pkgCache::Dep::PreDepends:
599                     printf("label: \"predepends\" color: blue }\n");
600                     break;
601                   
602                   default:
603                     printf("}\n");
604                   break;
605                }               
606             }       
607          }
608       }
609    }   
610    
611    /* Draw the box colours after the fact since we can not tell what colour
612       they should be until everything is finished drawing */
613    for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
614    {
615       if (Show[Pkg->ID] < DoneNR)
616          continue;
617
618       if (Show[Pkg->ID] == DoneNR)
619          printf("node: { title: \"%s\" label: \"%s\" color: orange shape: %s }\n", Pkg.Name(), Pkg.Name(),
620                 Shapes[ShapeMap[Pkg->ID]]);
621       else
622         printf("node: { title: \"%s\" label: \"%s\" shape: %s }\n", Pkg.Name(), Pkg.Name(), 
623                 Shapes[ShapeMap[Pkg->ID]]);
624       
625    }
626    
627    printf("}\n");
628    return true;
629 }
630                                                                         /*}}}*/
631
632
633 // Dotty - Generate a graph for Dotty                                   /*{{{*/
634 // ---------------------------------------------------------------------
635 /* Dotty is the graphvis program for generating graphs. It is a fairly
636    simple queuing algorithm that just writes dependencies and nodes. 
637    http://www.research.att.com/sw/tools/graphviz/ */
638 bool Dotty(CommandLine &CmdL)
639 {
640    pkgCache &Cache = *GCache;
641    bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false);
642    
643    /* Normal packages are boxes
644       Pure Provides are triangles
645       Mixed are diamonds
646       Hexagons are missing packages*/
647    const char *Shapes[] = {"hexagon","triangle","box","diamond"};
648    
649    /* Initialize the list of packages to show.
650       1 = To Show
651       2 = To Show no recurse
652       3 = Emitted no recurse
653       4 = Emitted
654       0 = None */
655    enum States {None=0, ToShow, ToShowNR, DoneNR, Done};
656    enum TheFlags {ForceNR=(1<<0)};
657    unsigned char *Show = new unsigned char[Cache.Head().PackageCount];
658    unsigned char *Flags = new unsigned char[Cache.Head().PackageCount];
659    unsigned char *ShapeMap = new unsigned char[Cache.Head().PackageCount];
660    
661    // Show everything if no arguments given
662    if (CmdL.FileList[1] == 0)
663       for (unsigned long I = 0; I != Cache.Head().PackageCount; I++)
664          Show[I] = ToShow;
665    else
666       for (unsigned long I = 0; I != Cache.Head().PackageCount; I++)
667          Show[I] = None;
668    memset(Flags,0,sizeof(*Flags)*Cache.Head().PackageCount);
669    
670    // Map the shapes
671    for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
672    {   
673       if (Pkg->VersionList == 0)
674       {
675          // Missing
676          if (Pkg->ProvidesList == 0)
677             ShapeMap[Pkg->ID] = 0;
678          else
679             ShapeMap[Pkg->ID] = 1;
680       }
681       else
682       {
683          // Normal
684          if (Pkg->ProvidesList == 0)
685             ShapeMap[Pkg->ID] = 2;
686          else
687             ShapeMap[Pkg->ID] = 3;
688       }
689    }
690    
691    // Load the list of packages from the command line into the show list
692    for (const char **I = CmdL.FileList + 1; *I != 0; I++)
693    {
694       // Process per-package flags
695       string P = *I;
696       bool Force = false;
697       if (P.length() > 3)
698       {
699          if (P.end()[-1] == '^')
700          {
701             Force = true;
702             P.erase(P.end()-1);
703          }
704          
705          if (P.end()[-1] == ',')
706             P.erase(P.end()-1);
707       }
708       
709       // Locate the package
710       pkgCache::PkgIterator Pkg = Cache.FindPkg(P);
711       if (Pkg.end() == true)
712       {
713          _error->Warning(_("Unable to locate package %s"),*I);
714          continue;
715       }
716       Show[Pkg->ID] = ToShow;
717       
718       if (Force == true)
719          Flags[Pkg->ID] |= ForceNR;
720    }
721    
722    // Little header
723    printf("digraph packages {\n");
724    printf("concentrate=true;\n");
725    printf("size=\"30,40\";\n");
726    
727    bool Act = true;
728    while (Act == true)
729    {
730       Act = false;
731       for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
732       {
733          // See we need to show this package
734          if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR)
735             continue;
736          
737          // Colour as done
738          if (Show[Pkg->ID] == ToShowNR || (Flags[Pkg->ID] & ForceNR) == ForceNR)
739          {
740             // Pure Provides and missing packages have no deps!
741             if (ShapeMap[Pkg->ID] == 0 || ShapeMap[Pkg->ID] == 1)
742                Show[Pkg->ID] = Done;
743             else
744                Show[Pkg->ID] = DoneNR;
745          }       
746          else
747             Show[Pkg->ID] = Done;
748          Act = true;
749
750          // No deps to map out
751          if (Pkg->VersionList == 0 || Show[Pkg->ID] == DoneNR)
752             continue;
753          
754          pkgCache::VerIterator Ver = Pkg.VersionList();
755          for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++)
756          {
757             // See if anything can meet this dep
758             // Walk along the actual package providing versions
759             bool Hit = false;
760             pkgCache::PkgIterator DPkg = D.TargetPkg();
761             for (pkgCache::VerIterator I = DPkg.VersionList();
762                       I.end() == false && Hit == false; I++)
763             {
764                if (Cache.VS->CheckDep(I.VerStr(),D->CompareOp,D.TargetVer()) == true)
765                   Hit = true;
766             }
767             
768             // Follow all provides
769             for (pkgCache::PrvIterator I = DPkg.ProvidesList(); 
770                       I.end() == false && Hit == false; I++)
771             {
772                if (Cache.VS->CheckDep(I.ProvideVersion(),D->CompareOp,D.TargetVer()) == false)
773                   Hit = true;
774             }
775             
776             // Only graph critical deps     
777             if (D.IsCritical() == true)
778             {
779                printf("\"%s\" -> \"%s\"",Pkg.Name(),D.TargetPkg().Name());
780                
781                // Colour the node for recursion
782                if (Show[D.TargetPkg()->ID] <= DoneNR)
783                {
784                   /* If a conflicts does not meet anything in the database
785                      then show the relation but do not recurse */
786                   if (Hit == false && 
787                       (D->Type == pkgCache::Dep::Conflicts ||
788                        D->Type == pkgCache::Dep::Obsoletes))
789                   {
790                      if (Show[D.TargetPkg()->ID] == None && 
791                          Show[D.TargetPkg()->ID] != ToShow)
792                         Show[D.TargetPkg()->ID] = ToShowNR;
793                   }               
794                   else
795                   {
796                      if (GivenOnly == true && Show[D.TargetPkg()->ID] != ToShow)
797                         Show[D.TargetPkg()->ID] = ToShowNR;
798                      else
799                         Show[D.TargetPkg()->ID] = ToShow;
800                   }
801                }
802                
803                // Edge colour
804                switch(D->Type)
805                {
806                   case pkgCache::Dep::Conflicts:
807                   case pkgCache::Dep::Obsoletes:
808                   printf("[color=springgreen];\n");
809                   break;
810                   
811                   case pkgCache::Dep::PreDepends:
812                   printf("[color=blue];\n");
813                   break;
814                   
815                   default:
816                   printf(";\n");
817                   break;
818                }               
819             }       
820          }
821       }
822    }   
823    
824    /* Draw the box colours after the fact since we can not tell what colour
825       they should be until everything is finished drawing */
826    for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
827    {
828       if (Show[Pkg->ID] < DoneNR)
829          continue;
830       
831       // Orange box for early recursion stoppage
832       if (Show[Pkg->ID] == DoneNR)
833          printf("\"%s\" [color=orange,shape=%s];\n",Pkg.Name(),
834                 Shapes[ShapeMap[Pkg->ID]]);
835       else
836          printf("\"%s\" [shape=%s];\n",Pkg.Name(),
837                 Shapes[ShapeMap[Pkg->ID]]);
838    }
839    
840    printf("}\n");
841    return true;
842 }
843                                                                         /*}}}*/
844 // DoAdd - Perform an adding operation                                  /*{{{*/
845 // ---------------------------------------------------------------------
846 /* */
847 bool DoAdd(CommandLine &CmdL)
848 {
849    return _error->Error("Unimplemented");
850 #if 0   
851    // Make sure there is at least one argument
852    if (CmdL.FileSize() <= 1)
853       return _error->Error("You must give at least one file name");
854    
855    // Open the cache
856    FileFd CacheF(_config->FindFile("Dir::Cache::pkgcache"),FileFd::WriteAny);
857    if (_error->PendingError() == true)
858       return false;
859    
860    DynamicMMap Map(CacheF,MMap::Public);
861    if (_error->PendingError() == true)
862       return false;
863
864    OpTextProgress Progress(*_config);
865    pkgCacheGenerator Gen(Map,Progress);
866    if (_error->PendingError() == true)
867       return false;
868
869    unsigned long Length = CmdL.FileSize() - 1;
870    for (const char **I = CmdL.FileList + 1; *I != 0; I++)
871    {
872       Progress.OverallProgress(I - CmdL.FileList,Length,1,"Generating cache");
873       Progress.SubProgress(Length);
874
875       // Do the merge
876       FileFd TagF(*I,FileFd::ReadOnly);
877       debListParser Parser(TagF);
878       if (_error->PendingError() == true)
879          return _error->Error("Problem opening %s",*I);
880       
881       if (Gen.SelectFile(*I,"") == false)
882          return _error->Error("Problem with SelectFile");
883          
884       if (Gen.MergeList(Parser) == false)
885          return _error->Error("Problem with MergeList");
886    }
887
888    Progress.Done();
889    GCache = &Gen.GetCache();
890    Stats(CmdL);
891    
892    return true;
893 #endif   
894 }
895                                                                         /*}}}*/
896 // DisplayRecord - Displays the complete record for the package         /*{{{*/
897 // ---------------------------------------------------------------------
898 /* This displays the package record from the proper package index file. 
899    It is not used by DumpAvail for performance reasons. */
900 bool DisplayRecord(pkgCache::VerIterator V)
901 {
902    return cmdDisplayRecord(V, *GCache);
903 }
904                                                                         /*}}}*/
905 // Search - Perform a search                                            /*{{{*/
906 // ---------------------------------------------------------------------
907 /* This searches the package names and pacakge descriptions for a pattern */
908 bool Search(CommandLine &CmdL)
909 {
910    return cmdSearch(CmdL, *GCache);
911 }
912                                                                         /*}}}*/
913 bool SearchFile(CommandLine &CmdL)
914 {
915    return cmdSearchFile(CmdL, *GCache);
916 }
917
918 // ShowPackage - Dump the package record to the screen                  /*{{{*/
919 // ---------------------------------------------------------------------
920 /* */
921 bool ShowPackage(CommandLine &CmdL)
922 {   
923    return cmdShowPackage(CmdL, *GCache);
924 }
925
926 bool FileList(CommandLine &CmdL)
927 {
928    return cmdFileList(CmdL, *GCache);
929 }
930                                                                         /*}}}*/
931 bool ChangeLog(CommandLine &CmdL)
932 {
933    return cmdChangeLog(CmdL, *GCache);
934 }
935
936 // ShowPkgNames - Show package names                                    /*{{{*/
937 // ---------------------------------------------------------------------
938 /* This does a prefix match on the first argument */
939 bool ShowPkgNames(CommandLine &CmdL)
940 {
941    pkgCache &Cache = *GCache;
942    pkgCache::PkgIterator I = Cache.PkgBegin();
943    bool All = _config->FindB("APT::Cache::AllNames", false);
944    
945    if (CmdL.FileList[1] != 0)
946    {
947       for (;I.end() != true; I++)
948       {
949          if (All == false && I->VersionList == 0)
950             continue;
951          
952          if (strncmp(I.Name(),CmdL.FileList[1],strlen(CmdL.FileList[1])) == 0)
953             cout << I.Name() << endl;
954       }
955
956       return true;
957    }
958    
959    // Show all pkgs
960    for (;I.end() != true; I++)
961    {
962       if (All == false && I->VersionList == 0)
963          continue;
964       cout << I.Name() << endl;
965    }
966    
967    return true;
968 }
969                                                                         /*}}}*/
970 // ShowSrcPackage - Show source package records                         /*{{{*/
971 // ---------------------------------------------------------------------
972 /* */
973 bool ShowSrcPackage(CommandLine &CmdL)
974 {
975    pkgSourceList List;
976    List.ReadMainList();
977    
978    // Create the text record parsers
979    pkgSrcRecords SrcRecs(List);
980    if (_error->PendingError() == true)
981       return false;
982
983    for (const char **I = CmdL.FileList + 1; *I != 0; I++)
984    {
985       SrcRecs.Restart();
986       
987       pkgSrcRecords::Parser *Parse;
988       while ((Parse = SrcRecs.Find(*I,false)) != 0)
989          cout << Parse->AsStr() << endl;;
990    }      
991    return true;
992 }
993                                                                         /*}}}*/
994 // Policy - Show the results of the preferences file                    /*{{{*/
995 // ---------------------------------------------------------------------
996 /* */
997 bool Policy(CommandLine &CmdL)
998 {
999    if (SrcList == 0)
1000       return _error->Error("Generate must be enabled for this function");
1001    
1002    pkgCache &Cache = *GCache;
1003    pkgPolicy Plcy(&Cache);
1004    if (ReadPinFile(Plcy) == false)
1005       return false;
1006    
1007    // Print out all of the package files
1008    if (CmdL.FileList[1] == 0)
1009    {
1010       cout << _("Package Files:") << endl;   
1011       for (pkgCache::PkgFileIterator F = Cache.FileBegin(); F.end() == false; F++)
1012       {
1013          // Locate the associated index files so we can derive a description
1014          pkgIndexFile *Indx;
1015          if (SrcList->FindIndex(F,Indx) == false &&
1016              _system->FindIndex(F,Indx) == false)
1017             return _error->Error(_("Cache is out of sync, can't x-ref a package file"));
1018          printf(_("%4i %s\n"),
1019                 Plcy.GetPriority(F),Indx->Describe(true).c_str());
1020          
1021          // Print the reference information for the package
1022          string Str = F.RelStr();
1023          if (Str.empty() == false)
1024             printf("     release %s\n",F.RelStr().c_str());
1025          if (F.Site() != 0 && F.Site()[0] != 0)
1026             printf("     origin %s\n",F.Site());
1027       }
1028       
1029       // Show any packages have explicit pins
1030       cout << _("Pinned Packages:") << endl;
1031       pkgCache::PkgIterator I = Cache.PkgBegin();
1032       for (;I.end() != true; I++)
1033       {
1034          if (Plcy.GetPriority(I) == 0)
1035             continue;
1036
1037          // Print the package name and the version we are forcing to
1038          cout << "     " << I.Name() << " -> ";
1039          
1040          pkgCache::VerIterator V = Plcy.GetMatch(I);
1041          if (V.end() == true)
1042             cout << _("(not found)") << endl;
1043          else
1044             cout << V.VerStr() << endl;
1045       }     
1046       
1047       return true;
1048    }
1049    
1050    // Print out detailed information for each package
1051    for (const char **I = CmdL.FileList + 1; *I != 0; I++)
1052    {
1053       pkgCache::PkgIterator Pkg = Cache.FindPkg(*I);
1054       if (Pkg.end() == true)
1055       {
1056          _error->Warning(_("Unable to locate package %s"),*I);
1057          continue;
1058       }
1059       
1060       cout << Pkg.Name() << ":" << endl;
1061       
1062       // Installed version
1063       cout << _("  Installed: ");
1064       if (Pkg->CurrentVer == 0)
1065          cout << _("(none)") << endl;
1066       else
1067          cout << Pkg.CurrentVer().VerStr() << endl;
1068       
1069       // Candidate Version 
1070       cout << _("  Candidate: ");
1071       pkgCache::VerIterator V = Plcy.GetCandidateVer(Pkg);
1072       if (V.end() == true)
1073          cout << _("(none)") << endl;
1074       else
1075          cout << V.VerStr() << endl;
1076
1077       // Pinned version
1078       if (Plcy.GetPriority(Pkg) != 0)
1079       {
1080          cout << _("  Package Pin: ");
1081          V = Plcy.GetMatch(Pkg);
1082          if (V.end() == true)
1083             cout << _("(not found)") << endl;
1084          else
1085             cout << V.VerStr() << endl;
1086       }
1087       
1088       // Show the priority tables
1089       cout << _("  Version Table:") << endl;
1090       for (V = Pkg.VersionList(); V.end() == false; V++)
1091       {
1092          if (Pkg.CurrentVer() == V)
1093             cout << " *** " << V.VerStr();
1094          else
1095             cout << "     " << V.VerStr();
1096          // CNC:2004-05-29
1097          if (Plcy.GetCandidateVer(Pkg) == V)
1098             cout << " " << Plcy.GetPriority(Pkg) << endl;
1099          else
1100             cout << " 0" << endl;
1101          for (pkgCache::VerFileIterator VF = V.FileList(); VF.end() == false; VF++)
1102          {
1103             // Locate the associated index files so we can derive a description
1104             pkgIndexFile *Indx;
1105             if (SrcList->FindIndex(VF.File(),Indx) == false &&
1106                 _system->FindIndex(VF.File(),Indx) == false)
1107                return _error->Error(_("Cache is out of sync, can't x-ref a package file"));
1108             printf(_("       %4i %s\n"),Plcy.GetPriority(VF.File()),
1109                    Indx->Describe(true).c_str());
1110          }       
1111       }      
1112    }
1113    
1114    return true;
1115 }
1116                                                                         /*}}}*/
1117 // GenCaches - Call the main cache generator                            /*{{{*/
1118 // ---------------------------------------------------------------------
1119 /* */
1120 bool GenCaches(CommandLine &Cmd)
1121 {
1122    OpTextProgress Progress(*_config);
1123    
1124    pkgSourceList List;
1125    if (List.ReadMainList() == false)
1126       return false;   
1127    return pkgMakeStatusCache(List,Progress);
1128 }
1129
1130                                                                         /*}}}*/
1131 // ShowHelp - Show a help screen                                        /*{{{*/
1132 // ---------------------------------------------------------------------
1133 /* */
1134 bool ShowHelp(CommandLine &Cmd)
1135 {
1136    ioprintf(cout,_("%s %s for %s %s compiled on %s %s\n"),PACKAGE,VERSION,
1137             COMMON_OS,COMMON_CPU,__DATE__,__TIME__);
1138    
1139    if (_config->FindB("version") == true)
1140      return true;
1141
1142    cout << 
1143     _("Usage: apt-cache [options] command\n"
1144       "       apt-cache [options] add file1 [file2 ...]\n"
1145       "       apt-cache [options] showpkg pkg1 [pkg2 ...]\n"
1146       "       apt-cache [options] showsrc pkg1 [pkg2 ...]\n"
1147       "\n"
1148       "apt-cache is a low-level tool used to manipulate APT's binary\n"
1149       "cache files, and query information from them\n"
1150       "\n"
1151       "Commands:\n"
1152       "   add - Add a package file to the source cache\n"
1153       "   gencaches - Build both the package and source cache\n"
1154       "   showpkg - Show some general information for a single package\n"
1155       "   showsrc - Show source records\n"
1156       "   stats - Show some basic statistics\n"
1157       "   dump - Show the entire file in a terse form\n"
1158       "   dumpavail - Print an available file to stdout\n"
1159       "   unmet - Show unmet dependencies\n"
1160       "   search - Search the package list for a regex pattern\n"
1161       "   searchfile - Search the packages for a file\n"
1162       "   files - Show file list of the package(s)\n"
1163       "   changelog - Show changelog entries of the package(s)\n"
1164       "   show - Show a readable record for the package\n"
1165       "   depends - Show raw dependency information for a package\n"
1166       "   whatdepends - Show packages depending on given capabilities\n"
1167       // "   rdepends - Show reverse dependency information for a package\n"
1168       "   whatprovides - Show packages that provide given capabilities\n"
1169       "   pkgnames - List the names of all packages\n"
1170       "   dotty - Generate package graphs for GraphVis\n"
1171       "   xvcg - Generate package graphs for xvcg\n"
1172       "   policy - Show policy settings\n"
1173 // CNC:2003-03-16
1174       );
1175 #ifdef APT_WITH_LUA
1176       _lua->RunScripts("Scripts::AptCache::Help::Command");
1177 #endif
1178       cout << _(
1179       "\n"
1180       "Options:\n"
1181       "  -h   This help text.\n"
1182       "  -p=? The package cache.\n"
1183       "  -s=? The source cache.\n"
1184       "  -q   Disable progress indicator.\n"
1185       "  -i   Show only important deps for the unmet command.\n"
1186       "  -c=? Read this configuration file\n"
1187       "  -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp\n"
1188       "See the apt-cache(8) and apt.conf(5) manual pages for more information.\n");
1189    return true;
1190 }
1191                                                                         /*}}}*/
1192 // CacheInitialize - Initialize things for apt-cache                    /*{{{*/
1193 // ---------------------------------------------------------------------
1194 /* */
1195 void CacheInitialize()
1196 {
1197    _config->Set("quiet",0);
1198    _config->Set("help",false);
1199 }
1200                                                                         /*}}}*/
1201
1202 int main(int argc,const char *argv[])
1203 {
1204    CommandLine::Args Args[] = {
1205       {'h',"help","help",0},
1206       {'v',"version","version",0},
1207       {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg},
1208       {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg},
1209       {'q',"quiet","quiet",CommandLine::IntLevel},
1210       {'i',"important","APT::Cache::Important",0},
1211       {'f',"full","APT::Cache::ShowFull",0},
1212       {'g',"generate","APT::Cache::Generate",0},
1213       {'a',"all-versions","APT::Cache::AllVersions",0},
1214       {0,"names-only","APT::Cache::NamesOnly",0},
1215       {'n',"all-names","APT::Cache::AllNames",0},
1216       {0,"recurse","APT::Cache::RecurseDepends",0},
1217       {'c',"config-file",0,CommandLine::ConfigFile},
1218       {'o',"option",0,CommandLine::ArbItem},
1219       {'n',"installed","APT::Cache::Installed",0},
1220       {0,0,0,0}};
1221    CommandLine::Dispatch CmdsA[] = {{"help",&ShowHelp},
1222                                     {"add",&DoAdd},
1223                                     {"gencaches",&GenCaches},
1224                                     {"showsrc",&ShowSrcPackage},
1225                                     {0,0}};
1226    CommandLine::Dispatch CmdsB[] = {{"showpkg",&DumpPackage},
1227                                     {"stats",&Stats},
1228                                     {"dump",&Dump},
1229                                     {"dumpavail",&DumpAvail},
1230                                     {"unmet",&UnMet},
1231                                     {"search",&Search},
1232                                     {"searchfile",&SearchFile},
1233                                     {"depends",&Depends},
1234                                     {"whatdepends",&WhatDepends},
1235                                     {"rdepends",&RDepends},
1236                                     {"whatprovides",&WhatProvides},
1237                                     {"files",&FileList},
1238                                     {"changelog",&ChangeLog},
1239                                     {"dotty",&Dotty},
1240                                     {"xvcg",&XVcg},
1241                                     {"show",&ShowPackage},
1242                                     {"pkgnames",&ShowPkgNames},
1243                                     {"policy",&Policy},
1244 // CNC:2003-11-23
1245 #ifdef APT_WITH_LUA
1246                                     {"script",&Script},
1247 #endif
1248                                     {0,0}};
1249
1250    CacheInitialize();
1251
1252    // Set up gettext support
1253    setlocale(LC_ALL,"");
1254    textdomain(PACKAGE);
1255
1256    // Parse the command line and initialize the package library
1257    CommandLine CmdL(Args,_config);
1258    if (pkgInitConfig(*_config) == false ||
1259        CmdL.Parse(argc,argv) == false ||
1260        pkgInitSystem(*_config,_system) == false)
1261    {
1262       _error->DumpErrors();
1263       return 100;
1264    }
1265
1266    // See if the help should be shown
1267    if (_config->FindB("help") == true ||
1268        CmdL.FileSize() == 0)
1269    {
1270       ShowHelp(CmdL);
1271       return 0;
1272    }
1273    
1274    // Deal with stdout not being a tty
1275    if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1)
1276       _config->Set("quiet","1");
1277
1278    // CNC:2004-02-18
1279    if (_system->LockRead() == false)
1280    {
1281       bool Errors = _error->PendingError();
1282       _error->DumpErrors();
1283       return Errors == true?100:0;
1284    }
1285
1286    if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false)
1287    { 
1288       MMap *Map = 0;
1289       if (_config->FindB("APT::Cache::Generate",true) == false)
1290       {
1291          Map = new MMap(*new FileFd(_config->FindFile("Dir::Cache::pkgcache"),
1292                                     FileFd::ReadOnly),MMap::Public|MMap::ReadOnly);
1293       }
1294       else
1295       {
1296          // Open the cache file
1297          SrcList = new pkgSourceList;
1298          SrcList->ReadMainList();
1299
1300          // Generate it and map it
1301          OpProgress Prog;
1302          pkgMakeStatusCache(*SrcList,Prog,&Map,true);
1303       }
1304       
1305       if (_error->PendingError() == false)
1306       {
1307          pkgCache Cache(Map);   
1308          GCache = &Cache;
1309 // CNC:2003-11-23
1310 #ifdef APT_WITH_LUA
1311          _lua->SetCache(&Cache);
1312          double Consume = 0;
1313          if (argc > 1 && _error->PendingError() == false &&
1314              _lua->HasScripts("Scripts::AptCache::Command") == true)
1315          {
1316             _lua->SetGlobal("command_args", CmdL.FileList);
1317             _lua->SetGlobal("command_consume", 0.0);
1318             _lua->RunScripts("Scripts::AptCache::Command");
1319             Consume = _lua->GetGlobalNum("command_consume");
1320             _lua->ResetGlobals();
1321             _lua->ResetCaches();
1322          }
1323
1324          if (Consume == 0)
1325 #endif
1326          if (_error->PendingError() == false)
1327             CmdL.DispatchArg(CmdsB);
1328       }
1329       delete Map;
1330    }
1331    
1332    // Print any errors or warnings found during parsing
1333    if (_error->empty() == false)
1334    {
1335       bool Errors = _error->PendingError();
1336       _error->DumpErrors();
1337       return Errors == true?100:0;
1338    }
1339           
1340    return 0;
1341 }
1342
1343 // vim:sts=3:sw=3