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