]> git.saurik.com Git - apt.git/blob - methods/cdrom.cc
Increase ReadMessages buffer. #111914
[apt.git] / methods / cdrom.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: cdrom.cc,v 1.18 2001/05/22 04:01:41 jgg Exp $
4 /* ######################################################################
5
6 CDROM URI method for APT
7
8 ##################################################################### */
9 /*}}}*/
10 // Include Files /*{{{*/
11 #include <apt-pkg/acquire-method.h>
12 #include <apt-pkg/cdromutl.h>
13 #include <apt-pkg/error.h>
14 #include <apt-pkg/configuration.h>
15 #include <apt-pkg/fileutl.h>
16
17 #include <sys/stat.h>
18 #include <unistd.h>
19
20 #include <iostream>
21 /*}}}*/
22
23 using namespace std;
24
25 class CDROMMethod : public pkgAcqMethod
26 {
27 bool DatabaseLoaded;
28 ::Configuration Database;
29 string CurrentID;
30 string CDROM;
31 bool Mounted;
32
33 virtual bool Fetch(FetchItem *Itm);
34 string GetID(string Name);
35 virtual void Exit();
36
37 public:
38
39 CDROMMethod();
40 };
41
42 // CDROMMethod::CDROMethod - Constructor /*{{{*/
43 // ---------------------------------------------------------------------
44 /* */
45 CDROMMethod::CDROMMethod() : pkgAcqMethod("1.0",SingleInstance | LocalOnly |
46 SendConfig | NeedsCleanup |
47 Removable),
48 DatabaseLoaded(false),
49 Mounted(false)
50 {
51 };
52 /*}}}*/
53 // CDROMMethod::Exit - Unmount the disc if necessary /*{{{*/
54 // ---------------------------------------------------------------------
55 /* */
56 void CDROMMethod::Exit()
57 {
58 if (Mounted == true)
59 UnmountCdrom(CDROM);
60 }
61 /*}}}*/
62 // CDROMMethod::GetID - Search the database for a matching string /*{{{*/
63 // ---------------------------------------------------------------------
64 /* */
65 string CDROMMethod::GetID(string Name)
66 {
67 // Search for an ID
68 const Configuration::Item *Top = Database.Tree("CD");
69 if (Top != 0)
70 Top = Top->Child;
71
72 for (; Top != 0;)
73 {
74 if (Top->Value == Name)
75 return Top->Tag;
76
77 Top = Top->Next;
78 }
79 return string();
80 }
81 /*}}}*/
82 // CDROMMethod::Fetch - Fetch a file /*{{{*/
83 // ---------------------------------------------------------------------
84 /* */
85 bool CDROMMethod::Fetch(FetchItem *Itm)
86 {
87 URI Get = Itm->Uri;
88 string File = Get.Path;
89 FetchResult Res;
90
91 bool Debug = _config->FindB("Debug::Acquire::cdrom",false);
92
93 /* All IMS queries are returned as a hit, CDROMs are readonly so
94 time stamps never change */
95 if (Itm->LastModified != 0)
96 {
97 Res.LastModified = Itm->LastModified;
98 Res.IMSHit = true;
99 Res.Filename = File;
100 URIDone(Res);
101 return true;
102 }
103
104 // Load the database
105 if (DatabaseLoaded == false)
106 {
107 // Read the database
108 string DFile = _config->FindFile("Dir::State::cdroms");
109 if (FileExists(DFile) == true)
110 {
111 if (ReadConfigFile(Database,DFile) == false)
112 return _error->Error("Unable to read the cdrom database %s",
113 DFile.c_str());
114 }
115 DatabaseLoaded = true;
116 }
117
118 // All non IMS queries for package files fail.
119 if (Itm->IndexFile == true || GetID(Get.Host).empty() == true)
120 {
121 Fail("Please use apt-cdrom to make this CD recognized by APT."
122 " apt-get update cannot be used to add new CDs");
123 return true;
124 }
125
126 // We already have a CD inserted, but it is the wrong one
127 if (CurrentID.empty() == false && Database.Find("CD::" + CurrentID) != Get.Host)
128 {
129 Fail("Wrong CD",true);
130 return true;
131 }
132
133 CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
134 if (CDROM[0] == '.')
135 CDROM= SafeGetCWD() + '/' + CDROM;
136 string NewID;
137 while (CurrentID.empty() == true)
138 {
139 bool Hit = false;
140 for (unsigned int Version = 2; Version != 0; Version--)
141 {
142 if (IdentCdrom(CDROM,NewID,Version) == false)
143 return false;
144
145 if (Debug == true)
146 clog << "ID " << Version << " " << NewID << endl;
147
148 // A hit
149 if (Database.Find("CD::" + NewID) == Get.Host)
150 {
151 Hit = true;
152 break;
153 }
154 }
155
156 if (Hit == true)
157 break;
158
159 // I suppose this should prompt somehow?
160 if (UnmountCdrom(CDROM) == false)
161 return _error->Error("Unable to unmount the CD-ROM in %s, it may still be in use.",
162 CDROM.c_str());
163 if (MediaFail(Get.Host,CDROM) == false)
164 {
165 CurrentID = "FAIL";
166 Fail("Wrong CD",true);
167 return true;
168 }
169
170 MountCdrom(CDROM);
171 Mounted = true;
172 }
173
174 // Found a CD
175 Res.Filename = CDROM + File;
176 struct stat Buf;
177 if (stat(Res.Filename.c_str(),&Buf) != 0)
178 return _error->Error("File not found");
179
180 if (NewID.empty() == false)
181 CurrentID = NewID;
182 Res.LastModified = Buf.st_mtime;
183 Res.Size = Buf.st_size;
184 URIDone(Res);
185 return true;
186 }
187 /*}}}*/
188
189 int main()
190 {
191 CDROMMethod Mth;
192 return Mth.Run();
193 }