1 // -*- mode: cpp; mode: fold -*-
3 // $Id: cdrom.cc,v 1.20.2.1 2004/01/16 18:58:50 mdz Exp $
4 /* ######################################################################
6 CDROM URI method for APT
8 ##################################################################### */
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 #include <apt-pkg/hashes.h>
29 struct udev_list_entry
;
31 // libudev dlopen stucture
33 struct udev
* (*udev_new
)(void);
34 int (*udev_enumerate_add_match_property
)(struct udev_enumerate
*udev_enumerate
, const char *property
, const char *value
);
35 int (*udev_enumerate_scan_devices
)(struct udev_enumerate
*udev_enumerate
);
36 struct udev_list_entry
*(*udev_enumerate_get_list_entry
)(struct udev_enumerate
*udev_enumerate
);
37 struct udev_device
*(*udev_device_new_from_syspath
)(struct udev
*udev
, const char *syspath
);
38 struct udev
*(*udev_enumerate_get_udev
)(struct udev_enumerate
*udev_enumerate
);
39 const char *(*udev_list_entry_get_name
)(struct udev_list_entry
*list_entry
);
40 const char *(*udev_device_get_devnode
)(struct udev_device
*udev_device
);
41 struct udev_enumerate
*(*udev_enumerate_new
) (struct udev
*udev
);
42 struct udev_list_entry
*(*udev_list_entry_get_next
)(struct udev_list_entry
*list_entry
);
45 class CDROMMethod
: public pkgAcqMethod
48 ::Configuration Database
;
52 vector
<string
> CdromDevices
;
54 virtual bool Fetch(FetchItem
*Itm
);
55 string
GetID(string Name
);
63 // CDROMMethod::CDROMethod - Constructor /*{{{*/
64 // ---------------------------------------------------------------------
66 CDROMMethod::CDROMMethod() : pkgAcqMethod("1.0",SingleInstance
| LocalOnly
|
67 SendConfig
| NeedsCleanup
|
69 DatabaseLoaded(false),
72 // see if we can get libudev
73 void *h
= dlopen("libudev.so.0", RTLD_LAZY
);
75 // the pointers for the udev struct
77 p
.udev_new
= (udev
* (*)(void)) dlsym(h
, "udev_new");
78 p
.udev_enumerate_add_match_property
= (int (*)(udev_enumerate
*, const char*, const char*))dlsym(h
, "udev_enumerate_add_match_property");
79 p
.udev_enumerate_scan_devices
= (int (*)(udev_enumerate
*))dlsym(h
, "udev_enumerate_scan_devices");
80 p
.udev_enumerate_get_list_entry
= (udev_list_entry
* (*)(udev_enumerate
*))dlsym(h
, "udev_enumerate_get_list_entry");
81 p
.udev_device_new_from_syspath
= (udev_device
* (*)(udev
*, const char*))dlsym(h
, "udev_device_new_from_syspath");
82 p
.udev_enumerate_get_udev
= (udev
* (*)(udev_enumerate
*))dlsym(h
, "udev_enumerate_get_udev");
83 p
.udev_list_entry_get_name
= (const char* (*)(udev_list_entry
*))dlsym(h
, "udev_list_entry_get_name");
84 p
.udev_device_get_devnode
= (const char* (*)(udev_device
*))dlsym(h
, "udev_device_get_devnode");
85 p
.udev_enumerate_new
= (udev_enumerate
* (*)(udev
*))dlsym(h
, "udev_enumerate_new");
86 p
.udev_list_entry_get_next
= (udev_list_entry
* (*)(udev_list_entry
*))dlsym(h
, "udev_list_entry_get_next");
87 struct udev_enumerate
*enumerate
;
88 struct udev_list_entry
*l
, *devices
;
89 struct udev
*udev_ctx
;
91 udev_ctx
= p
.udev_new();
92 enumerate
= p
.udev_enumerate_new (udev_ctx
);
93 p
.udev_enumerate_add_match_property(enumerate
, "ID_CDROM", "1");
95 p
.udev_enumerate_scan_devices (enumerate
);
96 devices
= p
.udev_enumerate_get_list_entry (enumerate
);
97 for (l
= devices
; l
!= NULL
; l
= p
.udev_list_entry_get_next (l
))
99 struct udev_device
*udevice
;
100 udevice
= p
.udev_device_new_from_syspath (p
.udev_enumerate_get_udev (enumerate
), p
.udev_list_entry_get_name (l
));
103 const char* devnode
= p
.udev_device_get_devnode(udevice
);
104 //std::cerr << devnode << std::endl;
105 CdromDevices
.push_back(string(devnode
));
112 // CDROMMethod::Exit - Unmount the disc if necessary /*{{{*/
113 // ---------------------------------------------------------------------
115 void CDROMMethod::Exit()
117 if (MountedByApt
== true)
121 // CDROMMethod::GetID - Search the database for a matching string /*{{{*/
122 // ---------------------------------------------------------------------
124 string
CDROMMethod::GetID(string Name
)
127 const Configuration::Item
*Top
= Database
.Tree("CD");
133 if (Top
->Value
== Name
)
141 // CDROMMethod::Fetch - Fetch a file /*{{{*/
142 // ---------------------------------------------------------------------
144 bool CDROMMethod::Fetch(FetchItem
*Itm
)
147 string File
= Get
.Path
;
150 bool Debug
= _config
->FindB("Debug::Acquire::cdrom",false);
152 /* All IMS queries are returned as a hit, CDROMs are readonly so
153 time stamps never change */
154 if (Itm
->LastModified
!= 0)
156 Res
.LastModified
= Itm
->LastModified
;
158 Res
.Filename
= Itm
->DestFile
;
164 if (DatabaseLoaded
== false)
167 string DFile
= _config
->FindFile("Dir::State::cdroms");
168 if (FileExists(DFile
) == true)
170 if (ReadConfigFile(Database
,DFile
) == false)
171 return _error
->Error(_("Unable to read the cdrom database %s"),
174 DatabaseLoaded
= true;
177 // All non IMS queries for package files fail.
178 if (Itm
->IndexFile
== true || GetID(Get
.Host
).empty() == true)
180 Fail(_("Please use apt-cdrom to make this CD-ROM recognized by APT."
181 " apt-get update cannot be used to add new CD-ROMs"));
185 // We already have a CD inserted, but it is the wrong one
186 if (CurrentID
.empty() == false && Database
.Find("CD::" + CurrentID
) != Get
.Host
)
188 Fail(_("Wrong CD-ROM"),true);
192 CDROM
= _config
->FindDir("Acquire::cdrom::mount","/cdrom/");
194 CDROM
= SafeGetCWD() + '/' + CDROM
;
196 while (CurrentID
.empty() == true)
199 if(!IsMounted(CDROM
))
200 MountedByApt
= MountCdrom(CDROM
);
201 for (unsigned int Version
= 2; Version
!= 0; Version
--)
203 if (IdentCdrom(CDROM
,NewID
,Version
) == false)
207 clog
<< "ID " << Version
<< " " << NewID
<< endl
;
210 if (Database
.Find("CD::" + NewID
) == Get
.Host
)
220 // I suppose this should prompt somehow?
221 if (_config
->FindB("APT::CDROM::NoMount",false) == false &&
222 UnmountCdrom(CDROM
) == false)
223 return _error
->Error(_("Unable to unmount the CD-ROM in %s, it may still be in use."),
225 if (MediaFail(Get
.Host
,CDROM
) == false)
228 return _error
->Error(_("Disk not found."));
233 Res
.Filename
= CDROM
+ File
;
235 if (stat(Res
.Filename
.c_str(),&Buf
) != 0)
236 return _error
->Error(_("File not found"));
238 if (NewID
.empty() == false)
240 Res
.LastModified
= Buf
.st_mtime
;
241 Res
.Size
= Buf
.st_size
;
244 FileFd
Fd(Res
.Filename
, FileFd::ReadOnly
);
245 Hash
.AddFD(Fd
.Fd(), Fd
.Size());
246 Res
.TakeHashes(Hash
);
255 setlocale(LC_ALL
, "");