home *** CD-ROM | disk | FTP | other *** search
- /* Newt based fdisk program
- *
- * Michael Fulbright (msf@redhat.com)
- *
- * Copyright 1998 Red Hat Software
- *
- * This software may be freely redistributed under the terms of the GNU
- * public license.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #include <alloca.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <malloc.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <errno.h>
-
- #include <newt.h>
-
- #include "kickstart.h"
- #include "fs.h"
- #include "fsedit.h"
- #include "hd.h"
- #include "install.h"
- #include "intl.h"
- #include "libfdisk/libfdisk.h"
- #include "devices.h"
- #include "windows.h"
-
- #include <popt.h>
-
- #define VERSION_STR "1.00"
-
- extern int testing;
-
- /* static char version[] = "0.01"; */
-
- struct attemptedPartition normalPartitioning[] = {
- #if defined(__i386__)
- { "/boot", 16, LINUX_NATIVE_PARTITION, 0, -1 },
- #elif defined(__alpha__)
- { "/dos", 2, DOS_PRIMARY_lt32MEG_PARTITION, 0, 1 },
- #endif
- { "/", 400, LINUX_NATIVE_PARTITION, 1, -1 },
- { "Swap-auto", 32, LINUX_SWAP_PARTITION, 0, -1 },
- { NULL, 0, 0, 0 }
- };
-
- /* need to move somewhere else eventually! */
- /* mostly gleamed from fdisk.[ch] */
- struct parttypes {
- unsigned char index;
- char *name;
- };
-
- /* this isn't const, as we have a loop which does i18n conversion on these */
- static struct parttypes allparttypes[] = {
- {0, "Empty"},
- {1, "DOS 12-bit FAT"},
- {2, "XENIX root"},
- {3, "XENIX usr"},
- {4, "DOS 16-bit <32M"},
- {5, "Extended"},
- {6, "DOS 16-bit >=32M"},
- {7, "OS/2 HPFS"}, /* or QNX? */
- {8, "AIX"},
- {9, "AIX bootable"},
- {10, "OS/2 Boot Manager"},
- {0xb, "Win95 FAT32"},
- {0xc, "Win95 FAT32"},
- {0xe, "Win95 FAT32"},
- {0x40, "Venix 80286"},
- {0x51, "Novell?"},
- {0x52, "Microport"}, /* or CPM? */
- {0x63, "GNU HURD"}, /* or System V/386? */
- {0x64, "Novell Netware 286"},
- {0x65, "Novell Netware 386"},
- {0x75, "PC/IX"},
- {0x80, "Old MINIX"}, /* Minix 1.4a and earlier */
-
- {0x81, "Linux/MINIX"}, /* Minix 1.4b and later */
- {0x82, "Linux swap"},
- {0x83, "Linux native"},
-
- {0x93, "Amoeba"},
- {0x94, "Amoeba BBT"}, /* (bad block table) */
- {0xa5, "BSD/386"},
- {0xb7, "BSDI fs"},
- {0xb8, "BSDI swap"},
- {0xc7, "Syrinx"},
- {0xdb, "CP/M"}, /* or Concurrent DOS? */
- {0xe1, "DOS access"},
- {0xe3, "DOS R/O"},
- {0xf2, "DOS secondary"},
- {0xff, "BBT"} /* (bad track table) */
- };
-
- int nparttypes = sizeof (allparttypes) / sizeof (struct parttypes);
-
-
- /* hardcoded, maybe someday we'll get these from tty ? */
- int screen_width=80;
- int screen_height=25;
-
- #define MAX_HARDDRIVES 16
-
- #define SECPERMEG 2048
-
- /* clean up that string */
- static void TrimWhitespace( char *s ) {
- char *f, *l, *p, *q;
-
- if (!(*s))
- return;
-
- for (f=s; *f && isspace(*f); f++) ;
-
- if (!*f) {
- *s = '\0';
- return;
- }
-
- for (l=f+strlen(f)-1; isspace(*l) ; l--)
- *l = '\0';
-
- q = s, p = f;
- while (*p)
- *q++ = *p++;
-
- *q = '\0';
- }
-
- /* fill in the */
- /* position in the status line, up to length characters */
- /* if cen=1, center it */
- static void BuildTableField( char *line, char *val,
- int pos, int length, int cen ) {
- char *p, *q;
- int i;
- int c;
-
- /* lets center field value in the field */
- if (cen) {
- c = strlen(val);
- c = (length-c)/2;
- if (c < 0)
- c = 0;
- } else
- c=0;
-
- /* first setup device name */
- for (p=val, q=line+pos+c, i=c; *p && i<length; p++, q++, i++)
- *q = *p;
- }
-
- #if 0
- /* some fdisk functions which don't have homes yet */
- static int fdiskPartitionIsBootable( HardDrive *hd, Partition *p ) {
- unsigned int i, bootable;
-
- /* see if drive #1 or #2 is a possible drive for partition */
- bootable = fdiskThisDriveSetIsActive( &p->drive, 1 ) ||
- fdiskThisDriveSetIsActive( &p->drive, 2 );
-
- /* if so, see if rest are EXCLUDED */
- if (bootable) {
- for (i=3; i<MAX_DRIVESET_NUM; i++) {
- if (fdiskThisDriveSetIsActive( &p->drive, i)) {
- bootable = 0;
- break;
- }
- }
- }
-
- if (bootable) {
- if (p->endcyl.active && p->endcyl.max < 1024) {
- bootable = 1;
- } else if (p->immutable) {
- unsigned int end, c, h, s;
- end = p->start.current + p->size.current - 1;
- fdiskSectorToCHS( hd, end, &c, &h, &s );
- if (c < 1024)
- bootable = 1;
- else
- bootable = 0;
- } else {
- bootable = 0;
- }
- }
-
- return bootable;
- }
- #endif
-
- /* check a mount point to make sure its valid */
- /* returns non-zero if bad mount point */
- static int badMountPoint(unsigned int type, char * item) {
- char * chptr = item;
-
- if (!strncmp(item, "/dev", 4) ||
- !strncmp(item, "/bin", 4) ||
- !strncmp(item, "/sbin", 5) ||
- !strncmp(item, "/etc", 4) ||
- #ifdef __sparc__
- !strncmp(item, "/boot", 5) ||
- #endif
- !strncmp(item, "/lib", 4)) {
- newtWinMessage(_("Bad Mount Point"), _("Ok"),
- _("The %s directory must be on the root filesystem."),
- item);
- return 1;
- }
-
- if (*chptr != '/') {
- newtWinMessage(_("Bad Mount Point"), _("Ok"),
- _("The mount point %s is illegal.\n\n"
- "Mount points must begin with a leading /."), item);
- return 1;
- }
-
- if (*(chptr + 1) && *(chptr + strlen(chptr) - 1) == '/') {
- newtWinMessage(_("Bad Mount Point"), _("Ok"),
- _("The mount point %s is illegal.\n\n"
- "Mount points may not end with a /."), item);
- return 1;
- }
-
- while (*chptr && isprint(*chptr)) chptr++;
-
- if (*chptr) {
- newtWinMessage(_("Bad Mount Point"), _("Ok"),
- _("The mount point %s is illegal.\n\n"
- "Mount points may only printable characters."), item);
- return 1;
- }
-
- if (type != LINUX_NATIVE_PARTITION && (
- !strncmp(item, "/var", 4) ||
- !strncmp(item, "/tmp", 4) ||
- !strncmp(item, "/boot", 4) ||
- !strcmp(item, "/") ||
- !strncmp(item, "/root", 4))) {
- newtWinMessage(_("Bad Mount Point"), _("Ok"),
- _("The mount point %s is illegal.\n\n"
- "System partitions must be on Linux Native "
- "partitions."), item);
- return 1;
- }
-
- if (type != LINUX_NATIVE_PARTITION &&
- type != NFS_REMOTE_PARTITION &&
- !strncmp(item, "/usr", 4)) {
- newtWinMessage(_("Bad Mount Point"), _("Ok"),
- _("The mount point %s is illegal.\n\n"
- "/usr must be on a Linux Native partition "
- "or an NFS volume."), item);
- return 1;
- }
-
- return 0;
- }
-
- /* */
- /* NEWT/screen related routines */
- /* */
-
- /* handles standard fdisk type errors */
- /* returns non-zero if user picked "yes" response, and zero if "no" */
- static int ErrorDialog(char *title, char *errbody, char *errmsg,
- char *yesmsg, char *nomsg) {
-
- int retcode;
- char *buf;
-
-
- /* I don't know if this is what msf intended, but it is a whole lot
- easier. */
- buf = alloca(strlen(errbody)+strlen(errmsg) + 10);
- sprintf(buf, "%s: %s", errbody, errmsg);
- retcode = newtWinChoice(title, yesmsg, nomsg, buf);
-
- if (retcode == 2) return 0; else return 1;
- }
-
- static int HandleFdiskError( int status, char *errbody, char *y, char *n ) {
- char errmsg[250];
- char yesmsg[]="Yes";
- char nomsg[] ="No";
-
- if (status < 0) {
- if (errno < sys_nerr-1)
- strncpy(errmsg,sys_errlist[errno],sizeof(errmsg));
- else
- snprintf(errmsg,sizeof(errmsg), _("System error %d"), errno);
- } else {
- if (status < fdisk_nerr)
- strcpy(errmsg, fdisk_errlist[status]);
- else
- snprintf(errmsg,sizeof(errmsg), "libfdisk error %d",errno);
- }
-
- if (y != NULL && n != NULL)
- return ErrorDialog( _("Fdisk Error"), errbody, errmsg, y, n);
- else
- return ErrorDialog( _("Fdisk Error"), errbody,errmsg,yesmsg,nomsg);
- }
-
- /* give summary of why partitions weren't allocated */
- static void showReasons( PartitionSpec *spec ) {
- newtComponent tbox, form, ok, lbox;
- int i;
-
- for (i=0; i<spec->num; i++)
- if (spec->entry[i].status == REQUEST_DENIED)
- break;
-
- /* nothing going on here, keep moving along */
- if (i == spec->num)
- return;
-
- /* build list of why they all failed */
- newtCenteredWindow(60, 18, _("Unallocated Partitions"));
- form = newtForm(NULL,NULL,0);
-
- tbox = newtTextbox(5, 1, 50, 5, NEWT_FLAG_WRAP );
- newtTextboxSetText(tbox, _("There are currently unallocated partition(s) "
- "present in the list of requested partitions. The "
- "unallocated partition(s) are shown below, along with "
- "the reason they were not allocated."));
-
- lbox = newtListbox(10, 6, 5, NEWT_FLAG_RETURNEXIT | NEWT_FLAG_SCROLL );
- for (i=0; i<spec->num; i++)
- if (spec->entry[i].status == REQUEST_DENIED) {
- char tmpstr[80];
- char *pname = spec->entry[i].name;
- char *s, *t;
-
- memset(tmpstr, ' ', 80);
- if (strncmp("Exist", pname, 5) && strncmp("Swap", pname, 4) &&
- strncmp("Dos", pname, 3))
- t = pname;
- else
- t = NULL;
- for (s=tmpstr;t && *t; t++,s++)
- *s = *t;
-
- t = GetReasonString(spec->entry[i].reason);
- for (s=tmpstr+20;t && *t; t++,s++)
- *s = *t;
- *s = '\0';
- newtListboxAddEntry(lbox, tmpstr, NULL);
- }
-
- ok = newtButton(25, 13, _("Ok"));
- newtFormAddComponents(form, tbox, lbox, ok, NULL);
- newtFormSetCurrent(form, ok);
-
- newtRunForm(form);
-
- newtPopWindow();
- newtFormDestroy(form);
- }
-
- /* read in the requested drives */
- /* pass an array of names of block devices, returns 0 if ok */
- static int ReadDrives( char **drives, int numdrives,
- HardDrive **hdarr, unsigned int *numhd,
- int forcezero, int readOnly) {
-
- char errbody[250];
- int i, done, status;
-
- /* loop over all specified block devices */
- *numhd = 0;
- for (i=0; i < numdrives; ) {
- status = fdiskOpenDevice(drives[i], *numhd+1, &hdarr[*numhd]);
- if (status != FDISK_SUCCESS) {
-
- /* HORRIBLE HACK XXX*/
-
- #ifdef __sparc__
- if (status == FDISK_ERR_CORRUPT) { /* bad Sun disklabel */
- snprintf(errbody, sizeof(errbody),
- _("A disk with a corrupt Sun disklabel has been "
- "found while reading block device %s. You must "
- "use fdisk to create and write a new label to "
- "this device."), drives[i]);
- if (newtWinChoice(_("Corrupt Sun disklabel"),
- _("Back"), _("Skip Drive"), errbody) == 1)
- return INST_CANCEL;
- else {
- i++;
- continue;
- }
- }
- #endif
- snprintf(errbody, sizeof(errbody),
- _("An error occurred reading the partition table for the "
- "block device %s. The error was:"), drives[i]);
- if (HandleFdiskError( status, errbody, "Retry", "Skip Drive" ))
- continue;
- else {
- i++;
- continue;
- }
- } else {
- done = 0;
- while (!done) {
- status = fdiskReadPartitions( hdarr[*numhd] );
- if (status != FDISK_SUCCESS) {
- int rc;
-
- if (status == FDISK_ERR_BADMAGIC) {
- if (forcezero) {
- if (!testing)
- #ifdef sparc
- fdiskInitSunLabel(hdarr[*numhd]);
- #else
- fdiskZeroMBR(hdarr[*numhd]);
- #endif
- fdiskCloseDevice(hdarr[*numhd]);
- done = 1;
- } else {
- if (kickstart) {
- newtWinMessage(_("Bad Partition Table"),
- _("Ok"),
- _("The partition table on device %s is "
- "corrupted. To create new partitions "
- "it must be initialized. You can "
- "specify \"zerombr yes\" in the "
- "kickstart file to have this done "
- "automatically"), drives[i]+5);
- return INST_ERROR;
- }
-
- rc = newtWinChoice(_("Bad Partition Table"),
- _("Initialize"), _("Skip Drive"),
- _("The partition table on device %s is "
- "corrupted. To create new partitions "
- "it must be initialized,"
- " causing the loss of ALL DATA on "
- "this drive."), drives[i]+5);
-
- if (rc != 2) {
- if (!testing)
- #ifdef sparc
- fdiskInitSunLabel(hdarr[*numhd]);
- #else
- fdiskZeroMBR(hdarr[*numhd]);
- #endif
- fdiskCloseDevice(hdarr[*numhd]);
- done = 1;
- } else {
- i++;
- fdiskCloseDevice(hdarr[*numhd]);
- done = 1;
- }
- }
- } else {
- snprintf(errbody, sizeof(errbody),
- _("An error occurred reading the partition table "
- "for the block device %s. The error was:"),
- drives[i]+5);
- if (HandleFdiskError(status,errbody,
- _("Retry"), _("Skip Drive"))){
- fdiskCloseDevice(hdarr[*numhd]);
- done = 1;
- } else {
- i++;
- fdiskCloseDevice(hdarr[*numhd]);
- done = 1;
- }
- }
- /* THIS IS A HORRIBLE NASTY HACK */
- #ifdef __alpha__
- } else if (hdarr[i]->limits.maxPrimary > 4 && !readOnly) {
- newtWinMessage(_("BSD Disklabel"), _("Ok"), _("A disk with "
- "a BSD disklabel has been found. The Red Hat "
- "installation only supports BSD Disklabels in "
- "read-only mode, so you must use a custom install "
- "and fdisk (instead of Disk Druid) for "
- "machines with BSD Disklabels."));
- return INST_CANCEL;
- #endif
- } else {
- *numhd += 1;
- i++;
- done = 1;
- }
- }
- }
- }
-
- return FDISK_SUCCESS;
-
- }
-
- /* see if anything really changed */
- int DisksChanged( HardDrive **oldhd, HardDrive **newhd, unsigned int numhd ) {
-
- int i, j;
-
- /* see if partition tables are identical */
- for (i=0; i<numhd; i++)
- for (j=0; j<MAX_PARTITIONS; j++) {
- if (memcmp(&oldhd[i]->table[j],&newhd[i]->table[j],
- sizeof(Partition)))
- return 1;
- if (memcmp(&oldhd[i]->eptable[j],&newhd[i]->eptable[j],
- sizeof(Partition)))
- return 1;
- }
-
- return 0;
- }
-
-
- /* edit an existing partition spec */
- /* callback for type listbox */
- struct typebox_cbstruct {
- newtComponent *entry;
- char *val;
- };
-
- static char typebox_mp[100];
- static int inswapentry;
-
- static void typebox_scroll(newtComponent box, struct typebox_cbstruct *s ) {
- int type;
-
- type = (long) newtListboxGetCurrent(box);
- if (type == LINUX_SWAP_PARTITION && !inswapentry) {
- strncpy(typebox_mp, s->val, 100);
- newtEntrySetFlags(*s->entry, _("Swap Partition"), 0);
- inswapentry = 1;
- newtEntrySetFlags(*s->entry, NEWT_FLAG_DISABLED, NEWT_FLAGS_SET);
- } else if (inswapentry) {
- newtEntrySetFlags(*s->entry, NEWT_FLAG_DISABLED, NEWT_FLAGS_RESET);
- if (typebox_mp[0] == -1) /* just clear string if it isnt initialized */
- typebox_mp[0] = '\0';
- newtEntrySet(*s->entry, typebox_mp, 1);
- inswapentry = 0;
- }
- }
-
- struct driveentry_struct {
- newtComponent cb;
- char state;
- };
-
- struct entrybox_cbstruct {
- newtComponent *form;
- char *val;
- unsigned char *val2;
- DriveSet curds, origds;
- int numhd;
- HardDrive **hdarr;
- struct driveentry_struct *de;
- int dobootable;
- };
-
- static void entrybox_cb(newtComponent box, struct entrybox_cbstruct *s) {
- unsigned char boot;
- int j;
-
- if (s->dobootable) {
- boot = (!strcmp(s->val, "/") || !strcmp(s->val, "/boot")) ? '*' : ' ';
- if (boot == '*' && *(s->val2) == ' ')
- memcpy(&s->origds, &s->curds, sizeof(DriveSet));
- *(s->val2) = boot;
- if (boot == '*') {
- fdiskDeactivateAllDriveSet( &s->curds );
- fdiskActivateDriveSet( &s->curds, 1 );
- fdiskActivateDriveSet( &s->curds, 2 );
- } else {
- memcpy(&s->curds, &s->origds, sizeof(DriveSet));
- }
-
- for (j=0; j<s->numhd; j++)
- s->de[j].state=fdiskThisDriveSetIsActive(&s->curds,
- s->hdarr[j]->num)?'*':' ';
-
- newtDrawForm(*s->form);
- }
- }
-
- #define NEW_PARTSPEC "NewPartition"
-
- static int EditPartitionSpec(HardDrive **hdarr, unsigned int numhd,
- PartitionSpec *spec,
- PartitionSpecEntry *entry) {
- int j;
- unsigned int hdidx, tmpuint;
- int tmpint;
- char tmpstr[80];
-
- Partition *p;
- newtComponent form, mntptentry;
- newtComponent sizeentry, growentry, bootentry, typeentry;
- newtComponent sb, driveform;
- newtComponent ok, cancel, answer;
-
- struct typebox_cbstruct cb1;
- struct entrybox_cbstruct cb2;
- struct driveentry_struct driveentry[MAX_HARDDRIVES];
-
- char *mntpt=NULL, *size=NULL, *eptr;
- char titlestr[80];
- unsigned char boot, grow;
-
- int row, col;
- int status=0;
- int done;
- int newpartition;
- int cval;
- int numfstypes = 4;
- char fstypesnames[][20] = { "Linux Swap", "Linux Native",
- "DOS 16-bit <32M", "DOS 16-bit >=32M"};
- int fstypes[] = {0x82, 0x83, 0x4, 0x6};
-
- p = (Partition *) alloca(sizeof(Partition));
- memcpy(p, &entry->partition, sizeof(Partition));
-
- newpartition = (strcmp(entry->name, NEW_PARTSPEC) == 0);
-
- if (p->immutable)
- cval = -2;
- else
- cval = ((numhd > 3) ? 4 : numhd);
-
- /* make title line a little more descriptive */
- if (newpartition) {
- strcpy(titlestr, "Edit New Partition");
- } else if (p->immutable) {
- for (hdidx=0; hdidx < numhd &&
- hdarr[hdidx]->num != p->drive.current; hdidx++);
- if (hdidx != numhd) {
- snprintf(titlestr, 80, "%s: /dev/%s%d", _("Edit Partition"),
- hdarr[hdidx]->name+5, p->num.current);
- if (entry->name && *entry->name && strncmp(entry->name, "Exist", 5))
- snprintf(titlestr+strlen(titlestr), 80-strlen(titlestr),
- " (%s)", entry->name);
- } else {
- strcpy(titlestr, _("Edit Partition"));
- }
- } else {
- if (entry->name && *entry->name)
- snprintf(titlestr, 80, "%s: %s", _("Edit Partition"), entry->name);
- else
- strcpy(titlestr, _("Edit Partition"));
- }
-
- newtCenteredWindow(70, 13+cval, titlestr );
- form = newtForm(NULL,NULL,0);
-
- /* mount point goes at top and is centered */
- row = 1;
- col = 3;
- newtFormAddComponent(form, newtLabel(col, row, "Mount Point:"));
- if (p->type.current != LINUX_SWAP_PARTITION) {
- if (!newpartition && strncmp("Exist", entry->name, 5) &&
- strncmp("Dos", entry->name, 3)) {
- mntptentry = newtEntry(22, row, entry->name, 30,
- &mntpt, NEWT_FLAG_RETURNEXIT);
- } else {
- mntptentry = newtEntry(22, row, "", 30,
- &mntpt, NEWT_FLAG_RETURNEXIT);
- }
- } else {
- mntptentry = newtEntry(22, row, "Swap Partition", 30, &mntpt,
- NEWT_FLAG_RETURNEXIT | NEWT_FLAG_DISABLED);
- }
-
- /* size, grow and boot flags on left under mount point */
- row = 3;
- newtFormAddComponent(form, newtLabel(col, row, "Size (Megs):"));
- if (p->immutable) {
- sizeentry = NULL;
- snprintf(tmpstr,sizeof(tmpstr),"%d", p->size.current/SECPERMEG);
- newtFormAddComponent(form, newtLabel(22, row, tmpstr));
- } else {
- snprintf(tmpstr,sizeof(tmpstr),"%d", p->size.min/SECPERMEG);
- sizeentry = newtEntry(22, row, tmpstr, 8,
- &size, NEWT_FLAG_RETURNEXIT);
- }
- row++;
-
- if (!newpartition) {
- grow = p->size.min != p->size.max;
- } else {
- grow = 0;
- }
- grow = (grow) ? '*' : ' ';
-
- newtFormAddComponent(form, newtLabel(col, row, "Growable?:"));
- if (p->immutable) {
- growentry = NULL;
- newtFormAddComponent(form, newtLabel(22, row, "[ ]"));
- } else {
- growentry = newtCheckbox(22, row, "", grow, NULL, &grow);
- }
- row++;
-
- /* give status */
- if (!newpartition) {
- newtFormAddComponent(form, newtLabel(col, row,
- _("Allocation Status:")));
- if (entry->status != REQUEST_DENIED)
- newtFormAddComponent(form, newtLabel(22, row, _("Successful")));
- else
- newtFormAddComponent(form, newtLabel(22, row, _("Failed")));
- row++;
-
- if (entry->status == REQUEST_DENIED) {
- newtFormAddComponent(form, newtLabel(col, row,
- _("Failure Reason:")));
- newtFormAddComponent(form,
- newtLabel(22,row,GetReasonString(entry->reason)));
- }
- row++;
- }
-
- /* blow this bootable stuff for now, its confusing */
- bootentry = NULL;
-
- /* type goes on right side under the mount point */
- row = 3;
- newtFormAddComponent(form, newtLabel(43, row, "Type:"));
- if (p->immutable) {
- typeentry = NULL;
-
- for (j=0; j<nparttypes; j++)
- if (allparttypes[j].index == p->type.current)
- break;
-
- if (j != nparttypes)
- snprintf(tmpstr, sizeof(tmpstr), "%s", allparttypes[j].name);
- else
- snprintf(tmpstr,sizeof(tmpstr),"%6s (0x%x)",
- "Unknown", p->type.current);
-
- newtFormAddComponent(form, newtLabel(48, row, tmpstr));
- row++;
- } else {
- typeentry = newtListbox( 48, row, 4,
- NEWT_FLAG_RETURNEXIT | NEWT_FLAG_SCROLL);
- for (j=0; j<numfstypes; j++) {
- snprintf(tmpstr,sizeof(tmpstr),"%s", fstypesnames[j]);
- newtListboxAddEntry(typeentry, tmpstr,
- (void *) (long)fstypes[j]);
- if (fstypes[j] == p->type.current)
- newtListboxSetCurrent(typeentry, j);
- else if (p->type.current == 0 &&
- fstypes[j] == LINUX_NATIVE_PARTITION)
- newtListboxSetCurrent(typeentry, j);
- }
- }
-
- /* have to fix this later */
- /* allowable drives goes in center under rest */
- row = 8;
- driveform = NULL;
- if (!p->immutable) {
- newtFormAddComponent(form, newtLabel(col, row, "Allowable Drives:"));
-
- sb = newtVerticalScrollbar(40, row, 4, 9, 10);
- driveform = newtForm(sb, NULL, 0);
- newtFormSetBackground(driveform, NEWT_COLORSET_CHECKBOX);
-
- for (j=0; j<numhd; j++) {
- driveentry[j].state = fdiskThisDriveSetIsActive(&p->drive,
- hdarr[j]->num);
- driveentry[j].cb = newtCheckbox(22, row+j, hdarr[j]->name+5,
- (driveentry[j].state) ? '*' : ' ',
- NULL,
- &driveentry[j].state);
- newtFormAddComponent(driveform, driveentry[j].cb);
- }
- if (j > 4) {
- newtFormSetHeight(driveform, 4);
- newtFormAddComponent(driveform, sb);
- } else {
- newtFormSetWidth(driveform, 10);
- }
- }
-
- /* setup type box callback */
- if (typeentry) {
- cb1.entry = &mntptentry;
- cb1.val = mntpt;
-
- /* yuck but it works */
- typebox_mp[0] = -1;
- inswapentry = (p->type.current == LINUX_SWAP_PARTITION);
- newtComponentAddCallback(typeentry,(newtCallback) typebox_scroll,&cb1);
- }
-
- /* setup mount point callback */
- if (!p->immutable) {
- cb2.form = &form;
- cb2.val = mntpt;
- cb2.val2 = &boot;
- memset(&cb2.curds, 0, sizeof(DriveSet));
- memcpy(&cb2.origds, &p->drive, sizeof(DriveSet));
- cb2.numhd = numhd;
- cb2.hdarr = hdarr;
- cb2.de = driveentry;
- cb2.dobootable = (fdiskIndexPartitionSpec(spec, "/boot", &j) !=
- FDISK_SUCCESS);
-
- newtComponentAddCallback(mntptentry,(newtCallback) entrybox_cb,&cb2);
- }
-
- row = 9+cval;
- ok = newtButton( 20, row, _("Ok"));
- cancel = newtButton( 40, row, _("Cancel"));
- if (mntptentry)
- newtFormAddComponents( form, mntptentry, NULL );
- if (sizeentry)
- newtFormAddComponents( form, sizeentry, NULL);
- if (growentry)
- newtFormAddComponents( form, growentry, NULL);
- if (typeentry)
- newtFormAddComponents( form, typeentry, NULL );
- if (driveform)
- newtFormAddComponents( form, driveform, NULL );
- newtFormAddComponents( form, ok, cancel, NULL);
-
- done = 0;
- while (!done) {
- answer = newtRunForm(form);
-
- if (answer != cancel) {
- /* modify partition request based on the entry boxes */
- if (typeentry) {
- tmpuint = (long) newtListboxGetCurrent( typeentry );
- fdiskSetConstraint(&p->type, tmpuint, tmpuint, tmpuint, 1);
- }
-
- /* make sure mount point is valid */
- if (p->type.current != LINUX_SWAP_PARTITION) {
- int valid=1;
- int skiprest=0;
-
- TrimWhitespace(mntpt);
-
- /* see if they even gave the partition a name */
- /* we will ask them if they really want to not */
- /* assign the partition a name at this time if */
- /* they have just created a non-ext2 partition */
- if (!*mntpt && p->type.current != LINUX_NATIVE_PARTITION) {
- if (newtWinChoice(_("No Mount Point"), _("Yes"), _("No"),
- _("You have not selected a mount point "
- "for this partition. Are you sure you "
- "want to do this?")) == 2)
- continue;
- else {
- /* we need a name for this partition */
- /* we'll name them like swap partitions */
- /* except use 'DOSxxx' */
- if (strncmp("Dos", entry->name, 4)) {
- char *t;
- fdiskMakeUniqSpecName( spec, "Dos", &t );
- fdiskRenamePartitionSpec(spec, entry->name, t);
- }
- skiprest = 1;
- }
- }
-
-
- /* do old test first */
- if (!skiprest) {
- if (entry->status != REQUEST_ORIGINAL || *mntpt)
- if (badMountPoint(p->type.current, mntpt))
- continue;
-
-
- if (entry->status == REQUEST_ORIGINAL) {
- /* this is an original partition, should have a */
- /* mount point of "" or a valid path */
- if (*mntpt &&
- (*mntpt != '/' || ((strcmp(entry->name, mntpt) &&
- !fdiskIndexPartitionSpec(spec, mntpt, &tmpuint))))) {
- valid = 0;
- }
- } else if (*mntpt != '/' || (strcmp(entry->name, mntpt) &&
- !fdiskIndexPartitionSpec(spec, mntpt, &tmpuint))) {
- valid = 0;
- }
- }
-
- if (!valid) {
- newtWinMessage(_("Mount Point Error"), _("Ok"),
- _("The mount point requested is either an illegal "
- "path or is already in use. Please select a "
- "valid mount point."));
-
- continue;
- }
- }
-
- if (sizeentry) {
- tmpint=strtol(size, &eptr, 10);
- if (eptr != size && *eptr == 0 && tmpint > 0) {
- tmpint *= SECPERMEG;
- if (growentry && grow != ' ')
- fdiskSetConstraint(&p->size,0,tmpint,FDISK_SIZE_MAX,1);
- else
- fdiskSetConstraint(&p->size,0,tmpint,tmpint,1);
- } else {
- newtWinMessage(_("Size Error"), _("Ok"),
- _("The size requested is illegal. Make sure the "
- "size is greater and zero (0), and is specified "
- "int decimal (base 10) format."));
- continue;
- }
- }
-
- /* make sure swap partitions are not too large */
- /* (PAGESIZE - 10)*8*PAGESIZE */
- /* on the right arch's */
- if (p->type.current == LINUX_SWAP_PARTITION) {
- unsigned int maxswap;
- #if defined(__alpha__)
- maxswap = (8192-10)*8*8192;
- #else
- maxswap = (4096-10)*8*4096;
- #endif
-
- if (p->size.min*SECTORSIZE > maxswap) {
- newtWinMessage(_("Swap Size Error"), _("Ok"),
- _("You have created a swap partition which is too "
- "large. The maximum size of a swap partition is "
- "%d Megabytes."), maxswap / 1024 / 1024);
- continue;
- }
- }
-
- if (driveform) {
- fdiskDeactivateAllDriveSet( &p->drive );
- for (j=0; j<numhd; j++)
- if (driveentry[j].state == '*')
- fdiskActivateDriveSet( &p->drive, hdarr[j]->num );
- }
-
- /* fdiskHandleSpecialPartitions() will do this for us */
- /* so I'm taking the boot entry out for now */
-
- if (p->type.current == LINUX_SWAP_PARTITION) {
- /* make sure we have a valid swap partition name */
- if (strncmp("Swap", entry->name, 4)) {
- char *t;
- fdiskMakeSwapSpecName( spec, &t );
- fdiskRenamePartitionSpec(spec, entry->name, t);
- free(t);
- }
- }
-
- /* first see if they changed the mount point */
- /* we only worry about ext2 and dos partitions */
- /* which have a valid mntpt */
- /* LOGIC is not the word for how all this works */
- if (p->type.current != LINUX_SWAP_PARTITION &&
- strncmp("Dos", mntpt, 3)) {
- TrimWhitespace(mntpt);
- if (p->immutable)
- status = REQUEST_ORIGINAL;
- else
- status = REQUEST_PENDING;
-
- if (strcmp(mntpt, entry->name)) {
- /* if this is an original partition which we just set */
- /* the name back to '' from a real name, set name back */
- /* to the 'Existxxxxx' name */
- if (entry->status == REQUEST_ORIGINAL && !*mntpt) {
- for (hdidx=0; hdidx < numhd; hdidx++)
- if (hdarr[hdidx]->num == p->drive.current)
- break;
-
- if (hdidx != numhd)
- sprintf(tmpstr, "Exist%03d%03d",
- hdarr[hdidx]->num, p->num.current);
- else
- strcpy(tmpstr,"Exist999999");
-
- fdiskRenamePartitionSpec( spec, entry->name, tmpstr );
- fdiskModifyPartitionSpec( spec, tmpstr, p, status);
- } else {
- fdiskRenamePartitionSpec( spec, entry->name, mntpt );
-
- /* this is a big kludge! */
- /* reset bootable partition handling so if we */
- /* rename '/' to '/usr', we don't enforce rules */
- fdiskSetConstraint(&p->endcyl,
- 0,FDISK_ENDCYL_MIN,FDISK_ENDCYL_MAX,0);
- fdiskModifyPartitionSpec( spec, mntpt, p, status);
- }
- } else {
- fdiskModifyPartitionSpec( spec, mntpt, p, status);
- }
- } else {
- fdiskModifyPartitionSpec( spec, entry->name, p, status);
- }
-
- fdiskHandleSpecialPartitions( spec );
- status = FDISK_SUCCESS;
- done = 1;
- } else {
- status = FDISK_ERR_USERABORT;
- done = 1;
- }
- }
-
- newtPopWindow();
- newtFormDestroy(form);
-
- return status;
- }
-
- /* add a partition spec */
- static int AddPartitionSpec(HardDrive **hdarr, unsigned int numhd,
- PartitionSpec *spec) {
-
- Partition template;
- int status;
- unsigned int i;
-
- /* create a template partitionspec to send to editpartition */
- memset(&template, 0, sizeof(Partition));
- template.size.min = SECPERMEG;
-
- /* insert with a name we know to mean its a new partition */
- fdiskInsertPartitionSpec(spec, NEW_PARTSPEC, &template, REQUEST_PENDING);
- fdiskIndexPartitionSpec( spec, NEW_PARTSPEC, &i );
- status = EditPartitionSpec(hdarr, numhd, spec, &spec->entry[i]);
- if (status == FDISK_SUCCESS) {
- return FDISK_SUCCESS;
- } else {
- fdiskDeletePartitionSpec(spec, NEW_PARTSPEC);
- return FDISK_ERR_USERABORT;
- }
- }
-
-
- /* delete a partition spec */
- static int DeletePartitionSpec( HardDrive **hdarr, unsigned int numhd,
- PartitionSpec *spec, PartitionSpecEntry *entry,
- int force) {
-
- Partition *p;
- int status;
- unsigned int c, l, m, n, t;
- char *tmpstr;
-
- p = &entry->partition;
-
- tmpstr=strdup(entry->name);
-
- if (!force && newtWinChoice(_("Delete Partition"), _("Yes"), _("No"),
- _("Are you sure you want to delete "
- "this partiton?")) == 2)
- return FDISK_ERR_USERABORT;
-
- if (p->immutable) {
- fdiskGetCurrentConstraint(&p->num, &c);
- fdiskGetCurrentConstraint(&p->type, &t);
- fdiskGetCurrentDriveSet(&p->drive, &l);
- for (m=0; m<numhd; m++)
- if (hdarr[m]->num == l)
- break;
-
- fdiskRemovePartition(hdarr[m], c);
-
- /* make it so we can delete this partition now */
- p->immutable = 0;
- fdiskModifyPartitionSpec( spec, tmpstr, p, REQUEST_PENDING );
-
- /* ok, see if this was the last immutable logical partition */
- /* in an immutable primary extended partition */
- /* we pray that fdiskCleanOriginal... will get rid of the */
- /* spec entry for the pep */
- if (c > 4) {
- if (fdiskLastLogical( hdarr[m], &n ) != FDISK_SUCCESS) {
- /* all logicals are gone, blow away pep */
- if (hdarr[m]->pep && hdarr[m]->table[hdarr[m]->pep].immutable){
- fdiskRemovePartition(hdarr[m], hdarr[m]->pep);
- }
- }
- }
- }
-
- status = fdiskDeletePartitionSpec( spec, tmpstr );
- fdiskHandleSpecialPartitions( spec );
- free(tmpstr);
-
- return FDISK_SUCCESS;
- }
-
- /* edit/add an NFS partition -> set index to -1 if adding new */
- int EditNFSMount( struct fstab *remotefs, int index,
- struct intfInfo *intf, struct netInfo *netc,
- struct driversLoaded **dl ) {
-
- int rc;
- struct fstabEntry entry;
-
- if (!(intf->set & INTFINFO_HAS_BOOTPROTO)) {
- rc = bringUpNetworking(intf, netc, dl, 1);
- } else {
- rc = 0;
- }
-
- if (rc)
- return 1;
-
- if (index == -1) {
- initFstabEntry(&entry);
- entry.type = PART_NFS;
- entry.tagName = "NFS Mount";
- entry.device = NULL;
- entry.mntpoint = NULL;
- rc = editNetMountPoint(&entry);
- if (!rc)
- addFstabEntry(remotefs, entry);
- } else {
- rc = editNetMountPoint(&remotefs->entries[index]);
- }
-
- return rc;
- }
-
-
- /* remote fstab entry */
- int DeleteNFSMount(struct fstab *remotefs, int index) {
- int i;
-
- if (remotefs->numEntries < 1)
- return 0;
-
- for (i=index; i<remotefs->numEntries-1; i++)
- remotefs->entries[i] = remotefs->entries[i+1];
-
- remotefs->numEntries -= 1;
- return 0;
- }
-
- /* used for each line in partbox - tells us what is on that line */
- enum partbox_types {PARTBOX_COMMENT, PARTBOX_NFS, PARTBOX_PART};
- struct partbox_entry {
- enum partbox_types type; /* what is on this line */
- int index; /* index in nfs or partition arrays */
- int hilite; /* element in drive window to hilight */
- };
-
- /* simple callback for scrollbox skipping non-entries */
- struct partbox_struct {
- unsigned int len; /* total entries allocated */
- unsigned int num; /* number in use */
- newtComponent *dbox; /* drive box */
- struct partbox_entry *entry; /* describes use of this line */
- };
-
- /* this is some ugly sh*t, don't try this at home kids */
- static void partbox_scroll(newtComponent list, struct partbox_struct *status) {
-
- static int last=-1;
- static int dontforce=0;
- int sel;
- int i;
- int odir, dir;
- int done;
- int lasttry;
-
- /* get the index into the partbox_struct array */
- sel = (long) newtListboxGetCurrent(list);
-
- /* see if this callback occurred because we were forcing */
- /* listbox to scroll */
- if (dontforce) {
- dontforce = 0;
- return;
- }
-
- /* if the element is ok then just return */
- if (status->entry[sel].type != PARTBOX_COMMENT) {
- if (status->entry[sel].type == PARTBOX_PART &&
- status->entry[sel].hilite >= 0 && status->dbox != NULL)
- newtListboxSetCurrent(*status->dbox, status->entry[sel].hilite);
- return;
- }
-
- /* see which direction we're heading , >0 means down, < 0 means up */
- if (last == -1)
- dir = 1;
- else {
- if (sel > last)
- dir = 1;
- else
- dir = -1;
- }
-
- odir = dir;
- done = 0;
- lasttry = 0;
- while (!done) {
- if (dir > 0) {
- for (i=sel; i < status->num; i++)
- if (status->entry[i].type != PARTBOX_COMMENT)
- break;
-
- if (i!=status->num) {
- dontforce = 1;
- newtListboxSetCurrent(list, i);
- last = i;
- done = 1;
-
- if (lasttry) {
- /* scroll to top, since this is last try so original */
- /* direction was going up */
- dontforce = 1;
- newtListboxSetCurrent(list, 0);
- dontforce = 1;
- newtListboxSetCurrent(list,last);
- }
- } else {
- if (!lasttry) {
- dir = -1;
- lasttry = 1;
- } else {
- done = 1;
- }
- }
- } else {
- for (i=sel; i >= 0; i--)
- if (status->entry[i].type != PARTBOX_COMMENT)
- break;
-
- if (i >= 0) {
- dontforce = 1;
- newtListboxSetCurrent(list, i);
- last = i;
- done = 1;
-
- if (lasttry) {
- /* scroll to bottom, since this is last try so original */
- /* direction was going up */
- dontforce = 1;
- newtListboxSetCurrent(list, status->num-1);
- dontforce = 1;
- newtListboxSetCurrent(list,last);
- }
- } else {
- if (!lasttry) {
- dir = 1;
- lasttry = 1;
- } else {
- done = 1;
- }
- }
- }
- }
-
- /* if we found a valid line then move drive box selection too */
- sel = (long) newtListboxGetCurrent(list);
- if (status->entry[sel].type == PARTBOX_PART &&
- status->entry[sel].hilite >= 0 && status->dbox != NULL)
- newtListboxSetCurrent(*status->dbox, status->entry[sel].hilite);
- }
-
-
- static int MakeDriveBox( HardDrive **hdarr, unsigned int numhd,
- unsigned int *drvused, int dheight,
- newtComponent *dbox ) {
- int hdidx, i, per;
- char tmpstr[80];
-
- *dbox = newtListbox( -1, -1, dheight, NEWT_FLAG_SCROLL );
- newtComponentTakesFocus( *dbox, 0 );
- for (hdidx=0; hdidx < numhd; hdidx++) {
- snprintf(tmpstr,sizeof(tmpstr),
- " %s [%5d/%3d/%2d] "
- "%6dM %6dM %6dM"
- " ",
- hdarr[hdidx]->name+5,
- hdarr[hdidx]->geom.cylinders,
- hdarr[hdidx]->geom.heads,
- hdarr[hdidx]->geom.sectors,
- hdarr[hdidx]->totalsectors/SECPERMEG,
- drvused[hdidx]/SECPERMEG,
- hdarr[hdidx]->totalsectors/SECPERMEG-drvused[hdidx]/SECPERMEG
- );
-
- tmpstr[58]='[';
- tmpstr[69]=']';
- per = (100*drvused[hdidx])/hdarr[hdidx]->totalsectors;
- if (per >= 99)
- per = 10;
- else
- per = per/10;
-
- for (i=0; i < per; i++)
- tmpstr[59+i] = '#';
-
- tmpstr[74]=0;
- newtListboxAddEntry(*dbox, tmpstr, (void *) 0);
- }
-
- return FDISK_SUCCESS;
- }
-
- /* given partitoins/hard drives, returns a listbox for use */
- /* includes the callback function to skip over headings */
- static int MakePartBox( HardDrive **hdarr, unsigned int numhd,
- PartitionSpec *spec, struct fstab *remotefs,
- int x, int y, int pheight, int dheight,
- newtComponent *list, struct partbox_struct *status,
- newtComponent *dbox) {
-
- newtComponent partbox;
-
- unsigned int drivenum;
- unsigned int totalused;
- int col;
- int i, k, hdidx;
-
- unsigned int listlen;
- unsigned int foundpart;
- char tmpstr[80];
- int num;
-
- unsigned int *drvused=alloca(numhd*sizeof(unsigned int));
-
- memset(drvused, 0, numhd*sizeof(unsigned int));
-
- /* check if there are *any* partitions to display */
- for (i = 0, num = 0; i < spec->num; i++) {
- if (fdiskIsExtended(spec->entry[i].partition.type.current))
- continue;
- num++;
- }
- num += remotefs->numEntries;
- if (!num) {
- *list = NULL;
- MakeDriveBox( hdarr, numhd, drvused, dheight, dbox );
- return FDISK_ERR_BADNUM;
- }
-
- partbox = newtListbox(-1, -1, pheight,
- NEWT_FLAG_RETURNEXIT | NEWT_FLAG_SCROLL);
-
- listlen = 0;
- status->entry=(struct partbox_entry *)malloc(100*
- sizeof(struct partbox_entry));
- status->len = 100;
- memset(status->entry, 0, status->len*sizeof(struct partbox_entry));
-
- status->dbox = NULL;
- for (hdidx=0; hdidx < numhd; hdidx++) {
- drivenum = hdarr[hdidx]->num;
-
- /* display all spec'd partitions for this drive */
- foundpart = 0;
- totalused = 0;
- for (i=0; i<spec->num; i++) {
- unsigned int num, minsize, actsize, drive, totsize;
- char statstr[80];
- char *pname, *devname;
- Partition *p;
-
- if (spec->entry[i].status == REQUEST_DENIED)
- continue;
-
- p = &spec->entry[i].partition;
- if ((drive = p->drive.current) != drivenum)
- continue;
-
- if (fdiskIsExtended(p->type.current))
- continue;
-
- num = p->num.current;
- actsize = p->size.current;
- minsize = p->size.min;
- pname = spec->entry[i].name;
- devname = hdarr[hdidx]->name;
- totsize = hdarr[hdidx]->totalsectors;
-
- if (!foundpart)
- foundpart = 1;
-
- /* increment amount of space used */
- totalused += actsize;
-
- /* mount point */
- col = 3;
- memset(statstr, ' ', sizeof(statstr));
- if (strncmp("Exist", pname, 5) && strncmp("Swap", pname, 4) &&
- strncmp("Dos", pname, 3))
- BuildTableField( statstr, pname, col, 16, 0 );
-
- /* Block device */
- snprintf(tmpstr, sizeof(tmpstr), "%s%d", devname+5, num );
- col += 22;
- BuildTableField( statstr, tmpstr, col, 10, 0 );
-
- /* Size */
- snprintf(tmpstr, sizeof(tmpstr), "%5dM", minsize/SECPERMEG);
- col += 10;
- BuildTableField( statstr, tmpstr, col, 9, 1 );
-
- snprintf(tmpstr, sizeof(tmpstr), "%5dM", actsize/SECPERMEG);
- col += 10;
- BuildTableField( statstr, tmpstr, col, 9, 1 );
-
- /* we dont want to see all that stuff, just English label */
- /* for the type */
- /* Type */
- col += 13;
- for (k=0; k<nparttypes; k++)
- if (allparttypes[k].index == p->type.current)
- break;
-
- if (k != nparttypes)
- snprintf(tmpstr, sizeof(tmpstr), "%s", allparttypes[k].name);
- else
- snprintf(tmpstr, sizeof(tmpstr), "0x%02x", p->type.current);
-
- BuildTableField( statstr, tmpstr, col, 18, 0);
-
- /* now stick it in listbox */
- statstr[73]=0;
- status->entry[listlen].type = PARTBOX_PART;
- status->entry[listlen].index = i;
- status->entry[listlen].hilite = hdidx;
- newtListboxAddEntry(partbox, statstr,(void *) (long) listlen);
- listlen++;
- }
-
- drvused[hdidx] = totalused;
- }
-
- for (i=0; i<remotefs->numEntries; i++) {
- char statstr[80];
-
- /* mount point */
- col = 2;
- memset(statstr, ' ', sizeof(statstr));
- BuildTableField( statstr, remotefs->entries[i].mntpoint, col, 16, 0 );
-
- /* Block device */
- col += 17;
- snprintf(tmpstr, sizeof(tmpstr), "%s:%s",
- remotefs->entries[i].netHost, remotefs->entries[i].netPath);
- BuildTableField( statstr, tmpstr, col, 40, 0 );
-
- /* Size */
- /* snprintf(tmpstr, sizeof(tmpstr), "%5dM/NA ", minsize/SECPERMEG);*/
- *tmpstr=0;
- col += 12;
- BuildTableField( statstr, "", col, 15, 0 );
-
- /* Type */
- col += 27;
- BuildTableField( statstr, "NFS", col, 18, 0);
-
- /* now stick it in listbox */
- statstr[70]=0;
- status->entry[listlen].type = PARTBOX_NFS;
- status->entry[listlen].index = i;
- newtListboxAddEntry(partbox, statstr,(void *) (long) (listlen));
- listlen++;
- }
-
-
- /* now display any partition specs which WERE NOT allocated */
- foundpart = 0;
- for (i=0; i<spec->num && !foundpart; i++)
- if (spec->entry[i].status == REQUEST_DENIED)
- foundpart = 1;
-
- if (foundpart) {
- status->entry[listlen].type = PARTBOX_COMMENT;
- newtListboxAddEntry(partbox,"", (void *)(long)listlen);
- listlen++;
- status->entry[listlen].type = PARTBOX_COMMENT;
- newtListboxAddEntry(partbox,"Unallocated requested partitions",
- (void *)(long)listlen);
- listlen++;
- status->entry[listlen].type = PARTBOX_COMMENT;
- newtListboxAddEntry(partbox,"--------------------------------",
- (void *)(long)listlen);
- listlen++;
-
- for (i=0; i<spec->num; i++) {
- if (spec->entry[i].status == REQUEST_DENIED) {
- unsigned int num, minsize, actsize;
- char statstr[80];
- char *pname;
- Partition *p;
-
- foundpart = 1;
- p = &spec->entry[i].partition;
- if (fdiskIsExtended(p->type.current))
- continue;
-
- num = p->num.current;
- minsize = p->size.min;
- actsize = p->size.current;
- pname = spec->entry[i].name;
-
- /* mount point */
- col = 3;
- memset(statstr, ' ', sizeof(statstr));
- if (strncmp("Exist", pname, 5) && strncmp("Swap", pname, 4) &&
- strncmp("Dos", pname, 3))
- BuildTableField( statstr, pname, col, 16, 0 );
-
- /* Reasons */
- col += 17;
- BuildTableField( statstr,
- GetReasonString(spec->entry[i].reason),
- col, 25, 0 );
-
- /* Size */
- snprintf(tmpstr, sizeof(tmpstr), "%5dM/NA ",
- minsize/SECPERMEG);
- col += 23;
- BuildTableField( statstr, tmpstr, col, 15, 0 );
-
- /* we dont want to see all that stuff, just English label */
- /* for the type */
- /* Type */
- col += 15;
- for (k=0; k<nparttypes; k++)
- if (allparttypes[k].index == p->type.current)
- break;
-
- if (k != nparttypes)
- snprintf(tmpstr, sizeof(tmpstr),"%s",allparttypes[k].name);
- else
- snprintf(tmpstr, sizeof(tmpstr),"0x%02x", p->type.current);
-
- BuildTableField( statstr, tmpstr, col, 18, 0);
-
- /* now stick it in listbox */
- statstr[70]=0;
- status->entry[listlen].type = PARTBOX_PART;
- status->entry[listlen].index = i;
- status->entry[listlen].hilite = -1;
- newtListboxAddEntry(partbox, statstr,(void *)(long)(listlen));
- listlen++;
- }
- }
- }
-
- /* mark the VERY end of listbox */
- status->num = listlen;
-
- /* setup the callback for the listbox */
- newtComponentAddCallback(partbox, (newtCallback) partbox_scroll, status);
- for (i=0; i<status->num-1;i++)
- if (status->entry[i].type != PARTBOX_COMMENT)
- break;
-
- if (i!=status->num)
- newtListboxSetCurrent(partbox,i);
-
- *list = partbox;
-
- /* now make the drive box IF desired */
- MakeDriveBox( hdarr, numhd, drvused, dheight, dbox );
-
- if (partbox)
- status->dbox = dbox;
-
-
- return 0;
- }
-
-
-
- /* do a operation on a partition */
- static int DoMenuFunction( char *function,
- HardDrive **orighd, unsigned int numhd,
- HardDrive **curhd,
- newtComponent partbox,
- struct partbox_struct *partbox_status,
- PartitionSpec *spec ) {
-
- unsigned int sel;
- int num=0;
- int status;
- int i;
- HardDrive *tmphdarr[MAX_HARDDRIVES];
-
- if (partbox) {
- sel = (long) newtListboxGetCurrent(partbox);
- if (partbox_status->entry[sel].type != PARTBOX_COMMENT)
- num = partbox_status->entry[sel].index;
- else
- num = -1;
- } else {
- num = -1;
- }
-
- for (i=0; i<numhd; i++) {
- tmphdarr[i] = (HardDrive *) alloca(sizeof(HardDrive));
- memcpy(tmphdarr[i], orighd[i], sizeof(HardDrive));
- }
-
- if (!strcmp("ADD", function)) {
- status = AddPartitionSpec(tmphdarr, numhd, spec);
- } else if (num >= 0 && !strcmp("EDIT", function)) {
- status = EditPartitionSpec(tmphdarr, numhd, spec, &spec->entry[num]);
- } else if (num >= 0 && !strcmp("DEL", function)) {
- status = DeletePartitionSpec(orighd, numhd, spec, &spec->entry[num],0);
- } else {
- status = FDISK_ERR_BADNUM;
- }
-
- if (status == FDISK_SUCCESS) {
- fdiskAutoInsertPartitions(orighd, numhd, tmphdarr, spec );
- showReasons( spec );
- fdiskGrowPartitions(orighd, numhd, tmphdarr, spec);
-
- /* if any original partitions were REMOVED we have to */
- /* sync up their entries in the partition spec table */
- /* with their actual representation in 'orighd'. */
- /* Mainly fixes up logical partition #'s which change */
- /* when other logical partitions are removed */
- if (!strcmp("DEL", function))
- fdiskCleanOriginalSpecs( orighd, numhd, spec );
-
- for (i=0; i<numhd; i++)
- memcpy(curhd[i],tmphdarr[i], sizeof(HardDrive));
-
- return FDISK_SUCCESS;
- } else {
- return FDISK_ERR_BADNUM;
- }
-
- }
-
- /* main loop of the program, builds the display of all drives/partitions */
- static int StartMaster( HardDrive **hdarr, unsigned int numhd,
- PartitionSpec *spec,
- struct fstab *remotefs,
- struct intfInfo *intf, struct netInfo *netc,
- struct driversLoaded **dl,
- int dontPartition,
- int *writeChanges) {
- newtComponent form, add, addnfs, del, edit, reset, ok, cancel, answer;
- newtComponent partbox, curcomponent;
- newtGrid buttons, grid;
- newtComponent dbox, partlabel, drivelabel, driveinfolabel;
- HardDrive *newhdarr[MAX_HARDDRIVES];
- HardDrive *prestinehdarr[MAX_HARDDRIVES];
- int formdone, totallydone, i, status;
- int currentselection;
- struct newtExitStruct event;
- char tmpstr[80];
- unsigned int width, height;
- int changesmade=0;
- int retcode = FDISK_SUCCESS; /* i'm optimistic */
- struct partbox_struct partbox_status;
- enum mywidgets {PARTBOX, ADD, ADDNFS, EDIT, DELETE,
- RESET, OK, CANCEL, NONE};
- enum mywidgets curwidget;
-
- width = 78;
- height = 20;
-
- /* FIXME: hack! */
- addnfs = (void *) 1;
- reset = (void *) 2;
-
- /* copy original hard drive configurations into work spaces */
- for (i=0; i<numhd; i++) {
- newhdarr[i] = (HardDrive *) alloca(sizeof(HardDrive));
- memcpy(newhdarr[i], hdarr[i], sizeof(HardDrive));
- prestinehdarr[i] = (HardDrive *) alloca(sizeof(HardDrive));
- memcpy(prestinehdarr[i], hdarr[i], sizeof(HardDrive));
- }
-
- /* build the main list of installed/probed devices */
- totallydone = 0;
- currentselection = -1;
- curwidget = NONE;
-
- newtCenteredWindow(width, height, _("Current Disk Partitions"));
-
- while (!totallydone) {
- /* are there ANY defined partitions ? */
- partlabel = newtLabel(-1, -1,
- " Mount Point Device Requested Actual Type");
- MakePartBox(newhdarr, numhd, spec, remotefs,
- 1, 2, height-12, 4,
- &partbox, &partbox_status, &dbox);
-
- form = newtForm(NULL, NULL, 0);
-
- if (dontPartition) {
- buttons = newtButtonBar(
- _("Edit"), &edit, _("Delete"), &del,
- _("Ok"), &ok, _("Back"), &cancel, NULL);
- add = reset = NULL;
- snprintf(tmpstr, sizeof(tmpstr),
- " F2-Add NFS F3-Edit F4-Delete"
- " F12-Ok v%5s", VERSION_STR);
- } else {
- buttons = newtButtonBar(_("Add"), &add,
- _("Edit"), &edit, _("Delete"), &del,
- _("Ok"), &ok, _("Back"), &cancel, NULL);
-
- newtFormAddHotKey(form, NEWT_KEY_F1);
- newtFormAddHotKey(form, NEWT_KEY_F5);
-
- snprintf(tmpstr, sizeof(tmpstr),
- " F1-Add F2-Add NFS F3-Edit "
- "F4-Delete F5-Reset F12-Ok v%5s", VERSION_STR);
- }
-
- drivelabel = newtLabel(-1, -1, _("Drive Summaries"));
- driveinfolabel = newtLabel(-1, -1,
- " Drive Geom [C/H/S] Total Used Free");
-
-
- grid = newtCreateGrid(1, 6);
- newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, partlabel,
- 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
- if (partbox)
- newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, partbox,
- 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
- newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, drivelabel,
- 0, partbox ? 0 : 8, 0, 0, NEWT_ANCHOR_LEFT, 0);
- newtGridSetField(grid, 0, 3, NEWT_GRID_COMPONENT, driveinfolabel,
- 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
- newtGridSetField(grid, 0, 4, NEWT_GRID_COMPONENT, dbox,
- 0, 0, 0, 0, 0, 0);
- newtGridSetField(grid, 0, 5, NEWT_GRID_SUBGRID, buttons,
- 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
-
- newtGridPlace(grid, 1, 0);
- newtGridAddComponentsToForm(grid, form, 1);
- newtGridFree(grid, 1);
-
- /* and the hotkeys */
- newtFormAddHotKey(form, NEWT_KEY_F2);
- newtFormAddHotKey(form, NEWT_KEY_F3);
- newtFormAddHotKey(form, NEWT_KEY_F4);
-
- /* and how to use this plus info on version */
- newtPushHelpLine(tmpstr);
-
- if (partbox) {
- if (currentselection < 0)
- currentselection = (long) newtListboxGetCurrent(partbox);
- else
- newtListboxSetCurrent(partbox, currentselection);
- }
-
- /* see if no partitions are present */
- /* we can't Add if we are in Read Only mode! */
- if (spec->num == 0 && !dontPartition)
- curwidget = ADD;
-
- /* set current widget if necessary */
-
- if (partbox != NULL && curwidget == PARTBOX)
- newtFormSetCurrent(form, partbox);
- else if (curwidget == ADD)
- newtFormSetCurrent(form, add);
- else if (curwidget == EDIT)
- newtFormSetCurrent(form, edit);
- else if (curwidget == DELETE)
- newtFormSetCurrent(form, del);
-
- /* setup main screen */
- formdone = 0;
- answer = NULL;
- while (!formdone) {
- newtFormRun(form, &event);
-
- /* store the current widget so we can reset it */
- /* if we have to destroy and recreate form */
- /* GetCurrent(), SetCurrent() use a ptr to */
- /* newtcomponent, so when we recreate form it */
- /* will be meaningless! */
- curcomponent = newtFormGetCurrent( form );
- curwidget = NONE;
- if (partbox != NULL && curcomponent == partbox)
- curwidget = PARTBOX;
- else if (curcomponent == add)
- curwidget = ADD;
- else if (curcomponent == addnfs)
- curwidget = ADDNFS;
- else if (curcomponent == edit)
- curwidget = EDIT;
- else if (curcomponent == del)
- curwidget = DELETE;
- else if (curcomponent == reset)
- curwidget = RESET;
- else
- curwidget = NONE;
-
- if (event.reason == NEWT_EXIT_HOTKEY) {
- event.reason = NEWT_EXIT_COMPONENT;
- if (event.u.key == NEWT_KEY_F12)
- event.u.co = ok;
- else if (event.u.key == NEWT_KEY_F1)
- event.u.co = add;
- else if (event.u.key == NEWT_KEY_F2)
- event.u.co = addnfs;
- else if (event.u.key == NEWT_KEY_F3)
- event.u.co = edit;
- else if (event.u.key == NEWT_KEY_F4)
- event.u.co = del;
- else if (event.u.key == NEWT_KEY_F5)
- event.u.co = reset;
- else
- continue;
- }
-
- if (event.reason == NEWT_EXIT_COMPONENT) {
- if (event.u.co != partbox) {
- if (event.u.co == ok || event.u.co == cancel) {
- if (event.u.co == ok) {
- *writeChanges = 1;
- /* make sure '/' is defined */
- status = fdiskIndexPartitionSpec(spec, "/", &i);
- if (!status)
- if (spec->entry[i].partition.type.current !=
- LINUX_NATIVE_PARTITION ||
- spec->entry[i].status == REQUEST_DENIED)
- status = 1;
-
- if (status) {
- newtWinMessage(_("No Root Partition"), _("Ok"),
- _("You must assign a root (/) "
- "partition "
- "to a Linux native partition (ext2) "
- "for the install to proceed."));
- continue;
- }
-
- /* make sure some swapspace is defined */
- status = 1;
- for (i=0; i < spec->num; i++)
- if (spec->entry[i].partition.type.current ==
- LINUX_SWAP_PARTITION &&
- spec->entry[i].status != REQUEST_DENIED) {
- status = 0;
- break;
- }
-
- if (status) {
- newtWinMessage(_("No Swap Partition"), _("Ok"),
- _("You must assign a swap "
- "partition "
- "for the install to proceed."));
- continue;
- }
- }
-
- /* make sure there are no unallocated partitions */
- status = 0;
- for (i=0; i < spec->num; i++)
- if (spec->entry[i].status == REQUEST_DENIED) {
- status = 1;
- break;
- }
-
- if (status) {
- if (newtWinChoice(_("Unallocated Partitions"),
- _("Yes"), _("No"),
- _("There are unallocated partitions "
- "left. If you quit now they will "
- "not be written to the disk.\n\n"
- "Are you sure you want to exit?")) == 2)
- continue;
- }
-
- /* dont trust the changes made I keep up with */
- /* above, compute it straight from the hd's */
- changesmade = DisksChanged( prestinehdarr,
- newhdarr,
- numhd );
- /* the dontPartition here isn't necessary, but it
- does make a reassuring sanity check */
- if (changesmade && !dontPartition) {
- int rc;
- rc = newtWinTernary(_("Save Changes"),
- _("Yes"), _("No"), _("Cancel"),
- _("Save changes to "
- "partition table(s)?"));
- if (rc == 1) {
- retcode = FDISK_SUCCESS;
- *writeChanges = 1;
-
- /* copy changes */
- if (changesmade) {
- for (i=0; i<numhd; i++) {
- memcpy(hdarr[i],
- newhdarr[i],
- sizeof(HardDrive));
- }
- }
- } else if (rc == 2) {
- retcode = FDISK_ERR_USERABORT;
- *writeChanges = 0;
- } else {
- continue;
- }
- } else {
- retcode = FDISK_SUCCESS; /* no changes made */
- }
-
- /* make sure we indicate they canceled */
- if (event.u.co == cancel)
- retcode = FDISK_ERR_USERABORT;
-
- formdone = 1;
- totallydone = 1;
- } else if (event.u.co == add) {
- status=DoMenuFunction("ADD", hdarr, numhd, newhdarr,
- partbox, &partbox_status, spec );
- if (status == FDISK_SUCCESS) {
- formdone = 1;
- changesmade = 1;
- }
- } else if (event.u.co == del && partbox != NULL) {
- /* see if its NFS or local mount */
- int sel;
- sel = (long) newtListboxGetCurrent(partbox);
- if (partbox_status.entry[sel].type == PARTBOX_PART)
- if (dontPartition)
- newtWinMessage(_("Error"), _("Ok"),
- _("You may only delete NFS mounts."));
- else
- status=DoMenuFunction("DEL", hdarr, numhd,
- newhdarr,
- partbox, &partbox_status,
- spec );
- else
- status=DeleteNFSMount(remotefs,
- partbox_status.entry[sel].index);
-
- if (status == FDISK_SUCCESS) {
- formdone = 1;
- changesmade = 1;
- }
- } else if (event.u.co == edit && partbox != NULL) {
- /* see if its NFS or local mount */
- int sel;
- sel = (long) newtListboxGetCurrent(partbox);
- if (partbox_status.entry[sel].type == PARTBOX_PART)
- status=DoMenuFunction("EDIT", hdarr, numhd,
- newhdarr,
- partbox, &partbox_status,
- spec );
- else
- status=EditNFSMount(remotefs,
- partbox_status.entry[sel].index,
- intf, netc, dl);
-
-
- if (status == FDISK_SUCCESS) {
- formdone = 1;
- changesmade = 1;
- }
- } else if (event.u.co == reset) {
- if (newtWinChoice(_("Reset Partition Table"),
- _("Yes"), _("No"),
- _("Reset partition table to original "
- "contents? ")) != 2) {
- for (i=0; i<numhd; i++)
- memcpy(hdarr[i],prestinehdarr[i],
- sizeof(HardDrive));
-
- fdiskWipePartitionSpec(spec);
- fdiskSetupPartitionSpec( hdarr, numhd, spec );
-
- changesmade = 0;
- formdone = 1;
- }
- } else if (event.u.co == addnfs) {
- status=EditNFSMount(remotefs, -1, intf, netc, dl);
-
- if (status == FDISK_SUCCESS) {
- formdone = 1;
- changesmade = 1;
- }
- }
- } else {
- /* see if its NFS or local mount */
- int sel;
- sel = (long) newtListboxGetCurrent(partbox);
- if (partbox_status.entry[sel].type == PARTBOX_PART)
- status=DoMenuFunction("EDIT", hdarr, numhd, newhdarr,
- partbox, &partbox_status, spec );
- else
- status=EditNFSMount(remotefs,
- partbox_status.entry[sel].index,
- intf, netc, dl);
-
- if (status == FDISK_SUCCESS) {
- formdone = 1;
- changesmade = 1;
- }
- }
- }
-
- /* save current line if leaving */
- if (partbox)
- currentselection = (long) newtListboxGetCurrent(partbox);
- }
-
- newtPopHelpLine();
- if (partbox)
- free(partbox_status.entry);
- newtFormDestroy(form);
- }
-
- newtPopWindow();
-
- return retcode;
- }
-
- /* converts a PartionSpec to an equivalent struct fstab */
- /* Creates fstab from scratch */
- static int PartitionSpecToFstab( HardDrive **hdarr, int numhd,
- PartitionSpec *spec, struct fstab *fstab ) {
-
- int i, j;
- struct fstabEntry entry;
-
- fstab->entries = malloc(sizeof(*fstab->entries) * spec->num);
- fstab->numEntries = 0;
- for (i = 0; i < spec->num; i++) {
- if (!spec->entry[i].name) continue;
-
- if (spec->entry[i].status != REQUEST_ORIGINAL &&
- spec->entry[i].status != REQUEST_GRANTED)
- continue;
-
- /* FIXME: hack, hack, hack */
- if (*spec->entry[i].name != '/' &&
- *spec->entry[i].name != 'S') continue;
-
- for (j=0; j<numhd; j++)
- if (hdarr[j]->num == spec->entry[i].partition.drive.current)
- break;
-
- if (j == numhd)
- continue;
-
- initFstabEntry(&entry);
- entry.mntpoint = strdup(spec->entry[i].name);
- entry.size = spec->entry[i].partition.size.current / 2;
-
- entry.device = malloc(6);
- sprintf(entry.device, "%s%d",
- hdarr[j]->name + 5, spec->entry[i].partition.num.current);
-
- switch (spec->entry[i].partition.type.current) {
- case LINUX_NATIVE_PARTITION:
- entry.type = PART_EXT2;
- entry.tagName = "Linux native";
- break;
-
- case LINUX_SWAP_PARTITION:
- entry.type = PART_SWAP;
- entry.tagName = "Linux swap";
- break;
-
- case DOS_PRIMARY_lt32MEG_PARTITION:
- case DOS_PRIMARY_gt32MEG_PARTITION:
- entry.type = PART_DOS;
- entry.tagName = "DOS 16-bit >=32";
- break;
-
- default:
- entry.type = PART_OTHER;
- entry.tagName = "Other";
- break;
- }
-
- addFstabEntry(fstab, entry);
- }
-
- fstabSort(fstab);
- return 0;
- }
-
-
- /* merges mount point info from existing struct fstab into a PartionSpec */
- /* PartitionSpec should already exist and be primed with existing partitions */
- /* Note - remote fs ARE NOT stored in the PartitionSpec */
- static int MergeFstabEntries( HardDrive **hdarr, int numhd,
- PartitionSpec *spec, struct fstab *fstab ) {
-
- int i, j, k;
- char device[6];
-
- for (j = 0; j < spec->num; j++) {
- for (k=0; k<numhd; k++)
- if (hdarr[k]->num == spec->entry[j].partition.drive.current)
- break;
-
- if (k == numhd)
- continue;
-
- sprintf(device, "%s%d",
- hdarr[k]->name + 5, spec->entry[j].partition.num.current);
-
- for (i = 0; i < fstab->numEntries; i++)
- if (!strcmp(fstab->entries[i].device, device))
- break;
-
- if ( i == fstab->numEntries )
- continue;
-
- /* we found a matching entry in the PartitionSpec */
- /* see if the old fstab file had any info we need */
- /* to use (like mount point, etc) */
- if (spec->entry[j].name)
- free(spec->entry[j].name);
-
- spec->entry[j].name = strdup(fstab->entries[i].mntpoint);
- }
-
- return 0;
- }
-
- /* suck out just the remote fs entries from an fstab */
- /* pretty much CopyFstab, with filter on type */
- struct fstab copyRemoteFSFstab(struct fstab * fstab) {
- struct fstab newfstab;
- int i, j;
-
- if (!fstab->numEntries) {
- newfstab.numEntries = 0;
- newfstab.entries = malloc(1);
- return newfstab;
- }
-
- /* duplicate the current fstab */
- newfstab.numEntries = fstab->numEntries;
- newfstab.entries = malloc(fstab->numEntries * sizeof(struct fstabEntry));
- for (i = j = 0; i < newfstab.numEntries; i++) {
- if (fstab->entries[i].type != PART_NFS)
- continue;
-
- if (fstab->entries[i].mntpoint) {
- newfstab.entries[j] = fstab->entries[i];
- newfstab.entries[j].mntpoint=nstrdup(fstab->entries[i].mntpoint);
- newfstab.entries[j].device = nstrdup(fstab->entries[i].device);
- newfstab.entries[j].netPath = nstrdup(fstab->entries[i].netPath);
- newfstab.entries[j].netHost = nstrdup(fstab->entries[i].netHost);
- j++;
- }
- }
-
- newfstab.numEntries = j;
-
- /* return the memory we don't actually need */
- newfstab.entries=realloc(newfstab.entries, j * sizeof(struct fstabEntry));
-
- return newfstab;
- }
-
-
- /* suck out just the remote fs entries from an fstab */
- /* pretty much CopyFstab, with filter on type */
- void MergeRemoteFSFstab(struct fstab *oldfstab, struct fstab *newfstab) {
- int i, j;
-
- /* copy remote fs entries */
- for (i = 0; i < oldfstab->numEntries; i++) {
- if (oldfstab->entries[i].type != PART_NFS)
- continue;
-
- if (oldfstab->entries[i].mntpoint) {
- j = newfstab->numEntries;
- newfstab->entries = realloc(newfstab->entries,
- (j+1)*sizeof(struct fstabEntry));
- newfstab->entries[j] = oldfstab->entries[i];
- newfstab->entries[j].mntpoint=nstrdup(oldfstab->entries[i].mntpoint);
- newfstab->entries[j].device=nstrdup(oldfstab->entries[i].device);
- newfstab->entries[j].netPath=nstrdup(oldfstab->entries[i].netPath);
- newfstab->entries[j].netHost=nstrdup(oldfstab->entries[i].netHost);
- newfstab->numEntries = j+1;
- }
- }
- }
-
- static int deletePartitionClass(HardDrive ** hd, int numhd,
- PartitionSpec * spec, int justLinux) {
- int deleteit;
- int type;
- int i;
-
- i = 0;
- while (i < spec->num) {
- type = spec->entry[i].partition.type.current;
-
- deleteit = !justLinux;
- if (justLinux && (type == LINUX_SWAP_PARTITION ||
- type == LINUX_NATIVE_PARTITION))
- deleteit = 1;
-
- if (deleteit) {
- DeletePartitionSpec(hd, numhd, spec, &spec->entry[i], 1);
- fdiskCleanOriginalSpecs( hd, numhd, spec );
- i=0; /* restart cause entries changed */
- continue;
- } else {
- i++;
- }
- }
-
- return 0;
- }
-
- int kickstartPartitioning(struct partitionTable * parts, struct fstab * fstab,
- char **drives) {
-
- HardDrive *hd[MAX_HARDDRIVES];
- HardDrive *tmphd[MAX_HARDDRIVES]; /* ORIGINAL HD partition data */
- unsigned int numhd; /* total # of drives to consider */
- Partition template;
- PartitionSpec spec;
- unsigned int i;
- struct fstab remotefstab;
- char ** deviceList;
- int rc;
- int numDrives;
-
- int size, maxsize, grow, clearall, clearlinux, zerombr;
- int argc;
- char *mntpt;
- char *eptr;
- char *sizestr, *maxsizestr;
- char **argv;
- poptContext optCon;
- struct poptOption ksPartOptions[] = {
- { "size", '\0', POPT_ARG_STRING, &sizestr, 0 },
- { "maxsize", '\0', POPT_ARG_STRING, &maxsize, 0 },
- { "grow", '\0', POPT_ARG_NONE, &grow, 0 },
- { 0, 0, 0, 0, 0 }
- };
-
- struct poptOption ksClearOptions[] = {
- { "linux", '\0', POPT_ARG_NONE, &clearlinux, 0},
- { "all", '\0', POPT_ARG_NONE, &clearall, 0},
- { 0, 0, 0, 0, 0 }
- };
-
- struct poptOption ksZeroMBROptions[] = {
- { 0, 0, 0, 0, 0 }
- };
-
- numDrives = 0;
- for (i = 0; drives[i]; i++, numDrives++);
-
- if (numDrives >= MAX_HARDDRIVES) {
- newtWinMessage(_("Too Many Drives"), _("Ok"),
- _("You have more drives than this program supports. "
- "Please use the standard fdisk program to setup your "
- "drives and please notify Red Hat Software that you "
- "saw this message."));
- return INST_ERROR;
- }
-
- deviceList = alloca(numDrives * sizeof(char *));
-
- for (i = 0; i < numDrives; i++) {
- deviceList[i] = alloca(15);
- strcpy(deviceList[i], "/tmp/");
- strcat(deviceList[i], drives[i]);
-
- if ((rc = devMakeInode(drives[i], deviceList[i]))) return INST_ERROR;
- }
-
- /* see if they want bad partition tables automatically zero'd */
- argv = NULL;
- zerombr = 0;
- while (1) {
- if (!ksGetCommand(KS_CMD_ZEROMBR, argv, &argc, &argv)) {
- char *t;
-
- optCon = poptGetContext(NULL, argc, argv, ksZeroMBROptions, 0);
-
- /* no options, but just a 'on' or 'off' command */
- /* have to parse options anyway to make popt see the leftover? */
- poptGetNextOpt(optCon);
- t = poptGetArg(optCon);
- if (*t && (!strcasecmp(t,"no") || !strcasecmp(t,"off") || !strcmp(t,"0")))
- zerombr = 0;
- else if (*t && (!strcasecmp(t,"yes") || !strcasecmp(t,"on") || !strcmp(t,"1")))
- zerombr = 1;
- else
- newtWinMessage(_("Zero Partition Table"), _("Ok"),
- _("bad argument to kickstart "
- "zerombr command: %s.\nMust be "
- "'on', '1', or 'yes' to enable, "
- "or 'off', '0', or 'no' to disable."),t);
-
- poptFreeContext(optCon);
- } else {
- break;
- }
- }
-
- /* Read in the partition tables from the requested drive(s) */
- /* first clear all entries */
- memset(hd, 0, MAX_HARDDRIVES*sizeof(HardDrive *));
- ReadDrives(deviceList, numDrives, hd, &numhd, zerombr, 0);
-
- if (numhd <1) {
- newtWinMessage(_("No Drives Found"), _("Ok"),
- _("An error has occurred - no valid devices were found "
- "on which to create new filesystems. Please check "
- "your hardware for the cause of this problem."));
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
- return INST_ERROR;
- }
-
-
- /* Translate into a PartitionSpec */
- memset(&spec, 0, sizeof(PartitionSpec));
- fdiskSetupPartitionSpec( hd, numhd, &spec );
-
- /* copy the fstab they passed, we'll use it until we're done */
- /* if they dont cancel it will be new fstab */
- remotefstab = copyRemoteFSFstab( fstab );
- MergeFstabEntries( hd, numhd, &spec, fstab );
-
- /* see if they want anything removed from disk */
- argv = NULL;
- clearall = 0;
- clearlinux = 0;
- if (!ksGetCommand(KS_CMD_CLEARPART, argv, &argc, &argv)) {
- optCon = poptGetContext(NULL, argc, argv, ksClearOptions, 0);
-
- rc = poptGetNextOpt(optCon);
- if ( rc < -1) {
- newtWinMessage(_("Clear Partition Command"), _("Ok"),
- _("bad argument to kickstart "
- "clearpart command %s: %s"),
- poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
- poptStrerror(rc));
-
- for (i=0; i<numhd; i++)
- fdiskCloseDevice(hd[i]);
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
-
- return INST_ERROR; /* may not clear what they intended */
- }
-
- if (clearall || clearlinux)
- deletePartitionClass(hd, numhd, &spec, clearlinux);
- poptFreeContext(optCon);
- }
-
- /* copy original hard drive configurations into work spaces */
- for (i=0; i<numhd; i++) {
- tmphd[i] = (HardDrive *) alloca(sizeof(HardDrive));
- memcpy(tmphd[i], hd[i], sizeof(HardDrive));
- }
-
-
- /* now stick their requests into the partition spec and allocate */
- /* the partitions */
- argv = NULL;
- while (1) {
- sizestr = NULL;
- maxsizestr = NULL;
- grow = 0;
- if (!ksGetCommand(KS_CMD_PART, argv, &argc, &argv)) {
- optCon = poptGetContext(NULL, argc, argv, ksPartOptions, 0);
-
- rc = poptGetNextOpt(optCon);
- if ( rc < -1) {
- newtWinMessage(_("Partition Command"), _("Ok"),
- _("bad argument to kickstart "
- "part command %s: %s"),
- poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
- poptStrerror(rc));
- }
-
- mntpt = poptGetArg(optCon);
-
- if (sizestr) {
- size=strtol(sizestr,&eptr, 10);
- if (eptr != sizestr && *eptr == 0 && size > 0)
- size *= SECPERMEG;
- else
- size = 0;
- } else {
- size=0;
- }
-
- if (maxsizestr) {
- maxsize=strtol(maxsizestr,&eptr, 10);
- if (eptr != maxsizestr && *eptr == 0 && maxsize > 0)
- maxsize *= SECPERMEG;
- else
- maxsize = 0;
- } else {
- maxsize=0;
- }
-
- if (maxsizestr && !maxsize)
- newtWinMessage(_("Option Ignored"), _("Ok"),
- _("The --maxsize option for the partition "
- "%s was ignored. Check that it is larger "
- "than the --size option."), mntpt);
-
- /* all done with current context */
- poptFreeContext(optCon);
-
- if (!mntpt || size == 0) {
- for (i=0; i<numhd; i++)
- fdiskCloseDevice(hd[i]);
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
- return INST_ERROR;
- }
-
- /* fill in the requested partition */
- memset(&template, 0, sizeof(Partition));
-
- /* set the size */
- if (grow)
- fdiskSetConstraint(&template.size,
- 0,
- size,
- (maxsize) ? maxsize : FDISK_SIZE_MAX,
- 1);
- else
- fdiskSetConstraint(&template.size,
- 0,
- size,
- size,
- 1);
-
- /* set the type */
- if (!strcasecmp(mntpt, "swap"))
- fdiskSetConstraint(&template.type,
- LINUX_SWAP_PARTITION,
- LINUX_SWAP_PARTITION,
- LINUX_SWAP_PARTITION,
- 1);
- else {
- fdiskSetConstraint(&template.type,
- LINUX_NATIVE_PARTITION,
- LINUX_NATIVE_PARTITION,
- LINUX_NATIVE_PARTITION,
- 1);
- /* test mntpt */
- if (badMountPoint(template.type.current, mntpt)) {
- for (i=0; i<numhd; i++)
- fdiskCloseDevice(hd[i]);
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
-
- return INST_ERROR;
- }
-
- if (!fdiskIndexPartitionSpec(&spec, mntpt, &rc)) {
- newtWinMessage(_("Mount Point Error"), _("Ok"),
- _("The mount point %s is already in use."), mntpt);
- for (i=0; i<numhd; i++)
- fdiskCloseDevice(hd[i]);
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
- return INST_ERROR;
- }
-
- }
-
- /* make sure we have a valid swap partition name */
- if (template.type.current == LINUX_SWAP_PARTITION) {
- if (strcasecmp("swap", mntpt)) {
- fdiskMakeSwapSpecName( &spec, &mntpt );
- }
- }
-
- /* make an entry */
- fdiskInsertPartitionSpec(&spec, mntpt,&template, REQUEST_PENDING);
- fdiskHandleSpecialPartitions( &spec );
- } else {
- break;
- }
- }
-
- /* insert the new partition spec */
- fdiskAutoInsertPartitions(hd, numhd, tmphd, &spec);
- showReasons( &spec );
- fdiskGrowPartitions(hd, numhd, tmphd, &spec);
-
- rc = REQUEST_GRANTED;
- for (i=0; i<spec.num; i++)
- if (spec.entry[i].status == REQUEST_DENIED) {
- rc = REQUEST_DENIED;
- newtWinMessage(_("Failed Allocation"), _("Ok"),
- _("The partition %s could not be allocated."),
- spec.entry[i].name);
- }
-
-
- if (rc == REQUEST_DENIED) {
- for (i=0; i<numhd; i++)
- fdiskCloseDevice(hd[i]);
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
-
- return INST_ERROR;
- }
-
- /* Write partitions to disk */
- for (i=0; i<numhd; i++)
- memcpy(hd[i], tmphd[i], sizeof(HardDrive));
-
- if (!testing) {
- for (i=0; i<numhd; i++)
- hd[i]->write_f(hd[i]);
- }
-
- if ((rc = findAllPartitions(NULL, parts))) {
- for (i=0; i<numhd; i++)
- fdiskCloseDevice(hd[i]);
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
-
- return INST_ERROR;
- }
-
- /* free up old fstab */
- if (fstab)
- freeFstab(*fstab);
- PartitionSpecToFstab( hd, numhd, &spec, fstab );
- MergeRemoteFSFstab( &remotefstab, fstab );
- freeFstab(remotefstab);
-
- for (i=0; i<numhd; i++)
- fdiskCloseDevice(hd[i]);
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
-
- return 0;
- }
-
- static int addNewPartition(PartitionSpec * spec,
- char * where, int megs, int grow, int bootable,
- unsigned char type, int startCyl) {
- Partition template;
-
- /* create a template partitionspec to send to editpartition */
- memset(&template, 0, sizeof(Partition));
- fdiskSetFixedConstraint(&template.type, type);
-
- if (bootable) {
- fdiskDeactivateAllDriveSet( &template.drive );
- fdiskActivateDriveSet(&template.drive, 1);
- fdiskActivateDriveSet(&template.drive, 2);
- fdiskSetConstraint(&template.endcyl, 0, 0, 1023, 1);
- }
-
- /* For now we'll make this alpha only code */
- #ifdef __alpha__
-
- if (startCyl != -1) {
- /* XXX HACK */
- /* Add a little buffer in case we need to skip a head */
- fdiskSetConstraint(&template.start, 0, startCyl, startCyl + 100, 1);
- }
-
- #endif
-
- fdiskSetConstraint(&template.size, SECPERMEG * megs, SECPERMEG * megs,
- grow ? FDISK_SIZE_MAX : SECPERMEG * megs, 1);
-
- /* insert with a name we know to mean its a new partition */
- fdiskInsertPartitionSpec(spec, where, &template,
- REQUEST_PENDING);
-
- return 0;
- }
-
- static int tryGoal(HardDrive ** hdarr, HardDrive ** tmphdarr, int numhd,
- PartitionSpec * spec, struct attemptedPartition * goals) {
- int i;
-
- for (i = 0; goals[i].mount; i++)
- addNewPartition(spec, goals[i].mount, goals[i].size,
- goals[i].grow, !strcmp(goals[i].mount, "/boot"),
- goals[i].type, goals[i].start);
-
- /* insert the new partition spec */
- fdiskAutoInsertPartitions(hdarr, numhd, tmphdarr, spec );
- fdiskGrowPartitions(hdarr, numhd, tmphdarr, spec);
-
- for (i = 0; i < spec->num; i++)
- if (spec->entry[i].status == REQUEST_DENIED)
- break;
-
- return (i < spec->num);
- }
-
- static int guessAtPartitioning(HardDrive ** hdarr, int numhd,
- PartitionSpec * spec, int * runDruid,
- int dir, int flags,
- struct attemptedPartition * goals) {
- HardDrive * tmparr[MAX_HARDDRIVES];
- int i, rc;
- static int mayDisplay = 1;
- int erasedLinux = 0;
- int erasedAll = 0;
-
- *runDruid = 1;
-
- if (!mayDisplay) {
- if (dir < 0) return INST_CANCEL;
- return 0;
- }
-
- for (i=0; i<numhd; i++) {
- tmparr[i] = (HardDrive *) alloca(sizeof(HardDrive));
- memcpy(tmparr[i], hdarr[i], sizeof(HardDrive));
- }
-
- if (fdiskIndexPartitionSpec(spec, "/", &i ) == FDISK_SUCCESS) {
- return 0;
- } else if (flags & (FSEDIT_CLEARLINUX | FSEDIT_CLEARALL)) {
- i = spec->num;
- deletePartitionClass(hdarr, numhd, spec,
- flags & FSEDIT_CLEARLINUX);
- if (spec->num != i) {
- erasedLinux = flags & FSEDIT_CLEARLINUX;
- erasedAll = flags & FSEDIT_CLEARALL;
- }
-
- rc = tryGoal(hdarr, tmparr, numhd, spec, goals);
- if (rc && (flags & FSEDIT_CLEARALL)) {
- i = spec->num;
- deletePartitionClass(hdarr, numhd, spec, 0);
- if (spec->num != i) {
- erasedAll = 1;
- memset(spec, 0, sizeof(PartitionSpec));
- fdiskSetupPartitionSpec( hdarr, numhd, spec );
- rc = tryGoal(hdarr, tmparr, numhd, spec, goals);
- }
- }
-
- if (!rc) {
- char message[2000];
-
- while (1) {
- strcpy(message, erasedAll ?
- "All of the partitions on your hard drive(s) will be "
- "erased.\n\n"
- "This means that all of the data on your system will be "
- "destroyed.\n"
- "\n"
- "If you do not want to lose all of your partitions, "
- "select \"Cancel\" now, and perform a \"Custom\" install."
- :
- "All of the Linux partitions on your hard drive(s) will be "
- "erased.\n\n"
- "This means that all of your previous Linux installations "
- "will be destroyed.\n"
- "\n"
- "If you do not want to lose all of your Linux partitions, "
- "select \"Cancel\" now, and perform a \"Custom\" install."
- );
-
- rc = newtWinChoice(_("Warning"), _("Ok"), _("Cancel"), message);
- if (rc == 2) return INST_CANCEL;
-
- rc = newtWinChoice(_("Warning"), _("Yes"), _("No"),
- _("You are about to lose data! Are you sure you want "
- "to do this?"));
- if (rc != 2) break;
- }
-
- *runDruid = 0, rc = 0;
- } else {
- newtWinMessage(_("Disk Space"), _("Ok"),
- _("There is not enough disk space for this type "
- "of installation."));
- return INST_CANCEL;
- }
- }
-
- if (*runDruid) {
- /* Put everything back */
- memset(spec, 0, sizeof(PartitionSpec));
- fdiskSetupPartitionSpec( hdarr, numhd, spec );
- } else {
- for (i=0; i<numhd; i++) {
- *hdarr[i] = *tmparr[i];
- }
- }
-
- mayDisplay = !(*runDruid);
-
- return 0;
- }
-
- /* main program */
- int FSEditPartitions(struct partitionTable * parts, struct fstab * fstab,
- char **drives,
- struct intfInfo * intf, struct netInfo * netc,
- struct driversLoaded ** dl,
- struct attemptedPartition * goals,
- int flags) {
- HardDrive *prestinehdarr[MAX_HARDDRIVES];
- HardDrive *hdarr[MAX_HARDDRIVES]; /* ORIGINAL HD partition data */
- unsigned int numhd; /* total # of drives to consider */
- PartitionSpec spec;
- unsigned int i;
- struct fstab remotefstab;
- char ** deviceList;
- int rc, ourrc = 0;
- int numDrives;
- static int beenManual = 0;
- int runDruid = 0;
- int writeChanges = 0;
- static int where = 0;
- int done = 0;
- int dir;
-
- if (where == 0)
- dir = 1;
- else
- dir = -1;
-
- numDrives = 0;
- for (i = 0; drives[i]; i++, numDrives++);
-
- if (numDrives >= MAX_HARDDRIVES) {
- newtWinMessage(_("Too Many Drives"), _("Ok"),
- _("You have more drives than this program supports. "
- "Please use the standard fdisk program to setup your "
- "drives and please notify Red Hat Software that you "
- "saw this message."));
- return INST_ERROR;
- }
-
- deviceList = alloca(numDrives * sizeof(char *));
-
- for (i = 0; i < numDrives; i++) {
- deviceList[i] = alloca(15);
- strcpy(deviceList[i], "/tmp/");
- strcat(deviceList[i], drives[i]);
-
- if ((rc = devMakeInode(drives[i], deviceList[i]))) return rc;
- }
-
- /* Read in the partition tables from the requested drive(s) */
- /* first clear all entries */
- memset(hdarr, 0, MAX_HARDDRIVES*sizeof(HardDrive *));
- rc = ReadDrives(deviceList, numDrives, hdarr, &numhd,0,
- flags & FSEDIT_READONLY);
- if (rc) return rc;
-
- if (numhd <1) {
- newtWinMessage(_("No Drives Found"), _("Ok"),
- _("An error has occurred - no valid devices were found "
- "on which to create new filesystems. Please check "
- "your hardware for the cause of this problem."));
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
- return INST_ERROR;
- }
-
- /* make backup of hdarr before user mucked with it */
- for (i=0; i<numhd; i++) {
- prestinehdarr[i] = (HardDrive *) alloca(sizeof(HardDrive));
- *prestinehdarr[i] = *hdarr[i];
- }
-
- /* Translate into a PartitionSpec */
- memset(&spec, 0, sizeof(PartitionSpec));
- fdiskSetupPartitionSpec( hdarr, numhd, &spec );
-
- /* copy the fstab they passed, we'll use it until we're done */
- /* if they dont cancel it will be new fstab */
- remotefstab = copyRemoteFSFstab( fstab );
- MergeFstabEntries( hdarr, numhd, &spec, fstab );
-
- if (flags & (FSEDIT_CLEARLINUX | FSEDIT_CLEARALL) && !beenManual) {
-
- if ((flags & FSEDIT_READONLY) || (!where && expert)) where = 1;
- rc = guessAtPartitioning(hdarr, numhd, &spec, &runDruid, dir,
- flags, goals ? goals : normalPartitioning);
- if (runDruid)
- return INST_CANCEL;
- else
- writeChanges = 1;
- } else
- beenManual = 1;
-
- if (beenManual) {
- /* Goto master screen */
- rc = StartMaster(hdarr, numhd, &spec,
- &remotefstab, intf, netc, dl,
- flags & FSEDIT_READONLY,
- &writeChanges);
- if (rc == FDISK_ERR_USERABORT)
- ourrc = INST_CANCEL;
- else if (rc)
- ourrc = INST_ERROR;
- else
- ourrc = 0;
- }
-
- if (writeChanges) {
-
- /* Write partitions to disk */
- if (!testing) {
- if (DisksChanged(prestinehdarr, hdarr, numhd)) {
- rc = 0;
- for (i=0; i<numhd; i++)
- rc |= hdarr[i]->write_f(hdarr[i]);
- if (rc) needReboot();
- }
- }
-
- if ((rc = findAllPartitions(NULL, parts))) {
-
- for (i=0; i<numhd; i++)
- fdiskCloseDevice(hdarr[i]);
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
-
- return INST_ERROR;
- }
-
- /* free up old fstab */
- if (fstab)
- freeFstab(*fstab);
- PartitionSpecToFstab( hdarr, numhd, &spec, fstab );
- MergeRemoteFSFstab( &remotefstab, fstab );
- freeFstab(remotefstab);
- }
-
- for (i=0; i<numhd; i++)
- fdiskCloseDevice(hdarr[i]);
-
- for (i = 0; i < numDrives; i++)
- unlink(deviceList[i]);
-
- return ourrc;
- }
-