diff --git a/installer/kayak-menu b/installer/kayak-menu index d571a32..1d23e27 100755 --- a/installer/kayak-menu +++ b/installer/kayak-menu @@ -45,6 +45,7 @@ if [ $debug -eq 0 ]; then echo echo "Scanning for media..." mkdir /.cdrom + mkdir /.usbdrive /kayak/bin/mount_media $VERSION fi diff --git a/src/mount_media.c b/src/mount_media.c index 8ee8d38..1e03050 100644 --- a/src/mount_media.c +++ b/src/mount_media.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,7 @@ #define HSFS_OPTS "ro" #define UFS_OPTS "ro,nologging,noatime" +#define PCFS_OPTS "ro" static boolean_t mounted = B_FALSE; static boolean_t verbose = B_FALSE; @@ -76,13 +78,106 @@ check_volsetid(const char *volid) return (ret); } +/* + * Mounts and tests supplied path to iso file for supplied volid + * Returns 0 if volid found, -1 otherwise. + */ +static int +test_iso_file(const char *path, const char *volid) +{ + int ret = -1; + char opts[MAX_MNTOPT_STR]; + + strcpy(opts, HSFS_OPTS); + if (verbose) + printf("%s: mount hsfs (iso)\n", path); + if (mount(path, "/.cdrom", MS_RDONLY | MS_OPTIONSTR, + "hsfs", NULL, 0, opts, sizeof (opts)) != 0) + return (ret); /* mount failed */ + + /* Mounted, see if it's the image we're looking for, unmount if not */ + ret = check_volsetid(volid); + if (ret != 0) { + if (verbose) + printf("%s: wrong ID, unmounting\n", path); + (void) umount("/.cdrom"); + } + return (ret); +} + +/* + * Attempt to mount the path as pcfs. Then walk the file tree + * and look for any iso files. + * For every one found, mount it and check for volid + * and umount if failed. return's 0 if the right iso is found + * and -1 otherwise. + */ +static int +check_for_iso(const char *path, const char *volid) +{ + int ret = -1; + char opts[MAX_MNTOPT_STR]; + + strcpy(opts, PCFS_OPTS); + if (verbose) + printf("%s: mount PCFS\n", path); + if (mount(path, "/.usbdrive", MS_RDONLY | MS_OPTIONSTR, + "pcfs", NULL, 0, opts, sizeof (opts)) != 0) { + return (ret); /* mount failed */ + } else { + /* mount succeeded, look for iso files */ + FTS *tree; + FTSENT *f; + char *pathtowalk[] = { "/.usbdrive", NULL }; + + tree = fts_open(pathtowalk, FTS_LOGICAL | FTS_NOSTAT, NULL); + if (tree == 0) { + if (verbose) + printf("%s: fts_open failed\n", path); + return (ret); /* traverse failed */ + } + + while ((f = fts_read(tree)) != 0) { + if (f->fts_info != FTS_F) /* regular file */ + continue; + + if (f->fts_namelen > 4 && + (strcasecmp(".iso", + f->fts_name + f->fts_namelen - 4) == 0)) { + if (verbose) + printf("iso found: %s\n", f->fts_name); + + ret = test_iso_file(f->fts_path, volid); + if (ret == 0) + break; /* correct iso found */ + } + } + + if (fts_close(tree) < 0) + if (verbose) + printf("error closing tree\n"); + + if (ret != 0) { + if (verbose) + printf("%s: wrong volume, unmounting\n", path); + (void) umount("/.usbdrive"); + /* if ret==0 we do not unmount the usbdrive mount */ + } + } + + return (ret); +} + static int mount_image(const char *path, const char *volid) { int ret = -1; char opts[MAX_MNTOPT_STR]; - /* First try mounting it as hsfs; if that fails, try ufs */ + /* + * First try mounting it as hsfs; if that fails, try ufs; if + * that fails try check_for_iso() + */ strcpy(opts, HSFS_OPTS); if (verbose) printf("%s: mount HSFS\n", path); @@ -93,7 +188,8 @@ mount_image(const char *path, const char *volid) printf("%s: mount UFS\n", path); if (mount(path, "/.cdrom", MS_OPTIONSTR, "ufs", NULL, 0, opts, sizeof (opts)) != 0) - return (ret); + if (check_for_iso(path, volid) != 0) + return (ret); } if (verbose)