~mvo/apt/dep8

« back to all changes in this revision

Viewing changes to cmdline/apt-cache.cc

  • Committer: Arch Librarian
  • Date: 2004-09-20 16:50:50 UTC
  • Revision ID: Arch-1:apt@arch.ubuntu.com%apt--MAIN--0--patch-19
Compile of apt-cache
Author: jgg
Date: 1998-07-15 05:56:42 GMT
Compile of apt-cache

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- mode: cpp; mode: fold -*-
 
2
// Description                                                          /*{{{*/
 
3
// $Id: apt-cache.cc,v 1.1 1998/07/15 05:56:47 jgg Exp $
 
4
/* ######################################################################
 
5
   
 
6
   apt-cache - Manages the cache file.
 
7
   
 
8
   This program should eventually handle both low and high level
 
9
   manipulation of the cache file. Depending how far things go it 
 
10
   might get quite a sophisticated UI.
 
11
   
 
12
   Currently the command line is as follows:
 
13
      apt-cache add cache file1:dist:ver file2:dist:ver ...
 
14
    ie:
 
15
      apt-cache add ./cache Pacakges:hamm:1.0
 
16
 
 
17
   A usefull feature is 'upgradable' ie
 
18
      apt-cache upgradable ./cache
 
19
   will list .debs that should be installed to make all packages the latest
 
20
   version.
 
21
   
 
22
   Returns 100 on failure, 0 on success.
 
23
   
 
24
   ##################################################################### */
 
25
                                                                        /*}}}*/
 
26
// Include Files                                                        /*{{{*/
 
27
#include <apt-pkg/error.h>
 
28
#include <apt-pkg/pkgcachegen.h>
 
29
#include <apt-pkg/deblistparser.h>
 
30
 
 
31
#include <iostream.h>
 
32
#include <fstream.h>
 
33
 
 
34
                                                                        /*}}}*/
 
35
 
 
36
string CacheFile;
 
37
 
 
38
// SplitArg - Split the triple                                          /*{{{*/
 
39
// ---------------------------------------------------------------------
 
40
/* */
 
41
bool SplitArg(const char *Arg,string &File,string &Dist,string Ver)
 
42
{
 
43
   const char *Start = Arg;
 
44
   const char *I = Arg;
 
45
   for (;*I != 0 && *I != ':'; I++);
 
46
   if (*I != ':')
 
47
      return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
 
48
   File = string(Start,I - Start);
 
49
 
 
50
   I++;
 
51
   Start = I;
 
52
   for (;*I != 0 && *I != ':'; I++);
 
53
   if (*I != ':')
 
54
      return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
 
55
   Dist = string(Start,I - Start);
 
56
   
 
57
   I++;
 
58
   Start = I;
 
59
   for (;*I != 0 && *I != ':'; I++);
 
60
   if (I == Start)
 
61
      return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg);
 
62
   Ver = string(Start,I - Start);
 
63
 
 
64
   return true;
 
65
}
 
66
                                                                        /*}}}*/
 
67
// DoAdd - Perform an adding operation                                  /*{{{*/
 
68
// ---------------------------------------------------------------------
 
69
/* */
 
70
bool DoAdd(int argc,char *argv[])
 
71
{
 
72
   string FileName;
 
73
   string Dist;
 
74
   string Ver;
 
75
   
 
76
   File CacheF(CacheFile,File::WriteEmpty);
 
77
   if (_error->PendingError() == true)
 
78
      return false;
 
79
   
 
80
   DynamicMMap Map(CacheF,MMap::Public);
 
81
   if (_error->PendingError() == true)
 
82
      return false;
 
83
   
 
84
   pkgCacheGenerator Gen(Map);
 
85
   if (_error->PendingError() == true)
 
86
      return false;
 
87
 
 
88
   for (int I = 0; I != argc; I++)
 
89
   {
 
90
      if (SplitArg(argv[I],FileName,Dist,Ver) == false)
 
91
         return false;
 
92
      
 
93
      // Do the merge
 
94
      File TagF(FileName.c_str(),File::ReadOnly);
 
95
      debListParser Parser(TagF);
 
96
      if (_error->PendingError() == true)
 
97
         return false;
 
98
      if (Gen.SelectFile(FileName) == false)
 
99
         return false;
 
100
         
 
101
      if (Gen.MergeList(Parser) == false)
 
102
         return false;
 
103
   }
 
104
   
 
105
   return true;
 
106
}
 
107
                                                                        /*}}}*/
 
108
// DumpPackage - Show a dump of a package record                        /*{{{*/
 
109
// ---------------------------------------------------------------------
 
110
/* */
 
111
bool DumpPackage(int argc,char *argv[])
 
