~mvo/apt/mvo

« back to all changes in this revision

Viewing changes to apt-pkg/sourcelist.cc

  • Committer: Arch Librarian
  • Date: 2004-09-20 16:56:32 UTC
  • Revision ID: Arch-1:apt@arch.ubuntu.com%apt--MAIN--0--patch-614
Join with aliencode
Author: jgg
Date: 2001-02-20 07:03:16 GMT
Join with aliencode

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// -*- mode: cpp; mode: fold -*-
2
2
// Description                                                          /*{{{*/
3
 
// $Id: sourcelist.cc,v 1.17 1999/10/17 07:30:23 jgg Exp $
 
3
// $Id: sourcelist.cc,v 1.18 2001/02/20 07:03:17 jgg Exp $
4
4
/* ######################################################################
5
5
 
6
6
   List of Sources
18
18
#include <apt-pkg/configuration.h>
19
19
#include <apt-pkg/strutl.h>
20
20
 
 
21
#include <apti18n.h>
 
22
 
21
23
#include <fstream.h>
22
 
#include <stdio.h>
23
 
#include <unistd.h>
24
 
#include <sys/stat.h>
 
24
                                                                        /*}}}*/
 
25
 
 
26
// Global list of Item supported
 
27
static  pkgSourceList::Type *ItmList[10];
 
28
pkgSourceList::Type **pkgSourceList::Type::GlobalList = ItmList;
 
29
unsigned long pkgSourceList::Type::GlobalListLen = 0;
 
30
 
 
31
// Type::Type - Constructor                                             /*{{{*/
 
32
// ---------------------------------------------------------------------
 
33
/* Link this to the global list of items*/
 
34
pkgSourceList::Type::Type()
 
35
{
 
36
   ItmList[GlobalListLen] = this;
 
37
   GlobalListLen++;
 
38
}
 
39
                                                                        /*}}}*/
 
40
// Type::GetType - Get a specific meta for a given type                 /*{{{*/
 
41
// ---------------------------------------------------------------------
 
42
/* */
 
43
pkgSourceList::Type *pkgSourceList::Type::GetType(const char *Type)
 
44
{
 
45
   for (unsigned I = 0; I != GlobalListLen; I++)
 
46
      if (strcmp(GlobalList[I]->Name,Type) == 0)
 
47
         return GlobalList[I];
 
48
   return 0;
 
49
}
 
50
                                                                        /*}}}*/
 
51
// Type::FixupURI - Normalize the URI and check it..                    /*{{{*/
 
52
// ---------------------------------------------------------------------
 
53
/* */
 
54
bool pkgSourceList::Type::FixupURI(string &URI) const
 
55
{
 
56
   if (URI.empty() == true)
 
57
      return false;
 
58
 
 
59
   if (URI.find(':') == string::npos)
 
60
      return false;
 
61
 
 
62
   URI = SubstVar(URI,"$(ARCH)",_config->Find("APT::Architecture"));
 
63
   
 
64
   // Make sure that the URN is / postfixed
 
65
   if (URI[URI.size() - 1] != '/')
 
66
      URI += '/';
 
67
   
 
68
   return true;
 
69
}
 
70
                                                                        /*}}}*/
 
71
// Type::ParseLine - Parse a single line                                /*{{{*/
 
72
// ---------------------------------------------------------------------
 
73
/* This is a generic one that is the 'usual' format for sources.list
 
74
   Weird types may override this. */
 
75
bool pkgSourceList::Type::ParseLine(vector<pkgIndexFile *> &List,
 
76
                                    const char *Buffer,
 
77
                                    unsigned long CurLine,
 
78
                                    string File) const
 
