home *** CD-ROM | disk | FTP | other *** search
- #include <alloca.h>
- #include <newt.h>
- #include <popt.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/stat.h>
- #include <unistd.h>
-
- #include "devices.h"
- #include "install.h"
- #include "intl.h"
- #include "lilo.h"
- #include "log.h"
- #include "run.h"
- #include "windows.h"
-
- #define KERNEL_IMAGE "/boot/vmlinuz-%s"
-
- static int mkinitrd(char * kernelVersion, char * initrdImage) {
- char * argv[] = { "/sbin/mkinitrd", "-f", initrdImage, "--ifneeded",
- kernelVersion, NULL };
- int rc;
- static alreadyHappened = 0;
-
- #ifdef __sparc__
- return 0;
- #endif
-
- if (alreadyHappened) return 0;
-
- if (loadModule("loop", DRIVER_OTHER, DRIVER_MINOR_NONE, NULL))
- return INST_ERROR;
-
- winStatus(32, 3, _("LILO"), _("Creating initial ramdisk..."));
- rc = runProgramRoot(RUN_LOG, "/mnt", "/sbin/mkinitrd", argv);
- newtPopWindow();
-
- removeModule("loop");
-
- if (rc) {
- unlink("/mnt/boot/initrd");
- } else {
- alreadyHappened = 1;
- }
-
- return rc;
- }
-
- static int noSpaceFilter(newtComponent entry, void * data, int ch, int cursor) {
- if (ch == ' ')
- return 0;
- return ch;
- }
-
- #define SKIP_LILO 1000
-
- #if defined(__i386__)
- static int liloWhere(char * hdName, char * bootDevice, char ** where) {
- char * format = "/dev/%-7s %s";
- char ** items;
- int which = 0, rc;
-
- items = alloca(sizeof(*items) * 3);
- items[0] = alloca(80);
- items[1] = alloca(80);
- items[2] = NULL;
-
- sprintf(items[0], format, hdName, _("Master Boot Record"));
- sprintf(items[1], format, bootDevice, _("First sector of boot partition"));
-
- rc = newtWinMenu(_("Lilo Installation"), _("Where do you want to install "
- "the bootloader?"), 50, 5, 5, 4, items, &which,
- _("Ok"), _("Skip"), _("Back"), NULL);
-
- if (rc == 3) return INST_CANCEL;
- if (rc == 2) return SKIP_LILO;
-
- switch (which) {
- case 0: *where = hdName; break;
- case 1: *where = bootDevice; break;
- }
-
- return 0;
- }
- #elif defined(__sparc__)
- static int liloWhere(char * hdName, char * bootDevice, char ** where) {
- newtComponent text, yes, no, cancel, f, answer;
- int rc;
-
- rc = newtWinTernary(_("SILO Installation"), _("Yes"), _("No"),
- _("Back"),
- _("Would you like to install or configure the SILO bootloader on "
- "your system?"));
-
- if (rc == 0 || rc == 1) {
- *where = bootDevice;
- rc = 0;
- } else if (rc == 3) {
- rc = INST_CANCEL;
- } else {
- rc = SKIP_LILO;
- }
-
- return rc;
- }
- #endif
-
- static void editBootLabel(struct partition * item) {
- newtComponent form, entry, okay, cancel, clear, answer;
- char buf[50];
- char * entryValue;
- newtGrid subgrid, grid, buttons;
-
- form = newtForm(NULL, NULL, 0);
-
- strcpy(buf, "/dev/");
- strcat(buf, item->device);
-
- entry = newtEntry(-1, -1, item->bootLabel, 20, &entryValue,
- NEWT_ENTRY_SCROLL | NEWT_ENTRY_RETURNEXIT);
- newtEntrySetFilter(entry, noSpaceFilter, NULL);
-
-
- subgrid = newtCreateGrid(2, 2);
- newtGridSetField(subgrid, 0, 0, NEWT_GRID_COMPONENT,
- newtLabel(-1, -1, _("Device:")),
- 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
- newtGridSetField(subgrid, 1, 0, NEWT_GRID_COMPONENT,
- newtLabel(-1, -1, buf),
- 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
- newtGridSetField(subgrid, 0, 1, NEWT_GRID_COMPONENT,
- newtLabel(-1, -1, _("Boot label:")),
- 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
- newtGridSetField(subgrid, 1, 1, NEWT_GRID_COMPONENT, entry,
- 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
-
- buttons = newtButtonBar(_("Ok"), &okay, _("Clear"), &clear,
- _("Cancel"), &cancel, NULL);
-
- grid = newtCreateGrid(1, 2);
- newtGridSetField(grid, 0, 0, NEWT_GRID_SUBGRID, subgrid,
- 0, 0, 0, 0, 0, 0);
- newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, buttons,
- 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-
- newtGridAddComponentsToForm(grid, form, 1);
- newtGridWrappedWindow(grid, _("Edit Boot Label"));
- newtGridFree(grid, 1);
-
- do {
- answer = newtRunForm(form);
-
- if (answer == clear)
- newtEntrySet(entry, "", 1);
- } while (answer == clear);
-
- if (answer != cancel) {
- if (item->bootLabel) free(item->bootLabel);
-
- if (strlen(entryValue))
- item->bootLabel = strdup(entryValue);
- else
- item->bootLabel = NULL;
- }
-
- newtPopWindow();
- }
-
- static int doinstallLilo(char * prefix, char * dev, char * rootdev,
- char * bootdev,
- struct partitionTable table,
- char * append, char * kernelVersion,
- char * hdname, int linear) {
- char filename[100];
- FILE * f;
- char * argv[] = { "/mnt/sbin/lilo", NULL };
- int i;
- int rc;
- struct stat sb;
- int useInitrd = 0;
- char relinitrdImage[50], absinitrdImage[55];
- int pass;
- static int firstTime = 1;
-
- sprintf(relinitrdImage, "/boot/initrd-%s.img", kernelVersion);
- strcpy(absinitrdImage, "/mnt");
- strcat(absinitrdImage, relinitrdImage);
-
- if (mkinitrd(kernelVersion, relinitrdImage))
- return INST_ERROR;
-
- if (testing) return 0;
-
- if (!stat(absinitrdImage, &sb))
- useInitrd = 1;
-
- #ifdef __sparc__
- sprintf(filename, "%s/silo.conf", prefix);
- #else
- sprintf(filename, "%s/lilo.conf", prefix);
- #endif
-
- /* why not? */
- if (firstTime) {
- rename("/mnt/etc/lilo.conf", "/mnt/etc/lilo.conf.rpmsave");
- rename("/mnt/etc/silo.conf", "/mnt/etc/silo.conf.rpmsave");
- firstTime = 0;
- }
-
- f = fopen(filename, "w");
- if (!f) {
- errorWindow("cannot create [ls]ilo config file: %s");
- return INST_ERROR;
- }
-
- logMessage("writing [sl]ilo config to %s", filename);
-
- #ifdef __i386__
- fprintf(f, "boot=/dev/%s\n", dev);
- fprintf(f, "map=/boot/map\n");
- fprintf(f, "install=/boot/boot.b\n");
- fprintf(f, "prompt\n");
- if (linear) fprintf(f, "linear\n");
- fprintf(f, "timeout=50\n");
- #elif __sparc__
- fprintf(f, "timeout=50\n");
- fprintf(f, "partition=%s\n", rootdev + 3);
- fprintf(f, "root=/dev/%s\n", rootdev);
- #else
- #error "unsupported architecture";
- #endif
-
- for (pass = 0; pass < 2; pass++) {
- for (i = 0; i < table.count; i++) {
- if (!table.parts[i].bootLabel) continue;
- if (pass == 0 && !table.parts[i].defaultBoot) continue;
- if (pass == 1 && table.parts[i].defaultBoot) continue;
-
- if (table.parts[i].type == PART_EXT2) {
- fprintf(f, "image=" KERNEL_IMAGE "\n", kernelVersion);
- fprintf(f, "\tlabel=%s\n", table.parts[i].bootLabel);
-
- /* remap /boot to root=/, but make sure we set up booting
- from old root partitions as well */
- if (!strcmp(bootdev, table.parts[i].device))
- fprintf(f, "\troot=/dev/%s\n", rootdev);
- else
- fprintf(f, "\troot=/dev/%s\n", table.parts[i].device);
-
- if (useInitrd)
- fprintf(f, "\tinitrd=%s\n", relinitrdImage);
- if (append) fprintf(f, "\tappend=\"%s\"\n", append);
- fprintf(f, "\tread-only\n");
- #ifdef __i386__
- } else {
- fprintf(f, "other=/dev/%s\n", table.parts[i].device);
- fprintf(f, "\tlabel=%s\n", table.parts[i].bootLabel);
- fprintf(f, "\ttable=/dev/%.3s\n", table.parts[i].device);
-
- if (strncmp(table.parts[i].device, hdname, 3)) {
- /* boot off the second drive, so reverse the BIOS maps */
- fprintf(f, "\tmap-drive=0x80\n");
- fprintf(f, "\t to = 0x81\n");
- fprintf(f, "\tmap-drive=0x81\n");
- fprintf(f, "\t to = 0x80\n");
- }
- #endif
- }
- }
- }
-
- fclose(f);
-
- winStatus(35, 3, _("Running"), _("Installing boot loader..."));
-
- #ifdef __i386__
- rc = runProgramRoot(RUN_LOG, "/mnt", "sbin/lilo", argv);
- #elif __sparc__
- rc = doMount("/proc", "/mnt/proc", "proc", 0, 0);
- if (rc) {
- newtPopWindow();
- return rc;
- }
- rc = runProgramRoot(RUN_LOG, "/mnt", "sbin/silo", argv);
- umount("/mnt/proc");
- #else
- #error unsupported architectures
- #endif
-
- newtPopWindow();
-
- if (rc)
- return INST_ERROR;
-
- return 0;
- }
-
- static void formatEntry(char * buf, struct partition * part) {
- sprintf(buf, "/dev/%-5s %-25s %-7s %-10s", part->device,
- part->tagName,
- part->defaultBoot ? " *" : "",
- part->bootLabel ? part->bootLabel : "");
- }
-
- static int getBootLabels(struct partitionTable table, struct fstab fstab) {
- newtComponent f, okay, text, listbox, label, cancel, edit;
- struct newtExitStruct answer;
- char buf[80];
- int i, j;
- int foundDos = 0;
- int mustAsk = 0;
- int * map;
- struct partition * curr;
- int * currNum;
- int count;
- int done;
- int defaultBootPart = 0;
- char * reflowedText;
- int width, height;
- newtGrid buttons, grid;
-
- reflowedText = newtReflowText(
- _("The boot manager Red Hat uses can boot other "
- "operating systems as well. You need to tell me "
- "what partitions you would like to be able to boot "
- "and what label you want to use for each of them."),
- 60, -5, -5, &width, &height);
- text = newtTextbox(-1, -1, width, height, NEWT_TEXTBOX_WRAP);
- newtTextboxSetText(text, reflowedText);
- free(reflowedText);
-
- f = newtForm(NULL, NULL, 0);
-
- sprintf(buf, "%-10s %-25s %-7s %-10s", _("Device"), _("Partition type"),
- _("Default"), _("Boot label"));
- label = newtLabel(-1, -1, buf);
-
- listbox = newtListbox(-1, -1, 10 - height,
- NEWT_LISTBOX_RETURNEXIT | NEWT_FLAG_SCROLL);
- map = alloca(sizeof(int) * table.count);
-
- for (i = 0, count = 0; i < table.count; i++) {
- if (table.parts[i].type != PART_SWAP &&
- table.parts[i].type != PART_IGNORE &&
- #ifdef __sparc__
- table.parts[i].type != PART_OTHER &&
- #endif
- (table.parts[i].type != PART_FAT32 || !foundDos) &&
- (table.parts[i].type != PART_DOS || !foundDos)) {
-
- if (table.parts[i].type == PART_DOS ||
- table.parts[i].type == PART_FAT32) {
- foundDos = 1;
- }
-
- if (table.parts[i].type == PART_EXT2) {
- for (j = 0; j < fstab.numEntries; j++) {
- if (!strcmp(table.parts[i].device, fstab.entries[j].device))
- break;
- }
-
- if (j < fstab.numEntries && !table.parts[i].bootLabel)
- continue;
- }
-
- if (!table.parts[i].bootLabel ||
- strcmp(table.parts[i].bootLabel, "linux")) mustAsk = 1;
-
- if (table.parts[i].defaultBoot)
- defaultBootPart = count;
-
- map[count] = i;
- formatEntry(buf, table.parts + i);
- newtListboxAddEntry(listbox, buf, map + count++);
- }
- }
-
- /* we add stuff to the form here so we can actually destroy it if
- we don't need this window after all */
- newtFormAddComponents(f, text, label, listbox, NULL);
-
- if (!mustAsk) {
- newtFormDestroy(f);
- return 0;
- }
-
- newtPushHelpLine("<F2> Selects the default partition");
-
- buttons = newtButtonBar(_("Ok"), &okay, _("Edit"), &edit,
- _("Back"), &cancel, NULL);
-
- newtFormAddComponents(f, okay, edit, cancel, NULL);
-
- newtFormAddHotKey(f, NEWT_KEY_F2);
-
- grid = newtCreateGrid(1, 4);
-
- newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text,
- 0, 0, 0, 1, NEWT_ANCHOR_LEFT, 0);
- newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, label,
- 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
- newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, listbox,
- 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
- newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons,
- 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-
- newtGridWrappedWindow(grid, _("Bootable Partitions"));
- newtGridFree(grid, 1);
-
- done = 0;
- while (!done) {
- newtFormRun(f, &answer);
-
- if (answer.reason == NEWT_EXIT_HOTKEY) {
- if (answer.u.key == NEWT_KEY_F12) {
- done = 1;
- } else if (answer.u.key == NEWT_KEY_F2) {
- currNum = newtListboxGetCurrent(listbox);
- curr = table.parts + *currNum;
-
- if (!curr->bootLabel) {
- newtWinMessage("Boot Partition", "Ok", "You cannot mark a "
- "partition as the default partition to "
- "boot from unless that partition has "
- "been assigned a boot label.");
- } else{
- for (i = 0; i < count; i++) {
- if (table.parts[map[i]].defaultBoot) {
- table.parts[map[i]].defaultBoot = 0;
- formatEntry(buf, table.parts + map[i]);
- newtListboxSetEntry(listbox, i, buf);
- break;
- }
- }
-
- curr->defaultBoot = 1;
- formatEntry(buf, curr);
- newtListboxSetEntry(listbox, currNum - map, buf);
- }
- }
- } else {
- if (answer.u.co == edit || answer.u.co== listbox) {
- currNum = newtListboxGetCurrent(listbox);
- curr = table.parts + *currNum;
- editBootLabel(curr);
-
- if (!curr->bootLabel && curr->defaultBoot) {
- curr->defaultBoot = 0;
- if (table.parts[map[defaultBootPart]].bootLabel) {
- table.parts[map[defaultBootPart]].defaultBoot = 1;
-
- formatEntry(buf, table.parts + map[defaultBootPart]);
- newtListboxSetEntry(listbox, defaultBootPart, buf);
- }
- }
-
- formatEntry(buf, curr);
- newtListboxSetEntry(listbox, currNum - map, buf);
- } else
- done = 1;
- }
- }
-
- newtPopHelpLine();
-
- newtFormDestroy(f);
- newtPopWindow();
-
- if (answer.reason == NEWT_EXIT_COMPONENT && answer.u.co == cancel)
- return INST_CANCEL;
- else
- return 0;
- }
-
- static int getAppendLine(char ** line, int * linear) {
- newtComponent form, text, entry, okay, cancel, answer;
- newtComponent linearCheck;
- char * result = NULL;
- char linearChar = (*linear) ? '*' : ' ';
- newtGrid grid, buttons, subgrid;
-
- text = newtTextboxReflowed(0, 0,
- _("A few systems will need to pass special options "
- "to the kernel at boot time for the system to function "
- "properly. If you need to pass boot options to the "
- "kernel, enter them now. If you don't need any or "
- "aren't sure, leave this blank."), 53, 10, 0, 0);
-
- form = newtForm(NULL, NULL, 0);
-
- entry = newtEntry(-1, -1, *line, 48, &result,
- NEWT_ENTRY_SCROLL | NEWT_ENTRY_RETURNEXIT);
-
- #ifndef __sparc__
- linearCheck = newtCheckbox(-1, -1,
- _("Use linear mode (needed for some SCSI drives)"),
- linearChar, NULL, &linearChar);
- #endif
-
- buttons = newtButtonBar(_("Ok"), &okay, _("Back"), &cancel, NULL);
- subgrid = newtGridVStacked(NEWT_GRID_COMPONENT, entry,
- #ifndef __sparc__
- NEWT_GRID_COMPONENT, linearCheck,
- #endif
- NULL);
- grid = newtGridBasicWindow(text, subgrid, buttons);
-
- newtGridAddComponentsToForm(grid, form, 1);
- newtFormSetCurrent(form, okay);
-
- #ifdef __sparc__
- newtGridWrappedWindow(grid, _("Silo Installation"));
- #else
- newtGridWrappedWindow(grid, _("Lilo Installation"));
- #endif
-
- newtGridFree(grid, 1);
-
- answer = newtRunForm(form);
-
- newtPopWindow();
-
- if (answer == cancel) {
- newtFormDestroy(form);
- return INST_CANCEL;
- }
-
- *linear = linearChar != ' ';
-
- if (!strlen(result))
- *line = NULL;
- else
- *line = strdup(result);
-
- newtFormDestroy(form);
-
- return 0;
- }
-
- #define LILO_WHERE 2
- #define LILO_LABELS 3
- #define LILO_INSTALL 4
- #define LILO_APPEND 5
- #define LILO_DONE 20
-
- int installLilo(char * prefix, struct partitionTable table, struct fstab fstab,
- char * kernelVersion, int flags, char * options) {
- char * rootDevice, * bootDevice = NULL;
- char * hdName;
- char * where = NULL;
- char * append = NULL;
- char * chptr = NULL;
- int i;
- int rc;
- int stage = LILO_WHERE;
- static int linear = 0;
- int foundDos = 0;
-
- hdName = alloca(4);
- strncpy(hdName, table.parts[0].device, 3);
- hdName[3] = '\0';
-
- for (i = 0; i < fstab.numEntries; i++) {
- if (!strcmp(fstab.entries[i].mntpoint, "/boot")) break;
- }
-
- if (i < fstab.numEntries)
- bootDevice = fstab.entries[i].device;
-
- for (i = 0; i < fstab.numEntries; i++) {
- if (!strcmp(fstab.entries[i].mntpoint, "/")) break;
- }
-
- rootDevice = fstab.entries[i].device;
- if (!bootDevice) {
- bootDevice = rootDevice;
- }
-
- for (i = 0; i < table.count; i++) {
- if (!strcmp(table.parts[i].device, bootDevice)) {
- table.parts[i].bootLabel = strdup("linux");
- table.parts[i].defaultBoot = 1;
- } else if ((table.parts[i].type == PART_DOS ||
- table.parts[i].type == PART_FAT32) && !foundDos) {
- table.parts[i].bootLabel = strdup("dos");
- foundDos = 1;
- }
- }
-
- if (flags & LILO_ON_MBR)
- where = hdName;
- else if (flags & LILO_ON_PARTITION)
- where = bootDevice;
-
- if (flags & LILO_USE_OPTIONS)
- append = options;
-
- if (where) {
- rc = doinstallLilo(prefix, where, rootDevice, bootDevice, table,
- append, kernelVersion, hdName, linear);
- if (rc == INST_ERROR) return INST_ERROR;
- stage = LILO_DONE;
- }
-
- while (stage != LILO_DONE) {
- switch (stage) {
- case LILO_WHERE:
- rc = liloWhere(hdName, bootDevice, &where);
- if (rc == SKIP_LILO ) return 0;
- if (rc) return rc;
- stage = LILO_APPEND;
- break;
-
- case LILO_APPEND:
- chptr = append;
- rc = getAppendLine(&chptr, &linear);
-
- if (rc == INST_ERROR) return INST_ERROR;
- if (rc == INST_CANCEL)
- stage = LILO_WHERE;
- else {
- stage = LILO_LABELS;
-
- if (append) free(append);
- if (chptr) {
- append = alloca(strlen(chptr) + 1);
- strcpy(append, chptr);
- free(chptr);
- } else {
- append = NULL;
- }
- }
-
- break;
-
- case LILO_LABELS:
- rc = getBootLabels(table, fstab);
- if (rc == INST_ERROR) return INST_ERROR;
- if (rc == INST_CANCEL)
- stage = LILO_APPEND;
- else
- stage = LILO_INSTALL;
- break;
-
- case LILO_INSTALL:
- rc = doinstallLilo(prefix, where, rootDevice, bootDevice,
- table, append,
- kernelVersion, hdName, linear);
- if (rc == INST_ERROR) return INST_ERROR;
- stage = LILO_DONE;
- break;
- }
- }
-
- return 0;
- }
-
- int makeBootdisk(char * prefix, char * kernelVersion) {
- char * argv[] = { "/sbin/mkbootdisk", "--noprompt", kernelVersion, NULL };
- int rc;
-
- #ifdef __sparc__
- return 0;
- #endif
-
- if (loadModule("loop", DRIVER_OTHER, DRIVER_MINOR_NONE, NULL))
- return INST_ERROR;
-
- winStatus(32, 3, _("Bootdisk"), _("Creating bootdisk..."));
- rc = runProgramRoot(RUN_LOG, "/mnt", "/sbin/mkbootdisk", argv);
- newtPopWindow();
-
- removeModule("loop");
-
- return rc;
- }
-