summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mdk-stage1/Makefile2
-rw-r--r--mdk-stage1/disk.c24
-rw-r--r--mdk-stage1/lomount.c170
-rw-r--r--mdk-stage1/lomount.h21
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