NetBSD/distrib/utils/sysinst/fdisk.c

142 lines
5.0 KiB
C

/* $NetBSD: fdisk.c,v 1.9 1998/07/21 14:53:36 rvb 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 /sbin/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);
/*
* Fetch current MBR from disk into core by parsing /sbin/fdisk output.
*/
void
get_fdisk_info()
{
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.
*/
/* XXX should warn user about this, and maybe ask! */
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;
}
}
}
/*
* Write incore MBR geometry and partition info to disk
* using /sbin/fdisk.
*/
void
set_fdisk_info()
{
int i;
for (i = 0; i < 4; i++)
if (part[i][SET])
run_prog("/sbin/fdisk -u -f -%d -b %d/%d/%d "
"-s %d/%d/%d /dev/r%sd",
i, bcyl, bhead, bsec,
part[i][ID], part[i][START],
part[i][SIZE], diskdev);
if (activepart >= 0)
run_prog("/sbin/fdisk -a -%d -f /dev/r%s",
activepart, diskdev);
}