home *** CD-ROM | disk | FTP | other *** search
- #include <ctype.h>
- #include <fcntl.h>
- #include <linux/hdreg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/ioctl.h>
- #include <sys/stat.h>
- #include <sys/sysmacros.h>
- #include <sys/wait.h>
- #include <unistd.h>
-
- #include "hd.h"
- #include "install.h"
- #include "intl.h"
- #include "libfdisk/libfdisk.h"
- #include "log.h"
- #include "newt.h"
- #include "run.h"
- #include "scsi.h"
- #include "windows.h"
-
- #define MAX_HARDDRIVES 16
-
- extern int testing;
-
- /* shame we can't get this from any header files */
- #define BLKRRPART _IO(0x12,95) /* re-read partition table */
-
- struct fdiskTag {
- int tag;
- int type;
- char * tagName;
- } ;
-
- #if defined(__sparc__)
- const struct fdiskTag fdiskTags[] = {
- { 0x05, PART_IGNORE, N_("Whole disk") },
- { 0x82, PART_SWAP, N_("Linux swap") },
- { 0x83, PART_EXT2, N_("Linux native") },
- { 0, 0 },
- };
- #else
- const struct fdiskTag fdiskTags[] = {
- { 0x01, PART_DOS, N_("DOS 12-bit FAT") },
- { 0x04, PART_DOS, N_("DOS 16-bit <32M") },
- { 0x05, PART_IGNORE, "Extended" },
- { 0x06, PART_DOS, N_("DOS 16-bit >=32") },
- { 0x07, PART_HPFS, N_("OS/2 HPFS") },
- { 0x0b, PART_FAT32, N_("Win95 FAT32") },
- { 0x0c, PART_FAT32, N_("Win95 FAT32") },
- { 0x0e, PART_FAT32, N_("Win95 FAT32") },
- { 0x82, PART_SWAP, N_("Linux swap") },
- { 0x83, PART_EXT2, N_("Linux native") },
- { 0, 0 },
- };
- #endif
-
- #define MAX_NUM_DRIVES 40
-
- static int findDrivesPresent(struct deviceInfo * drives, int * numPtr);
-
- static int findPartitions(char * hdname, int * numPartitions,
- struct partition partitions[15]) {
- char devBuf[20];
- int j, i;
- int status;
- HardDrive * hd = NULL;
- PartitionSpec spec;
-
- *numPartitions = 0;
-
- /* don't bother with any of this if the main device doesn't exist
- or doesn't look like a hard drive */
- sprintf(devBuf, "/tmp/%s", hdname);
-
- if (devMakeInode(hdname, devBuf)) {
- return 0;
- }
-
- status = fdiskOpenDevice(devBuf, 0, &hd);
- if (status != FDISK_SUCCESS) {
- unlink(devBuf);
- return 0;
- }
-
- status = fdiskReadPartitions(hd);
- if (status != FDISK_SUCCESS) {
- fdiskCloseDevice(hd);
- unlink(devBuf);
- return 0;
- }
-
- fdiskCloseDevice(hd);
- unlink(devBuf);
-
- /* Translate into a PartitionSpec */
- memset(&spec, 0, sizeof(PartitionSpec));
- fdiskSetupPartitionSpec(&hd, 1, &spec );
-
- *numPartitions = spec.num;
- for (i = 0; i < spec.num; i++) {
- memset(partitions + i, 0, sizeof(*partitions));
- sprintf(partitions[i].device, "%s%d",
- hdname, spec.entry[i].partition.num.current);
- /* the /2 converts from 512 byte sectors to 1k blocks */
- partitions[i].size = spec.entry[i].partition.size.current / 2;
- partitions[i].begin = spec.entry[i].partition.start.current;
- partitions[i].end = spec.entry[i].partition.endcyl.current;
-
- for (j = 0; fdiskTags[j].tag; j++) {
- if (fdiskTags[j].tag == spec.entry[i].partition.type.current) {
- partitions[i].type = fdiskTags[j].type;
- strcpy(partitions[i].tagName, fdiskTags[j].tagName);
- break;
- }
- }
-
- }
-
- return 0;
- }
-
- int findAllPartitions(struct deviceInfo * devices,
- struct partitionTable * table) {
- int numPartitions;
- int i;
- struct partition parts[16];
- struct partition * allParts = NULL;
- int numAllParts = 0;
-
- if (!devices) {
- /* FIXME: memory leak for internal structures */
- devices = alloca(sizeof(*devices) * MAX_NUM_DRIVES);
- if (findDrivesPresent(devices, NULL)) return INST_ERROR;
- }
-
- winStatus(30, 3, _("Hard Drives"), _("Scanning hard drives..."));
-
- for (i = 0; devices[i].deviceName; i++) {
- findPartitions(devices[i].deviceName, &numPartitions, parts);
- if (!numPartitions) continue;
-
- if (!numAllParts) {
- numAllParts = numPartitions;
- allParts = malloc(sizeof(*allParts) * numAllParts);
- memcpy(allParts, parts, sizeof(*allParts) * numAllParts);
- } else {
- allParts = realloc(allParts, sizeof(*allParts) *
- (numAllParts + numPartitions));
- memcpy(allParts + numAllParts, parts,
- sizeof(*allParts) * numPartitions);
- numAllParts += numPartitions;
- }
- }
-
- table->count = numAllParts;
- table->parts = allParts;
-
- newtPopWindow();
-
- return 0;
- }
-
- static int findDrivesPresent(struct deviceInfo * drives, int * numPtr) {
- struct deviceInfo * scsi = NULL, * ide = NULL;
- int num = 0;
- int i;
-
- /* FIXME: this results in memory leaks via the strings inside of
- the decice structures! */
-
- if (scsiDeviceAvailable()) {
- if (scsiGetDevices(&scsi)) return INST_ERROR;
- }
-
- if (ideGetDevices(&ide)) return INST_ERROR;
-
- i = 0, num = 0;
- while (ide[i].deviceName) {
- if (ide[i].type == DEVICE_HD)
- drives[num++] = ide[i];
- i++;
- }
-
- i = 0;
- while (scsi && scsi[i].deviceName) {
- if (scsi[i].type == DEVICE_HD)
- drives[num++] = scsi[i];
- i++;
- }
-
- drives[num].deviceName = NULL;
-
- if (numPtr) *numPtr = num;
-
- return 0;
- }
-
- int getDriveList(char *** drives, int * num) {
- struct deviceInfo drivesPresent[MAX_NUM_DRIVES];
- int rc;
- int i;
-
- if ((rc = findDrivesPresent(drivesPresent, num))) return rc;
-
- *drives = malloc(sizeof(char *) * (*num + 1));
-
- for (i = 0; i < *num; i++) {
- (*drives)[i] = drivesPresent[i].deviceName;
- }
-
- (*drives)[i] = NULL;
-
- return 0;
- }
-
- int partitionDrives(void) {
- struct deviceInfo drivesPresent[MAX_NUM_DRIVES];
- int numDrivesPresent = 0;
- int childpid;
- int i, fd;
- int haveEdited = 0;
- char devBuf[100], idBuf[3];
- char * driveText[50];
- struct deviceInfo * currhd;
- int status;
- int reboot = 0;
- char * cmd;
- char * text;
- int rc, driveNum = 0;
-
- if (!access("/sbin/fdisk", X_OK))
- cmd = "/sbin/fdisk";
- else
- cmd = "/usr/bin/fdisk";
-
- findDrivesPresent(drivesPresent, &numDrivesPresent);
-
- if (!numDrivesPresent) {
- newtWinMessage(_("Hard Drives"), _("Ok"),
- _("You don't have any hard drives available! "
- "You probably forgot to configure a SCSI "
- "controller."));
-
- return INST_ERROR;
- }
-
- #ifdef __i386__
- text = _("To install Red Hat Linux, you must have at least one parition "
- "of 150 MB dedicated to Linux. We suggest placing that partition "
- "on one of the first two hard drives in your system so you can "
- "boot into Linux with LILO.");
- #else
- text = _("To install Red Hat Linux, you must have at least one parition "
- "of 150 MB dedicated to Linux.");
- #endif
-
- for (i = 0; i < numDrivesPresent; i++) {
- sprintf(devBuf, "/dev/%s", drivesPresent[i].deviceName);
-
- if (!strncmp(drivesPresent[i].deviceName, "sd", 2)) {
- sprintf(idBuf, "%d", drivesPresent[i].id);
- strcat(devBuf, " - SCSI ID ");
- strcat(devBuf, idBuf);
- }
-
- strcat(devBuf, " - Model ");
- strcat(devBuf, drivesPresent[i].info);
-
- /* truncate at 50 columns for now */
- devBuf[50] = '\0';
-
- driveText[i] = alloca(strlen(devBuf) + 1);
- strcpy(driveText[i], devBuf);
- }
- driveText[i] = NULL;
-
- do {
- rc = newtWinMenu(_("Partition Disks"), text, 56, 5, 6, 5,
- driveText, &driveNum, _("Done"), _("Edit"),
- _("Back"), NULL);
-
- if (rc == 2 || rc == 0) {
- haveEdited = 1;
- currhd = drivesPresent + driveNum;
-
- sprintf(devBuf, "/tmp/%s", currhd->deviceName);
- if (devMakeInode(currhd->deviceName, devBuf)) return 0;
-
- newtSuspend();
- for (i = 0; i < 25; i++) puts("");
- printf("This is the fdisk program for partitioning your drive. It "
- "is running\non /dev/%s.\n\n", currhd->deviceName);
-
- logMessage("running fdisk on %s", devBuf);
-
- if (!(childpid = fork())) {
- execl(cmd, cmd, devBuf, NULL);
- return -1;
- }
-
- waitpid(childpid, &status, 0);
-
- newtResume();
- }
- } while (rc == 2 || rc == 0);
-
- if (haveEdited) {
- for (i = 0; i < numDrivesPresent; i++) {
- sprintf(devBuf, "/tmp/%s", drivesPresent[i].deviceName);
- if (devMakeInode(drivesPresent[i].deviceName, devBuf))
- return INST_ERROR;
- fd = open(devBuf, O_RDONLY);
- unlink(devBuf);
- if (fd < 0) reboot = 1;
-
- if (ioctl(fd, BLKRRPART, 0)) reboot = 1;
- close(fd);
- }
- }
-
- if (reboot) needReboot();
-
- if (rc == 3)
- return INST_CANCEL;
-
- return 0;
- }
-
- void needReboot(void) {
- newtWinMessage(_("Reboot Needed"), _("Ok"),
- _("The kernel is unable to read your new partitioning "
- "information, probably because you modified extended "
- "partitions. While this is not critical, you must "
- "reboot your machine before proceeding. Insert the "
- "Red Hat boot disk now and press Return to reboot "
- "your system.\n\n"
- "If you have a ZIP or JAZ drive, make sure there is "
- "a disk in the drive as an empty SCSI drive can also "
- "cause this problem."));
-
- newtFinished();
- exit(0);
- }
-