201 lines
6.4 KiB
C
201 lines
6.4 KiB
C
/* $NetBSD: mbr.c,v 1.4 1997/11/29 21:49:13 fvdl Exp $ */
|
|
|
|
/*
|
|
* Copyright 1997 Piermont Information Systems Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Written by Philip A. Nelson for Piermont Information Systems Inc.
|
|
*
|
|
* 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.
|
|
* 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 develooped for the NetBSD Project by
|
|
* Piermont Information Systems Inc.
|
|
* 4. The name of Piermont Information Systems Inc. may not be used to endorse
|
|
* or promote products derived from this software without specific prior
|
|
* written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``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 PIERMONT INFORMATION SYSTEMS INC. 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, 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.
|
|
*
|
|
*/
|
|
|
|
/* fdisk.c -- routines to deal with fdisk ... */
|
|
|
|
#include <stdio.h>
|
|
#include "defs.h"
|
|
#include "md.h"
|
|
#include "txtwalk.h"
|
|
#include "msg_defs.h"
|
|
#include "menu_defs.h"
|
|
|
|
struct lookfor fdiskbuf[] = {
|
|
{"DLCYL", "DLCYL=%d", "a $0", &dlcyl, NULL},
|
|
{"DLHEAD", "DLHEAD=%d", "a $0", &dlhead, NULL},
|
|
{"DLSEC", "DLSEC=%d", "a $0", &dlsec, NULL},
|
|
{"BCYL", "BCYL=%d", "a $0", &bcyl, NULL},
|
|
{"BHEAD", "BHEAD=%d", "a $0", &bhead, NULL},
|
|
{"BSEC", "BSEC=%d", "a $0", &bsec, NULL},
|
|
{"PART0ID", "PART0ID=%d", "a $0", &part[0][ID], NULL},
|
|
{"PART0SIZE", "PART0SIZE=%d", "a $0", &part[0][SIZE], NULL},
|
|
{"PART0START", "PART0START=%d", "a $0", &part[0][START], NULL},
|
|
{"PART0FLAG", "PART0FLAG=0x%d", "a $0", &part[0][FLAG], NULL},
|
|
{"PART1ID", "PART1ID=%d", "a $0", &part[1][ID], NULL},
|
|
{"PART1SIZE", "PART1SIZE=%d", "a $0", &part[1][SIZE], NULL},
|
|
{"PART1START", "PART1START=%d", "a $0", &part[1][START], NULL},
|
|
{"PART1FLAG", "PART1FLAG=0x%d", "a $0", &part[1][FLAG], NULL},
|
|
{"PART2ID", "PART2ID=%d", "a $0", &part[2][ID], NULL},
|
|
{"PART2SIZE", "PART2SIZE=%d", "a $0", &part[2][SIZE], NULL},
|
|
{"PART2START", "PART2START=%d", "a $0", &part[2][START], NULL},
|
|
{"PART2FLAG", "PART2FLAG=0x%d", "a $0", &part[2][FLAG], NULL},
|
|
{"PART3ID", "PART3ID=%d", "a $0", &part[3][ID], NULL},
|
|
{"PART3SIZE", "PART3SIZE=%d", "a $0", &part[3][SIZE], NULL},
|
|
{"PART3START", "PART3START=%d", "a $0", &part[3][START], NULL},
|
|
{"PART3FLAG", "PART3FLAG=0x%d", "a $0", &part[3][FLAG], NULL}
|
|
};
|
|
|
|
int numfdiskbuf = sizeof(fdiskbuf) / sizeof(struct lookfor);
|
|
|
|
struct part_id {
|
|
int id;
|
|
char *name;
|
|
} part_ids[] = {
|
|
{0, "unused"},
|
|
{1, "Primary DOS, 12 bit FAT"},
|
|
{4, "Primary DOS, 16 bit FAT <32M"},
|
|
{5, "Extended DOS"},
|
|
{6, "Primary DOS, 16-bit FAT >32MB"},
|
|
{7, "NTFS"},
|
|
{165, "NetBSD"},
|
|
{-1, "Unknown"},
|
|
};
|
|
|
|
int partsoverlap(int i, int j)
|
|
{
|
|
if (part[i][SIZE] == 0 || part[j][SIZE] == 0)
|
|
return 0;
|
|
|
|
return
|
|
(part[i][START] < part[j][START] &&
|
|
part[i][START] + part[i][SIZE] > part[j][START])
|
|
||
|
|
(part[i][START] > part[j][START] &&
|
|
part[i][START] < part[j][START] + part[j][SIZE])
|
|
||
|
|
(part[i][START] == part[j][START]);
|
|
|
|
}
|
|
|
|
|
|
void disp_cur_part(int sel, int disp)
|
|
{
|
|
int i, j, start, stop, rsize, rend;
|
|
|
|
if (disp < 0)
|
|
start = 0, stop = 4;
|
|
else
|
|
start = disp, stop = disp+1;
|
|
msg_display_add (MSG_part_head, multname, multname, multname);
|
|
for (i=start; i<stop; i++) {
|
|
if (sel == i) msg_standout();
|
|
if (part[i][SIZE] == 0 && part[i][START] == 0)
|
|
msg_printf_add ("%d %36s ", i, "");
|
|
else {
|
|
rsize = part[i][SIZE] / sizemult;
|
|
if (part[i][SIZE] % sizemult)
|
|
rsize++;
|
|
rend = (part[i][START] + part[i][SIZE]) / sizemult;
|
|
if ((part[i][SIZE] + part[i][SIZE]) % sizemult)
|
|
rend++;
|
|
msg_printf_add("%d %12d%12d%12d ", i,
|
|
part[i][START] / sizemult,
|
|
rsize, rend);
|
|
}
|
|
for (j = 0; part_ids[j].id != -1 &&
|
|
part_ids[j].id != part[i][ID]; j++);
|
|
msg_printf_add ("%s\n", part_ids[j].name);
|
|
if (sel == i) msg_standend();
|
|
}
|
|
}
|
|
|
|
int check_geom (void)
|
|
{
|
|
return bcyl <= 1024 && bsec < 64 && bcyl > 0 && bhead > 0 && bsec > 0;
|
|
}
|
|
|
|
|
|
void set_fdisk_geom (void)
|
|
{
|
|
char res[80];
|
|
msg_display_add(MSG_setbiosgeom);
|
|
disp_cur_geom();
|
|
msg_printf_add ("\n");
|
|
msg_prompt_add (MSG_cylinders, NULL, res, 80);
|
|
bcyl = atoi(res);
|
|
msg_prompt_add (MSG_heads, NULL, res, 80);
|
|
bhead = atoi(res);
|
|
msg_prompt_add (MSG_sectors, NULL, res, 80);
|
|
bsec = atoi(res);
|
|
bstuffset = 1;
|
|
}
|
|
|
|
void disp_cur_geom (void)
|
|
{
|
|
msg_display_add(MSG_realgeom, dlcyl, dlhead, dlsec);
|
|
msg_display_add(MSG_biosgeom, bcyl, bhead, bsec);
|
|
}
|
|
|
|
void get_fdisk_info (void)
|
|
{
|
|
char *textbuf;
|
|
int textsize;
|
|
int t1, t2;
|
|
|
|
/* Get Fdisk information */
|
|
textsize = collect (T_OUTPUT, &textbuf,
|
|
"/sbin/fdisk -S /dev/r%sd 2>/dev/null", diskdev);
|
|
if (textsize < 0) {
|
|
endwin();
|
|
(void) fprintf (stderr, "Could not run fdisk.");
|
|
exit (1);
|
|
}
|
|
walk (textbuf, textsize, fdiskbuf, numfdiskbuf);
|
|
free (textbuf);
|
|
|
|
/* A common failure of fdisk is to get the number of cylinders
|
|
wrong and the number of sectors and heads right. This makes
|
|
a disk look very big. In this case, we can just recompute
|
|
the number of cylinders and things should work just fine.
|
|
Also, fdisk may correctly indentify the settings to include
|
|
a cylinder total > 1024, because translation mode is not used.
|
|
Check for it. */
|
|
|
|
if (bcyl > 1024 && disk->geom[1] == bhead && disk->geom[2] == bsec)
|
|
bcyl = 1024;
|
|
else if (bcyl > 1024 && bsec < 64) {
|
|
t1 = disk->geom[0] * disk->geom[1] * disk->geom[2];
|
|
t2 = bhead * bsec;
|
|
if (bcyl * t2 > t1) {
|
|
t2 = t1 / t2;
|
|
if (t2 < 1024)
|
|
bcyl = t2;
|
|
}
|
|
}
|
|
}
|