1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
|
// cdrom.cc. Cdrom-specific routines for vold
// (c) David A. van Leeuwen, 1996, 1997
#include <unistd.h> // lseek, read. etc
#include <fcntl.h> // O_RDONLY etc.
#include <string.h> // old strings
#include <sys/mount.h> // mount, umount
#include <sys/stat.h> // mkdir
#include <sys/ioctl.h> // ioctls
#include <linux/iso_fs.h> // isofs constants
#include <linux/cdrom.h> // old ioctls for cdrom
//#include <linux/ucdrom.h> // new ioctls for cdrom
//#include <linux/fs.h>
#include <fstream.h> // c++ file i/o
#include <strstream.h> // c++ string i/o
#include <String.h> // c++ strings
#include "vold.h"
String vol_regex ="^.*[^ ]"; // everythink upto last non-blank
int convert_blanks_to_underscores = 0;
extern int debug; // defined in vold
int cdrom_count=0;
void mount_isofs(mel * entry, int fd)
{
struct iso_primary_descriptor * vdp;
char buf[ISOFS_BLOCK_SIZE];
Mntent * mep = entry->mep;
for(int sector=16; sector < 100; sector++) {
lseek(fd, sector*ISOFS_BLOCK_SIZE, SEEK_SET);
read(fd, buf, ISOFS_BLOCK_SIZE);
vdp = (struct iso_primary_descriptor *) &buf;
if (!strncmp(vdp->id, ISO_STANDARD_ID, sizeof vdp->id)) {
/* found an iso-cdrom */
String volume_id = String(vdp->volume_id,32).at(Regex(vol_regex));
if (volume_id != "") {
if (volume_id.matches(Regex("^[A-Z_0-9]+$")))
volume_id.downcase();
} else {
ostrstream o;
o << "cdrom" << cdrom_count; // make up some name
// why aren't String and ostrstream compatible?
volume_id = String(o.str(), o.pcount());
}
if (convert_blanks_to_underscores)
volume_id.gsub(" ", "_");
String path = mep->dir + "/" + volume_id;
if (debug>0) cerr << "making " << path << "\n";
if (mkdir(path, 0755) < 0) perror("mkdir");
if (mount(mep->fsname, path, mep->type,
MS_MGC_VAL | MS_RDONLY | MS_NODEV, NULL) < 0)
perror("mount");
else {
entry->dir = path;
entry->mounted = is_mounted;
add_entry_mtab(entry);
if (debug>0)
cerr << "CDrom `" << volume_id << "' mounted\n";
cdrom_count++;
ioctl(fd, CDROMEJECT_SW, 0); // no auto-ejects!
}
break;
}
}
}
int cdrom_media_changed(int fd)
{
int r=ioctl(fd, CDROM_MEDIA_CHANGED);
if (debug) cout << "media changed " << r << endl;
return r;
}
void check_isofs(mel * i)
{
int fd = open(i->mep->fsname, O_RDONLY | O_NONBLOCK);
if (fd>=0) {
int s=ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
if (debug) cout << "Drive status " << s << endl;
if (i->mounted==un_mounted && s == CDS_DISC_OK &&
cdrom_media_changed(fd))
i->mounted=not_mounted;
if (i->mounted==not_mounted) {
s = ioctl(fd, CDROM_DISC_STATUS);
if (s == CDS_DATA_1)
mount_isofs(i, fd);
}
}
close(fd);
}
void after_unmount_isofs(mel * entry, int eject)
{
cdrom_count--;
if (eject) {
int cdfd = open(entry->mep->fsname, O_RDONLY | O_NONBLOCK);
ioctl(cdfd, CDROMEJECT);
close(cdfd);
}
}
//
// local Variables:
// c-file-style: "K&R"
// comment-column: 40
// compile-command: "g++ -g -c cdrom.cc"
// End:
//
|