/* $NetBSD: fdisk.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 #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 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; } } }