summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mdk-stage1/automatic.h1
-rw-r--r--mdk-stage1/disk.c172
-rw-r--r--mdk-stage1/disk.h1
-rw-r--r--mdk-stage1/stage1.c7
-rw-r--r--mdk-stage1/stage1.h2
-rw-r--r--mdk-stage1/tools.c1
6 files changed, 148 insertions, 36 deletions
diff --git a/mdk-stage1/automatic.h b/mdk-stage1/automatic.h
index c2ac0a73d..4b58c0ea8 100644
--- a/mdk-stage1/automatic.h
+++ b/mdk-stage1/automatic.h
@@ -24,6 +24,7 @@
#include "stage1.h"
void grab_automatic_params(char * line);
+char * get_auto_value(char * auto_param);
enum return_type ask_from_list_auto(char *msg, char ** elems, char ** choice, char * auto_param, char ** elems_auto);
enum return_type ask_from_list_comments_auto(char *msg, char ** elems, char ** elems_comments, char ** choice, char * auto_param, char ** elems_auto);
diff --git a/mdk-stage1/disk.c b/mdk-stage1/disk.c
index 375727fdf..32f312862 100644
--- a/mdk-stage1/disk.c
+++ b/mdk-stage1/disk.c
@@ -147,32 +147,17 @@ static char * disk_extract_list_directory(char * direct)
return strdup(tmp);
}
-static enum return_type try_with_device(char *dev_name)
+static int list_partitions(char * dev_name, char ** parts, char ** comments)
{
- char * questions_location[] = { "Directory or ISO image", NULL };
- char * questions_location_auto[] = { "directory", NULL };
- static char ** answers_location = NULL;
- char device_fullname[50];
- char location_full[500];
-
- char * disk_own_mount = "/tmp/hdimage";
-
int major, minor, blocks;
char name[100];
-
- char buf[512];
FILE * f;
- char * parts[50];
- char * parts_comments[50];
- struct stat statbuf;
int i = 0;
- enum return_type results;
- char * choice;
+ char buf[512];
if (!(f = fopen("/proc/partitions", "rb")) || !fgets(buf, sizeof(buf), f) || !fgets(buf, sizeof(buf), f)) {
log_perror(dev_name);
- stg1_error_message("Could not read partitions information.");
- return RETURN_ERROR;
+ return 1;
}
while (fgets(buf, sizeof(buf), f)) {
@@ -181,11 +166,11 @@ static enum return_type try_with_device(char *dev_name)
if ((strstr(name, dev_name) == name) && (blocks > 1) && (name[strlen(dev_name)] != '\0')) {
const char * partition_type = detect_partition_type(name);
parts[i] = strdup(name);
- parts_comments[i] = (char *) malloc(sizeof(char) * 100);
- sprintf(parts_comments[i], "size: %d Mbytes", blocks >> 10);
+ comments[i] = (char *) malloc(sizeof(char) * 100);
+ sprintf(comments[i], "size: %d Mbytes", blocks >> 10);
if (partition_type) {
- strcat(parts_comments[i], ", type: ");
- strcat(parts_comments[i], partition_type);
+ strcat(comments[i], ", type: ");
+ strcat(comments[i], partition_type);
}
i++;
}
@@ -193,6 +178,44 @@ static enum return_type try_with_device(char *dev_name)
parts[i] = NULL;
fclose(f);
+ return 0;
+}
+
+static int try_mount(char * dev, char * location)
+{
+ char device_fullname[50];
+ strcpy(device_fullname, "/dev/");
+ strcat(device_fullname, dev);
+
+ if (my_mount(device_fullname, location, "ext2", 0) == -1 &&
+ my_mount(device_fullname, location, "vfat", 0) == -1 &&
+ my_mount(device_fullname, location, "reiserfs", 0) == -1) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static enum return_type try_with_device(char *dev_name)
+{
+ char * questions_location[] = { "Directory or ISO image", NULL };
+ char * questions_location_auto[] = { "directory", NULL };
+ static char ** answers_location = NULL;
+ char location_full[500];
+
+ char * disk_own_mount = "/tmp/hdimage";
+
+ char * parts[50];
+ char * parts_comments[50];
+ struct stat statbuf;
+ enum return_type results;
+ char * choice;
+
+ if (list_partitions(dev_name, parts, parts_comments)) {
+ stg1_error_message("Could not read partitions information.");
+ return RETURN_ERROR;
+ }
+
if (parts[0] == NULL) {
stg1_error_message("No partitions found.");
return RETURN_ERROR;
@@ -203,12 +226,7 @@ static enum return_type try_with_device(char *dev_name)
if (results != RETURN_OK)
return results;
- strcpy(device_fullname, "/dev/");
- strcat(device_fullname, choice);
-
- if (my_mount(device_fullname, disk_own_mount, "ext2", 0) == -1 &&
- my_mount(device_fullname, disk_own_mount, "vfat", 0) == -1 &&
- my_mount(device_fullname, disk_own_mount, "reiserfs", 0) == -1) {
+ if (try_mount(choice, disk_own_mount)) {
stg1_error_message("I can't find a valid filesystem (tried: ext2, vfat, reiserfs).");
return try_with_device(dev_name);
}
@@ -292,23 +310,33 @@ static enum return_type try_with_device(char *dev_name)
return RETURN_OK;
}
-enum return_type disk_prepare(void)
+static int get_disks(char *** names, char *** models)
{
- char ** medias, ** ptr, ** medias_models;
- char * choice;
- int i, count = 0;
- enum return_type results;
+ char ** ptr;
+ int count = 0;
my_insmod("sd_mod", ANY_DRIVER_TYPE, NULL);
- get_medias(DISK, &medias, &medias_models, BUS_ANY);
+ get_medias(DISK, names, models, BUS_ANY);
- ptr = medias;
+ ptr = *names;
while (ptr && *ptr) {
count++;
ptr++;
}
+ return count;
+}
+
+enum return_type disk_prepare(void)
+{
+ char ** medias, ** medias_models;
+ char * choice;
+ int i;
+ enum return_type results;
+
+ int count = get_disks(&medias, &medias_models);
+
if (count == 0) {
stg1_error_message("No DISK drive found.");
i = ask_insmod(SCSI_ADAPTERS);
@@ -341,3 +369,77 @@ enum return_type disk_prepare(void)
return RETURN_BACK;
return disk_prepare();
}
+
+int
+process_recovery(void)
+{
+ char ** medias, ** medias_models;
+ int count, i;
+
+ log_message("trying the automatic recovery of oem installs");
+
+ count = get_disks(&medias, &medias_models);
+
+ for (i=0; i<count; i++) {
+ char * parts[50];
+ char * parts_comments[50];
+ char ** part, ** comment;
+ log_message("examining disk %s (%s)", medias[i], medias_models[i]);
+
+ if (list_partitions(medias[i], parts, parts_comments)) {
+ log_message("could not read partitions information, bailing out");
+ return 0;
+ }
+
+ part = parts;
+ comment = parts_comments;
+ while (part && *part) {
+ char * disk_own_mount = "/tmp/hdimage";
+ log_message("examining partition %s (%s)", *part, *comment);
+ if (try_mount(*part, disk_own_mount))
+ log_message("couldn't mount it");
+ else {
+ FILE *f;
+ char buf[500];
+ char location[500];
+ strcpy(location, disk_own_mount);
+ strcat(location, "/VERSION");
+ if (!(f = fopen(location, "rb")) || !fgets(buf, sizeof(buf), f)) {
+ log_perror("could not fopen or fgets VERSION");
+ goto examine_next_part;
+ }
+ fclose(f);
+ if (!strstr(buf, VERSION)) {
+ log_message("mismatching VERSION contents");
+ goto examine_next_part;
+ }
+ strcpy(location, disk_own_mount);
+ strcat(location, "/Mandrake/oem_patch.pl");
+ if (access(location, R_OK)) {
+ log_message("Mandrake/oem_patch.pl is not here");
+ goto examine_next_part;
+ }
+
+ log_message("going on with a recovery on disk %s partition %s", medias[i], *part);
+
+ symlink(disk_own_mount, IMAGE_LOCATION);
+ if (load_ramdisk() != RETURN_OK) {
+ log_perror("loading ramdisk failed");
+ umount(disk_own_mount);
+ return 0;
+ }
+
+ umount(disk_own_mount);
+ method_name = strdup("disk");
+ return 1;
+ }
+
+ examine_next_part:
+ umount(disk_own_mount);
+ part++;
+ comment++;
+ }
+ }
+
+ return 0;
+}
diff --git a/mdk-stage1/disk.h b/mdk-stage1/disk.h
index 54213cf68..303cbe138 100644
--- a/mdk-stage1/disk.h
+++ b/mdk-stage1/disk.h
@@ -23,5 +23,6 @@
#define _DISK_H_
enum return_type disk_prepare(void);
+int process_recovery(void);
#endif
diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c
index 553e6a23b..bc3b457e3 100644
--- a/mdk-stage1/stage1.c
+++ b/mdk-stage1/stage1.c
@@ -418,7 +418,12 @@ int main(int argc __attribute__ ((unused)), char **argv __attribute__ ((unused))
"your own risk. Alternatively, you may reboot your system now.");
}
- ret = method_select_and_prepare();
+#ifndef DISABLE_DISK
+ if (IS_RECOVERY && streq(get_auto_value("method"), "cdrom") && process_recovery())
+ ret = RETURN_OK;
+ else
+#endif
+ ret = method_select_and_prepare();
finish_frontend();
close_log();
diff --git a/mdk-stage1/stage1.h b/mdk-stage1/stage1.h
index d32543309..94f99e7c7 100644
--- a/mdk-stage1/stage1.h
+++ b/mdk-stage1/stage1.h
@@ -42,6 +42,7 @@ extern char * stage2_kickstart;
#define MODE_UPDATEMODULES (1 << 11)
#define MODE_NOAUTO (1 << 12)
#define MODE_NETAUTO (1 << 13)
+#define MODE_RECOVERY (1 << 14)
#define IS_TESTING (get_param(MODE_TESTING))
#define IS_EXPERT (get_param(MODE_EXPERT))
@@ -53,6 +54,7 @@ extern char * stage2_kickstart;
#define IS_UPDATEMODULES (get_param(MODE_UPDATEMODULES))
#define IS_NOAUTO (get_param(MODE_NOAUTO))
#define IS_NETAUTO (get_param(MODE_NETAUTO))
+#define IS_RECOVERY (get_param(MODE_RECOVERY))
void fatal_error(char *msg) __attribute__ ((noreturn));
diff --git a/mdk-stage1/tools.c b/mdk-stage1/tools.c
index fd2e556b8..5faad8d88 100644
--- a/mdk-stage1/tools.c
+++ b/mdk-stage1/tools.c
@@ -92,6 +92,7 @@ void process_cmdline(void)
if (!strcmp(name, "rescue")) set_param(MODE_RESCUE);
if (!strcmp(name, "noauto")) set_param(MODE_NOAUTO);
if (!strcmp(name, "netauto")) set_param(MODE_NETAUTO);
+ if (!strcmp(name, "recovery")) set_param(MODE_RECOVERY);
if (!strcmp(name, "special_stage2")) set_param(MODE_SPECIAL_STAGE2);
if (!strcmp(name, "automatic")) {
set_param(MODE_AUTOMATIC);