]>
git.saurik.com Git - apt.git/blob - apt-pkg/sourcelist.cc
62d5e6fcd5eb98b23757a2e2bbe9a7f30026140a
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: sourcelist.cc,v 1.1 1998/07/07 04:17:06 jgg Exp $
4 /* ######################################################################
8 ##################################################################### */
10 // Include Files /*{{{*/
12 #pragma implementation "pkglib/sourcelist.h"
15 #include <pkglib/sourcelist.h>
16 #include <pkglib/error.h>
17 #include <pkglib/fileutl.h>
27 // SourceList::pkgSourceList - Constructors /*{{{*/
28 // ---------------------------------------------------------------------
30 pkgSourceList::pkgSourceList()
34 pkgSourceList::pkgSourceList(string File
)
39 // SourceList::ReadMainList - Read the main source list from etc /*{{{*/
40 // ---------------------------------------------------------------------
42 bool pkgSourceList::ReadMainList()
44 return Read(PKG_DEB_CF_SOURCELIST
);
47 // SourceList::Read - Parse the sourcelist file /*{{{*/
48 // ---------------------------------------------------------------------
50 bool pkgSourceList::Read(string File
)
52 // Open the stream for reading
53 ifstream
F(File
.c_str(),ios::in
| ios::nocreate
);
55 return _error
->Errno("ifstream::ifstream","Opening %s",File
.c_str());
57 List
.erase(List
.begin(),List
.end());
61 while (F
.eof() == false)
63 F
.getline(Buffer
,sizeof(Buffer
));
65 _strtabexpand(Buffer
,sizeof(Buffer
));
69 if (Buffer
[0] == '#' || Buffer
[0] == 0)
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());
88 // Check for an absolute dists specification.
89 if (Itm
.Dist
.empty() == false && Itm
.Dist
[Itm
.Dist
.size() - 1] == '/')
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)",PKG_DEB_ARCH
);
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());
106 while (ParseQuoteWord(C
,Itm
.Section
) == true);
111 // SourceList::SanitizeURI - Hash the uri /*{{{*/
112 // ---------------------------------------------------------------------
113 /* This converts a URI into a safe filename. It quotes all unsafe characters
114 and converts / to _ and removes the scheme identifier. */
115 string
pkgSourceList::SanitizeURI(string URI
)
117 string::const_iterator I
= URI
.begin() + URI
.find(':') + 1;
118 for (; I
< URI
.end() && *I
== '/'; I
++);
120 // "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF";
121 URI
= QuoteString(string(I
,URI
.end() - I
),"\\|{}[]<>\"^~_=!@#$%^&*");
122 string::iterator J
= URI
.begin();
123 for (; J
!= URI
.end(); J
++)
129 // SourceList::MatchPkgFile - Find the package file that has the ver /*{{{*/
130 // ---------------------------------------------------------------------
131 /* This will return List.end() if it could not find the matching
133 pkgSourceList::const_iterator
pkgSourceList::MatchPkgFile(pkgCache::VerIterator Ver
)
135 string Base
= PKG_DEB_ST_LIST
;
136 for (const_iterator I
= List
.begin(); I
!= List
.end(); I
++)
138 string URI
= I
->PackagesURI();
142 if (Base
+ SanitizeURI(URI
) == Ver
.File().FileName())
150 // SourceList::Item << - Writes the item to a stream /*{{{*/
151 // ---------------------------------------------------------------------
152 /* This is not suitable for rebuilding the sourcelist file but it good for
154 ostream
&operator <<(ostream
&O
,pkgSourceList::Item
&Itm
)
156 O
<< Itm
.Type
<< ' ' << Itm
.URI
<< ' ' << Itm
.Dist
<< ' ' << Itm
.Section
;
160 // SourceList::Item::SetType - Sets the distribution type /*{{{*/
161 // ---------------------------------------------------------------------
163 bool pkgSourceList::Item::SetType(string S
)
174 // SourceList::Item::SetURI - Set the URI /*{{{*/
175 // ---------------------------------------------------------------------
176 /* For simplicity we strip the scheme off the uri */
177 bool pkgSourceList::Item::SetURI(string S
)
179 if (S
.empty() == true)
182 if (S
.find(':') == string::npos
)
185 S
= SubstVar(S
,"$(ARCH)",PKG_DEB_ARCH
);
187 // Make sure that the URN is / postfixed
189 if (URI
[URI
.size() - 1] != '/')
195 // SourceList::Item::PackagesURI - Returns a URI to the packages file /*{{{*/
196 // ---------------------------------------------------------------------
198 string
pkgSourceList::Item::PackagesURI() const
204 if (Dist
[Dist
.size() - 1] == '/')
207 Res
= URI
+ "dists/" + Dist
+ '/' + Section
+
208 "/binary-" + PKG_DEB_ARCH
+ '/';
216 // SourceList::Item::PackagesInfo - Shorter version of the URI /*{{{*/
217 // ---------------------------------------------------------------------
218 /* This is a shorter version that is designed to be < 60 chars or so */
219 string
pkgSourceList::Item::PackagesInfo() const
225 Res
+= SiteOnly(URI
) + ' ';
226 if (Dist
[Dist
.size() - 1] == '/')
229 Res
+= Dist
+ '/' + Section
;
237 // SourceList::Item::ArchiveInfo - Shorter version of the archive spec /*{{{*/
238 // ---------------------------------------------------------------------
239 /* This is a shorter version that is designed to be < 60 chars or so */
240 string
pkgSourceList::Item::ArchiveInfo(pkgCache::VerIterator Ver
) const
246 Res
+= SiteOnly(URI
) + ' ';
247 if (Dist
[Dist
.size() - 1] == '/')
250 Res
+= Dist
+ '/' + Section
;
253 Res
+= Ver
.ParentPkg().Name();
259 // SourceList::Item::ArchiveURI - Returns a URI to the given archive /*{{{*/
260 // ---------------------------------------------------------------------
262 string
pkgSourceList::Item::ArchiveURI(string File
) const
274 // SourceList::Item::SiteOnly - Strip off the path part of a URI /*{{{*/
275 // ---------------------------------------------------------------------
277 string
pkgSourceList::Item::SiteOnly(string URI
) const
279 unsigned int Pos
= URI
.find(':');
280 if (Pos
== string::npos
|| Pos
+ 3 > URI
.length())
282 if (URI
[Pos
+ 1] != '/' || URI
[Pos
+ 2] != '/')
285 Pos
= URI
.find('/',Pos
+ 3);
286 if (Pos
== string::npos
)
288 return string(URI
,0,Pos
);
292 // UpdateMeta - Update the meta information /*{{{*/
293 // ---------------------------------------------------------------------
294 /* The meta information is package files, revision information and mirror
296 bool pkgUpdateMeta(pkgSourceList
&List
,pkgAquire
&Engine
)
298 if (Engine
.OutputDir(PKG_DEB_ST_LIST
) == false)
301 for (pkgSourceList::const_iterator I
= List
.begin(); I
!= List
.end(); I
++)
303 string URI
= I
->PackagesURI();
304 string GetInfo
= I
->PackagesInfo();
307 case pkgSourceList::Item::Deb
:
308 if (Engine
.Get(URI
+ ".gz",List
.SanitizeURI(URI
),GetInfo
) == false)
317 // MakeSrcCache - Generate a cache file of all the package files /*{{{*/
318 // ---------------------------------------------------------------------
319 /* This goes over the source list and builds a cache of all the package
321 bool pkgMakeSrcCache(pkgSourceList
&List
)
323 // First we date check the cache
327 if (FileExists(PKG_DEB_CA_SRCCACHE
) == false)
330 pkgCache
Cache(PKG_DEB_CA_SRCCACHE
,true,true);
331 if (_error
->PendingError() == true)
337 // They are certianly out of sync
338 if (Cache
.Head().PackageFileCount
!= List
.size())
341 for (pkgCache::PkgFileIterator
F(Cache
); F
.end() == false; F
++)
343 // Search for a match in the source list
345 for (pkgSourceList::const_iterator I
= List
.begin();
346 I
!= List
.end(); I
++)
348 string File
= string(PKG_DEB_ST_LIST
) +
349 List
.SanitizeURI(I
->PackagesURI());
350 if (F
.FileName() == File
)
357 // Check if the file matches what was cached
367 unlink(PKG_DEB_CA_SRCCACHE
);
368 pkgCache::MergeState
Merge(PKG_DEB_CA_SRCCACHE
);
369 if (_error
->PendingError() == true)
372 for (pkgSourceList::const_iterator I
= List
.begin(); I
!= List
.end(); I
++)
374 string File
= string(PKG_DEB_ST_LIST
) + List
.SanitizeURI(I
->PackagesURI());
375 if (Merge
.MergePackageFile(File
,"??","??") == false)
382 // MakeStatusCache - Generates a cache that includes the status files /*{{{*/
383 // ---------------------------------------------------------------------
384 /* This copies the package source cache and then merges the status and
385 xstatus files into it. */
386 bool pkgMakeStatusCache()
388 // Quickly check if the existing package cache is ok
392 if (FileExists(PKG_DEB_CA_PKGCACHE
) == false)
395 /* We check the dates of the two caches. This takes care of most things
396 quickly and easially */
399 if (stat(PKG_DEB_CA_PKGCACHE
,&Pkg
) != 0 ||
400 stat(PKG_DEB_CA_SRCCACHE
,&Src
) != 0)
402 if (difftime(Src
.st_mtime
,Pkg
.st_mtime
) > 0)
405 pkgCache
Cache(PKG_DEB_CA_PKGCACHE
,true,true);
406 if (_error
->PendingError() == true)
412 for (pkgCache::PkgFileIterator
F(Cache
); F
.end() == false; F
++)
414 if (F
.IsOk() == false)
425 // Check the integrity of the source cache.
427 pkgCache
Cache(PKG_DEB_CA_SRCCACHE
,true,true);
428 if (_error
->PendingError() == true)
432 // Sub scope so that merge destructs before we rename the file...
433 string Cache
= PKG_DEB_CA_PKGCACHE
".new";
435 if (CopyFile(PKG_DEB_CA_SRCCACHE
,Cache
) == false)
438 pkgCache::MergeState
Merge(Cache
);
439 if (_error
->PendingError() == true)
442 // Merge in the user status file
443 if (FileExists(PKG_DEB_ST_USERSTATUS
) == true)
444 if (Merge
.MergePackageFile(PKG_DEB_ST_USERSTATUS
,"status","0",
445 pkgFLAG_NotSource
) == false)
448 // Merge in the extra status file
449 if (FileExists(PKG_DEB_ST_XSTATUS
) == true)
450 if (Merge
.MergePackageFile(PKG_DEB_ST_XSTATUS
,"status","0",
451 pkgFLAG_NotSource
) == false)
454 // Merge in the status file
455 if (Merge
.MergePackageFile("/var/lib/dpkg/status","status","0",
456 pkgFLAG_NotSource
) == false)
460 if (rename(Cache
.c_str(),PKG_DEB_CA_PKGCACHE
) != 0)