112
{
 
113
   File CacheF(CacheFile,File::ReadOnly);
 
114
   if (_error->PendingError() == true)
 
115
      return false;
 
116
   
 
117
   MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
 
118
   if (_error->PendingError() == true)
 
119
      return false;
 
120
   
 
121
   pkgCache Cache(Map);   
 
122
   if (_error->PendingError() == true)
 
123
      return false;
 
124
   
 
125
   for (int I = 0; I != argc; I++)
 
126
   {
 
127
      pkgCache::PkgIterator Pkg = Cache.FindPkg(argv[I]);
 
128
      if (Pkg.end() == true)
 
129
      {
 
130
         _error->Warning("Unable to locate package %s",argv[0]);
 
131
         continue;
 
132
      }
 
133
 
 
134
      cout << "Package: " << Pkg.Name() << endl;
 
135
      cout << "Versions: ";
 
136
      for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
 
137
         cout << Cur.VerStr() << ',';
 
138
      cout << endl;
 
139
      
 
140
      cout << "Reverse Depends: " << endl;
 
141
      for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; D++)
 
142
         cout << "  " << D.ParentPkg().Name() << ',' << D.TargetPkg().Name() << endl;
 
143
 
 
144
      cout << "Dependencies: " << endl;
 
145
      for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
 
146
      {
 
147
         cout << Cur.VerStr() << " - ";
 
148
         for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; Dep++)
 
149
            cout << Dep.TargetPkg().Name() << " (" << (int)Dep->CompareOp << " " << Dep.TargetVer() << ") ";
 
150
         cout << endl;
 
151
      }      
 
152
 
 
153
      cout << "Provides: " << endl;
 
154
      for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++)
 
155
      {
 
156
         cout << Cur.VerStr() << " - ";
 
157
         for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; Prv++)
 
158
            cout << Prv.ParentPkg().Name() << " ";
 
159
         cout << endl;
 
160
      }      
 
161
   }
 
162
 
 
163
   return true;
 
164
}
 
165
                                                                        /*}}}*/
 
166
// Stats - Dump some nice statistics                                    /*{{{*/
 
167
// ---------------------------------------------------------------------
 
168
/* */
 
169
bool Stats(const char *FileName)
 
170
{
 
171
   File CacheF(FileName,File::ReadOnly);
 
172
   if (_error->PendingError() == true)
 
173
      return false;
 
174
   
 
175
   MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
 
176
   if (_error->PendingError() == true)
 
177
      return false;
 
178
   
 
179
   pkgCache Cache(Map);   
 
180
   if (_error->PendingError() == true)
 
181
      return false;
 
182
       
 
183
   cout << "Total Package Names : " << Cache.Head().PackageCount << endl;
 
184
   pkgCache::PkgIterator I = Cache.PkgBegin();
 
185
   
 
186
   int Normal = 0;
 
187
   int Virtual = 0;
 
188
   int NVirt = 0;
 
189
   int DVirt = 0;
 
190
   int Missing = 0;
 
191
   for (;I.end() != true; I++)
 
192
   {
 
193
      if (I->VersionList != 0 && I->ProvidesList == 0)
 
194
      {
 
195
         Normal++;
 
196
         continue;
 
197
      }
 
198
 
 
199
      if (I->VersionList != 0 && I->ProvidesList != 0)
 
200
      {
 
201
         NVirt++;
 
202
         continue;
 
203
      }
 
204
      
 
205
      if (I->VersionList == 0 && I->ProvidesList != 0)
 
206
      {
 
207
         // Only 1 provides
 
208
         if (I.ProvidesList()->NextProvides == 0)
 
209
         {
 
210
            DVirt++;
 
211
         }
 
212
         else
 
213
            Virtual++;
 
214
         continue;
 
215
      }
 
216
      if (I->VersionList == 0 && I->ProvidesList == 0)
 
217
      {
 
218
         Missing++;
 
219
         continue;
 
220
      }
 
221
   }
 
222
   cout << "  Normal Packages: " << Normal << endl;
 
223
   cout << "  Pure Virtual Packages: " << Virtual << endl;
 
224
   cout << "  Single Virtual Packages: " << DVirt << endl;
 
225
   cout << "  Mixed Virtual Packages: " << NVirt << endl;
 
226
   cout << "  Missing: " << Missing << endl;
 
227
   
 
228
   cout << "Total Distinct Versions: " << Cache.Head().VersionCount << endl;
 
229
   cout << "Total Dependencies: " << Cache.Head().DependsCount << endl;
 
230
   return true;
 
231
}
 
232
                                                                        /*}}}*/
 
233
// Dump - show everything                                               /*{{{*/
 
234
// ---------------------------------------------------------------------
 
235
/* */
 
236
bool Dump()
 