79
{
 
80
   string URI;
 
81
   string Dist;
 
82
   string Section;   
 
83
   
 
84
   if (ParseQuoteWord(Buffer,URI) == false)
 
85
      return _error->Error(_("Malformed line %lu in source list %s (URI)"),CurLine,File.c_str());
 
86
   if (ParseQuoteWord(Buffer,Dist) == false)
 
87
      return _error->Error(_("Malformed line %lu in source list %s (dist)"),CurLine,File.c_str());
 
88
      
 
89
   if (FixupURI(URI) == false)
 
90
      return _error->Error(_("Malformed line %lu in source list %s (URI parse)"),CurLine,File.c_str());
 
91
   
 
92
   // Check for an absolute dists specification.
 
93
   if (Dist.empty() == false && Dist[Dist.size() - 1] == '/')
 
94
   {
 
95
      if (ParseQuoteWord(Buffer,Section) == true)
 
96
         return _error->Error(_("Malformed line %lu in source list %s (Absolute dist)"),CurLine,File.c_str());
 
97
      Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture"));
 
98
      return CreateItem(List,URI,Dist,Section);
 
99
   }
 
100
   
 
101
   // Grab the rest of the dists
 
102
   if (ParseQuoteWord(Buffer,Section) == false)
 
103
      return _error->Error(_("Malformed line %lu in source list %s (dist parse)"),CurLine,File.c_str());
 
104
   
 
105
   do
 
106
   {
 
107
      if (CreateItem(List,URI,Dist,Section) == false)
 
108
         return false;
 
109
   }
 
110
   while (ParseQuoteWord(Buffer,Section) == true);
 
111
   
 
112
   return true;
 
113
}
25
114
                                                                        /*}}}*/
26
115
 
27
116
// SourceList::pkgSourceList - Constructors                             /*{{{*/
52
141
   // Open the stream for reading
53
142
   ifstream F(File.c_str(),ios::in | ios::nocreate);
54
143
   if (!F != 0)
55
 
      return _error->Errno("ifstream::ifstream","Opening %s",File.c_str());
 
144
      return _error->Errno("ifstream::ifstream",_("Opening %s"),File.c_str());
56
145
   
57
146
   List.erase(List.begin(),List.end());
58
147
   char Buffer[300];
63
152
      F.getline(Buffer,sizeof(Buffer));
64
153
      CurLine++;
65
154
      _strtabexpand(Buffer,sizeof(Buffer));
66
 
      _strstrip(Buffer);
 
155
      
 
156
      
 
157
      char *I;
 
158
      for (I = Buffer; *I != 0 && *I != '#'; I++);
 
159
      *I = 0;
 
160
      
 
161
      const char *C = _strstrip(Buffer);
67
162
      
68
163
      // Comment or blank
69
 
      if (Buffer[0] == '#' || Buffer[0] == 0)
 
164
      if (C[0] == '#' || C[0] == 0)
70
165
         continue;
71
 
      
 
166
            
72
167
      // Grok it
73
 
      string Type;
74
 
      string URI;
75
 
      Item Itm;
76
 
      const char *C = Buffer;
77
 
      if (ParseQuoteWord(C,Type) == false)
78
 
         return _error->Error("Malformed line %u in source list %s (type)",CurLine,File.c_str());
79
 
      if (ParseQuoteWord(C,URI) == false)
80
 
         return _error->Error("Malformed line %u in source list %s (URI)",CurLine,File.c_str());
81
 
      if (ParseQuoteWord(C,Itm.Dist) == false)
82
 
         return _error->Error("Malformed line %u in source list %s (dist)",CurLine,File.c_str());
83
 
      if (Itm.SetType(Type) == false)
84
 
         return _error->Error("Malformed line %u in source list %s (type parse)",CurLine,File.c_str());
85
 
      if (Itm.SetURI(URI) == false)
86
 
         return _error->Error("Malformed line %u in source list %s (URI parse)",CurLine,File.c_str());
87
 
 
88
 
      // Check for an absolute dists specification.
89
 
      if (Itm.Dist.empty() == false && Itm.Dist[Itm.Dist.size() - 1] == '/')
90
 
      {
91
 
         if (ParseQuoteWord(C,Itm.Section) == true)
92
 
            return _error->Error("Malformed line %u in source list %s (Absolute dist)",CurLine,File.c_str());
93
 
         Itm.Dist = SubstVar(Itm.Dist,"$(ARCH)",_config->Find("APT::Architecture"));
94
 
         List.push_back(Itm);
95
 
         continue;
96
 
      }
