#include <alloca.h>
#include <ctype.h>
#include <linux/fs.h>
#include <newt.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <unistd.h>
#include "devices.h"
#include "fs.h"
#include "install.h"
#include "log.h"
#include "mkswap.h"
#include "perror.h"
#include "run.h"
#include "windows.h"
static int partFilter(struct partition * part) {
int rc;
if (doMount(part->device, "/mnt", "ext2", 0, 0)) {
return 0;
}
if (access("/mnt/etc", R_OK) || access("/mnt/etc/fstab", R_OK) ||
access("/mnt/proc", R_OK) || access("/mnt/bin", R_OK) ||
access("/mnt/etc/redhat-release", R_OK)) {
rc = 0;
} else
rc = 1;
umount("/mnt");
return rc;
}
int readMountTable(struct partitionTable table, struct fstab * finalFstab) {
newtComponent okay, cancel, form, text, listbox, answer;
int rootPartNum;
struct partition * rootPart = NULL;
FILE * f;
char buf[200];
char * start, * end;
char device[50], mntpoint[50], type[50];
struct fstab fstab;
struct fstabEntry entry;
int numParts;
umountFilesystems(finalFstab);
newtOpenWindow(10, 2, 55, 19, "Root Partition");
text = newtTextbox(1, 1, 53, 2, NEWT_TEXTBOX_WRAP);
newtTextboxSetText(text, "What partition holds the root partition "
"of your installation?");
okay = newtButton(11, 15, "Ok");
cancel = newtButton(33, 15, "Cancel");
form = newtForm(NULL, NULL, 0);
listbox = addPartitionListbox(table, form, 3, 4, 7, PART_EXT2,
partFilter, &numParts);
if (!numParts) {
newtFormDestroy(form);
/* try again, but don't be quite so picky */
form = newtForm(NULL, NULL, 0);
listbox = addPartitionListbox(table, form, 3, 4, 7, PART_EXT2,
NULL, &numParts);
if (!numParts) {
newtFormDestroy(form);
newtPopWindow();
errorWindow("You don't have any Linux partitions. You "
"can't upgrade this system!");
return INST_CANCEL; /* INST_ERROR would hang everything */
}
}
if (numParts == 1) {
rootPart = newtListboxGetCurrent(listbox);
rootPartNum = (rootPart - table.parts);
logMessage("Using partition %s for the root device",
table.parts[rootPartNum].device);
if (doMount(table.parts[rootPartNum].device, "/mnt", "ext2", 0, 0)) {
errorWindow("Could not mount automatically selected device.");
answer = NULL;
return INST_ERROR;
}
answer = okay;
} else {
newtFormAddComponents(form, text, okay, cancel, NULL);
do {
answer = newtRunForm(form);
if (answer == cancel) continue;
rootPart = newtListboxGetCurrent(listbox);
rootPartNum = (rootPart - table.parts);
if (doMount(table.parts[rootPartNum].device, "/mnt", "ext2",
0, 0)) {
errorWindow("Could not mount device.");
answer = NULL;
continue;
}
if (testing) {
continue;
}
if (access("/mnt/etc", R_OK) || access("/mnt/etc/fstab", R_OK) ||
access("/mnt/proc", R_OK) || access("/mnt/bin", R_OK)) {
errorWindow("That doesn't appear to be a root partition.");
umount("/mnt");
answer = NULL;
}
} while (!answer);
}
newtFormDestroy(form);
newtPopWindow();
if (answer == cancel) return INST_CANCEL;
if (testing)
f = fopen("/etc/fstab", "r");
else
f = fopen("/mnt/etc/fstab", "r");
if (!f) {
errorWindow("Cannot read /mnt/etc/fstab: %s");
return INST_ERROR;
}
memset(&fstab, 0, sizeof(fstab));
while (fgets(buf, sizeof(buf) - 1, f)) {
start = buf;
while (*start && isspace(*start)) start++;
if (!*start || *start == '#') continue;
if (strncmp(start, "/dev/", 5)) {
continue;
}
if (strstr(start, "noauto")) continue;
end = start + strlen(start) - 1;
while (isspace(*end)) end--;
end++;
*end = '\0';
if (sscanf(start, "%s %s %s", device, mntpoint, type) != 3) {
errorWindow("Bad line in /mnt/etc/fstab -- aborting");
fclose(f);
freeFstab(fstab);
umount("/mnt");
return INST_ERROR;
}
if (strncmp(device, "/dev/hd", 7) && strncmp(device, "/dev/sd", 7))
continue;
entry.device = strdup(device + 5);
entry.size = 0;
entry.isMounted = 0;
entry.doFormat = 0;
entry.mntpoint = strdup(mntpoint);
if (!strcmp(type, "ext2")) {
entry.type = PART_EXT2;
entry.tagName = "Linux native";
} else if (!strcmp(type, "swap")) {
entry.type = PART_SWAP;
entry.tagName = "Linux swap";
if (canEnableSwap) {
enableswap(entry.device, 0, 0);
canEnableSwap = 0;
}
} else if (!strcmp(type, "msdos")) {
entry.type = PART_DOS;
entry.tagName = "DOS 16-bit >=32";
} else if (!strcmp(type, "hpfs")) {
entry.type = PART_HPFS;
entry.tagName = "OS/2 HPFS";
} else {
entry.type = PART_OTHER;
entry.tagName = "Unknown";
}
addFstabEntry(&fstab, entry);
}
fclose(f);
umount("/mnt");
freeFstab(*finalFstab);
*finalFstab = fstab;
return 0;
}