237
{
 
238
   File CacheF(CacheFile,File::ReadOnly);
 
239
   if (_error->PendingError() == true)
 
240
      return false;
 
241
   
 
242
   MMap Map(CacheF,MMap::Public | MMap::ReadOnly);
 
243
   if (_error->PendingError() == true)
 
244
      return false;
 
245
   
 
246
   pkgCache Cache(Map);   
 
247
   if (_error->PendingError() == true)
 
248
      return false;
 
249
 
 
250
   for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
 
251
   {
 
252
      cout << "Package: " << P.Name() << endl;
 
253
      for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++)
 
254
      {
 
255
         cout << " Version: " << V.VerStr() << endl;
 
256
         cout << "     File: " << V.FileList().File().FileName() << endl;
 
257
         for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++)
 
258
            cout << "  Depends: " << D.TargetPkg().Name() << ' ' << D.TargetVer() << endl;
 
259
      }      
 
260
   }
 
261
 
 
262
   for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++)
 
263
   {
 
264
      cout << "File: " << F.FileName() << endl;
 
265
      cout << " Size: " << F->Size << endl;
 
266
      cout << " ID: " << F->ID << endl;
 
267
      cout << " Flags: " << F->Flags << endl;
 
268
      cout << " Time: " << ctime(&F->mtime) << endl;
 
269
   }
 
270
 
 
271
   return true;
 
272
}
 
273
                                                                        /*}}}*/
 
274
// DumpAvail - Print out the available list                             /*{{{*/
 
275
// ---------------------------------------------------------------------
 
276
/* This is needed to make dpkg --merge happy */
 
277
bool DumpAvail()
 
278
{
 
279
#if 0
 
280
   pkgCache Cache(CacheFile,true,true);
 
281
   if (_error->PendingError() == true)
 
282
      return false;
 
283
 
 
284
   pkgControlCache CCache(Cache);
 
285
   if (_error->PendingError() == true)
 
286
      return false;
 
287
 
 
288
   vector<string> Lines;
 
289
   Lines.reserve(30);
 
290
   
 
291
   pkgCache::PkgIterator I = Cache.PkgBegin();
 
292
   for (;I.end() != true; I++)
 
293
   {
 
294
      if (I->VersionList == 0)
 
295
         continue;
 
296
      
 
297
      pkgSPkgCtrlInfo Inf = CCache[I.VersionList()];
 
298
      if (Inf.isNull() == true)
 
299
         return _error->Error("Couldn't locate info record");
 
300
      
 
301
      // Iterate over each element
 
302
      pkgPkgCtrlInfo::const_iterator Elm = Inf->begin();
 
303
      for (; Elm != Inf->end(); Elm++)
 
304
      {
 
305
         // Write the tag: value
 
306
         cout << (*Elm)->Tag() << ": " << (*Elm)->Value() << endl;
 
307
         
 
308
         // Write the multiline
 
309
         (*Elm)->GetLines(Lines);
 
310
         for (vector<string>::iterator j = Lines.begin(); j != Lines.end(); j++)
 
311
         {
 
312
            if ((*j).length() == 0)
 
313
               cout << " ." << endl;
 
314
            else
 
315
               cout << " " << *j << endl;
 
316
         }
 
317
         
 
318
         Lines.erase(Lines.begin(),Lines.end());
 
319
      }
 
320
      
 
321
      cout << endl;
 
322
   }
 
323
#endif
 
324
   return true;
 
325
}
 
326
                                                                        /*}}}*/
 
327
 
 
328
int main(int argc, char *argv[])
 
329
{
 
330
   // Check arguments.
 
331
   if (argc < 3)
 
332
   {
 
333
      cerr << "Usage is apt-cache add cache file1:dist:ver file2:dist:ver ..." << endl;
 
334
      return 100;
 
335
   }
 
336
   
 
337
   while (1)
 
338
   {
 
339
      if (strcmp(argv[1],"add") == 0)
 
340
      {
 
341
         CacheFile = argv[2];
 
342
         if (DoAdd(argc - 3,argv + 3) == true) 
 
343
            Stats(argv[2]);
 
344
         break;
 
345
      }
 
346
    
 
347
      if (strcmp(argv[1],"showpkg") == 0)
 
348
      {
 
349
         CacheFile = argv[2];
 
350
         DumpPackage(argc - 3,argv + 3);
 
351
         break;
 
352
      }
 
353
 
 
354
      if (strcmp(argv[1],"stats") == 0)
 
355
      {
 
356
         Stats(argv[2]);
 
357
         break;
 
358
      }
 
359
      
 
360
      if (strcmp(argv[1],"dump") == 0)
 
361
      {
 
362
         CacheFile = argv[2];
 
363
         Dump();
 
364
         break;
 
365
      }
 
366
      
 
367
      if (strcmp(argv[1],"dumpavail") == 0)
 
368
      {
 
369
         CacheFile = argv[2];
 
370
         DumpAvail();
 
371
         break;
 
372
      }
 
373
      
 
374
      _error->Error("Invalid operation %s", argv[1]);
 
375
      break;
 
376
   }
 
377
   
 
378
   // Print any errors or warnings found during parsing
 
379
   if (_error->empty() == false)
 
380
   {
 
381
      _error->DumpErrors();
 
382
      return 100;
 
383
   }
 
384
          
 
385
   return 0;
 
386
}