97
 
 
98
 
      // Grab the rest of the dists
99
 
      if (ParseQuoteWord(C,Itm.Section) == false)
100
 
            return _error->Error("Malformed line %u in source list %s (dist parse)",CurLine,File.c_str());
 
168
      string LineType;
 
169
      if (ParseQuoteWord(C,LineType) == false)
 
170
         return _error->Error(_("Malformed line %u in source list %s (type)"),CurLine,File.c_str());
 
171
 
 
172
      Type *Parse = Type::GetType(LineType.c_str());
 
173
      if (Parse == 0)
 
174
         return _error->Error(_("Type '%s' is not known in on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
101
175
      
102
 
      do
103
 
      {
104
 
         List.push_back(Itm);
105
 
      }
106
 
      while (ParseQuoteWord(C,Itm.Section) == true);
 
176
      if (Parse->ParseLine(List,C,CurLine,File) == false)
 
177
         return false;
107
178
   }
108
179
   return true;
109
180
}
110
181
                                                                        /*}}}*/
111
 
// SourceList::Item << - Writes the item to a stream                    /*{{{*/
112
 
// ---------------------------------------------------------------------
113
 
/* This is not suitable for rebuilding the sourcelist file but it good for
114
 
   debugging. */
115
 
ostream &operator <<(ostream &O,pkgSourceList::Item &Itm)
116
 
{
117
 
   O << (int)Itm.Type << ' ' << Itm.URI << ' ' << Itm.Dist << ' ' << Itm.Section;
118
 
   return O;
119
 
}
120
 
                                                                        /*}}}*/
121
 
// SourceList::Item::SetType - Sets the distribution type               /*{{{*/
 
182
// SourceList::FindIndex - Get the index associated with a file         /*{{{*/
122
183
// ---------------------------------------------------------------------
123
184
/* */
124
 
bool pkgSourceList::Item::SetType(string S)
 
185
bool pkgSourceList::FindIndex(pkgCache::PkgFileIterator File,
 
186
                              pkgIndexFile *&Found) const
125
187
{
126
 
   if (S == "deb")
127
 
   {
128
 
      Type = Deb;
129
 
      return true;
130
 
   }
131
 
 
132
 
   if (S == "deb-src")
133
 
   {
134
 
      Type = DebSrc;
135
 
      return true;
136
 
   }
137
 
 
 
188
   for (const_iterator I = List.begin(); I != List.end(); I++)
 
189
   {
 
190
      if ((*I)->FindInCache(*File.Cache()) == File)
 
191
      {
 
192
         Found = *I;
 
193
         return true;
 
194
      }
 
195
   }
 
196
   
138
197
   return false;
139
198
}
140
199
                                                                        /*}}}*/
141
 
// SourceList::Item::SetURI - Set the URI                               /*{{{*/
 
200
// SourceList::GetIndexes - Load the index files into the downloader    /*{{{*/
142
201
// ---------------------------------------------------------------------
143
 
/* For simplicity we strip the scheme off the uri */
144
 
bool pkgSourceList::Item::SetURI(string S)
 
202
/* */
 
203
bool pkgSourceList::GetIndexes(pkgAcquire *Owner) const
145
204
{
146
 
   if (S.empty() == true)
147
 
      return false;
148
 
 
149
 
   if (S.find(':') == string::npos)
150
 
      return false;
151
 
 
152
 
   S = SubstVar(S,"$(ARCH)",_config->Find("APT::Architecture"));
153
 
   
154
 
   // Make sure that the URN is / postfixed
155
 
   URI = S;
156
 
   if (URI[URI.size() - 1] != '/')
157
 
      URI += '/';
158
 
   
 
205
   for (const_iterator I = List.begin(); I != List.end(); I++)
 
206
      if ((*I)->GetIndexes(Owner) == false)
 
207
         return false;
159
208
   return true;
160
209
}
161
210
                                                                        /*}}}*/
