apt  2.2.4
About: Apt (Advanced Package Tool) is a management system for software packages (Debian/Ubuntu). Release series 2.2.
  Fossies Dox: apt-2.2.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

cdrom.cc
Go to the documentation of this file.
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /* ######################################################################
4 
5  CDROM URI method for APT
6 
7  ##################################################################### */
8  /*}}}*/
9 // Include Files /*{{{*/
10 #include <config.h>
11 
12 #include <apt-pkg/cdrom.h>
13 #include <apt-pkg/cdromutl.h>
14 #include <apt-pkg/configuration.h>
15 #include <apt-pkg/error.h>
16 #include <apt-pkg/fileutl.h>
17 #include <apt-pkg/hashes.h>
18 #include <apt-pkg/strutl.h>
19 
20 #include "aptmethod.h"
21 
22 #include <string>
23 #include <vector>
24 #include <sys/stat.h>
25 
26 #include <iostream>
27 #include <apti18n.h>
28  /*}}}*/
29 
30 using namespace std;
31 
32 class CDROMMethod : public aptMethod
33 {
35  bool Debug;
36 
38  string CurrentID;
39  string CDROM;
42 
43  bool IsCorrectCD(URI want, string MountPath, string& NewID);
44  bool AutoDetectAndMount(const URI, string &NewID);
45  virtual bool Fetch(FetchItem *Itm) APT_OVERRIDE;
46  std::string GetID(std::string const &Name);
47  virtual void Exit() APT_OVERRIDE;
48  virtual bool Configuration(std::string Message) APT_OVERRIDE;
49 
50  public:
51 
52  CDROMMethod();
53 };
54 
55 // CDROMMethod::CDROMethod - Constructor /*{{{*/
56 // ---------------------------------------------------------------------
57 /* */
62  Debug(false),
64 {
65 }
66  /*}}}*/
67 // CDROMMethod::Exit - Unmount the disc if necessary /*{{{*/
68 // ---------------------------------------------------------------------
69 /* */
71 {
72  if (MountedByApt == true)
74 }
75  /*}}}*/
76 // CDROMMethod::GetID - Search the database for a matching string /*{{{*/
77 // ---------------------------------------------------------------------
78 /* */
79 std::string CDROMMethod::GetID(std::string const &Name)
80 {
81  // Search for an ID
82  const Configuration::Item *Top = Database.Tree("CD");
83  if (Top != 0)
84  Top = Top->Child;
85 
86  for (; Top != 0;)
87  {
88  if (Top->Value == Name)
89  return Top->Tag;
90 
91  Top = Top->Next;
92  }
93  return string();
94 }
95  /*}}}*/
96 // CDROMMethod::AutoDetectAndMount /*{{{*/
97 // ---------------------------------------------------------------------
98 /* Modifies class variable CDROM to the mountpoint */
99 bool CDROMMethod::AutoDetectAndMount(const URI Get, string &NewID)
100 {
101  vector<struct CdromDevice> v = UdevCdroms.Scan();
102 
103  // first check if its mounted somewhere already
104  for (unsigned int i=0; i < v.size(); i++)
105  {
106  if (v[i].Mounted)
107  {
108  if (Debug)
109  clog << "Checking mounted cdrom device " << v[i].DeviceName << endl;
110  if (IsCorrectCD(Get, v[i].MountPath, NewID))
111  {
112  CDROM = v[i].MountPath;
113  return true;
114  }
115  }
116  }
117 
118  // we are not supposed to mount, exit
119  if (_config->FindB("APT::CDROM::NoMount",false) == true)
120  return false;
121 
122  // check if we have the mount point
123  string AptMountPoint = _config->FindDir("Dir::Media::MountPath");
124  if (!FileExists(AptMountPoint))
125  mkdir(AptMountPoint.c_str(), 0750);
126 
127  // now try mounting
128  for (unsigned int i=0; i < v.size(); i++)
129  {
130  if (!v[i].Mounted)
131  {
132  if(MountCdrom(AptMountPoint, v[i].DeviceName))
133  {
134  if (IsCorrectCD(Get, AptMountPoint, NewID))
135  {
136  MountedByApt = true;
137  CDROM = AptMountPoint;
138  return true;
139  } else {
140  UnmountCdrom(AptMountPoint);
141  }
142  }
143  }
144  }
145 
146  return false;
147 }
148  /*}}}*/
149 // CDROMMethod::IsCorrectCD /*{{{*/
150 // ---------------------------------------------------------------------
151 /* */
152 bool CDROMMethod::IsCorrectCD(URI want, string MountPath, string& NewID)
153 {
154  for (unsigned int Version = 2; Version != 0; Version--)
155  {
156  if (IdentCdrom(MountPath,NewID,Version) == false)
157  return false;
158 
159  if (Debug)
160  clog << "ID " << Version << " " << NewID << endl;
161 
162  // A hit
163  if (Database.Find("CD::" + NewID) == want.Host)
164  return true;
165  }
166 
167  return false;
168 }
169  /*}}}*/
170 // CDROMMethod::Fetch - Fetch a file /*{{{*/
171 // ---------------------------------------------------------------------
172 /* */
174 {
175  FetchResult Res;
176 
177  URI Get(Itm->Uri);
178  std::string const File = DecodeSendURI(Get.Path);
179  Debug = DebugEnabled();
180 
181  if (Debug)
182  clog << "CDROMMethod::Fetch " << Itm->Uri << endl;
183 
184  /* All IMS queries are returned as a hit, CDROMs are readonly so
185  time stamps never change */
186  if (Itm->LastModified != 0)
187  {
188  Res.LastModified = Itm->LastModified;
189  Res.IMSHit = true;
190  Res.Filename = Itm->DestFile;
191  URIDone(Res);
192  return true;
193  }
194 
195  // Load the database
196  if (DatabaseLoaded == false)
197  {
198  // Read the database
199  string DFile = _config->FindFile("Dir::State::cdroms");
200  if (FileExists(DFile) == true)
201  {
202  if (ReadConfigFile(Database,DFile) == false)
203  return _error->Error(_("Unable to read the cdrom database %s"),
204  DFile.c_str());
205  }
206  DatabaseLoaded = true;
207  }
208 
209  // All non IMS queries for package files fail.
210  if (Itm->IndexFile == true || GetID(Get.Host).empty() == true)
211  {
212  Fail(_("Please use apt-cdrom to make this CD-ROM recognized by APT."
213  " apt-get update cannot be used to add new CD-ROMs"));
214  return true;
215  }
216 
217  // We already have a CD inserted, but it is the wrong one
218  if (CurrentID.empty() == false &&
219  CurrentID != "FAIL" &&
220  Database.Find("CD::" + CurrentID) != Get.Host)
221  {
222  Fail(_("Wrong CD-ROM"),true);
223  return true;
224  }
225 
226  bool const AutoDetect = ConfigFindB("AutoDetect", true);
227  CDROM = _config->FindDir("Acquire::cdrom::mount");
228  if (Debug)
229  clog << "Looking for CDROM at " << CDROM << endl;
230 
231  if (CDROM[0] == '.')
232  CDROM= SafeGetCWD() + '/' + CDROM;
233 
234  string NewID;
235  while (CurrentID.empty() == true)
236  {
237  if (AutoDetect)
238  AutoDetectAndMount(Get, NewID);
239 
240  if(!IsMounted(CDROM))
242 
243  if (IsCorrectCD(Get, CDROM, NewID))
244  break;
245 
246  // I suppose this should prompt somehow?
247  if (_config->FindB("APT::CDROM::NoMount",false) == false &&
248  UnmountCdrom(CDROM) == false)
249  return _error->Error(_("Unable to unmount the CD-ROM in %s, it may still be in use."),
250  CDROM.c_str());
251  if (MediaFail(Get.Host,CDROM) == false)
252  {
253  CurrentID = "FAIL";
254  return _error->Error(_("Disk not found."));
255  }
256  }
257 
258  // Found a CD
259  Res.Filename = CDROM + File;
260  struct stat Buf;
261  if (stat(Res.Filename.c_str(),&Buf) != 0)
262  return _error->Error(_("File not found"));
263 
264  URIStart(Res);
265  if (NewID.empty() == false)
266  CurrentID = NewID;
267  Res.LastModified = Buf.st_mtime;
268  Res.Size = Buf.st_size;
269 
270  Hashes Hash(Itm->ExpectedHashes);
272  Hash.AddFD(Fd);
273  Res.TakeHashes(Hash);
274 
275  URIDone(Res);
276  return true;
277 }
278  /*}}}*/
279 bool CDROMMethod::Configuration(std::string Message) /*{{{*/
280 {
281  _config->CndSet("Binary::cdrom::Debug::NoDropPrivs", true);
282  return aptMethod::Configuration(Message);
283 }
284  /*}}}*/
285 
286 int main()
287 {
288  return CDROMMethod().Run();
289 }
return false
bool MountCdrom(string Path, string DeviceName)
Definition: cdromutl.cc:130
bool IdentCdrom(string CD, string &Res, unsigned int Version)
Definition: cdromutl.cc:182
bool UnmountCdrom(string Path)
Definition: cdromutl.cc:75
bool IsMounted(string &Path)
Definition: cdromutl.cc:44
Provide access methods to various configuration settings.
virtual bool Fetch(FetchItem *Itm) APT_OVERRIDE
Definition: cdrom.cc:173
std::string GetID(std::string const &Name)
Definition: cdrom.cc:79
::Configuration Database
Definition: cdrom.cc:37
virtual void Exit() APT_OVERRIDE
Definition: cdrom.cc:70
string CDROM
Definition: cdrom.cc:39
virtual bool Configuration(std::string Message) APT_OVERRIDE
Definition: cdrom.cc:279
bool AutoDetectAndMount(const URI, string &NewID)
Definition: cdrom.cc:99
string CurrentID
Definition: cdrom.cc:38
CDROMMethod()
Definition: cdrom.cc:58
pkgUdevCdromDevices UdevCdroms
Definition: cdrom.cc:41
bool IsCorrectCD(URI want, string MountPath, string &NewID)
Definition: cdrom.cc:152
bool Debug
Definition: cdrom.cc:35
bool DatabaseLoaded
Definition: cdrom.cc:34
bool MountedByApt
Definition: cdrom.cc:40
Definition: fileutl.h:39
@ ReadOnly
Definition: fileutl.h:59
Definition: hashes.h:170
bool AddFD(int const Fd, unsigned long long Size=0)
Definition: hashes.cc:362
Definition: strutl.h:193
std::string Path
Definition: strutl.h:202
std::string Host
Definition: strutl.h:201
bool DebugEnabled() const
Definition: aptmethod.h:409
bool ConfigFindB(char const *const postfix, bool const defValue) const APT_NONNULL(2)
Definition: aptmethod.h:441
virtual bool Configuration(std::string Message) APT_OVERRIDE
Definition: aptmethod.h:59
static std::string DecodeSendURI(std::string const &part)
Definition: aptmethod.h:493
struct stat Buf
Definition: aptmethod.h:464
virtual void URIStart(FetchResult &Res)
bool MediaFail(std::string Required, std::string Drive)
void Fail(bool Transient=false)
virtual void URIDone(FetchResult &Res, FetchResult *Alt=0)
std::vector< CdromDevice > Scan()
Definition: cdrom.cc:920
bool ReadConfigFile(Configuration &Conf, const string &FName, bool const &AsSectional, unsigned const &Depth)
Configuration * _config
bool FileExists(string File)
Definition: fileutl.cc:326
string SafeGetCWD()
Definition: fileutl.cc:637
#define APT_OVERRIDE
Definition: macros.h:111
int main()
Definition: cdrom.cc:286
HashStringList ExpectedHashes
unsigned long long Size
void TakeHashes(class Hashes &Hash)