summaryrefslogtreecommitdiffstats
path: root/sbin/mount_cd9660
diff options
context:
space:
mode:
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