162
 
// SourceList::Item::PackagesURI - Returns a URI to the packages file   /*{{{*/
163
 
// ---------------------------------------------------------------------
164
 
/* */
165
 
string pkgSourceList::Item::PackagesURI() const
166
 
{
167
 
   string Res;
168
 
   switch (Type)
169
 
   {
170
 
      case Deb:
171
 
      if (Dist[Dist.size() - 1] == '/')
172
 
      {
173
 
         if (Dist != "/")
174
 
            Res = URI + Dist;
175
 
         else 
176
 
            Res = URI;
177
 
      }      
178
 
      else
179
 
         Res = URI + "dists/" + Dist + '/' + Section +
180
 
         "/binary-" + _config->Find("APT::Architecture") + '/';
181
 
      
182
 
      Res += "Packages";
183
 
      break;
184
 
      
185
 
      case DebSrc:
186
 
      if (Dist[Dist.size() - 1] == '/')
187
 
         Res = URI + Dist;
188
 
      else
189
 
         Res = URI + "dists/" + Dist + '/' + Section +
190
 
         "/source/";
191
 
      
192
 
      Res += "Sources";
193
 
      break;
194
 
   };
195
 
   return Res;
196
 
}
197
 
                                                                        /*}}}*/
198
 
// SourceList::Item::PackagesInfo - Shorter version of the URI          /*{{{*/
199
 
// ---------------------------------------------------------------------
200
 
/* This is a shorter version that is designed to be < 60 chars or so */
201
 
string pkgSourceList::Item::PackagesInfo() const
202
 
{
203
 
   string Res;
204
 
   switch (Type)
205
 
   {
206
 
      case Deb:
207
 
      Res += SiteOnly(URI) + ' ';
208
 
      if (Dist[Dist.size() - 1] == '/')
209
 
      {
210
 
         if (Dist != "/")
211
 
            Res += Dist;
212
 
      }      
213
 
      else
214
 
         Res += Dist + '/' + Section;
215
 
      
216
 
      Res += " Packages";
217
 
      break;
218
 
     
219
 
      case DebSrc:
220
 
      Res += SiteOnly(URI) + ' ';
221
 
      if (Dist[Dist.size() - 1] == '/')
222
 
         Res += Dist;
223
 
      else
224
 
         Res += Dist + '/' + Section;
225
 
      
226
 
      Res += " Sources";
227
 
      break;
228
 
   };
229
 
   return Res;
230
 
}
231
 
                                                                        /*}}}*/
232
 
// SourceList::Item::ReleaseURI - Returns a URI to the release file     /*{{{*/
233
 
// ---------------------------------------------------------------------
234
 
/* */
235
 
string pkgSourceList::Item::ReleaseURI() const
236
 
{
237
 
   string Res;
238
 
   switch (Type)
239
 
   {
240
 
      case Deb:
241
 
      if (Dist[Dist.size() - 1] == '/')
242
 
      {
243
 
         if (Dist != "/")
244
 
            Res = URI + Dist;
245
 
         else
246
 
            Res = URI;
247
 
      }      
248
 
      else
249
 
         Res = URI + "dists/" + Dist + '/' + Section +
250
 
         "/binary-" + _config->Find("APT::Architecture") + '/';
251
 
      
252
 
      Res += "Release";
253
 
      break;
254
 
      
255
 
      case DebSrc:
256
 
      if (Dist[Dist.size() - 1] == '/')
257
 
         Res = URI + Dist;
258
 
      else
259
 
         Res = URI + "dists/" + Dist + '/' + Section +
260
 
         "/source/";
261
 
      
262
 
      Res += "Release";
263
 
      break;
264
 
   };
265
 
   return Res;
266
 
}
267
 
                                                                        /*}}}*/
268
 
// SourceList::Item::ReleaseInfo - Shorter version of the URI           /*{{{*/
269
 
// ---------------------------------------------------------------------
270
 
