summaryrefslogtreecommitdiffstats
path: root/sbin/mount_cd9660
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1997-04-29 15:56:40 +0000
committerjoerg <joerg@FreeBSD.org>1997-04-29 15:56:40 +0000
commitaae566870b75a1750d60935043266ae63691a1b4 (patch)
tree3cecdd2daa4a6dc3d33bd1dcb2edb0cbbe5dba7a /sbin/mount_cd9660
parent57e93106aa9f89b04e44d5b1042cfae84541c5d2 (diff)
downloadFreeBSD-src-aae566870b75a1750d60935043266ae63691a1b4.zip
FreeBSD-src-aae566870b75a1750d60935043266ae63691a1b4.tar.gz
Userland part of ISO9660 multi-session support. mount_cd9660(8) will
now by default mount the last data track (thus last session), as opposed to the very first session it has been mounting previously. This is consistent with the ISO9660 multi-session idea, and the way other operating systems are working. There's support to mount arbitrary sessions using the -s option. This way, you can simulate multi-session CDs on something like vn devices that don't support CDIO* ioctl commands. You can also force the historic behaviour with mount -t cd9660 -o -s=0 /dev/cd0a /cdrom
Diffstat (limited to 'sbin/mount_cd9660')
-rw-r--r--sbin/mount_cd9660/mount_cd9660.823
-rw-r--r--sbin/mount_cd9660/mount_cd9660.c91
2 files changed, 103 insertions, 11 deletions
diff --git a/sbin/mount_cd9660/mount_cd9660.8 b/sbin/mount_cd9660/mount_cd9660.8
index 262bbc1..2e0e661 100644
--- a/sbin/mount_cd9660/mount_cd9660.8
+++ b/sbin/mount_cd9660/mount_cd9660.8
@@ -42,8 +42,9 @@
.Nd mount an ISO-9660 filesystem
.Sh SYNOPSIS
.Nm mount_cd9660
-.Op Fl egr
+.Op Fl egrv
.Op Fl o Ar options
+.Op Fl s startsector
.Ar special | node
.Sh DESCRIPTION
The
@@ -75,11 +76,31 @@ See the
man page for possible options and their meanings.
.It Fl r
Do not use any Rockridge extensions included in the filesystem.
+.It Fl s Ar startsector
+Start the filesystem at
+.Ar startsector .
+Normally, if the underlying device is a CD-ROM drive,
+.Nm
+will try to figure out the last track from the CD-ROM containing
+data, and start the filesystem there. If the device is not a CD-ROM,
+or the table of contents cannot be examined, the filesystem will be
+started at sector 0. This option can be used to override the behaviour.
+Note that
+.Ar startsector
+is measured in CD-ROM blocks, with 2048 bytes each. This is the same
+as for example the
+.Cm info
+command of
+.Xr cdcontrol 8
+is printing.
+.It Fl v
+Be verbose about the starting sector decisions made.
.El
.Sh SEE ALSO
.Xr mount 2 ,
.Xr unmount 2 ,
.Xr fstab 5 ,
+.Xr cdcontrol 8 ,
.Xr mount 8
.Sh BUGS
POSIX device node mapping is currently not supported.
diff --git a/sbin/mount_cd9660/mount_cd9660.c b/sbin/mount_cd9660/mount_cd9660.c
index 23ccd0e..a5b0cc0 100644
--- a/sbin/mount_cd9660/mount_cd9660.c
+++ b/sbin/mount_cd9660/mount_cd9660.c
@@ -49,9 +49,11 @@ static char copyright[] =
static char sccsid[] = "@(#)mount_cd9660.c 8.7 (Berkeley) 5/1/95";
*/
static const char rcsid[] =
- "$Id: mount_cd9660.c,v 1.10 1997/03/11 12:29:02 peter Exp $";
+ "$Id: mount_cd9660.c,v 1.11 1997/03/29 03:32:35 imp Exp $";
#endif /* not lint */
+#include <sys/cdio.h>
+#include <sys/file.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/../isofs/cd9660/cd9660_mount.h>
@@ -74,21 +76,22 @@ struct mntopt mopts[] = {
{ NULL }
};
-void usage __P((void));
+int get_ssector(const char *dev);
+void usage(void);
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char **argv)
{
struct iso_args args;
int ch, mntflags, opts;
char *dev, *dir;
struct vfsconf vfc;
- int error;
+ int error, verbose;
- mntflags = opts = 0;
- while ((ch = getopt(argc, argv, "ego:r")) != -1)
+ mntflags = opts = verbose = 0;
+ memset(&args, 0, sizeof args);
+ args.ssector = -1;
+ while ((ch = getopt(argc, argv, "ego:rs:v")) != -1)
switch (ch) {
case 'e':
opts |= ISOFSMNT_EXTATT;
@@ -102,6 +105,12 @@ main(argc, argv)
case 'r':
opts |= ISOFSMNT_NORRIP;
break;
+ case 's':
+ args.ssector = atoi(optarg);
+ break;
+ case 'v':
+ verbose++;
+ break;
case '?':
default:
usage();
@@ -125,6 +134,26 @@ main(argc, argv)
args.export.ex_root = DEFAULT_ROOTUID;
args.flags = opts;
+ if (args.ssector == -1) {
+ /*
+ * The start of the session has not been specified on
+ * the command line. If we can successfully read the
+ * TOC of a CD-ROM, use the last data track we find.
+ * Otherwise, just use 0, in order to mount the very
+ * first session. This is compatible with the
+ * historic behaviour of mount_cd9660(8). If the user
+ * has specified -s <ssector> above, we don't get here
+ * and leave the user's will.
+ */
+ if ((args.ssector = get_ssector(dev)) == -1) {
+ if (verbose)
+ printf("could not determine starting sector, "
+ "using very first session\n");
+ args.ssector = 0;
+ } else if (verbose)
+ printf("using starting sector %d\n", args.ssector);
+ }
+
error = getvfsbyname("cd9660", &vfc);
if (error && vfsisloadable("cd9660")) {
if (vfsload("cd9660"))
@@ -141,9 +170,51 @@ main(argc, argv)
}
void
-usage()
+usage(void)
{
(void)fprintf(stderr,
- "usage: mount_cd9660 [-egrt] [-o options] special node\n");
+ "usage: mount_cd9660 [-egrv] [-o options] [-s startsector] special node\n");
exit(EX_USAGE);
}
+
+int
+get_ssector(const char *dev)
+{
+ struct ioc_toc_header h;
+ struct ioc_read_toc_entry t;
+ struct cd_toc_entry toc_buffer[100];
+ int fd, ntocentries, i;
+
+ if ((fd = open(dev, O_RDONLY)) == -1)
+ return -1;
+ if (ioctl(fd, CDIOREADTOCHEADER, &h) == -1) {
+ close(fd);
+ return -1;
+ }
+
+ ntocentries = h.ending_track - h.starting_track + 1;
+ if (ntocentries > 100) {
+ /* unreasonable, only 100 allowed */
+ close(fd);
+ return -1;
+ }
+ t.address_format = CD_LBA_FORMAT;
+ t.starting_track = 0;
+ t.data_len = ntocentries * sizeof(struct cd_toc_entry);
+ t.data = toc_buffer;
+
+ if (ioctl(fd, CDIOREADTOCENTRYS, (char *) &t) == -1) {
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
+ for (i = ntocentries - 1; i >= 0; i--)
+ if ((toc_buffer[i].control & 4) != 0)
+ /* found a data track */
+ break;
+ if (i < 0)
+ return -1;
+
+ return ntohl(toc_buffer[i].addr.lba);
+}
OpenPOWER on IntegriCloud