1995-05-05 00:36:23 +01:00
/*
* The new sysinstall program .
*
* This is probably the last program in the ` sysinstall ' line - the next
* generation being essentially a complete rewrite .
*
1995-05-28 21:28:15 +01:00
* $ Id : disks . c , v 1.28 1995 / 05 / 25 18 : 48 : 23 jkh Exp $
1995-05-05 00:36:23 +01:00
*
* Copyright ( c ) 1995
* Jordan Hubbard . All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer ,
* verbatim and that no modifications are made prior to this
* point in the file .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement :
* This product includes software developed by Jordan Hubbard
* for the FreeBSD Project .
* 4. The name of Jordan Hubbard or the FreeBSD project may not be used to
* endorse or promote products derived from this software without specific
* prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ` ` AS IS ' ' AND
* ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , LIFE OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
* LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
*
*/
# include "sysinstall.h"
1995-05-06 00:47:47 +01:00
# include <ctype.h>
1995-05-06 10:34:24 +01:00
# include <sys/disklabel.h>
1995-05-06 00:47:47 +01:00
1995-05-16 03:53:31 +01:00
/* Where we start displaying chunk information on the screen */
# define CHUNK_START_ROW 5
1995-05-08 01:38:02 +01:00
1995-05-16 03:53:31 +01:00
/* Where we keep track of MBR chunks */
static struct chunk * chunk_info [ 10 ] ;
1995-05-06 00:47:47 +01:00
static int current_chunk ;
static void
1995-05-16 03:53:31 +01:00
record_chunks ( Disk * d )
1995-05-06 00:47:47 +01:00
{
1995-05-16 03:53:31 +01:00
struct chunk * c1 ;
int i = 0 ;
int last_free = 0 ;
if ( ! d - > chunks )
msgFatal ( " No chunk list found for %s! " , d - > name ) ;
c1 = d - > chunks - > part ;
current_chunk = 0 ;
while ( c1 ) {
if ( c1 - > type = = unused & & c1 - > size > last_free ) {
last_free = c1 - > size ;
current_chunk = i ;
1995-05-06 00:47:47 +01:00
}
1995-05-16 03:53:31 +01:00
chunk_info [ i + + ] = c1 ;
c1 = c1 - > next ;
1995-05-06 00:47:47 +01:00
}
1995-05-16 03:53:31 +01:00
chunk_info [ i ] = NULL ;
1995-05-08 00:37:34 +01:00
}
1995-05-06 00:47:47 +01:00
static void
1995-05-16 03:53:31 +01:00
print_chunks ( Disk * d )
1995-05-06 00:47:47 +01:00
{
1995-05-16 03:53:31 +01:00
int row ;
int i ;
1995-05-06 00:47:47 +01:00
attrset ( A_NORMAL ) ;
1995-05-16 03:53:31 +01:00
mvaddstr ( 0 , 0 , " Disk name: \t " ) ;
1995-05-21 05:34:12 +01:00
clrtobot ( ) ;
1995-05-16 03:53:31 +01:00
attrset ( A_REVERSE ) ; addstr ( d - > name ) ; attrset ( A_NORMAL ) ;
attrset ( A_REVERSE ) ; mvaddstr ( 0 , 55 , " Master Partition Editor " ) ; attrset ( A_NORMAL ) ;
mvprintw ( 1 , 0 ,
" BIOS Geometry: \t %lu cyls/%lu heads/%lu sectors " ,
d - > bios_cyl , d - > bios_hd , d - > bios_sect ) ;
mvprintw ( 3 , 1 , " %10s %10s %10s %8s %8s %8s %8s %8s " ,
" Offset " , " Size " , " End " , " Name " , " PType " , " Desc " ,
" Subtype " , " Flags " ) ;
for ( i = 0 , row = CHUNK_START_ROW ; chunk_info [ i ] ; i + + , row + + ) {
1995-05-06 00:47:47 +01:00
if ( i = = current_chunk )
1995-05-07 04:38:03 +01:00
attrset ( A_REVERSE ) ;
1995-05-21 05:34:12 +01:00
mvprintw ( row , 2 , " %10ld %10lu %10lu %8s %8d %8s %8d %6lx " ,
1995-05-16 03:53:31 +01:00
chunk_info [ i ] - > offset , chunk_info [ i ] - > size ,
chunk_info [ i ] - > end , chunk_info [ i ] - > name ,
chunk_info [ i ] - > type , chunk_n [ chunk_info [ i ] - > type ] ,
chunk_info [ i ] - > subtype , chunk_info [ i ] - > flags ) ;
1995-05-06 00:47:47 +01:00
if ( i = = current_chunk )
attrset ( A_NORMAL ) ;
}
}
static void
print_command_summary ( )
{
1995-05-16 03:53:31 +01:00
mvprintw ( 14 , 0 , " The following commands are supported (in upper or lower case): " ) ;
mvprintw ( 16 , 0 , " A = Use Entire Disk B = Bad Block Scan C = Create Partition " ) ;
mvprintw ( 17 , 0 , " D = Delete Partition G = Set BIOS Geometry S = Set Bootable " ) ;
1995-05-28 21:28:15 +01:00
mvprintw ( 18 , 0 , " U = Undo All Changes ESC = Exit this screen " ) ;
1995-05-16 03:53:31 +01:00
mvprintw ( 20 , 0 , " The currently selected partition is displayed in " ) ;
1995-05-25 19:48:33 +01:00
attrset ( A_REVERSE ) ; addstr ( " reverse " ) ; attrset ( A_NORMAL ) ; addstr ( " video. " ) ;
1995-05-16 03:53:31 +01:00
mvprintw ( 21 , 0 , " Use F1 or ? to get more help, arrow keys to move. " ) ;
1995-05-06 00:47:47 +01:00
move ( 0 , 0 ) ;
}
1995-05-16 03:53:31 +01:00
static Disk *
diskPartition ( Disk * d )
1995-05-05 00:36:23 +01:00
{
1995-05-16 03:53:31 +01:00
char * p ;
int key = 0 ;
Boolean chunking ;
1995-05-06 00:47:47 +01:00
char * msg = NULL ;
1995-05-16 03:53:31 +01:00
char name [ 40 ] ;
1995-05-06 00:47:47 +01:00
1995-05-16 03:53:31 +01:00
chunking = TRUE ;
strncpy ( name , d - > name , 40 ) ;
1995-05-06 00:47:47 +01:00
keypad ( stdscr , TRUE ) ;
1995-05-20 20:22:21 +01:00
clear ( ) ;
1995-05-16 03:53:31 +01:00
record_chunks ( d ) ;
while ( chunking ) {
print_chunks ( d ) ;
1995-05-06 00:47:47 +01:00
print_command_summary ( ) ;
if ( msg ) {
1995-05-16 03:53:31 +01:00
standout ( ) ; mvprintw ( 23 , 0 , msg ) ; standend ( ) ;
1995-05-06 00:47:47 +01:00
beep ( ) ;
msg = NULL ;
}
1995-05-16 03:53:31 +01:00
1995-05-06 00:47:47 +01:00
key = toupper ( getch ( ) ) ;
switch ( key ) {
1995-05-25 19:48:33 +01:00
case ' \014 ' : /* ^L */
clear ( ) ;
continue ;
1995-05-06 00:47:47 +01:00
case KEY_UP :
case ' - ' :
if ( current_chunk ! = 0 )
- - current_chunk ;
break ;
case KEY_DOWN :
case ' + ' :
case ' \r ' :
case ' \n ' :
1995-05-16 03:53:31 +01:00
if ( chunk_info [ current_chunk + 1 ] )
1995-05-06 00:47:47 +01:00
+ + current_chunk ;
break ;
case KEY_HOME :
current_chunk = 0 ;
break ;
case KEY_END :
1995-05-16 03:53:31 +01:00
while ( chunk_info [ current_chunk + 1 ] )
1995-05-06 00:47:47 +01:00
+ + current_chunk ;
break ;
case KEY_F ( 1 ) :
case ' ? ' :
1995-05-16 03:53:31 +01:00
systemDisplayFile ( " slice.hlp " ) ;
break ;
case ' A ' :
All_FreeBSD ( d ) ;
record_chunks ( d ) ;
break ;
case ' B ' :
if ( chunk_info [ current_chunk ] - > type ! = freebsd )
msg = " Can only scan for bad blocks in FreeBSD partition. " ;
else if ( strncmp ( name , " sd " , 2 ) | |
! msgYesNo ( " This typically makes sense only for ESDI, IDE or MFM drives. \n Are you sure you want to do this on a SCSI disk? " ) )
1995-05-18 10:02:06 +01:00
if ( chunk_info [ current_chunk ] - > flags & CHUNK_BAD144 )
chunk_info [ current_chunk ] - > flags & = ~ CHUNK_BAD144 ;
else
chunk_info [ current_chunk ] - > flags | = CHUNK_BAD144 ;
1995-05-06 00:47:47 +01:00
break ;
case ' C ' :
1995-05-16 03:53:31 +01:00
if ( chunk_info [ current_chunk ] - > type ! = unused )
msg = " Partition in use, delete it first or move to an unused one. " ;
1995-05-06 00:47:47 +01:00
else {
1995-05-16 12:37:27 +01:00
char * val , tmp [ 20 ] , * cp ;
1995-05-06 00:47:47 +01:00
int size ;
1995-05-16 03:53:31 +01:00
snprintf ( tmp , 20 , " %d " , chunk_info [ current_chunk ] - > size ) ;
1995-05-16 12:37:27 +01:00
val = msgGetInput ( tmp , " Please specify the size for new FreeBSD partition in blocks, or append \n a trailing `M' for megabytes (e.g. 20M). " ) ;
if ( val & & ( size = strtol ( val , & cp , 0 ) ) > 0 ) {
if ( * cp & & toupper ( * cp ) = = ' M ' )
size * = 2048 ;
1995-05-16 03:53:31 +01:00
Create_Chunk ( d , chunk_info [ current_chunk ] - > offset ,
size ,
freebsd ,
3 ,
( chunk_info [ current_chunk ] - > flags &
CHUNK_ALIGN ) ) ;
record_chunks ( d ) ;
1995-05-06 00:47:47 +01:00
}
}
break ;
1995-05-06 10:34:24 +01:00
1995-05-16 03:53:31 +01:00
case ' D ' :
if ( chunk_info [ current_chunk ] - > type = = unused )
msg = " Partition is already unused! " ;
else {
Delete_Chunk ( d , chunk_info [ current_chunk ] ) ;
record_chunks ( d ) ;
1995-05-06 10:34:24 +01:00
}
break ;
1995-05-07 06:58:57 +01:00
1995-05-16 03:53:31 +01:00
case ' G ' : {
char * val , geometry [ 80 ] ;
snprintf ( geometry , 80 , " %lu/%lu/%lu " ,
d - > bios_cyl , d - > bios_hd , d - > bios_sect ) ;
val = msgGetInput ( geometry ,
" Please specify the new geometry in cyl/hd/sect format. \n Don't forget to use the two slash (/) separator characters! \n It's not possible to parse the field without them. " ) ;
if ( val ) {
d - > bios_cyl = strtol ( val , & val , 0 ) ;
d - > bios_hd = strtol ( val + 1 , & val , 0 ) ;
d - > bios_sect = strtol ( val + 1 , 0 , 0 ) ;
1995-05-07 06:58:57 +01:00
}
1995-05-16 03:53:31 +01:00
}
1995-05-07 06:58:57 +01:00
break ;
1995-05-16 03:53:31 +01:00
case ' S ' :
/* Set Bootable */
chunk_info [ current_chunk ] - > flags | = CHUNK_ACTIVE ;
1995-05-08 00:37:34 +01:00
break ;
1995-05-16 03:53:31 +01:00
case ' U ' :
Free_Disk ( d ) ;
d = Open_Disk ( name ) ;
if ( ! d )
msgFatal ( " Can't reopen disk %s! " , name ) ;
record_chunks ( d ) ;
1995-05-08 00:37:34 +01:00
break ;
1995-05-08 01:56:28 +01:00
case ' W ' :
1995-05-16 03:53:31 +01:00
if ( ! msgYesNo ( " Are you sure you want to go into Wizard mode? \n No seat belts whatsoever are provided! " ) ) {
1995-05-08 01:56:28 +01:00
dialog_clear ( ) ;
end_dialog ( ) ;
DialogActive = FALSE ;
1995-05-16 03:53:31 +01:00
slice_wizard ( d ) ;
1995-05-08 01:56:28 +01:00
dialog_clear ( ) ;
DialogActive = TRUE ;
1995-05-16 03:53:31 +01:00
record_chunks ( d ) ;
1995-05-08 01:56:28 +01:00
}
else
1995-05-16 03:53:31 +01:00
msg = " Wise choice! " ;
1995-05-08 01:56:28 +01:00
break ;
1995-05-06 00:47:47 +01:00
case 27 : /* ESC */
1995-05-16 03:53:31 +01:00
chunking = FALSE ;
1995-05-06 00:47:47 +01:00
break ;
1995-05-08 00:37:34 +01:00
default :
beep ( ) ;
msg = " Type F1 or ? for help " ;
break ;
1995-05-06 00:47:47 +01:00
}
}
1995-05-16 03:53:31 +01:00
p = CheckRules ( d ) ;
if ( p ) {
msgConfirm ( p ) ;
free ( p ) ;
}
1995-05-17 17:16:10 +01:00
dialog_clear ( ) ;
1995-05-16 03:53:31 +01:00
variable_set2 ( DISK_PARTITIONED , " yes " ) ;
return d ;
1995-05-05 00:36:23 +01:00
}
1995-05-16 03:53:31 +01:00
static int
partitionHook ( char * str )
1995-05-05 00:36:23 +01:00
{
1995-05-16 12:37:27 +01:00
Device * * devs = NULL ;
1995-05-16 03:53:31 +01:00
/* Clip garbage off the ends */
string_prune ( str ) ;
str = string_skipwhite ( str ) ;
/* Try and open all the disks */
while ( str ) {
char * cp ;
cp = index ( str , ' \n ' ) ;
if ( cp )
* cp + + = 0 ;
if ( ! * str ) {
beep ( ) ;
return 0 ;
1995-05-08 02:27:07 +01:00
}
1995-05-16 03:53:31 +01:00
devs = deviceFind ( str , DEVICE_TYPE_DISK ) ;
if ( ! devs ) {
msgConfirm ( " Unable to find disk %s! " , str ) ;
1995-05-08 02:27:07 +01:00
return 0 ;
1995-05-05 00:36:23 +01:00
}
1995-05-16 03:53:31 +01:00
else if ( devs [ 1 ] )
msgConfirm ( " Bizarre multiple match for %s! " , str ) ;
devs [ 0 ] - > private = diskPartition ( ( Disk * ) devs [ 0 ] - > private ) ;
1995-05-16 12:37:27 +01:00
devs [ 0 ] - > enabled = TRUE ;
1995-05-16 03:53:31 +01:00
str = cp ;
}
return devs ? 1 : 0 ;
}
int
diskPartitionEditor ( char * str )
{
DMenu * menu ;
menu = deviceCreateMenu ( & MenuDiskDevices , DEVICE_TYPE_DISK , partitionHook ) ;
if ( ! menu ) {
msgConfirm ( " No devices suitable for installation found! \n \n Please verify that your disk controller (and attached drives) were detected properly. This can be done by selecting the ``Bootmsg'' option on the main menu and reviewing the boot messages carefully. " ) ;
1995-05-05 00:36:23 +01:00
}
1995-05-17 15:40:00 +01:00
else {
1995-05-20 11:33:14 +01:00
dmenuOpenSimple ( menu ) ;
1995-05-17 15:40:00 +01:00
free ( menu ) ;
}
1995-05-16 03:53:31 +01:00
return 0 ;
1995-05-05 00:36:23 +01:00
}