disks.c revision 16718
159769Sgrog/*
259769Sgrog * The new sysinstall program.
324424Swosch *
424424Swosch * This is probably the last program in the `sysinstall' line - the next
524424Swosch * generation being essentially a complete rewrite.
624424Swosch *
724424Swosch * $Id: disks.c,v 1.51 1996/06/11 13:07:57 jkh Exp $
824424Swosch *
924424Swosch * Copyright (c) 1995
1024424Swosch *	Jordan Hubbard.  All rights reserved.
1124424Swosch *
1224424Swosch * Redistribution and use in source and binary forms, with or without
1324424Swosch * modification, are permitted provided that the following conditions
1424424Swosch * are met:
1542704Swosch * 1. Redistributions of source code must retain the above copyright
1642704Swosch *    notice, this list of conditions and the following disclaimer,
1742704Swosch *    verbatim and that no modifications are made prior to this
1824424Swosch *    point in the file.
1942704Swosch * 2. Redistributions in binary form must reproduce the above copyright
2042704Swosch *    notice, this list of conditions and the following disclaimer in the
2142704Swosch *    documentation and/or other materials provided with the distribution.
2242704Swosch *
2342704Swosch * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND
2442704Swosch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2542704Swosch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2642704Swosch * ARE DISCLAIMED.  IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
2742704Swosch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2842704Swosch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2942704Swosch * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION)
3059769Sgrog * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3159769Sgrog * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3259769Sgrog * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3359769Sgrog * SUCH DAMAGE.
3459769Sgrog *
3559769Sgrog */
3659769Sgrog
3759769Sgrog#include "sysinstall.h"
3859769Sgrog#include <ctype.h>
3924424Swosch#include <sys/disklabel.h>
4042704Swosch
4124424Swosch/* Where we start displaying chunk information on the screen */
4242704Swosch#define CHUNK_START_ROW		5
4324424Swosch
4442704Swosch/* Where we keep track of MBR chunks */
4524424Swoschstatic struct chunk *chunk_info[16];
4624424Swoschstatic int current_chunk;
4724424Swosch
4842704Swoschstatic void
4925031Swoschrecord_chunks(Disk *d)
5059156Swosch{
5125031Swosch    struct chunk *c1;
5225031Swosch    int i = 0;
5324424Swosch    int last_free = 0;
5424424Swosch    if (!d->chunks)
5524424Swosch	msgFatal("No chunk list found for %s!", d->name);
5624424Swosch    current_chunk = 0;
5771231Sitojun    for (c1 = d->chunks->part; c1; c1 = c1->next) {
5824424Swosch	if (c1->type == unused && c1->size > last_free) {
5971231Sitojun	    last_free = c1->size;
6025031Swosch	    current_chunk = i;
6171231Sitojun	}
6224424Swosch	chunk_info[i++] = c1;
6325031Swosch    }
6425031Swosch    chunk_info[i] = NULL;
6571231Sitojun}
6625031Swosch
6771231Sitojunstatic void
6870110Swoschprint_chunks(Disk *d)
6970110Swosch{
7070110Swosch    int row;
7170110Swosch    int i;
7270110Swosch
7370110Swosch    if ((!d->bios_cyl || d->bios_cyl > 65536) || (!d->bios_hd || d->bios_hd > 256) || (!d->bios_sect || d->bios_sect >= 64)) {
7470110Swosch	int sz;
7570110Swosch
7670110Swosch	dialog_clear();
7770110Swosch	msgConfirm("WARNING:  The current geometry for %s is incorrect.  Using\n"
7870110Swosch		   "a default geometry of 64 heads and 32 sectors.  If this geometry\n"
7980675Sasmodai		   "is incorrect or you are unsure as to whether or not it's correct,\n"
8080675Sasmodai		   "please consult the Hardware Guide in the Documentation submenu\n"
8180675Sasmodai		   "or use the (G)eometry command to change it now.", d->name);
8280675Sasmodai	d->bios_hd = 64;
8380675Sasmodai	d->bios_sect = 32;
8480675Sasmodai	sz = 0;
8580675Sasmodai	for (i = 0; chunk_info[i]; i++)
8680675Sasmodai	    sz += chunk_info[i]->size;
8780675Sasmodai	if (sz)
8880675Sasmodai	    d->bios_cyl = sz / ONE_MEG;
8980675Sasmodai	else
9080675Sasmodai	    msgConfirm("Couldn't set geometry!  You'll have to do it by hand.");
9180675Sasmodai    }
9280675Sasmodai    attrset(A_NORMAL);
9380675Sasmodai    mvaddstr(0, 0, "Disk name:\t");
9480675Sasmodai    clrtobot();
9580675Sasmodai    attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL);
9680675Sasmodai    attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL);
9780675Sasmodai    mvprintw(1, 0,
9880675Sasmodai	     "DISK Geometry:\t%lu cyls/%lu heads/%lu sectors",
9980675Sasmodai	     d->bios_cyl, d->bios_hd, d->bios_sect);
10080675Sasmodai    mvprintw(3, 1, "%10s %10s %10s %8s %8s %8s %8s %8s",
10180675Sasmodai	     "Offset", "Size", "End", "Name", "PType", "Desc",
10280675Sasmodai	     "Subtype", "Flags");
10380675Sasmodai    for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) {
10480675Sasmodai	if (i == current_chunk)
10580675Sasmodai	    attrset(ATTR_SELECTED);
10680675Sasmodai	mvprintw(row, 2, "%10ld %10lu %10lu %8s %8d %8s %8d\t%-6s",
10780675Sasmodai		 chunk_info[i]->offset, chunk_info[i]->size,
10880675Sasmodai		 chunk_info[i]->end, chunk_info[i]->name,
10980675Sasmodai		 chunk_info[i]->type, chunk_n[chunk_info[i]->type],
11080675Sasmodai		 chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i]));
11180675Sasmodai	if (i == current_chunk)
11280675Sasmodai	    attrset(A_NORMAL);
11380675Sasmodai    }
11480675Sasmodai}
11580675Sasmodai
11680675Sasmodaistatic void
11780675Sasmodaiprint_command_summary()
11880675Sasmodai{
11980675Sasmodai    mvprintw(14, 0, "The following commands are supported (in upper or lower case):");
12080675Sasmodai    mvprintw(16, 0, "A = Use Entire Disk    B = Bad Block Scan     C = Create Partition");
12180675Sasmodai    mvprintw(17, 0, "D = Delete Partition   G = Set Drive Geometry S = Set Bootable");
12280675Sasmodai    mvprintw(18, 0, "U = Undo All Changes   Q = Finish");
12380675Sasmodai    if (!RunningAsInit)
12480675Sasmodai	mvprintw(18, 46, "W = Write Changes");
12580675Sasmodai    mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select.");
12680675Sasmodai    move(0, 0);
12780675Sasmodai}
12880675Sasmodai
12980675Sasmodaistatic u_char *
13080675SasmodaigetBootMgr(char *dname)
13180675Sasmodai{
13280675Sasmodai    extern u_char mbr[], bteasy17[];
13380675Sasmodai    char str[80];
13480675Sasmodai    char *cp;
13580675Sasmodai    int i = 0;
13680675Sasmodai
13780675Sasmodai    cp = variable_get(VAR_BOOTMGR);
138101401Swosch    if (!cp) {
13980675Sasmodai	/* Figure out what kind of MBR the user wants */
140147593Shrs	sprintf(str, "Install Boot Manager for drive %s?", dname);
14187200Swosch	MenuMBRType.title = str;
142147593Shrs	i = dmenuOpenSimple(&MenuMBRType);
14380675Sasmodai    }
144104772Smaxim    else {
145104772Smaxim	if (!strncmp(cp, "boot", 4))
146104772Smaxim	    BootMgr = 0;
147104772Smaxim	else if (!strcmp(cp, "standard"))
148104781Sjhb	    BootMgr = 1;
149104781Sjhb	else
150104781Sjhb	    BootMgr = 2;
151104781Sjhb    }
152104781Sjhb    if (cp || i) {
153104781Sjhb	switch (BootMgr) {
154119217Smurray	case 0:
155147593Shrs	    return bteasy17;
156147593Shrs
157119217Smurray	case 1:
158119217Smurray	    return mbr;
159119217Smurray
160119217Smurray	case 2:
161132652Sosa	default:
162132652Sosa	    break;
163132652Sosa	}
164132652Sosa    }
165132652Sosa    return NULL;
166132652Sosa}
167132652Sosa
168132652Sosavoid
169132652SosadiskPartition(Device *dev, Disk *d)
170132652Sosa{
171140831Smaxim    char *p;
172176637Smaxim    int key = 0;
173176637Smaxim    Boolean chunking;
174132652Sosa    char *msg = NULL;
175132652Sosa    u_char *mbrContents;
176132652Sosa    WINDOW *w;
177171778Smaxim
178132652Sosa    chunking = TRUE;
179132652Sosa    keypad(stdscr, TRUE);
180132652Sosa
181132652Sosa    w = savescr();
182132652Sosa    clear();
183132652Sosa    record_chunks(d);
184132652Sosa    while (chunking) {
185158916Smaxim	print_chunks(d);
186158916Smaxim	print_command_summary();
187158916Smaxim	if (msg) {
188171778Smaxim	    attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL);
189158916Smaxim	    beep();
190158916Smaxim	    msg = NULL;
191158916Smaxim	}
192158916Smaxim
193158916Smaxim	key = toupper(getch());
194158916Smaxim	switch (key) {
195158916Smaxim
196158916Smaxim	case '\014':	/* ^L */
197158916Smaxim	    clear();
198158916Smaxim	    print_command_summary();
199158916Smaxim	    continue;
200158916Smaxim
201171778Smaxim	case KEY_UP:
202164001Smaxim	case '-':
203164001Smaxim	    if (current_chunk != 0)
204164001Smaxim		--current_chunk;
205164001Smaxim	    break;
206171778Smaxim
207164001Smaxim	case KEY_DOWN:
208166020Smaxim	case '+':
209166020Smaxim	case '\r':
210166020Smaxim	case '\n':
211166020Smaxim	    if (chunk_info[current_chunk + 1])
212171778Smaxim		++current_chunk;
213169192Smaxim	    break;
214171777Smaxim
215176637Smaxim	case KEY_HOME:
216176637Smaxim	    current_chunk = 0;
217173289Smaxim	    break;
218174783Smaxim
219175454Smaxim	case KEY_END:
220175454Smaxim	    while (chunk_info[current_chunk + 1])
221176637Smaxim		++current_chunk;
222176637Smaxim	    break;
223178706Smaxim
224180757Smaxim	case KEY_F(1):
225184517Smaxim	case '?':
226175454Smaxim	    systemDisplayHelp("slice");
227176637Smaxim	    break;
228152003Smaxim
229132652Sosa	case 'A': {
23024424Swosch	    int rv;
23124424Swosch
23224424Swosch	    rv = msgYesNo("Do you want to do this with a true partition entry\n"
23324424Swosch			  "so as to remain cooperative with any future possible\n"
23469277Sasmodai			  "operating systems on the drive(s)?");
23569277Sasmodai	    if (rv) {
23624424Swosch		rv = !msgYesNo("This is dangerous in that it will make the drive totally\n"
23725031Swosch			       "uncooperative with other potential operating systems on the\n"
23825031Swosch			       "same disk.  It will lead instead to a totally dedicated disk,\n"
23925031Swosch			       "starting at the very first sector, bypassing all BIOS geometry\n"
24080675Sasmodai			       "considerations.  This precludes the existance of any boot\n"
241104782Sjhb			       "manager or other stuff in sector 0, since the BSD bootstrap\n"
242144864Smaxim			       "will live there.\n"
24325031Swosch			       "You will run into serious trouble with ST-506 and ESDI drives\n"
244104782Sjhb			       "and possibly some IDE drives (e.g. drives running under the\n"
245104782Sjhb			       "control of sort of disk manager).  SCSI drives are considerably\n"
246104782Sjhb			       "less at risk.\n\n"
247104797Sjhb			       "Do you insist on dedicating the entire disk this way?");
248104797Sjhb	    }
24925031Swosch	    All_FreeBSD(d, rv);
25025031Swosch	    if (rv)
25125031Swosch		d->bios_hd = d->bios_sect = d->bios_cyl = 1;
25245349Swosch	    variable_set2(DISK_PARTITIONED, "yes");
25345349Swosch	    record_chunks(d);
254104782Sjhb	}
255104782Sjhb	break;
256104782Sjhb
257104782Sjhb	case 'B':
25842704Swosch	    if (chunk_info[current_chunk]->type != freebsd)
25925031Swosch		msg = "Can only scan for bad blocks in FreeBSD partition.";
26024424Swosch	    else if (strncmp(d->name, "sd", 2) ||
26159769Sgrog		     !msgYesNo("This typically makes sense only for ESDI, IDE or MFM drives.\n"
26225031Swosch			       "Are you sure you want to do this on a SCSI disk?")) {
26325031Swosch		if (chunk_info[current_chunk]->flags & CHUNK_BAD144)
26425031Swosch		    chunk_info[current_chunk]->flags &= ~CHUNK_BAD144;
26525031Swosch		else
26659769Sgrog		    chunk_info[current_chunk]->flags |= CHUNK_BAD144;
26725031Swosch	    }
26825031Swosch	    break;
26925031Swosch
27025031Swosch	case 'C':
27124424Swosch	    if (chunk_info[current_chunk]->type != unused)
27225031Swosch		msg = "Partition in use, delete it first or move to an unused one.";
27325031Swosch	    else {
27425031Swosch		char *val, tmp[20], *cp;
27525031Swosch		int size, subtype;
27625031Swosch		chunk_e partitiontype;
27759769Sgrog
27859769Sgrog		snprintf(tmp, 20, "%d", chunk_info[current_chunk]->size);
27942704Swosch		val = msgGetInput(tmp, "Please specify the size for new FreeBSD partition in blocks\n"
28042704Swosch				       "or append a trailing `M' for megabytes (e.g. 20M).");
28142704Swosch		if (val && (size = strtol(val, &cp, 0)) > 0) {
28270110Swosch		    if (*cp && toupper(*cp) == 'M')
28342704Swosch			size *= ONE_MEG;
28442704Swosch		    strcpy(tmp, "165");
28525031Swosch		    val = msgGetInput(tmp, "Enter type of partition to create:\n\n"
28625031Swosch				      "Pressing Enter will choose the default, a native FreeBSD\n"
28724424Swosch				      "partition (type 165).  You can choose other types, 6 for a\n"
28825031Swosch				      "DOS partition or 131 for a Linux partition, for example.\n\n"
28925031Swosch				      "Note:  If you choose a non-FreeBSD partition type, it will not\n"
29025031Swosch				      "be formatted or otherwise prepared, it will simply reserve space\n"
29125031Swosch				      "for you to use another tool, such as DOS FORMAT, to later format\n"
29225031Swosch				      "and use the partition.");
29325031Swosch		    if (val && (subtype = strtol(val, NULL, 0)) > 0) {
29425031Swosch			if (subtype==165)
29525031Swosch				partitiontype=freebsd;
29625031Swosch			else if (subtype==6)
29724424Swosch				partitiontype=fat;
29825031Swosch			else
29925031Swosch				partitiontype=unknown;
30025031Swosch		    Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype,
30125031Swosch				 (chunk_info[current_chunk]->flags & CHUNK_ALIGN));
30225031Swosch		    variable_set2(DISK_PARTITIONED, "yes");
30325031Swosch		    record_chunks(d);
30425031Swosch		    }
30525031Swosch		}
30659156Swosch	    }
30725031Swosch	    break;
30825031Swosch
30925031Swosch	case '\177':
31025031Swosch	case 'D':
31125031Swosch	    if (chunk_info[current_chunk]->type == unused)
31225031Swosch		msg = "Partition is already unused!";
31389981Sjoe	    else {
31425031Swosch		Delete_Chunk(d, chunk_info[current_chunk]);
31525031Swosch		variable_set2(DISK_PARTITIONED, "yes");
31625031Swosch		record_chunks(d);
31724424Swosch	    }
31825031Swosch	    break;
31925031Swosch
32089981Sjoe	case 'G': {
32125031Swosch	    char *val, geometry[80];
32289981Sjoe
32389981Sjoe	    snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect);
32425031Swosch	    val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n"
32589981Sjoe			      "Don't forget to use the two slash (/) separator characters!\n"
32689981Sjoe			      "It's not possible to parse the field without them.");
32789981Sjoe	    if (val) {
32870110Swosch		d->bios_cyl = strtol(val, &val, 0);
32971231Sitojun		d->bios_hd = strtol(val + 1, &val, 0);
33070110Swosch		d->bios_sect = strtol(val + 1, 0, 0);
33125031Swosch	    }
33271231Sitojun	}
33371231Sitojun	break;
33469278Sasmodai
33525031Swosch    case 'S':
33671231Sitojun	/* Set Bootable */
33770110Swosch	chunk_info[current_chunk]->flags |= CHUNK_ACTIVE;
33871231Sitojun	break;
33970110Swosch
34070110Swosch    case 'U':
34171231Sitojun	    clear();
34270110Swosch	    if (msgYesNo("Are you SURE you want to Undo everything?"))
34357000Swosch		break;
34425031Swosch	    d = Open_Disk(d->name);
34545349Swosch	    if (!d) {
34678270Snik		msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", d->name);
347170145Simp		break;
348170145Simp	    }
34971231Sitojun	    Free_Disk(dev->private);
35025031Swosch	    dev->private = d;
351147051Smaxim	    variable_unset(DISK_PARTITIONED);
352147051Smaxim	    record_chunks(d);
353147051Smaxim	    break;
354147051Smaxim
35557000Swosch	case 'W':
35638440Sjkh	    if (!msgYesNo("WARNING:  This should only be used for modifying an\n"
357147055Smaxim			  "EXISTING installation - DO NOT USE this option if you\n"
35870110Swosch			  "are installing FreeBSD for the first time!  This is not\n"
35969278Sasmodai			  "an option for use during the standard install.\n\n"
36070110Swosch			  "Are you absolutely sure you want to do this now?")) {
36125031Swosch		WINDOW *save = savescr();
36225031Swosch
36369278Sasmodai		variable_set2(DISK_PARTITIONED, "yes");
36445349Swosch		clear();
36570110Swosch
36669278Sasmodai		/* Don't trash the MBR if the first (and therefore only) chunk is marked for a truly dedicated
36745349Swosch		 * disk (i.e., the disklabel starts at sector 0), even in cases where the user has requested
36845349Swosch		 * booteasy or a "standard" MBR -- both would be fatal in this case.
36969278Sasmodai		 */
37069278Sasmodai		if ((d->chunks->part->flags & CHUNK_FORCE_ALL) != CHUNK_FORCE_ALL
37180675Sasmodai		    && (mbrContents = getBootMgr(d->name)) != NULL)
37269278Sasmodai		    Set_Boot_Mgr(d, mbrContents);
37370110Swosch
37469278Sasmodai		if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS)
37569278Sasmodai		    msgConfirm("Disk partition write returned an error status!");
37669278Sasmodai		else
37757000Swosch		    msgConfirm("Wrote FDISK partition information out successfully.");
37845349Swosch		restorescr(save);
37969277Sasmodai	    }
38045349Swosch	    break;
38166542Sitojun
38269277Sasmodai	case '|':
38357000Swosch	    if (!msgYesNo("Are you SURE you want to go into Wizard mode?\n"
38470110Swosch			  "No seat belts whatsoever are provided!")) {
38545349Swosch		WINDOW *w;
38657000Swosch
38769277Sasmodai		w = savescr();
38870110Swosch		dialog_clear();
38970110Swosch		end_dialog();
39042589Swosch		DialogActive = FALSE;
39170110Swosch		slice_wizard(d);
39270110Swosch		variable_set2(DISK_PARTITIONED, "yes");
39346321Swosch		dialog_clear();
39445349Swosch		DialogActive = TRUE;
39545349Swosch		record_chunks(d);
39657000Swosch		restorescr(w);
39746318Swosch	    }
39870110Swosch	    else
39956406Swosch		msg = "Wise choice!";
40055389Sbillf	    break;
40155389Sbillf
40257000Swosch	case 'Q':
40355389Sbillf	    chunking = FALSE;
40455389Sbillf	    clear();
40555389Sbillf	    /* Don't trash the MBR if the first (and therefore only) chunk is marked for a truly dedicated
40670110Swosch	     * disk (i.e., the disklabel starts at sector 0), even in cases where the user has requested
40758448Swosch	     * booteasy or a "standard" MBR -- both would be fatal in this case.
40858448Swosch	     */
40965412Swosch	    if ((d->chunks->part->flags & CHUNK_FORCE_ALL) != CHUNK_FORCE_ALL
41064612Salex		&& (mbrContents = getBootMgr(d->name)) != NULL)
41164612Salex		Set_Boot_Mgr(d, mbrContents);
41265411Swosch	    break;
41365974Swosch
41469277Sasmodai	default:
41569277Sasmodai	    beep();
41670119Swosch	    msg = "Type F1 or ? for help";
41769277Sasmodai	    break;
41870111Swosch	}
41980675Sasmodai    }
42075833Swosch    p = CheckRules(d);
42178867Sitojun    if (p) {
42279603Sitojun	char buf[FILENAME_MAX];
42384087Swosch
42483686Sobrien	dialog_clear();
425104797Sjhb        use_helpline("Press F1 to read more about disk partitioning.");
42687201Swosch	use_helpfile(systemHelpFile("partition", buf));
42792013Swosch	dialog_mesgbox("Disk partitioning warning:", p, -1, -1);
428104772Smaxim	free(p);
429101331Swosch    }
430101331Swosch    restorescr(w);
431104797Sjhb}
432104781Sjhb
433104781Sjhbstatic int
434104781SjhbpartitionHook(dialogMenuItem *selected)
435104659Smurray{
436106406Smaxim    Device **devs = NULL;
437111949Swosch
438111949Swosch    devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
439111949Swosch    if (!devs) {
440113054Smurray	msgConfirm("Unable to find disk %s!", selected->prompt);
441114211Swosch	return DITEM_FAILURE;
442114572Swosch    }
443119217Smurray    /* Toggle enabled status? */
444119217Smurray    if (!devs[0]->enabled) {
445121648Smurray	devs[0]->enabled = TRUE;
446121648Smurray	diskPartition(devs[0], (Disk *)devs[0]->private);
447126724Swosch    }
448121787Swosch    else
449124462Smaxim	devs[0]->enabled = FALSE;
450126235Swosch    return DITEM_SUCCESS | DITEM_REDRAW;
451128863Smaxim}
452128863Smaxim
453129793Shrsstatic int
454144864SmaximpartitionCheck(dialogMenuItem *selected)
455137120Smaxim{
456137326Shrs    Device **devs = NULL;
457138844Smaxim
458140831Smaxim    devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK);
459144864Smaxim    if (!devs || devs[0]->enabled == FALSE)
460147593Shrs	return FALSE;
461146091Smaxim    return TRUE;
462146071Smaxim}
463146433Smaxim
464152004Smaximint
465151926SmaximdiskPartitionEditor(dialogMenuItem *self)
466152003Smaxim{
467152004Smaxim    DMenu *menu;
468153699Smaxim    Device **devs;
469154120Smaxim    int i, cnt;
470158234Smaxim    char *cp;
471158956Smaxim
472158956Smaxim    cp = variable_get(VAR_DISK);
473160877Smaxim    devs = deviceFind(cp, DEVICE_TYPE_DISK);
474160663Smaxim    cnt = deviceCount(devs);
475163859Smaxim    if (!cnt) {
476164001Smaxim	msgConfirm("No disks found!  Please verify that your disk controller is being\n"
477164001Smaxim		   "properly probed at boot time.  See the Hardware Guide on the\n"
478166020Smaxim		   "Documentation menu for clues on diagnosing this type of problem.");
479166362Smaxim	i = DITEM_FAILURE;
480169192Smaxim    }
481171777Smaxim    else if (cnt == 1) {
482176637Smaxim	devs[0]->enabled = TRUE;
483173289Smaxim	diskPartition(devs[0], (Disk *)devs[0]->private);
484174783Smaxim	i = DITEM_SUCCESS;
485175454Smaxim    }
486176637Smaxim    else {
487176637Smaxim	menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook, partitionCheck);
488178706Smaxim	if (!menu) {
489180757Smaxim	    msgConfirm("No devices suitable for installation found!\n\n"
490184517Smaxim		       "Please verify that your disk controller (and attached drives)\n"
49124424Swosch		       "were detected properly.  This can be done by pressing the\n"
49224424Swosch		       "[Scroll Lock] key and using the Arrow keys to move back to\n"
49324424Swosch		       "the boot messages.  Press [Scroll Lock] again to return.");
49424424Swosch	    i = DITEM_FAILURE;
49524424Swosch	}
49624424Swosch	else {
49724424Swosch	    i = dmenuOpenSimple(menu) ? DITEM_SUCCESS : DITEM_FAILURE;
49824424Swosch	    free(menu);
49924424Swosch	}
50024424Swosch	i = i | DITEM_RESTORE | DITEM_RECREATE;
50124424Swosch    }
50224424Swosch    return i;
50324424Swosch}
50424424Swosch
50524424Swoschint
506134378SosadiskPartitionWrite(dialogMenuItem *self)
507134378Sosa{
508134378Sosa    Device **devs;
509134378Sosa    char *cp;
51025031Swosch    int i;
51125031Swosch
51224424Swosch    if ((cp = variable_get(DISK_PARTITIONED)) && strcmp(cp, "yes"))
51324424Swosch	return DITEM_SUCCESS;
51424424Swosch    else if (!cp) {
51524424Swosch	msgConfirm("You must partition the disk(s) before this option can be used.");
51659769Sgrog	return DITEM_FAILURE;
517147051Smaxim    }
51824424Swosch
51925031Swosch    devs = deviceFind(NULL, DEVICE_TYPE_DISK);
52025031Swosch    if (!devs) {
52125031Swosch	msgConfirm("Unable to find any disks to write to??");
52225031Swosch	return DITEM_FAILURE;
52359769Sgrog    }
52425031Swosch    if (isDebug())
52531658Swosch	msgDebug("diskPartitionWrite: Examining %d devices\n", deviceCount(devs));
52679514Sitojun
52731658Swosch    for (i = 0; devs[i]; i++) {
52859769Sgrog	Chunk *c1;
52979514Sitojun	Disk *d = (Disk *)devs[i]->private;
53059769Sgrog
53165415Swosch	if (!devs[i]->enabled)
532104786Sjhb	    continue;
53365415Swosch
53475834Swosch	Set_Boot_Blocks(d, boot1, boot2);
535156214Smaxim	msgNotify("Writing partition information to drive %s", d->name);
53675834Swosch	if (!Fake && Write_Disk(d)) {
53775834Swosch	    msgConfirm("ERROR: Unable to write data to disk %s!", d->name);
53875834Swosch	    return DITEM_FAILURE;
53925031Swosch	}
54025031Swosch	/* Now scan for bad blocks, if necessary */
54125031Swosch	for (c1 = d->chunks->part; c1; c1 = c1->next) {
54259769Sgrog	    if (c1->flags & CHUNK_BAD144) {
54325031Swosch		int ret;
54425031Swosch
54531658Swosch		msgNotify("Running bad block scan on partition %s", c1->name);
54625031Swosch		if (!Fake) {
54724424Swosch		    ret = vsystem("bad144 -v /dev/r%s 1234", c1->name);
548166020Smaxim		    if (ret)
549121787Swosch			msgConfirm("Bad144 init on %s returned status of %d!", c1->name, ret);
55042589Swosch		    ret = vsystem("bad144 -v -s /dev/r%s", c1->name);
55150970Speter		    if (ret)
552			msgConfirm("Bad144 scan on %s returned status of %d!", c1->name, ret);
553		}
554	    }
555	}
556    }
557    /* Now it's not "yes", but "written" */
558    variable_set2(DISK_PARTITIONED, "written");
559    return DITEM_SUCCESS;
560}
561