diff options
Diffstat (limited to 'mdk-stage1/disk.c')
| -rw-r--r-- | mdk-stage1/disk.c | 289 |
1 files changed, 146 insertions, 143 deletions
diff --git a/mdk-stage1/disk.c b/mdk-stage1/disk.c index d6aa1596d..51a033639 100644 --- a/mdk-stage1/disk.c +++ b/mdk-stage1/disk.c @@ -1,7 +1,7 @@ /* - * Guillaume Cottenceau (gc@mandrakesoft.com) + * Guillaume Cottenceau (gc) * - * Copyright 2000 MandrakeSoft + * Copyright 2000 Mandriva * * This software may be freely redistributed under the terms of the GNU * public license. @@ -19,198 +19,200 @@ * */ +#define _GNU_SOURCE /* We want the non segfaulting my_dirname() -- See dirname(3) */ +#include <string.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> -#include <string.h> #include <sys/mount.h> #include <sys/stat.h> #include <fcntl.h> +#include <libgen.h> #include "stage1.h" #include "frontend.h" #include "modules.h" #include "probing.h" #include "log.h" +#include "tools.h" +#include "utils.h" #include "mount.h" -#include "lomount.h" #include "automatic.h" +#include "directory.h" +#include "partition.h" #include "disk.h" -static char * disk_extract_list_directory(char * direct) +static enum return_type try_automatic_with_partition(char *dev) { + enum return_type results; + int mounted; + char *dir= get_auto_value("directory"); + char location_full[500]; + strcpy(location_full, MEDIA_LOCATION); + if (dir) { + strcat(location_full, "/"); + strcat(location_full, dir); + } + wait_message("Trying to access " DISTRIB_NAME " disk (partition %s)", dev); + mounted = !try_mount(dev, MEDIA_LOCATION); + remove_wait_message(); + if (mounted) { + create_IMAGE_LOCATION(MEDIA_LOCATION); + if (image_has_stage2()) { + results = try_with_directory(MEDIA_LOCATION, "disk", "disk-iso"); + } else { + results = try_with_directory(location_full, "disk", "disk-iso"); + } + if (results == RETURN_OK) { + if (!KEEP_MOUNTED) + umount(MEDIA_LOCATION); + return RETURN_OK; + } + } + if (mounted) + umount(MEDIA_LOCATION); + return RETURN_ERROR; +} + +static enum return_type try_automatic_with_disk(char *disk, char *model) { + char * parts[50]; + char * parts_comments[50]; + enum return_type results; + char **dev; + char *part = get_auto_value("partition"); + wait_message("Trying to access " DISTRIB_NAME " disk (drive %s)", model); + if (list_partitions(disk, parts, parts_comments)) { + stg1_error_message("Could not read partitions information."); + return RETURN_ERROR; + } + remove_wait_message(); + dev = parts; + while (dev && *dev) { + if (part && strcmp(part, *dev) != 0) + goto next; + results = try_automatic_with_partition(*dev); + if (results == RETURN_OK) { + return RETURN_OK; + } + next: + dev++; + } + return RETURN_ERROR; +} + +static enum return_type try_automatic(char ** medias, char ** medias_models) { - char ** full = list_directory(direct); - char tmp[2000] = ""; - int i; - for (i=0; i<5 ; i++) { - if (!full || !*full) - break; - strcat(tmp, *full); - strcat(tmp, "\n"); - full++; + char ** model = medias_models; + char ** ptr = medias; + char *disk = get_auto_value("disk"); + while (ptr && *ptr) { + enum return_type results; + if (disk && strcmp(disk, *ptr) != 0) + goto next; + results = try_automatic_with_disk(*ptr, *model); + if (results == RETURN_OK) + return RETURN_OK; + next: + ptr++; + model++; } - return strdup(tmp); + return RETURN_ERROR; } static enum return_type try_with_device(char *dev_name) { - char * questions_location[] = { "Directory or ISO image", NULL }; + char * questions_location[] = { "Directory or ISO images 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; - - 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."); + + if (list_partitions(dev_name, parts, parts_comments)) { + stg1_error_message("Could not read partitions information."); return RETURN_ERROR; - } - - while (fgets(buf, sizeof(buf), f)) { - sscanf(buf, " %d %d %d %s", &major, &minor, &blocks, name); - if ((strstr(name, dev_name) == name) && (blocks > 1) && (name[strlen(dev_name)] != '\0')) { - parts[i] = strdup(name); - parts_comments[i] = (char *) malloc(sizeof(char) * 25); - snprintf(parts_comments[i], 24, "size: %d Mbytes", blocks >> 10); - i++; - } - } - parts[i] = NULL; - fclose(f); - - if (parts[0] == NULL) { - error_message("No partitions found."); - return RETURN_ERROR; - } - - results = ask_from_list_comments_auto("Please choose the partition where is copied the " DISTRIB_NAME " Distribution.", - parts, parts_comments, &choice, "partition", parts); - if (results != RETURN_OK) - return results; - - strcpy(device_fullname, "/dev/"); - strcat(device_fullname, choice); - - if (my_mount(device_fullname, disk_own_mount, "ext2") == -1 && - my_mount(device_fullname, disk_own_mount, "vfat") == -1 && - my_mount(device_fullname, disk_own_mount, "reiserfs") == -1) { - error_message("I can't find a valid filesystem (tried: ext2, vfat, reiserfs)."); + } + + /* uglyness to allow auto starting with devfs */ + if (!IS_AUTOMATIC || streq((choice = get_auto_value("partition")), "")) { + if (parts[0] == NULL) { + stg1_error_message("No partition found."); + return RETURN_ERROR; + } + + results = ask_from_list_comments_auto("Please select the partition containing the copy of the " + DISTRIB_NAME " Distribution install source.", + parts, parts_comments, &choice, "partition", parts); + if (results != RETURN_OK) + return results; + } + + /* in testing mode, assume the partition is already mounted on MEDIA_LOCATION */ + if (!IS_TESTING && try_mount(choice, MEDIA_LOCATION)) { + stg1_error_message("I can't find a valid filesystem (tried: ext4, vfat, ntfs, reiserfs). " + "Make sure the partition has been cleanly unmounted."); return try_with_device(dev_name); } - if (ask_from_entries_auto("Please enter the directory (or ISO image file) containing the " DISTRIB_NAME " Distribution.", + ask_dir: + if (ask_from_entries_auto("Please enter the directory (or ISO image file) containing the " + DISTRIB_NAME " Distribution install source.", questions_location, &answers_location, 24, questions_location_auto, NULL) != RETURN_OK) { - umount(disk_own_mount); + umount(MEDIA_LOCATION); return try_with_device(dev_name); } - strcpy(location_full, disk_own_mount); + strcpy(location_full, MEDIA_LOCATION); strcat(location_full, "/"); strcat(location_full, answers_location[0]); if (access(location_full, R_OK)) { - 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", disk_extract_list_directory(disk_own_mount)); - umount(disk_own_mount); - return try_with_device(dev_name); + char * path = strdup(answers_location[0]); + stg1_error_message("Directory or ISO image file could not be found on partition.\n" + "Here's a short extract of the files in the directory %s:\n" + "%s", my_dirname(path), extract_list_directory(my_dirname(location_full))); + free(path); + goto ask_dir; } - unlink(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 file %s as an ISO image of the " DISTRIB_NAME " Distribution.", answers_location[0]); - umount(disk_own_mount); - return try_with_device(dev_name); - } - } else - symlink(location_full, IMAGE_LOCATION); - - if (IS_SPECIAL_STAGE2 || ramdisk_possible()) { - /* RAMDISK install */ - if (access(IMAGE_LOCATION RAMDISK_LOCATION, R_OK)) { - error_message("I can't find the " DISTRIB_NAME " Distribution in the specified directory. " - "(I need the subdirectory " RAMDISK_LOCATION ")\n" - "Here's a short extract of the files in the directory:\n" - "%s", disk_extract_list_directory(IMAGE_LOCATION)); - loumount(); - umount(disk_own_mount); - return try_with_device(dev_name); - } - if (load_ramdisk() != RETURN_OK) { - error_message("Could not load program into memory."); - loumount(); - umount(disk_own_mount); - return try_with_device(dev_name); - } - } else { - /* LIVE install */ - char p; - if (access(IMAGE_LOCATION LIVE_LOCATION, R_OK)) { - error_message("I can't find the " DISTRIB_NAME " Distribution in the specified directory. " - "(I need the subdirectory " LIVE_LOCATION ")\n" - "Here's a short extract of the files in the directory:\n" - "%s", disk_extract_list_directory(IMAGE_LOCATION)); - loumount(); - umount(disk_own_mount); - return try_with_device(dev_name); - } - if (readlink(IMAGE_LOCATION LIVE_LOCATION "/usr/bin/runinstall2", &p, 1) != 1) { - error_message("The " DISTRIB_NAME " Distribution seems to be copied on a Windows partition. " - "You need more memory to perform an installation from a Windows partition. " - "Another solution if to copy the " DISTRIB_NAME " Distribution on a Linux partition."); - loumount(); - umount(disk_own_mount); - return try_with_device(dev_name); - } - log_message("found the " DISTRIB_NAME " Installation, good news!"); + results = try_with_directory(location_full, "disk", "disk-iso"); + if (results != RETURN_OK) { + goto ask_dir; } - if (IS_RESCUE) { - loumount(); - umount(disk_own_mount); - } + if (!KEEP_MOUNTED) + umount(MEDIA_LOCATION); - method_name = strdup("disk"); return RETURN_OK; } enum return_type disk_prepare(void) { - char ** medias, ** ptr, ** medias_models; + char ** medias, ** medias_models; char * choice; - int i, count = 0; + int i; enum return_type results; + static int already_probed_ide_generic = 0; - my_insmod("sd_mod", ANY_DRIVER_TYPE, NULL); - - get_medias(DISK, &medias, &medias_models); + int count = get_disks(&medias, &medias_models); - ptr = medias; - while (ptr && *ptr) { - count++; - ptr++; - } + if (IS_AUTOMATIC) { + results = try_automatic(medias, medias_models); + if (results != RETURN_ERROR) + return results; + unset_automatic(); + } if (count == 0) { - error_message("No DISK drive found."); - i = ask_insmod(SCSI_ADAPTERS); + if (!already_probed_ide_generic) { + already_probed_ide_generic = 1; + my_modprobe("ide_generic", ANY_DRIVER_TYPE, NULL); + return disk_prepare(); + } + stg1_error_message("No DISK drive found."); + i = ask_insmod(MEDIA_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return disk_prepare(); @@ -218,24 +220,25 @@ enum return_type disk_prepare(void) if (count == 1) { results = try_with_device(*medias); - if (results == RETURN_OK) - return RETURN_OK; - i = ask_insmod(SCSI_ADAPTERS); + if (results != RETURN_ERROR) + return results; + i = ask_insmod(MEDIA_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return disk_prepare(); } - results = ask_from_list_comments_auto("Please choose the DISK drive on which you copied the " DISTRIB_NAME " Distribution.", + results = ask_from_list_comments_auto("Please select the disk containing the copy of the " + DISTRIB_NAME " Distribution install source.", medias, medias_models, &choice, "disk", medias); if (results != RETURN_OK) return results; results = try_with_device(choice); - if (results == RETURN_OK) - return RETURN_OK; - i = ask_insmod(SCSI_ADAPTERS); + if (results != RETURN_ERROR) + return results; + i = ask_insmod(MEDIA_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return disk_prepare(); |
