// -*- mode: cpp; mode: fold -*- // Description /*{{{*/ // $Id: sourcelist.cc,v 1.13 1999/04/07 05:30:17 jgg Exp $ /* ###################################################################### List of Sources ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ #ifdef __GNUG__ #pragma implementation "apt-pkg/sourcelist.h" #endif #include <apt-pkg/sourcelist.h> #include <apt-pkg/error.h> #include <apt-pkg/fileutl.h> #include <apt-pkg/configuration.h> #include <apt-pkg/strutl.h> #include <fstream.h> #include <stdio.h> #include <unistd.h> #include <sys/stat.h> /*}}}*/ // SourceList::pkgSourceList - Constructors /*{{{*/ // --------------------------------------------------------------------- /* */ pkgSourceList::pkgSourceList() { } pkgSourceList::pkgSourceList(string File) { Read(File); } /*}}}*/ // SourceList::ReadMainList - Read the main source list from etc /*{{{*/ // --------------------------------------------------------------------- /* */ bool pkgSourceList::ReadMainList() { return Read(_config->FindFile("Dir::Etc::sourcelist")); } /*}}}*/ // SourceList::Read - Parse the sourcelist file /*{{{*/ // --------------------------------------------------------------------- /* */ bool pkgSourceList::Read(string File) { // Open the stream for reading ifstream F(File.c_str(),ios::in | ios::nocreate); if (!F != 0) return _error->Errno("ifstream::ifstream","Opening %s",File.c_str()); List.erase(List.begin(),List.end()); char Buffer[300]; int CurLine = 0; while (F.eof() == false) { F.getline(Buffer,sizeof(Buffer)); CurLine++; _strtabexpand(Buffer,sizeof(Buffer)); _strstrip(Buffer); // Comment or blank if (Buffer[0] == '#' || Buffer[0] == 0) continue; // Grok it string Type; string URI; Item Itm; char *C = Buffer; if (ParseQuoteWord(C,Type) == false) return _error->Error("Malformed line %u in source list %s (type)",CurLine,File.c_str()); if (ParseQuoteWord(C,URI) == false) return _error->Error("Malformed line %u in source list %s (URI)",CurLine,File.c_str()); if (ParseQuoteWord(C,Itm.Dist) == false) return _error->Error("Malformed line %u in source list %s (dist)",CurLine,File.c_str()); if (Itm.SetType(Type) == false) return _error->Error("Malformed line %u in source list %s (type parse)",CurLine,File.c_str()); if (Itm.SetURI(URI) == false) return _error->Error("Malformed line %u in source list %s (URI parse)",CurLine,File.c_str()); // Check for an absolute dists specification. if (Itm.Dist.empty() == false && Itm.Dist[Itm.Dist.size() - 1] == '/') { if (ParseQuoteWord(C,Itm.Section) == true) return _error->Error("Malformed line %u in source list %s (Absolute dist)",CurLine,File.c_str()); Itm.Dist = SubstVar(Itm.Dist,"$(ARCH)",_config->Find("APT::Architecture")); List.push_back(Itm); continue; } // Grab the rest of the dists if (ParseQuoteWord(C,Itm.Section) == false) return _error->Error("Malformed line %u in source list %s (dist parse)",CurLine,File.c_str()); do { List.push_back(Itm); } while (ParseQuoteWord(C,Itm.Section) == true); } return true; } /*}}}*/ // SourceList::Item << - Writes the item to a stream /*{{{*/ // --------------------------------------------------------------------- /* This is not suitable for rebuilding the sourcelist file but it good for debugging. */ ostream &operator <<(ostream &O,pkgSourceList::Item &Itm) { O << (int)Itm.Type << ' ' << Itm.URI << ' ' << Itm.Dist << ' ' << Itm.Section; return O; } /*}}}*/ // SourceList::Item::SetType - Sets the distribution type /*{{{*/ // --------------------------------------------------------------------- /* */ bool pkgSourceList::Item::SetType(string S) { if (S == "deb") { Type = Deb; return true; } if (S == "deb-src") { Type = DebSrc; return true; } return false; } /*}}}*/ // SourceList::Item::SetURI - Set the URI /*{{{*/ // --------------------------------------------------------------------- /* For simplicity we strip the scheme off the uri */ bool pkgSourceList::Item::SetURI(string S) { if (S.empty() == true) return false; if (S.find(':') == string::npos) return false; S = SubstVar(S,"$(ARCH)",_config->Find("APT::Architecture")); // Make sure that the URN is / postfixed URI = S; if (URI[URI.size() - 1] != '/') URI += '/'; return true; } /*}}}*/ // SourceList::Item::PackagesURI - Returns a URI to the packages file /*{{{*/ // --------------------------------------------------------------------- /* */ string pkgSourceList::Item::PackagesURI() const { string Res; switch (Type) { case Deb: if (Dist[Dist.size() - 1] == '/') Res = URI + Dist; else Res = URI + "dists/" + Dist + '/' + Section + "/binary-" + _config->Find("APT::Architecture") + '/'; Res += "Packages"; break; case DebSrc: if (Dist[Dist.size() - 1] == '/') Res = URI + Dist; else Res = URI + "dists/" + Dist + '/' + Section + "/source/"; Res += "Sources"; break; }; return Res; } /*}}}*/ // SourceList::Item::PackagesInfo - Shorter version of the URI /*{{{*/ // --------------------------------------------------------------------- /* This is a shorter version that is designed to be < 60 chars or so */ string pkgSourceList::Item::PackagesInfo() const { string Res; switch (Type) { case Deb: Res += SiteOnly(URI) + ' '; if (Dist[Dist.size() - 1] == '/') Res += Dist; else Res += Dist + '/' + Section; Res += " Packages"; break; case DebSrc: Res += SiteOnly(URI) + ' '; if (Dist[Dist.size() - 1] == '/') Res += Dist; else Res += Dist + '/' + Section; Res += " Sources"; break; }; return Res; } /*}}}*/ // SourceList::Item::ReleaseURI - Returns a URI to the release file /*{{{*/ // --------------------------------------------------------------------- /* */ string pkgSourceList::Item::ReleaseURI() const { string Res; switch (Type) { case Deb: if (Dist[Dist.size() - 1] == '/') Res = URI + Dist; else Res = URI + "dists/" + Dist + '/' + Section + "/binary-" + _config->Find("APT::Architecture") + '/'; Res += "Release"; break; case DebSrc: if (Dist[Dist.size() - 1] == '/') Res = URI + Dist; else Res = URI + "dists/" + Dist + '/' + Section + "/source/"; Res += "Release"; break; }; return Res; } /*}}}*/ // SourceList::Item::ReleaseInfo - Shorter version of the URI /*{{{*/ // --------------------------------------------------------------------- /* This is a shorter version that is designed to be < 60 chars or so */ string pkgSourceList::Item::ReleaseInfo() const { string Res; switch (Type) { case Deb: case DebSrc: Res += SiteOnly(URI) + ' '; if (Dist[Dist.size() - 1] == '/') Res += Dist; else Res += Dist + '/' + Section; Res += " Release"; break; }; return Res; } /*}}}*/ // SourceList::Item::ArchiveInfo - Shorter version of the archive spec /*{{{*/ // --------------------------------------------------------------------- /* This is a shorter version that is designed to be < 60 chars or so */ string pkgSourceList::Item::ArchiveInfo(pkgCache::VerIterator Ver) const { string Res; switch (Type) { case DebSrc: case Deb: Res += SiteOnly(URI) + ' '; if (Dist[Dist.size() - 1] == '/') Res += Dist; else Res += Dist + '/' + Section; Res += " "; Res += Ver.ParentPkg().Name(); Res += " "; Res += Ver.VerStr(); break; }; return Res; } /*}}}*/ // SourceList::Item::ArchiveURI - Returns a URI to the given archive /*{{{*/ // --------------------------------------------------------------------- /* */ string pkgSourceList::Item::ArchiveURI(string File) const { string Res; switch (Type) { case Deb: case DebSrc: Res = URI + File; break; }; return Res; } /*}}}*/ // SourceList::Item::SourceInfo - Returns an info line for a source /*{{{*/ // --------------------------------------------------------------------- /* */ string pkgSourceList::Item::SourceInfo(string Pkg,string Ver,string Comp) const { string Res; switch (Type) { case DebSrc: case Deb: Res += SiteOnly(URI) + ' '; if (Dist[Dist.size() - 1] == '/') Res += Dist; else Res += Dist + '/' + Section; Res += " "; Res += Pkg; Res += " "; Res += Ver; if (Comp.empty() == false) Res += " (" + Comp + ")"; break; }; return Res; } /*}}}*/ // SourceList::Item::SiteOnly - Strip off the path part of a URI /*{{{*/ // --------------------------------------------------------------------- /* */ string pkgSourceList::Item::SiteOnly(string URI) const { unsigned int Pos = URI.find(':'); if (Pos == string::npos || Pos + 3 > URI.length()) return URI; if (URI[Pos + 1] != '/' || URI[Pos + 2] != '/') return URI; Pos = URI.find('/',Pos + 3); if (Pos == string::npos) return URI; return string(URI,0,Pos); } /*}}}*/