disks.c revision 18683
1232958Sbschmidt/* 2232958Sbschmidt * The new sysinstall program. 3232958Sbschmidt * 4232958Sbschmidt * This is probably the last program in the `sysinstall' line - the next 5232958Sbschmidt * generation being essentially a complete rewrite. 6232958Sbschmidt * 7232958Sbschmidt * $Id: disks.c,v 1.66 1996/10/03 06:01:31 jkh Exp $ 8232958Sbschmidt * 9232958Sbschmidt * Copyright (c) 1995 10232958Sbschmidt * Jordan Hubbard. All rights reserved. 11232958Sbschmidt * 12232958Sbschmidt * Redistribution and use in source and binary forms, with or without 13232958Sbschmidt * modification, are permitted provided that the following conditions 14232958Sbschmidt * are met: 15232958Sbschmidt * 1. Redistributions of source code must retain the above copyright 16232958Sbschmidt * notice, this list of conditions and the following disclaimer, 17232958Sbschmidt * verbatim and that no modifications are made prior to this 18232958Sbschmidt * point in the file. 19232958Sbschmidt * 2. Redistributions in binary form must reproduce the above copyright 20232958Sbschmidt * notice, this list of conditions and the following disclaimer in the 21232958Sbschmidt * documentation and/or other materials provided with the distribution. 22232958Sbschmidt * 23232958Sbschmidt * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 24232958Sbschmidt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25232958Sbschmidt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26232958Sbschmidt * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 27232958Sbschmidt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28232958Sbschmidt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29232958Sbschmidt * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 30232958Sbschmidt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31232958Sbschmidt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32232958Sbschmidt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33232958Sbschmidt * SUCH DAMAGE. 34232958Sbschmidt * 35232958Sbschmidt */ 36232958Sbschmidt 37232958Sbschmidt#include "sysinstall.h" 38232958Sbschmidt#include <ctype.h> 39232958Sbschmidt#include <sys/disklabel.h> 40232958Sbschmidt 41232958Sbschmidt/* Where we start displaying chunk information on the screen */ 42232958Sbschmidt#define CHUNK_START_ROW 5 43232958Sbschmidt 44232958Sbschmidt/* Where we keep track of MBR chunks */ 45232958Sbschmidtstatic struct chunk *chunk_info[16]; 46232958Sbschmidtstatic int current_chunk; 47232958Sbschmidt 48232958Sbschmidtstatic void 49232958Sbschmidtrecord_chunks(Disk *d) 50232958Sbschmidt{ 51232958Sbschmidt struct chunk *c1 = NULL; 52232958Sbschmidt int i = 0; 53232958Sbschmidt int last_free = 0; 54232958Sbschmidt 55232958Sbschmidt if (!d->chunks) 56232958Sbschmidt msgFatal("No chunk list found for %s!", d->name); 57232958Sbschmidt 58232958Sbschmidt for (c1 = d->chunks->part; c1; c1 = c1->next) { 59232958Sbschmidt if (c1->type == unused && c1->size > last_free) { 60232958Sbschmidt last_free = c1->size; 61232958Sbschmidt current_chunk = i; 62232958Sbschmidt } 63232958Sbschmidt chunk_info[i++] = c1; 64232958Sbschmidt } 65232958Sbschmidt chunk_info[i] = NULL; 66232958Sbschmidt} 67232958Sbschmidt 68232958Sbschmidtstatic void 69232958Sbschmidtprint_chunks(Disk *d) 70232958Sbschmidt{ 71232958Sbschmidt int row; 72232958Sbschmidt int i, sz; 73232958Sbschmidt 74232958Sbschmidt for (i = sz = 0; chunk_info[i]; i++) 75232958Sbschmidt sz += chunk_info[i]->size; 76232958Sbschmidt if (d->bios_hd <= 1 && d->bios_sect <= 1) { 77232958Sbschmidt All_FreeBSD(d, TRUE); 78232958Sbschmidt d->bios_hd = d->bios_sect = d->bios_cyl = 1; 79232958Sbschmidt } 80232958Sbschmidt else if (d->bios_cyl > 65536 || d->bios_hd > 256 || d->bios_sect >= 64) { 81232958Sbschmidt dialog_clear_norefresh(); 82232958Sbschmidt msgConfirm("WARNING: A geometry of %d/%d/%d for %s is incorrect. Using\n" 83232958Sbschmidt "a default geometry of 64 heads and 32 sectors. If this geometry\n" 84232958Sbschmidt "is incorrect or you are unsure as to whether or not it's correct,\n" 85232958Sbschmidt "please consult the Hardware Guide in the Documentation submenu\n" 86232958Sbschmidt "or use the (G)eometry command to change it now.", d->bios_cyl, d->bios_hd, d->bios_sect, d->name); 87232958Sbschmidt d->bios_hd = 64; 88232958Sbschmidt d->bios_sect = 32; 89232958Sbschmidt d->bios_cyl = sz / ONE_MEG; 90232958Sbschmidt } 91232958Sbschmidt attrset(A_NORMAL); 92232958Sbschmidt mvaddstr(0, 0, "Disk name:\t"); 93232958Sbschmidt clrtobot(); 94232958Sbschmidt attrset(A_REVERSE); addstr(d->name); attrset(A_NORMAL); 95232958Sbschmidt attrset(A_REVERSE); mvaddstr(0, 55, "FDISK Partition Editor"); attrset(A_NORMAL); 96232958Sbschmidt mvprintw(1, 0, 97232958Sbschmidt "DISK Geometry:\t%lu cyls/%lu heads/%lu sectors", 98232958Sbschmidt d->bios_cyl, d->bios_hd, d->bios_sect); 99232958Sbschmidt mvprintw(3, 1, "%10s %10s %10s %8s %8s %8s %8s %8s", 100232958Sbschmidt "Offset", "Size", "End", "Name", "PType", "Desc", 101232958Sbschmidt "Subtype", "Flags"); 102232958Sbschmidt for (i = 0, row = CHUNK_START_ROW; chunk_info[i]; i++, row++) { 103232958Sbschmidt if (i == current_chunk) 104232958Sbschmidt attrset(ATTR_SELECTED); 105232958Sbschmidt mvprintw(row, 2, "%10ld %10lu %10lu %8s %8d %8s %8d\t%-6s", 106232958Sbschmidt chunk_info[i]->offset, chunk_info[i]->size, 107232958Sbschmidt chunk_info[i]->end, chunk_info[i]->name, 108232958Sbschmidt chunk_info[i]->type, chunk_n[chunk_info[i]->type], 109232958Sbschmidt chunk_info[i]->subtype, ShowChunkFlags(chunk_info[i])); 110232958Sbschmidt if (i == current_chunk) 111232958Sbschmidt attrset(A_NORMAL); 112232958Sbschmidt } 113232958Sbschmidt} 114232958Sbschmidt 115232958Sbschmidtstatic void 116232958Sbschmidtprint_command_summary() 117232958Sbschmidt{ 118232958Sbschmidt mvprintw(14, 0, "The following commands are supported (in upper or lower case):"); 119232958Sbschmidt mvprintw(16, 0, "A = Use Entire Disk B = Bad Block Scan C = Create Partition"); 120232958Sbschmidt mvprintw(17, 0, "D = Delete Partition G = Set Drive Geometry S = Set Bootable"); 121232958Sbschmidt mvprintw(18, 0, "U = Undo All Changes Q = Finish"); 122232958Sbschmidt if (!RunningAsInit) 123232958Sbschmidt mvprintw(18, 46, "W = Write Changes"); 124232958Sbschmidt mvprintw(21, 0, "Use F1 or ? to get more help, arrow keys to select."); 125232958Sbschmidt move(0, 0); 126232958Sbschmidt} 127232958Sbschmidt 128232958Sbschmidtstatic u_char * 129232958SbschmidtgetBootMgr(char *dname) 130232958Sbschmidt{ 131232958Sbschmidt extern u_char mbr[], bteasy17[]; 132232958Sbschmidt char str[80]; 133232958Sbschmidt char *cp; 134232958Sbschmidt int i = 0; 135232958Sbschmidt 136232958Sbschmidt cp = variable_get(VAR_BOOTMGR); 137232958Sbschmidt if (!cp) { 138232958Sbschmidt /* Figure out what kind of MBR the user wants */ 139232958Sbschmidt sprintf(str, "Install Boot Manager for drive %s?", dname); 140232958Sbschmidt MenuMBRType.title = str; 141232958Sbschmidt i = dmenuOpenSimple(&MenuMBRType, FALSE); 142232958Sbschmidt } 143232958Sbschmidt else { 144232958Sbschmidt if (!strncmp(cp, "boot", 4)) 145232958Sbschmidt BootMgr = 0; 146232958Sbschmidt else if (!strcmp(cp, "standard")) 147232958Sbschmidt BootMgr = 1; 148232958Sbschmidt else 149232958Sbschmidt BootMgr = 2; 150232958Sbschmidt } 151232958Sbschmidt if (cp || i) { 152232958Sbschmidt switch (BootMgr) { 153232958Sbschmidt case 0: 154232958Sbschmidt return bteasy17; 155232958Sbschmidt 156232958Sbschmidt case 1: 157232958Sbschmidt return mbr; 158232958Sbschmidt 159232958Sbschmidt case 2: 160232958Sbschmidt default: 161232958Sbschmidt break; 162232958Sbschmidt } 163232958Sbschmidt } 164232958Sbschmidt return NULL; 165232958Sbschmidt} 166232958Sbschmidt 167232958Sbschmidtvoid 168232958SbschmidtdiskPartition(Device *dev, Disk *d) 169232958Sbschmidt{ 170232958Sbschmidt char *p; 171232958Sbschmidt int rv, key = 0; 172232958Sbschmidt Boolean chunking; 173232958Sbschmidt char *msg = NULL; 174232958Sbschmidt u_char *mbrContents; 175232958Sbschmidt WINDOW *w = savescr(); 176232958Sbschmidt 177232958Sbschmidt chunking = TRUE; 178232958Sbschmidt keypad(stdscr, TRUE); 179232958Sbschmidt 180232958Sbschmidt /* Flush both the dialog and curses library views of the screen 181232958Sbschmidt since we don't always know who called us */ 182232958Sbschmidt dialog_clear_norefresh(), clear(); 183232958Sbschmidt 184232958Sbschmidt /* Set up the chunk array */ 185232958Sbschmidt record_chunks(d); 186232958Sbschmidt 187232958Sbschmidt while (chunking) { 188232958Sbschmidt /* Now print our overall state */ 189232958Sbschmidt print_chunks(d); 190232958Sbschmidt print_command_summary(); 191232958Sbschmidt if (msg) { 192232958Sbschmidt attrset(title_attr); mvprintw(23, 0, msg); attrset(A_NORMAL); 193232958Sbschmidt beep(); 194232958Sbschmidt msg = NULL; 195232958Sbschmidt } 196232958Sbschmidt else { 197232958Sbschmidt move(23, 0); 198232958Sbschmidt clrtoeol(); 199232958Sbschmidt } 200232958Sbschmidt 201232958Sbschmidt /* Get command character */ 202232958Sbschmidt key = getch(); 203232958Sbschmidt switch (toupper(key)) { 204232958Sbschmidt 205232958Sbschmidt /* redraw */ 206232958Sbschmidt case '\014': /* ^L */ 207232958Sbschmidt clear(); 208232958Sbschmidt msg = NULL; 209232958Sbschmidt break; 210232958Sbschmidt 211232958Sbschmidt case KEY_UP: 212232958Sbschmidt case '-': 213232958Sbschmidt if (current_chunk != 0) 214232958Sbschmidt --current_chunk; 215232958Sbschmidt break; 216232958Sbschmidt 217232958Sbschmidt case KEY_DOWN: 218232958Sbschmidt case '+': 219232958Sbschmidt case '\r': 220232958Sbschmidt case '\n': 221232958Sbschmidt if (chunk_info[current_chunk + 1]) 222232958Sbschmidt ++current_chunk; 223232958Sbschmidt break; 224232958Sbschmidt 225232958Sbschmidt case KEY_HOME: 226232958Sbschmidt current_chunk = 0; 227232958Sbschmidt break; 228232958Sbschmidt 229232958Sbschmidt case KEY_END: 230232958Sbschmidt while (chunk_info[current_chunk + 1]) 231232958Sbschmidt ++current_chunk; 232232958Sbschmidt break; 233232958Sbschmidt 234232958Sbschmidt case KEY_F(1): 235232958Sbschmidt case '?': 236232958Sbschmidt systemDisplayHelp("slice"); 237232958Sbschmidt clear(); 238232958Sbschmidt break; 239232958Sbschmidt 240232958Sbschmidt case 'A': 241232958Sbschmidt rv = msgYesNo("Do you want to do this with a true partition entry\n" 242232958Sbschmidt "so as to remain cooperative with any future possible\n" 243232958Sbschmidt "operating systems on the drive(s)?"); 244232958Sbschmidt if (rv) { 245232958Sbschmidt rv = !msgYesNo("This is dangerous in that it will make the drive totally\n" 246232958Sbschmidt "uncooperative with other potential operating systems on the\n" 247232958Sbschmidt "same disk. It will lead instead to a totally dedicated disk,\n" 248232958Sbschmidt "starting at the very first sector, bypassing all BIOS geometry\n" 249232958Sbschmidt "considerations. This precludes the existance of any boot\n" 250232958Sbschmidt "manager or other stuff in sector 0, since the BSD bootstrap\n" 251232958Sbschmidt "will live there.\n" 252232958Sbschmidt "You will run into serious trouble with ST-506 and ESDI drives\n" 253232958Sbschmidt "and possibly some IDE drives (e.g. drives running under the\n" 254232958Sbschmidt "control of sort of disk manager). SCSI drives are considerably\n" 255232958Sbschmidt "less at risk.\n\n" 256232958Sbschmidt "Do you insist on dedicating the entire disk this way?"); 257232958Sbschmidt } 258232958Sbschmidt All_FreeBSD(d, rv); 259232958Sbschmidt if (rv) 260232958Sbschmidt d->bios_hd = d->bios_sect = d->bios_cyl = 1; 261232958Sbschmidt variable_set2(DISK_PARTITIONED, "yes"); 262232958Sbschmidt record_chunks(d); 263232958Sbschmidt clear(); 264232958Sbschmidt break; 265232958Sbschmidt 266232958Sbschmidt case 'B': 267232958Sbschmidt if (chunk_info[current_chunk]->type != freebsd) 268232958Sbschmidt msg = "Can only scan for bad blocks in FreeBSD partition."; 269232958Sbschmidt else if (strncmp(d->name, "sd", 2) || 270232958Sbschmidt !msgYesNo("This typically makes sense only for ESDI, IDE or MFM drives.\n" 271232958Sbschmidt "Are you sure you want to do this on a SCSI disk?")) { 272232958Sbschmidt if (chunk_info[current_chunk]->flags & CHUNK_BAD144) 273232958Sbschmidt chunk_info[current_chunk]->flags &= ~CHUNK_BAD144; 274232958Sbschmidt else 275232958Sbschmidt chunk_info[current_chunk]->flags |= CHUNK_BAD144; 276232958Sbschmidt } 277232958Sbschmidt clear(); 278232958Sbschmidt break; 279232958Sbschmidt 280232958Sbschmidt case 'C': 281232958Sbschmidt if (chunk_info[current_chunk]->type != unused) 282232958Sbschmidt msg = "Partition in use, delete it first or move to an unused one."; 283232958Sbschmidt else { 284232958Sbschmidt char *val, tmp[20], *cp; 285232958Sbschmidt int size, subtype; 286232958Sbschmidt chunk_e partitiontype; 287232958Sbschmidt 288232958Sbschmidt snprintf(tmp, 20, "%d", chunk_info[current_chunk]->size); 289232958Sbschmidt val = msgGetInput(tmp, "Please specify the size for new FreeBSD partition in blocks\n" 290232958Sbschmidt "or append a trailing `M' for megabytes (e.g. 20M)."); 291232958Sbschmidt if (val && (size = strtol(val, &cp, 0)) > 0) { 292232958Sbschmidt if (*cp && toupper(*cp) == 'M') 293232958Sbschmidt size *= ONE_MEG; 294232958Sbschmidt strcpy(tmp, "165"); 295232958Sbschmidt val = msgGetInput(tmp, "Enter type of partition to create:\n\n" 296232958Sbschmidt "Pressing Enter will choose the default, a native FreeBSD\n" 297232958Sbschmidt "partition (type 165). You can choose other types, 6 for a\n" 298232958Sbschmidt "DOS partition or 131 for a Linux partition, for example.\n\n" 299232958Sbschmidt "Note: If you choose a non-FreeBSD partition type, it will not\n" 300232958Sbschmidt "be formatted or otherwise prepared, it will simply reserve space\n" 301232958Sbschmidt "for you to use another tool, such as DOS FORMAT, to later format\n" 302232958Sbschmidt "and use the partition."); 303232958Sbschmidt if (val && (subtype = strtol(val, NULL, 0)) > 0) { 304232958Sbschmidt if (subtype==165) 305232958Sbschmidt partitiontype=freebsd; 306232958Sbschmidt else if (subtype==6) 307232958Sbschmidt partitiontype=fat; 308232958Sbschmidt else 309232958Sbschmidt partitiontype=unknown; 310232958Sbschmidt Create_Chunk(d, chunk_info[current_chunk]->offset, size, partitiontype, subtype, 311232958Sbschmidt (chunk_info[current_chunk]->flags & CHUNK_ALIGN)); 312232958Sbschmidt variable_set2(DISK_PARTITIONED, "yes"); 313232958Sbschmidt record_chunks(d); 314232958Sbschmidt } 315232958Sbschmidt } 316232958Sbschmidt clear(); 317232958Sbschmidt } 318232958Sbschmidt break; 319232958Sbschmidt 320232958Sbschmidt case KEY_DC: 321232958Sbschmidt case 'D': 322232958Sbschmidt if (chunk_info[current_chunk]->type == unused) 323232958Sbschmidt msg = "Partition is already unused!"; 324232958Sbschmidt else { 325232958Sbschmidt Delete_Chunk(d, chunk_info[current_chunk]); 326232958Sbschmidt variable_set2(DISK_PARTITIONED, "yes"); 327232958Sbschmidt record_chunks(d); 328232958Sbschmidt } 329232958Sbschmidt break; 330232958Sbschmidt 331232958Sbschmidt case 'G': { 332232958Sbschmidt char *val, geometry[80]; 333232958Sbschmidt 334232958Sbschmidt snprintf(geometry, 80, "%lu/%lu/%lu", d->bios_cyl, d->bios_hd, d->bios_sect); 335232958Sbschmidt val = msgGetInput(geometry, "Please specify the new geometry in cyl/hd/sect format.\n" 336232958Sbschmidt "Don't forget to use the two slash (/) separator characters!\n" 337232958Sbschmidt "It's not possible to parse the field without them."); 338232958Sbschmidt if (val) { 339232958Sbschmidt d->bios_cyl = strtol(val, &val, 0); 340232958Sbschmidt d->bios_hd = strtol(val + 1, &val, 0); 341232958Sbschmidt d->bios_sect = strtol(val + 1, 0, 0); 342232958Sbschmidt } 343232958Sbschmidt clear(); 344232958Sbschmidt } 345232958Sbschmidt break; 346232958Sbschmidt 347232958Sbschmidt case 'S': 348232958Sbschmidt /* Set Bootable */ 349232958Sbschmidt chunk_info[current_chunk]->flags |= CHUNK_ACTIVE; 350232958Sbschmidt break; 351232958Sbschmidt 352232958Sbschmidt case 'U': 353232958Sbschmidt if (msgYesNo("Are you SURE you want to Undo everything?")) { 354232958Sbschmidt clear(); 355232958Sbschmidt break; 356232958Sbschmidt } 357232958Sbschmidt d = Open_Disk(d->name); 358232958Sbschmidt if (!d) { 359232958Sbschmidt msgConfirm("Can't reopen disk %s! Internal state is probably corrupted", d->name); 360232958Sbschmidt clear(); 361232958Sbschmidt break; 362232958Sbschmidt } 363232958Sbschmidt Free_Disk(dev->private); 364232958Sbschmidt dev->private = d; 365232958Sbschmidt variable_unset(DISK_PARTITIONED); 366232958Sbschmidt variable_unset(DISK_LABELLED); 367232958Sbschmidt record_chunks(d); 368232958Sbschmidt clear(); 369232958Sbschmidt break; 370232958Sbschmidt 371232958Sbschmidt case 'W': 372232958Sbschmidt if (!msgYesNo("WARNING: This should only be used for modifying an\n" 373232958Sbschmidt "EXISTING installation - If you are installing FreeBSD\n" 374232958Sbschmidt "for the first time then you should simply hit 'Q' now." 375232958Sbschmidt "Your changes will be committed in one batch at the end\n" 376232958Sbschmidt "of this section and do not have to be written now.\n\n" 377232958Sbschmidt "Are you absolutely sure you want to do this now?")) { 378232958Sbschmidt 379232958Sbschmidt variable_set2(DISK_PARTITIONED, "yes"); 380232958Sbschmidt 381232958Sbschmidt /* Don't trash the MBR if the first (and therefore only) chunk is marked for a truly dedicated 382232958Sbschmidt * disk (i.e., the disklabel starts at sector 0), even in cases where the user has requested 383232958Sbschmidt * booteasy or a "standard" MBR -- both would be fatal in this case. 384232958Sbschmidt */ 385232958Sbschmidt if ((d->chunks->part->flags & CHUNK_FORCE_ALL) != CHUNK_FORCE_ALL 386232958Sbschmidt && (mbrContents = getBootMgr(d->name)) != NULL) 387232958Sbschmidt Set_Boot_Mgr(d, mbrContents); 388232958Sbschmidt 389232958Sbschmidt if (DITEM_STATUS(diskPartitionWrite(NULL)) != DITEM_SUCCESS) 390232958Sbschmidt msgConfirm("Disk partition write returned an error status!"); 391232958Sbschmidt else 392232958Sbschmidt msgConfirm("Wrote FDISK partition information out successfully."); 393232958Sbschmidt } 394232958Sbschmidt clear(); 395232958Sbschmidt break; 396232958Sbschmidt 397232958Sbschmidt case '|': 398232958Sbschmidt if (!msgYesNo("Are you SURE you want to go into Wizard mode?\n" 399232958Sbschmidt "No seat belts whatsoever are provided!")) { 400232958Sbschmidt clear(); 401232958Sbschmidt refresh(); 402232958Sbschmidt slice_wizard(d); 403232958Sbschmidt variable_set2(DISK_PARTITIONED, "yes"); 404232958Sbschmidt record_chunks(d); 405232958Sbschmidt } 406232958Sbschmidt else 407232958Sbschmidt msg = "Wise choice!"; 408232958Sbschmidt clear(); 409232958Sbschmidt break; 410232958Sbschmidt 411232958Sbschmidt case 'Q': 412232958Sbschmidt chunking = FALSE; 413232958Sbschmidt /* Don't trash the MBR if the first (and therefore only) chunk is marked for a truly dedicated 414232958Sbschmidt * disk (i.e., the disklabel starts at sector 0), even in cases where the user has requested 415232958Sbschmidt * booteasy or a "standard" MBR -- both would be fatal in this case. 416232958Sbschmidt */ 417232958Sbschmidt if ((d->chunks->part->flags & CHUNK_FORCE_ALL) != CHUNK_FORCE_ALL 418232958Sbschmidt && (mbrContents = getBootMgr(d->name)) != NULL) 419232958Sbschmidt Set_Boot_Mgr(d, mbrContents); 420232958Sbschmidt break; 421232958Sbschmidt 422232958Sbschmidt default: 423232958Sbschmidt beep(); 424232958Sbschmidt msg = "Type F1 or ? for help"; 425232958Sbschmidt break; 426232958Sbschmidt } 427232958Sbschmidt } 428232958Sbschmidt p = CheckRules(d); 429232958Sbschmidt if (p) { 430232958Sbschmidt char buf[FILENAME_MAX]; 431232958Sbschmidt 432232958Sbschmidt dialog_clear_norefresh(); 433232958Sbschmidt use_helpline("Press F1 to read more about disk partitioning."); 434232958Sbschmidt use_helpfile(systemHelpFile("partition", buf)); 435232958Sbschmidt dialog_mesgbox("Disk partitioning warning:", p, -1, -1); 436232958Sbschmidt free(p); 437232958Sbschmidt } 438232958Sbschmidt restorescr(w); 439232958Sbschmidt} 440232958Sbschmidt 441232958Sbschmidtstatic int 442232958SbschmidtpartitionHook(dialogMenuItem *selected) 443232958Sbschmidt{ 444232958Sbschmidt Device **devs = NULL; 445232958Sbschmidt 446232958Sbschmidt devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK); 447232958Sbschmidt if (!devs) { 448232958Sbschmidt msgConfirm("Unable to find disk %s!", selected->prompt); 449232958Sbschmidt return DITEM_FAILURE; 450232958Sbschmidt } 451232958Sbschmidt /* Toggle enabled status? */ 452232958Sbschmidt if (!devs[0]->enabled) { 453232958Sbschmidt devs[0]->enabled = TRUE; 454232958Sbschmidt diskPartition(devs[0], (Disk *)devs[0]->private); 455232958Sbschmidt } 456232958Sbschmidt else 457232958Sbschmidt devs[0]->enabled = FALSE; 458232958Sbschmidt return DITEM_SUCCESS | DITEM_REDRAW; 459232958Sbschmidt} 460232958Sbschmidt 461232958Sbschmidtstatic int 462232958SbschmidtpartitionCheck(dialogMenuItem *selected) 463232958Sbschmidt{ 464232958Sbschmidt Device **devs = NULL; 465232958Sbschmidt 466232958Sbschmidt devs = deviceFind(selected->prompt, DEVICE_TYPE_DISK); 467232958Sbschmidt if (!devs || devs[0]->enabled == FALSE) 468232958Sbschmidt return FALSE; 469232958Sbschmidt return TRUE; 470232958Sbschmidt} 471232958Sbschmidt 472232958Sbschmidtint 473232958SbschmidtdiskPartitionEditor(dialogMenuItem *self) 474232958Sbschmidt{ 475232958Sbschmidt DMenu *menu; 476232958Sbschmidt Device **devs; 477232958Sbschmidt int i, cnt; 478232958Sbschmidt char *cp; 479232958Sbschmidt 480232958Sbschmidt cp = variable_get(VAR_DISK); 481232958Sbschmidt devs = deviceFind(cp, DEVICE_TYPE_DISK); 482232958Sbschmidt cnt = deviceCount(devs); 483232958Sbschmidt if (!cnt) { 484232958Sbschmidt msgConfirm("No disks found! Please verify that your disk controller is being\n" 485232958Sbschmidt "properly probed at boot time. See the Hardware Guide on the\n" 486232958Sbschmidt "Documentation menu for clues on diagnosing this type of problem."); 487232958Sbschmidt i = DITEM_FAILURE; 488232958Sbschmidt } 489232958Sbschmidt else if (cnt == 1) { 490232958Sbschmidt devs[0]->enabled = TRUE; 491232958Sbschmidt diskPartition(devs[0], (Disk *)devs[0]->private); 492232958Sbschmidt i = DITEM_SUCCESS; 493232958Sbschmidt } 494232958Sbschmidt else { 495232958Sbschmidt menu = deviceCreateMenu(&MenuDiskDevices, DEVICE_TYPE_DISK, partitionHook, partitionCheck); 496232958Sbschmidt if (!menu) { 497232958Sbschmidt msgConfirm("No devices suitable for installation found!\n\n" 498232958Sbschmidt "Please verify that your disk controller (and attached drives)\n" 499232958Sbschmidt "were detected properly. This can be done by pressing the\n" 500232958Sbschmidt "[Scroll Lock] key and using the Arrow keys to move back to\n" 501232958Sbschmidt "the boot messages. Press [Scroll Lock] again to return."); 502232958Sbschmidt i = DITEM_FAILURE; 503232958Sbschmidt } 504232958Sbschmidt else { 505232958Sbschmidt i = dmenuOpenSimple(menu, FALSE) ? DITEM_SUCCESS : DITEM_FAILURE; 506232958Sbschmidt free(menu); 507232958Sbschmidt } 508232958Sbschmidt i = i | DITEM_RECREATE; 509232958Sbschmidt } 510232958Sbschmidt return i; 511232958Sbschmidt} 512232958Sbschmidt 513232958Sbschmidtint 514232958SbschmidtdiskPartitionWrite(dialogMenuItem *self) 515232958Sbschmidt{ 516232958Sbschmidt Device **devs; 517232958Sbschmidt char *cp; 518232958Sbschmidt int i; 519232958Sbschmidt 520232958Sbschmidt if ((cp = variable_get(DISK_PARTITIONED)) && strcmp(cp, "yes")) 521232958Sbschmidt return DITEM_SUCCESS; 522232958Sbschmidt else if (!cp) { 523232958Sbschmidt msgConfirm("You must partition the disk(s) before this option can be used."); 524232958Sbschmidt return DITEM_FAILURE; 525232958Sbschmidt } 526232958Sbschmidt 527232958Sbschmidt devs = deviceFind(NULL, DEVICE_TYPE_DISK); 528232958Sbschmidt if (!devs) { 529232958Sbschmidt msgConfirm("Unable to find any disks to write to??"); 530232958Sbschmidt return DITEM_FAILURE; 531232958Sbschmidt } 532232958Sbschmidt if (isDebug()) 533232958Sbschmidt msgDebug("diskPartitionWrite: Examining %d devices\n", deviceCount(devs)); 534232958Sbschmidt 535232958Sbschmidt for (i = 0; devs[i]; i++) { 536232958Sbschmidt Chunk *c1; 537232958Sbschmidt Disk *d = (Disk *)devs[i]->private; 538232958Sbschmidt 539232958Sbschmidt if (!devs[i]->enabled) 540232958Sbschmidt continue; 541232958Sbschmidt 542232958Sbschmidt Set_Boot_Blocks(d, boot1, boot2); 543232958Sbschmidt msgNotify("Writing partition information to drive %s", d->name); 544232958Sbschmidt if (!Fake && Write_Disk(d)) { 545232958Sbschmidt msgConfirm("ERROR: Unable to write data to disk %s!", d->name); 546232958Sbschmidt return DITEM_FAILURE; 547232958Sbschmidt } 548232958Sbschmidt /* Now scan for bad blocks, if necessary */ 549232958Sbschmidt for (c1 = d->chunks->part; c1; c1 = c1->next) { 550232958Sbschmidt if (c1->flags & CHUNK_BAD144) { 551232958Sbschmidt int ret; 552232958Sbschmidt 553232958Sbschmidt msgNotify("Running bad block scan on partition %s", c1->name); 554232958Sbschmidt if (!Fake) { 555232958Sbschmidt ret = vsystem("bad144 -v /dev/r%s 1234", c1->name); 556232958Sbschmidt if (ret) 557232958Sbschmidt msgConfirm("Bad144 init on %s returned status of %d!", c1->name, ret); 558232958Sbschmidt ret = vsystem("bad144 -v -s /dev/r%s", c1->name); 559232958Sbschmidt if (ret) 560232958Sbschmidt msgConfirm("Bad144 scan on %s returned status of %d!", c1->name, ret); 561232958Sbschmidt } 562232958Sbschmidt } 563232958Sbschmidt } 564232958Sbschmidt } 565232958Sbschmidt /* Now it's not "yes", but "written" */ 566232958Sbschmidt variable_set2(DISK_PARTITIONED, "written"); 567232958Sbschmidt return DITEM_SUCCESS; 568232958Sbschmidt} 569232958Sbschmidt