[280] | 1 | /* rsource.cc - access the sources.list file |
---|
| 2 | * |
---|
| 3 | * Copyright (c) 1999 Patrick Cole <z@amused.net> |
---|
| 4 | * (c) 2002 Synaptic development team |
---|
| 5 | * |
---|
| 6 | * Author: Patrick Cole <z@amused.net> |
---|
| 7 | * Michael Vogt <mvo@debian.org> |
---|
| 8 | * Gustavo Niemeyer <niemeyer@conectiva.com> |
---|
| 9 | * |
---|
| 10 | * This program is free software; you can redistribute it and/or |
---|
| 11 | * modify it under the terms of the GNU General Public License as |
---|
| 12 | * published by the Free Software Foundation; either version 2 of the |
---|
| 13 | * License, or (at your option) any later version. |
---|
| 14 | * |
---|
| 15 | * This program is distributed in the hope that it will be useful, |
---|
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 18 | * GNU General Public License for more details. |
---|
| 19 | * |
---|
| 20 | * You should have received a copy of the GNU General Public License |
---|
| 21 | * along with this program; if not, write to the Free Software |
---|
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
---|
| 23 | * USA |
---|
| 24 | */ |
---|
| 25 | |
---|
| 26 | #include <sys/stat.h> |
---|
| 27 | #include <dirent.h> |
---|
| 28 | |
---|
| 29 | #include "rsources.h" |
---|
| 30 | #include <apt-pkg/configuration.h> |
---|
| 31 | #include <apt-pkg/fileutl.h> |
---|
| 32 | #include <apt-pkg/sourcelist.h> |
---|
| 33 | #include <apt-pkg/strutl.h> |
---|
| 34 | #include <apt-pkg/error.h> |
---|
| 35 | #include <algorithm> |
---|
| 36 | #include <fstream> |
---|
| 37 | #include "config.h" |
---|
| 38 | #include "i18n.h" |
---|
| 39 | |
---|
| 40 | SourcesList::~SourcesList() |
---|
| 41 | { |
---|
| 42 | for (list<SourceRecord *>::iterator it = SourceRecords.begin(); |
---|
| 43 | it != SourceRecords.end(); it++) |
---|
| 44 | delete *it; |
---|
| 45 | for (list<VendorRecord *>::iterator it = VendorRecords.begin(); |
---|
| 46 | it != VendorRecords.end(); it++) |
---|
| 47 | delete *it; |
---|
| 48 | } |
---|
| 49 | |
---|
| 50 | SourcesList::SourceRecord *SourcesList::AddSourceNode(SourceRecord &rec) |
---|
| 51 | { |
---|
| 52 | SourceRecord *newrec = new SourceRecord; |
---|
| 53 | *newrec = rec; |
---|
| 54 | SourceRecords.push_back(newrec); |
---|
| 55 | |
---|
| 56 | return newrec; |
---|
| 57 | } |
---|
| 58 | |
---|
| 59 | bool SourcesList::ReadSourcePart(string listpath) |
---|
| 60 | { |
---|
| 61 | //cout << "SourcesList::ReadSourcePart() "<< listpath << endl; |
---|
| 62 | char buf[512]; |
---|
| 63 | const char *p; |
---|
| 64 | ifstream ifs(listpath.c_str(), ios::in); |
---|
| 65 | bool record_ok = true; |
---|
| 66 | |
---|
| 67 | // cannot open file |
---|
| 68 | if (!ifs != 0) |
---|
| 69 | return _error->Error(_("Can't read %s"), listpath.c_str()); |
---|
| 70 | |
---|
| 71 | while (ifs.eof() == false) { |
---|
| 72 | p = buf; |
---|
| 73 | SourceRecord rec; |
---|
| 74 | string Type; |
---|
| 75 | string Section; |
---|
| 76 | string VURI; |
---|
| 77 | |
---|
| 78 | ifs.getline(buf, sizeof(buf)); |
---|
| 79 | |
---|
| 80 | rec.SourceFile = listpath; |
---|
| 81 | while (isspace(*p)) |
---|
| 82 | p++; |
---|
| 83 | if (*p == '#') { |
---|
| 84 | rec.Type = Disabled; |
---|
| 85 | p++; |
---|
| 86 | while (isspace(*p)) |
---|
| 87 | p++; |
---|
| 88 | } |
---|
| 89 | |
---|
| 90 | if (*p == '\r' || *p == '\n' || *p == 0) { |
---|
| 91 | rec.Type = Comment; |
---|
| 92 | rec.Comment = p; |
---|
| 93 | |
---|
| 94 | AddSourceNode(rec); |
---|
| 95 | continue; |
---|
| 96 | } |
---|
| 97 | |
---|
| 98 | bool Failed = true; |
---|
| 99 | if (ParseQuoteWord(p, Type) == true && |
---|
| 100 | rec.SetType(Type) == true && ParseQuoteWord(p, VURI) == true) { |
---|
| 101 | if (VURI[0] == '[') { |
---|
| 102 | rec.VendorID = VURI.substr(1, VURI.length() - 2); |
---|
| 103 | if (ParseQuoteWord(p, VURI) == true && rec.SetURI(VURI) == true) |
---|
| 104 | Failed = false; |
---|
| 105 | } else if (rec.SetURI(VURI) == true) { |
---|
| 106 | Failed = false; |
---|
| 107 | } |
---|
| 108 | if (Failed == false && ParseQuoteWord(p, rec.Dist) == false) |
---|
| 109 | Failed = true; |
---|
| 110 | } |
---|
| 111 | |
---|
| 112 | if (Failed == true) { |
---|
| 113 | if (rec.Type == Disabled) { |
---|
| 114 | // treat as a comment field |
---|
| 115 | rec.Type = Comment; |
---|
| 116 | rec.Comment = buf; |
---|
| 117 | } else { |
---|
| 118 | // syntax error on line |
---|
| 119 | rec.Type = Comment; |
---|
| 120 | string s = "#" + string(buf); |
---|
| 121 | rec.Comment = s; |
---|
| 122 | record_ok = false; |
---|
| 123 | //return _error->Error(_("Syntax error in line %s"), buf); |
---|
| 124 | } |
---|
| 125 | } |
---|
| 126 | #ifndef HAVE_RPM |
---|
| 127 | // check for absolute dist |
---|
| 128 | if (rec.Dist.empty() == false && rec.Dist[rec.Dist.size() - 1] == '/') { |
---|
| 129 | // make sure there's no section |
---|
| 130 | if (ParseQuoteWord(p, Section) == true) |
---|
| 131 | return _error->Error(_("Syntax error in line %s"), buf); |
---|
| 132 | |
---|
| 133 | rec.Dist = SubstVar(rec.Dist, "$(ARCH)", |
---|
| 134 | _config->Find("APT::Architecture")); |
---|
| 135 | |
---|
| 136 | AddSourceNode(rec); |
---|
| 137 | continue; |
---|
| 138 | } |
---|
| 139 | #endif |
---|
| 140 | |
---|
| 141 | const char *tmp = p; |
---|
| 142 | rec.NumSections = 0; |
---|
| 143 | while (ParseQuoteWord(p, Section) == true) |
---|
| 144 | rec.NumSections++; |
---|
| 145 | if (rec.NumSections > 0) { |
---|
| 146 | p = tmp; |
---|
| 147 | rec.Sections = new string[rec.NumSections]; |
---|
| 148 | rec.NumSections = 0; |
---|
| 149 | while (ParseQuoteWord(p, Section) == true) { |
---|
| 150 | // comments inside the record are preserved |
---|
| 151 | if (Section[0] == '#') { |
---|
| 152 | SourceRecord rec; |
---|
| 153 | string s = Section + string(p); |
---|
| 154 | rec.Type = Comment; |
---|
| 155 | rec.Comment = s; |
---|
| 156 | rec.SourceFile = listpath; |
---|
| 157 | AddSourceNode(rec); |
---|
| 158 | break; |
---|
| 159 | } else { |
---|
| 160 | rec.Sections[rec.NumSections++] = Section; |
---|
| 161 | } |
---|
| 162 | } |
---|
| 163 | } |
---|
| 164 | AddSourceNode(rec); |
---|
| 165 | } |
---|
| 166 | |
---|
| 167 | ifs.close(); |
---|
| 168 | return record_ok; |
---|
| 169 | } |
---|
| 170 | |
---|
| 171 | bool SourcesList::ReadSourceDir(string Dir) |
---|
| 172 | { |
---|
| 173 | //cout << "SourcesList::ReadSourceDir() " << Dir << endl; |
---|
| 174 | |
---|
| 175 | DIR *D = opendir(Dir.c_str()); |
---|
| 176 | if (D == 0) |
---|
| 177 | return _error->Errno("opendir", _("Unable to read %s"), Dir.c_str()); |
---|
| 178 | |
---|
| 179 | vector<string> List; |
---|
| 180 | for (struct dirent * Ent = readdir(D); Ent != 0; Ent = readdir(D)) { |
---|
| 181 | if (Ent->d_name[0] == '.') |
---|
| 182 | continue; |
---|
| 183 | |
---|
| 184 | // Skip bad file names ala run-parts |
---|
| 185 | const char *C = Ent->d_name; |
---|
| 186 | for (; *C != 0; C++) |
---|
| 187 | if (isalpha(*C) == 0 && isdigit(*C) == 0 |
---|
| 188 | && *C != '_' && *C != '-' && *C != '.') |
---|
| 189 | break; |
---|
| 190 | if (*C != 0) |
---|
| 191 | continue; |
---|
| 192 | |
---|
| 193 | // Only look at files ending in .list to skip .rpmnew etc files |
---|
| 194 | if (strcmp(Ent->d_name + strlen(Ent->d_name) - 5, ".list") != 0) |
---|
| 195 | continue; |
---|
| 196 | |
---|
| 197 | // Make sure it is a file and not something else |
---|
| 198 | string File = flCombine(Dir, Ent->d_name); |
---|
| 199 | struct stat St; |
---|
| 200 | if (stat(File.c_str(), &St) != 0 || S_ISREG(St.st_mode) == 0) |
---|
| 201 | continue; |
---|
| 202 | List.push_back(File); |
---|
| 203 | |
---|
| 204 | } |
---|
| 205 | closedir(D); |
---|
| 206 | |
---|
| 207 | sort(List.begin(), List.end()); |
---|
| 208 | |
---|
| 209 | // Read the files |
---|
| 210 | for (vector<string>::const_iterator I = List.begin(); I != List.end(); |
---|
| 211 | I++) |
---|
| 212 | if (ReadSourcePart(*I) == false) |
---|
| 213 | return false; |
---|
| 214 | return true; |
---|
| 215 | } |
---|
| 216 | |
---|
| 217 | |
---|
| 218 | bool SourcesList::ReadSources() |
---|
| 219 | { |
---|
| 220 | //cout << "SourcesList::ReadSources() " << endl; |
---|
| 221 | |
---|
| 222 | bool Res = true; |
---|
| 223 | |
---|
| 224 | string Parts = _config->FindDir("Dir::Etc::sourceparts"); |
---|
| 225 | if (FileExists(Parts) == true) |
---|
| 226 | Res &= ReadSourceDir(Parts); |
---|
| 227 | string Main = _config->FindFile("Dir::Etc::sourcelist"); |
---|
| 228 | if (FileExists(Main) == true) |
---|
| 229 | Res &= ReadSourcePart(Main); |
---|
| 230 | |
---|
| 231 | return Res; |
---|
| 232 | } |
---|
| 233 | |
---|
| 234 | SourcesList::SourceRecord *SourcesList::AddEmptySource() |
---|
| 235 | { |
---|
| 236 | SourceRecord rec; |
---|
| 237 | #ifdef HAVE_RPM |
---|
| 238 | rec.Type = Rpm; |
---|
| 239 | #else |
---|
| 240 | rec.Type = Deb; |
---|
| 241 | #endif |
---|
| 242 | rec.VendorID = ""; |
---|
| 243 | rec.SourceFile = _config->FindFile("Dir::Etc::sourcelist"); |
---|
| 244 | rec.Dist = ""; |
---|
| 245 | rec.NumSections = 0; |
---|
| 246 | return AddSourceNode(rec); |
---|
| 247 | } |
---|
| 248 | |
---|
| 249 | SourcesList::SourceRecord *SourcesList::AddSource(RecType Type, |
---|
| 250 | string VendorID, string URI, |
---|
| 251 | string Dist, |
---|
| 252 | string *Sections, |
---|
| 253 | unsigned short count, |
---|
| 254 | string SourceFile) |
---|
| 255 | { |
---|
| 256 | SourceRecord rec; |
---|
| 257 | rec.Type = Type; |
---|
| 258 | rec.VendorID = VendorID; |
---|
| 259 | rec.SourceFile = SourceFile; |
---|
| 260 | |
---|
| 261 | if (rec.SetURI(URI) == false) { |
---|
| 262 | return NULL; |
---|
| 263 | } |
---|
| 264 | rec.Dist = Dist; |
---|
| 265 | rec.NumSections = count; |
---|
| 266 | rec.Sections = new string[count]; |
---|
| 267 | for (unsigned int i = 0; i < count; i++) |
---|
| 268 | rec.Sections[i] = Sections[i]; |
---|
| 269 | |
---|
| 270 | return AddSourceNode(rec); |
---|
| 271 | } |
---|
| 272 | |
---|
| 273 | void SourcesList::RemoveSource(SourceRecord *&rec) |
---|
| 274 | { |
---|
| 275 | SourceRecords.remove(rec); |
---|
| 276 | delete rec; |
---|
| 277 | rec = 0; |
---|
| 278 | } |
---|
| 279 | |
---|
| 280 | void SourcesList::SwapSources( SourceRecord *&rec_one, SourceRecord *&rec_two ) |
---|
| 281 | { |
---|
| 282 | list<SourceRecord *>::iterator rec_p; |
---|
| 283 | list<SourceRecord *>::iterator rec_n; |
---|
| 284 | |
---|
| 285 | rec_p = find( SourceRecords.begin(), SourceRecords.end(), rec_one ); |
---|
| 286 | rec_n = find( SourceRecords.begin(), SourceRecords.end(), rec_two ); |
---|
| 287 | |
---|
| 288 | SourceRecords.insert( rec_p, rec_two ); |
---|
| 289 | SourceRecords.erase( rec_n ); |
---|
| 290 | } |
---|
| 291 | |
---|
| 292 | bool SourcesList::UpdateSources() |
---|
| 293 | { |
---|
| 294 | list<string> filenames; |
---|
| 295 | for (list<SourceRecord *>::iterator it = SourceRecords.begin(); |
---|
| 296 | it != SourceRecords.end(); it++) { |
---|
| 297 | if ((*it)->SourceFile == "") |
---|
| 298 | continue; |
---|
| 299 | filenames.push_front((*it)->SourceFile); |
---|
| 300 | } |
---|
| 301 | filenames.sort(); |
---|
| 302 | filenames.unique(); |
---|
| 303 | |
---|
| 304 | for (list<string>::iterator fi = filenames.begin(); |
---|
| 305 | fi != filenames.end(); fi++) { |
---|
| 306 | ofstream ofs((*fi).c_str(), ios::out); |
---|
| 307 | if (!ofs != 0) |
---|
| 308 | return false; |
---|
| 309 | |
---|
| 310 | for (list<SourceRecord *>::iterator it = SourceRecords.begin(); |
---|
| 311 | it != SourceRecords.end(); it++) { |
---|
| 312 | if ((*fi) != (*it)->SourceFile) |
---|
| 313 | continue; |
---|
| 314 | string S; |
---|
| 315 | if (((*it)->Type & Comment) != 0) { |
---|
| 316 | S = (*it)->Comment; |
---|
| 317 | } else if ((*it)->URI.empty() || (*it)->Dist.empty()) { |
---|
| 318 | continue; |
---|
| 319 | } else { |
---|
| 320 | if (((*it)->Type & Disabled) != 0) |
---|
| 321 | S = "# "; |
---|
| 322 | |
---|
| 323 | S += (*it)->GetType() + " "; |
---|
| 324 | |
---|
| 325 | if ((*it)->VendorID.empty() == false) |
---|
| 326 | S += "[" + (*it)->VendorID + "] "; |
---|
| 327 | |
---|
| 328 | S += (*it)->URI + " "; |
---|
| 329 | S += (*it)->Dist + " "; |
---|
| 330 | |
---|
| 331 | for (unsigned int J = 0; J < (*it)->NumSections; J++) |
---|
| 332 | S += (*it)->Sections[J] + " "; |
---|
| 333 | } |
---|
| 334 | ofs << S << endl; |
---|
| 335 | } |
---|
| 336 | ofs.close(); |
---|
| 337 | } |
---|
| 338 | return true; |
---|
| 339 | } |
---|
| 340 | |
---|
| 341 | bool SourcesList::SourceRecord::SetType(string S) |
---|
| 342 | { |
---|
| 343 | if (S == "deb") |
---|
| 344 | Type |= Deb; |
---|
| 345 | else if (S == "deb-src") |
---|
| 346 | Type |= DebSrc; |
---|
| 347 | else if (S == "rpm") |
---|
| 348 | Type |= Rpm; |
---|
| 349 | else if (S == "rpm-src") |
---|
| 350 | Type |= RpmSrc; |
---|
| 351 | else if (S == "rpm-dir") |
---|
| 352 | Type |= RpmDir; |
---|
| 353 | else if (S == "rpm-src-dir") |
---|
| 354 | Type |= RpmSrcDir; |
---|
| 355 | else if (S == "repomd") |
---|
| 356 | Type |= Repomd; |
---|
| 357 | else if (S == "repomd-src") |
---|
| 358 | Type |= RepomdSrc; |
---|
| 359 | else |
---|
| 360 | return false; |
---|
| 361 | cout << S << " settype " << (Type | Repomd) << endl; |
---|
| 362 | return true; |
---|
| 363 | } |
---|
| 364 | |
---|
| 365 | string SourcesList::SourceRecord::GetType() |
---|
| 366 | { |
---|
| 367 | if ((Type & Deb) != 0) |
---|
| 368 | return "deb"; |
---|
| 369 | else if ((Type & DebSrc) != 0) |
---|
| 370 | return "deb-src"; |
---|
| 371 | else if ((Type & Rpm) != 0) |
---|
| 372 | return "rpm"; |
---|
| 373 | else if ((Type & RpmSrc) != 0) |
---|
| 374 | return "rpm-src"; |
---|
| 375 | else if ((Type & RpmDir) != 0) |
---|
| 376 | return "rpm-dir"; |
---|
| 377 | else if ((Type & RpmSrcDir) != 0) |
---|
| 378 | return "rpm-src-dir"; |
---|
| 379 | else if ((Type & Repomd) != 0) |
---|
| 380 | return "repomd"; |
---|
| 381 | else if ((Type & RepomdSrc) != 0) |
---|
| 382 | return "repomd-src"; |
---|
| 383 | cout << "type " << (Type & Repomd) << endl; |
---|
| 384 | return "unknown"; |
---|
| 385 | } |
---|
| 386 | |
---|
| 387 | bool SourcesList::SourceRecord::SetURI(string S) |
---|
| 388 | { |
---|
| 389 | if (S.empty() == true) |
---|
| 390 | return false; |
---|
| 391 | if (S.find(':') == string::npos) |
---|
| 392 | return false; |
---|
| 393 | |
---|
| 394 | S = SubstVar(S, "$(ARCH)", _config->Find("APT::Architecture")); |
---|
| 395 | S = SubstVar(S, "$(VERSION)", _config->Find("APT::DistroVersion")); |
---|
| 396 | URI = S; |
---|
| 397 | |
---|
| 398 | // append a / to the end if one is not already there |
---|
| 399 | if (URI[URI.size() - 1] != '/') |
---|
| 400 | URI += '/'; |
---|
| 401 | |
---|
| 402 | return true; |
---|
| 403 | } |
---|
| 404 | |
---|
| 405 | SourcesList::SourceRecord &SourcesList::SourceRecord:: |
---|
| 406 | operator=(const SourceRecord &rhs) |
---|
| 407 | { |
---|
| 408 | // Needed for a proper deep copy of the record; uses the string operator= to properly copy the strings |
---|
| 409 | Type = rhs.Type; |
---|
| 410 | VendorID = rhs.VendorID; |
---|
| 411 | URI = rhs.URI; |
---|
| 412 | Dist = rhs.Dist; |
---|
| 413 | Sections = new string[rhs.NumSections]; |
---|
| 414 | for (unsigned int I = 0; I < rhs.NumSections; I++) |
---|
| 415 | Sections[I] = rhs.Sections[I]; |
---|
| 416 | NumSections = rhs.NumSections; |
---|
| 417 | Comment = rhs.Comment; |
---|
| 418 | SourceFile = rhs.SourceFile; |
---|
| 419 | |
---|
| 420 | return *this; |
---|
| 421 | } |
---|
| 422 | |
---|
| 423 | SourcesList::VendorRecord *SourcesList::AddVendorNode(VendorRecord &rec) |
---|
| 424 | { |
---|
| 425 | VendorRecord *newrec = new VendorRecord; |
---|
| 426 | *newrec = rec; |
---|
| 427 | VendorRecords.push_back(newrec); |
---|
| 428 | |
---|
| 429 | return newrec; |
---|
| 430 | } |
---|
| 431 | |
---|
| 432 | bool SourcesList::ReadVendors() |
---|
| 433 | { |
---|
| 434 | Configuration Cnf; |
---|
| 435 | |
---|
| 436 | string CnfFile = _config->FindFile("Dir::Etc::vendorlist"); |
---|
| 437 | if (FileExists(CnfFile) == true) |
---|
| 438 | if (ReadConfigFile(Cnf, CnfFile, true) == false) |
---|
| 439 | return false; |
---|
| 440 | |
---|
| 441 | for (list<VendorRecord *>::const_iterator I = VendorRecords.begin(); |
---|
| 442 | I != VendorRecords.end(); I++) |
---|
| 443 | delete *I; |
---|
| 444 | VendorRecords.clear(); |
---|
| 445 | |
---|
| 446 | // Process 'simple-key' type sections |
---|
| 447 | const Configuration::Item *Top = Cnf.Tree("simple-key"); |
---|
| 448 | for (Top = (Top == 0 ? 0 : Top->Child); Top != 0; Top = Top->Next) { |
---|
| 449 | Configuration Block(Top); |
---|
| 450 | VendorRecord Vendor; |
---|
| 451 | |
---|
| 452 | Vendor.VendorID = Top->Tag; |
---|
| 453 | Vendor.FingerPrint = Block.Find("Fingerprint"); |
---|
| 454 | Vendor.Description = Block.Find("Name"); |
---|
| 455 | |
---|
| 456 | char *buffer = new char[Vendor.FingerPrint.length() + 1]; |
---|
| 457 | char *p = buffer;; |
---|
| 458 | for (string::const_iterator I = Vendor.FingerPrint.begin(); |
---|
| 459 | I != Vendor.FingerPrint.end(); I++) { |
---|
| 460 | if (*I != ' ' && *I != '\t') |
---|
| 461 | *p++ = *I; |
---|
| 462 | } |
---|
| 463 | *p = 0; |
---|
| 464 | Vendor.FingerPrint = buffer; |
---|
| 465 | delete[]buffer; |
---|
| 466 | |
---|
| 467 | if (Vendor.FingerPrint.empty() == true || |
---|
| 468 | Vendor.Description.empty() == true) { |
---|
| 469 | _error->Error(_("Vendor block %s is invalid"), |
---|
| 470 | Vendor.VendorID.c_str()); |
---|
| 471 | continue; |
---|
| 472 | } |
---|
| 473 | |
---|
| 474 | AddVendorNode(Vendor); |
---|
| 475 | } |
---|
| 476 | |
---|
| 477 | return !_error->PendingError(); |
---|
| 478 | } |
---|
| 479 | |
---|
| 480 | SourcesList::VendorRecord *SourcesList::AddVendor(string VendorID, |
---|
| 481 | string FingerPrint, |
---|
| 482 | string Description) |
---|
| 483 | { |
---|
| 484 | VendorRecord rec; |
---|
| 485 | rec.VendorID = VendorID; |
---|
| 486 | rec.FingerPrint = FingerPrint; |
---|
| 487 | rec.Description = Description; |
---|
| 488 | return AddVendorNode(rec); |
---|
| 489 | } |
---|
| 490 | |
---|
| 491 | bool SourcesList::UpdateVendors() |
---|
| 492 | { |
---|
| 493 | ofstream ofs(_config->FindFile("Dir::Etc::vendorlist").c_str(), ios::out); |
---|
| 494 | if (!ofs != 0) |
---|
| 495 | return false; |
---|
| 496 | |
---|
| 497 | for (list<VendorRecord *>::iterator it = VendorRecords.begin(); |
---|
| 498 | it != VendorRecords.end(); it++) { |
---|
| 499 | ofs << "simple-key \"" << (*it)->VendorID << "\" {" << endl; |
---|
| 500 | ofs << "\tFingerPrint \"" << (*it)->FingerPrint << "\";" << endl; |
---|
| 501 | ofs << "\tName \"" << (*it)->Description << "\";" << endl; |
---|
| 502 | ofs << "}" << endl; |
---|
| 503 | } |
---|
| 504 | |
---|
| 505 | ofs.close(); |
---|
| 506 | return true; |
---|
| 507 | } |
---|
| 508 | |
---|
| 509 | |
---|
| 510 | void SourcesList::RemoveVendor(VendorRecord *&rec) |
---|
| 511 | { |
---|
| 512 | VendorRecords.remove(rec); |
---|
| 513 | delete rec; |
---|
| 514 | rec = 0; |
---|
| 515 | } |
---|
| 516 | |
---|
| 517 | ostream &operator<<(ostream &os, const SourcesList::SourceRecord &rec) |
---|
| 518 | { |
---|
| 519 | os << "Type: "; |
---|
| 520 | if ((rec.Type & SourcesList::Comment) != 0) |
---|
| 521 | os << "Comment "; |
---|
| 522 | if ((rec.Type & SourcesList::Disabled) != 0) |
---|
| 523 | os << "Disabled "; |
---|
| 524 | if ((rec.Type & SourcesList::Deb) != 0) |
---|
| 525 | os << "Deb"; |
---|
| 526 | if ((rec.Type & SourcesList::DebSrc) != 0) |
---|
| 527 | os << "DebSrc"; |
---|
| 528 | if ((rec.Type & SourcesList::Rpm) != 0) |
---|
| 529 | os << "Rpm"; |
---|
| 530 | if ((rec.Type & SourcesList::RpmSrc) != 0) |
---|
| 531 | os << "RpmSrc"; |
---|
| 532 | if ((rec.Type & SourcesList::RpmDir) != 0) |
---|
| 533 | os << "RpmDir"; |
---|
| 534 | if ((rec.Type & SourcesList::RpmSrcDir) != 0) |
---|
| 535 | os << "RpmSrcDir"; |
---|
| 536 | if ((rec.Type & SourcesList::Repomd) != 0) |
---|
| 537 | os << "Repomd"; |
---|
| 538 | if ((rec.Type & SourcesList::RepomdSrc) != 0) |
---|
| 539 | os << "RepomdSrc"; |
---|
| 540 | os << endl; |
---|
| 541 | os << "SourceFile: " << rec.SourceFile << endl; |
---|
| 542 | os << "VendorID: " << rec.VendorID << endl; |
---|
| 543 | os << "URI: " << rec.URI << endl; |
---|
| 544 | os << "Dist: " << rec.Dist << endl; |
---|
| 545 | os << "Section(s):" << endl; |
---|
| 546 | for (unsigned int J = 0; J < rec.NumSections; J++) { |
---|
| 547 | cout << "\t" << rec.Sections[J] << endl; |
---|
| 548 | } |
---|
| 549 | os << endl; |
---|
| 550 | return os; |
---|
| 551 | } |
---|
| 552 | |
---|
| 553 | ostream &operator<<(ostream &os, const SourcesList::VendorRecord &rec) |
---|
| 554 | { |
---|
| 555 | os << "VendorID: " << rec.VendorID << endl; |
---|
| 556 | os << "FingerPrint: " << rec.FingerPrint << endl; |
---|
| 557 | os << "Description: " << rec.Description << endl; |
---|
| 558 | return os; |
---|
| 559 | } |
---|
| 560 | |
---|
| 561 | // vim:sts=4:sw=4 |
---|