mirror.cc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: mirror.cc,v 1.59 2004/05/08 19:42:35 mdz Exp $
  4. /* ######################################################################
  5. Mirror Aquire Method - This is the Mirror aquire method for APT.
  6. ##################################################################### */
  7. /*}}}*/
  8. // Include Files /*{{{*/
  9. #include <apt-pkg/fileutl.h>
  10. #include <apt-pkg/acquire-method.h>
  11. #include <apt-pkg/acquire-item.h>
  12. #include <apt-pkg/acquire.h>
  13. #include <apt-pkg/error.h>
  14. #include <apt-pkg/hashes.h>
  15. #include <fstream>
  16. #include <iostream>
  17. #include <stdarg.h>
  18. using namespace std;
  19. #include "mirror.h"
  20. #include "http.h"
  21. /*}}}*/
  22. /*
  23. * TODO:
  24. * - better method to download than having a pkgAcquire interface here
  25. * - support keeping the mirror file around (evil listclearer strikes again)
  26. * -> /var/lib/apt/mirrors dir? how to cleanup? by time?
  27. * - provide some TTL time until the mirror file is get again (1h? 6h?)
  28. * - deal with runing as non-root (we can't write to the lists dir then)
  29. * - testing :)
  30. */
  31. MirrorMethod::MirrorMethod()
  32. : HttpMethod(), HasMirrorFile(false)
  33. {
  34. #if 0
  35. HasMirrorFile=true;
  36. BaseUri="mirror://people.ubuntu.com/~mvo/mirror/mirrors";
  37. MirrorFile="/var/lib/apt/lists/people.ubuntu.com_%7emvo_apt_mirror_mirrors";
  38. Mirror="http://de.archive.ubuntu.com/ubuntu/";
  39. #endif
  40. };
  41. // HttpMethod::Configuration - Handle a configuration message /*{{{*/
  42. // ---------------------------------------------------------------------
  43. /* We stash the desired pipeline depth */
  44. bool MirrorMethod::Configuration(string Message)
  45. {
  46. if (pkgAcqMethod::Configuration(Message) == false)
  47. return false;
  48. Debug = _config->FindB("Debug::Acquire::mirror",false);
  49. return true;
  50. }
  51. /*}}}*/
  52. bool MirrorMethod::GetMirrorFile(string uri)
  53. {
  54. string Marker = _config->Find("Acquire::Mirror::MagicMarker","///");
  55. BaseUri = uri.substr(0,uri.find(Marker));
  56. string fetch = BaseUri;
  57. fetch.replace(0,strlen("mirror://"),"http://");
  58. MirrorFile = _config->FindDir("Dir::State::lists") + URItoFileName(BaseUri);
  59. if(Debug)
  60. {
  61. cerr << "base-uri: " << BaseUri << endl;
  62. cerr << "mirror-file: " << MirrorFile << endl;
  63. }
  64. // FIXME: fetch it with curl
  65. pkgAcquire Fetcher;
  66. new pkgAcqFile(&Fetcher, fetch, "", 0, "", "", "", MirrorFile);
  67. bool res = (Fetcher.Run() == pkgAcquire::Continue);
  68. if(res)
  69. HasMirrorFile = true;
  70. Fetcher.Shutdown();
  71. return true;
  72. }
  73. bool MirrorMethod::SelectMirror()
  74. {
  75. ifstream in(MirrorFile.c_str());
  76. getline(in, Mirror);
  77. if(Debug)
  78. cerr << "Using mirror: " << Mirror << endl;
  79. return true;
  80. }
  81. // MirrorMethod::Fetch - Fetch an item /*{{{*/
  82. // ---------------------------------------------------------------------
  83. /* This adds an item to the pipeline. We keep the pipeline at a fixed
  84. depth. */
  85. bool MirrorMethod::Fetch(FetchItem *Itm)
  86. {
  87. // get mirror information
  88. if(!HasMirrorFile)
  89. {
  90. GetMirrorFile(Itm->Uri);
  91. SelectMirror();
  92. }
  93. for (FetchItem *I = Queue; I != 0; I = I->Next)
  94. {
  95. if(I->Uri.find("mirror://") != string::npos)
  96. I->Uri.replace(0,BaseUri.size(),Mirror);
  97. }
  98. // now run the real fetcher
  99. return HttpMethod::Fetch(Itm);
  100. };
  101. void MirrorMethod::Fail(string Err,bool Transient)
  102. {
  103. if(Queue->Uri.find("http://") != string::npos)
  104. Queue->Uri.replace(0,Mirror.size(), BaseUri);
  105. pkgAcqMethod::Fail(Err, Transient);
  106. }
  107. void MirrorMethod::URIStart(FetchResult &Res)
  108. {
  109. if(Queue->Uri.find("http://") != string::npos)
  110. Queue->Uri.replace(0,Mirror.size(), BaseUri);
  111. pkgAcqMethod::URIStart(Res);
  112. }
  113. void MirrorMethod::URIDone(FetchResult &Res,FetchResult *Alt)
  114. {
  115. if(Queue->Uri.find("http://") != string::npos)
  116. Queue->Uri.replace(0,Mirror.size(), BaseUri);
  117. pkgAcqMethod::URIDone(Res, Alt);
  118. }
  119. int main()
  120. {
  121. setlocale(LC_ALL, "");
  122. MirrorMethod Mth;
  123. return Mth.Loop();
  124. }