summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mdk-stage1/disk.c103
-rw-r--r--mdk-stage1/mount.c2
-rw-r--r--mdk-stage1/mount.h4
-rw-r--r--mdk-stage1/stage1.c2
4 files changed, 107 insertions, 4 deletions
diff --git a/mdk-stage1/disk.c b/mdk-stage1/disk.c
index ec9e1a97f..515b95395 100644
--- a/mdk-stage1/disk.c
+++ b/mdk-stage1/disk.c
@@ -37,6 +37,100 @@
#include "disk.h"
+struct partition_detection_anchor {
+ off_t offset;
+ const char * anchor;
+};
+
+static int seek_and_compare(int fd, struct partition_detection_anchor anch)
+{
+ char buf[500];
+ int count;
+ if (lseek(fd, anch.offset, SEEK_SET) == (off_t)-1) {
+ log_perror("seek failed");
+ return -1;
+ }
+ count = read(fd, buf, strlen(anch.anchor));
+ if (count != strlen(anch.anchor)) {
+ log_perror("read failed");
+ return -1;
+ }
+ buf[count] = '\0';
+ if (strcmp(anch.anchor, buf))
+ return 1;
+ return 0;
+}
+
+static const char * detect_partition_type(char * dev)
+{
+ struct partition_detection_info {
+ const char * name;
+ struct partition_detection_anchor anchor0;
+ struct partition_detection_anchor anchor1;
+ struct partition_detection_anchor anchor2;
+ };
+ struct partition_detection_info partitions_signatures[] = {
+ { "Linux Swap", { 4086, "SWAP-SPACE" }, { 0, NULL } },
+ { "Linux Swap", { 4086, "SWAPSPACE2" }, { 0, NULL } },
+ { "Ext2", { 0x438, "\x53\xEF" }, { 0, NULL } },
+ { "ReiserFS", { 0x10034, "ReIsErFs" }, { 0, NULL } },
+ { "ReiserFS", { 0x10034, "ReIsEr2Fs" }, { 0, NULL } },
+ { "XFS", { 0, "XFSB" }, { 0x200, "XAGF" }, { 0x400, "XAGI" } },
+ { "JFS", { 0x8000, "JFS1" }, { 0, NULL } },
+ { "NTFS", { 0x1FE, "\x55\xAA" }, { 0x3, "NTFS" }, { 0, NULL } },
+ { "FAT32", { 0x1FE, "\x55\xAA" }, { 0x52, "FAT32" }, { 0, NULL } },
+ { "FAT", { 0x1FE, "\x55\xAA" }, { 0x36, "FAT" }, { 0, NULL } },
+ { "Linux LVM", { 0, "HM\1\0" }, { 0, NULL }, { 0, NULL } }
+ };
+ int partitions_signatures_nb = sizeof(partitions_signatures) / sizeof(struct partition_detection_info);
+ int i;
+ int fd;
+
+ char device_fullname[50];
+ strcpy(device_fullname, "/dev/");
+ strcat(device_fullname, dev);
+
+ if (ensure_dev_exists(device_fullname))
+ return NULL;
+ log_message("guessing type of %s", device_fullname);
+
+ if ((fd = open(device_fullname, O_RDONLY, 0)) < 0) {
+ log_perror("open");
+ return NULL;
+ }
+
+ for (i=0; i<partitions_signatures_nb; i++) {
+ int results = seek_and_compare(fd, partitions_signatures[i].anchor0);
+ if (results == -1)
+ goto detect_partition_type_end;
+ if (results == 1)
+ continue;
+ if (!partitions_signatures[i].anchor1.anchor)
+ goto detect_partition_found_it;
+
+ results = seek_and_compare(fd, partitions_signatures[i].anchor1);
+ if (results == -1)
+ goto detect_partition_type_end;
+ if (results == 1)
+ continue;
+ if (!partitions_signatures[i].anchor2.anchor)
+ goto detect_partition_found_it;
+
+ results = seek_and_compare(fd, partitions_signatures[i].anchor2);
+ if (results == -1)
+ goto detect_partition_type_end;
+ if (results == 1)
+ continue;
+
+ detect_partition_found_it:
+ return partitions_signatures[i].name;
+ }
+
+ detect_partition_type_end:
+ close(fd);
+ return NULL;
+}
+
static char * disk_extract_list_directory(char * direct)
{
char ** full = list_directory(direct);
@@ -84,9 +178,14 @@ static enum return_type try_with_device(char *dev_name)
bzero(name, sizeof(name));
sscanf(buf, " %d %d %d %s", &major, &minor, &blocks, 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) * 25);
- snprintf(parts_comments[i], 24, "size: %d Mbytes", blocks >> 10);
+ parts_comments[i] = (char *) malloc(sizeof(char) * 100);
+ sprintf(parts_comments[i], "size: %d Mbytes", blocks >> 10);
+ if (partition_type) {
+ strcat(parts_comments[i], ", type: ");
+ strcat(parts_comments[i], partition_type);
+ }
i++;
}
}
diff --git a/mdk-stage1/mount.c b/mdk-stage1/mount.c
index b41604cfe..257638421 100644
--- a/mdk-stage1/mount.c
+++ b/mdk-stage1/mount.c
@@ -34,7 +34,7 @@
#ifndef DISABLE_MEDIAS
/* WARNING: this won't work if the argument is not /dev/ based */
-static int ensure_dev_exists(char *dev)
+int ensure_dev_exists(char *dev)
{
int major, minor;
int type = S_IFBLK; /* my default type is block. don't forget to change for chars */
diff --git a/mdk-stage1/mount.h b/mdk-stage1/mount.h
index 992796bde..82795462f 100644
--- a/mdk-stage1/mount.h
+++ b/mdk-stage1/mount.h
@@ -28,4 +28,8 @@
int my_mount(char *dev, char *location, char *fs, int force_rw);
+#ifndef DISABLE_MEDIAS
+int ensure_dev_exists(char *dev);
+#endif
+
#endif
diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c
index b8c6914ce..de9bffd2f 100644
--- a/mdk-stage1/stage1.c
+++ b/mdk-stage1/stage1.c
@@ -324,7 +324,7 @@ static enum return_type method_select_and_prepare(void)
results = ask_from_list_auto("Please choose the installation method.", means, &choice, "method", means_auto);
if (results != RETURN_OK)
- return method_select_and_prepare();
+ return method_select_and_prepare();
results = RETURN_ERROR;