/* This is a shorter version that is designed to be < 60 chars or so */
271
 
string pkgSourceList::Item::ReleaseInfo() const
272
 
{
273
 
   string Res;
274
 
   switch (Type)
275
 
   {
276
 
      case Deb:
277
 
      case DebSrc:
278
 
      Res += SiteOnly(URI) + ' ';
279
 
      if (Dist[Dist.size() - 1] == '/')
280
 
      {
281
 
         if (Dist != "/")
282
 
            Res += Dist;
283
 
      }      
284
 
      else
285
 
         Res += Dist + '/' + Section;
286
 
      
287
 
      Res += " Release";
288
 
      break;
289
 
   };
290
 
   return Res;
291
 
}
292
 
                                                                        /*}}}*/
293
 
// SourceList::Item::ArchiveInfo - Shorter version of the archive spec  /*{{{*/
294
 
// ---------------------------------------------------------------------
295
 
/* This is a shorter version that is designed to be < 60 chars or so */
296
 
string pkgSourceList::Item::ArchiveInfo(pkgCache::VerIterator Ver) const
297
 
{
298
 
   string Res;
299
 
   switch (Type)
300
 
   {
301
 
      case DebSrc:
302
 
      case Deb:
303
 
      Res += SiteOnly(URI) + ' ';
304
 
      if (Dist[Dist.size() - 1] == '/')
305
 
      {
306
 
         if (Dist != "/")
307
 
            Res += Dist;
308
 
      }      
309
 
      else
310
 
         Res += Dist + '/' + Section;
311
 
      
312
 
      Res += " ";
313
 
      Res += Ver.ParentPkg().Name();
314
 
      Res += " ";
315
 
      Res += Ver.VerStr();
316
 
      
317
 
      break;
318
 
   };
319
 
   return Res;
320
 
}
321
 
                                                                        /*}}}*/
322
 
// SourceList::Item::ArchiveURI - Returns a URI to the given archive    /*{{{*/
323
 
// ---------------------------------------------------------------------
324
 
/* */
325
 
string pkgSourceList::Item::ArchiveURI(string File) const
326
 
{
327
 
   string Res;
328
 
   switch (Type)
329
 
   {
330
 
      case Deb:
331
 
      case DebSrc:
332
 
      Res = URI + File;
333
 
      break;
334
 
   };
335
 
   return Res;
336
 
}
337
 
                                                                        /*}}}*/
338
 
// SourceList::Item::SourceInfo - Returns an info line for a source     /*{{{*/
339
 
// ---------------------------------------------------------------------
340
 
/* */
341
 
string pkgSourceList::Item::SourceInfo(string Pkg,string Ver,string Comp) const
342
 
{
343
 
   string Res;
344
 
   switch (Type)
345
 
   {
346
 
      case DebSrc:
347
 
      case Deb:
348
 
      Res += SiteOnly(URI) + ' ';
349
 
      if (Dist[Dist.size() - 1] == '/')
350
 
      {
351
 
         if (Dist != "/")
352
 
            Res += Dist;
353
 
      }      
354
 
      else
355
 
         Res += Dist + '/' + Section;
356
 
      
357
 
      Res += " ";
358
 
      Res += Pkg;
359
 
      Res += " ";
360
 
      Res += Ver;
361
 
      if (Comp.empty() == false)
362
 
         Res += " (" + Comp + ")";
363
 
      break;
364
 
   };
365
 
   return Res;
366
 
}
367
 
                                                                        /*}}}*/
368
 
// SourceList::Item::SiteOnly - Strip off the path part of a URI        /*{{{*/
369
 
// ---------------------------------------------------------------------
370
 
/* */
371
 
string pkgSourceList::Item::SiteOnly(string URI) const
372
 
{
373
 
   ::URI U(URI);
374
 
   U.User = string();
375
 
   U.Password = string();
376
 
   U.Path = string();
377
 
   U.Port = 0;
378
 
   return U;
379
 
}
380
 
                                                                        /*}}}*/