diff options
-rw-r--r-- | mdk-stage1/Makefile | 2 | ||||
-rw-r--r-- | mdk-stage1/disk.c | 24 | ||||
-rw-r--r-- | mdk-stage1/lomount.c | 170 | ||||
-rw-r--r-- | mdk-stage1/lomount.h | 21 |
4 files changed, 211 insertions, 6 deletions
diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile index 7ee40bf05..2aeee3990 100644 --- a/mdk-stage1/Makefile +++ b/mdk-stage1/Makefile @@ -80,7 +80,7 @@ STAGE1_NETWORK_LIBS = /usr/lib/libresolv.a #- stage1 itself STAGE1SRC = stage1.c log.c tools.c modules.c probing.c mount.c automatic.c CDROMSRC = cdrom.c -DISKSRC = disk.c +DISKSRC = disk.c lomount.c NETWORKSRC = network.c dns.c nfsmount.c dhcp.c url.c ALLSRC = $(INITSRC) $(STAGE1SRC) $(CDROMSRC) $(DISKSRC) $(NETWORKSRC) diff --git a/mdk-stage1/disk.c b/mdk-stage1/disk.c index b154f8d0b..b092604e4 100644 --- a/mdk-stage1/disk.c +++ b/mdk-stage1/disk.c @@ -25,12 +25,16 @@ #include <string.h> #include <sys/mount.h> #include <dirent.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include "stage1.h" #include "frontend.h" #include "modules.h" #include "probing.h" #include "log.h" #include "mount.h" +#include "lomount.h" #include "disk.h" @@ -69,13 +73,14 @@ static enum return_type try_with_device(char *dev_name) FILE * f; char * parts[50]; char * parts_comments[50]; + struct stat statbuf; int i = 0; enum return_type results; char * choice; if (!(f = fopen("/proc/partitions", "rb")) || !fgets(buf, sizeof(buf), f) || !fgets(buf, sizeof(buf), f)) { log_perror(dev_name); - error_message("Could not read partitions information"); + error_message("Could not read partitions information."); return RETURN_ERROR; } @@ -106,7 +111,7 @@ static enum return_type try_with_device(char *dev_name) return try_with_device(dev_name); } - if (ask_from_entries("Please enter the directory containing the " DISTRIB_NAME " Distribution.", + if (ask_from_entries("Please enter the directory (or ISO image file) containing the " DISTRIB_NAME " Distribution.", questions_location, &answers_location, 24) != RETURN_OK) { umount(disk_own_mount); return try_with_device(dev_name); @@ -117,7 +122,7 @@ static enum return_type try_with_device(char *dev_name) strcat(location_full, answers_location[0]); if (access(location_full, R_OK)) { - error_message("Directory could not be found on partition.\n" + error_message("Directory or ISO image file could not be found on partition.\n" "Here's a short extract of the files in the root of the partition:\n" "%s", list_directory(disk_own_mount)); umount(disk_own_mount); @@ -125,7 +130,16 @@ static enum return_type try_with_device(char *dev_name) } unlink(IMAGE_LOCATION); - symlink(location_full, IMAGE_LOCATION); + + if (!stat(location_full, &statbuf) && !S_ISDIR(statbuf.st_mode)) { + log_message("%s exists and is not a directory, assuming this is an ISO image", location_full); + if (lomount(location_full, IMAGE_LOCATION)) { + error_message("Could not mount ISO image."); + umount(IMAGE_LOCATION); + return try_with_device(dev_name); + } + } else + symlink(location_full, IMAGE_LOCATION); if (IS_SPECIAL_STAGE2 || ramdisk_possible()) { /* RAMDISK install */ @@ -139,7 +153,7 @@ static enum return_type try_with_device(char *dev_name) return try_with_device(dev_name); } if (load_ramdisk() != RETURN_OK) { - error_message("Could not load program into memory"); + error_message("Could not load program into memory."); return try_with_device(dev_name); } } else { diff --git a/mdk-stage1/lomount.c b/mdk-stage1/lomount.c new file mode 100644 index 000000000..7150694d1 --- /dev/null +++ b/mdk-stage1/lomount.c @@ -0,0 +1,170 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 MandrakeSoft + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* This code comes from util-linux-2.10n (mount/lomount.c) + * (this is a simplified version of this code) + */ + +#include <sys/types.h> +#include <sys/mount.h> +#include <sys/ioctl.h> +#include <sys/mount.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include "stage1.h" +#include "frontend.h" +#include "log.h" +#include "mount.h" +#include "modules.h" + +#include "lomount.h" + + +#define LO_NAME_SIZE 64 +#define LO_KEY_SIZE 32 + +struct loop_info +{ + int lo_number; /* ioctl r/o */ + dev_t lo_device; /* ioctl r/o */ + unsigned long lo_inode; /* ioctl r/o */ + dev_t lo_rdevice; /* ioctl r/o */ + int lo_offset; + int lo_encrypt_type; + int lo_encrypt_key_size; /* ioctl w/o */ + int lo_flags; /* ioctl r/o */ + char lo_name[LO_NAME_SIZE]; + unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ + unsigned long lo_init[2]; + char reserved[4]; +}; + +#define LOOP_SET_FD 0x4C00 +#define LOOP_CLR_FD 0x4C01 +#define LOOP_SET_STATUS 0x4C02 +#define LOOP_GET_STATUS 0x4C03 + +int +set_loop (const char *device, const char *file) +{ + struct loop_info loopinfo; + int fd, ffd, mode; + + mode = O_RDONLY; + + if ((ffd = open (file, mode)) < 0) + return 1; + + if ((fd = open (device, mode)) < 0) + return 1; + + memset(&loopinfo, 0, sizeof (loopinfo)); + strncpy(loopinfo.lo_name, file, LO_NAME_SIZE); + loopinfo.lo_name[LO_NAME_SIZE - 1] = 0; + loopinfo.lo_offset = 0; + +#ifdef MCL_FUTURE + /* + * Oh-oh, sensitive data coming up. Better lock into memory to prevent + * passwd etc being swapped out and left somewhere on disk. + */ + + if(mlockall(MCL_CURRENT|MCL_FUTURE)) { + log_message("%s (memlock)\n", strerror(errno)); + log_message("CRITICAL Couldn't lock into memory!\n"); + return 1; + } +#endif + + if (ioctl(fd, LOOP_SET_FD, ffd) < 0) + return 1; + + if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) { + (void) ioctl (fd, LOOP_CLR_FD, 0); + return 1; + } + + close(fd); + close(ffd); + return 0; +} + +int +del_loop (const char *device) +{ + int fd; + + if ((fd = open (device, O_RDONLY)) < 0) + return 1; + + if (ioctl (fd, LOOP_CLR_FD, 0) < 0) + return 1; + + close (fd); + return 0; +} + + +char * loopdev = "/dev/loop3"; /* Ugly. But do I care? */ + +int +lomount(char *loopfile, char *where) +{ + + long int flag; + + flag = MS_MGC_VAL; + flag |= MS_RDONLY; + + if (my_insmod("loop", ANY_DRIVER_TYPE, NULL)) { + log_message("can't lomount without loop.o kernel driver"); + return 1; + } + + if (set_loop(loopdev, loopfile)) { + log_message("set_loop failed on %s (%s)\n", loopdev, strerror(errno)); + return 1; + } + + if (my_mount(loopdev, where, "iso9660")) { + log_message("mount failed: %s\n", strerror(errno)); + del_loop(loopdev); + return 1; + } + + log_message("lomount succeded for %s on %s\n", loopfile, where); + return 0; +} + + +int +loumount() +{ + if (umount(loopdev)) { + log_perror("loumount"); + return 1; + } + + if (del_loop(loopdev)) { + log_perror("del_loop"); + return 1; + } + return 0; +} + + diff --git a/mdk-stage1/lomount.h b/mdk-stage1/lomount.h new file mode 100644 index 000000000..f298fe341 --- /dev/null +++ b/mdk-stage1/lomount.h @@ -0,0 +1,21 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2000 MandrakeSoft + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef LOMOUNT_H +#define LOMOUNT_H + +int lomount(char *loopfile, char *where); +int loumount(); + +#endif |