summaryrefslogtreecommitdiffstats
path: root/fdisk
diff options
context:
space:
mode:
Diffstat (limited to 'fdisk')
-rw-r--r--fdisk/.gitignore3
-rw-r--r--fdisk/Makefile.am94
-rw-r--r--fdisk/cfdisk.8452
-rw-r--r--fdisk/cfdisk.c2854
-rw-r--r--fdisk/common.h15
-rw-r--r--fdisk/fdisk.8283
-rw-r--r--fdisk/fdisk.c2116
-rw-r--r--fdisk/fdisk.h253
-rw-r--r--fdisk/fdiskaixlabel.c67
-rw-r--r--fdisk/fdiskaixlabel.h27
-rw-r--r--fdisk/fdiskbsdlabel.c847
-rw-r--r--fdisk/fdiskbsdlabel.h246
-rw-r--r--fdisk/fdiskdoslabel.c682
-rw-r--r--fdisk/fdiskdoslabel.h57
-rw-r--r--fdisk/fdiskmaclabel.c83
-rw-r--r--fdisk/fdiskmaclabel.h39
-rw-r--r--fdisk/fdisksgilabel.c879
-rw-r--r--fdisk/fdisksgilabel.h137
-rw-r--r--fdisk/fdisksunlabel.c643
-rw-r--r--fdisk/fdisksunlabel.h97
-rw-r--r--fdisk/gpt.c216
-rw-r--r--fdisk/gpt.h8
-rw-r--r--fdisk/i386_sys_types.c110
-rw-r--r--fdisk/partname.c49
-rw-r--r--fdisk/sfdisk.8603
-rw-r--r--fdisk/sfdisk.c3242
-rw-r--r--fdisk/utils.c290
27 files changed, 0 insertions, 14392 deletions
diff --git a/fdisk/.gitignore b/fdisk/.gitignore
deleted file mode 100644
index c20d140e7..000000000
--- a/fdisk/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-cfdisk
-fdisk
-sfdisk
diff --git a/fdisk/Makefile.am b/fdisk/Makefile.am
deleted file mode 100644
index e9be84111..000000000
--- a/fdisk/Makefile.am
+++ /dev/null
@@ -1,94 +0,0 @@
-include $(top_srcdir)/config/include-Makefile.am
-
-fdisk_common = \
- common.h \
- gpt.c \
- gpt.h \
- i386_sys_types.c \
- $(top_srcdir)/lib/blkdev.c \
- $(top_srcdir)/lib/mbsalign.c \
- $(top_srcdir)/lib/strutils.c \
- $(top_srcdir)/lib/randutils.c \
- $(top_srcdir)/lib/wholedisk.c
-
-if LINUX
-fdisk_common += $(top_srcdir)/lib/linux_version.c
-endif
-
-if !ARCH_M68K
-
-sbin_PROGRAMS = fdisk
-dist_man_MANS = fdisk.8
-fdisk_SOURCES = \
- utils.c \
- fdisk.c \
- fdisk.h \
- fdiskaixlabel.c \
- fdiskaixlabel.h \
- fdiskbsdlabel.c \
- fdiskbsdlabel.h \
- fdiskmaclabel.c \
- fdiskmaclabel.h \
- fdisksgilabel.c \
- fdisksgilabel.h \
- fdisksunlabel.c \
- fdisksunlabel.h \
- fdiskdoslabel.c \
- fdiskdoslabel.h \
- partname.c \
- $(fdisk_common) \
- $(top_srcdir)/lib/canonicalize.c
-
-cflags_blkid = $(AM_CFLAGS)
-ldadd_blkid =
-
-if BUILD_LIBBLKID
-ldadd_blkid += $(ul_libblkid_la)
-cflags_blkid += -I$(ul_libblkid_incdir)
-endif
-
-if HAVE_STATIC_FDISK
-sbin_PROGRAMS += fdisk.static
-fdisk_static_SOURCES = $(fdisk_SOURCES)
-fdisk_static_LDFLAGS = -all-static
-fdisk_static_CFLAGS = $(cflags_blkid)
-fdisk_static_LDADD = $(ldadd_blkid)
-endif
-
-fdisk_CFLAGS = $(cflags_blkid)
-fdisk_LDADD = $(ldadd_blkid)
-
-if !ARCH_SPARC
-
-sbin_PROGRAMS += sfdisk
-dist_man_MANS += sfdisk.8
-sfdisk_SOURCES = \
- partname.c \
- sfdisk.c \
- $(fdisk_common) \
- $(top_srcdir)/lib/canonicalize.c
-
-if HAVE_STATIC_SFDISK
-sbin_PROGRAMS += sfdisk.static
-sfdisk_static_SOURCES = $(sfdisk_SOURCES)
-sfdisk_static_LDFLAGS = -all-static
-endif
-
-if USE_SLANG
-sbin_PROGRAMS += cfdisk
-dist_man_MANS += cfdisk.8
-cfdisk_SOURCES = cfdisk.c $(fdisk_common)
-cfdisk_CFLAGS = $(cflags_blkid)
-cfdisk_LDADD = -lslang $(ldadd_blkid)
-else
-if HAVE_NCURSES
-sbin_PROGRAMS += cfdisk
-dist_man_MANS += cfdisk.8
-cfdisk_SOURCES = cfdisk.c $(fdisk_common)
-cfdisk_CFLAGS = $(cflags_blkid)
-cfdisk_LDADD = @NCURSES_LIBS@ $(ldadd_blkid)
-endif
-endif
-
-endif # !ARCH_SPARC
-endif # !ARCH_M68K
diff --git a/fdisk/cfdisk.8 b/fdisk/cfdisk.8
deleted file mode 100644
index 28ddad668..000000000
--- a/fdisk/cfdisk.8
+++ /dev/null
@@ -1,452 +0,0 @@
-.\" cfdisk.8 -- man page for cfdisk
-.\" Copyright 1994 Kevin E. Martin (martin@cs.unc.edu)
-.\"
-.\" Permission is granted to make and distribute verbatim copies of this
-.\" manual provided the copyright notice and this permission notice are
-.\" preserved on all copies.
-.\"
-.\" Permission is granted to copy and distribute modified versions of this
-.\" manual under the conditions for verbatim copying, provided that the
-.\" entire resulting derived work is distributed under the terms of a
-.\" permission notice identical to this one.
-.\"
-.\" " for hilit mode
-.TH CFDISK 8 "July 2009" "util-linux" "System Administration"
-.SH NAME
-cfdisk \- display or manipulate disk partition table
-.SH SYNOPSIS
-.B cfdisk
-.RB [ \-agvz ]
-.RB [ \-c
-.IR cylinders ]
-.RB [ \-h
-.IR heads ]
-.RB [ \-s
-.IR sectors-per-track ]
-.RB [ \-P
-.IR opt ]
-.RI [ device ]
-.SH DESCRIPTION
-.B cfdisk
-is a curses-based program for partitioning any hard disk drive.
-Typical values of the
-.I device
-argument are:
-.sp
-.nf
-.RS
-/dev/hda [default]
-/dev/hdb
-/dev/sda
-/dev/sdb
-/dev/sdc
-/dev/sdd
-.RE
-.fi
-
-Note that
-.B cfdisk
-does not align partitions to block device I/O limits. This functionality is
-provided by
-.BR fdisk (8).
-
-In order to write the partition table
-.B cfdisk
-needs something called the `geometry' of the disk: the number
-of `heads' and the number of `sectors per track'. Linux does not
-use any geometry, so if the disk will not be accessed by other
-operating systems, you can safely accept the defaults that
-.B cfdisk
-chooses for you. The geometry used by
-.B cfdisk
-is found as follows. First the partition table is examined,
-to see what geometry was used by the previous program that
-changed it. If the partition table is empty, or contains garbage,
-or does not point at a consistent geometry, the kernel is
-asked for advice. If nothing works 255 heads and 63 sectors/track
-is assumed. The geometry can be overridden on the command line
-or by use of the `g' command. When partitioning an empty large modern
-disk, picking 255 heads and 63 sectors/track is always a good idea.
-There is no need to set the number of cylinders, since
-.B cfdisk
-knows the disk size.
-
-Next,
-.B cfdisk
-tries to read the current partition table from the disk drive. If it
-is unable to figure out the partition table, an error is displayed and
-the program will exit. This might also be caused by incorrect
-geometry information, and can be overridden on the command line.
-Another way around this problem is with the
-.B \-z
-option. This will ignore the partition table on the disk.
-
-The main display is composed of four sections, from top to bottom: the
-header, the partitions, the command line and a warning line. The
-header contains the program name and version number followed by the
-disk drive and its geometry. The partitions section always displays
-the current partition table. The command line is the place where
-commands and text are entered. The available commands are usually
-displayed in brackets. The warning line is usually empty except when
-there is important information to be displayed. The current partition
-is highlighted with reverse video (or an arrow if the
-.B \-a
-option is given). All partition specific commands apply to the
-current partition.
-
-The format of the partition table in the partitions section is, from
-left to right: Name, Flags, Partition Type, Filesystem Type and Size.
-The name is the partition device name. The flags can be
-.IR Boot ,
-which designates a bootable partition or
-.IR NC ,
-which stands for "Not Compatible with DOS or OS/2". DOS, OS/2 and
-possibly other operating systems require the first sector of the first
-partition on the disk and all logical partitions to begin on the
-second head. This wastes the second through the last sector of the
-first track of the first head (the first sector is taken by the
-partition table itself).
-.B cfdisk
-allows you to recover these "lost" sectors with the maximize command
-.RB ( m ).
-.I Note:
-.BR fdisk (8)
-and some early versions of DOS create all partitions with the number
-of sectors already maximized. For more information, see the maximize
-command below. The partition type can be one of
-.IR Primary " or " Logical .
-For unallocated space on the drive, the partition type can also be
-.IR Pri/Log ,
-or empty (if the space is unusable). The filesystem type section
-displays the name of the filesystem used on the partition, if known.
-If it is unknown, then
-.I Unknown
-and the hex value of the filesystem type are displayed. A special
-case occurs when there are sections of the disk drive that cannot be
-used (because all of the primary partitions are used). When this is
-detected, the filesystem type is displayed as
-.IR Unusable .
-The size field displays the size of the partition in megabytes (by
-default). It can also display the size in sectors and cylinders (see
-the change units command below). If an asterisk
-.RB ( * )
-appears after the size, this means that the partition is not aligned
-on cylinder boundaries.
-.SH "DOS 6.x WARNING"
-
-The DOS 6.x FORMAT command looks for some information in the first
-sector of the data area of the partition, and treats this information
-as more reliable than the information in the partition table. DOS
-FORMAT expects DOS FDISK to clear the first 512 bytes of the data area
-of a partition whenever a size change occurs. DOS FORMAT will look at
-this extra information even if the /U flag is given -- we consider
-this a bug in DOS FORMAT and DOS FDISK.
-
-The bottom line is that if you use cfdisk or fdisk to change the size of a
-DOS partition table entry, then you must also use
-.B dd
-to zero the first 512 bytes of that partition before using DOS FORMAT to
-format the partition. For example, if you were using cfdisk to make a DOS
-partition table entry for /dev/hda1, then (after exiting fdisk or cfdisk
-and rebooting Linux so that the partition table information is valid) you
-would use the command "dd if=/dev/zero of=/dev/hda1 bs=512 count=1" to zero
-the first 512 bytes of the partition. Note:
-
-.B BE EXTREMELY CAREFUL
-if you use the
-.B dd
-command, since a small typo can make all of the data on your disk useless.
-
-For best results, you should always use an OS-specific partition table
-program. For example, you should make DOS partitions with the DOS FDISK
-program and Linux partitions with the Linux fdisk or Linux cfdisk program.
-
-.SH COMMANDS
-.B cfdisk
-commands can be entered by pressing the desired key (pressing
-.I Enter
-after the command is not necessary). Here is a list of the available
-commands:
-.TP
-.B b
-Toggle bootable flag of the current partition. This allows you to
-select which primary partition is bootable on the drive.
-.TP
-.B d
-Delete the current partition. This will convert the current partition
-into free space and merge it with any free space immediately
-surrounding the current partition. A partition already marked as free
-space or marked as unusable cannot be deleted.
-.TP
-.B g
-Change the disk geometry (cylinders, heads, or sectors-per-track).
-.B WARNING:
-This option should only be used by people who know what they are
-doing. A command line option is also available to change the disk
-geometry. While at the change disk geometry command line, you can
-choose to change cylinders
-.RB ( c ),
-heads
-.RB ( h ),
-and sectors per track
-.RB ( s ).
-The default value will be printed at the prompt which you can accept
-by simply pressing the
-.I Enter
-key, or you can exit without changes by pressing the
-.I ESC
-key. If you want to change the default value, simply enter the
-desired value and press
-.IR Enter .
-The altered disk parameter values do not take effect until you return
-to the main menu (by pressing
-.IR Enter " or " ESC
-at the change disk geometry command line). If you change the geometry
-such that the disk appears larger, the extra sectors are added at the
-end of the disk as free space. If the disk appears smaller, the
-partitions that are beyond the new last sector are deleted and the
-last partition on the drive (or the free space at the end of the
-drive) is made to end at the new last sector.
-.TP
-.B h
-Print the help screen.
-.TP
-.B m
-Maximize disk usage of the current partition. This command will
-recover the unused space between the partition table and the
-beginning of the partition, but at the cost of making the partition
-incompatible with DOS, OS/2 and possibly other operating systems.
-This option will toggle between maximal disk usage and DOS, OS/2,
-etc. compatible disk usage. The default when creating a partition is
-to create DOS, OS/2, etc. compatible partitions.
-.TP
-.B n
-Create new partition from free space. If the partition type is
-.IR Primary " or " Logical ,
-a partition of that type will be created, but if the partition type is
-.IR Pri/Log ,
-you will be prompted for the type you want to create. Be aware that
-(1) there are only four slots available for primary partitions and (2)
-since there can be only one extended partition, which contains all of
-the logical drives, all of the logical drives must be contiguous (with
-no intervening primary partition).
-.B cfdisk
-next prompts you for the size of the partition you want to create.
-The default size, equal to the entire free space of the current
-partition, is displayed in megabytes. You can either press the
-.I Enter
-key to accept the default size or enter a different size at the
-prompt.
-.B cfdisk
-accepts size entries in megabytes
-.RB ( M )
-[default], kilobytes
-.RB ( K ),
-cylinders
-.RB ( C )
-and sectors
-.RB ( S )
-by entering the number immediately followed by one of
-.RB ( M ", " K ", " C " or " S ).
-If the partition fills the free space available, the partition is
-created and you are returned to the main command line. Otherwise, the
-partition can be created at the beginning or the end of the free
-space, and
-.B cfdisk
-will ask you to choose where to place the partition. After the
-partition is created,
-.B cfdisk
-automatically adjusts the other partitions' partition types if all of
-the primary partitions are used.
-.TP
-.B p
-Print the partition table to the screen or to a file. There are
-several different formats for the partition that you can choose from:
-.sp
-.RS
-.TP
-.B r
-Raw data format (exactly what would be written to disk)
-.TP
-.B s
-Partition table in sector order format
-.TP
-.B t
-Partition table in raw format
-.RE
-
-.RS
-The
-.I raw data format
-will print the sectors that would be written to disk if a
-.BR w rite
-command is selected. First, the primary partition table is printed,
-followed by the partition tables associated with each logical
-partition. The data is printed in hex byte by byte with 16 bytes per
-line.
-
-The
-.I partition table in sector order format
-will print the partition table ordered by sector number. The fields,
-from left to right, are the number of the partition, the partition
-type, the first sector, the last sector, the offset from the first
-sector of the partition to the start of the data, the length of the
-partition, the filesystem type (with the hex value in parenthesis),
-and the flags (with the hex value in parenthesis). In addition to the
-primary and logical partitions, free and unusable space is printed and
-the extended partition is printed before the first logical partition.
-
-If a partition does not start or end on a cylinder boundary or if the
-partition length is not divisible by the cylinder size, an asterisk
-.RB ( * )
-is printed after the non-aligned sector number/count. This usually
-indicates that a partition was created by an operating system that
-either does not align partitions to cylinder boundaries or that used
-different disk geometry information. If you know the disk geometry of
-the other operating system, you could enter the geometry information
-with the change geometry command
-.RB ( g ).
-
-For the first partition on the disk and for all logical partitions, if
-the offset from the beginning of the partition is not equal to the
-number of sectors per track (i.e., the data does not start on the
-first head), a number sign
-.RB ( # )
-is printed after the offset. For the remaining partitions, if the
-offset is not zero, a number sign will be printed after the offset.
-This corresponds to the
-.I NC
-flag in the partitions section of the main display.
-
-The
-.I partition table in raw format
-will print the partition table ordered by partition number. It will
-leave out all free and unusable space. The fields, from left to
-right, are the number of the partition, the flags (in hex), the
-starting head, sector and cylinder, the filesystem ID (in hex), the
-ending head, sector and cylinder, the starting sector in the partition
-and the number of sectors in the partition. The information in this
-table can be directly translated to the
-.IR "raw data format" .
-
-The partition table entries only have 10 bits available to represent
-the starting and ending cylinders. Thus, when the absolute starting
-(ending) sector number is on a cylinder greater than 1023, the maximal
-values for starting (ending) head, sector and cylinder are printed.
-This is the method used by OS/2, and thus fixes the problems
-associated with OS/2's fdisk rewriting the partition table when it is
-not in this format. Since Linux and OS/2 use absolute sector counts,
-the values in the starting and ending head, sector and cylinder are
-not used.
-.RE
-.TP
-.B q
-Quit program. This will exit the program without writing any data to
-disk.
-.TP
-.B t
-Change the filesystem type. By default, new partitions are created as
-.I Linux
-partitions, but since
-.B cfdisk
-can create partitions for other operating systems, change partition
-type allows you to enter the hex value of the filesystem you desire.
-A list of the know filesystem types is displayed. You can type in the
-filesystem type at the prompt or accept the default filesystem type
-.RI [ Linux ].
-.TP
-.B u
-Change units of the partition size display. It will rotate through
-megabytes, sectors and cylinders.
-.TP
-.B W
-Write partition table to disk (must enter an upper case W). Since
-this might destroy data on the disk, you must either confirm or deny
-the write by entering `yes' or `no'. If you enter `yes',
-.B cfdisk
-will write the partition table to disk and the tell the kernel to re-read the
-partition table from the disk. The re-reading of the partition table does not
-work in some cases, for example for device-mapper devices. In
-particular case you need to inform kernel about new
-partitions by
-.B partprobe(8),
-.B kpartx(8)
-or reboot the system.
-.TP
-.I Up Arrow
-.TP
-.I Down Arrow
-Move cursor to the previous or next partition. If there are more
-partitions than can be displayed on a screen, you can display the next
-(previous) set of partitions by moving down (up) at the last (first)
-partition displayed on the screen.
-.TP
-.I CTRL-L
-Redraws the screen. In case something goes wrong and you cannot read
-anything, you can refresh the screen from the main command line.
-.TP
-.B ?
-Print the help screen.
-
-.RE
-All of the commands can be entered with either upper or lower case
-letters (except for
-.BR W rites).
-When in a sub-menu or at a prompt to enter a filename, you can hit the
-.I ESC
-key to return to the main command line.
-.SH OPTIONS
-.TP
-.B \-a
-Use an arrow cursor instead of reverse video for highlighting the
-current partition.
-.TP
-.B \-g
-Do not use the geometry given by the disk driver, but try to
-guess a geometry from the partition table.
-.TP
-.B \-v
-Print the version number and copyright.
-.TP
-.B \-z
-Start with zeroed partition table. This option is useful when you
-want to repartition your entire disk.
-.I Note:
-this option does not zero the partition table on the disk; rather, it
-simply starts the program without reading the existing partition
-table.
-.TP
-.BI \-c " cylinders"
-.TP
-.BI \-h " heads"
-.TP
-.BI \-s " sectors-per-track"
-Override the number of cylinders, heads and sectors per track read
-from the BIOS. If your BIOS or adapter does not supply this
-information or if it supplies incorrect information, use these options
-to set the disk geometry values.
-.TP
-.BI \-P " opt"
-Prints the partition table in specified formats.
-.I opt
-can be one or more of "r", "s" or "t". See the
-.BR p rint
-command (above) for more information on the print formats.
-.SH "EXIT STATUS"
-0: No errors; 1: Invocation error; 2: I/O error;
-3: cannot get geometry; 4: bad partition table on disk.
-.SH "SEE ALSO"
-.BR fdisk (8),
-.BR sfdisk (8),
-.BR mkfs (8),
-.BR parted (8),
-.BR partprobe (8),
-.BR kpartx(8)
-.SH BUGS
-The current version does not support multiple disks.
-.SH AUTHOR
-Kevin E. Martin (martin@cs.unc.edu)
-
-.SH AVAILABILITY
-The cfdisk command is part of the util-linux package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/fdisk/cfdisk.c b/fdisk/cfdisk.c
deleted file mode 100644
index 967a1034c..000000000
--- a/fdisk/cfdisk.c
+++ /dev/null
@@ -1,2854 +0,0 @@
-/****************************************************************************
- *
- * CFDISK
- *
- * cfdisk is a curses based disk drive partitioning program that can
- * create partitions for a wide variety of operating systems including
- * Linux, MS-DOS and OS/2.
- *
- * cfdisk was inspired by the fdisk program, by A. V. Le Blanc
- * (LeBlanc@mcc.ac.uk).
- *
- * Copyright (C) 1994 Kevin E. Martin (martin@cs.unc.edu)
- *
- * cfdisk is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * cfdisk is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Created: Fri Jan 28 22:46:58 1994, martin@cs.unc.edu
- * >2GB patches: Sat Feb 11 09:08:10 1995, faith@cs.unc.edu
- * Prettier menus: Sat Feb 11 09:08:25 1995, Janne Kukonlehto
- * <jtklehto@stekt.oulu.fi>
- * Versions 0.8e-p: aeb@cwi.nl
- * Rebaptised 2.9p, following util-linux versioning.
- *
- * Recognition of NTFS / HPFS difference inspired by patches
- * from Marty Leisner <leisner@sdsp.mc.xerox.com>
- * Exit codes by Enrique Zanardi <ezanardi@ull.es>:
- * 0: all went well
- * 1: command line error, out of memory
- * 2: hardware problems [Cannot open/seek/read/write disk drive].
- * 3: ioctl(fd, HDIO_GETGEO,...) failed. (Probably it is not a disk.)
- * 4: bad partition table on disk. [Bad primary/logical partition].
- *
- * Sat, 23 Jan 1999 19:34:45 +0100 <Vincent.Renardias@ldsol.com>
- * Internationalized + provided initial French translation.
- * Sat Mar 20 09:26:34 EST 1999 <acme@conectiva.com.br>
- * Some more i18n.
- * Sun Jul 18 03:19:42 MEST 1999 <aeb@cwi.nl>
- * Terabyte-sized disks.
- * Sat Jun 30 05:23:19 EST 2001 <nathans@sgi.com>
- * XFS label recognition.
- * Thu Nov 22 15:42:56 CET 2001 <flavio.stanchina@tin.it>
- * ext3 and ReiserFS recognition.
- * Sun Oct 12 17:43:43 CEST 2003 <flavio.stanchina@tin.it>
- * JFS recognition; ReiserFS label recognition.
- *
- ****************************************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <errno.h>
-#include <getopt.h>
-#include <fcntl.h>
-
-#ifdef HAVE_SLANG_H
-#include <slang.h>
-#elif defined(HAVE_SLANG_SLANG_H)
-#include <slang/slang.h>
-#endif
-
-#ifdef HAVE_SLCURSES_H
-#include <slcurses.h>
-#elif defined(HAVE_SLANG_SLCURSES_H)
-#include <slang/slcurses.h>
-#elif defined(HAVE_NCURSESW_NCURSES_H) && defined(HAVE_WIDECHAR)
-#include <ncursesw/ncurses.h>
-#elif defined(HAVE_NCURSES_H)
-#include <ncurses.h>
-#elif defined(HAVE_NCURSES_NCURSES_H)
-#include <ncurses/ncurses.h>
-#endif
-
-#include <signal.h>
-#include <math.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#ifdef HAVE_LIBBLKID
-#include <blkid.h>
-#endif
-
-#ifdef HAVE_WIDECHAR
-#include <wctype.h>
-#endif
-
-#include "closestream.h"
-#include "nls.h"
-#include "rpmatch.h"
-#include "blkdev.h"
-#include "strutils.h"
-#include "common.h"
-#include "gpt.h"
-#include "mbsalign.h"
-#include "widechar.h"
-
-#ifdef __GNU__
-#define DEFAULT_DEVICE "/dev/hd0"
-#define ALTERNATE_DEVICE "/dev/sd0"
-#elif defined(__FreeBSD__)
-#define DEFAULT_DEVICE "/dev/ad0"
-#define ALTERNATE_DEVICE "/dev/da0"
-#else
-#define DEFAULT_DEVICE "/dev/hda"
-#define ALTERNATE_DEVICE "/dev/sda"
-#endif
-
-/* With K=1024 we have `binary' megabytes, gigabytes, etc.
- Some misguided hackers like that.
- With K=1000 we have MB and GB that follow the standards
- [SI, ATA, IEEE etc] and the disk manufacturers and the law. */
-#define K 1000
-
-#define LINE_LENGTH 80
-#define MAXIMUM_PARTS 60
-
-#define SECTOR_SIZE 512
-
-#define MAX_HEADS 256
-#define MAX_SECTORS 63
-
-#define ACTIVE_FLAG 0x80
-#define PART_TABLE_FLAG0 0x55
-#define PART_TABLE_FLAG1 0xAA
-
-#define UNUSABLE -1
-#define FREE_SPACE 0x00
-#define DOS_EXTENDED 0x05
-#define OS2_OR_NTFS 0x07
-#define WIN98_EXTENDED 0x0f
-#define LINUX_EXTENDED 0x85
-#define LINUX_MINIX 0x81
-#define LINUX_SWAP 0x82
-#define LINUX 0x83
-
-#define PRI_OR_LOG -1
-#define PRIMARY -2
-#define LOGICAL -3
-
-#define COL_ID_WIDTH 25
-
-#define ESC '\033'
-#define DEL '\177'
-#define BELL '\007'
-#define REDRAWKEY '\014' /* ^L */
-
-/* Display units */
-#define GIGABYTES 1
-#define MEGABYTES 2
-#define SECTORS 3
-#define CYLINDERS 4
-
-#define GS_DEFAULT -1
-#define GS_ESCAPE -2
-
-#define PRINT_RAW_TABLE 1
-#define PRINT_SECTOR_TABLE 2
-#define PRINT_PARTITION_TABLE 4
-
-#define IS_PRIMARY(p) ((p) >= 0 && (p) < 4)
-#define IS_LOGICAL(p) ((p) > 3)
-
-#define round_int(d) ((double)((int)(d+0.5)))
-#define ceiling(d) ((double)(((d) != (int)(d)) ? (int)(d+1.0) : (int)(d)))
-
-struct partition {
- unsigned char boot_ind; /* 0x80 - active */
- unsigned char head; /* starting head */
- unsigned char sector; /* starting sector */
- unsigned char cyl; /* starting cylinder */
- unsigned char sys_ind; /* What partition type */
- unsigned char end_head; /* end head */
- unsigned char end_sector; /* end sector */
- unsigned char end_cyl; /* end cylinder */
- unsigned char start4[4]; /* starting sector counting from 0 */
- unsigned char size4[4]; /* nr of sectors in partition */
-};
-
-int heads = 0;
-int sectors = 0;
-long long cylinders = 0;
-int cylinder_size = 0; /* heads * sectors */
-long long actual_size = 0; /* (in 512-byte sectors) - set using ioctl */
- /* explicitly given user values */
-int user_heads = 0, user_sectors = 0;
-long long user_cylinders = 0;
- /* kernel values; ignore the cylinders */
-int kern_heads = 0, kern_sectors = 0;
- /* partition-table derived values */
-int pt_heads = 0, pt_sectors = 0;
-
-
-static void
-set_hsc0(unsigned char *h, unsigned char *s, int *c, long long sector) {
- *s = sector % sectors + 1;
- sector /= sectors;
- *h = sector % heads;
- sector /= heads;
- *c = sector;
-}
-
-static void
-set_hsc(unsigned char *h, unsigned char *s, unsigned char *c,
- long long sector) {
- int cc;
-
- if (sector >= 1024*cylinder_size)
- sector = 1024*cylinder_size - 1;
- set_hsc0(h, s, &cc, sector);
- *c = cc & 0xFF;
- *s |= (cc >> 2) & 0xC0;
-}
-
-static void
-set_hsc_begin(struct partition *p, long long sector) {
- set_hsc(& p->head, & p->sector, & p->cyl, sector);
-}
-
-static void
-set_hsc_end(struct partition *p, long long sector) {
- set_hsc(& p->end_head, & p->end_sector, & p->end_cyl, sector);
-}
-
-#define is_extended(x) ((x) == DOS_EXTENDED || (x) == WIN98_EXTENDED || \
- (x) == LINUX_EXTENDED)
-
-/* start_sect and nr_sects are stored little endian on all machines */
-/* moreover, they are not aligned correctly */
-static void
-store4_little_endian(unsigned char *cp, unsigned int val) {
- cp[0] = (val & 0xff);
- cp[1] = ((val >> 8) & 0xff);
- cp[2] = ((val >> 16) & 0xff);
- cp[3] = ((val >> 24) & 0xff);
-}
-
-static unsigned int
-read4_little_endian(unsigned char *cp) {
- return (unsigned int)(cp[0]) + ((unsigned int)(cp[1]) << 8)
- + ((unsigned int)(cp[2]) << 16)
- + ((unsigned int)(cp[3]) << 24);
-}
-
-static void
-set_start_sect(struct partition *p, unsigned int start_sect) {
- store4_little_endian(p->start4, start_sect);
-}
-
-static unsigned int
-get_start_sect(struct partition *p) {
- return read4_little_endian(p->start4);
-}
-
-static void
-set_nr_sects(struct partition *p, unsigned int nr_sects) {
- store4_little_endian(p->size4, nr_sects);
-}
-
-static unsigned int
-get_nr_sects(struct partition *p) {
- return read4_little_endian(p->size4);
-}
-
-#define ALIGNMENT 2
-typedef union {
- struct {
- unsigned char align[ALIGNMENT];
- unsigned char b[SECTOR_SIZE];
- } c;
- struct {
- unsigned char align[ALIGNMENT];
- unsigned char buffer[0x1BE];
- struct partition part[4];
- unsigned char magicflag[2];
- } p;
-} partition_table;
-
-typedef struct {
- long long first_sector; /* first sector in partition */
- long long last_sector; /* last sector in partition */
- long offset; /* offset from first sector to start of data */
- int flags; /* active == 0x80 */
- int id; /* filesystem type */
- int num; /* number of partition -- primary vs. logical */
-#define LABELSZ 16
- char volume_label[LABELSZ+1];
-#define OSTYPESZ 8
- char ostype[OSTYPESZ+1];
-#define FSTYPESZ 12
- char fstype[FSTYPESZ+1];
-} partition_info;
-
-char *disk_device = DEFAULT_DEVICE;
-int fd;
-int changed = FALSE;
-int opened = FALSE;
-int opentype;
-int curses_started = 0;
-
-partition_info p_info[MAXIMUM_PARTS];
-partition_info ext_info;
-int num_parts = 0;
-
-int logical = 0;
-long long logical_sectors[MAXIMUM_PARTS];
-
-__sighandler_t old_SIGINT, old_SIGTERM;
-
-int arrow_cursor = FALSE;
-int display_units = MEGABYTES;
-int zero_table = FALSE;
-int use_partition_table_geometry = FALSE;
-int print_only = 0;
-
-/* Curses screen information */
-int cur_part = 0;
-int warning_last_time = FALSE;
-int defined = FALSE;
-int COLUMNS = 80;
-int NUM_ON_SCREEN = 1;
-
-/* Y coordinates */
-int HEADER_START = 0;
-int DISK_TABLE_START = 6;
-int WARNING_START = 23;
-int COMMAND_LINE_Y = 21;
-
-/* X coordinates */
-int NAME_START = 4;
-int FLAGS_START = 16;
-int PTYPE_START = 28;
-int FSTYPE_START = 38;
-int LABEL_START = 54;
-int SIZE_START = 68;
-int COMMAND_LINE_X = 5;
-
-static void die_x(int ret);
-static void draw_screen(void);
-
-/* Guaranteed alloc */
-static void *
-xmalloc (size_t size) {
- void *t;
-
- if (size == 0)
- return NULL;
-
- t = malloc (size);
- if (t == NULL) {
- fprintf (stderr, _("%s: Out of memory!\n"), "cfdisk");
- die_x(1);
- }
- return t;
-}
-
-/* Some libc's have their own basename() */
-static char *
-my_basename(char *devname) {
- char *s = strrchr(devname, '/');
- return s ? s+1 : devname;
-}
-
-static char *
-partition_type_name(unsigned char type) {
- struct systypes *s = i386_sys_types;
-
- while(s->name && s->type != type)
- s++;
- return s->name;
-}
-
-static char *
-partition_type_text(int i) {
- if (p_info[i].id == UNUSABLE)
- return _("Unusable");
- else if (p_info[i].id == FREE_SPACE)
- return _("Free Space");
- else if (*p_info[i].fstype)
- return p_info[i].fstype;
- else
- return _(partition_type_name(p_info[i].id));
-}
-
-static void
-fdexit(int ret) {
- if (opened) {
- if (changed)
- fsync(fd);
- close(fd);
- }
- if (changed) {
- fprintf(stderr, _("Disk has been changed.\n"));
-#if 0
- fprintf(stderr, _("Reboot the system to ensure the partition "
- "table is correctly updated.\n"));
-#endif
-
- fprintf( stderr, _("\nWARNING: If you have created or modified any\n"
- "DOS 6.x partitions, please see the cfdisk manual\n"
- "page for additional information.\n") );
- }
-
- exit(ret);
-}
-
-/*
- * Note that @len is size of @str buffer.
- *
- * Returns number of read bytes (without \0).
- */
-static int
-get_string(char *str, int len, char *def) {
- size_t cells = 0;
- ssize_t i = 0;
- int x, y;
- int use_def = FALSE;
- wint_t c;
-
- getyx(stdscr, y, x);
- clrtoeol();
-
- str[i] = 0;
-
- if (def != NULL) {
- mvaddstr(y, x, def);
- move(y, x);
- use_def = TRUE;
- }
-
- refresh();
-
- while (1) {
-#if !defined(HAVE_SLCURSES_H) && !defined(HAVE_SLANG_SLCURSES_H) && \
- defined(HAVE_LIBNCURSESW) && defined(HAVE_WIDECHAR)
- if (get_wch(&c) == ERR) {
-#else
- if ((c = getch()) == ERR) {
-#endif
- if (!isatty(STDIN_FILENO))
- exit(2);
- else
- break;
- }
- if (c == '\r' || c == '\n' || c == KEY_ENTER)
- break;
-
- switch (c) {
- case ESC:
- move(y, x);
- clrtoeol();
- refresh();
- return GS_ESCAPE;
- case DEL:
- case '\b':
- case KEY_BACKSPACE:
- if (i > 0) {
- cells--;
- i = mbs_truncate(str, &cells);
- if (i < 0)
- return GS_ESCAPE;
- mvaddch(y, x + cells, ' ');
- move(y, x + cells);
- } else if (use_def) {
- clrtoeol();
- use_def = FALSE;
- } else
- putchar(BELL);
- break;
- default:
-#if defined(HAVE_LIBNCURSESW) && defined(HAVE_WIDECHAR)
- if (i + 1 < len && iswprint(c)) {
- wchar_t wc = (wchar_t) c;
- char s[MB_CUR_MAX + 1];
- int sz = wctomb(s, wc);
-
- if (sz > 0 && sz + i < len) {
- s[sz] = '\0';
- mvaddnstr(y, x + cells, s, sz);
- if (use_def) {
- clrtoeol();
- use_def = FALSE;
- }
- memcpy(str + i, s, sz);
- i += sz;
- str[i] = '\0';
- cells += wcwidth(wc);
- } else
- putchar(BELL);
- }
-#else
- if (i + 1 < len && isprint(c)) {
- mvaddch(y, x + cells, c);
- if (use_def) {
- clrtoeol();
- use_def = FALSE;
- }
- str[i++] = c;
- str[i] = 0;
- cells++;
- }
-#endif
- else
- putchar(BELL);
- }
- refresh();
- }
-
- if (use_def)
- return GS_DEFAULT;
- else
- return i;
-}
-
-static void
-clear_warning(void) {
- int i;
-
- if (!curses_started || !warning_last_time)
- return;
-
- move(WARNING_START,0);
- for (i = 0; i < COLS; i++)
- addch(' ');
-
- warning_last_time = FALSE;
-}
-
-static void
-print_warning(char *s) {
- if (!curses_started) {
- fprintf(stderr, "%s\n", s);
- } else {
- mvaddstr(WARNING_START, (COLS-strlen(s))/2, s);
- putchar(BELL); /* CTRL-G */
-
- warning_last_time = TRUE;
- }
-}
-
-static void
-fatal(char *s, int ret) {
- char *err1 = _("FATAL ERROR");
- char *err2 = _("Press any key to exit cfdisk");
-
- if (curses_started) {
- char *str = xmalloc(strlen(s) + strlen(err1) + strlen(err2) + 10);
-
- sprintf(str, "%s: %s", err1, s);
- if (strlen(str) > (size_t) COLS)
- str[COLS] = 0;
- mvaddstr(WARNING_START, (COLS-strlen(str))/2, str);
- sprintf(str, "%s", err2);
- if (strlen(str) > (size_t) COLS)
- str[COLS] = 0;
- mvaddstr(WARNING_START+1, (COLS-strlen(str))/2, str);
- putchar(BELL); /* CTRL-G */
- refresh();
- (void)getch();
- die_x(ret);
- } else {
- fprintf(stderr, "%s: %s\n", err1, s);
- exit(ret);
- }
-}
-
-static void
-die(int dummy __attribute__((__unused__))) {
- die_x(0);
-}
-
-static void
-die_x(int ret) {
- signal(SIGINT, old_SIGINT);
- signal(SIGTERM, old_SIGTERM);
-#if defined(HAVE_SLCURSES_H) || defined(HAVE_SLANG_SLCURSES_H)
- SLsmg_gotorc(LINES-1, 0);
- SLsmg_refresh();
-#else
- mvcur(0, COLS-1, LINES-1, 0);
-#endif
- nl();
- endwin();
- printf("\n");
- fdexit(ret);
-}
-
-static void
-read_sector(unsigned char *buffer, long long sect_num) {
- if (lseek(fd, sect_num*SECTOR_SIZE, SEEK_SET) < 0)
- fatal(_("Cannot seek on disk drive"), 2);
- if (read(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
- fatal(_("Cannot read disk drive"), 2);
-}
-
-static void
-write_sector(unsigned char *buffer, long long sect_num) {
- if (lseek(fd, sect_num*SECTOR_SIZE, SEEK_SET) < 0)
- fatal(_("Cannot seek on disk drive"), 2);
- if (write(fd, buffer, SECTOR_SIZE) != SECTOR_SIZE)
- fatal(_("Cannot write disk drive"), 2);
-}
-
-#ifdef HAVE_LIBBLKID
-static void
-get_fsinfo(int i)
-{
- blkid_probe pr;
- blkid_loff_t offset, size;
- const char *data;
-
- offset = (p_info[i].first_sector + p_info[i].offset) * SECTOR_SIZE;
- size = (p_info[i].last_sector - p_info[i].first_sector + 1) * SECTOR_SIZE;
- pr = blkid_new_probe();
- if (!pr)
- return;
- blkid_probe_enable_superblocks(pr, 1);
- blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL |
- BLKID_SUBLKS_TYPE);
- if (blkid_probe_set_device(pr, fd, offset, size))
- goto done;
- if (blkid_do_safeprobe(pr))
- goto done;
-
- if (!blkid_probe_lookup_value(pr, "TYPE", &data, 0))
- strncpy(p_info[i].fstype, data, FSTYPESZ);
-
- if (!blkid_probe_lookup_value(pr, "LABEL", &data, 0))
- strncpy(p_info[i].volume_label, data, LABELSZ);
-done:
- blkid_free_probe(pr);
-}
-#endif
-
-static void
-check_part_info(void) {
- int i, pri = 0, log = 0;
-
- for (i = 0; i < num_parts; i++)
- if (p_info[i].id > 0 && IS_PRIMARY(p_info[i].num))
- pri++;
- else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
- log++;
- if (is_extended(ext_info.id)) {
- if (log > 0)
- pri++;
- else {
- ext_info.first_sector = 0;
- ext_info.last_sector = 0;
- ext_info.offset = 0;
- ext_info.flags = 0;
- ext_info.id = FREE_SPACE;
- ext_info.num = PRIMARY;
- }
- }
-
- if (pri >= 4) {
- for (i = 0; i < num_parts; i++)
- if (p_info[i].id == FREE_SPACE || p_info[i].id == UNUSABLE) {
- if (is_extended(ext_info.id)) {
- if (p_info[i].first_sector >= ext_info.first_sector &&
- p_info[i].last_sector <= ext_info.last_sector) {
- p_info[i].id = FREE_SPACE;
- p_info[i].num = LOGICAL;
- } else if (i > 0 &&
- p_info[i-1].first_sector >=
- ext_info.first_sector &&
- p_info[i-1].last_sector <=
- ext_info.last_sector) {
- p_info[i].id = FREE_SPACE;
- p_info[i].num = LOGICAL;
- } else if (i < num_parts-1 &&
- p_info[i+1].first_sector >=
- ext_info.first_sector &&
- p_info[i+1].last_sector <=
- ext_info.last_sector) {
- p_info[i].id = FREE_SPACE;
- p_info[i].num = LOGICAL;
- } else
- p_info[i].id = UNUSABLE;
- } else /* if (!is_extended(ext_info.id)) */
- p_info[i].id = UNUSABLE;
- } else /* if (p_info[i].id > 0) */
- while (0); /* Leave these alone */
- } else { /* if (pri < 4) */
- for (i = 0; i < num_parts; i++) {
- if (p_info[i].id == UNUSABLE)
- p_info[i].id = FREE_SPACE;
- if (p_info[i].id == FREE_SPACE) {
- if (is_extended(ext_info.id)) {
- if (p_info[i].first_sector >= ext_info.first_sector &&
- p_info[i].last_sector <= ext_info.last_sector)
- p_info[i].num = LOGICAL;
- else if (i > 0 &&
- p_info[i-1].first_sector >=
- ext_info.first_sector &&
- p_info[i-1].last_sector <=
- ext_info.last_sector)
- p_info[i].num = PRI_OR_LOG;
- else if (i < num_parts-1 &&
- p_info[i+1].first_sector >=
- ext_info.first_sector &&
- p_info[i+1].last_sector <=
- ext_info.last_sector)
- p_info[i].num = PRI_OR_LOG;
- else
- p_info[i].num = PRIMARY;
- } else /* if (!is_extended(ext_info.id)) */
- p_info[i].num = PRI_OR_LOG;
- } else /* if (p_info[i].id > 0) */
- while (0); /* Leave these alone */
- }
- }
-}
-
-static void
-remove_part(int i) {
- int p;
-
- for (p = i; p < num_parts; p++)
- p_info[p] = p_info[p+1];
-
- num_parts--;
- if (cur_part == num_parts)
- cur_part--;
-}
-
-static void
-insert_empty_part(int i, long long first, long long last) {
- int p;
-
- for (p = num_parts; p > i; p--)
- p_info[p] = p_info[p-1];
-
- p_info[i].first_sector = first;
- p_info[i].last_sector = last;
- p_info[i].offset = 0;
- p_info[i].flags = 0;
- p_info[i].id = FREE_SPACE;
- p_info[i].num = PRI_OR_LOG;
- p_info[i].volume_label[0] = 0;
- p_info[i].fstype[0] = 0;
- p_info[i].ostype[0] = 0;
-
- num_parts++;
-}
-
-static void
-del_part(int i) {
- int num = p_info[i].num;
-
- if (i > 0 && (p_info[i-1].id == FREE_SPACE ||
- p_info[i-1].id == UNUSABLE)) {
- /* Merge with previous partition */
- p_info[i-1].last_sector = p_info[i].last_sector;
- remove_part(i--);
- }
-
- if (i < num_parts - 1 && (p_info[i+1].id == FREE_SPACE ||
- p_info[i+1].id == UNUSABLE)) {
- /* Merge with next partition */
- p_info[i+1].first_sector = p_info[i].first_sector;
- remove_part(i);
- }
-
- if (i > 0)
- p_info[i].first_sector = p_info[i-1].last_sector + 1;
- else
- p_info[i].first_sector = 0;
-
- if (i < num_parts - 1)
- p_info[i].last_sector = p_info[i+1].first_sector - 1;
- else
- p_info[i].last_sector = actual_size - 1;
-
- p_info[i].offset = 0;
- p_info[i].flags = 0;
- p_info[i].id = FREE_SPACE;
- p_info[i].num = PRI_OR_LOG;
-
- if (IS_LOGICAL(num)) {
- /* We have a logical partition --> shrink the extended partition
- * if (1) this is the first logical drive, or (2) this is the
- * last logical drive; and if there are any other logical drives
- * then renumber the ones after "num".
- */
- if (i == 0 || (i > 0 && IS_PRIMARY(p_info[i-1].num))) {
- ext_info.first_sector = p_info[i].last_sector + 1;
- ext_info.offset = 0;
- }
- if (i == num_parts-1 ||
- (i < num_parts-1 && IS_PRIMARY(p_info[i+1].num)))
- ext_info.last_sector = p_info[i].first_sector - 1;
- for (i = 0; i < num_parts; i++)
- if (p_info[i].num > num)
- p_info[i].num--;
- }
-
- /* Clean up the rest of the partitions */
- check_part_info();
-}
-
-static int
-add_part(int num, int id, int flags, long long first, long long last,
- long long offset, int want_label, char **errmsg) {
- int i, pri = 0, log = 0;
-
- if (num_parts == MAXIMUM_PARTS) {
- *errmsg = _("Too many partitions");
- return -1;
- }
-
- if (first < 0) {
- *errmsg = _("Partition begins before sector 0");
- return -1;
- }
-
- if (last < 0) {
- *errmsg = _("Partition ends before sector 0");
- return -1;
- }
-
- if (first >= actual_size) {
- *errmsg = _("Partition begins after end-of-disk");
- return -1;
- }
-
- if (last >= actual_size) {
- *errmsg = _("Partition ends after end-of-disk");
- return -1;
- }
-
- for (i = 0; i < num_parts; i++) {
- if (p_info[i].id > 0 && IS_PRIMARY(p_info[i].num))
- pri++;
- else if (p_info[i].id > 0 && IS_LOGICAL(p_info[i].num))
- log++;
- }
- if (is_extended(ext_info.id) && log > 0)
- pri++;
-
- if (IS_PRIMARY(num)) {
- if (pri >= 4) {
- return -1; /* no room for more */
- } else
- pri++;
- }
-
- for (i = 0; i < num_parts && p_info[i].last_sector < first; i++);
-
- if (i < num_parts && p_info[i].id != FREE_SPACE) {
- if (last < p_info[i].first_sector)
- *errmsg = _("logical partitions not in disk order");
- else if (first + offset <= p_info[i].last_sector &&
- p_info[i].first_sector + p_info[i].offset <= last)
- *errmsg = _("logical partitions overlap");
- else
- /* the enlarged logical partition starts at the
- partition table sector that defines it */
- *errmsg = _("enlarged logical partitions overlap");
- return -1;
- }
-
- if (i == num_parts || last > p_info[i].last_sector) {
- return -1;
- }
-
- if (is_extended(id)) {
- if (ext_info.id != FREE_SPACE) {
- return -1; /* second extended */
- }
- else if (IS_PRIMARY(num)) {
- ext_info.first_sector = first;
- ext_info.last_sector = last;
- ext_info.offset = offset;
- ext_info.flags = flags;
- ext_info.id = id;
- ext_info.num = num;
- ext_info.volume_label[0] = 0;
- ext_info.fstype[0] = 0;
- ext_info.ostype[0] = 0;
- return 0;
- } else {
- return -1; /* explicit extended logical */
- }
- }
-
- if (IS_LOGICAL(num)) {
- if (!is_extended(ext_info.id)) {
- print_warning(_("!!!! Internal error creating logical "
- "drive with no extended partition !!!!"));
- } else {
- /* We might have a logical partition outside of the extended
- * partition's range --> we have to extend the extended
- * partition's range to encompass this new partition, but we
- * must make sure that there are no primary partitions between
- * it and the closest logical drive in extended partition.
- */
- if (first < ext_info.first_sector) {
- if (i < num_parts-1 && IS_PRIMARY(p_info[i+1].num)) {
- print_warning(_("Cannot create logical drive here -- would create two extended partitions"));
- return -1;
- } else {
- if (first == 0) {
- ext_info.first_sector = 0;
- ext_info.offset = first = offset;
- } else {
- ext_info.first_sector = first;
- }
- }
- } else if (last > ext_info.last_sector) {
- if (i > 0 && IS_PRIMARY(p_info[i-1].num)) {
- print_warning(_("Cannot create logical drive here -- would create two extended partitions"));
- return -1;
- } else {
- ext_info.last_sector = last;
- }
- }
- }
- }
-
- if (first != p_info[i].first_sector &&
- !(IS_LOGICAL(num) && first == offset)) {
- insert_empty_part(i, p_info[i].first_sector, first-1);
- i++;
- }
-
- if (last != p_info[i].last_sector)
- insert_empty_part(i+1, last+1, p_info[i].last_sector);
-
- p_info[i].first_sector = first;
- p_info[i].last_sector = last;
- p_info[i].offset = offset;
- p_info[i].flags = flags;
- p_info[i].id = id;
- p_info[i].num = num;
- p_info[i].volume_label[0] = 0;
- p_info[i].fstype[0] = 0;
- p_info[i].ostype[0] = 0;
-
-#ifdef HAVE_LIBBLKID
- if (want_label)
- get_fsinfo(i);
-#endif
- check_part_info();
-
- return 0;
-}
-
-static int
-find_primary(void) {
- int num = 0, cur = 0;
-
- while (cur < num_parts && IS_PRIMARY(num))
- if ((p_info[cur].id > 0 && p_info[cur].num == num) ||
- (is_extended(ext_info.id) && ext_info.num == num)) {
- num++;
- cur = 0;
- } else
- cur++;
-
- if (!IS_PRIMARY(num))
- return -1;
- else
- return num;
-}
-
-static int
-find_logical(int i) {
- int num = -1;
- int j;
-
- for (j = i; j < num_parts && num == -1; j++)
- if (p_info[j].id > 0 && IS_LOGICAL(p_info[j].num))
- num = p_info[j].num;
-
- if (num == -1) {
- num = 4;
- for (j = 0; j < num_parts; j++)
- if (p_info[j].id > 0 && p_info[j].num == num)
- num++;
- }
-
- return num;
-}
-
-/*
- * Command menu support by Janne Kukonlehto <jtklehto@phoenix.oulu.fi>
- * September 1994
- */
-
-/* Constants for menuType parameter of menuSelect function */
-#define MENU_ACCEPT_OTHERS 4
-#define MENU_BUTTON 8
-/* Miscellenous constants */
-#define MENU_SPACING 2
-#define MENU_MAX_ITEMS 256 /* for simpleMenu function */
-
-struct MenuItem
-{
- int key; /* Keyboard shortcut; if zero, then there is no more items in the menu item table */
- char *name; /* Item name, should be eight characters with current implementation */
- char *desc; /* Item description to be printed when item is selected */
-};
-
-/*
- * Actual function which prints the button bar and highlights the active button
- * Should not be called directly. Call function menuSelect instead.
- */
-
-static int
-menuUpdate( int y, int x, struct MenuItem *menuItems, int itemLength,
- char *available, int menuType, int current ) {
- int i, lmargin = x;
- char *mcd;
-
- /* Print available buttons */
- move( y, x ); clrtoeol();
-
- for( i = 0; menuItems[i].key; i++ ) {
- char buff[20];
- int lenName;
- const char *mi;
-
- /* Search next available button */
- while( menuItems[i].key && !strchr(available, menuItems[i].key) )
- i++;
-
- if( !menuItems[i].key ) break; /* No more menu items */
-
- /* If selected item is not available and we have bypassed it,
- make current item selected */
- if( current < i && menuItems[current].key < 0 ) current = i;
-
- /* If current item is selected, highlight it */
- if( current == i ) /*attron( A_REVERSE )*/ standout ();
-
- /* Print item */
- /* Because of a bug in gettext() we must not translate empty strings */
- if (menuItems[i].name[0])
- mi = _(menuItems[i].name);
- else
- mi = "";
- lenName = strlen( mi );
-#if 0
- if(lenName > itemLength || lenName >= sizeof(buff))
- print_warning(_("Menu item too long. Menu may look odd."));
-#endif
- if ((size_t) lenName >= sizeof(buff)) { /* truncate ridiculously long string */
- xstrncpy(buff, mi, sizeof(buff));
- } else if (lenName >= itemLength) {
- snprintf(buff, sizeof(buff),
- (menuType & MENU_BUTTON) ? "[%s]" : "%s", mi);
- } else {
- snprintf(buff, sizeof(buff),
- (menuType & MENU_BUTTON) ? "[%*s%-*s]" : "%*s%-*s",
- (itemLength - lenName) / 2, "",
- (itemLength - lenName + 1) / 2 + lenName, mi);
- }
- mvaddstr( y, x, buff );
-
- /* Lowlight after selected item */
- if( current == i ) /*attroff( A_REVERSE )*/ standend ();
-
- /* Calculate position for the next item */
- x += itemLength + MENU_SPACING;
- if( menuType & MENU_BUTTON ) x += 2;
- if( x > COLUMNS - lmargin - 12 )
- {
- x = lmargin;
- y ++ ;
- }
- }
-
- /* Print the description of selected item */
- mcd = _(menuItems[current].desc);
- mvaddstr( WARNING_START + 1, (COLUMNS - strlen( mcd )) / 2, mcd );
- return y;
-}
-
-/* This function takes a list of menu items, lets the user choose one *
- * and returns the keyboard shortcut value of the selected menu item */
-
-static int
-menuSelect( int y, int x, struct MenuItem *menuItems, int itemLength,
- char *available, int menuType, int menuDefault ) {
- int i, ylast = y, key = 0, current = menuDefault;
-
- /* Make sure that the current is one of the available items */
- while( !strchr(available, menuItems[current].key) ) {
- current ++ ;
- if( !menuItems[current].key ) current = 0;
- }
-
- keypad(stdscr, TRUE);
-
- /* Repeat until allowable choice has been made */
- while( !key ) {
- /* Display the menu and read a command */
- ylast = menuUpdate( y, x, menuItems, itemLength, available,
- menuType, current );
- refresh();
- key = getch();
-
- if (key == ERR)
- if (!isatty(STDIN_FILENO))
- exit(2);
-
- /* Clear out all prompts and such */
- clear_warning();
- for (i = y; i < ylast; i++) {
- move(i, x);
- clrtoeol();
- }
- move( WARNING_START + 1, 0 );
- clrtoeol();
-
- switch (key) {
- case KEY_RIGHT:
- case '\t':
- /* Select next menu item */
- do {
- current++;
- if (!menuItems[current].key)
- current = 0;
- } while (!strchr(available, menuItems[current].key));
- key = 0;
- break;
- case KEY_LEFT:
-#ifdef KEY_BTAB
- case KEY_BTAB: /* Back tab */
-#endif
- /* Select previous menu item */
- do {
- current--;
- if (current < 0) {
- while (menuItems[current + 1].key)
- current++;
- }
- } while (!strchr(available, menuItems[current].key));
- key = 0;
- break;
- case KEY_ENTER:
- case '\n':
- case '\r':
- /* Enter equals the keyboard shortcut of current menu item */
- key = menuItems[current].key;
- break;
- }
-
- /* Should all keys to be accepted? */
- if( key && (menuType & MENU_ACCEPT_OTHERS) ) break;
-
- /* Is pressed key among acceptable ones? */
- if( key && (strchr(available, tolower(key)) || strchr(available, key)))
- break;
-
- /* The key has not been accepted so far -> let's reject it */
- if (key) {
- key = 0;
- putchar( BELL );
- print_warning(_("Illegal key"));
- }
- }
-
- keypad(stdscr, FALSE);
-
- /* Clear out prompts and such */
- clear_warning();
- for( i = y; i <= ylast; i ++ ) {
- move( i, x );
- clrtoeol();
- }
- move( WARNING_START + 1, 0 );
- clrtoeol();
- return key;
-}
-
-/* A function which displays "Press a key to continue" *
- * and waits for a keypress. *
- * Perhaps calling function menuSelect is a bit overkill but who cares? */
-
-static void
-menuContinue(void) {
- static struct MenuItem menuContinueBtn[]=
- {
- { 'c', "", N_("Press a key to continue") },
- { 0, NULL, NULL }
- };
-
- menuSelect(COMMAND_LINE_Y, COMMAND_LINE_X,
- menuContinueBtn, 0, "c", MENU_ACCEPT_OTHERS, 0 );
-}
-
-/* Function menuSelect takes way too many parameters *
- * Luckily, most of time we can do with this function */
-
-static int
-menuSimple(struct MenuItem *menuItems, int menuDefault) {
- int i, j, itemLength = 0;
- char available[MENU_MAX_ITEMS];
-
- for(i = 0; menuItems[i].key; i++)
- {
- j = strlen( _(menuItems[i].name) );
- if( j > itemLength ) itemLength = j;
- available[i] = menuItems[i].key;
- }
- available[i] = 0;
- return menuSelect(COMMAND_LINE_Y, COMMAND_LINE_X, menuItems, itemLength,
- available, MENU_BUTTON, menuDefault);
-}
-
-/* End of command menu support code */
-
-static void
-new_part(int i) {
- char response[LINE_LENGTH], def[LINE_LENGTH];
- char c;
- long long first = p_info[i].first_sector;
- long long last = p_info[i].last_sector;
- long long offset = 0;
- int flags = 0;
- int id = LINUX;
- int num = -1;
- long long num_sects = last - first + 1;
- int len, ext, j;
- char *errmsg;
- double sectors_per_MB = K*K / 512.0;
-
- if (p_info[i].num == PRI_OR_LOG) {
- static struct MenuItem menuPartType[]=
- {
- { 'p', N_("Primary"), N_("Create a new primary partition") },
- { 'l', N_("Logical"), N_("Create a new logical partition") },
- { ESC, N_("Cancel"), N_("Don't create a partition") },
- { 0, NULL, NULL }
- };
-
- c = menuSimple( menuPartType, 0 );
- if (toupper(c) == 'P')
- num = find_primary();
- else if (toupper(c) == 'L')
- num = find_logical(i);
- else
- return;
- } else if (p_info[i].num == PRIMARY)
- num = find_primary();
- else if (p_info[i].num == LOGICAL)
- num = find_logical(i);
- else
- print_warning(_("!!! Internal error !!!"));
-
- snprintf(def, sizeof(def), "%.2f", num_sects/sectors_per_MB);
- mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, _("Size (in MB): "));
- if ((len = get_string(response, LINE_LENGTH, def)) <= 0 &&
- len != GS_DEFAULT)
- return;
- else if (len > 0) {
-#define num_cyls(bytes) (round_int(bytes/SECTOR_SIZE/cylinder_size))
- for (j = 0;
- j < len-1 && (isdigit(response[j]) || response[j] == '.');
- j++);
- if (toupper(response[j]) == 'K') {
- num_sects = num_cyls(atof(response)*K)*cylinder_size;
- } else if (toupper(response[j]) == 'M') {
- num_sects = num_cyls(atof(response)*K*K)*cylinder_size;
- } else if (toupper(response[j]) == 'G') {
- num_sects = num_cyls(atof(response)*K*K*K)*cylinder_size;
- } else if (toupper(response[j]) == 'C') {
- num_sects = round_int(atof(response))*cylinder_size;
- } else if (toupper(response[j]) == 'S') {
- num_sects = round_int(atof(response));
- } else {
- num_sects = num_cyls(atof(response)*K*K)*cylinder_size;
- }
- }
-
- if (num_sects <= 0 ||
- num_sects > p_info[i].last_sector - p_info[i].first_sector + 1)
- return;
-
- move( COMMAND_LINE_Y, COMMAND_LINE_X ); clrtoeol();
- if (num_sects < p_info[i].last_sector - p_info[i].first_sector + 1) {
- /* Determine where inside free space to put partition.
- */
- static struct MenuItem menuPlace[]=
- {
- { 'b', N_("Beginning"), N_("Add partition at beginning of free space") },
- { 'e', N_("End"), N_("Add partition at end of free space") },
- { ESC, N_("Cancel"), N_("Don't create a partition") },
- { 0, NULL, NULL }
- };
- c = menuSimple( menuPlace, 0 );
- if (toupper(c) == 'B')
- last = first + num_sects - 1;
- else if (toupper(c) == 'E')
- first = last - num_sects + 1;
- else
- return;
- }
-
- if (IS_LOGICAL(num) && !is_extended(ext_info.id)) {
- /* We want to add a logical partition, but need to create an
- * extended partition first.
- */
- if ((ext = find_primary()) < 0) {
- print_warning(_("No room to create the extended partition"));
- return;
- }
- errmsg = 0;
- if (add_part(ext, DOS_EXTENDED, 0, first, last,
- (first == 0 ? sectors : 0), 0, &errmsg) && errmsg)
- print_warning(errmsg);
- first = ext_info.first_sector + ext_info.offset;
- }
-
- /* increment number of all partitions past this one */
- if (IS_LOGICAL(num)) {
-#if 0
- /* original text - ok, but fails when partitions not in disk order */
- for (j = i; j < num_parts; j++)
- if (p_info[j].id > 0 && IS_LOGICAL(p_info[j].num))
- p_info[j].num++;
-#else
- /* always ok */
- for (j = 0; j < num_parts; j++)
- if (p_info[j].id > 0 && p_info[j].num >= num)
- p_info[j].num++;
-#endif
- }
-
- /* Now we have a complete partition to ourselves */
- if (first == 0 || IS_LOGICAL(num))
- offset = sectors;
-
- errmsg = 0;
- if (add_part(num, id, flags, first, last, offset, 0, &errmsg) && errmsg)
- print_warning(errmsg);
-}
-
-static void
-get_kernel_geometry(void) {
-#ifdef HDIO_GETGEO
- struct hd_geometry geometry;
-
- if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
- kern_heads = geometry.heads;
- kern_sectors = geometry.sectors;
- }
-#endif
-}
-
-static int
-said_yes(char answer) {
- char reply[2];
-
- reply[0] = answer;
- reply[1] = 0;
-
- return (rpmatch(reply) == 1) ? 1 : 0;
-}
-
-static void
-get_partition_table_geometry(partition_table *bufp) {
- struct partition *p;
- int i,h,s,hh,ss;
- int first = TRUE;
- int bad = FALSE;
-
- for (i=0; i<66; i++)
- if (bufp->c.b[446+i])
- goto nonz;
-
- /* zero table */
- if (!curses_started) {
- fatal(_("No partition table.\n"), 3);
- return;
- } else {
- mvaddstr(WARNING_START, 0,
- _("No partition table. Starting with zero table."));
- putchar(BELL);
- refresh();
- zero_table = TRUE;
- return;
- }
- nonz:
- if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 ||
- bufp->p.magicflag[1] != PART_TABLE_FLAG1) {
- if (!curses_started)
- fatal(_("Bad signature on partition table"), 3);
-
- /* Matthew Wilcox */
- mvaddstr(WARNING_START, 0,
- _("Unknown partition table type"));
- mvaddstr(WARNING_START+1, 0,
- _("Do you wish to start with a zero table [y/N] ?"));
- putchar(BELL);
- refresh();
- {
- int cont = getch();
- if (cont == EOF || !said_yes(cont))
- die_x(3);
- }
- zero_table = TRUE;
- return;
- }
-
- hh = ss = 0;
- for (i=0; i<4; i++) {
- p = &(bufp->p.part[i]);
- if (p->sys_ind != 0) {
- h = p->end_head + 1;
- s = (p->end_sector & 077);
- if (first) {
- hh = h;
- ss = s;
- first = FALSE;
- } else if (hh != h || ss != s)
- bad = TRUE;
- }
- }
-
- if (!first && !bad) {
- pt_heads = hh;
- pt_sectors = ss;
- }
-}
-
-static void
-decide_on_geometry(void) {
- heads = (user_heads ? user_heads :
- pt_heads ? pt_heads :
- kern_heads ? kern_heads : 255);
- sectors = (user_sectors ? user_sectors :
- pt_sectors ? pt_sectors :
- kern_sectors ? kern_sectors : 63);
- cylinder_size = heads*sectors;
- cylinders = actual_size/cylinder_size;
- if (user_cylinders > 0)
- cylinders = user_cylinders;
-
- if (cylinder_size * cylinders > actual_size)
- print_warning(_("You specified more cylinders than fit on disk"));
-}
-
-static void
-clear_p_info(void) {
- num_parts = 1;
- p_info[0].first_sector = 0;
- p_info[0].last_sector = actual_size - 1;
- p_info[0].offset = 0;
- p_info[0].flags = 0;
- p_info[0].id = FREE_SPACE;
- p_info[0].num = PRI_OR_LOG;
-
- ext_info.first_sector = 0;
- ext_info.last_sector = 0;
- ext_info.offset = 0;
- ext_info.flags = 0;
- ext_info.id = FREE_SPACE;
- ext_info.num = PRIMARY;
-}
-
-static void
-fill_p_info(void) {
- int pn, i;
- long long bs, bsz;
- unsigned long long llsectors;
- struct partition *p;
- partition_table buffer;
- partition_info tmp_ext;
-
- memset(&tmp_ext, 0, sizeof tmp_ext);
- tmp_ext.id = FREE_SPACE;
- tmp_ext.num = PRIMARY;
-
- if ((fd = open(disk_device, O_RDWR)) < 0) {
- if ((fd = open(disk_device, O_RDONLY)) < 0)
- fatal(_("Cannot open disk drive"), 2);
- opentype = O_RDONLY;
- print_warning(_("Opened disk read-only - you have no permission to write"));
- if (curses_started) {
- refresh();
- getch();
- clear_warning();
- }
- } else
- opentype = O_RDWR;
- opened = TRUE;
-
- if (gpt_probe_signature_fd(fd)) {
- print_warning(_("Warning!! Unsupported GPT (GUID Partition Table) detected. Use GNU Parted."));
- refresh();
- getch();
- clear_warning();
- }
-
-#ifdef BLKFLSBUF
- /* Blocks are visible in more than one way:
- e.g. as block on /dev/hda and as block on /dev/hda3
- By a bug in the Linux buffer cache, we will see the old
- contents of /dev/hda when the change was made to /dev/hda3.
- In order to avoid this, discard all blocks on /dev/hda.
- Note that partition table blocks do not live in /dev/hdaN,
- so this only plays a role if we want to show volume labels. */
- ioctl(fd, BLKFLSBUF); /* ignore errors */
- /* e.g. Permission Denied */
-#endif
-
- if (blkdev_get_sectors(fd, &llsectors) == -1)
- fatal(_("Cannot get disk size"), 3);
- actual_size = llsectors;
-
- read_sector(buffer.c.b, 0);
-
- get_kernel_geometry();
-
- if (!zero_table || use_partition_table_geometry)
- get_partition_table_geometry(& buffer);
-
- decide_on_geometry();
-
- clear_p_info();
-
- if (!zero_table) {
- char *errmsg = "";
-
- for (i = 0; i < 4; i++) {
- p = & buffer.p.part[i];
- bs = get_start_sect(p);
- bsz = get_nr_sects(p);
-
- if (p->sys_ind > 0 &&
- add_part(i, p->sys_ind, p->boot_ind,
- ((bs <= sectors) ? 0 : bs), bs + bsz - 1,
- ((bs <= sectors) ? bs : 0), 1, &errmsg)) {
- char *bad = _("Bad primary partition");
- char *msg = (char *) xmalloc(strlen(bad) + strlen(errmsg) + 30);
- sprintf(msg, "%s %d: %s", bad, i + 1, errmsg);
- fatal(msg, 4);
- }
- if (is_extended(buffer.p.part[i].sys_ind))
- tmp_ext = ext_info;
- }
-
- if (is_extended(tmp_ext.id)) {
- ext_info = tmp_ext;
- logical_sectors[logical] =
- ext_info.first_sector + ext_info.offset;
- read_sector(buffer.c.b, logical_sectors[logical++]);
- i = 4;
- do {
- for (pn = 0;
- pn < 4 && (!buffer.p.part[pn].sys_ind ||
- is_extended(buffer.p.part[pn].sys_ind));
- pn++);
-
- if (pn < 4) {
- p = & buffer.p.part[pn];
- bs = get_start_sect(p);
- bsz = get_nr_sects(p);
-
- if (add_part(i++, p->sys_ind, p->boot_ind,
- logical_sectors[logical-1],
- logical_sectors[logical-1] + bs + bsz - 1,
- bs, 1, &errmsg)) {
- char *bad = _("Bad logical partition");
- char *msg = (char *) xmalloc(strlen(bad) + strlen(errmsg) + 30);
- sprintf(msg, "%s %d: %s", bad, i, errmsg);
- fatal(msg, 4);
- }
- }
-
- for (pn = 0;
- pn < 4 && !is_extended(buffer.p.part[pn].sys_ind);
- pn++);
- if (pn < 4) {
- p = & buffer.p.part[pn];
- bs = get_start_sect(p);
- logical_sectors[logical] = ext_info.first_sector
- + ext_info.offset + bs;
- read_sector(buffer.c.b, logical_sectors[logical++]);
- }
- } while (pn < 4 && logical < MAXIMUM_PARTS-4);
- }
- }
-}
-
-static void
-fill_part_table(struct partition *p, partition_info *pi) {
- long long begin;
-
- p->boot_ind = pi->flags;
- p->sys_ind = pi->id;
- begin = pi->first_sector + pi->offset;
- if (IS_LOGICAL(pi->num))
- set_start_sect(p,pi->offset);
- else
- set_start_sect(p,begin);
- set_nr_sects(p, pi->last_sector - begin + 1);
- set_hsc_begin(p, begin);
- set_hsc_end(p, pi->last_sector);
-}
-
-static void
-fill_primary_table(partition_table *buffer) {
- int i;
-
- /* Zero out existing table */
- for (i = 0x1BE; i < SECTOR_SIZE; i++)
- buffer->c.b[i] = 0;
-
- for (i = 0; i < num_parts; i++)
- if (IS_PRIMARY(p_info[i].num))
- fill_part_table(&(buffer->p.part[p_info[i].num]), &(p_info[i]));
-
- if (is_extended(ext_info.id))
- fill_part_table(&(buffer->p.part[ext_info.num]), &ext_info);
-
- buffer->p.magicflag[0] = PART_TABLE_FLAG0;
- buffer->p.magicflag[1] = PART_TABLE_FLAG1;
-}
-
-static void
-fill_logical_table(partition_table *buffer, partition_info *pi) {
- struct partition *p;
- int i;
-
- for (i = 0; i < logical && pi->first_sector != logical_sectors[i]; i++);
- if (i == logical || buffer->p.magicflag[0] != PART_TABLE_FLAG0
- || buffer->p.magicflag[1] != PART_TABLE_FLAG1)
- for (i = 0; i < SECTOR_SIZE; i++)
- buffer->c.b[i] = 0;
-
- /* Zero out existing table */
- for (i = 0x1BE; i < SECTOR_SIZE; i++)
- buffer->c.b[i] = 0;
-
- fill_part_table(&(buffer->p.part[0]), pi);
-
- for (i = 0;
- i < num_parts && pi->num != p_info[i].num - 1;
- i++);
-
- if (i < num_parts) {
- p = &(buffer->p.part[1]);
- pi = &(p_info[i]);
-
- p->boot_ind = 0;
- p->sys_ind = DOS_EXTENDED;
- set_start_sect(p, pi->first_sector - ext_info.first_sector - ext_info.offset);
- set_nr_sects(p, pi->last_sector - pi->first_sector + 1);
- set_hsc_begin(p, pi->first_sector);
- set_hsc_end(p, pi->last_sector);
- }
-
- buffer->p.magicflag[0] = PART_TABLE_FLAG0;
- buffer->p.magicflag[1] = PART_TABLE_FLAG1;
-}
-
-static void
-write_part_table(void) {
- int i, ct, done = FALSE, len;
- partition_table buffer;
- struct stat s;
- int is_bdev;
- char response[LINE_LENGTH];
-
- if (opentype == O_RDONLY) {
- print_warning(_("Opened disk read-only - you have no permission to write"));
- refresh();
- getch();
- clear_warning();
- return;
- }
-
- is_bdev = 0;
- if(fstat(fd, &s) == 0 && S_ISBLK(s.st_mode))
- is_bdev = 1;
-
- if (is_bdev) {
- print_warning(_("Warning!! This may destroy data on your disk!"));
-
- while (!done) {
- mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
- _("Are you sure you want to write the partition table "
- "to disk? (yes or no): "));
- len = get_string(response, LINE_LENGTH, NULL);
- clear_warning();
- if (len == GS_ESCAPE)
- return;
- else if (strcasecmp(response, _("no")) == 0 ||
- strcasecmp(response, "no") == 0) {
- print_warning(_("Did not write partition table to disk"));
- return;
- } else if (strcasecmp(response, _("yes")) == 0 ||
- strcasecmp(response, "yes") == 0)
- done = TRUE;
- else
- print_warning(_("Please enter `yes' or `no'"));
- }
-
- clear_warning();
- print_warning(_("Writing partition table to disk..."));
- refresh();
- }
-
- read_sector(buffer.c.b, 0);
- fill_primary_table(&buffer);
- write_sector(buffer.c.b, 0);
-
- for (i = 0; i < num_parts; i++)
- if (IS_LOGICAL(p_info[i].num)) {
- read_sector(buffer.c.b, p_info[i].first_sector);
- fill_logical_table(&buffer, &(p_info[i]));
- write_sector(buffer.c.b, p_info[i].first_sector);
- }
-
- if (is_bdev) {
-#ifdef BLKRRPART
- sync();
- if (!ioctl(fd,BLKRRPART))
- changed = TRUE;
-#endif
- sync();
-
- clear_warning();
- if (changed)
- print_warning(_("Wrote partition table to disk"));
- else
- print_warning(_("Wrote partition table, but re-read table failed. Run partprobe(8), kpartx(8) or reboot to update table."));
- } else
- print_warning(_("Wrote partition table to disk"));
-
- /* Check: unique bootable primary partition? */
- ct = 0;
- for (i = 0; i < num_parts; i++)
- if (IS_PRIMARY(i) && p_info[i].flags == ACTIVE_FLAG)
- ct++;
- if (ct == 0)
- print_warning(_("No primary partitions are marked bootable. DOS MBR cannot boot this."));
- if (ct > 1)
- print_warning(_("More than one primary partition is marked bootable. DOS MBR cannot boot this."));
-}
-
-static void
-fp_printf(FILE *fp, char *format, ...) {
- va_list args;
- char buf[1024];
- int y, x __attribute__((unused));
-
- va_start(args, format);
- vsnprintf(buf, sizeof(buf), format, args);
- va_end(args);
-
- if (fp == NULL) {
- /* The following works best if the string to be printed has at
- most only one newline. */
- printw("%s", buf);
- getyx(stdscr, y, x);
- if (y >= COMMAND_LINE_Y-2) {
- menuContinue();
- erase();
- move(0, 0);
- }
- } else
- fprintf(fp, "%s", buf);
-}
-
-#define MAX_PER_LINE 16
-static void
-print_file_buffer(FILE *fp, unsigned char *buffer) {
- int i,l;
-
- for (i = 0, l = 0; i < SECTOR_SIZE; i++, l++) {
- if (l == 0)
- fp_printf(fp, "0x%03X:", i);
- fp_printf(fp, " %02X", buffer[i]);
- if (l == MAX_PER_LINE - 1) {
- fp_printf(fp, "\n");
- l = -1;
- }
- }
- if (l > 0)
- fp_printf(fp, "\n");
- fp_printf(fp, "\n");
-}
-
-static void
-print_raw_table(void) {
- int i, to_file;
- partition_table buffer;
- char fname[LINE_LENGTH];
- FILE *fp;
-
- if (print_only) {
- fp = stdout;
- to_file = TRUE;
- } else {
- mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
- _("Enter filename or press RETURN to display on screen: "));
-
- if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
- return;
-
- if (to_file) {
- if ((fp = fopen(fname, "w")) == NULL) {
- char errstr[LINE_LENGTH];
- snprintf(errstr, sizeof(errstr),
- _("Cannot open file '%s'"), fname);
- print_warning(errstr);
- return;
- }
- } else {
- fp = NULL;
- erase();
- move(0, 0);
- }
- }
-
- fp_printf(fp, _("Disk Drive: %s\n"), disk_device);
-
- fp_printf(fp, _("Sector 0:\n"));
- read_sector(buffer.c.b, 0);
- fill_primary_table(&buffer);
- print_file_buffer(fp, buffer.c.b);
-
- for (i = 0; i < num_parts; i++)
- if (IS_LOGICAL(p_info[i].num)) {
- fp_printf(fp, _("Sector %d:\n"), p_info[i].first_sector);
- read_sector(buffer.c.b, p_info[i].first_sector);
- fill_logical_table(&buffer, &(p_info[i]));
- print_file_buffer(fp, buffer.c.b);
- }
-
- if (to_file) {
- if (!print_only)
- fclose(fp);
- } else {
- menuContinue();
- }
-}
-
-static void
-print_p_info_entry(FILE *fp, partition_info *p) {
- long long size;
- char part_str[40];
-
- if (p->id == UNUSABLE)
- fp_printf(fp, _(" None "));
- else if (p->id == FREE_SPACE && p->num == PRI_OR_LOG)
- fp_printf(fp, _(" Pri/Log"));
- else if (p->id == FREE_SPACE && p->num == PRIMARY)
- fp_printf(fp, _(" Primary"));
- else if (p->id == FREE_SPACE && p->num == LOGICAL)
- fp_printf(fp, _(" Logical"));
- else
- fp_printf(fp, "%2d %-7.7s", p->num+1,
- IS_LOGICAL(p->num) ? _("Logical") : _("Primary"));
-
- fp_printf(fp, " ");
-
- fp_printf(fp, "%11lld%c", p->first_sector,
- ((p->first_sector/cylinder_size) !=
- ((float)p->first_sector/cylinder_size) ?
- '*' : ' '));
-
- fp_printf(fp, "%11lld%c", p->last_sector,
- (((p->last_sector+1)/cylinder_size) !=
- ((float)(p->last_sector+1)/cylinder_size) ?
- '*' : ' '));
-
- fp_printf(fp, "%6ld%c", p->offset,
- ((((p->first_sector == 0 || IS_LOGICAL(p->num)) &&
- (p->offset != sectors)) ||
- (p->first_sector != 0 && IS_PRIMARY(p->num) &&
- p->offset != 0)) ?
- '#' : ' '));
-
- size = p->last_sector - p->first_sector + 1;
- fp_printf(fp, "%11lld%c", size,
- ((size/cylinder_size) != ((float)size/cylinder_size) ?
- '*' : ' '));
-
- /* fp_printf(fp, " "); */
-
- if (p->id == UNUSABLE)
- sprintf(part_str, "%.15s", _("Unusable"));
- else if (p->id == FREE_SPACE)
- sprintf(part_str, "%.15s", _("Free Space"));
- else if (partition_type_name(p->id))
- sprintf(part_str, "%.15s (%02X)", _(partition_type_name(p->id)), p->id);
- else
- sprintf(part_str, "%.15s (%02X)", _("Unknown"), p->id);
- fp_printf(fp, "%-20.20s", part_str);
-
- fp_printf(fp, " ");
-
- if (p->flags == ACTIVE_FLAG)
- fp_printf(fp, _("Boot"), p->flags);
- else if (p->flags != 0)
- fp_printf(fp, _("(%02X)"), p->flags);
- else
- fp_printf(fp, _("None"), p->flags);
-
- fp_printf(fp, "\n");
-}
-
-static void
-print_p_info(void) {
- char fname[LINE_LENGTH];
- FILE *fp;
- int i, to_file, pext = is_extended(ext_info.id);
-
- if (print_only) {
- fp = stdout;
- to_file = TRUE;
- } else {
- mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
- _("Enter filename or press RETURN to display on screen: "));
-
- if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
- return;
-
- if (to_file) {
- if ((fp = fopen(fname, "w")) == NULL) {
- char errstr[LINE_LENGTH];
- snprintf(errstr, LINE_LENGTH, _("Cannot open file '%s'"), fname);
- print_warning(errstr);
- return;
- }
- } else {
- fp = NULL;
- erase();
- move(0, 0);
- }
- }
-
- fp_printf(fp, _("Partition Table for %s\n"), disk_device);
- fp_printf(fp, "\n");
- fp_printf(fp, _(" First Last\n"));
- fp_printf(fp, _(" # Type Sector Sector Offset Length Filesystem Type (ID) Flag\n"));
- fp_printf(fp, _("-- ------- ----------- ----------- ------ ----------- -------------------- ----\n"));
-
- for (i = 0; i < num_parts; i++) {
- if (pext && (p_info[i].first_sector >= ext_info.first_sector)) {
- print_p_info_entry(fp,&ext_info);
- pext = FALSE;
- }
- print_p_info_entry(fp, &(p_info[i]));
- }
-
- if (to_file) {
- if (!print_only)
- fclose(fp);
- } else {
- menuContinue();
- }
-}
-
-static void
-print_part_entry(FILE *fp, int num, partition_info *pi) {
- long long first = 0, start = 0, end = 0, size = 0;
- unsigned char ss, es, sh, eh;
- int sc, ec;
- int flags = 0, id = 0;
-
- ss = sh = es = eh = 0;
- sc = ec = 0;
-
- if (pi != NULL) {
- flags = pi->flags;
- id = pi->id;
-
- if (IS_LOGICAL(num))
- first = pi->offset;
- else
- first = pi->first_sector + pi->offset;
-
- start = pi->first_sector + pi->offset;
- end = pi->last_sector;
- size = end - start + 1;
-
- set_hsc0(&sh, &ss, &sc, start);
- set_hsc0(&eh, &es, &ec, end);
- }
-
- fp_printf(fp, "%2d 0x%02X %4d %4d %5d 0x%02X %4d %4d %5d %11lld %11lld\n",
- num+1, flags, sh, ss, sc, id, eh, es, ec, first, size);
-}
-
-
-static void
-print_part_table(void) {
- int i, j, to_file;
- char fname[LINE_LENGTH];
- FILE *fp;
-
- if (print_only) {
- fp = stdout;
- to_file = TRUE;
- } else {
- mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
- _("Enter filename or press RETURN to display on screen: "));
-
- if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0)
- return;
-
- if (to_file) {
- if ((fp = fopen(fname, "w")) == NULL) {
- char errstr[LINE_LENGTH];
- snprintf(errstr, LINE_LENGTH, _("Cannot open file '%s'"), fname);
- print_warning(errstr);
- return;
- }
- } else {
- fp = NULL;
- erase();
- move(0, 0);
- }
- }
-
- fp_printf(fp, _("Partition Table for %s\n"), disk_device);
- fp_printf(fp, "\n");
- /* Three-line heading. Read "Start Sector" etc vertically. */
- fp_printf(fp, _(" ---Starting---- ----Ending----- Start Number of\n"));
- fp_printf(fp, _(" # Flags Head Sect Cyl ID Head Sect Cyl Sector Sectors\n"));
- fp_printf(fp, _("-- ----- ---- ---- ----- ---- ---- ---- ----- ----------- -----------\n"));
-
- for (i = 0; i < 4; i++) {
- for (j = 0;
- j < num_parts && (p_info[j].id <= 0 || p_info[j].num != i);
- j++);
- if (j < num_parts) {
- print_part_entry(fp, i, &(p_info[j]));
- } else if (is_extended(ext_info.id) && ext_info.num == i) {
- print_part_entry(fp, i, &ext_info);
- } else {
- print_part_entry(fp, i, NULL);
- }
- }
-
- for (i = 0; i < num_parts; i++)
- if (IS_LOGICAL(p_info[i].num))
- print_part_entry(fp, p_info[i].num, &(p_info[i]));
-
- if (to_file) {
- if (!print_only)
- fclose(fp);
- } else {
- menuContinue();
- }
-}
-
-static void
-print_tables(void) {
- int done = FALSE;
-
- static struct MenuItem menuFormat[]=
- {
- { 'r', N_("Raw"), N_("Print the table using raw data format") },
- { 's', N_("Sectors"), N_("Print the table ordered by sectors") },
- { 't', N_("Table"), N_("Just print the partition table") },
- { ESC, N_("Cancel"), N_("Don't print the table") },
- { 0, NULL, NULL }
- };
-
- while (!done)
- switch ( toupper(menuSimple( menuFormat, 2)) ) {
- case 'R':
- print_raw_table();
- done = TRUE;
- break;
- case 'S':
- print_p_info();
- done = TRUE;
- break;
- case 'T':
- print_part_table();
- done = TRUE;
- break;
- case ESC:
- done = TRUE;
- break;
- }
-}
-
-#define END_OF_HELP "EOHS!"
-static void
-display_help(void) {
- char *help_text[] = {
- N_("Help Screen for cfdisk"),
- "",
- N_("This is cfdisk, a curses based disk partitioning program, which"),
- N_("allows you to create, delete and modify partitions on your hard"),
- N_("disk drive."),
- "",
- N_("Copyright (C) 1994-1999 Kevin E. Martin & aeb"),
- "",
- N_("Command Meaning"),
- N_("------- -------"),
- N_(" b Toggle bootable flag of the current partition"),
- N_(" d Delete the current partition"),
- N_(" g Change cylinders, heads, sectors-per-track parameters"),
- N_(" WARNING: This option should only be used by people who"),
- N_(" know what they are doing."),
- N_(" h Print this screen"),
- N_(" m Maximize disk usage of the current partition"),
- N_(" Note: This may make the partition incompatible with"),
- N_(" DOS, OS/2, ..."),
- N_(" n Create new partition from free space"),
- N_(" p Print partition table to the screen or to a file"),
- N_(" There are several different formats for the partition"),
- N_(" that you can choose from:"),
- N_(" r - Raw data (exactly what would be written to disk)"),
- N_(" s - Table ordered by sectors"),
- N_(" t - Table in raw format"),
- N_(" q Quit program without writing partition table"),
- N_(" t Change the filesystem type"),
- N_(" u Change units of the partition size display"),
- N_(" Rotates through MB, sectors and cylinders"),
- N_(" W Write partition table to disk (must enter upper case W)"),
- N_(" Since this might destroy data on the disk, you must"),
- N_(" either confirm or deny the write by entering `yes' or"),
- N_(" `no'"),
- N_("Up Arrow Move cursor to the previous partition"),
- N_("Down Arrow Move cursor to the next partition"),
- N_("CTRL-L Redraws the screen"),
- N_(" ? Print this screen"),
- "",
- N_("Note: All of the commands can be entered with either upper or lower"),
- N_("case letters (except for Writes)."),
- END_OF_HELP
- };
-
- int cur_line = 0;
- FILE *fp = NULL;
-
- erase();
- move(0, 0);
- while (strcmp(help_text[cur_line], END_OF_HELP)) {
- if (help_text[cur_line][0])
- fp_printf(fp, "%s\n", _(help_text[cur_line]));
- else
- fp_printf(fp, "\n");
- cur_line++;
- }
- menuContinue();
-}
-
-static int
-change_geometry(void) {
- int ret_val = FALSE;
- int done = FALSE;
- char def[LINE_LENGTH];
- char response[LINE_LENGTH];
- long long tmp_val;
- int i;
-
- while (!done) {
- static struct MenuItem menuGeometry[]=
- {
- { 'c', N_("Cylinders"), N_("Change cylinder geometry") },
- { 'h', N_("Heads"), N_("Change head geometry") },
- { 's', N_("Sectors"), N_("Change sector geometry") },
- { 'd', N_("Done"), N_("Done with changing geometry") },
- { 0, NULL, NULL }
- };
- move(COMMAND_LINE_Y, COMMAND_LINE_X);
- clrtoeol();
- refresh();
-
- clear_warning();
-
- switch (toupper( menuSimple(menuGeometry, 3) )) {
- case 'C':
- sprintf(def, "%llu", actual_size/cylinder_size);
- mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
- _("Enter the number of cylinders: "));
- i = get_string(response, LINE_LENGTH, def);
- if (i == GS_DEFAULT) {
- user_cylinders = actual_size/cylinder_size;
- ret_val = TRUE;
- } else if (i > 0) {
- tmp_val = atoll(response);
- if (tmp_val > 0) {
- user_cylinders = tmp_val;
- ret_val = TRUE;
- } else
- print_warning(_("Illegal cylinders value"));
- }
- break;
- case 'H':
- sprintf(def, "%d", heads);
- mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
- _("Enter the number of heads: "));
- if (get_string(response, LINE_LENGTH, def) > 0) {
- tmp_val = atoll(response);
- if (tmp_val > 0 && tmp_val <= MAX_HEADS) {
- user_heads = tmp_val;
- ret_val = TRUE;
- } else
- print_warning(_("Illegal heads value"));
- }
- break;
- case 'S':
- sprintf(def, "%d", sectors);
- mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X,
- _("Enter the number of sectors per track: "));
- if (get_string(response, LINE_LENGTH, def) > 0) {
- tmp_val = atoll(response);
- if (tmp_val > 0 && tmp_val <= MAX_SECTORS) {
- user_sectors = tmp_val;
- ret_val = TRUE;
- } else
- print_warning(_("Illegal sectors value"));
- }
- break;
- case ESC:
- case 'D':
- done = TRUE;
- break;
- default:
- putchar(BELL);
- break;
- }
-
- if (ret_val) {
- decide_on_geometry();
- draw_screen();
- }
- }
-
- if (ret_val) {
- long long disk_end;
-
- disk_end = actual_size-1;
-
- if (p_info[num_parts-1].last_sector > disk_end) {
- while (p_info[num_parts-1].first_sector > disk_end) {
- if (p_info[num_parts-1].id == FREE_SPACE ||
- p_info[num_parts-1].id == UNUSABLE)
- remove_part(num_parts-1);
- else
- del_part(num_parts-1);
- }
-
- p_info[num_parts-1].last_sector = disk_end;
-
- if (ext_info.last_sector > disk_end)
- ext_info.last_sector = disk_end;
- } else if (p_info[num_parts-1].last_sector < disk_end) {
- if (p_info[num_parts-1].id == FREE_SPACE ||
- p_info[num_parts-1].id == UNUSABLE) {
- p_info[num_parts-1].last_sector = disk_end;
- } else {
- insert_empty_part(num_parts,
- p_info[num_parts-1].last_sector+1,
- disk_end);
- }
- }
-
- /* Make sure the partitions are correct */
- check_part_info();
- }
-
- return ret_val;
-}
-
-static void
-change_id(int i) {
- char id[LINE_LENGTH], def[LINE_LENGTH];
- int num_types = 0;
- int num_across, num_down;
- int len, new_id = ((p_info[i].id == LINUX) ? LINUX_SWAP : LINUX);
- int y_start, y_end, row, row_min, row_max, row_offset, j, needmore;
-
- for (j = 1; i386_sys_types[j].name; j++) ;
- num_types = j-1; /* do not count the Empty type */
-
- num_across = COLS/COL_ID_WIDTH;
- num_down = (((float)num_types)/num_across + 1);
- y_start = COMMAND_LINE_Y - 1 - num_down;
- if (y_start < 1) {
- y_start = 1;
- y_end = COMMAND_LINE_Y - 2;
- } else {
- if (y_start > DISK_TABLE_START+cur_part+4)
- y_start = DISK_TABLE_START+cur_part+4;
- y_end = y_start + num_down - 1;
- }
-
- row_min = 1;
- row_max = COMMAND_LINE_Y - 2;
- row_offset = 0;
- do {
- for (j = y_start - 1; j <= y_end + 1; j++) {
- move(j, 0);
- clrtoeol();
- }
- needmore = 0;
- for (j = 1; i386_sys_types[j].name; j++) {
- row = y_start + (j-1) % num_down - row_offset;
- if (row >= row_min && row <= row_max) {
- move(row, ((j-1)/num_down)*COL_ID_WIDTH + 1);
- printw("%02X %-20.20s",
- i386_sys_types[j].type,
- _(i386_sys_types[j].name));
- }
- if (row > row_max)
- needmore = 1;
- }
- if (needmore)
- menuContinue();
- row_offset += (row_max - row_min + 1);
- } while(needmore);
-
- sprintf(def, "%02X", new_id);
- mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, _("Enter filesystem type: "));
- if ((len = get_string(id, 3, def)) <= 0 && len != GS_DEFAULT)
- return;
-
- if (len != GS_DEFAULT) {
- if (!isxdigit(id[0]))
- return;
- new_id = (isdigit(id[0]) ? id[0] - '0' : tolower(id[0]) - 'a' + 10);
- if (len == 2) {
- if (isxdigit(id[1]))
- new_id = new_id*16 +
- (isdigit(id[1]) ? id[1] - '0' : tolower(id[1]) - 'a' + 10);
- else
- return;
- }
- }
-
- if (new_id == 0)
- print_warning(_("Cannot change FS Type to empty"));
- else if (is_extended(new_id))
- print_warning(_("Cannot change FS Type to extended"));
- else
- p_info[i].id = new_id;
-}
-
-static void
-draw_partition(int i) {
- int j;
- int y = i + DISK_TABLE_START + 2 - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN;
- char *t;
- long long size;
- double fsize;
-
- if (!arrow_cursor) {
- move(y, 0);
- for (j = 0; j < COLS; j++)
- addch(' ');
- }
-
- if (p_info[i].id > 0) {
- char *dbn = my_basename(disk_device);
- int l = strlen(dbn);
- int digit_last = isdigit(dbn[l-1]);
-
- mvprintw(y, NAME_START,
- "%s%s%d", dbn, (digit_last ? "p" : ""),
- p_info[i].num+1);
- if (p_info[i].flags) {
- if (p_info[i].flags == ACTIVE_FLAG)
- mvaddstr(y, FLAGS_START, _("Boot"));
- else
- mvprintw(y, FLAGS_START, _("Unk(%02X)"), p_info[i].flags);
- if (p_info[i].first_sector == 0 || IS_LOGICAL(p_info[i].num)) {
- if (p_info[i].offset != sectors)
- addstr(_(", NC"));
- } else {
- if (p_info[i].offset != 0)
- addstr(_(", NC"));
- }
- } else {
- if (p_info[i].first_sector == 0 || IS_LOGICAL(p_info[i].num)) {
- if (p_info[i].offset != sectors)
- mvaddstr(y, FLAGS_START, _("NC"));
- } else {
- if (p_info[i].offset != 0)
- mvaddstr(y, FLAGS_START, _("NC"));
- }
- }
- }
- mvaddstr(y, PTYPE_START,
- (p_info[i].id == UNUSABLE ? "" :
- (IS_LOGICAL(p_info[i].num) ? _("Logical") :
- (p_info[i].num >= 0 ? _("Primary") :
- (p_info[i].num == PRI_OR_LOG ? _("Pri/Log") :
- (p_info[i].num == PRIMARY ? _("Primary") : _("Logical")))))));
-
- t = partition_type_text(i);
- if (t)
- mvaddstr(y, FSTYPE_START, t);
- else
- mvprintw(y, FSTYPE_START, _("Unknown (%02X)"), p_info[i].id);
-
- if (p_info[i].volume_label[0]) {
- int l = strlen(p_info[i].volume_label);
- int s = SIZE_START-5-l;
- mvprintw(y, (s > LABEL_START) ? LABEL_START : s,
- " [%s] ", p_info[i].volume_label);
- }
-
- size = p_info[i].last_sector - p_info[i].first_sector + 1;
- fsize = (double) size * SECTOR_SIZE;
- if (display_units == SECTORS)
- mvprintw(y, SIZE_START, "%11lld", size);
- else if (display_units == CYLINDERS)
- mvprintw(y, SIZE_START, "%11lld", size/cylinder_size);
- else if (display_units == MEGABYTES)
- mvprintw(y, SIZE_START, "%11.2f", ceiling((100*fsize)/(K*K))/100);
- else if (display_units == GIGABYTES)
- mvprintw(y, SIZE_START, "%11.2f", ceiling((100*fsize)/(K*K*K))/100);
- if (size % cylinder_size != 0 ||
- p_info[i].first_sector % cylinder_size != 0)
- mvprintw(y, COLUMNS-1, "*");
-}
-
-static void
-init_const(void) {
- if (!defined) {
- NAME_START = (((float)NAME_START)/COLUMNS)*COLS;
- FLAGS_START = (((float)FLAGS_START)/COLUMNS)*COLS;
- PTYPE_START = (((float)PTYPE_START)/COLUMNS)*COLS;
- FSTYPE_START = (((float)FSTYPE_START)/COLUMNS)*COLS;
- LABEL_START = (((float)LABEL_START)/COLUMNS)*COLS;
- SIZE_START = (((float)SIZE_START)/COLUMNS)*COLS;
- COMMAND_LINE_X = (((float)COMMAND_LINE_X)/COLUMNS)*COLS;
-
- COMMAND_LINE_Y = LINES - 4;
- WARNING_START = LINES - 2;
-
- if ((NUM_ON_SCREEN = COMMAND_LINE_Y - DISK_TABLE_START - 3) <= 0)
- NUM_ON_SCREEN = 1;
-
- COLUMNS = COLS;
- defined = TRUE;
- }
-}
-
-static void
-draw_screen(void) {
- int i;
- char *line;
-
- line = (char *) xmalloc((COLS+1)*sizeof(char));
-
- if (warning_last_time) {
- for (i = 0; i < COLS; i++) {
- move(WARNING_START, i);
- line[i] = inch();
- }
- line[COLS] = 0;
- }
-
- erase();
-
- if (warning_last_time)
- mvaddstr(WARNING_START, 0, line);
-
-
- snprintf(line, COLS+1, "cfdisk (%s)", PACKAGE_STRING);
- mvaddstr(HEADER_START, (COLS-strlen(line))/2, line);
- snprintf(line, COLS+1, _("Disk Drive: %s"), disk_device);
- mvaddstr(HEADER_START+2, (COLS-strlen(line))/2, line);
- {
- long long bytes = actual_size*(long long) SECTOR_SIZE;
- long long megabytes = bytes/(K*K);
-
- if (megabytes < 10000)
- sprintf(line, _("Size: %lld bytes, %lld MB"),
- bytes, megabytes);
- else
- sprintf(line, _("Size: %lld bytes, %lld.%lld GB"),
- bytes, megabytes/K, (10*megabytes/K)%10);
- }
- mvaddstr(HEADER_START+3, (COLS-strlen(line))/2, line);
- snprintf(line, COLS+1, _("Heads: %d Sectors per Track: %d Cylinders: %lld"),
- heads, sectors, cylinders);
- mvaddstr(HEADER_START+4, (COLS-strlen(line))/2, line);
-
- mvaddstr(DISK_TABLE_START, NAME_START, _("Name"));
- mvaddstr(DISK_TABLE_START, FLAGS_START, _("Flags"));
- mvaddstr(DISK_TABLE_START, PTYPE_START-1, _("Part Type"));
- mvaddstr(DISK_TABLE_START, FSTYPE_START, _("FS Type"));
- mvaddstr(DISK_TABLE_START, LABEL_START+1, _("[Label]"));
- if (display_units == SECTORS)
- mvaddstr(DISK_TABLE_START, SIZE_START, _(" Sectors"));
- else if (display_units == CYLINDERS)
- mvaddstr(DISK_TABLE_START, SIZE_START, _(" Cylinders"));
- else if (display_units == MEGABYTES)
- mvaddstr(DISK_TABLE_START, SIZE_START, _(" Size (MB)"));
- else if (display_units == GIGABYTES)
- mvaddstr(DISK_TABLE_START, SIZE_START, _(" Size (GB)"));
-
- move(DISK_TABLE_START+1, 1);
- for (i = 1; i < COLS-1; i++)
- addch('-');
-
- if (NUM_ON_SCREEN >= num_parts)
- for (i = 0; i < num_parts; i++)
- draw_partition(i);
- else
- for (i = (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN;
- i < NUM_ON_SCREEN + (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN &&
- i < num_parts;
- i++)
- draw_partition(i);
-
- free(line);
-}
-
-static void
-draw_cursor(int move) {
- if (move != 0 && (cur_part + move < 0 || cur_part + move >= num_parts)) {
- print_warning(_("No more partitions"));
- return;
- }
-
- if (arrow_cursor)
- mvaddstr(DISK_TABLE_START + cur_part + 2
- - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN, 0, " ");
- else
- draw_partition(cur_part);
-
- cur_part += move;
-
- if (((cur_part - move)/NUM_ON_SCREEN)*NUM_ON_SCREEN !=
- (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN)
- draw_screen();
-
- if (arrow_cursor)
- mvaddstr(DISK_TABLE_START + cur_part + 2
- - (cur_part/NUM_ON_SCREEN)*NUM_ON_SCREEN, 0, "-->");
- else {
- standout();
- draw_partition(cur_part);
- standend();
- }
-}
-
-static void
-do_curses_fdisk(void) {
- int done = FALSE;
- int command;
- int is_first_run = TRUE;
-
- static struct MenuItem menuMain[] = {
- { 'b', N_("Bootable"), N_("Toggle bootable flag of the current partition") },
- { 'd', N_("Delete"), N_("Delete the current partition") },
- { 'g', N_("Geometry"), N_("Change disk geometry (experts only)") },
- { 'h', N_("Help"), N_("Print help screen") },
- { 'm', N_("Maximize"), N_("Maximize disk usage of the current partition (experts only)") },
- { 'n', N_("New"), N_("Create new partition from free space") },
- { 'p', N_("Print"), N_("Print partition table to the screen or to a file") },
- { 'q', N_("Quit"), N_("Quit program without writing partition table") },
- { 't', N_("Type"), N_("Change the filesystem type (DOS, Linux, OS/2 and so on)") },
- { 'u', N_("Units"), N_("Change units of the partition size display (MB, sect, cyl)") },
- { 'W', N_("Write"), N_("Write partition table to disk (this might destroy data)") },
- { 0, NULL, NULL }
- };
- curses_started = 1;
- initscr();
- init_const();
-
- old_SIGINT = signal(SIGINT, die);
- old_SIGTERM = signal(SIGTERM, die);
-#ifdef DEBUG
- signal(SIGINT, old_SIGINT);
- signal(SIGTERM, old_SIGTERM);
-#endif
-
- cbreak();
- noecho();
- nonl();
-
- fill_p_info();
-
- draw_screen();
-
- while (!done) {
- char *s;
-
- draw_cursor(0);
-
- if (p_info[cur_part].id == FREE_SPACE) {
- s = ((opentype == O_RDWR) ? "hnpquW" : "hnpqu");
- command = menuSelect(COMMAND_LINE_Y, COMMAND_LINE_X, menuMain, 10,
- s, MENU_BUTTON | MENU_ACCEPT_OTHERS, 5);
- } else if (p_info[cur_part].id > 0) {
- s = ((opentype == O_RDWR) ? "bdhmpqtuW" : "bdhmpqtu");
- command = menuSelect(COMMAND_LINE_Y, COMMAND_LINE_X, menuMain, 10,
- s, MENU_BUTTON | MENU_ACCEPT_OTHERS, is_first_run ? 7 : 0);
- } else {
- s = ((opentype == O_RDWR) ? "hpquW" : "hpqu");
- command = menuSelect(COMMAND_LINE_Y, COMMAND_LINE_X, menuMain, 10,
- s, MENU_BUTTON | MENU_ACCEPT_OTHERS, 0);
- }
- is_first_run = FALSE;
- switch ( command ) {
- case 'B':
- case 'b':
- if (p_info[cur_part].id > 0)
- p_info[cur_part].flags ^= 0x80;
- else
- print_warning(_("Cannot make this partition bootable"));
- break;
- case 'D':
- case 'd':
- if (p_info[cur_part].id > 0) {
- del_part(cur_part);
- if (cur_part >= num_parts)
- cur_part = num_parts - 1;
- draw_screen();
- } else
- print_warning(_("Cannot delete an empty partition"));
- break;
- case 'G':
- case 'g':
- if (change_geometry())
- draw_screen();
- break;
- case 'M':
- case 'm':
- if (p_info[cur_part].id > 0) {
- if (p_info[cur_part].first_sector == 0 ||
- IS_LOGICAL(p_info[cur_part].num)) {
- if (p_info[cur_part].offset == sectors)
- p_info[cur_part].offset = 1;
- else
- p_info[cur_part].offset = sectors;
- draw_screen();
- } else if (p_info[cur_part].offset != 0)
- p_info[cur_part].offset = 0;
- else
- print_warning(_("Cannot maximize this partition"));
- } else
- print_warning(_("Cannot maximize this partition"));
- break;
- case 'N':
- case 'n':
- if (p_info[cur_part].id == FREE_SPACE) {
- new_part(cur_part);
- draw_screen();
- } else if (p_info[cur_part].id == UNUSABLE)
- print_warning(_("This partition is unusable"));
- else
- print_warning(_("This partition is already in use"));
- break;
- case 'P':
- case 'p':
- print_tables();
- draw_screen();
- break;
- case 'Q':
- case 'q':
- done = TRUE;
- break;
- case 'T':
- case 't':
- if (p_info[cur_part].id > 0) {
- change_id(cur_part);
- draw_screen();
- } else
- print_warning(_("Cannot change the type of an empty partition"));
- break;
- case 'U':
- case 'u':
- if (display_units == GIGABYTES)
- display_units = MEGABYTES;
- else if (display_units == MEGABYTES)
- display_units = SECTORS;
- else if (display_units == SECTORS)
- display_units = CYLINDERS;
- else if (display_units == CYLINDERS)
- display_units = MEGABYTES; /* not yet GIGA */
- draw_screen();
- break;
- case 'W':
- write_part_table();
- break;
- case 'H':
- case 'h':
- case '?':
- display_help();
- draw_screen();
- break;
- case KEY_UP: /* Up arrow key */
- case '\020': /* ^P */
- case 'k': /* Vi-like alternative */
- draw_cursor(-1);
- break;
- case KEY_DOWN: /* Down arrow key */
- case '\016': /* ^N */
- case 'j': /* Vi-like alternative */
- draw_cursor(1);
- break;
- case REDRAWKEY:
- clear();
- draw_screen();
- break;
- case KEY_HOME:
- draw_cursor(-cur_part);
- break;
- case KEY_END:
- draw_cursor(num_parts - cur_part - 1);
- break;
- default:
- print_warning(_("Illegal command"));
- putchar(BELL); /* CTRL-G */
- }
- }
-
- die_x(0);
-}
-
-static void
-copyright(void) {
- fprintf(stderr, _("Copyright (C) 1994-2002 Kevin E. Martin & aeb\n"));
-}
-
-static void
-usage(char *prog_name) {
- /* Unfortunately, xgettext does not handle multi-line strings */
- /* so, let's use explicit \n's instead */
- fprintf(stderr, _("\n"
-"Usage:\n"
-"Print version:\n"
-" %s -v\n"
-"Print partition table:\n"
-" %s -P {r|s|t} [options] device\n"
-"Interactive use:\n"
-" %s [options] device\n"
-"\n"
-"Options:\n"
-"-a: Use arrow instead of highlighting;\n"
-"-z: Start with a zero partition table, instead of reading the pt from disk;\n"
-"-c C -h H -s S: Override the kernel's idea of the number of cylinders,\n"
-" the number of heads and the number of sectors/track.\n\n"),
- prog_name, prog_name, prog_name);
-
- copyright();
-}
-
-int
-main(int argc, char **argv)
-{
- int c;
- int i, len;
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
- atexit(close_stdout);
-
- while ((c = getopt(argc, argv, "ac:gh:s:vzP:")) != -1)
- switch (c) {
- case 'a':
- arrow_cursor = TRUE;
- break;
- case 'c':
- user_cylinders = cylinders = strtos64_or_err(optarg, _("cannot parse number of cylinders"));
- if (cylinders <= 0) {
- fprintf(stderr, "%s: %s\n", argv[0], _("Illegal cylinders value"));
- exit(1);
- }
- break;
- case 'g':
- use_partition_table_geometry = TRUE;
- break;
- case 'h':
- user_heads = heads = strtol_or_err(optarg, _("cannot parse number of heads"));
- if (heads <= 0 || heads > MAX_HEADS) {
- fprintf(stderr, "%s: %s\n", argv[0], _("Illegal heads value"));
- exit(1);
- }
- break;
- case 's':
- user_sectors = sectors = strtol_or_err(optarg, _("cannot parse number of sectors"));
- if (sectors <= 0 || sectors > MAX_SECTORS) {
- fprintf(stderr, "%s: %s\n", argv[0], _("Illegal sectors value"));
- exit(1);
- }
- break;
- case 'v':
- fprintf(stderr, "cfdisk (%s)\n", PACKAGE_STRING);
- copyright();
- exit(0);
- case 'z':
- zero_table = TRUE;
- break;
- case 'P':
- len = strlen(optarg);
- for (i = 0; i < len; i++) {
- switch (optarg[i]) {
- case 'r':
- print_only |= PRINT_RAW_TABLE;
- break;
- case 's':
- print_only |= PRINT_SECTOR_TABLE;
- break;
- case 't':
- print_only |= PRINT_PARTITION_TABLE;
- break;
- default:
- usage(argv[0]);
- exit(1);
- }
- }
- break;
- default:
- usage(argv[0]);
- exit(1);
- }
-
- if (argc-optind == 1)
- disk_device = argv[optind];
- else if (argc-optind != 0) {
- usage(argv[0]);
- exit(1);
- } else if ((fd = open(DEFAULT_DEVICE, O_RDONLY)) < 0)
- disk_device = ALTERNATE_DEVICE;
- else close(fd);
-
- if (print_only) {
- fill_p_info();
- if (print_only & PRINT_RAW_TABLE)
- print_raw_table();
- if (print_only & PRINT_SECTOR_TABLE)
- print_p_info();
- if (print_only & PRINT_PARTITION_TABLE)
- print_part_table();
- } else
- do_curses_fdisk();
-
- return 0;
-}
diff --git a/fdisk/common.h b/fdisk/common.h
deleted file mode 100644
index 352b9a597..000000000
--- a/fdisk/common.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef FDISK_COMMON_H
-#define FDISK_COMMON_H
-
-/* common stuff for fdisk, cfdisk, sfdisk */
-
-struct systypes {
- unsigned char type;
- char *name;
-};
-
-extern struct systypes i386_sys_types[];
-
-extern char *partname(char *dev, int pno, int lth);
-
-#endif /* FDISK_COMMON_H */
diff --git a/fdisk/fdisk.8 b/fdisk/fdisk.8
deleted file mode 100644
index 5233f0f51..000000000
--- a/fdisk/fdisk.8
+++ /dev/null
@@ -1,283 +0,0 @@
-.\" Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
-.\" Copyright 1998 Andries E. Brouwer (aeb@cwi.nl)
-.\" Copyright 2012 Davidlohr Bueso <dave@gnu.org>
-.\" May be distributed under the GNU General Public License
-.TH FDISK 8 "June 2012" "util-linux" "System Administration"
-.SH NAME
-fdisk \- manipulate disk partition table
-.SH SYNOPSIS
-.B fdisk
-.RB [ \-uc ]
-.RB [ \-b
-.IR sectorsize ]
-.RB [ \-C
-.IR cyls ]
-.RB [ \-H
-.IR heads ]
-.RB [ \-S
-.IR sects ]
-.I device
-.sp
-.B fdisk \-l
-.RB [ \-u ]
-.RI [ device ...]
-.sp
-.B fdisk \-s
-.IR partition ...
-.sp
-.B fdisk \-v
-.sp
-.B fdisk \-h
-.SH DESCRIPTION
-.B fdisk
-(in the first form of invocation)
-is a menu-driven program for creation and manipulation of
-partition tables.
-It understands DOS-type partition tables and BSD- or SUN-type disklabels.
-
-.B fdisk
-does not understand GUID partition tables (GPTs) and it is not designed
-for large partitions. In these cases, use the more advanced GNU
-.BR parted (8).
-
-.B fdisk
-does not use DOS-compatible mode and cylinders as display units by default.
-The old deprecated DOS behavior can be enabled with
-the '-c=dos -u=cylinders' command-line options.
-
-Hard disks can be divided into one or more logical disks called
-.IR partitions .
-This division is recorded in the
-.IR "partition table" ,
-found in sector 0 of the disk.
-(In the BSD world one talks about `disk slices' and a `disklabel'.)
-
-Linux needs at least one partition, namely for its root file system.
-It can use swap files and/or swap partitions, but the latter are more
-efficient. So, usually one will want a second Linux partition
-dedicated as swap partition.
-On Intel-compatible hardware, the BIOS that boots the system
-can often only access the first 1024 cylinders of the disk.
-For this reason people with large disks often create a third partition,
-just a few MB large, typically mounted on
-.IR /boot ,
-to store the kernel image and a few auxiliary files needed at boot time,
-so as to make sure that this stuff is accessible to the BIOS.
-There may be reasons of security, ease of administration and backup,
-or testing, to use more than the minimum number of partitions.
-
-.SH DEVICES
-The
-.I device
-is usually /dev/sda, /dev/sdb or so. A device name refers to the entire disk.
-Old systems without libata (a library used inside the Linux kernel to
-support ATA host controllers and devices) make a difference between IDE and
-SCSI disks. In such cases the device name will be /dev/hd* (IDE) or /dev/sd*
-(SCSI).
-
-The
-.I partition
-is a device name followed by a partition number. For example, /dev/sda1
-is the first partition on the first hard disk in the system.
-See also Linux kernel documentation (the Documentation/devices.txt file).
-
-.SH DISK LABELS
-A BSD/SUN-type disklabel can describe 8 partitions,
-the third of which should be a `whole disk' partition.
-Do not start a partition that actually uses its first sector
-(like a swap partition) at cylinder 0, since that will
-destroy the disklabel.
-
-An IRIX/SGI-type disklabel can describe 16 partitions,
-the eleventh of which should be an entire `volume' partition,
-while the ninth should be labeled `volume header'.
-The volume header will also cover the partition table, i.e.,
-it starts at block zero and extends by default over five cylinders.
-The remaining space in the volume header may be used by header
-directory entries. No partitions may overlap with the volume header.
-Also do not change its type or make some filesystem on it, since
-you will lose the partition table. Use this type of label only when
-working with Linux on IRIX/SGI machines or IRIX/SGI disks under Linux.
-
-A DOS-type partition table can describe an unlimited number
-of partitions. In sector 0 there is room for the description
-of 4 partitions (called `primary'). One of these may be an
-extended partition; this is a box holding logical partitions,
-with descriptors found in a linked list of sectors, each
-preceding the corresponding logical partitions.
-The four primary partitions, present or not, get numbers 1-4.
-Logical partitions start numbering from 5.
-
-In a DOS-type partition table the starting offset and the size
-of each partition is stored in two ways: as an absolute number
-of sectors (given in 32 bits), and as a Cylinders/Heads/Sectors
-triple (given in 10+8+6 bits). The former is OK -- with 512-byte
-sectors this will work up to 2 TB. The latter has two
-problems. First, these C/H/S fields can be filled only
-when the number of heads and the number of sectors per track
-are known. And second, even if we know what these numbers should be,
-the 24 bits that are available do not suffice.
-DOS uses C/H/S only, Windows uses both, Linux never uses C/H/S.
-
-If possible,
-.B fdisk
-will obtain the disk geometry automatically. This is not
-necessarily the physical disk geometry (indeed, modern disks do not
-really have anything like a physical geometry, certainly not something
-that can be described in simplistic Cylinders/Heads/Sectors form),
-but it is the disk geometry that MS-DOS uses for the partition table.
-
-Usually all goes well by default, and there are no problems if
-Linux is the only system on the disk. However, if the disk has
-to be shared with other operating systems, it is often a good idea
-to let an fdisk from another operating system make at least one
-partition. When Linux boots it looks at the partition table, and
-tries to deduce what (fake) geometry is required for good
-cooperation with other systems.
-
-Whenever a partition table is printed out, a consistency check is performed
-on the partition table entries. This check verifies that the physical and
-logical start and end points are identical, and that each partition starts
-and ends on a cylinder boundary (except for the first partition).
-
-Some versions of MS-DOS create a first partition which does not begin
-on a cylinder boundary, but on sector 2 of the first cylinder.
-Partitions beginning in cylinder 1 cannot begin on a cylinder boundary, but
-this is unlikely to cause difficulty unless you have OS/2 on your machine.
-
-A sync() and an ioctl(BLKRRPART) (reread partition table from disk)
-are performed before exiting when the partition table has been updated.
-Long ago it used to be necessary to reboot after the use of fdisk.
-I do not think this is the case anymore -- indeed, rebooting too quickly
-might cause loss of not-yet-written data. Note that both the kernel
-and the disk hardware may buffer data.
-
-.SH "DOS 6.x WARNING"
-
-The DOS 6.x FORMAT command looks for some information in the first
-sector of the data area of the partition, and treats this information
-as more reliable than the information in the partition table. DOS
-FORMAT expects DOS FDISK to clear the first 512 bytes of the data area
-of a partition whenever a size change occurs. DOS FORMAT will look at
-this extra information even if the /U flag is given -- we consider
-this a bug in DOS FORMAT and DOS FDISK.
-
-The bottom line is that if you use cfdisk or fdisk to change the size of a
-DOS partition table entry, then you must also use
-.B dd
-to zero the first 512 bytes of that partition before using DOS FORMAT to
-format the partition. For example, if you were using cfdisk to make a DOS
-partition table entry for /dev/sda1, then (after exiting fdisk or cfdisk
-and rebooting Linux so that the partition table information is valid) you
-would use the command "dd if=/dev/zero of=/dev/sda1 bs=512 count=1" to zero
-the first 512 bytes of the partition.
-
-.B BE EXTREMELY CAREFUL
-if you use the
-.B dd
-command, since a small typo can make all of the data on your disk useless.
-
-For best results, you should always use an OS-specific partition table
-program. For example, you should make DOS partitions with the DOS FDISK
-program and Linux partitions with the Linux fdisk or Linux cfdisk program.
-
-.SH OPTIONS
-.TP
-.BI "\-b " sectorsize
-Specify the sector size of the disk. Valid values are 512, 1024, 2048 or 4096.
-(Recent kernels know the sector size. Use this only on old kernels or
-to override the kernel's ideas.) Since util-linux-2.17, fdisk differentiates
-between logical and physical sector size. This option changes both sector sizes to
-.IB sectorsize .
-.TP
-.BI "\-c"[=mode]
-Specify the compatibility mode, 'dos' or 'nondos'. The default is non-DOS
-mode. For backward compatibility, it is possible to use the option without
-the <mode> argument -- then the default is used. Note that the optional
-<mode> argument cannot be separated from the -c option by a space, the correct
-form is for example '-c=dos'. This option is DEPRECATED.
-.TP
-.BI "\-C " cyls
-Specify the number of cylinders of the disk.
-I have no idea why anybody would want to do so. This option is DEPRECATED.
-.TP
-.BI "\-H " heads
-Specify the number of heads of the disk. (Not the physical number,
-of course, but the number used for partition tables.)
-Reasonable values are 255 and 16. This option is DEPRECATED.
-.TP
-.BI "\-S " sects
-Specify the number of sectors per track of the disk.
-(Not the physical number, of course, but the number used for
-partition tables.)
-A reasonable value is 63. This option is DEPRECATED.
-.TP
-.BI \-h
-Print help and then exit.
-.TP
-.B \-l
-List the partition tables for the specified devices and then exit.
-If no devices are given, those mentioned in
-.I /proc/partitions
-(if that exists) are used.
-.TP
-.BI "\-s " partition...
-Print the size (in blocks) of each given partition.
-.TP
-.BI "\-u"[=unit]
-When listing partition tables, show sizes in 'sectors' or in 'cylinders'. The
-default is to show sizes in sectors. For backward compatibility, it is possible
-to use the option without the <units> argument -- then the default is used.
-Note that the optional <unit> argument cannot be separated from the -u option
-by a space, the correct form is for example '-u=cylinders'.
-.TP
-.B \-v
-Print version number of
-.B fdisk
-program and exit.
-.SH BUGS
-There are several *fdisk programs around.
-Each has its problems and strengths.
-Try them in the order
-.BR cfdisk ,
-.BR fdisk ,
-.BR sfdisk .
-(Indeed,
-.B cfdisk
-is a beautiful program that has strict requirements on
-the partition tables it accepts, and produces high quality partition
-tables. Use it if you can.
-.B fdisk
-is a buggy program that does fuzzy things - usually it happens to
-produce reasonable results. Its single advantage is that it has
-some support for BSD disk labels and other non-DOS partition tables.
-Avoid it if you can.
-.B sfdisk
-is for hackers only -- the user interface is terrible, but it is
-more correct than fdisk and more powerful than both fdisk and cfdisk.
-Moreover, it can be used noninteractively.)
-.PP
-There also is
-.BR parted
-which supports many types of different partition table formats.
-.PP
-The IRIX/SGI-type disklabel is currently not supported by the kernel.
-Moreover, IRIX/SGI header directories are not fully supported yet.
-.PP
-The option `dump partition table to file' is missing.
-.\" .SH AUTHORS
-.\" A. V. Le Blanc (LeBlanc@mcc.ac.uk)
-.\" Bernhard Fastenrath (fasten@informatik.uni-bonn.de)
-.\" Jakub Jelinek (jj@sunsite.mff.cuni.cz)
-.\" Andreas Neuper (ANeuper@GUUG.de)
-.\" and many others.
-.SH "SEE ALSO"
-.BR cfdisk (8),
-.BR sfdisk (8),
-.BR mkfs (8),
-.BR parted (8),
-.BR partprobe (8),
-.BR kpartx (8)
-.SH AVAILABILITY
-The fdisk command is part of the util-linux package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/fdisk/fdisk.c b/fdisk/fdisk.c
deleted file mode 100644
index 748badf47..000000000
--- a/fdisk/fdisk.c
+++ /dev/null
@@ -1,2116 +0,0 @@
-/* fdisk.c -- Partition table manipulator for Linux.
- *
- * Copyright (C) 1992 A. V. Le Blanc (LeBlanc@mcc.ac.uk)
- * Copyright (C) 2012 Davidlohr Bueso <dave@gnu.org>
- *
- * This program is free software. You can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation: either version 1 or
- * (at your option) any later version.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <errno.h>
-#include <getopt.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <time.h>
-#include <limits.h>
-
-#include "xalloc.h"
-#include "nls.h"
-#include "rpmatch.h"
-#include "blkdev.h"
-#include "common.h"
-#include "mbsalign.h"
-#include "fdisk.h"
-#include "wholedisk.h"
-#include "pathnames.h"
-#include "canonicalize.h"
-#include "strutils.h"
-#include "closestream.h"
-
-#include "fdisksunlabel.h"
-#include "fdisksgilabel.h"
-#include "fdiskaixlabel.h"
-#include "fdiskmaclabel.h"
-#include "fdiskdoslabel.h"
-#include "fdiskbsdlabel.h"
-
-#ifdef HAVE_LINUX_COMPILER_H
-#include <linux/compiler.h>
-#endif
-#ifdef HAVE_LINUX_BLKPG_H
-#include <linux/blkpg.h>
-#endif
-
-#include "gpt.h"
-
-int MBRbuffer_changed;
-
-#define hex_val(c) ({ \
- char _c = (c); \
- isdigit(_c) ? _c - '0' : \
- tolower(_c) + 10 - 'a'; \
- })
-
-
-#define sector(s) ((s) & 0x3f)
-#define cylinder(s, c) ((c) | (((s) & 0xc0) << 2))
-
-/* menu list description */
-
-struct menulist_descr {
- char command; /* command key */
- char *description; /* command description */
- enum labeltype label[2]; /* disklabel types associated with main and expert menu */
-};
-
-static const struct menulist_descr menulist[] = {
- {'a', N_("toggle a bootable flag"), {DOS_LABEL, 0}},
- {'a', N_("toggle a read only flag"), {SUN_LABEL, 0}},
- {'a', N_("select bootable partition"), {SGI_LABEL, 0}},
- {'a', N_("change number of alternate cylinders"), {0, SUN_LABEL}},
- {'b', N_("edit bsd disklabel"), {DOS_LABEL, 0}},
- {'b', N_("edit bootfile entry"), {SGI_LABEL, 0}},
- {'b', N_("move beginning of data in a partition"), {0, DOS_LABEL}},
- {'c', N_("toggle the dos compatibility flag"), {DOS_LABEL, 0}},
- {'c', N_("toggle the mountable flag"), {SUN_LABEL, 0}},
- {'c', N_("select sgi swap partition"), {SGI_LABEL, 0}},
- {'c', N_("change number of cylinders"), {0, DOS_LABEL | SUN_LABEL}},
- {'d', N_("delete a partition"), {DOS_LABEL | SUN_LABEL | SGI_LABEL | OSF_LABEL, 0}},
- {'d', N_("print the raw data in the partition table"), {0, ANY_LABEL}},
- {'e', N_("change number of extra sectors per cylinder"), {0, SUN_LABEL}},
- {'e', N_("list extended partitions"), {0, DOS_LABEL}},
- {'e', N_("edit drive data"), {OSF_LABEL, 0}},
- {'f', N_("fix partition order"), {0, DOS_LABEL}},
- {'g', N_("create an IRIX (SGI) partition table"), {0, ANY_LABEL}},
- {'h', N_("change number of heads"), {0, DOS_LABEL | SUN_LABEL}},
- {'i', N_("change interleave factor"), {0, SUN_LABEL}},
- {'i', N_("change the disk identifier"), {0, DOS_LABEL}},
- {'i', N_("install bootstrap"), {OSF_LABEL, 0}},
- {'l', N_("list known partition types"), {DOS_LABEL | SUN_LABEL | SGI_LABEL | OSF_LABEL, 0}},
- {'m', N_("print this menu"), {ANY_LABEL, ANY_LABEL}},
- {'n', N_("add a new partition"), {DOS_LABEL | SUN_LABEL | SGI_LABEL | OSF_LABEL, 0}},
- {'o', N_("create a new empty DOS partition table"), {~OSF_LABEL, 0}},
- {'o', N_("change rotation speed (rpm)"), {0, SUN_LABEL}},
- {'p', N_("print the partition table"), {DOS_LABEL | SUN_LABEL | SGI_LABEL | OSF_LABEL, DOS_LABEL | SUN_LABEL}},
- {'q', N_("quit without saving changes"), {ANY_LABEL, ANY_LABEL}},
- {'r', N_("return to main menu"), {OSF_LABEL, DOS_LABEL | SUN_LABEL | SGI_LABEL | OSF_LABEL}},
- {'s', N_("create a new empty Sun disklabel"), {~OSF_LABEL, 0}},
- {'s', N_("change number of sectors/track"), {0, DOS_LABEL | SUN_LABEL}},
- {'s', N_("show complete disklabel"), {OSF_LABEL, 0}},
- {'t', N_("change a partition's system id"), {DOS_LABEL | SUN_LABEL | SGI_LABEL | OSF_LABEL, 0}},
- {'u', N_("change display/entry units"), {DOS_LABEL | SUN_LABEL | SGI_LABEL | OSF_LABEL, 0}},
- {'v', N_("verify the partition table"), {DOS_LABEL | SUN_LABEL | SGI_LABEL, DOS_LABEL | SUN_LABEL | SGI_LABEL}},
- {'w', N_("write table to disk and exit"), {DOS_LABEL | SUN_LABEL | SGI_LABEL, DOS_LABEL | SUN_LABEL | SGI_LABEL}},
- {'w', N_("write disklabel to disk"), {OSF_LABEL, 0}},
- {'x', N_("extra functionality (experts only)"), {DOS_LABEL | SUN_LABEL | SGI_LABEL, 0}},
-#if !defined (__alpha__)
- {'x', N_("link BSD partition to non-BSD partition"), {OSF_LABEL, 0}},
-#endif
- {'y', N_("change number of physical cylinders"), {0, SUN_LABEL}},
-};
-
-int
-valid_part_table_flag(unsigned char *b) {
- return (b[510] == 0x55 && b[511] == 0xaa);
-}
-
-sector_t get_nr_sects(struct partition *p) {
- return read4_little_endian(p->size4);
-}
-
-char *line_ptr, /* interactive input */
- line_buffer[LINE_LENGTH];
-
-int nowarn = 0, /* no warnings for fdisk -l/-s */
- dos_compatible_flag = 0, /* disabled by default */
- dos_changed = 0,
- partitions = 4; /* maximum partition + 1 */
-
-unsigned int user_cylinders, user_heads, user_sectors;
-sector_t sector_offset = 1;
-unsigned int units_per_sector = 1, display_in_cyl_units = 0;
-unsigned long grain = DEFAULT_SECTOR_SIZE;
-enum labeltype disklabel; /* Current disklabel */
-
-static void __attribute__ ((__noreturn__)) usage(FILE *out)
-{
- fprintf(out, _("Usage:\n"
- " %1$s [options] <disk> change partition table\n"
- " %1$s [options] -l <disk> list partition table(s)\n"
- " %1$s -s <partition> give partition size(s) in blocks\n"
- "\nOptions:\n"
- " -b <size> sector size (512, 1024, 2048 or 4096)\n"
- " -c[=<mode>] compatible mode: 'dos' or 'nondos' (default)\n"
- " -h print this help text\n"
- " -u[=<unit>] display units: 'cylinders' or 'sectors' (default)\n"
- " -v print program version\n"
- " -C <number> specify the number of cylinders\n"
- " -H <number> specify the number of heads\n"
- " -S <number> specify the number of sectors per track\n"
- "\n"), program_invocation_short_name);
- exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
-}
-
-void fatal(struct fdisk_context *cxt, enum failure why)
-{
- close(cxt->dev_fd);
- switch (why) {
- case unable_to_read:
- err(EXIT_FAILURE, _("unable to read %s"), cxt->dev_path);
-
- case unable_to_seek:
- err(EXIT_FAILURE, _("unable to seek on %s"), cxt->dev_path);
-
- case unable_to_write:
- err(EXIT_FAILURE, _("unable to write %s"), cxt->dev_path);
-
- case ioctl_error:
- err(EXIT_FAILURE, _("BLKGETSIZE ioctl failed on %s"), cxt->dev_path);
-
- default:
- err(EXIT_FAILURE, _("fatal error"));
- }
-}
-
-struct partition *
-get_part_table(int i) {
- return ptes[i].part_table;
-}
-
-void
-set_all_unchanged(void) {
- int i;
-
- for (i = 0; i < MAXIMUM_PARTS; i++)
- ptes[i].changed = 0;
-}
-
-void
-set_changed(int i) {
- ptes[i].changed = 1;
-}
-
-static int
-is_garbage_table(void) {
- int i;
-
- for (i = 0; i < 4; i++) {
- struct pte *pe = &ptes[i];
- struct partition *p = pe->part_table;
-
- if (p->boot_ind != 0 && p->boot_ind != 0x80)
- return 1;
- }
- return 0;
-}
-
-void print_menu(enum menutype menu)
-{
- size_t i;
-
- puts(_("Command action"));
-
- for (i = 0; i < ARRAY_SIZE(menulist); i++)
- if (menulist[i].label[menu] & disklabel)
- printf(" %c %s\n", menulist[i].command, menulist[i].description);
-}
-
-static int
-get_sysid(struct fdisk_context *cxt, int i) {
- return (
- disklabel == SUN_LABEL ? sun_get_sysid(cxt, i) :
- disklabel == SGI_LABEL ? sgi_get_sysid(cxt, i) :
- ptes[i].part_table->sys_ind);
-}
-
-static struct systypes *
-get_sys_types(void) {
- return (
- disklabel == SUN_LABEL ? sun_sys_types :
- disklabel == SGI_LABEL ? sgi_sys_types :
- i386_sys_types);
-}
-
-char *partition_type(unsigned char type)
-{
- int i;
- struct systypes *types = get_sys_types();
-
- for (i=0; types[i].name; i++)
- if (types[i].type == type)
- return _(types[i].name);
-
- return NULL;
-}
-
-void list_types(struct systypes *sys)
-{
- unsigned int last[4], done = 0, next = 0, size;
- int i;
-
- for (i = 0; sys[i].name; i++);
- size = i;
-
- for (i = 3; i >= 0; i--)
- last[3 - i] = done += (size + i - done) / (i + 1);
- i = done = 0;
-
- do {
- #define NAME_WIDTH 15
- char name[NAME_WIDTH * MB_LEN_MAX];
- size_t width = NAME_WIDTH;
-
- printf("%c%2x ", i ? ' ' : '\n', sys[next].type);
- size_t ret = mbsalign(_(sys[next].name), name, sizeof(name),
- &width, MBS_ALIGN_LEFT, 0);
- if (ret == (size_t)-1 || ret >= sizeof(name))
- printf("%-15.15s", _(sys[next].name));
- else
- fputs(name, stdout);
-
- next = last[i++] + done;
- if (i > 3 || next >= last[i]) {
- i = 0;
- next = ++done;
- }
- } while (done < last[0]);
- putchar('\n');
-}
-
-static int
-test_c(char **m, char *mesg) {
- int val = 0;
- if (!*m)
- fprintf(stderr, _("You must set"));
- else {
- fprintf(stderr, " %s", *m);
- val = 1;
- }
- *m = mesg;
- return val;
-}
-
-static int
-lba_is_aligned(struct fdisk_context *cxt, sector_t lba)
-{
- unsigned int granularity = max(cxt->phy_sector_size, cxt->min_io_size);
- sector_t offset = (lba * cxt->sector_size) & (granularity - 1);
-
- return !((granularity + cxt->alignment_offset - offset) & (granularity - 1));
-}
-
-sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction)
-{
- sector_t res;
-
- if (lba_is_aligned(cxt, lba))
- res = lba;
- else {
- sector_t sects_in_phy = grain / cxt->sector_size;
-
- if (lba < sector_offset)
- res = sector_offset;
-
- else if (direction == ALIGN_UP)
- res = ((lba + sects_in_phy) / sects_in_phy) * sects_in_phy;
-
- else if (direction == ALIGN_DOWN)
- res = (lba / sects_in_phy) * sects_in_phy;
-
- else /* ALIGN_NEAREST */
- res = ((lba + sects_in_phy / 2) / sects_in_phy) * sects_in_phy;
-
- if (cxt->alignment_offset && !lba_is_aligned(cxt, res) &&
- res > cxt->alignment_offset / cxt->sector_size) {
- /*
- * apply alignment_offset
- *
- * On disk with alignment compensation physical blocks starts
- * at LBA < 0 (usually LBA -1). It means we have to move LBA
- * according the offset to be on the physical boundary.
- */
- /* fprintf(stderr, "LBA: %llu apply alignment_offset\n", res); */
- res -= (max(cxt->phy_sector_size, cxt->min_io_size) -
- cxt->alignment_offset) / cxt->sector_size;
-
- if (direction == ALIGN_UP && res < lba)
- res += sects_in_phy;
- }
- }
-
- /***
- fprintf(stderr, "LBA %llu (%s) --align-(%s)--> %llu (%s)\n",
- lba,
- lba_is_aligned(lba) ? "OK" : "FALSE",
- direction == ALIGN_UP ? "UP " :
- direction == ALIGN_DOWN ? "DOWN " : "NEAREST",
- res,
- lba_is_aligned(res) ? "OK" : "FALSE");
- ***/
- return res;
-}
-
-int warn_geometry(struct fdisk_context *cxt)
-{
- char *m = NULL;
- int prev = 0;
-
- if (disklabel == SGI_LABEL) /* cannot set cylinders etc anyway */
- return 0;
- if (!cxt->geom.heads)
- prev = test_c(&m, _("heads"));
- if (!cxt->geom.sectors)
- prev = test_c(&m, _("sectors"));
- if (!cxt->geom.cylinders)
- prev = test_c(&m, _("cylinders"));
- if (!m)
- return 0;
- fprintf(stderr,
- _("%s%s.\nYou can do this from the extra functions menu.\n"),
- prev ? _(" and ") : " ", m);
- return 1;
-}
-
-void update_units(struct fdisk_context *cxt)
-{
- int cyl_units = cxt->geom.heads * cxt->geom.sectors;
-
- if (display_in_cyl_units && cyl_units)
- units_per_sector = cyl_units;
- else
- units_per_sector = 1; /* in sectors */
-}
-
-void warn_limits(struct fdisk_context *cxt)
-{
- if (cxt->total_sectors > UINT_MAX && !nowarn) {
- unsigned long long bytes = cxt->total_sectors * cxt->sector_size;
- int giga = bytes / 1000000000;
- int hectogiga = (giga + 50) / 100;
-
- fprintf(stderr, _("\n"
-"WARNING: The size of this disk is %d.%d TB (%llu bytes).\n"
-"DOS partition table format can not be used on drives for volumes\n"
-"larger than (%llu bytes) for %ld-byte sectors. Use parted(1) and GUID \n"
-"partition table format (GPT).\n\n"),
- hectogiga / 10, hectogiga % 10,
- bytes,
- (sector_t ) UINT_MAX * cxt->sector_size,
- cxt->sector_size);
- }
-}
-
-void warn_alignment(struct fdisk_context *cxt)
-{
- if (nowarn)
- return;
-
- if (cxt->sector_size != cxt->phy_sector_size)
- fprintf(stderr, _("\n"
-"The device presents a logical sector size that is smaller than\n"
-"the physical sector size. Aligning to a physical sector (or optimal\n"
-"I/O) size boundary is recommended, or performance may be impacted.\n"));
-
- if (dos_compatible_flag)
- fprintf(stderr, _("\n"
-"WARNING: DOS-compatible mode is deprecated. It's strongly recommended to\n"
-" switch off the mode (with command 'c')."));
-
- if (display_in_cyl_units)
- fprintf(stderr, _("\n"
-"WARNING: cylinders as display units are deprecated. Use command 'u' to\n"
-" change units to sectors.\n"));
-
-}
-
-void
-get_partition_table_geometry(struct fdisk_context *cxt, unsigned int *ph, unsigned int *ps) {
- unsigned char *bufp = cxt->mbr;
- struct partition *p;
- int i, h, s, hh, ss;
- int first = 1;
- int bad = 0;
-
- if (!(valid_part_table_flag(bufp)))
- return;
-
- hh = ss = 0;
- for (i=0; i<4; i++) {
- p = pt_offset(bufp, i);
- if (p->sys_ind != 0) {
- h = p->end_head + 1;
- s = (p->end_sector & 077);
- if (first) {
- hh = h;
- ss = s;
- first = 0;
- } else if (hh != h || ss != s)
- bad = 1;
- }
- }
-
- if (!first && !bad) {
- *ph = hh;
- *ps = ss;
- }
-}
-
-/*
- * Sets LBA of the first partition
- */
-void
-update_sector_offset(struct fdisk_context *cxt)
-{
- grain = cxt->io_size;
-
- if (dos_compatible_flag)
- sector_offset = cxt->geom.sectors; /* usually 63 sectors */
- else {
- /*
- * Align the begin of partitions to:
- *
- * a) topology
- * a2) alignment offset
- * a1) or physical sector (minimal_io_size, aka "grain")
- *
- * b) or default to 1MiB (2048 sectrors, Windows Vista default)
- *
- * c) or for very small devices use 1 phy.sector
- */
- sector_t x = 0;
-
- if (fdisk_dev_has_topology(cxt)) {
- if (cxt->alignment_offset)
- x = cxt->alignment_offset;
- else if (cxt->io_size > 2048 * 512)
- x = cxt->io_size;
- }
- /* default to 1MiB */
- if (!x)
- x = 2048 * 512;
-
- sector_offset = x / cxt->sector_size;
-
- /* don't use huge offset on small devices */
- if (cxt->total_sectors <= sector_offset * 4)
- sector_offset = cxt->phy_sector_size / cxt->sector_size;
-
- /* use 1MiB grain always when possible */
- if (grain < 2048 * 512)
- grain = 2048 * 512;
-
- /* don't use huge grain on small devices */
- if (cxt->total_sectors <= (grain * 4 / cxt->sector_size))
- grain = cxt->phy_sector_size;
- }
-}
-
-/*
- * Read MBR. Returns:
- * -1: no 0xaa55 flag present (possibly entire disk BSD)
- * 0: found or created label
- * 1: I/O error
- */
-static int get_boot(struct fdisk_context *cxt, int try_only) {
-
- disklabel = ANY_LABEL;
- update_units(cxt);
-
- if (!check_dos_label(cxt))
- if (check_sun_label(cxt) || check_sgi_label(cxt) || check_aix_label(cxt)
- || check_mac_label(cxt))
- return 0;
-
- if (check_osf_label(cxt)) {
- /* intialize partitions for BSD as well */
- dos_init(cxt);
- if (!valid_part_table_flag(cxt->mbr)) {
- disklabel = OSF_LABEL;
- return 0;
- }
- printf(_("This disk has both DOS and BSD magic.\n"
- "Give the 'b' command to go to BSD mode.\n"));
- return 0;
- }
-
- if (disklabel == ANY_LABEL) {
- if (try_only)
- return -1;
-
- fprintf(stderr,
- _("Device does not contain a recognized partition table\n"));
-#ifdef __sparc__
- create_sunlabel(cxt);
-#else
- create_doslabel(cxt);
-#endif
- }
- return 0;
-}
-
-static int is_partition_table_changed(void)
-{
- int i;
-
- for (i = 0; i < partitions; i++)
- if (ptes[i].changed)
- return 1;
- return 0;
-}
-
-static void maybe_exit(int rc, int *asked)
-{
- char line[LINE_LENGTH];
-
- putchar('\n');
- if (asked)
- *asked = 0;
-
- if (is_partition_table_changed() || MBRbuffer_changed) {
- fprintf(stderr, _("Do you really want to quit? "));
-
- if (!fgets(line, LINE_LENGTH, stdin) || rpmatch(line) == 1)
- exit(rc);
- if (asked)
- *asked = 1;
- } else
- exit(rc);
-}
-
-/* read line; return 0 or first char */
-int
-read_line(int *asked)
-{
- line_ptr = line_buffer;
- if (!fgets(line_buffer, LINE_LENGTH, stdin)) {
- maybe_exit(1, asked);
- return 0;
- }
- if (asked)
- *asked = 0;
- while (*line_ptr && !isgraph(*line_ptr))
- line_ptr++;
- return *line_ptr;
-}
-
-char
-read_char(char *mesg)
-{
- do {
- fputs(mesg, stdout);
- fflush (stdout); /* requested by niles@scyld.com */
- } while (!read_line(NULL));
- return *line_ptr;
-}
-
-char
-read_chars(char *mesg)
-{
- int rc, asked = 0;
-
- do {
- fputs(mesg, stdout);
- fflush (stdout); /* niles@scyld.com */
- rc = read_line(&asked);
- } while (asked);
-
- if (!rc) {
- *line_ptr = '\n';
- line_ptr[1] = 0;
- }
- return *line_ptr;
-}
-
-int
-read_hex(struct systypes *sys)
-{
- int hex;
-
- while (1)
- {
- read_char(_("Hex code (type L to list codes): "));
- if (tolower(*line_ptr) == 'l')
- list_types(sys);
- else if (isxdigit (*line_ptr))
- {
- hex = 0;
- do
- hex = hex << 4 | hex_val(*line_ptr++);
- while (isxdigit(*line_ptr));
- return hex;
- }
- }
-}
-
-unsigned int
-read_int_with_suffix(struct fdisk_context *cxt,
- unsigned int low, unsigned int dflt, unsigned int high,
- unsigned int base, char *mesg, int *is_suffix_used)
-{
- unsigned int res;
- int default_ok = 1;
- int absolute = 0;
- static char *ms = NULL;
- static size_t mslen = 0;
-
- if (!ms || strlen(mesg)+100 > mslen) {
- mslen = strlen(mesg)+200;
- ms = xrealloc(ms,mslen);
- }
-
- if (dflt < low || dflt > high)
- default_ok = 0;
-
- if (default_ok)
- snprintf(ms, mslen, _("%s (%u-%u, default %u): "),
- mesg, low, high, dflt);
- else
- snprintf(ms, mslen, "%s (%u-%u): ",
- mesg, low, high);
-
- while (1) {
- int use_default = default_ok;
-
- /* ask question and read answer */
- while (read_chars(ms) != '\n' && !isdigit(*line_ptr)
- && *line_ptr != '-' && *line_ptr != '+')
- continue;
-
- if (*line_ptr == '+' || *line_ptr == '-') {
- int minus = (*line_ptr == '-');
- int suflen;
-
- absolute = 0;
- res = atoi(line_ptr + 1);
-
- while (isdigit(*++line_ptr))
- use_default = 0;
-
- while (isspace(*line_ptr))
- line_ptr++;
-
- suflen = strlen(line_ptr) - 1;
-
- while(isspace(*(line_ptr + suflen)))
- *(line_ptr + suflen--) = '\0';
-
- if ((*line_ptr == 'C' || *line_ptr == 'c') &&
- *(line_ptr + 1) == '\0') {
- /*
- * Cylinders
- */
- if (!display_in_cyl_units)
- res *= cxt->geom.heads * cxt->geom.sectors;
- } else if (*line_ptr &&
- *(line_ptr + 1) == 'B' &&
- *(line_ptr + 2) == '\0') {
- /*
- * 10^N
- */
- if (*line_ptr == 'K')
- absolute = 1000;
- else if (*line_ptr == 'M')
- absolute = 1000000;
- else if (*line_ptr == 'G')
- absolute = 1000000000;
- else
- absolute = -1;
- } else if (*line_ptr &&
- *(line_ptr + 1) == '\0') {
- /*
- * 2^N
- */
- if (*line_ptr == 'K')
- absolute = 1 << 10;
- else if (*line_ptr == 'M')
- absolute = 1 << 20;
- else if (*line_ptr == 'G')
- absolute = 1 << 30;
- else
- absolute = -1;
- } else if (*line_ptr != '\0')
- absolute = -1;
-
- if (absolute == -1) {
- printf(_("Unsupported suffix: '%s'.\n"), line_ptr);
- printf(_("Supported: 10^N: KB (KiloByte), MB (MegaByte), GB (GigaByte)\n"
- " 2^N: K (KibiByte), M (MebiByte), G (GibiByte)\n"));
- continue;
- }
-
- if (absolute && res) {
- unsigned long long bytes;
- unsigned long unit;
-
- bytes = (unsigned long long) res * absolute;
- unit = cxt->sector_size * units_per_sector;
- bytes += unit/2; /* round */
- bytes /= unit;
- res = bytes;
- }
- if (minus)
- res = -res;
- res += base;
- } else {
- res = atoi(line_ptr);
- while (isdigit(*line_ptr)) {
- line_ptr++;
- use_default = 0;
- }
- }
- if (use_default) {
- printf(_("Using default value %u\n"), dflt);
- return dflt;
- }
- if (res >= low && res <= high)
- break;
- else
- printf(_("Value out of range.\n"));
- }
- if (is_suffix_used)
- *is_suffix_used = absolute > 0;
- return res;
-}
-
-/*
- * Print the message MESG, then read an integer in LOW..HIGH.
- * If the user hits Enter, DFLT is returned, provided that is in LOW..HIGH.
- * Answers like +10 are interpreted as offsets from BASE.
- *
- * There is no default if DFLT is not between LOW and HIGH.
- */
-unsigned int
-read_int(struct fdisk_context *cxt,
- unsigned int low, unsigned int dflt, unsigned int high,
- unsigned int base, char *mesg)
-{
- return read_int_with_suffix(cxt, low, dflt, high, base, mesg, NULL);
-}
-
-int
-get_partition_dflt(struct fdisk_context *cxt, int warn, int max, int dflt) {
- struct pte *pe;
- int i;
-
- i = read_int(cxt, 1, dflt, max, 0, _("Partition number")) - 1;
- pe = &ptes[i];
-
- if (warn) {
- if ((disklabel != SUN_LABEL && disklabel != SGI_LABEL && !pe->part_table->sys_ind)
- || (disklabel == SUN_LABEL &&
- (!sunlabel->partitions[i].num_sectors ||
- !sunlabel->part_tags[i].tag))
- || (disklabel == SGI_LABEL && (!sgi_get_num_sectors(cxt, i)))
- )
- fprintf(stderr,
- _("Warning: partition %d has empty type\n"),
- i+1);
- }
- return i;
-}
-
-int
-get_partition(struct fdisk_context *cxt, int warn, int max) {
- return get_partition_dflt(cxt, warn, max, 0);
-}
-
-/* User partition selection unless one partition only is available */
-
-static int
-get_existing_partition(struct fdisk_context *cxt, int warn, int max) {
- int pno = -1;
- int i;
-
- if (disklabel != DOS_LABEL)
- goto not_implemented;
-
- for (i = 0; i < max; i++) {
- struct pte *pe = &ptes[i];
- struct partition *p = pe->part_table;
-
- if (p && !is_cleared_partition(p)) {
- if (pno >= 0)
- goto not_unique;
- pno = i;
- }
- }
-
- if (pno >= 0) {
- printf(_("Selected partition %d\n"), pno+1);
- return pno;
- }
- printf(_("No partition is defined yet!\n"));
- return -1;
-
-not_implemented:
-not_unique:
- return get_partition(cxt, warn, max);
-}
-
-const char *
-str_units(int n)
-{
- if (display_in_cyl_units)
- return P_("cylinder", "cylinders", n);
- return P_("sector", "sectors", n);
-}
-
-void change_units(struct fdisk_context *cxt)
-{
- display_in_cyl_units = !display_in_cyl_units;
- update_units(cxt);
-
- if (display_in_cyl_units)
- printf(_("Changing display/entry units to cylinders (DEPRECATED!)\n"));
- else
- printf(_("Changing display/entry units to sectors\n"));
-}
-
-static void
-toggle_active(int i) {
- struct pte *pe = &ptes[i];
- struct partition *p = pe->part_table;
-
- if (IS_EXTENDED (p->sys_ind) && !p->boot_ind)
- fprintf(stderr,
- _("WARNING: Partition %d is an extended partition\n"),
- i + 1);
- p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG);
- pe->changed = 1;
-}
-
-static void
-toggle_dos_compatibility_flag(struct fdisk_context *cxt) {
- dos_compatible_flag = ~dos_compatible_flag;
- if (dos_compatible_flag)
- printf(_("DOS Compatibility flag is set (DEPRECATED!)\n"));
- else
- printf(_("DOS Compatibility flag is not set\n"));
-
- update_sector_offset(cxt);
-}
-
-static void
-delete_partition(struct fdisk_context *cxt, int i)
-{
- if (i < 0)
- return;
-
- if (warn_geometry(cxt))
- return; /* C/H/S not set */
-
- ptes[i].changed = 1;
-
- if (disklabel == DOS_LABEL)
- dos_delete_partition(i);
- else if (disklabel == SUN_LABEL)
- sun_delete_partition(cxt, i);
- else if (disklabel == SGI_LABEL)
- sgi_delete_partition(cxt, i);
-
- printf(_("Partition %d is deleted\n"), i + 1);
-}
-
-static void change_sysid(struct fdisk_context *cxt)
-{
- char *temp;
- int i, sys, origsys;
- struct partition *p;
-
- i = get_existing_partition(cxt, 0, partitions);
-
- if (i == -1)
- return;
- p = ptes[i].part_table;
- origsys = sys = get_sysid(cxt, i);
-
- /* if changing types T to 0 is allowed, then
- the reverse change must be allowed, too */
- if (!sys && disklabel != SGI_LABEL && disklabel != SUN_LABEL && !get_nr_sects(p))
- printf(_("Partition %d does not exist yet!\n"), i + 1);
- else while (1) {
- sys = read_hex (get_sys_types());
-
- if (!sys && disklabel != SGI_LABEL && disklabel != SUN_LABEL) {
- printf(_("Type 0 means free space to many systems\n"
- "(but not to Linux). Having partitions of\n"
- "type 0 is probably unwise. You can delete\n"
- "a partition using the `d' command.\n"));
- /* break; */
- }
-
- if (disklabel != SGI_LABEL && disklabel != SUN_LABEL) {
- if (IS_EXTENDED (sys) != IS_EXTENDED (p->sys_ind)) {
- printf(_("You cannot change a partition into"
- " an extended one or vice versa\n"
- "Delete it first.\n"));
- break;
- }
- }
-
- if (sys < 256) {
- if (disklabel == SUN_LABEL && i == 2 && sys != SUN_TAG_BACKUP)
- printf(_("Consider leaving partition 3 "
- "as Whole disk (5),\n"
- "as SunOS/Solaris expects it and "
- "even Linux likes it.\n\n"));
- if (disklabel == SGI_LABEL && ((i == 10 && sys != ENTIRE_DISK)
- || (i == 8 && sys != 0)))
- printf(_("Consider leaving partition 9 "
- "as volume header (0),\nand "
- "partition 11 as entire volume (6), "
- "as IRIX expects it.\n\n"));
- if (sys == origsys)
- break;
- if (disklabel == SUN_LABEL) {
- ptes[i].changed = sun_change_sysid(cxt, i, sys);
- } else
- if (disklabel == SGI_LABEL) {
- ptes[i].changed = sgi_change_sysid(cxt, i, sys);
- } else {
- p->sys_ind = sys;
- ptes[i].changed = 1;
- }
- temp = partition_type(sys) ? : _("Unknown");
- if (ptes[i].changed)
- printf (_("Changed system type of partition %d "
- "to %x (%s)\n"), i + 1, sys, temp);
- else
- printf (_("System type of partition %d is unchanged: "
- "%x (%s)\n"), i + 1, sys, temp);
- if (is_dos_partition(origsys) ||
- is_dos_partition(sys))
- dos_changed = 1;
- break;
- }
- }
-}
-
-/* check_consistency() and long2chs() added Sat Mar 6 12:28:16 1993,
- * faith@cs.unc.edu, based on code fragments from pfdisk by Gordon W. Ross,
- * Jan. 1990 (version 1.2.1 by Gordon W. Ross Aug. 1990; Modified by S.
- * Lubkin Oct. 1991). */
-
-static void
-long2chs(struct fdisk_context *cxt, unsigned long ls,
- unsigned int *c, unsigned int *h, unsigned int *s) {
- int spc = cxt->geom.heads * cxt->geom.sectors;
-
- *c = ls / spc;
- ls = ls % spc;
- *h = ls / cxt->geom.sectors;
- *s = ls % cxt->geom.sectors + 1; /* sectors count from 1 */
-}
-
-static void check_consistency(struct fdisk_context *cxt, struct partition *p, int partition) {
- unsigned int pbc, pbh, pbs; /* physical beginning c, h, s */
- unsigned int pec, peh, pes; /* physical ending c, h, s */
- unsigned int lbc, lbh, lbs; /* logical beginning c, h, s */
- unsigned int lec, leh, les; /* logical ending c, h, s */
-
- if (!dos_compatible_flag)
- return;
-
- if (!cxt->geom.heads || !cxt->geom.sectors || (partition >= 4))
- return; /* do not check extended partitions */
-
-/* physical beginning c, h, s */
- pbc = (p->cyl & 0xff) | ((p->sector << 2) & 0x300);
- pbh = p->head;
- pbs = p->sector & 0x3f;
-
-/* physical ending c, h, s */
- pec = (p->end_cyl & 0xff) | ((p->end_sector << 2) & 0x300);
- peh = p->end_head;
- pes = p->end_sector & 0x3f;
-
-/* compute logical beginning (c, h, s) */
- long2chs(cxt, get_start_sect(p), &lbc, &lbh, &lbs);
-
-/* compute logical ending (c, h, s) */
- long2chs(cxt, get_start_sect(p) + get_nr_sects(p) - 1, &lec, &leh, &les);
-
-/* Same physical / logical beginning? */
- if (cxt->geom.cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) {
- printf(_("Partition %d has different physical/logical "
- "beginnings (non-Linux?):\n"), partition + 1);
- printf(_(" phys=(%d, %d, %d) "), pbc, pbh, pbs);
- printf(_("logical=(%d, %d, %d)\n"),lbc, lbh, lbs);
- }
-
-/* Same physical / logical ending? */
- if (cxt->geom.cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) {
- printf(_("Partition %d has different physical/logical "
- "endings:\n"), partition + 1);
- printf(_(" phys=(%d, %d, %d) "), pec, peh, pes);
- printf(_("logical=(%d, %d, %d)\n"),lec, leh, les);
- }
-
-/* Ending on cylinder boundary? */
- if (peh != (cxt->geom.heads - 1) || pes != cxt->geom.sectors) {
- printf(_("Partition %i does not end on cylinder boundary.\n"),
- partition + 1);
- }
-}
-
-static void
-check_alignment(struct fdisk_context *cxt, sector_t lba, int partition)
-{
- if (!lba_is_aligned(cxt, lba))
- printf(_("Partition %i does not start on physical sector boundary.\n"),
- partition + 1);
-}
-
-static void
-list_disk_geometry(struct fdisk_context *cxt) {
- unsigned long long bytes = cxt->total_sectors * cxt->sector_size;
- long megabytes = bytes/1000000;
-
- if (megabytes < 10000)
- printf(_("\nDisk %s: %ld MB, %lld bytes\n"),
- cxt->dev_path, megabytes, bytes);
- else {
- long hectomega = (megabytes + 50) / 100;
- printf(_("\nDisk %s: %ld.%ld GB, %llu bytes\n"),
- cxt->dev_path, hectomega / 10, hectomega % 10, bytes);
- }
- printf(_("%d heads, %llu sectors/track, %llu cylinders"),
- cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders);
- if (units_per_sector == 1)
- printf(_(", total %llu sectors"), cxt->total_sectors);
- printf("\n");
- printf(_("Units = %s of %d * %ld = %ld bytes\n"),
- str_units(PLURAL),
- units_per_sector, cxt->sector_size, units_per_sector * cxt->sector_size);
-
- printf(_("Sector size (logical/physical): %lu bytes / %lu bytes\n"),
- cxt->sector_size, cxt->phy_sector_size);
- printf(_("I/O size (minimum/optimal): %lu bytes / %lu bytes\n"),
- cxt->min_io_size, cxt->io_size);
- if (cxt->alignment_offset)
- printf(_("Alignment offset: %lu bytes\n"), cxt->alignment_offset);
- if (disklabel == DOS_LABEL)
- dos_print_mbr_id(cxt);
- printf("\n");
-}
-
-/*
- * Check whether partition entries are ordered by their starting positions.
- * Return 0 if OK. Return i if partition i should have been earlier.
- * Two separate checks: primary and logical partitions.
- */
-static int
-wrong_p_order(int *prev) {
- struct pte *pe;
- struct partition *p;
- unsigned int last_p_start_pos = 0, p_start_pos;
- int i, last_i = 0;
-
- for (i = 0 ; i < partitions; i++) {
- if (i == 4) {
- last_i = 4;
- last_p_start_pos = 0;
- }
- pe = &ptes[i];
- if ((p = pe->part_table)->sys_ind) {
- p_start_pos = get_partition_start(pe);
-
- if (last_p_start_pos > p_start_pos) {
- if (prev)
- *prev = last_i;
- return i;
- }
-
- last_p_start_pos = p_start_pos;
- last_i = i;
- }
- }
- return 0;
-}
-
-/*
- * Fix the chain of logicals.
- * extended_offset is unchanged, the set of sectors used is unchanged
- * The chain is sorted so that sectors increase, and so that
- * starting sectors increase.
- *
- * After this it may still be that cfdisk doesn't like the table.
- * (This is because cfdisk considers expanded parts, from link to
- * end of partition, and these may still overlap.)
- * Now
- * sfdisk /dev/hda > ohda; sfdisk /dev/hda < ohda
- * may help.
- */
-static void
-fix_chain_of_logicals(void) {
- int j, oj, ojj, sj, sjj;
- struct partition *pj,*pjj,tmp;
-
- /* Stage 1: sort sectors but leave sector of part 4 */
- /* (Its sector is the global extended_offset.) */
- stage1:
- for (j = 5; j < partitions-1; j++) {
- oj = ptes[j].offset;
- ojj = ptes[j+1].offset;
- if (oj > ojj) {
- ptes[j].offset = ojj;
- ptes[j+1].offset = oj;
- pj = ptes[j].part_table;
- set_start_sect(pj, get_start_sect(pj)+oj-ojj);
- pjj = ptes[j+1].part_table;
- set_start_sect(pjj, get_start_sect(pjj)+ojj-oj);
- set_start_sect(ptes[j-1].ext_pointer,
- ojj-extended_offset);
- set_start_sect(ptes[j].ext_pointer,
- oj-extended_offset);
- goto stage1;
- }
- }
-
- /* Stage 2: sort starting sectors */
- stage2:
- for (j = 4; j < partitions-1; j++) {
- pj = ptes[j].part_table;
- pjj = ptes[j+1].part_table;
- sj = get_start_sect(pj);
- sjj = get_start_sect(pjj);
- oj = ptes[j].offset;
- ojj = ptes[j+1].offset;
- if (oj+sj > ojj+sjj) {
- tmp = *pj;
- *pj = *pjj;
- *pjj = tmp;
- set_start_sect(pj, ojj+sjj-oj);
- set_start_sect(pjj, oj+sj-ojj);
- goto stage2;
- }
- }
-
- /* Probably something was changed */
- for (j = 4; j < partitions; j++)
- ptes[j].changed = 1;
-}
-
-static void
-fix_partition_table_order(void) {
- struct pte *pei, *pek;
- int i,k;
-
- if (!wrong_p_order(NULL)) {
- printf(_("Nothing to do. Ordering is correct already.\n\n"));
- return;
- }
-
- while ((i = wrong_p_order(&k)) != 0 && i < 4) {
- /* partition i should have come earlier, move it */
- /* We have to move data in the MBR */
- struct partition *pi, *pk, *pe, pbuf;
- pei = &ptes[i];
- pek = &ptes[k];
-
- pe = pei->ext_pointer;
- pei->ext_pointer = pek->ext_pointer;
- pek->ext_pointer = pe;
-
- pi = pei->part_table;
- pk = pek->part_table;
-
- memmove(&pbuf, pi, sizeof(struct partition));
- memmove(pi, pk, sizeof(struct partition));
- memmove(pk, &pbuf, sizeof(struct partition));
-
- pei->changed = pek->changed = 1;
- }
-
- if (i)
- fix_chain_of_logicals();
-
- printf(_("Done.\n"));
-
-}
-
-static void
-list_table(struct fdisk_context *cxt, int xtra) {
- struct partition *p;
- char *type;
- int i, w;
-
- if (disklabel == SUN_LABEL) {
- sun_list_table(cxt, xtra);
- return;
- }
-
- if (disklabel == SGI_LABEL) {
- sgi_list_table(cxt, xtra);
- return;
- }
-
- list_disk_geometry(cxt);
-
- if (disklabel == OSF_LABEL) {
- xbsd_print_disklabel(cxt, xtra);
- return;
- }
-
- if (is_garbage_table()) {
- printf(_("This doesn't look like a partition table\n"
- "Probably you selected the wrong device.\n\n"));
- }
-
- /* Heuristic: we list partition 3 of /dev/foo as /dev/foo3,
- but if the device name ends in a digit, say /dev/foo1,
- then the partition is called /dev/foo1p3. */
- w = strlen(cxt->dev_path);
- if (w && isdigit(cxt->dev_path[w-1]))
- w++;
- if (w < 5)
- w = 5;
-
- printf(_("%*s Boot Start End Blocks Id System\n"),
- w+1, _("Device"));
-
- for (i = 0; i < partitions; i++) {
- struct pte *pe = &ptes[i];
-
- p = pe->part_table;
- if (p && !is_cleared_partition(p)) {
- unsigned int psects = get_nr_sects(p);
- unsigned int pblocks = psects;
- unsigned int podd = 0;
-
- if (cxt->sector_size < 1024) {
- pblocks /= (1024 / cxt->sector_size);
- podd = psects % (1024 / cxt->sector_size);
- }
- if (cxt->sector_size > 1024)
- pblocks *= (cxt->sector_size / 1024);
- printf(
- "%s %c %11lu %11lu %11lu%c %2x %s\n",
- partname(cxt->dev_path, i+1, w+2),
-/* boot flag */ !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG
- ? '*' : '?',
-/* start */ (unsigned long) cround(get_partition_start(pe)),
-/* end */ (unsigned long) cround(get_partition_start(pe) + psects
- - (psects ? 1 : 0)),
-/* odd flag on end */ (unsigned long) pblocks, podd ? '+' : ' ',
-/* type id */ p->sys_ind,
-/* type name */ (type = partition_type(p->sys_ind)) ?
- type : _("Unknown"));
- check_consistency(cxt, p, i);
- check_alignment(cxt, get_partition_start(pe), i);
- }
- }
-
- /* Is partition table in disk order? It need not be, but... */
- /* partition table entries are not checked for correct order if this
- is a sgi, sun or aix labeled disk... */
- if (disklabel == DOS_LABEL && wrong_p_order(NULL)) {
- printf(_("\nPartition table entries are not in disk order\n"));
- }
-}
-
-static void
-x_list_table(struct fdisk_context *cxt, int extend) {
- struct pte *pe;
- struct partition *p;
- int i;
-
- printf(_("\nDisk %s: %d heads, %llu sectors, %llu cylinders\n\n"),
- cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders);
- printf(_("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"));
- for (i = 0 ; i < partitions; i++) {
- pe = &ptes[i];
- p = (extend ? pe->ext_pointer : pe->part_table);
- if (p != NULL) {
- printf("%2d %02x%4d%4d%5d%4d%4d%5d%11lu%11lu %02x\n",
- i + 1, p->boot_ind, p->head,
- sector(p->sector),
- cylinder(p->sector, p->cyl), p->end_head,
- sector(p->end_sector),
- cylinder(p->end_sector, p->end_cyl),
- (unsigned long) get_start_sect(p),
- (unsigned long) get_nr_sects(p), p->sys_ind);
- if (p->sys_ind) {
- check_consistency(cxt, p, i);
- check_alignment(cxt, get_partition_start(pe), i);
- }
- }
- }
-}
-
-void fill_bounds(sector_t *first, sector_t *last)
-{
- int i;
- struct pte *pe = &ptes[0];
- struct partition *p;
-
- for (i = 0; i < partitions; pe++,i++) {
- p = pe->part_table;
- if (!p->sys_ind || IS_EXTENDED (p->sys_ind)) {
- first[i] = 0xffffffff;
- last[i] = 0;
- } else {
- first[i] = get_partition_start(pe);
- last[i] = first[i] + get_nr_sects(p) - 1;
- }
- }
-}
-
-static void
-check(struct fdisk_context *cxt, int n, unsigned int h, unsigned int s, unsigned int c,
- unsigned int start) {
- unsigned int total, real_s, real_c;
-
- real_s = sector(s) - 1;
- real_c = cylinder(s, c);
- total = (real_c * cxt->geom.sectors + real_s) * cxt->geom.heads + h;
- if (!total)
- fprintf(stderr, _("Warning: partition %d contains sector 0\n"), n);
- if (h >= cxt->geom.heads)
- fprintf(stderr,
- _("Partition %d: head %d greater than maximum %d\n"),
- n, h + 1, cxt->geom.heads);
- if (real_s >= cxt->geom.sectors)
- fprintf(stderr, _("Partition %d: sector %d greater than "
- "maximum %llu\n"), n, s, cxt->geom.sectors);
- if (real_c >= cxt->geom.cylinders)
- fprintf(stderr, _("Partitions %d: cylinder %d greater than "
- "maximum %llu\n"), n, real_c + 1, cxt->geom.cylinders);
- if (cxt->geom.cylinders <= 1024 && start != total)
- fprintf(stderr,
- _("Partition %d: previous sectors %d disagrees with "
- "total %d\n"), n, start, total);
-}
-
-static void
-verify(struct fdisk_context *cxt) {
- int i, j;
- sector_t total = 1, n_sectors = cxt->total_sectors;
- unsigned long long first[partitions], last[partitions];
- struct partition *p;
-
- if (warn_geometry(cxt))
- return;
-
- if (disklabel == SUN_LABEL) {
- verify_sun(cxt);
- return;
- }
-
- if (disklabel == SGI_LABEL) {
- verify_sgi(cxt, 1);
- return;
- }
-
- fill_bounds(first, last);
- for (i = 0; i < partitions; i++) {
- struct pte *pe = &ptes[i];
-
- p = pe->part_table;
- if (p->sys_ind && !IS_EXTENDED (p->sys_ind)) {
- check_consistency(cxt, p, i);
- check_alignment(cxt, get_partition_start(pe), i);
- if (get_partition_start(pe) < first[i])
- printf(_("Warning: bad start-of-data in "
- "partition %d\n"), i + 1);
- check(cxt, i + 1, p->end_head, p->end_sector, p->end_cyl,
- last[i]);
- total += last[i] + 1 - first[i];
- for (j = 0; j < i; j++)
- if ((first[i] >= first[j] && first[i] <= last[j])
- || ((last[i] <= last[j] && last[i] >= first[j]))) {
- printf(_("Warning: partition %d overlaps "
- "partition %d.\n"), j + 1, i + 1);
- total += first[i] >= first[j] ?
- first[i] : first[j];
- total -= last[i] <= last[j] ?
- last[i] : last[j];
- }
- }
- }
-
- if (extended_offset) {
- struct pte *pex = &ptes[ext_index];
- sector_t e_last = get_start_sect(pex->part_table) +
- get_nr_sects(pex->part_table) - 1;
-
- for (i = 4; i < partitions; i++) {
- total++;
- p = ptes[i].part_table;
- if (!p->sys_ind) {
- if (i != 4 || i + 1 < partitions)
- printf(_("Warning: partition %d "
- "is empty\n"), i + 1);
- }
- else if (first[i] < extended_offset ||
- last[i] > e_last)
- printf(_("Logical partition %d not entirely in "
- "partition %d\n"), i + 1, ext_index + 1);
- }
- }
-
- if (total > n_sectors)
- printf(_("Total allocated sectors %llu greater than the maximum"
- " %llu\n"), total, n_sectors);
- else if (total < n_sectors)
- printf(_("Remaining %lld unallocated %ld-byte sectors\n"),
- n_sectors - total, cxt->sector_size);
-}
-
-void print_partition_size(struct fdisk_context *cxt,
- int num, sector_t start, sector_t stop, int sysid)
-{
- char *str = size_to_human_string(SIZE_SUFFIX_3LETTER | SIZE_SUFFIX_SPACE,
- (stop - start + 1) * cxt->sector_size);
- printf(_("Partition %d of type %s and of size %s is set\n"), num, partition_type(sysid), str);
- free(str);
-}
-
-static void new_partition(struct fdisk_context *cxt)
-{
- if (warn_geometry(cxt))
- return;
-
- if (disklabel == SUN_LABEL) {
- add_sun_partition(cxt, get_partition(cxt, 0, partitions), LINUX_NATIVE);
- return;
- }
-
- if (disklabel == SGI_LABEL) {
- sgi_add_partition(cxt, get_partition(cxt, 0, partitions), LINUX_NATIVE);
- return;
- }
-
- if (disklabel == AIX_LABEL) {
- printf(_("\tSorry - this fdisk cannot handle AIX disk labels."
- "\n\tIf you want to add DOS-type partitions, create"
- "\n\ta new empty DOS partition table first. (Use o.)"
- "\n\tWARNING: "
- "This will destroy the present disk contents.\n"));
- return;
- }
-
- if (disklabel == MAC_LABEL) {
- printf(_("\tSorry - this fdisk cannot handle Mac disk labels."
- "\n\tIf you want to add DOS-type partitions, create"
- "\n\ta new empty DOS partition table first. (Use o.)"
- "\n\tWARNING: "
- "This will destroy the present disk contents.\n"));
- return;
- }
-
- /* default to DOS/BSD */
- dos_new_partition(cxt);
-}
-
-static void
-write_table(struct fdisk_context *cxt) {
- int i;
-
- if (disklabel == DOS_LABEL)
- dos_write_table(cxt);
- else if (disklabel == SGI_LABEL)
- /* no test on change? the printf below might be mistaken */
- sgi_write_table(cxt);
- else if (disklabel == SUN_LABEL) {
- int needw = 0;
-
- for (i=0; i<8; i++)
- if (ptes[i].changed)
- needw = 1;
- if (needw)
- sun_write_table(cxt);
- }
-
- printf(_("The partition table has been altered!\n\n"));
- reread_partition_table(cxt, 1);
-}
-
-void
-reread_partition_table(struct fdisk_context *cxt, int leave) {
- int i;
- struct stat statbuf;
-
- i = fstat(cxt->dev_fd, &statbuf);
- if (i == 0 && S_ISBLK(statbuf.st_mode)) {
- sync();
-#ifdef BLKRRPART
- printf(_("Calling ioctl() to re-read partition table.\n"));
- i = ioctl(cxt->dev_fd, BLKRRPART);
-#else
- errno = ENOSYS;
- i = 1;
-#endif
- }
-
- if (i) {
- printf(_("\nWARNING: Re-reading the partition table failed with error %d: %m.\n"
- "The kernel still uses the old table. The new table will be used at\n"
- "the next reboot or after you run partprobe(8) or kpartx(8)\n"),
- errno);
- }
-
- if (dos_changed)
- printf(
- _("\nWARNING: If you have created or modified any DOS 6.x\n"
- "partitions, please see the fdisk manual page for additional\n"
- "information.\n"));
-
- if (leave) {
- if (fsync(cxt->dev_fd) || close(cxt->dev_fd)) {
- fprintf(stderr, _("\nError closing file\n"));
- exit(1);
- }
-
- printf(_("Syncing disks.\n"));
- sync();
- exit(!!i);
- }
-}
-
-#define MAX_PER_LINE 16
-static void
-print_buffer(struct fdisk_context *cxt, unsigned char pbuffer[]) {
- unsigned int i, l;
-
- for (i = 0, l = 0; i < cxt->sector_size; i++, l++) {
- if (l == 0)
- printf("0x%03X:", i);
- printf(" %02X", pbuffer[i]);
- if (l == MAX_PER_LINE - 1) {
- printf("\n");
- l = -1;
- }
- }
- if (l > 0)
- printf("\n");
- printf("\n");
-}
-
-static void print_raw(struct fdisk_context *cxt)
-{
- int i;
-
- printf(_("Device: %s\n"), cxt->dev_path);
- if (disklabel == SUN_LABEL || disklabel == SGI_LABEL)
- print_buffer(cxt, cxt->mbr);
- else for (i = 3; i < partitions; i++)
- print_buffer(cxt, ptes[i].sectorbuffer);
-}
-
-static void
-move_begin(struct fdisk_context *cxt, int i) {
- struct pte *pe = &ptes[i];
- struct partition *p = pe->part_table;
- unsigned int new, free_start, curr_start, last;
- int x;
-
- if (warn_geometry(cxt))
- return;
- if (!p->sys_ind || !get_nr_sects(p) || IS_EXTENDED (p->sys_ind)) {
- printf(_("Partition %d has no data area\n"), i + 1);
- return;
- }
-
- /* the default start is at the second sector of the disk or at the
- * second sector of the extended partition
- */
- free_start = pe->offset ? pe->offset + 1 : 1;
-
- curr_start = get_partition_start(pe);
-
- /* look for a free space before the current start of the partition */
- for (x = 0; x < partitions; x++) {
- unsigned int end;
- struct pte *prev_pe = &ptes[x];
- struct partition *prev_p = prev_pe->part_table;
-
- if (!prev_p)
- continue;
- end = get_partition_start(prev_pe) + get_nr_sects(prev_p);
-
- if (!is_cleared_partition(prev_p) &&
- end > free_start && end <= curr_start)
- free_start = end;
- }
-
- last = get_partition_start(pe) + get_nr_sects(p) - 1;
-
- new = read_int(cxt, free_start, curr_start, last, free_start,
- _("New beginning of data")) - pe->offset;
-
- if (new != get_nr_sects(p)) {
- unsigned int sects = get_nr_sects(p) + get_start_sect(p) - new;
- set_nr_sects(p, sects);
- set_start_sect(p, new);
- pe->changed = 1;
- }
-}
-
-static void __attribute__ ((__noreturn__)) handle_quit(struct fdisk_context *cxt)
-{
- fdisk_free_context(cxt);
- printf("\n");
- exit(EXIT_SUCCESS);
-}
-
-static void
-expert_command_prompt(struct fdisk_context *cxt)
-{
- char c;
-
- while(1) {
- putchar('\n');
- c = tolower(read_char(_("Expert command (m for help): ")));
- switch (c) {
- case 'a':
- if (disklabel == SUN_LABEL)
- sun_set_alt_cyl(cxt);
- break;
- case 'b':
- if (disklabel == DOS_LABEL)
- move_begin(cxt, get_partition(cxt, 0, partitions));
- break;
- case 'c':
- user_cylinders = cxt->geom.cylinders =
- read_int(cxt, 1, cxt->geom.cylinders, 1048576, 0,
- _("Number of cylinders"));
- if (disklabel == SUN_LABEL)
- sun_set_ncyl(cxt, cxt->geom.cylinders);
- break;
- case 'd':
- print_raw(cxt);
- break;
- case 'e':
- if (disklabel == SGI_LABEL)
- sgi_set_xcyl();
- else if (disklabel == SUN_LABEL)
- sun_set_xcyl(cxt);
- else
- if (disklabel == DOS_LABEL)
- x_list_table(cxt, 1);
- break;
- case 'f':
- if (disklabel == DOS_LABEL)
- fix_partition_table_order();
- break;
- case 'g':
- create_sgilabel(cxt);
- break;
- case 'h':
- user_heads = cxt->geom.heads = read_int(cxt, 1, cxt->geom.heads, 256, 0,
- _("Number of heads"));
- update_units(cxt);
- break;
- case 'i':
- if (disklabel == SUN_LABEL)
- sun_set_ilfact(cxt);
- else if (disklabel == DOS_LABEL)
- dos_set_mbr_id(cxt);
- break;
- case 'o':
- if (disklabel == SUN_LABEL)
- sun_set_rspeed(cxt);
- break;
- case 'p':
- if (disklabel == SUN_LABEL)
- list_table(cxt, 1);
- else
- x_list_table(cxt, 0);
- break;
- case 'q':
- handle_quit(cxt);
- case 'r':
- return;
- case 's':
- user_sectors = cxt->geom.sectors = read_int(cxt, 1, cxt->geom.sectors, 63, 0,
- _("Number of sectors"));
- if (dos_compatible_flag)
- fprintf(stderr, _("Warning: setting "
- "sector offset for DOS "
- "compatiblity\n"));
- update_sector_offset(cxt);
- update_units(cxt);
- break;
- case 'v':
- verify(cxt);
- break;
- case 'w':
- write_table(cxt);
- break;
- case 'y':
- if (disklabel == SUN_LABEL)
- sun_set_pcylcount(cxt);
- break;
- default:
- print_menu(EXPERT_MENU);
- }
- }
-}
-
-static int is_ide_cdrom_or_tape(char *device)
-{
- int fd, ret;
-
- if ((fd = open(device, O_RDONLY)) < 0)
- return 0;
- ret = blkdev_is_cdrom(fd);
-
- close(fd);
- return ret;
-}
-
-static void
-gpt_warning(char *dev)
-{
- if (dev && gpt_probe_signature_devname(dev))
- fprintf(stderr, _("\nWARNING: GPT (GUID Partition Table) detected on '%s'! "
- "The util fdisk doesn't support GPT. Use GNU Parted.\n\n"), dev);
-}
-
-/* Print disk geometry and partition table of a specified device (-l option) */
-static void print_partition_table_from_option(char *device, unsigned long sector_size)
-{
- int gb;
-
- struct fdisk_context *cxt = fdisk_new_context_from_filename(device, 1); /* read-only */
- if (!cxt)
- err(EXIT_FAILURE, _("unable to open %s"), device);
- if (sector_size) /* passed -b option, override autodiscovery */
- cxt->phy_sector_size = cxt->sector_size = sector_size;
- /* passed CHS option(s), override autodiscovery */
- if (user_cylinders)
- cxt->geom.cylinders = user_cylinders;
- if (user_heads) {
- cxt->geom.heads = user_heads;
- fdisk_geom_set_cyls(cxt);
- }
- if (user_sectors) {
- cxt->geom.sectors = user_sectors;
- fdisk_geom_set_cyls(cxt);
- }
-
- gpt_warning(device);
- gb = get_boot(cxt, 1);
- if (gb < 0) { /* no DOS signature */
- list_disk_geometry(cxt);
- if (disklabel != AIX_LABEL && disklabel != MAC_LABEL)
- btrydev(cxt);
- }
- else if (!gb)
- list_table(cxt, 0);
- fdisk_free_context(cxt);
- cxt = NULL;
-}
-
-/*
- * for fdisk -l:
- * try all things in /proc/partitions that look like a full disk
- */
-static void
-print_all_partition_table_from_option(unsigned long sector_size)
-{
- FILE *procpt;
- char line[128], ptname[128], devname[256];
- int ma, mi;
- unsigned long long sz;
-
- procpt = fopen(_PATH_PROC_PARTITIONS, "r");
- if (procpt == NULL) {
- fprintf(stderr, _("cannot open %s\n"), _PATH_PROC_PARTITIONS);
- return;
- }
-
- while (fgets(line, sizeof(line), procpt)) {
- if (sscanf (line, " %d %d %llu %128[^\n ]",
- &ma, &mi, &sz, ptname) != 4)
- continue;
- snprintf(devname, sizeof(devname), "/dev/%s", ptname);
- if (is_whole_disk(devname)) {
- char *cn = canonicalize_path(devname);
- if (cn) {
- if (!is_ide_cdrom_or_tape(cn))
- print_partition_table_from_option(cn, sector_size);
- free(cn);
- }
- }
- }
- fclose(procpt);
-}
-
-static void
-unknown_command(int c) {
- printf(_("%c: unknown command\n"), c);
-}
-
-static void print_welcome(void)
-{
- printf(_("Welcome to fdisk (%s).\n\n"
- "Changes will remain in memory only, until you decide to write them.\n"
- "Be careful before using the write command.\n\n"), PACKAGE_STRING);
-
- fflush(stdout);
-}
-
-static void command_prompt(struct fdisk_context *cxt)
-{
- int c;
-
- if (disklabel == OSF_LABEL) {
- putchar('\n');
- /* OSF label, and no DOS label */
- printf(_("Detected an OSF/1 disklabel on %s, entering "
- "disklabel mode.\n"),
- cxt->dev_path);
- bsd_command_prompt(cxt);
- /* If we return we may want to make an empty DOS label? */
- disklabel = DOS_LABEL;
- }
-
- while (1) {
- putchar('\n');
- c = tolower(read_char(_("Command (m for help): ")));
- switch (c) {
- case 'a':
- if (disklabel == DOS_LABEL)
- toggle_active(get_partition(cxt, 1, partitions));
- else if (disklabel == SUN_LABEL)
- toggle_sunflags(cxt, get_partition(cxt, 1, partitions),
- SUN_FLAG_UNMNT);
- else if (disklabel == SGI_LABEL)
- sgi_set_bootpartition(cxt,
- get_partition(cxt, 1, partitions));
- else
- unknown_command(c);
- break;
- case 'b':
- if (disklabel == SGI_LABEL)
- sgi_set_bootfile(cxt);
- else if (disklabel == DOS_LABEL) {
- disklabel = OSF_LABEL;
- bsd_command_prompt(cxt);
- disklabel = DOS_LABEL;
- } else
- unknown_command(c);
- break;
- case 'c':
- if (disklabel == DOS_LABEL)
- toggle_dos_compatibility_flag(cxt);
- else if (disklabel == SUN_LABEL)
- toggle_sunflags(cxt, get_partition(cxt, 1, partitions),
- SUN_FLAG_RONLY);
- else if (disklabel == SGI_LABEL)
- sgi_set_swappartition(cxt,
- get_partition(cxt, 1, partitions));
- else
- unknown_command(c);
- break;
- case 'd':
- delete_partition(cxt, get_existing_partition(cxt, 1, partitions));
- break;
- case 'i':
- if (disklabel == SGI_LABEL)
- create_sgiinfo(cxt);
- else
- unknown_command(c);
- break;
- case 'l':
- list_types(get_sys_types());
- break;
- case 'm':
- print_menu(MAIN_MENU);
- break;
- case 'n':
- new_partition(cxt);
- break;
- case 'o':
- create_doslabel(cxt);
- break;
- case 'p':
- list_table(cxt, 0);
- break;
- case 'q':
- handle_quit(cxt);
- case 's':
- create_sunlabel(cxt);
- break;
- case 't':
- change_sysid(cxt);
- break;
- case 'u':
- change_units(cxt);
- break;
- case 'v':
- verify(cxt);
- break;
- case 'w':
- write_table(cxt);
- break;
- case 'x':
- expert_command_prompt(cxt);
- break;
- default:
- unknown_command(c);
- print_menu(MAIN_MENU);
- }
- }
-}
-
-static sector_t get_dev_blocks(char *dev)
-{
- int fd;
- sector_t size;
-
- if ((fd = open(dev, O_RDONLY)) < 0)
- err(EXIT_FAILURE, _("unable to open %s"), dev);
- if (blkdev_get_sectors(fd, &size) == -1) {
- close(fd);
- err(EXIT_FAILURE, _("BLKGETSIZE ioctl failed on %s"), dev);
- }
- close(fd);
- return size/2;
-}
-
-int main(int argc, char **argv)
-{
- int c, optl = 0, opts = 0;
- unsigned long sector_size = 0;
- struct fdisk_context *cxt = NULL;
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
- atexit(close_stdout);
-
- while ((c = getopt(argc, argv, "b:c::C:hH:lsS:u::vV")) != -1) {
- switch (c) {
- case 'b':
- /* Ugly: this sector size is really per device,
- so cannot be combined with multiple disks,
- and te same goes for the C/H/S options.
- */
- sector_size = strtou32_or_err(optarg, _("invalid sector size argument"));
- if (sector_size != 512 && sector_size != 1024 &&
- sector_size != 2048 && sector_size != 4096)
- usage(stderr);
- sector_offset = 2;
- break;
- case 'C':
- user_cylinders = strtou32_or_err(optarg, _("invalid cylinders argument"));
- break;
- case 'c':
- dos_compatible_flag = 0; /* default */
-
- if (optarg && !strcmp(optarg, "=dos"))
- dos_compatible_flag = ~0;
- else if (optarg && strcmp(optarg, "=nondos"))
- usage(stderr);
- break;
- case 'H':
- user_heads = strtou32_or_err(optarg, _("invalid heads argument"));
- if (user_heads > 256)
- user_heads = 0;
- break;
- case 'S':
- user_sectors = strtou32_or_err(optarg, _("invalid sectors argument"));
- if (user_sectors >= 64)
- user_sectors = 0;
- break;
- case 'l':
- optl = 1;
- break;
- case 's':
- opts = 1;
- break;
- case 'u':
- display_in_cyl_units = 0; /* default */
- if (optarg && strcmp(optarg, "=cylinders") == 0)
- display_in_cyl_units = !display_in_cyl_units;
- else if (optarg && strcmp(optarg, "=sectors"))
- usage(stderr);
- break;
- case 'V':
- case 'v':
- printf(UTIL_LINUX_VERSION);
- return EXIT_SUCCESS;
- case 'h':
- usage(stdout);
- default:
- usage(stderr);
- }
- }
-
- fdisk_init_debug(0);
-
- if (sector_size && argc-optind != 1)
- printf(_("Warning: the -b (set sector size) option should"
- " be used with one specified device\n"));
-
- if (optl) {
- nowarn = 1;
- if (argc > optind) {
- int k;
- for (k = optind; k < argc; k++)
- print_partition_table_from_option(argv[k], sector_size);
- } else
- print_all_partition_table_from_option(sector_size);
- exit(EXIT_SUCCESS);
- }
-
- if (opts) {
- /* print partition size for one or more devices */
- int i, ndevs = argc - optind;
- if (ndevs <= 0)
- usage(stderr);
-
- for (i = optind; i < argc; i++) {
- if (ndevs == 1)
- printf("%llu\n", get_dev_blocks(argv[i]));
- else
- printf("%s: %llu\n", argv[i], get_dev_blocks(argv[i]));
- }
- exit(EXIT_SUCCESS);
- }
-
- if (argc-optind == 1) {
- cxt = fdisk_new_context_from_filename(argv[optind], 0);
- if (!cxt)
- err(EXIT_FAILURE, _("unable to open %s"), argv[optind]);
- if (sector_size) /* passed -b option, override autodiscovery */
- cxt->phy_sector_size = cxt->sector_size = sector_size;
- /* passed CHS option(s), override autodiscovery */
- if (user_cylinders)
- cxt->geom.cylinders = user_cylinders;
- if (user_heads) {
- cxt->geom.heads = user_heads;
- fdisk_geom_set_cyls(cxt);
- }
- if (user_sectors) {
- cxt->geom.sectors = user_sectors;
- fdisk_geom_set_cyls(cxt);
- }
- }
- else
- usage(stderr);
-
- print_welcome();
-
- if (!fdisk_dev_sectsz_is_default(cxt))
- printf(_("Note: sector size is %ld (not %d)\n"),
- cxt->sector_size, DEFAULT_SECTOR_SIZE);
-
- gpt_warning(cxt->dev_path);
- get_boot(cxt, 0);
-
- command_prompt(cxt);
-
- return 0;
-}
diff --git a/fdisk/fdisk.h b/fdisk/fdisk.h
deleted file mode 100644
index 51a63b228..000000000
--- a/fdisk/fdisk.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- fdisk.h
-*/
-
-#include "c.h"
-
-#define DEFAULT_SECTOR_SIZE 512
-#define MAX_SECTOR_SIZE 2048
-#define SECTOR_SIZE 512 /* still used in BSD code */
-#define MAXIMUM_PARTS 60
-
-#define ACTIVE_FLAG 0x80
-
-#define EXTENDED 0x05
-#define WIN98_EXTENDED 0x0f
-#define LINUX_PARTITION 0x81
-#define LINUX_SWAP 0x82
-#define LINUX_NATIVE 0x83
-#define LINUX_EXTENDED 0x85
-#define LINUX_LVM 0x8e
-#define LINUX_RAID 0xfd
-
-#define ALIGN_UP 1
-#define ALIGN_DOWN 2
-#define ALIGN_NEAREST 3
-
-#define LINE_LENGTH 800
-
-#define IS_EXTENDED(i) \
- ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
-
-#define cround(n) (display_in_cyl_units ? ((n)/units_per_sector)+1 : (n))
-#define scround(x) (((x)+units_per_sector-1)/units_per_sector)
-
-/* fdisk debugging flags/options */
-#define FDISK_DEBUG_INIT (1 << 1)
-#define FDISK_DEBUG_CONTEXT (1 << 2)
-#define FDISK_DEBUG_TOPOLOGY (1 << 3)
-#define FDISK_DEBUG_GEOMETRY (1 << 4)
-#define FDISK_DEBUG_ALL 0xFFFF
-
-# define ON_DBG(m, x) do { \
- if ((FDISK_DEBUG_ ## m) & fdisk_debug_mask) { \
- x; \
- } \
- } while (0)
-
-# define DBG(m, x) do { \
- if ((FDISK_DEBUG_ ## m) & fdisk_debug_mask) { \
- fprintf(stderr, "%d: fdisk: %8s: ", getpid(), # m); \
- x; \
- } \
- } while (0)
-
-# define DBG_FLUSH do { \
- if (fdisk_debug_mask && \
- fdisk_debug_mask != FDISK_DEBUG_INIT) \
- fflush(stderr); \
- } while(0)
-
-static inline void __attribute__ ((__format__ (__printf__, 1, 2)))
-dbgprint(const char *mesg, ...)
-{
- va_list ap;
- va_start(ap, mesg);
- vfprintf(stderr, mesg, ap);
- va_end(ap);
- fputc('\n', stderr);
-}
-
-extern int fdisk_debug_mask;
-extern void fdisk_init_debug(int mask);
-
-struct partition {
- unsigned char boot_ind; /* 0x80 - active */
- unsigned char head; /* starting head */
- unsigned char sector; /* starting sector */
- unsigned char cyl; /* starting cylinder */
- unsigned char sys_ind; /* What partition type */
- unsigned char end_head; /* end head */
- unsigned char end_sector; /* end sector */
- unsigned char end_cyl; /* end cylinder */
- unsigned char start4[4]; /* starting sector counting from 0 */
- unsigned char size4[4]; /* nr of sectors in partition */
-} __attribute__ ((packed));
-
-enum menutype {
- MAIN_MENU,
- EXPERT_MENU,
-};
-
-enum failure {
- ioctl_error,
- unable_to_read,
- unable_to_seek,
- unable_to_write
-};
-
-typedef unsigned long long sector_t;
-
-/*
- * Legacy CHS based geometry
- */
-struct fdisk_geometry {
- unsigned int heads;
- sector_t sectors;
- sector_t cylinders;
-};
-
-struct fdisk_context {
- int dev_fd; /* device descriptor */
- char *dev_path; /* device path */
- unsigned char *mbr; /* buffer with master boot record */
-
- /* topology */
- unsigned long io_size; /* I/O size used by fdisk */
- unsigned long optimal_io_size; /* optional I/O returned by device */
- unsigned long min_io_size; /* minimal I/O size */
- unsigned long phy_sector_size; /* physical size */
- unsigned long sector_size; /* logical size */
- unsigned long alignment_offset;
-
- /* geometry */
- sector_t total_sectors; /* in logical sectors */
- struct fdisk_geometry geom;
-};
-
-extern struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int readonly);
-extern int fdisk_dev_has_topology(struct fdisk_context *cxt);
-extern int fdisk_dev_sectsz_is_default(struct fdisk_context *cxt);
-extern void fdisk_free_context(struct fdisk_context *cxt);
-extern void fdisk_mbr_zeroize(struct fdisk_context *cxt);
-extern void fdisk_geom_set_cyls(struct fdisk_context *cxt);
-
-/* prototypes for fdisk.c */
-extern char *disk_device, *line_ptr;
-extern int fd, partitions;
-extern unsigned int display_in_cyl_units, units_per_sector;
-extern void change_units(struct fdisk_context *cxt);
-extern void fatal(struct fdisk_context *cxt, enum failure why);
-extern int get_partition(struct fdisk_context *cxt, int warn, int max);
-extern void list_types(struct systypes *sys);
-extern int read_line (int *asked);
-extern char read_char(char *mesg);
-extern int read_hex(struct systypes *sys);
-extern void reread_partition_table(struct fdisk_context *cxt, int leave);
-extern struct partition *get_part_table(int);
-extern int valid_part_table_flag(unsigned char *b);
-extern unsigned int read_int(struct fdisk_context *cxt,
- unsigned int low, unsigned int dflt,
- unsigned int high, unsigned int base, char *mesg);
-extern void print_menu(enum menutype);
-extern void print_partition_size(struct fdisk_context *cxt, int num, sector_t start, sector_t stop, int sysid);
-
-extern void fill_bounds(sector_t *first, sector_t *last);
-extern unsigned int heads, cylinders;
-extern sector_t sectors;
-extern char *partition_type(unsigned char type);
-extern void update_units(struct fdisk_context *cxt);
-extern char read_chars(char *mesg);
-extern void set_changed(int);
-extern void set_all_unchanged(void);
-extern int warn_geometry(struct fdisk_context *cxt);
-extern void warn_limits(struct fdisk_context *cxt);
-extern void warn_alignment(struct fdisk_context *cxt);
-extern unsigned int read_int_with_suffix(struct fdisk_context *cxt,
- unsigned int low, unsigned int dflt, unsigned int high,
- unsigned int base, char *mesg, int *is_suffix_used);
-extern sector_t align_lba(struct fdisk_context *cxt, sector_t lba, int direction);
-extern int get_partition_dflt(struct fdisk_context *cxt, int warn, int max, int dflt);
-extern void update_sector_offset(struct fdisk_context *cxt);
-extern void get_partition_table_geometry(struct fdisk_context *cxt,
- unsigned int *ph, unsigned int *ps);
-
-#define PLURAL 0
-#define SINGULAR 1
-extern const char * str_units(int);
-
-extern sector_t get_nr_sects(struct partition *p);
-
-enum labeltype {
- DOS_LABEL = 1,
- SUN_LABEL = 2,
- SGI_LABEL = 4,
- AIX_LABEL = 8,
- OSF_LABEL = 16,
- MAC_LABEL = 32,
- ANY_LABEL = -1
-};
-
-extern enum labeltype disklabel;
-extern int MBRbuffer_changed;
-extern unsigned long grain;
-
-/* start_sect and nr_sects are stored little endian on all machines */
-/* moreover, they are not aligned correctly */
-static inline void
-store4_little_endian(unsigned char *cp, unsigned int val) {
- cp[0] = (val & 0xff);
- cp[1] = ((val >> 8) & 0xff);
- cp[2] = ((val >> 16) & 0xff);
- cp[3] = ((val >> 24) & 0xff);
-}
-
-static inline unsigned int read4_little_endian(const unsigned char *cp)
-{
- return (unsigned int)(cp[0]) + ((unsigned int)(cp[1]) << 8)
- + ((unsigned int)(cp[2]) << 16)
- + ((unsigned int)(cp[3]) << 24);
-}
-
-static inline void set_nr_sects(struct partition *p, sector_t nr_sects)
-{
- store4_little_endian(p->size4, nr_sects);
-}
-
-static inline void set_start_sect(struct partition *p, unsigned int start_sect)
-{
- store4_little_endian(p->start4, start_sect);
-}
-
-static inline void seek_sector(struct fdisk_context *cxt, sector_t secno)
-{
- off_t offset = (off_t) secno * cxt->sector_size;
- if (lseek(cxt->dev_fd, offset, SEEK_SET) == (off_t) -1)
- fatal(cxt, unable_to_seek);
-}
-
-static inline void read_sector(struct fdisk_context *cxt, sector_t secno, unsigned char *buf)
-{
- seek_sector(cxt, secno);
- if (read(cxt->dev_fd, buf, cxt->sector_size) != (ssize_t) cxt->sector_size)
- fatal(cxt, unable_to_read);
-}
-
-static inline void write_sector(struct fdisk_context *cxt, sector_t secno, unsigned char *buf)
-{
- seek_sector(cxt, secno);
- if (write(cxt->dev_fd, buf, cxt->sector_size) != (ssize_t) cxt->sector_size)
- fatal(cxt, unable_to_write);
-}
-
-static inline sector_t get_start_sect(struct partition *p)
-{
- return read4_little_endian(p->start4);
-}
-
-static inline int is_cleared_partition(struct partition *p)
-{
- return !(!p || p->boot_ind || p->head || p->sector || p->cyl ||
- p->sys_ind || p->end_head || p->end_sector || p->end_cyl ||
- get_start_sect(p) || get_nr_sects(p));
-}
diff --git a/fdisk/fdiskaixlabel.c b/fdisk/fdiskaixlabel.c
deleted file mode 100644
index fb36489e1..000000000
--- a/fdisk/fdiskaixlabel.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- Changes:
- Sat Mar 20 09:51:38 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- Internationalization
-*/
-#include <stdio.h> /* stderr */
-#include <string.h> /* strstr */
-#include <unistd.h> /* write */
-
-#include <endian.h>
-
-#include "common.h"
-#include "fdisk.h"
-#include "fdiskaixlabel.h"
-#include "nls.h"
-
-#define aixlabel ((aix_partition *)cxt->mbr)
-
-static int other_endian = 0;
-static short volumes=1;
-
-/*
- * only dealing with free blocks here
- */
-
-static void
-aix_info( void ) {
- puts(
- _("\n\tThere is a valid AIX label on this disk.\n"
- "\tUnfortunately Linux cannot handle these\n"
- "\tdisks at the moment. Nevertheless some\n"
- "\tadvice:\n"
- "\t1. fdisk will destroy its contents on write.\n"
- "\t2. Be sure that this disk is NOT a still vital\n"
- "\t part of a volume group. (Otherwise you may\n"
- "\t erase the other disks as well, if unmirrored.)\n"
- "\t3. Before deleting this physical volume be sure\n"
- "\t to remove the disk logically from your AIX\n"
- "\t machine. (Otherwise you become an AIXpert).")
- );
-}
-
-void
-aix_nolabel(struct fdisk_context *cxt)
-{
- aixlabel->magic = 0;
- partitions = 4;
- fdisk_mbr_zeroize(cxt);
- return;
-}
-
-int check_aix_label(struct fdisk_context *cxt)
-{
- if (aixlabel->magic != AIX_LABEL_MAGIC &&
- aixlabel->magic != AIX_LABEL_MAGIC_SWAPPED) {
- other_endian = 0;
- return 0;
- }
- other_endian = (aixlabel->magic == AIX_LABEL_MAGIC_SWAPPED);
- update_units(cxt);
- disklabel = AIX_LABEL;
- partitions= 1016;
- volumes = 15;
- aix_info();
- aix_nolabel(cxt); /* %% */
- return 1;
-}
diff --git a/fdisk/fdiskaixlabel.h b/fdisk/fdiskaixlabel.h
deleted file mode 100644
index bd4cb2781..000000000
--- a/fdisk/fdiskaixlabel.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef FDISK_AIX_LABEL_H
-#define FDISK_AIX_LABEL_H
-
-#include <stdint.h>
-/*
- * Copyright (C) Andreas Neuper, Sep 1998.
- * This file may be redistributed under
- * the terms of the GNU Public License.
- */
-
-typedef struct {
- unsigned int magic; /* expect AIX_LABEL_MAGIC */
- unsigned int fillbytes1[124];
- unsigned int physical_volume_id;
- unsigned int fillbytes2[124];
-} aix_partition;
-
-#define AIX_LABEL_MAGIC 0xc9c2d4c1
-#define AIX_LABEL_MAGIC_SWAPPED 0xc1d4c2c9
-#define AIX_INFO_MAGIC 0x00072959
-#define AIX_INFO_MAGIC_SWAPPED 0x59290700
-
-/* fdiskaixlabel.c */
-extern struct systypes aix_sys_types[];
-extern int check_aix_label(struct fdisk_context *cxt);
-
-#endif /* FDISK_AIX_LABEL_H */
diff --git a/fdisk/fdiskbsdlabel.c b/fdisk/fdiskbsdlabel.c
deleted file mode 100644
index 71efd33f6..000000000
--- a/fdisk/fdiskbsdlabel.c
+++ /dev/null
@@ -1,847 +0,0 @@
-/*
- NetBSD disklabel editor for Linux fdisk
- Written by Bernhard Fastenrath (fasten@informatik.uni-bonn.de)
- with code from the NetBSD disklabel command:
-
- Copyright (c) 1987, 1988 Regents of the University of California.
- 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.
- 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 the University of
- California, Berkeley and its contributors.
- 4. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
-
- Changes:
- 19990319 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> - i18n/nls
-
- 20000101 - David Huggins-Daines <dhuggins@linuxcare.com> - Better
- support for OSF/1 disklabels on Alpha.
- Also fixed unaligned accesses in alpha_bootblock_checksum()
-*/
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <setjmp.h>
-#include <errno.h>
-#include "nls.h"
-
-#include <sys/param.h>
-
-#include "common.h"
-#include "fdisk.h"
-#define FREEBSD_PARTITION 0xa5
-#define NETBSD_PARTITION 0xa9
-#define DKTYPENAMES
-#include "fdiskbsdlabel.h"
-
-static void xbsd_delete_part (void);
-static void xbsd_new_part (struct fdisk_context *cxt);
-static void xbsd_write_disklabel (struct fdisk_context *cxt);
-static int xbsd_create_disklabel (struct fdisk_context *cxt);
-static void xbsd_edit_disklabel (void);
-static void xbsd_write_bootstrap (struct fdisk_context *cxt);
-static void xbsd_change_fstype (void);
-static int xbsd_get_part_index (int max);
-static int xbsd_check_new_partition (int *i);
-static void xbsd_list_types (void);
-static unsigned short xbsd_dkcksum (struct xbsd_disklabel *lp);
-static int xbsd_initlabel (struct fdisk_context *cxt,
- struct partition *p, struct xbsd_disklabel *d,
- int pindex);
-static int xbsd_readlabel (struct fdisk_context *cxt,
- struct partition *p, struct xbsd_disklabel *d);
-static int xbsd_writelabel (struct fdisk_context *cxt, struct partition *p, struct xbsd_disklabel *d);
-static void sync_disks (void);
-
-#if defined (__alpha__)
-void alpha_bootblock_checksum (char *boot);
-#endif
-
-#if !defined (__alpha__)
-static int xbsd_translate_fstype (int linux_type);
-static void xbsd_link_part (struct fdisk_context *cxt);
-static struct partition *xbsd_part;
-static int xbsd_part_index;
-#endif
-
-#if defined (__alpha__)
-/* We access this through a u_int64_t * when checksumming */
-static char disklabelbuffer[BSD_BBSIZE] __attribute__((aligned(8)));
-#else
-static char disklabelbuffer[BSD_BBSIZE];
-#endif
-
-static struct xbsd_disklabel xbsd_dlabel;
-
-#define bsd_cround(n) \
- (display_in_cyl_units ? ((n)/xbsd_dlabel.d_secpercyl) + 1 : (n))
-
-/*
- * Test whether the whole disk has BSD disk label magic.
- *
- * Note: often reformatting with DOS-type label leaves the BSD magic,
- * so this does not mean that there is a BSD disk label.
- */
-int
-check_osf_label(struct fdisk_context *cxt) {
- if (xbsd_readlabel (cxt, NULL, &xbsd_dlabel) == 0)
- return 0;
- return 1;
-}
-
-int
-btrydev (struct fdisk_context *cxt) {
- if (xbsd_readlabel (cxt, NULL, &xbsd_dlabel) == 0)
- return -1;
- printf(_("\nBSD label for device: %s\n"), cxt->dev_path);
- xbsd_print_disklabel (cxt, 0);
- return 0;
-}
-
-#if !defined (__alpha__)
-static int
-hidden(int type) {
- return type ^ 0x10;
-}
-
-static int
-is_bsd_partition_type(int type) {
- return (type == FREEBSD_PARTITION ||
- type == hidden(FREEBSD_PARTITION) ||
- type == NETBSD_PARTITION ||
- type == hidden(NETBSD_PARTITION));
-}
-#endif
-
-void
-bsd_command_prompt (struct fdisk_context *cxt)
-{
-#if !defined (__alpha__)
- int t, ss;
- struct partition *p;
-
- for (t=0; t<4; t++) {
- p = get_part_table(t);
- if (p && is_bsd_partition_type(p->sys_ind)) {
- xbsd_part = p;
- xbsd_part_index = t;
- ss = get_start_sect(xbsd_part);
- if (ss == 0) {
- fprintf (stderr, _("Partition %s has invalid starting sector 0.\n"),
- partname(cxt->dev_path, t+1, 0));
- return;
- }
- printf (_("Reading disklabel of %s at sector %d.\n"),
- partname(cxt->dev_path, t+1, 0), ss + BSD_LABELSECTOR);
- if (xbsd_readlabel (cxt, xbsd_part, &xbsd_dlabel) == 0)
- if (xbsd_create_disklabel (cxt) == 0)
- return;
- break;
- }
- }
-
- if (t == 4) {
- printf (_("There is no *BSD partition on %s.\n"), cxt->dev_path);
- return;
- }
-
-#elif defined (__alpha__)
-
- if (xbsd_readlabel (cxt, NULL, &xbsd_dlabel) == 0)
- if (xbsd_create_disklabel (cxt) == 0)
- exit ( EXIT_SUCCESS );
-
-#endif
-
- while (1) {
- putchar ('\n');
- switch (tolower (read_char (_("BSD disklabel command (m for help): ")))) {
- case 'd':
- xbsd_delete_part ();
- break;
- case 'e':
- xbsd_edit_disklabel ();
- break;
- case 'i':
- xbsd_write_bootstrap (cxt);
- break;
- case 'l':
- xbsd_list_types ();
- break;
- case 'n':
- xbsd_new_part (cxt);
- break;
- case 'p':
- xbsd_print_disklabel (cxt, 0);
- break;
- case 'q':
- close (cxt->dev_fd);
- exit ( EXIT_SUCCESS );
- case 'r':
- return;
- case 's':
- xbsd_print_disklabel (cxt, 1);
- break;
- case 't':
- xbsd_change_fstype ();
- break;
- case 'u':
- change_units(cxt);
- break;
- case 'w':
- xbsd_write_disklabel (cxt);
- break;
-#if !defined (__alpha__)
- case 'x':
- xbsd_link_part (cxt);
- break;
-#endif
- default:
- print_menu(MAIN_MENU);
- break;
- }
- }
-}
-
-static void
-xbsd_delete_part (void)
-{
- int i;
-
- i = xbsd_get_part_index (xbsd_dlabel.d_npartitions);
- xbsd_dlabel.d_partitions[i].p_size = 0;
- xbsd_dlabel.d_partitions[i].p_offset = 0;
- xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED;
- if (xbsd_dlabel.d_npartitions == i + 1)
- while (xbsd_dlabel.d_partitions[xbsd_dlabel.d_npartitions-1].p_size == 0)
- xbsd_dlabel.d_npartitions--;
-}
-
-static void
-xbsd_new_part (struct fdisk_context *cxt)
-{
- unsigned int begin, end;
- char mesg[256];
- int i;
-
- if (!xbsd_check_new_partition (&i))
- return;
-
-#if !defined (__alpha__) && !defined (__powerpc__) && !defined (__hppa__)
- begin = get_start_sect(xbsd_part);
- end = begin + get_nr_sects(xbsd_part) - 1;
-#else
- begin = 0;
- end = xbsd_dlabel.d_secperunit - 1;
-#endif
-
- snprintf (mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
- begin = read_int (cxt, bsd_cround (begin), bsd_cround (begin), bsd_cround (end),
- 0, mesg);
-
- if (display_in_cyl_units)
- begin = (begin - 1) * xbsd_dlabel.d_secpercyl;
-
- snprintf (mesg, sizeof(mesg), _("Last %s or +size or +sizeM or +sizeK"),
- str_units(SINGULAR));
- end = read_int (cxt, bsd_cround (begin), bsd_cround (end), bsd_cround (end),
- bsd_cround (begin), mesg);
-
- if (display_in_cyl_units)
- end = end * xbsd_dlabel.d_secpercyl - 1;
-
- xbsd_dlabel.d_partitions[i].p_size = end - begin + 1;
- xbsd_dlabel.d_partitions[i].p_offset = begin;
- xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED;
-}
-
-void
-xbsd_print_disklabel (struct fdisk_context *cxt, int show_all) {
- struct xbsd_disklabel *lp = &xbsd_dlabel;
- struct xbsd_partition *pp;
- FILE *f = stdout;
- int i, j;
-
- if (show_all) {
-#if defined (__alpha__)
- fprintf(f, "# %s:\n", cxt->dev_path);
-#else
- fprintf(f, "# %s:\n", partname(cxt->dev_path, xbsd_part_index+1, 0));
-#endif
- if ((unsigned) lp->d_type < BSD_DKMAXTYPES)
- fprintf(f, _("type: %s\n"), xbsd_dktypenames[lp->d_type]);
- else
- fprintf(f, _("type: %d\n"), lp->d_type);
- fprintf(f, _("disk: %.*s\n"), (int) sizeof(lp->d_typename), lp->d_typename);
- fprintf(f, _("label: %.*s\n"), (int) sizeof(lp->d_packname), lp->d_packname);
- fprintf(f, _("flags:"));
- if (lp->d_flags & BSD_D_REMOVABLE)
- fprintf(f, _(" removable"));
- if (lp->d_flags & BSD_D_ECC)
- fprintf(f, _(" ecc"));
- if (lp->d_flags & BSD_D_BADSECT)
- fprintf(f, _(" badsect"));
- fprintf(f, "\n");
- /* On various machines the fields of *lp are short/int/long */
- /* In order to avoid problems, we cast them all to long. */
- fprintf(f, _("bytes/sector: %ld\n"), (long) lp->d_secsize);
- fprintf(f, _("sectors/track: %ld\n"), (long) lp->d_nsectors);
- fprintf(f, _("tracks/cylinder: %ld\n"), (long) lp->d_ntracks);
- fprintf(f, _("sectors/cylinder: %ld\n"), (long) lp->d_secpercyl);
- fprintf(f, _("cylinders: %ld\n"), (long) lp->d_ncylinders);
- fprintf(f, _("rpm: %d\n"), lp->d_rpm);
- fprintf(f, _("interleave: %d\n"), lp->d_interleave);
- fprintf(f, _("trackskew: %d\n"), lp->d_trackskew);
- fprintf(f, _("cylinderskew: %d\n"), lp->d_cylskew);
- fprintf(f, _("headswitch: %ld\t\t# milliseconds\n"),
- (long) lp->d_headswitch);
- fprintf(f, _("track-to-track seek: %ld\t# milliseconds\n"),
- (long) lp->d_trkseek);
- fprintf(f, _("drivedata: "));
- for (i = NDDATA - 1; i >= 0; i--)
- if (lp->d_drivedata[i])
- break;
- if (i < 0)
- i = 0;
- for (j = 0; j <= i; j++)
- fprintf(f, "%ld ", (long) lp->d_drivedata[j]);
- }
- fprintf (f, _("\n%d partitions:\n"), lp->d_npartitions);
- fprintf (f, _("# start end size fstype [fsize bsize cpg]\n"));
- pp = lp->d_partitions;
- for (i = 0; i < lp->d_npartitions; i++, pp++) {
- if (pp->p_size) {
- if (display_in_cyl_units && lp->d_secpercyl) {
- fprintf(f, " %c: %8ld%c %8ld%c %8ld%c ",
- 'a' + i,
- (long) pp->p_offset / lp->d_secpercyl + 1,
- (pp->p_offset % lp->d_secpercyl) ? '*' : ' ',
- (long) (pp->p_offset + pp->p_size + lp->d_secpercyl - 1)
- / lp->d_secpercyl,
- ((pp->p_offset + pp->p_size) % lp->d_secpercyl) ? '*' : ' ',
- (long) pp->p_size / lp->d_secpercyl,
- (pp->p_size % lp->d_secpercyl) ? '*' : ' ');
- } else {
- fprintf(f, " %c: %8ld %8ld %8ld ",
- 'a' + i,
- (long) pp->p_offset,
- (long) pp->p_offset + pp->p_size - 1,
- (long) pp->p_size);
- }
- if ((unsigned) pp->p_fstype < BSD_FSMAXTYPES)
- fprintf(f, "%8.8s", xbsd_fstypes[pp->p_fstype].name);
- else
- fprintf(f, "%8x", pp->p_fstype);
- switch (pp->p_fstype) {
- case BSD_FS_UNUSED:
- fprintf(f, " %5ld %5ld %5.5s ",
- (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, "");
- break;
-
- case BSD_FS_BSDFFS:
- fprintf(f, " %5ld %5ld %5d ",
- (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag,
- pp->p_cpg);
- break;
-
- default:
- fprintf(f, "%22.22s", "");
- break;
- }
- fprintf(f, "\n");
- }
- }
-}
-
-static void
-xbsd_write_disklabel (struct fdisk_context *cxt) {
-#if defined (__alpha__)
- printf (_("Writing disklabel to %s.\n"), cxt->dev_path);
- xbsd_writelabel (cxt, NULL, &xbsd_dlabel);
-#else
- printf (_("Writing disklabel to %s.\n"),
- partname(cxt->dev_path, xbsd_part_index+1, 0));
- xbsd_writelabel (cxt, xbsd_part, &xbsd_dlabel);
-#endif
- reread_partition_table(cxt, 0); /* no exit yet */
-}
-
-static int
-xbsd_create_disklabel (struct fdisk_context *cxt) {
- char c;
-
-#if defined (__alpha__)
- fprintf (stderr, _("%s contains no disklabel.\n"), cxt->dev_path);
-#else
- fprintf (stderr, _("%s contains no disklabel.\n"),
- partname(cxt->dev_path, xbsd_part_index+1, 0));
-#endif
-
- while (1) {
- c = read_char (_("Do you want to create a disklabel? (y/n) "));
- if (tolower(c) == 'y') {
- if (xbsd_initlabel (cxt,
-#if defined (__alpha__) || defined (__powerpc__) || defined (__hppa__) || \
- defined (__s390__) || defined (__s390x__)
- NULL, &xbsd_dlabel, 0
-#else
- xbsd_part, &xbsd_dlabel, xbsd_part_index
-#endif
- ) == 1) {
- xbsd_print_disklabel (cxt, 1);
- return 1;
- } else
- return 0;
- } else if (c == 'n')
- return 0;
- }
-}
-
-static int
-edit_int (int def, char *mesg)
-{
- do {
- fputs (mesg, stdout);
- printf (" (%d): ", def);
- if (!read_line (NULL))
- return def;
- }
- while (!isdigit (*line_ptr));
- return atoi (line_ptr);
-}
-
-static void
-xbsd_edit_disklabel (void)
-{
- struct xbsd_disklabel *d;
-
- d = &xbsd_dlabel;
-
-#if defined (__alpha__) || defined (__ia64__)
- d -> d_secsize = (unsigned long) edit_int ((unsigned long) d -> d_secsize ,_("bytes/sector"));
- d -> d_nsectors = (unsigned long) edit_int ((unsigned long) d -> d_nsectors ,_("sectors/track"));
- d -> d_ntracks = (unsigned long) edit_int ((unsigned long) d -> d_ntracks ,_("tracks/cylinder"));
- d -> d_ncylinders = (unsigned long) edit_int ((unsigned long) d -> d_ncylinders ,_("cylinders"));
-#endif
-
- /* d -> d_secpercyl can be != d -> d_nsectors * d -> d_ntracks */
- while (1)
- {
- d -> d_secpercyl = (unsigned long) edit_int ((unsigned long) d -> d_nsectors * d -> d_ntracks,
- _("sectors/cylinder"));
- if (d -> d_secpercyl <= d -> d_nsectors * d -> d_ntracks)
- break;
-
- printf (_("Must be <= sectors/track * tracks/cylinder (default).\n"));
- }
- d -> d_rpm = (unsigned short) edit_int ((unsigned short) d -> d_rpm ,_("rpm"));
- d -> d_interleave = (unsigned short) edit_int ((unsigned short) d -> d_interleave,_("interleave"));
- d -> d_trackskew = (unsigned short) edit_int ((unsigned short) d -> d_trackskew ,_("trackskew"));
- d -> d_cylskew = (unsigned short) edit_int ((unsigned short) d -> d_cylskew ,_("cylinderskew"));
- d -> d_headswitch = (unsigned long) edit_int ((unsigned long) d -> d_headswitch ,_("headswitch"));
- d -> d_trkseek = (unsigned long) edit_int ((unsigned long) d -> d_trkseek ,_("track-to-track seek"));
-
- d -> d_secperunit = d -> d_secpercyl * d -> d_ncylinders;
-}
-
-static int
-xbsd_get_bootstrap (char *path, void *ptr, int size)
-{
- int fd;
-
- if ((fd = open (path, O_RDONLY)) < 0)
- {
- perror (path);
- return 0;
- }
- if (read (fd, ptr, size) < 0)
- {
- perror (path);
- close (fd);
- return 0;
- }
- printf (" ... %s\n", path);
- close (fd);
- return 1;
-}
-
-static void
-xbsd_write_bootstrap (struct fdisk_context *cxt)
-{
- char *bootdir = BSD_LINUX_BOOTDIR;
- char path[sizeof(BSD_LINUX_BOOTDIR) + 1 + 2 + 4]; /* BSD_LINUX_BOOTDIR + / + {sd,wd} + boot */
- char *dkbasename;
- struct xbsd_disklabel dl;
- char *d, *p, *e;
- int sector;
-
- if (xbsd_dlabel.d_type == BSD_DTYPE_SCSI)
- dkbasename = "sd";
- else
- dkbasename = "wd";
-
- printf (_("Bootstrap: %sboot -> boot%s (%s): "),
- dkbasename, dkbasename, dkbasename);
- if (read_line (NULL)) {
- line_ptr[strlen (line_ptr)-1] = '\0';
- dkbasename = line_ptr;
- }
- snprintf (path, sizeof(path), "%s/%sboot", bootdir, dkbasename);
- if (!xbsd_get_bootstrap (path, disklabelbuffer, (int) xbsd_dlabel.d_secsize))
- return;
-
- /* We need a backup of the disklabel (xbsd_dlabel might have changed). */
- d = &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE];
- memmove (&dl, d, sizeof (struct xbsd_disklabel));
-
- /* The disklabel will be overwritten by 0's from bootxx anyway */
- memset (d, 0, sizeof (struct xbsd_disklabel));
-
- snprintf (path, sizeof(path), "%s/boot%s", bootdir, dkbasename);
- if (!xbsd_get_bootstrap (path, &disklabelbuffer[xbsd_dlabel.d_secsize],
- (int) xbsd_dlabel.d_bbsize - xbsd_dlabel.d_secsize))
- return;
-
- e = d + sizeof (struct xbsd_disklabel);
- for (p=d; p < e; p++)
- if (*p) {
- fprintf (stderr, _("Bootstrap overlaps with disk label!\n"));
- exit ( EXIT_FAILURE );
- }
-
- memmove (d, &dl, sizeof (struct xbsd_disklabel));
-
-#if defined (__powerpc__) || defined (__hppa__)
- sector = 0;
-#elif defined (__alpha__)
- sector = 0;
- alpha_bootblock_checksum (disklabelbuffer);
-#else
- sector = get_start_sect(xbsd_part);
-#endif
-
- if (lseek (cxt->dev_fd, (off_t) sector * SECTOR_SIZE, SEEK_SET) == -1)
- fatal (cxt, unable_to_seek);
- if (BSD_BBSIZE != write (cxt->dev_fd, disklabelbuffer, BSD_BBSIZE))
- fatal (cxt, unable_to_write);
-
-#if defined (__alpha__)
- printf (_("Bootstrap installed on %s.\n"), cxt->dev_path);
-#else
- printf (_("Bootstrap installed on %s.\n"),
- partname (cxt->dev_path, xbsd_part_index+1, 0));
-#endif
-
- sync_disks ();
-}
-
-static void
-xbsd_change_fstype (void)
-{
- int i;
-
- i = xbsd_get_part_index (xbsd_dlabel.d_npartitions);
- xbsd_dlabel.d_partitions[i].p_fstype = read_hex (xbsd_fstypes);
-}
-
-static int
-xbsd_get_part_index (int max)
-{
- char prompt[256];
- char l;
-
- snprintf (prompt, sizeof(prompt), _("Partition (a-%c): "), 'a' + max - 1);
- do
- l = tolower (read_char (prompt));
- while (l < 'a' || l > 'a' + max - 1);
- return l - 'a';
-}
-
-static int
-xbsd_check_new_partition (int *i) {
-
- /* room for more? various BSD flavours have different maxima */
- if (xbsd_dlabel.d_npartitions == BSD_MAXPARTITIONS) {
- int t;
-
- for (t = 0; t < BSD_MAXPARTITIONS; t++)
- if (xbsd_dlabel.d_partitions[t].p_size == 0)
- break;
-
- if (t == BSD_MAXPARTITIONS) {
- fprintf (stderr, _("The maximum number of partitions "
- "has been created\n"));
- return 0;
- }
- }
-
- *i = xbsd_get_part_index (BSD_MAXPARTITIONS);
-
- if (*i >= xbsd_dlabel.d_npartitions)
- xbsd_dlabel.d_npartitions = (*i) + 1;
-
- if (xbsd_dlabel.d_partitions[*i].p_size != 0) {
- fprintf (stderr, _("This partition already exists.\n"));
- return 0;
- }
-
- return 1;
-}
-
-static void
-xbsd_list_types (void) {
- list_types (xbsd_fstypes);
-}
-
-static unsigned short
-xbsd_dkcksum (struct xbsd_disklabel *lp) {
- unsigned short *start, *end;
- unsigned short sum = 0;
-
- start = (unsigned short *) lp;
- end = (unsigned short *) &lp->d_partitions[lp->d_npartitions];
- while (start < end)
- sum ^= *start++;
- return sum;
-}
-
-static int
-xbsd_initlabel (struct fdisk_context *cxt, struct partition *p, struct xbsd_disklabel *d,
- int pindex __attribute__((__unused__))) {
- struct xbsd_partition *pp;
-
- memset (d, 0, sizeof (struct xbsd_disklabel));
-
- d -> d_magic = BSD_DISKMAGIC;
-
- if (strncmp (cxt->dev_path, "/dev/sd", 7) == 0)
- d -> d_type = BSD_DTYPE_SCSI;
- else
- d -> d_type = BSD_DTYPE_ST506;
-
-#if 0 /* not used (at least not written to disk) by NetBSD/i386 1.0 */
- d -> d_subtype = BSD_DSTYPE_INDOSPART & pindex;
-#endif
-
-#if !defined (__alpha__)
- d -> d_flags = BSD_D_DOSPART;
-#else
- d -> d_flags = 0;
-#endif
- d -> d_secsize = SECTOR_SIZE; /* bytes/sector */
- d -> d_nsectors = cxt->geom.sectors; /* sectors/track */
- d -> d_ntracks = cxt->geom.heads; /* tracks/cylinder (heads) */
- d -> d_ncylinders = cxt->geom.cylinders;
- d -> d_secpercyl = cxt->geom.sectors * cxt->geom.heads;/* sectors/cylinder */
- if (d -> d_secpercyl == 0)
- d -> d_secpercyl = 1; /* avoid segfaults */
- d -> d_secperunit = d -> d_secpercyl * d -> d_ncylinders;
-
- d -> d_rpm = 3600;
- d -> d_interleave = 1;
- d -> d_trackskew = 0;
- d -> d_cylskew = 0;
- d -> d_headswitch = 0;
- d -> d_trkseek = 0;
-
- d -> d_magic2 = BSD_DISKMAGIC;
- d -> d_bbsize = BSD_BBSIZE;
- d -> d_sbsize = BSD_SBSIZE;
-
-#if !defined (__alpha__)
- d -> d_npartitions = 4;
- pp = &d -> d_partitions[2]; /* Partition C should be
- the NetBSD partition */
- pp -> p_offset = get_start_sect(p);
- pp -> p_size = get_nr_sects(p);
- pp -> p_fstype = BSD_FS_UNUSED;
- pp = &d -> d_partitions[3]; /* Partition D should be
- the whole disk */
- pp -> p_offset = 0;
- pp -> p_size = d -> d_secperunit;
- pp -> p_fstype = BSD_FS_UNUSED;
-#elif defined (__alpha__)
- d -> d_npartitions = 3;
- pp = &d -> d_partitions[2]; /* Partition C should be
- the whole disk */
- pp -> p_offset = 0;
- pp -> p_size = d -> d_secperunit;
- pp -> p_fstype = BSD_FS_UNUSED;
-#endif
-
- return 1;
-}
-
-/*
- * Read a xbsd_disklabel from sector 0 or from the starting sector of p.
- * If it has the right magic, return 1.
- */
-static int
-xbsd_readlabel (struct fdisk_context *cxt, struct partition *p, struct xbsd_disklabel *d)
-{
- int t, sector;
-
- /* p is used only to get the starting sector */
-#if !defined (__alpha__)
- sector = (p ? get_start_sect(p) : 0);
-#elif defined (__alpha__)
- sector = 0;
-#endif
-
- if (lseek (cxt->dev_fd, (off_t) sector * SECTOR_SIZE, SEEK_SET) == -1)
- fatal (cxt, unable_to_seek);
- if (BSD_BBSIZE != read (cxt->dev_fd, disklabelbuffer, BSD_BBSIZE))
- fatal (cxt, unable_to_read);
-
- memmove (d,
- &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
- sizeof (struct xbsd_disklabel));
-
- if (d -> d_magic != BSD_DISKMAGIC || d -> d_magic2 != BSD_DISKMAGIC)
- return 0;
-
- for (t = d -> d_npartitions; t < BSD_MAXPARTITIONS; t++) {
- d -> d_partitions[t].p_size = 0;
- d -> d_partitions[t].p_offset = 0;
- d -> d_partitions[t].p_fstype = BSD_FS_UNUSED;
- }
-
- if (d -> d_npartitions > BSD_MAXPARTITIONS)
- fprintf (stderr, _("Warning: too many partitions "
- "(%d, maximum is %d).\n"),
- d -> d_npartitions, BSD_MAXPARTITIONS);
- return 1;
-}
-
-static int
-xbsd_writelabel (struct fdisk_context *cxt, struct partition *p, struct xbsd_disklabel *d)
-{
- unsigned int sector;
-
-#if !defined (__alpha__) && !defined (__powerpc__) && !defined (__hppa__)
- sector = get_start_sect(p) + BSD_LABELSECTOR;
-#else
- sector = BSD_LABELSECTOR;
-#endif
-
- d -> d_checksum = 0;
- d -> d_checksum = xbsd_dkcksum (d);
-
- /* This is necessary if we want to write the bootstrap later,
- otherwise we'd write the old disklabel with the bootstrap.
- */
- memmove (&disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], d,
- sizeof (struct xbsd_disklabel));
-
-#if defined (__alpha__) && BSD_LABELSECTOR == 0
- alpha_bootblock_checksum (disklabelbuffer);
- if (lseek (cxt->dev_fd, (off_t) 0, SEEK_SET) == -1)
- fatal (cxt, unable_to_seek);
- if (BSD_BBSIZE != write (cxt->dev_fd, disklabelbuffer, BSD_BBSIZE))
- fatal (cxt, unable_to_write);
-#else
- if (lseek (cxt->dev_fd, (off_t) sector * SECTOR_SIZE + BSD_LABELOFFSET,
- SEEK_SET) == -1)
- fatal (cxt, unable_to_seek);
- if (sizeof (struct xbsd_disklabel) != write (cxt->dev_fd, d, sizeof (struct xbsd_disklabel)))
- fatal (cxt, unable_to_write);
-#endif
-
- sync_disks ();
-
- return 1;
-}
-
-static void
-sync_disks (void)
-{
- printf (_("\nSyncing disks.\n"));
- sync ();
- sleep (4);
-}
-
-#if !defined (__alpha__)
-static int
-xbsd_translate_fstype (int linux_type)
-{
- switch (linux_type)
- {
- case 0x01: /* DOS 12-bit FAT */
- case 0x04: /* DOS 16-bit <32M */
- case 0x06: /* DOS 16-bit >=32M */
- case 0xe1: /* DOS access */
- case 0xe3: /* DOS R/O */
- case 0xf2: /* DOS secondary */
- return BSD_FS_MSDOS;
- case 0x07: /* OS/2 HPFS */
- return BSD_FS_HPFS;
- default:
- return BSD_FS_OTHER;
- }
-}
-
-static void
-xbsd_link_part (struct fdisk_context *cxt)
-{
- int k, i;
- struct partition *p;
-
- k = get_partition (cxt, 1, partitions);
-
- if (!xbsd_check_new_partition (&i))
- return;
-
- p = get_part_table(k);
-
- xbsd_dlabel.d_partitions[i].p_size = get_nr_sects(p);
- xbsd_dlabel.d_partitions[i].p_offset = get_start_sect(p);
- xbsd_dlabel.d_partitions[i].p_fstype = xbsd_translate_fstype(p->sys_ind);
-}
-#endif
-
-#if defined (__alpha__)
-
-#if !defined(__GLIBC__)
-typedef unsigned long long u_int64_t;
-#endif
-
-void
-alpha_bootblock_checksum (char *boot)
-{
- u_int64_t *dp, sum;
- int i;
-
- dp = (u_int64_t *)boot;
- sum = 0;
- for (i = 0; i < 63; i++)
- sum += dp[i];
- dp[63] = sum;
-}
-#endif /* __alpha__ */
diff --git a/fdisk/fdiskbsdlabel.h b/fdisk/fdiskbsdlabel.h
deleted file mode 100644
index 79f291348..000000000
--- a/fdisk/fdiskbsdlabel.h
+++ /dev/null
@@ -1,246 +0,0 @@
-#ifndef FDISK_BSD_LABEL_H
-#define FDISK_BSD_LABEL_H
-
-/*
- * Copyright (c) 1987, 1988 Regents of the University of California.
- * 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.
- * 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 the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
- */
-
-#include <stdint.h>
-
-#ifndef BSD_DISKMAGIC
-#define BSD_DISKMAGIC ((uint32_t) 0x82564557)
-#endif
-
-#ifndef BSD_MAXPARTITIONS
-#define BSD_MAXPARTITIONS 16
-#endif
-
-#define BSD_LINUX_BOOTDIR "/usr/ucb/mdec"
-
-#if defined (__i386__) || defined (__sparc__) || defined (__arm__) || \
- defined (__mips__) || defined (__s390__) || defined (__sh__) || \
- defined(__x86_64__) || defined (__avr32__) || defined(__cris__)
-#define BSD_LABELSECTOR 1
-#define BSD_LABELOFFSET 0
-#elif defined (__alpha__) || defined (__powerpc__) || defined (__ia64__) || defined (__hppa__)
-#define BSD_LABELSECTOR 0
-#define BSD_LABELOFFSET 64
-#elif defined (__s390__) || defined (__s390x__)
-#define BSD_LABELSECTOR 1
-#define BSD_LABELOFFSET 0
-#else
-#error unknown architecture
-#endif
-
-#define BSD_BBSIZE 8192 /* size of boot area, with label */
-#define BSD_SBSIZE 8192 /* max size of fs superblock */
-
-struct xbsd_disklabel {
- uint32_t d_magic; /* the magic number */
- int16_t d_type; /* drive type */
- int16_t d_subtype; /* controller/d_type specific */
- char d_typename[16]; /* type name, e.g. "eagle" */
- char d_packname[16]; /* pack identifier */
- /* disk geometry: */
- uint32_t d_secsize; /* # of bytes per sector */
- uint32_t d_nsectors; /* # of data sectors per track */
- uint32_t d_ntracks; /* # of tracks per cylinder */
- uint32_t d_ncylinders; /* # of data cylinders per unit */
- uint32_t d_secpercyl; /* # of data sectors per cylinder */
- uint32_t d_secperunit; /* # of data sectors per unit */
- /*
- * Spares (bad sector replacements) below
- * are not counted in d_nsectors or d_secpercyl.
- * Spare sectors are assumed to be physical sectors
- * which occupy space at the end of each track and/or cylinder.
- */
- uint16_t d_sparespertrack; /* # of spare sectors per track */
- uint16_t d_sparespercyl; /* # of spare sectors per cylinder */
- /*
- * Alternate cylinders include maintenance, replacement,
- * configuration description areas, etc.
- */
- uint32_t d_acylinders; /* # of alt. cylinders per unit */
-
- /* hardware characteristics: */
- /*
- * d_interleave, d_trackskew and d_cylskew describe perturbations
- * in the media format used to compensate for a slow controller.
- * Interleave is physical sector interleave, set up by the formatter
- * or controller when formatting. When interleaving is in use,
- * logically adjacent sectors are not physically contiguous,
- * but instead are separated by some number of sectors.
- * It is specified as the ratio of physical sectors traversed
- * per logical sector. Thus an interleave of 1:1 implies contiguous
- * layout, while 2:1 implies that logical sector 0 is separated
- * by one sector from logical sector 1.
- * d_trackskew is the offset of sector 0 on track N
- * relative to sector 0 on track N-1 on the same cylinder.
- * Finally, d_cylskew is the offset of sector 0 on cylinder N
- * relative to sector 0 on cylinder N-1.
- */
- uint16_t d_rpm; /* rotational speed */
- uint16_t d_interleave; /* hardware sector interleave */
- uint16_t d_trackskew; /* sector 0 skew, per track */
- uint16_t d_cylskew; /* sector 0 skew, per cylinder */
- uint32_t d_headswitch; /* head switch time, usec */
- uint32_t d_trkseek; /* track-to-track seek, usec */
- uint32_t d_flags; /* generic flags */
-#define NDDATA 5
- uint32_t d_drivedata[NDDATA]; /* drive-type specific information */
-#define NSPARE 5
- uint32_t d_spare[NSPARE]; /* reserved for future use */
- uint32_t d_magic2; /* the magic number (again) */
- uint16_t d_checksum; /* xor of data incl. partitions */
- /* filesystem and partition information: */
- uint16_t d_npartitions; /* number of partitions in following */
- uint32_t d_bbsize; /* size of boot area at sn0, bytes */
- uint32_t d_sbsize; /* max size of fs superblock, bytes */
- struct xbsd_partition { /* the partition table */
- uint32_t p_size; /* number of sectors in partition */
- uint32_t p_offset; /* starting sector */
- uint32_t p_fsize; /* filesystem basic fragment size */
- uint8_t p_fstype; /* filesystem type, see below */
- uint8_t p_frag; /* filesystem fragments per block */
- uint16_t p_cpg; /* filesystem cylinders per group */
- } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
-};
-
-/* d_type values: */
-#define BSD_DTYPE_SMD 1 /* SMD, XSMD; VAX hp/up */
-#define BSD_DTYPE_MSCP 2 /* MSCP */
-#define BSD_DTYPE_DEC 3 /* other DEC (rk, rl) */
-#define BSD_DTYPE_SCSI 4 /* SCSI */
-#define BSD_DTYPE_ESDI 5 /* ESDI interface */
-#define BSD_DTYPE_ST506 6 /* ST506 etc. */
-#define BSD_DTYPE_HPIB 7 /* CS/80 on HP-IB */
-#define BSD_DTYPE_HPFL 8 /* HP Fiber-link */
-#define BSD_DTYPE_FLOPPY 10 /* floppy */
-
-/* d_subtype values: */
-#define BSD_DSTYPE_INDOSPART 0x8 /* is inside dos partition */
-#define BSD_DSTYPE_DOSPART(s) ((s) & 3) /* dos partition number */
-#define BSD_DSTYPE_GEOMETRY 0x10 /* drive params in label */
-
-#ifdef DKTYPENAMES
-static char *xbsd_dktypenames[] = {
- "unknown",
- "SMD",
- "MSCP",
- "old DEC",
- "SCSI",
- "ESDI",
- "ST506",
- "HP-IB",
- "HP-FL",
- "type 9",
- "floppy",
- 0
-};
-#define BSD_DKMAXTYPES (sizeof(xbsd_dktypenames) / sizeof(xbsd_dktypenames[0]) - 1)
-#endif
-
-/*
- * Filesystem type and version.
- * Used to interpret other filesystem-specific
- * per-partition information.
- */
-#define BSD_FS_UNUSED 0 /* unused */
-#define BSD_FS_SWAP 1 /* swap */
-#define BSD_FS_V6 2 /* Sixth Edition */
-#define BSD_FS_V7 3 /* Seventh Edition */
-#define BSD_FS_SYSV 4 /* System V */
-#define BSD_FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */
-#define BSD_FS_V8 6 /* Eighth Edition, 4K blocks */
-#define BSD_FS_BSDFFS 7 /* 4.2BSD fast file system */
-#define BSD_FS_BSDLFS 9 /* 4.4BSD log-structured file system */
-#define BSD_FS_OTHER 10 /* in use, but unknown/unsupported */
-#define BSD_FS_HPFS 11 /* OS/2 high-performance file system */
-#define BSD_FS_ISO9660 12 /* ISO-9660 filesystem (cdrom) */
-#define BSD_FS_ISOFS BSD_FS_ISO9660
-#define BSD_FS_BOOT 13 /* partition contains bootstrap */
-#define BSD_FS_ADOS 14 /* AmigaDOS fast file system */
-#define BSD_FS_HFS 15 /* Macintosh HFS */
-#define BSD_FS_ADVFS 16 /* Digital Unix AdvFS */
-
-/* this is annoying, but it's also the way it is :-( */
-#ifdef __alpha__
-#define BSD_FS_EXT2 8 /* ext2 file system */
-#else
-#define BSD_FS_MSDOS 8 /* MS-DOS file system */
-#endif
-
-#ifdef DKTYPENAMES
-static struct systypes xbsd_fstypes[] = {
- {BSD_FS_UNUSED, "unused"},
- {BSD_FS_SWAP, "swap"},
- {BSD_FS_V6, "Version 6"},
- {BSD_FS_V7, "Version 7"},
- {BSD_FS_SYSV, "System V"},
- {BSD_FS_V71K, "4.1BSD"},
- {BSD_FS_V8, "Eighth Edition"},
- {BSD_FS_BSDFFS, "4.2BSD"},
-#ifdef __alpha__
- {BSD_FS_EXT2, "ext2"},
-#else
- {BSD_FS_MSDOS, "MS-DOS"},
-#endif
- {BSD_FS_BSDLFS, "4.4LFS"},
- {BSD_FS_OTHER, "unknown"},
- {BSD_FS_HPFS, "HPFS"},
- {BSD_FS_ISO9660,"ISO-9660"},
- {BSD_FS_BOOT, "boot"},
- {BSD_FS_ADOS, "ADOS"},
- {BSD_FS_HFS, "HFS"},
- {BSD_FS_ADVFS, "AdvFS"},
- { 0, NULL }
-};
-#define BSD_FSMAXTYPES (ARRAY_SIZE(xbsd_fstypes)-1)
-
-#endif
-
-/*
- * flags shared by various drives:
- */
-#define BSD_D_REMOVABLE 0x01 /* removable media */
-#define BSD_D_ECC 0x02 /* supports ECC */
-#define BSD_D_BADSECT 0x04 /* supports bad sector forw. */
-#define BSD_D_RAMDISK 0x08 /* disk emulator */
-#define BSD_D_CHAIN 0x10 /* can do back-back transfers */
-#define BSD_D_DOSPART 0x20 /* within MSDOS partition */
-
-extern void bsd_command_prompt(struct fdisk_context *cxt);
-extern int check_osf_label(struct fdisk_context *cxt);
-extern int btrydev(struct fdisk_context *cxt);
-extern void xbsd_print_disklabel(struct fdisk_context *cxt, int);
-
-#endif /* FDISK_BSD_LABEL_H */
diff --git a/fdisk/fdiskdoslabel.c b/fdisk/fdiskdoslabel.c
deleted file mode 100644
index a72a432c1..000000000
--- a/fdisk/fdiskdoslabel.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * Many, many hands.
- * Specific DOS label file - Davidlohr Bueso <dave@gnu.org>
- */
-
-#include <unistd.h>
-#include <ctype.h>
-
-#include "nls.h"
-#include "xalloc.h"
-#include "randutils.h"
-#include "common.h"
-#include "fdisk.h"
-#include "fdiskdoslabel.h"
-
-#define set_hsc(h,s,c,sector) { \
- s = sector % cxt->geom.sectors + 1; \
- sector /= cxt->geom.sectors; \
- h = sector % cxt->geom.heads; \
- sector /= cxt->geom.heads; \
- c = sector & 0xff; \
- s |= (sector >> 2) & 0xc0; \
- }
-
-#define alignment_required (grain != cxt->sector_size)
-
-struct pte ptes[MAXIMUM_PARTS];
-sector_t extended_offset;
-int ext_index;
-
-static int get_nonexisting_partition(struct fdisk_context *cxt, int warn, int max)
-{
- int pno = -1;
- int i;
- int dflt = 0;
-
- for (i = 0; i < max; i++) {
- struct pte *pe = &ptes[i];
- struct partition *p = pe->part_table;
-
- if (p && is_cleared_partition(p)) {
- if (pno >= 0) {
- dflt = pno + 1;
- goto not_unique;
- }
- pno = i;
- }
- }
- if (pno >= 0) {
- printf(_("Selected partition %d\n"), pno+1);
- return pno;
- }
- printf(_("All primary partitions have been defined already!\n"));
- return -1;
-
- not_unique:
- return get_partition_dflt(cxt, warn, max, dflt);
-}
-
-
-/* Allocate a buffer and read a partition table sector */
-static void read_pte(struct fdisk_context *cxt, int pno, sector_t offset)
-{
- struct pte *pe = &ptes[pno];
-
- pe->offset = offset;
- pe->sectorbuffer = xmalloc(cxt->sector_size);
- read_sector(cxt, offset, pe->sectorbuffer);
- pe->changed = 0;
- pe->part_table = pe->ext_pointer = NULL;
-}
-
-static void dos_write_mbr_id(unsigned char *b, unsigned int id)
-{
- store4_little_endian(&b[440], id);
-}
-
-static unsigned int dos_read_mbr_id(const unsigned char *b)
-{
- return read4_little_endian(&b[440]);
-}
-
-static void clear_partition(struct partition *p)
-{
- if (!p)
- return;
- p->boot_ind = 0;
- p->head = 0;
- p->sector = 0;
- p->cyl = 0;
- p->sys_ind = 0;
- p->end_head = 0;
- p->end_sector = 0;
- p->end_cyl = 0;
- set_start_sect(p,0);
- set_nr_sects(p,0);
-}
-
-void dos_init(struct fdisk_context *cxt)
-{
- int i;
-
- disklabel = DOS_LABEL;
- partitions = 4;
- ext_index = 0;
- extended_offset = 0;
-
- for (i = 0; i < 4; i++) {
- struct pte *pe = &ptes[i];
-
- pe->part_table = pt_offset(cxt->mbr, i);
- pe->ext_pointer = NULL;
- pe->offset = 0;
- pe->sectorbuffer = cxt->mbr;
- pe->changed = 0;
- }
-
- warn_geometry(cxt);
- warn_limits(cxt);
- warn_alignment(cxt);
-}
-
-static void read_extended(struct fdisk_context *cxt, int ext)
-{
- int i;
- struct pte *pex;
- struct partition *p, *q;
-
- ext_index = ext;
- pex = &ptes[ext];
- pex->ext_pointer = pex->part_table;
-
- p = pex->part_table;
- if (!get_start_sect(p)) {
- fprintf(stderr,
- _("Bad offset in primary extended partition\n"));
- return;
- }
-
- while (IS_EXTENDED (p->sys_ind)) {
- struct pte *pe = &ptes[partitions];
-
- if (partitions >= MAXIMUM_PARTS) {
- /* This is not a Linux restriction, but
- this program uses arrays of size MAXIMUM_PARTS.
- Do not try to `improve' this test. */
- struct pte *pre = &ptes[partitions-1];
-
- fprintf(stderr,
- _("Warning: omitting partitions after #%d.\n"
- "They will be deleted "
- "if you save this partition table.\n"),
- partitions);
- clear_partition(pre->ext_pointer);
- pre->changed = 1;
- return;
- }
-
- read_pte(cxt, partitions, extended_offset + get_start_sect(p));
-
- if (!extended_offset)
- extended_offset = get_start_sect(p);
-
- q = p = pt_offset(pe->sectorbuffer, 0);
- for (i = 0; i < 4; i++, p++) if (get_nr_sects(p)) {
- if (IS_EXTENDED (p->sys_ind)) {
- if (pe->ext_pointer)
- fprintf(stderr,
- _("Warning: extra link "
- "pointer in partition table"
- " %d\n"), partitions + 1);
- else
- pe->ext_pointer = p;
- } else if (p->sys_ind) {
- if (pe->part_table)
- fprintf(stderr,
- _("Warning: ignoring extra "
- "data in partition table"
- " %d\n"), partitions + 1);
- else
- pe->part_table = p;
- }
- }
-
- /* very strange code here... */
- if (!pe->part_table) {
- if (q != pe->ext_pointer)
- pe->part_table = q;
- else
- pe->part_table = q + 1;
- }
- if (!pe->ext_pointer) {
- if (q != pe->part_table)
- pe->ext_pointer = q;
- else
- pe->ext_pointer = q + 1;
- }
-
- p = pe->ext_pointer;
- partitions++;
- }
-
- /* remove empty links */
- remove:
- for (i = 4; i < partitions; i++) {
- struct pte *pe = &ptes[i];
-
- if (!get_nr_sects(pe->part_table) &&
- (partitions > 5 || ptes[4].part_table->sys_ind)) {
- printf(_("omitting empty partition (%d)\n"), i+1);
- dos_delete_partition(i);
- goto remove; /* numbering changed */
- }
- }
-}
-
-void dos_print_mbr_id(struct fdisk_context *cxt)
-{
- printf(_("Disk identifier: 0x%08x\n"), dos_read_mbr_id(cxt->mbr));
-}
-
-void create_doslabel(struct fdisk_context *cxt)
-{
- unsigned int id;
-
- /* random disk signature */
- random_get_bytes(&id, sizeof(id));
-
- fprintf(stderr, _("Building a new DOS disklabel with disk identifier 0x%08x.\n"), id);
-
- dos_init(cxt);
- fdisk_mbr_zeroize(cxt);
- set_all_unchanged();
- set_changed(0);
-
- /* Generate an MBR ID for this disk */
- dos_write_mbr_id(cxt->mbr, id);
-
- /* Put MBR signature */
- write_part_table_flag(cxt->mbr);
-}
-
-void dos_set_mbr_id(struct fdisk_context *cxt)
-{
- unsigned long new_id;
- char *ep;
- char ps[64];
-
- snprintf(ps, sizeof ps, _("New disk identifier (current 0x%08x): "),
- dos_read_mbr_id(cxt->mbr));
-
- if (read_chars(ps) == '\n')
- return;
-
- new_id = strtoul(line_ptr, &ep, 0);
- if (*ep != '\n')
- return;
-
- dos_write_mbr_id(cxt->mbr, new_id);
- MBRbuffer_changed = 1;
- dos_print_mbr_id(cxt);
-}
-
-void dos_delete_partition(int i)
-{
- struct pte *pe = &ptes[i];
- struct partition *p = pe->part_table;
- struct partition *q = pe->ext_pointer;
-
- /* Note that for the fifth partition (i == 4) we don't actually
- decrement partitions. */
-
- if (i < 4) {
- if (IS_EXTENDED (p->sys_ind) && i == ext_index) {
- partitions = 4;
- ptes[ext_index].ext_pointer = NULL;
- extended_offset = 0;
- }
- clear_partition(p);
- } else if (!q->sys_ind && i > 4) {
- /* the last one in the chain - just delete */
- --partitions;
- --i;
- clear_partition(ptes[i].ext_pointer);
- ptes[i].changed = 1;
- } else {
- /* not the last one - further ones will be moved down */
- if (i > 4) {
- /* delete this link in the chain */
- p = ptes[i-1].ext_pointer;
- *p = *q;
- set_start_sect(p, get_start_sect(q));
- set_nr_sects(p, get_nr_sects(q));
- ptes[i-1].changed = 1;
- } else if (partitions > 5) { /* 5 will be moved to 4 */
- /* the first logical in a longer chain */
- struct pte *pe = &ptes[5];
-
- if (pe->part_table) /* prevent SEGFAULT */
- set_start_sect(pe->part_table,
- get_partition_start(pe) -
- extended_offset);
- pe->offset = extended_offset;
- pe->changed = 1;
- }
-
- if (partitions > 5) {
- partitions--;
- while (i < partitions) {
- ptes[i] = ptes[i+1];
- i++;
- }
- } else
- /* the only logical: clear only */
- clear_partition(ptes[i].part_table);
- }
-}
-
-int check_dos_label(struct fdisk_context *cxt)
-{
- int i;
-
- if (!valid_part_table_flag(cxt->mbr))
- return 0;
-
- dos_init(cxt);
-
- for (i = 0; i < 4; i++) {
- struct pte *pe = &ptes[i];
-
- if (IS_EXTENDED (pe->part_table->sys_ind)) {
- if (partitions != 4)
- fprintf(stderr, _("Ignoring extra extended "
- "partition %d\n"), i + 1);
- else
- read_extended(cxt, i);
- }
- }
-
- for (i = 3; i < partitions; i++) {
- struct pte *pe = &ptes[i];
-
- if (!valid_part_table_flag(pe->sectorbuffer)) {
- fprintf(stderr,
- _("Warning: invalid flag 0x%04x of partition "
- "table %d will be corrected by w(rite)\n"),
- part_table_flag(pe->sectorbuffer), i + 1);
- pe->changed = 1;
- }
- }
-
- return 1;
-}
-
-/*
- * Avoid warning about DOS partitions when no DOS partition was changed.
- * Here a heuristic "is probably dos partition".
- * We might also do the opposite and warn in all cases except
- * for "is probably nondos partition".
- */
-int is_dos_partition(int t)
-{
- return (t == 1 || t == 4 || t == 6 ||
- t == 0x0b || t == 0x0c || t == 0x0e ||
- t == 0x11 || t == 0x12 || t == 0x14 || t == 0x16 ||
- t == 0x1b || t == 0x1c || t == 0x1e || t == 0x24 ||
- t == 0xc1 || t == 0xc4 || t == 0xc6);
-}
-
-static void set_partition(struct fdisk_context *cxt,
- int i, int doext, sector_t start,
- sector_t stop, int sysid)
-{
- struct partition *p;
- sector_t offset;
-
- if (doext) {
- p = ptes[i].ext_pointer;
- offset = extended_offset;
- } else {
- p = ptes[i].part_table;
- offset = ptes[i].offset;
- }
- p->boot_ind = 0;
- p->sys_ind = sysid;
- set_start_sect(p, start - offset);
- set_nr_sects(p, stop - start + 1);
-
- if (!doext)
- print_partition_size(cxt, i + 1, start, stop, sysid);
-
- if (dos_compatible_flag && (start/(cxt->geom.sectors*cxt->geom.heads) > 1023))
- start = cxt->geom.heads*cxt->geom.sectors*1024 - 1;
- set_hsc(p->head, p->sector, p->cyl, start);
- if (dos_compatible_flag && (stop/(cxt->geom.sectors*cxt->geom.heads) > 1023))
- stop = cxt->geom.heads*cxt->geom.sectors*1024 - 1;
- set_hsc(p->end_head, p->end_sector, p->end_cyl, stop);
- ptes[i].changed = 1;
-}
-
-static sector_t get_unused_start(int part_n, sector_t start,
- sector_t first[], sector_t last[])
-{
- int i;
-
- for (i = 0; i < partitions; i++) {
- sector_t lastplusoff;
-
- if (start == ptes[i].offset)
- start += sector_offset;
- lastplusoff = last[i] + ((part_n < 4) ? 0 : sector_offset);
- if (start >= first[i] && start <= lastplusoff)
- start = lastplusoff + 1;
- }
-
- return start;
-}
-
-static sector_t align_lba_in_range(struct fdisk_context *cxt,
- sector_t lba, sector_t start, sector_t stop)
-{
- start = align_lba(cxt, start, ALIGN_UP);
- stop = align_lba(cxt, stop, ALIGN_DOWN);
-
- lba = align_lba(cxt, lba, ALIGN_NEAREST);
-
- if (lba < start)
- return start;
- else if (lba > stop)
- return stop;
- return lba;
-}
-
-void dos_add_partition(struct fdisk_context *cxt, int n, int sys)
-{
- char mesg[256]; /* 48 does not suffice in Japanese */
- int i, read = 0;
- struct partition *p = ptes[n].part_table;
- struct partition *q = ptes[ext_index].part_table;
- sector_t start, stop = 0, limit, temp,
- first[partitions], last[partitions];
-
- if (p && p->sys_ind) {
- printf(_("Partition %d is already defined. Delete "
- "it before re-adding it.\n"), n + 1);
- return;
- }
- fill_bounds(first, last);
- if (n < 4) {
- start = sector_offset;
- if (display_in_cyl_units || !cxt->total_sectors)
- limit = cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders - 1;
- else
- limit = cxt->total_sectors - 1;
-
- if (limit > UINT_MAX)
- limit = UINT_MAX;
-
- if (extended_offset) {
- first[ext_index] = extended_offset;
- last[ext_index] = get_start_sect(q) +
- get_nr_sects(q) - 1;
- }
- } else {
- start = extended_offset + sector_offset;
- limit = get_start_sect(q) + get_nr_sects(q) - 1;
- }
- if (display_in_cyl_units)
- for (i = 0; i < partitions; i++)
- first[i] = (cround(first[i]) - 1) * units_per_sector;
-
- snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
- do {
- sector_t dflt, aligned;
-
- temp = start;
- dflt = start = get_unused_start(n, start, first, last);
-
- /* the default sector should be aligned and unused */
- do {
- aligned = align_lba_in_range(cxt, dflt, dflt, limit);
- dflt = get_unused_start(n, aligned, first, last);
- } while (dflt != aligned && dflt > aligned && dflt < limit);
-
- if (dflt >= limit)
- dflt = start;
- if (start > limit)
- break;
- if (start >= temp+units_per_sector && read) {
- printf(_("Sector %llu is already allocated\n"), temp);
- temp = start;
- read = 0;
- }
- if (!read && start == temp) {
- sector_t i = start;
-
- start = read_int(cxt, cround(i), cround(dflt), cround(limit),
- 0, mesg);
- if (display_in_cyl_units) {
- start = (start - 1) * units_per_sector;
- if (start < i) start = i;
- }
- read = 1;
- }
- } while (start != temp || !read);
- if (n > 4) { /* NOT for fifth partition */
- struct pte *pe = &ptes[n];
-
- pe->offset = start - sector_offset;
- if (pe->offset == extended_offset) { /* must be corrected */
- pe->offset++;
- if (sector_offset == 1)
- start++;
- }
- }
-
- for (i = 0; i < partitions; i++) {
- struct pte *pe = &ptes[i];
-
- if (start < pe->offset && limit >= pe->offset)
- limit = pe->offset - 1;
- if (start < first[i] && limit >= first[i])
- limit = first[i] - 1;
- }
- if (start > limit) {
- printf(_("No free sectors available\n"));
- if (n > 4)
- partitions--;
- return;
- }
- if (cround(start) == cround(limit)) {
- stop = limit;
- } else {
- int is_suffix_used = 0;
-
- snprintf(mesg, sizeof(mesg),
- _("Last %1$s, +%2$s or +size{K,M,G}"),
- str_units(SINGULAR), str_units(PLURAL));
-
- stop = read_int_with_suffix(cxt,
- cround(start), cround(limit), cround(limit),
- cround(start), mesg, &is_suffix_used);
- if (display_in_cyl_units) {
- stop = stop * units_per_sector - 1;
- if (stop >limit)
- stop = limit;
- }
-
- if (is_suffix_used && alignment_required) {
- /* the last sector has not been exactly requested (but
- * defined by +size{K,M,G} convention), so be smart
- * and align the end of the partition. The next
- * partition will start at phy.block boundary.
- */
- stop = align_lba_in_range(cxt, stop, start, limit) - 1;
- if (stop > limit)
- stop = limit;
- }
- }
-
- set_partition(cxt, n, 0, start, stop, sys);
- if (n > 4)
- set_partition(cxt, n - 1, 1, ptes[n].offset, stop, EXTENDED);
-
- if (IS_EXTENDED (sys)) {
- struct pte *pe4 = &ptes[4];
- struct pte *pen = &ptes[n];
-
- ext_index = n;
- pen->ext_pointer = p;
- pe4->offset = extended_offset = start;
- pe4->sectorbuffer = xcalloc(1, cxt->sector_size);
- pe4->part_table = pt_offset(pe4->sectorbuffer, 0);
- pe4->ext_pointer = pe4->part_table + 1;
- pe4->changed = 1;
- partitions = 5;
- }
-}
-
-static void add_logical(struct fdisk_context *cxt)
-{
- if (partitions > 5 || ptes[4].part_table->sys_ind) {
- struct pte *pe = &ptes[partitions];
-
- pe->sectorbuffer = xcalloc(1, cxt->sector_size);
- pe->part_table = pt_offset(pe->sectorbuffer, 0);
- pe->ext_pointer = pe->part_table + 1;
- pe->offset = 0;
- pe->changed = 1;
- partitions++;
- }
- printf(_("Adding logical partition %d\n"), partitions);
- dos_add_partition(cxt, partitions - 1, LINUX_NATIVE);
-}
-
-/*
- * Ask the user for new partition type information (logical, extended).
- * This function calls the actual partition adding logic - dos_add_partition.
- */
-void dos_new_partition(struct fdisk_context *cxt)
-{
- int i, free_primary = 0;
-
- for (i = 0; i < 4; i++)
- free_primary += !ptes[i].part_table->sys_ind;
-
- if (!free_primary && partitions >= MAXIMUM_PARTS) {
- printf(_("The maximum number of partitions has been created\n"));
- return;
- }
-
- if (!free_primary) {
- if (extended_offset) {
- printf(_("All primary partitions are in use\n"));
- add_logical(cxt);
- } else
- printf(_("If you want to create more than four partitions, you must replace a\n"
- "primary partition with an extended partition first.\n"));
- } else if (partitions >= MAXIMUM_PARTS) {
- printf(_("All logical partitions are in use\n"));
- printf(_("Adding a primary partition\n"));
- dos_add_partition(cxt, get_partition(cxt, 0, 4), LINUX_NATIVE);
- } else {
- char c, dflt, line[LINE_LENGTH];
-
- dflt = (free_primary == 1 && !extended_offset) ? 'e' : 'p';
- snprintf(line, sizeof(line),
- _("Partition type:\n"
- " p primary (%d primary, %d extended, %d free)\n"
- "%s\n"
- "Select (default %c): "),
- 4 - (extended_offset ? 1 : 0) - free_primary, extended_offset ? 1 : 0, free_primary,
- extended_offset ? _(" l logical (numbered from 5)") : _(" e extended"),
- dflt);
-
- c = tolower(read_chars(line));
- if (c == '\n') {
- c = dflt;
- printf(_("Using default response %c\n"), c);
- }
- if (c == 'p') {
- int i = get_nonexisting_partition(cxt, 0, 4);
- if (i >= 0)
- dos_add_partition(cxt, i, LINUX_NATIVE);
- return;
- } else if (c == 'l' && extended_offset) {
- add_logical(cxt);
- return;
- } else if (c == 'e' && !extended_offset) {
- int i = get_nonexisting_partition(cxt, 0, 4);
- if (i >= 0)
- dos_add_partition(cxt, i, EXTENDED);
- return;
- } else
- printf(_("Invalid partition type `%c'\n"), c);
- }
-}
-
-void dos_write_table(struct fdisk_context *cxt)
-{
- int i;
-
- /* MBR (primary partitions) */
- if (!MBRbuffer_changed) {
- for (i = 0; i < 4; i++)
- if (ptes[i].changed)
- MBRbuffer_changed = 1;
- }
- if (MBRbuffer_changed) {
- write_part_table_flag(cxt->mbr);
- write_sector(cxt, 0, cxt->mbr);
- }
- /* EBR (logical partitions) */
- for (i = 4; i < partitions; i++) {
- struct pte *pe = &ptes[i];
-
- if (pe->changed) {
- write_part_table_flag(pe->sectorbuffer);
- write_sector(cxt, pe->offset, pe->sectorbuffer);
- }
- }
-}
diff --git a/fdisk/fdiskdoslabel.h b/fdisk/fdiskdoslabel.h
deleted file mode 100644
index f64a4cedd..000000000
--- a/fdisk/fdiskdoslabel.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef FDISK_DOS_LABEL_H
-#define FDISK_DOS_LABEL_H
-
-/*
- * per partition table entry data
- *
- * The four primary partitions have the same sectorbuffer (MBRbuffer)
- * and have NULL ext_pointer.
- * Each logical partition table entry has two pointers, one for the
- * partition and one link to the next one.
- */
-struct pte {
- struct partition *part_table; /* points into sectorbuffer */
- struct partition *ext_pointer; /* points into sectorbuffer */
- char changed; /* boolean */
- sector_t offset; /* disk sector number */
- unsigned char *sectorbuffer; /* disk sector contents */
-};
-
-extern struct pte ptes[MAXIMUM_PARTS];
-extern int dos_compatible_flag;
-
-#define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \
- (n) * sizeof(struct partition)))
-
-extern int ext_index; /* the prime extended partition */
-extern sector_t extended_offset, sector_offset;
-
-static inline void write_part_table_flag(unsigned char *b)
-{
- b[510] = 0x55;
- b[511] = 0xaa;
-}
-
-/* A valid partition table sector ends in 0x55 0xaa */
-static inline unsigned int part_table_flag(unsigned char *b)
-{
- return ((unsigned int) b[510]) + (((unsigned int) b[511]) << 8);
-}
-
-static inline sector_t get_partition_start(struct pte *pe)
-{
- return pe->offset + get_start_sect(pe->part_table);
-}
-
-extern void create_doslabel(struct fdisk_context *cxt);
-extern void dos_print_mbr_id(struct fdisk_context *cxt);
-extern void dos_set_mbr_id(struct fdisk_context *cxt);
-extern void dos_delete_partition(int i);
-extern int check_dos_label(struct fdisk_context *cxt);
-extern int is_dos_partition(int t);
-extern void dos_init(struct fdisk_context *cxt);
-extern void dos_add_partition(struct fdisk_context *cxt, int n, int sys);
-extern void dos_new_partition(struct fdisk_context *cxt);
-extern void dos_write_table(struct fdisk_context *cxt);
-
-#endif
diff --git a/fdisk/fdiskmaclabel.c b/fdisk/fdiskmaclabel.c
deleted file mode 100644
index 96fc7121e..000000000
--- a/fdisk/fdiskmaclabel.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- Changes:
- Sat Mar 20 09:51:38 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- Internationalization
-*/
-#include <stdio.h> /* stderr */
-#include <string.h> /* strstr */
-#include <unistd.h> /* write */
-
-#include <endian.h>
-
-#include "common.h"
-#include "fdisk.h"
-#include "fdiskmaclabel.h"
-#include "nls.h"
-
-#define MAC_BITMASK 0xffff0000
-
-
-static int other_endian = 0;
-static short volumes=1;
-
-/*
- * only dealing with free blocks here
- */
-
-static void
-mac_info( void ) {
- puts(
- _("\n\tThere is a valid Mac label on this disk.\n"
- "\tUnfortunately fdisk(1) cannot handle these disks.\n"
- "\tUse either pdisk or parted to modify the partition table.\n"
- "\tNevertheless some advice:\n"
- "\t1. fdisk will destroy its contents on write.\n"
- "\t2. Be sure that this disk is NOT a still vital\n"
- "\t part of a volume group. (Otherwise you may\n"
- "\t erase the other disks as well, if unmirrored.)\n")
- );
-}
-
-void
-mac_nolabel(struct fdisk_context *cxt)
-{
- maclabel->magic = 0;
- partitions = 4;
- fdisk_mbr_zeroize(cxt);
- return;
-}
-
-int
-check_mac_label(struct fdisk_context *cxt)
-{
- /*
- Conversion: only 16 bit should compared
- e.g.: HFS Label is only 16bit long
- */
- int magic_masked = 0 ;
- magic_masked = maclabel->magic & MAC_BITMASK ;
-
- switch (magic_masked) {
- case MAC_LABEL_MAGIC :
- case MAC_LABEL_MAGIC_2:
- case MAC_LABEL_MAGIC_3:
- goto IS_MAC;
- break;
- default:
- other_endian = 0;
- return 0;
-
-
- }
-
-IS_MAC:
- other_endian = (maclabel->magic == MAC_LABEL_MAGIC_SWAPPED); // =?
- update_units(cxt);
- disklabel = MAC_LABEL;
- partitions= 1016; // =?
- volumes = 15; // =?
- mac_info();
- mac_nolabel(cxt); /* %% */
- return 1;
-}
-
diff --git a/fdisk/fdiskmaclabel.h b/fdisk/fdiskmaclabel.h
deleted file mode 100644
index 4873dcdf0..000000000
--- a/fdisk/fdiskmaclabel.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef FDISK_MAC_LABEL_H
-#define FDISK_MAC_LABEL_H
-
-#include <sys/types.h>
-/*
- * Copyright (C) Andreas Neuper, Sep 1998.
- * This file may be redistributed under
- * the terms of the GNU Public License.
- */
-
-typedef struct {
- unsigned int magic; /* expect MAC_LABEL_MAGIC */
- unsigned int fillbytes1[124];
- unsigned int physical_volume_id;
- unsigned int fillbytes2[124];
-} mac_partition;
-
-/* MAC magic number only 16bits, do I always know that there are 0200
- * following? Problem, after magic the uint16_t res1; follows, I donnno know
- * about the 200k */
-#define MAC_LABEL_MAGIC 0x45520000
-#define MAC_LABEL_MAGIC_2 0x50530000
-#define MAC_LABEL_MAGIC_3 0x504d0000
-
-#define MAC_LABEL_MAGIC_SWAPPED 0x00002554
-
-#define MAC_LABEL_MAGIC_2_SWAPPED 0x00003505
-#define MAC_LABEL_MAGIC_3_SWAPPED 0x0000d405
-
-/* fdisk.c */
-#define maclabel ((mac_partition *)cxt->mbr)
-
-/* fdiskmaclabel.c */
-extern struct systypes mac_sys_types[];
-extern void mac_nolabel(struct fdisk_context *cxt);
-extern int check_mac_label(struct fdisk_context *cxt);
-
-#endif /* FDISK_MAC_LABEL_H */
-
diff --git a/fdisk/fdisksgilabel.c b/fdisk/fdisksgilabel.c
deleted file mode 100644
index c9033cb41..000000000
--- a/fdisk/fdisksgilabel.c
+++ /dev/null
@@ -1,879 +0,0 @@
-/*
- *
- * fdisksgilabel.c
- *
- * Copyright (C) Andreas Neuper, Sep 1998.
- * This file may be modified and redistributed under
- * the terms of the GNU Public License.
- *
- * 1999-03-20 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * Internationalization
- *
- * 2003-03-20 Phillip Kesling <pkesling@sgi.com>
- * Some fixes
- *
- * 2012-06-16 Davidlohr Bueso <dave@gnu.org>
- * Adapt to fdisk context and add heap sort for partitions
- */
-
-#include <stdio.h> /* stderr */
-#include <stdlib.h> /* exit */
-#include <string.h> /* strstr */
-#include <unistd.h> /* write */
-#include <sys/ioctl.h> /* ioctl */
-#include <sys/stat.h> /* stat */
-#include <assert.h> /* assert */
-
-#include <endian.h>
-#include "nls.h"
-#include "xalloc.h"
-
-#include "blkdev.h"
-
-#include "common.h"
-#include "fdisk.h"
-#include "fdisksgilabel.h"
-
-static int other_endian = 0;
-static int debug = 0;
-static short volumes=1;
-
-/*
- * only dealing with free blocks here
- */
-
-typedef struct { unsigned int first; unsigned int last; } freeblocks;
-static freeblocks freelist[17]; /* 16 partitions can produce 17 vacant slots */
-
-static void
-setfreelist(int i, unsigned int f, unsigned int l) {
- if (i < 17) {
- freelist[i].first = f;
- freelist[i].last = l;
- }
-}
-
-static void
-add2freelist(unsigned int f, unsigned int l) {
- int i = 0;
- for ( ; i < 17 ; i++)
- if (freelist[i].last == 0)
- break;
- setfreelist(i, f, l);
-}
-
-static void
-clearfreelist(void) {
- int i;
-
- for (i = 0; i < 17 ; i++)
- setfreelist(i, 0, 0);
-}
-
-static unsigned int
-isinfreelist(unsigned int b) {
- int i;
-
- for (i = 0; i < 17 ; i++)
- if (freelist[i].first <= b && freelist[i].last >= b)
- return freelist[i].last;
- return 0;
-}
- /* return last vacant block of this stride (never 0). */
- /* the '>=' is not quite correct, but simplifies the code */
-/*
- * end of free blocks section
- */
-struct systypes sgi_sys_types[] = {
- {SGI_VOLHDR, N_("SGI volhdr")},
- {0x01, N_("SGI trkrepl")},
- {0x02, N_("SGI secrepl")},
- {SGI_SWAP, N_("SGI raw")},
- {0x04, N_("SGI bsd")},
- {0x05, N_("SGI sysv")},
- {ENTIRE_DISK, N_("SGI volume")},
- {SGI_EFS, N_("SGI efs")},
- {0x08, N_("SGI lvol")},
- {0x09, N_("SGI rlvol")},
- {SGI_XFS, N_("SGI xfs")},
- {SGI_XFSLOG, N_("SGI xfslog")},
- {SGI_XLV, N_("SGI xlv")},
- {SGI_XVM, N_("SGI xvm")},
- {LINUX_SWAP, N_("Linux swap")},
- {LINUX_NATIVE, N_("Linux native")},
- {LINUX_LVM, N_("Linux LVM")},
- {LINUX_RAID, N_("Linux RAID")},
- {0, NULL }
-};
-
-static int
-sgi_get_nsect(struct fdisk_context *cxt) {
- return SSWAP16(sgilabel->devparam.nsect);
-}
-
-static int
-sgi_get_ntrks(struct fdisk_context *cxt) {
- return SSWAP16(sgilabel->devparam.ntrks);
-}
-
-static unsigned int
-two_s_complement_32bit_sum(unsigned int *base, int size /* in bytes */) {
- int i = 0;
- unsigned int sum = 0;
-
- size /= sizeof(unsigned int);
- for (i = 0; i < size; i++)
- sum -= SSWAP32(base[i]);
- return sum;
-}
-
-int
-check_sgi_label(struct fdisk_context *cxt) {
- if (sizeof(sgilabel) > 512) {
- fprintf(stderr,
- _("According to MIPS Computer Systems, Inc the "
- "Label must not contain more than 512 bytes\n"));
- exit(1);
- }
-
- if (sgilabel->magic != SGI_LABEL_MAGIC &&
- sgilabel->magic != SGI_LABEL_MAGIC_SWAPPED) {
- other_endian = 0;
- return 0;
- }
-
- other_endian = (sgilabel->magic == SGI_LABEL_MAGIC_SWAPPED);
- /*
- * test for correct checksum
- */
- if (two_s_complement_32bit_sum((unsigned int*)sgilabel,
- sizeof(*sgilabel))) {
- fprintf(stderr,
- _("Detected sgi disklabel with wrong checksum.\n"));
- }
- update_units(cxt);
- disklabel = SGI_LABEL;
- partitions= 16;
- volumes = 15;
- return 1;
-}
-
-void
-sgi_list_table(struct fdisk_context *cxt, int xtra) {
- int i, w;
- int kpi = 0; /* kernel partition ID */
- char *type;
-
- w = strlen(cxt->dev_path);
-
- if (xtra) {
- printf(_("\nDisk %s (SGI disk label): %d heads, %llu sectors\n"
- "%llu cylinders, %d physical cylinders\n"
- "%d extra sects/cyl, interleave %d:1\n"
- "%s\n"
- "Units = %s of %d * %ld bytes\n\n"),
- cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders,
- SSWAP16(sgiparam.pcylcount),
- (int) sgiparam.sparecyl, SSWAP16(sgiparam.ilfact),
- (char *)sgilabel,
- str_units(PLURAL), units_per_sector,
- cxt->sector_size);
- } else {
- printf(_("\nDisk %s (SGI disk label): "
- "%d heads, %llu sectors, %llu cylinders\n"
- "Units = %s of %d * %ld bytes\n\n"),
- cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders,
- str_units(PLURAL), units_per_sector,
- cxt->sector_size);
- }
- printf(_("----- partitions -----\n"
- "Pt# %*s Info Start End Sectors Id System\n"),
- w + 1, _("Device"));
- for (i = 0 ; i < partitions; i++) {
- if (sgi_get_num_sectors(cxt, i) || debug) {
- uint32_t start = sgi_get_start_sector(cxt, i);
- uint32_t len = sgi_get_num_sectors(cxt, i);
- kpi++; /* only count nonempty partitions */
- printf(
- "%2d: %s %4s %9ld %9ld %9ld %2x %s\n",
-/* fdisk part number */ i+1,
-/* device */ partname(cxt->dev_path, kpi, w+2),
-/* flags */ (sgi_get_swappartition(cxt) == i) ? "swap" :
-/* flags */ (sgi_get_bootpartition(cxt) == i) ? "boot" : " ",
-/* start */ (long) scround(start),
-/* end */ (long) scround(start+len)-1,
-/* no odd flag on end */ (long) len,
-/* type id */ sgi_get_sysid(cxt, i),
-/* type name */ (type = partition_type(sgi_get_sysid(cxt, i)))
- ? type : _("Unknown"));
- }
- }
- printf(_("----- Bootinfo -----\nBootfile: %s\n"
- "----- Directory Entries -----\n"),
- sgilabel->boot_file);
- for (i = 0 ; i < volumes; i++) {
- if (sgilabel->directory[i].vol_file_size) {
- uint32_t start = SSWAP32(sgilabel->directory[i].vol_file_start);
- uint32_t len = SSWAP32(sgilabel->directory[i].vol_file_size);
- unsigned char *name = sgilabel->directory[i].vol_file_name;
- printf(_("%2d: %-10s sector%5u size%8u\n"),
- i, name, (unsigned int) start,
- (unsigned int) len);
- }
- }
-}
-
-unsigned int
-sgi_get_start_sector(struct fdisk_context *cxt, int i) {
- return SSWAP32(sgilabel->partitions[i].start_sector);
-}
-
-unsigned int
-sgi_get_num_sectors(struct fdisk_context *cxt, int i) {
- return SSWAP32(sgilabel->partitions[i].num_sectors);
-}
-
-int
-sgi_get_sysid(struct fdisk_context *cxt, int i)
-{
- return SSWAP32(sgilabel->partitions[i].id);
-}
-
-int
-sgi_get_bootpartition(struct fdisk_context *cxt)
-{
- return (short) SSWAP16(sgilabel->boot_part);
-}
-
-int
-sgi_get_swappartition(struct fdisk_context *cxt)
-{
- return (short) SSWAP16(sgilabel->swap_part);
-}
-
-void
-sgi_set_bootpartition(struct fdisk_context *cxt, int i)
-{
- sgilabel->boot_part = SSWAP16(((short)i));
-}
-
-static unsigned int
-sgi_get_lastblock(struct fdisk_context *cxt) {
- return cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders;
-}
-
-void
-sgi_set_swappartition(struct fdisk_context *cxt, int i) {
- sgilabel->swap_part = SSWAP16(((short)i));
-}
-
-static int
-sgi_check_bootfile(struct fdisk_context *cxt, const char* aFile) {
- if (strlen(aFile) < 3) /* "/a\n" is minimum */ {
- printf(_("\nInvalid Bootfile!\n"
- "\tThe bootfile must be an absolute non-zero pathname,\n"
- "\te.g. \"/unix\" or \"/unix.save\".\n"));
- return 0;
- } else {
- if (strlen(aFile) > 16) {
- printf(_("\n\tName of Bootfile too long: "
- "16 bytes maximum.\n"));
- return 0;
- } else {
- if (aFile[0] != '/') {
- printf(_("\n\tBootfile must have a "
- "fully qualified pathname.\n"));
- return 0;
- }
- }
- }
- if (strncmp(aFile, (char *) sgilabel->boot_file, 16)) {
- printf(_("\n\tBe aware, that the bootfile is not checked for existence.\n\t"
- "SGI's default is \"/unix\" and for backup \"/unix.save\".\n"));
- /* filename is correct and did change */
- return 1;
- }
- return 0; /* filename did not change */
-}
-
-void
-sgi_set_bootfile(struct fdisk_context *cxt)
-{
- printf(_("\nThe current boot file is: %s\n"), sgilabel->boot_file);
- if (read_chars(_("Please enter the name of the new boot file: ")) == '\n') {
- printf(_("Boot file unchanged\n"));
- return;
- }
-
- if (sgi_check_bootfile(cxt, line_ptr)) {
- size_t i = 0;
- while (i < 16) {
- if ((line_ptr[i] != '\n') /* in principle caught again by next line */
- && (strlen(line_ptr) > i))
- sgilabel->boot_file[i] = line_ptr[i];
- else
- sgilabel->boot_file[i] = 0;
- i++;
- }
- printf(_("\n\tBootfile is changed to \"%s\".\n"),
- sgilabel->boot_file);
- }
-}
-
-void
-create_sgiinfo(struct fdisk_context *cxt) {
- /* I keep SGI's habit to write the sgilabel to the second block */
- sgilabel->directory[0].vol_file_start = SSWAP32(2);
- sgilabel->directory[0].vol_file_size = SSWAP32(sizeof(sgiinfo));
- strncpy((char *) sgilabel->directory[0].vol_file_name, "sgilabel", 8);
-}
-
-sgiinfo *fill_sgiinfo(void);
-
-void
-sgi_write_table(struct fdisk_context *cxt) {
- sgilabel->csum = 0;
- sgilabel->csum = SSWAP32(two_s_complement_32bit_sum(
- (unsigned int*)sgilabel,
- sizeof(*sgilabel)));
- assert(two_s_complement_32bit_sum(
- (unsigned int*)sgilabel, sizeof(*sgilabel)) == 0);
- if (lseek(cxt->dev_fd, 0, SEEK_SET) < 0)
- fatal(cxt, unable_to_seek);
- if (write(cxt->dev_fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE)
- fatal(cxt, unable_to_write);
- if (! strncmp((char *) sgilabel->directory[0].vol_file_name, "sgilabel", 8)) {
- /*
- * keep this habit of first writing the "sgilabel".
- * I never tested whether it works without (AN 981002).
- */
- sgiinfo *info = fill_sgiinfo();
- int infostartblock = SSWAP32(sgilabel->directory[0].vol_file_start);
- if (lseek(cxt->dev_fd, (off_t) infostartblock*
- SECTOR_SIZE, SEEK_SET) < 0)
- fatal(cxt, unable_to_seek);
- if (write(cxt->dev_fd, info, SECTOR_SIZE) != SECTOR_SIZE)
- fatal(cxt, unable_to_write);
- free(info);
- }
-}
-
-static int
-compare_start(struct fdisk_context *cxt, const void *x, const void *y) {
- /*
- * sort according to start sectors
- * and prefers largest partition:
- * entry zero is entire disk entry
- */
- unsigned int i = *(int *) x;
- unsigned int j = *(int *) y;
- unsigned int a = sgi_get_start_sector(cxt, i);
- unsigned int b = sgi_get_start_sector(cxt, j);
- unsigned int c = sgi_get_num_sectors(cxt, i);
- unsigned int d = sgi_get_num_sectors(cxt, j);
-
- if (a == b)
- return (d > c) ? 1 : (d == c) ? 0 : -1;
- return (a > b) ? 1 : -1;
-}
-
-static int
-sgi_gaps(struct fdisk_context *cxt) {
- /*
- * returned value is:
- * = 0 : disk is properly filled to the rim
- * < 0 : there is an overlap
- * > 0 : there is still some vacant space
- */
- return verify_sgi(cxt, 0);
-}
-
-static void generic_swap(void *a, void *b, int size)
-{
- char t;
-
- do {
- t = *(char *)a;
- *(char *)a++ = *(char *)b;
- *(char *)b++ = t;
- } while (--size > 0);
-}
-
-
-/* heap sort, based on Matt Mackall's linux kernel version */
-static void sort(void *base, size_t num, size_t size, struct fdisk_context *cxt,
- int (*cmp_func)(struct fdisk_context *, const void *, const void *))
-{
- /* pre-scale counters for performance */
- int i = (num/2 - 1) * size;
- size_t n = num * size, c, r;
-
- /* heapify */
- for ( ; i >= 0; i -= size) {
- for (r = i; r * 2 + size < n; r = c) {
- c = r * 2 + size;
- if (c < n - size &&
- cmp_func(cxt, base + c, base + c + size) < 0)
- c += size;
- if (cmp_func(cxt, base + r, base + c) >= 0)
- break;
- generic_swap(base + r, base + c, size);
- }
- }
-
- /* sort */
- for (i = n - size; i > 0; i -= size) {
- generic_swap(base, base + i, size);
- for (r = 0; r * 2 + size < (size_t) i; r = c) {
- c = r * 2 + size;
- if (c < i - size &&
- cmp_func(cxt, base + c, base + c + size) < 0)
- c += size;
- if (cmp_func(cxt, base + r, base + c) >= 0)
- break;
- generic_swap(base + r, base + c, size);
- }
- }
-}
-
-
-int
-verify_sgi(struct fdisk_context *cxt, int verbose)
-{
- int Index[16]; /* list of valid partitions */
- int sortcount = 0; /* number of used partitions, i.e. non-zero lengths */
- int entire = 0, i = 0;
- unsigned int start = 0;
- long long gap = 0; /* count unused blocks */
- unsigned int lastblock = sgi_get_lastblock(cxt);
-
- clearfreelist();
- for (i=0; i<16; i++) {
- if (sgi_get_num_sectors(cxt, i) != 0) {
- Index[sortcount++]=i;
- if (sgi_get_sysid(cxt, i) == ENTIRE_DISK) {
- if (entire++ == 1) {
- if (verbose)
- printf(_("More than one entire disk entry present.\n"));
- }
- }
- }
- }
- if (sortcount == 0) {
- if (verbose)
- printf(_("No partitions defined\n"));
- return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1;
- }
-
- sort(Index, sortcount, sizeof(Index[0]), cxt, compare_start);
-
- if (sgi_get_sysid(cxt, Index[0]) == ENTIRE_DISK) {
- if ((Index[0] != 10) && verbose)
- printf(_("IRIX likes when Partition 11 covers the entire disk.\n"));
- if ((sgi_get_start_sector(cxt, Index[0]) != 0) && verbose)
- printf(_("The entire disk partition should start "
- "at block 0,\n"
- "not at diskblock %d.\n"),
- sgi_get_start_sector(cxt, Index[0]));
- if (debug) /* I do not understand how some disks fulfil it */
- if ((sgi_get_num_sectors(cxt, Index[0]) != lastblock) && verbose)
- printf(_("The entire disk partition is only %d diskblock large,\n"
- "but the disk is %d diskblocks long.\n"),
- sgi_get_num_sectors(cxt, Index[0]), lastblock);
- lastblock = sgi_get_num_sectors(cxt, Index[0]);
- } else {
- if (verbose)
- printf(_("Partition 11 should cover the entire disk.\n"));
- if (debug>2)
- printf("sysid=%d\tpartition=%d\n",
- sgi_get_sysid(cxt, Index[0]), Index[0]+1);
- }
- for (i=1, start=0; i<sortcount; i++) {
- int cylsize = sgi_get_nsect(cxt) * sgi_get_ntrks(cxt);
- if ((sgi_get_start_sector(cxt, Index[i]) % cylsize) != 0) {
- if (debug) /* I do not understand how some disks fulfil it */
- if (verbose)
- printf(_("Partition %d does not start on cylinder boundary.\n"),
- Index[i]+1);
- }
- if (sgi_get_num_sectors(cxt, Index[i]) % cylsize != 0) {
- if (debug) /* I do not understand how some disks fulfil it */
- if (verbose)
- printf(_("Partition %d does not end on cylinder boundary.\n"),
- Index[i]+1);
- }
- /* We cannot handle several "entire disk" entries. */
- if (sgi_get_sysid(cxt, Index[i]) == ENTIRE_DISK) continue;
- if (start > sgi_get_start_sector(cxt, Index[i])) {
- if (verbose)
- printf(_("The Partition %d and %d overlap by %d sectors.\n"),
- Index[i-1]+1, Index[i]+1,
- start - sgi_get_start_sector(cxt, Index[i]));
- if (gap > 0) gap = -gap;
- if (gap == 0) gap = -1;
- }
- if (start < sgi_get_start_sector(cxt, Index[i])) {
- if (verbose)
- printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"),
- sgi_get_start_sector(cxt, Index[i]) - start,
- start, sgi_get_start_sector(cxt, Index[i])-1);
- gap += sgi_get_start_sector(cxt, Index[i]) - start;
- add2freelist(start, sgi_get_start_sector(cxt, Index[i]));
- }
- start = sgi_get_start_sector(cxt, Index[i])
- + sgi_get_num_sectors(cxt, Index[i]);
- /* Align free space on cylinder boundary */
- if (start % cylsize)
- start += cylsize - (start % cylsize);
- if (debug > 1) {
- if (verbose)
- printf("%2d:%12d\t%12d\t%12d\n", Index[i],
- sgi_get_start_sector(cxt, Index[i]),
- sgi_get_num_sectors(cxt, Index[i]),
- sgi_get_sysid(cxt, Index[i]));
- }
- }
- if (start < lastblock) {
- if (verbose)
- printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"),
- lastblock - start, start, lastblock-1);
- gap += lastblock - start;
- add2freelist(start, lastblock);
- }
- /*
- * Done with arithmetics
- * Go for details now
- */
- if (verbose) {
- if (sgi_get_bootpartition(cxt) < 0 || !sgi_get_num_sectors(cxt, sgi_get_bootpartition(cxt))) {
- printf(_("\nThe boot partition does not exist.\n"));
- }
- if (sgi_get_swappartition(cxt) < 0 || !sgi_get_num_sectors(cxt, sgi_get_swappartition(cxt))) {
- printf(_("\nThe swap partition does not exist.\n"));
- } else {
- if ((sgi_get_sysid(cxt, sgi_get_swappartition(cxt)) != SGI_SWAP)
- && (sgi_get_sysid(cxt, sgi_get_swappartition(cxt)) != LINUX_SWAP))
- printf(_("\nThe swap partition has no swap type.\n"));
- }
- if (sgi_check_bootfile(cxt, "/unix"))
- printf(_("\tYou have chosen an unusual boot file name.\n"));
- }
- return (gap > 0) ? 1 : (gap == 0) ? 0 : -1;
-}
-
-int
-sgi_change_sysid(struct fdisk_context *cxt, int i, int sys)
-{
- if (sgi_get_num_sectors(cxt, i) == 0) /* caught already before, ... */ {
- printf(_("Sorry, only for non-empty partitions you can change the tag.\n"));
- return 0;
- }
- if (((sys != ENTIRE_DISK) && (sys != SGI_VOLHDR))
- && (sgi_get_start_sector(cxt, i)<1)) {
- read_chars(
- _("It is highly recommended that the partition at offset 0\n"
- "is of type \"SGI volhdr\", the IRIX system will rely on it to\n"
- "retrieve from its directory standalone tools like sash and fx.\n"
- "Only the \"SGI volume\" entire disk section may violate this.\n"
- "Type YES if you are sure about tagging this partition differently.\n"));
- if (strcmp (line_ptr, _("YES\n")))
- return 0;
- }
- sgilabel->partitions[i].id = SSWAP32(sys);
- return 1;
-}
-
-/* returns partition index of first entry marked as entire disk */
-static int
-sgi_entire(struct fdisk_context *cxt) {
- int i;
-
- for (i=0; i<16; i++)
- if (sgi_get_sysid(cxt, i) == SGI_VOLUME)
- return i;
- return -1;
-}
-
-static void
-sgi_set_partition(struct fdisk_context *cxt,
- int i, unsigned int start, unsigned int length, int sys) {
- sgilabel->partitions[i].id = SSWAP32(sys);
- sgilabel->partitions[i].num_sectors = SSWAP32(length);
- sgilabel->partitions[i].start_sector = SSWAP32(start);
- set_changed(i);
- if (sgi_gaps(cxt) < 0) /* rebuild freelist */
- printf(_("Partition overlap on the disk.\n"));
- if (length)
- print_partition_size(cxt, i + 1, start, start + length, sys);
-}
-
-static void
-sgi_set_entire(struct fdisk_context *cxt) {
- int n;
-
- for (n=10; n<partitions; n++) {
- if (!sgi_get_num_sectors(cxt, n)) {
- sgi_set_partition(cxt, n, 0, sgi_get_lastblock(cxt), SGI_VOLUME);
- break;
- }
- }
-}
-
-static
-void
-sgi_set_volhdr(struct fdisk_context *cxt)
-{
- int n;
-
- for (n=8; n<partitions; n++) {
- if (!sgi_get_num_sectors(cxt, n)) {
- /*
- * Choose same default volume header size
- * as IRIX fx uses.
- */
- if (4096 < sgi_get_lastblock(cxt))
- sgi_set_partition(cxt, n, 0, 4096, SGI_VOLHDR);
- break;
- }
- }
-}
-
-void
-sgi_delete_partition(struct fdisk_context *cxt, int i)
-{
- sgi_set_partition(cxt, i, 0, 0, 0);
-}
-
-void
-sgi_add_partition(struct fdisk_context *cxt, int n, int sys)
-{
- char mesg[256];
- unsigned int first=0, last=0;
-
- if (n == 10) {
- sys = SGI_VOLUME;
- } else if (n == 8) {
- sys = 0;
- }
- if (sgi_get_num_sectors(cxt, n)) {
- printf(_("Partition %d is already defined. Delete "
- "it before re-adding it.\n"), n + 1);
- return;
- }
- if ((sgi_entire(cxt) == -1)
- && (sys != SGI_VOLUME)) {
- printf(_("Attempting to generate entire disk entry automatically.\n"));
- sgi_set_entire(cxt);
- sgi_set_volhdr(cxt);
- }
- if ((sgi_gaps(cxt) == 0) && (sys != SGI_VOLUME)) {
- printf(_("The entire disk is already covered with partitions.\n"));
- return;
- }
- if (sgi_gaps(cxt) < 0) {
- printf(_("You got a partition overlap on the disk. Fix it first!\n"));
- return;
- }
- snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
- for (;;) {
- if (sys == SGI_VOLUME) {
- last = sgi_get_lastblock(cxt);
- first = read_int(cxt, 0, 0, last-1, 0, mesg);
- if (first != 0) {
- printf(_("It is highly recommended that eleventh partition\n"
- "covers the entire disk and is of type `SGI volume'\n"));
- }
- } else {
- first = freelist[0].first;
- last = freelist[0].last;
- first = read_int(cxt, scround(first), scround(first), scround(last)-1,
- 0, mesg);
- }
- if (display_in_cyl_units)
- first *= units_per_sector;
- /*else
- first = first; * align to cylinder if you know how ... */
- if (!last)
- last = isinfreelist(first);
- if (last == 0) {
- printf(_("You will get a partition overlap on the disk. "
- "Fix it first!\n"));
- } else
- break;
- }
- snprintf(mesg, sizeof(mesg), _(" Last %s"), str_units(SINGULAR));
- last = read_int(cxt, scround(first), scround(last)-1, scround(last)-1,
- scround(first), mesg)+1;
- if (display_in_cyl_units)
- last *= units_per_sector;
- /*else
- last = last; * align to cylinder if You know how ... */
- if ((sys == SGI_VOLUME) && (first != 0 || last != sgi_get_lastblock(cxt)))
- printf(_("It is highly recommended that eleventh partition\n"
- "covers the entire disk and is of type `SGI volume'\n"));
- sgi_set_partition(cxt, n, first, last-first, sys);
-}
-
-void
-create_sgilabel(struct fdisk_context *cxt)
-{
- struct hd_geometry geometry;
- struct {
- unsigned int start;
- unsigned int nsect;
- int sysid;
- } old[4];
- int i=0;
- sector_t llsectors;
- int res; /* the result from the ioctl */
- int sec_fac; /* the sector factor */
-
- sec_fac = cxt->sector_size / 512; /* determine the sector factor */
-
- fprintf(stderr,
- _("Building a new SGI disklabel.\n"));
-
- other_endian = (BYTE_ORDER == LITTLE_ENDIAN);
-
- res = blkdev_get_sectors(cxt->dev_fd, &llsectors);
-
-#ifdef HDIO_GETGEO
- if (ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry) < 0)
- err(EXIT_FAILURE, _("HDIO_GETGEO ioctl failed on %s"), cxt->dev_path);
-
- cxt->geom.heads = geometry.heads;
- cxt->geom.sectors = geometry.sectors;
- if (res == 0) {
- /* the get device size ioctl was successful */
- sector_t llcyls;
- llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac);
- cxt->geom.cylinders = llcyls;
- if (cxt->geom.cylinders != llcyls) /* truncated? */
- cxt->geom.cylinders = ~0;
- } else {
- /* otherwise print error and use truncated version */
- cxt->geom.cylinders = geometry.cylinders;
- fprintf(stderr,
- _("Warning: BLKGETSIZE ioctl failed on %s. "
- "Using geometry cylinder value of %llu.\n"
- "This value may be truncated for devices"
- " > 33.8 GB.\n"), cxt->dev_path, cxt->geom.cylinders);
- }
-#endif
- for (i = 0; i < 4; i++) {
- old[i].sysid = 0;
- if (valid_part_table_flag(cxt->mbr)) {
- if (get_part_table(i)->sys_ind) {
- old[i].sysid = get_part_table(i)->sys_ind;
- old[i].start = get_start_sect(get_part_table(i));
- old[i].nsect = get_nr_sects(get_part_table(i));
- if (debug)
- printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"),
- old[i].sysid, old[i].start, old[i].nsect);
- }
- }
- }
-
- for (i = 0; i < 4; i++)
- if (old[i].sysid) {
- printf(_("Trying to keep parameters of partitions already set.\n"));
- break;
- }
-
- fdisk_mbr_zeroize(cxt);
- sgilabel->magic = SSWAP32(SGI_LABEL_MAGIC);
- sgilabel->boot_part = SSWAP16(0);
- sgilabel->swap_part = SSWAP16(1);
-
- /* sizeof(sgilabel->boot_file) = 16 > 6 */
- memset(sgilabel->boot_file, 0, 16);
- strcpy((char *) sgilabel->boot_file, "/unix");
-
- sgilabel->devparam.skew = (0);
- sgilabel->devparam.gap1 = (0);
- sgilabel->devparam.gap2 = (0);
- sgilabel->devparam.sparecyl = (0);
- sgilabel->devparam.pcylcount = SSWAP16(geometry.cylinders);
- sgilabel->devparam.head_vol0 = SSWAP16(0);
- sgilabel->devparam.ntrks = SSWAP16(geometry.heads);
- /* tracks/cylinder (heads) */
- sgilabel->devparam.cmd_tag_queue_depth = (0);
- sgilabel->devparam.unused0 = (0);
- sgilabel->devparam.unused1 = SSWAP16(0);
- sgilabel->devparam.nsect = SSWAP16(geometry.sectors);
- /* sectors/track */
- sgilabel->devparam.bytes = SSWAP16(cxt->sector_size);
- sgilabel->devparam.ilfact = SSWAP16(1);
- sgilabel->devparam.flags = SSWAP32(TRACK_FWD|\
- IGNORE_ERRORS|RESEEK);
- sgilabel->devparam.datarate = SSWAP32(0);
- sgilabel->devparam.retries_on_error = SSWAP32(1);
- sgilabel->devparam.ms_per_word = SSWAP32(0);
- sgilabel->devparam.xylogics_gap1 = SSWAP16(0);
- sgilabel->devparam.xylogics_syncdelay = SSWAP16(0);
- sgilabel->devparam.xylogics_readdelay = SSWAP16(0);
- sgilabel->devparam.xylogics_gap2 = SSWAP16(0);
- sgilabel->devparam.xylogics_readgate = SSWAP16(0);
- sgilabel->devparam.xylogics_writecont = SSWAP16(0);
- memset(&(sgilabel->directory), 0, sizeof(struct volume_directory)*15);
- memset(&(sgilabel->partitions), 0, sizeof(struct sgi_partition)*16);
- disklabel = SGI_LABEL;
- partitions = 16;
- volumes = 15;
- sgi_set_entire(cxt);
- sgi_set_volhdr(cxt);
- for (i = 0; i < 4; i++) {
- if (old[i].sysid) {
- sgi_set_partition(cxt, i, old[i].start, old[i].nsect, old[i].sysid);
- }
- }
-}
-
-void
-sgi_set_ilfact(void)
-{
- /* do nothing in the beginning */
-}
-
-void
-sgi_set_rspeed(void)
-{
- /* do nothing in the beginning */
-}
-
-void
-sgi_set_pcylcount(void)
-{
- /* do nothing in the beginning */
-}
-
-void
-sgi_set_xcyl(void)
-{
- /* do nothing in the beginning */
-}
-
-void
-sgi_set_ncyl(void)
-{
- /* do nothing in the beginning */
-}
-
-/* _____________________________________________________________
- */
-
-sgiinfo *
-fill_sgiinfo(void)
-{
- sgiinfo *info=xcalloc(1, sizeof(sgiinfo));
- info->magic=SSWAP32(SGI_INFO_MAGIC);
- info->b1=SSWAP32(-1);
- info->b2=SSWAP16(-1);
- info->b3=SSWAP16(1);
- /* You may want to replace this string !!!!!!! */
- strcpy((char *) info->scsi_string, "IBM OEM 0662S12 3 30");
- strcpy((char *) info->serial, "0000");
- info->check1816 = SSWAP16(18*256 +16);
- strcpy((char *) info->installer, "Sfx version 5.3, Oct 18, 1994");
- return info;
-}
diff --git a/fdisk/fdisksgilabel.h b/fdisk/fdisksgilabel.h
deleted file mode 100644
index 0c76edb91..000000000
--- a/fdisk/fdisksgilabel.h
+++ /dev/null
@@ -1,137 +0,0 @@
-#ifndef FDISK_SGI_LABEL_H
-#define FDISK_SGI_LABEL_H
-
-#include <stdint.h>
-
-#include "bitops.h"
-
-/*
- * Copyright (C) Andreas Neuper, Sep 1998.
- * This file may be modified and redistributed under
- * the terms of the GNU Public License.
- */
-
-struct device_parameter { /* 48 bytes */
- unsigned char skew;
- unsigned char gap1;
- unsigned char gap2;
- unsigned char sparecyl;
- unsigned short pcylcount;
- unsigned short head_vol0;
- unsigned short ntrks; /* tracks in cyl 0 or vol 0 */
- unsigned char cmd_tag_queue_depth;
- unsigned char unused0;
- unsigned short unused1;
- unsigned short nsect; /* sectors/tracks in cyl 0 or vol 0 */
- unsigned short bytes;
- unsigned short ilfact;
- unsigned int flags; /* controller flags */
- unsigned int datarate;
- unsigned int retries_on_error;
- unsigned int ms_per_word;
- unsigned short xylogics_gap1;
- unsigned short xylogics_syncdelay;
- unsigned short xylogics_readdelay;
- unsigned short xylogics_gap2;
- unsigned short xylogics_readgate;
- unsigned short xylogics_writecont;
-};
-
-#define SGI_VOLHDR 0x00
-/* 1 and 2 were used for drive types no longer supported by SGI */
-#define SGI_SWAP 0x03
-/* 4 and 5 were for filesystem types SGI haven't ever supported on MIPS CPUs */
-#define SGI_VOLUME 0x06
-#define SGI_EFS 0x07
-#define SGI_LVOL 0x08
-#define SGI_RLVOL 0x09
-#define SGI_XFS 0x0a
-#define SGI_XFSLOG 0x0b
-#define SGI_XLV 0x0c
-#define SGI_XVM 0x0d
-#define ENTIRE_DISK SGI_VOLUME
-/*
- * controller flags
- */
-#define SECTOR_SLIP 0x01
-#define SECTOR_FWD 0x02
-#define TRACK_FWD 0x04
-#define TRACK_MULTIVOL 0x08
-#define IGNORE_ERRORS 0x10
-#define RESEEK 0x20
-#define CMDTAGQ_ENABLE 0x40
-
-typedef struct {
- unsigned int magic; /* expect SGI_LABEL_MAGIC */
- short boot_part; /* active boot partition */
- short swap_part; /* active swap partition */
- unsigned char boot_file[16]; /* name of the bootfile */
- struct device_parameter devparam; /* 1 * 48 bytes */
- struct volume_directory { /* 15 * 16 bytes */
- unsigned char vol_file_name[8]; /* a character array */
- unsigned int vol_file_start; /* number of logical block */
- unsigned int vol_file_size; /* number of bytes */
- } directory[15];
- struct sgi_partition { /* 16 * 12 bytes */
- unsigned int num_sectors; /* number of blocks */
- unsigned int start_sector; /* must be cylinder aligned */
- unsigned int id;
- } partitions[16];
- unsigned int csum;
- unsigned int fillbytes;
-} sgi_partition;
-
-typedef struct {
- unsigned int magic; /* looks like a magic number */
- unsigned int a2;
- unsigned int a3;
- unsigned int a4;
- unsigned int b1;
- unsigned short b2;
- unsigned short b3;
- unsigned int c[16];
- unsigned short d[3];
- unsigned char scsi_string[50];
- unsigned char serial[137];
- unsigned short check1816;
- unsigned char installer[225];
-} sgiinfo;
-
-#define SGI_LABEL_MAGIC 0x0be5a941
-#define SGI_LABEL_MAGIC_SWAPPED 0x41a9e50b
-#define SGI_INFO_MAGIC 0x00072959
-#define SGI_INFO_MAGIC_SWAPPED 0x59290700
-
-#define SSWAP16(x) (other_endian ? swab16(x) : (uint16_t)(x))
-#define SSWAP32(x) (other_endian ? swab32(x) : (uint32_t)(x))
-
-/* fdisk.c */
-#define sgilabel ((sgi_partition *)cxt->mbr)
-#define sgiparam (sgilabel->devparam)
-
-/* fdisksgilabel.c */
-extern struct systypes sgi_sys_types[];
-extern int check_sgi_label(struct fdisk_context *cxt);
-extern void sgi_list_table( struct fdisk_context *cxt, int xtra );
-extern int sgi_change_sysid(struct fdisk_context *cxt, int i, int sys);
-extern unsigned int sgi_get_start_sector(struct fdisk_context *cxt, int i );
-extern unsigned int sgi_get_num_sectors(struct fdisk_context *cxt, int i );
-extern int sgi_get_sysid(struct fdisk_context *cxt, int i );
-extern void sgi_delete_partition( struct fdisk_context *cxt, int i );
-extern void sgi_add_partition( struct fdisk_context *cxt, int n, int sys );
-extern void create_sgilabel( struct fdisk_context *cxt );
-extern void create_sgiinfo(struct fdisk_context *cxt);
-extern int verify_sgi(struct fdisk_context *cxt, int verbose );
-extern void sgi_write_table( struct fdisk_context *cxt );
-extern void sgi_set_ilfact( void );
-extern void sgi_set_rspeed( void );
-extern void sgi_set_pcylcount( void );
-extern void sgi_set_xcyl( void );
-extern void sgi_set_ncyl( void );
-extern void sgi_set_bootpartition(struct fdisk_context *cxt, int i );
-extern void sgi_set_swappartition(struct fdisk_context *cxt, int i );
-extern int sgi_get_bootpartition(struct fdisk_context *cxt);
-extern int sgi_get_swappartition(struct fdisk_context *cxt);
-extern void sgi_set_bootfile(struct fdisk_context *cxt);
-
-#endif /* FDISK_SGI_LABEL_H */
diff --git a/fdisk/fdisksunlabel.c b/fdisk/fdisksunlabel.c
deleted file mode 100644
index 65cbf8f16..000000000
--- a/fdisk/fdisksunlabel.c
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- * fdisksunlabel.c
- *
- * I think this is mostly, or entirely, due to
- * Jakub Jelinek (jj@sunsite.mff.cuni.cz), July 1996
- *
- * Merged with fdisk for other architectures, aeb, June 1998.
- *
- * Sat Mar 20 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * Internationalization
- */
-
-#include <stdio.h> /* stderr */
-#include <stdlib.h> /* qsort */
-#include <string.h> /* strstr */
-#include <unistd.h> /* write */
-#include <sys/ioctl.h> /* ioctl */
-
-#include "nls.h"
-#include "blkdev.h"
-
-#include <endian.h>
-
-#include "common.h"
-#include "fdisk.h"
-#include "fdisksunlabel.h"
-
-static int other_endian = 0;
-
-struct systypes sun_sys_types[] = {
- {SUN_TAG_UNASSIGNED, N_("Unassigned")},
- {SUN_TAG_BOOT, N_("Boot")},
- {SUN_TAG_ROOT, N_("SunOS root")},
- {SUN_TAG_SWAP, N_("SunOS swap")},
- {SUN_TAG_USR, N_("SunOS usr")},
- {SUN_TAG_BACKUP, N_("Whole disk")},
- {SUN_TAG_STAND, N_("SunOS stand")},
- {SUN_TAG_VAR, N_("SunOS var")},
- {SUN_TAG_HOME, N_("SunOS home")},
- {SUN_TAG_ALTSCTR, N_("SunOS alt sectors")},
- {SUN_TAG_CACHE, N_("SunOS cachefs")},
- {SUN_TAG_RESERVED, N_("SunOS reserved")},
- {SUN_TAG_LINUX_SWAP, N_("Linux swap")},
- {SUN_TAG_LINUX_NATIVE, N_("Linux native")},
- {SUN_TAG_LINUX_LVM, N_("Linux LVM")},
- {SUN_TAG_LINUX_RAID, N_("Linux raid autodetect")},
- { 0, NULL }
-};
-
-static inline unsigned short __swap16(unsigned short x) {
- return (((uint16_t)(x) & 0xFF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8);
-}
-static inline uint32_t __swap32(uint32_t x) {
- return (((uint32_t)(x) & 0xFF) << 24) | (((uint32_t)(x) & 0xFF00) << 8) | (((uint32_t)(x) & 0xFF0000) >> 8) | (((uint32_t)(x) & 0xFF000000) >> 24);
-}
-
-#define SSWAP16(x) (other_endian ? __swap16(x) \
- : (uint16_t)(x))
-#define SSWAP32(x) (other_endian ? __swap32(x) \
- : (uint32_t)(x))
-
-static void set_sun_partition(struct fdisk_context *cxt,
- int i, uint32_t start, uint32_t stop, uint16_t sysid)
-{
- sunlabel->part_tags[i].tag = SSWAP16(sysid);
- sunlabel->part_tags[i].flag = SSWAP16(0);
- sunlabel->partitions[i].start_cylinder =
- SSWAP32(start / (cxt->geom.heads * cxt->geom.sectors));
- sunlabel->partitions[i].num_sectors =
- SSWAP32(stop - start);
- set_changed(i);
- print_partition_size(cxt, i + 1, start, stop, sysid);
-}
-
-static void init(void)
-{
- disklabel = SUN_LABEL;
- partitions = SUN_NUM_PARTITIONS;
-}
-
-int check_sun_label(struct fdisk_context *cxt)
-{
- unsigned short *ush;
- int csum;
-
- if (sunlabel->magic != SUN_LABEL_MAGIC &&
- sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) {
- other_endian = 0;
- return 0;
- }
-
- init();
- other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
-
- ush = ((unsigned short *) (sunlabel + 1)) - 1;
- for (csum = 0; ush >= (unsigned short *)sunlabel;)
- csum ^= *ush--;
-
- if (csum) {
- fprintf(stderr,_("Detected sun disklabel with wrong checksum.\n"
- "Probably you'll have to set all the values,\n"
- "e.g. heads, sectors, cylinders and partitions\n"
- "or force a fresh label (s command in main menu)\n"));
- } else {
- int need_fixing = 0;
-
- cxt->geom.heads = SSWAP16(sunlabel->nhead);
- cxt->geom.cylinders = SSWAP16(sunlabel->ncyl);
- cxt->geom.sectors = SSWAP16(sunlabel->nsect);
-
- if (sunlabel->version != SSWAP32(SUN_LABEL_VERSION)) {
- fprintf(stderr,_("Detected sun disklabel with wrong version [0x%08x].\n"),
- SSWAP32(sunlabel->version));
- need_fixing = 1;
- }
- if (sunlabel->sanity != SSWAP32(SUN_LABEL_SANE)) {
- fprintf(stderr,_("Detected sun disklabel with wrong sanity [0x%08x].\n"),
- SSWAP32(sunlabel->sanity));
- need_fixing = 1;
- }
- if (sunlabel->num_partitions != SSWAP16(SUN_NUM_PARTITIONS)) {
- fprintf(stderr,_("Detected sun disklabel with wrong num_partitions [%u].\n"),
- SSWAP16(sunlabel->num_partitions));
- need_fixing = 1;
- }
- if (need_fixing) {
- fprintf(stderr, _("Warning: Wrong values need to be "
- "fixed up and will be corrected "
- "by w(rite)\n"));
- sunlabel->version = SSWAP32(SUN_LABEL_VERSION);
- sunlabel->sanity = SSWAP32(SUN_LABEL_SANE);
- sunlabel->num_partitions = SSWAP16(SUN_NUM_PARTITIONS);
-
- ush = (unsigned short *)sunlabel;
- csum = 0;
- while(ush < (unsigned short *)(&sunlabel->cksum))
- csum ^= *ush++;
- sunlabel->cksum = csum;
-
- set_changed(0);
- }
- }
- update_units(cxt);
- return 1;
-}
-
-void create_sunlabel(struct fdisk_context *cxt)
-{
- struct hd_geometry geometry;
- sector_t llsectors, llcyls;
- unsigned int ndiv, sec_fac;
- int res;
-
- fprintf(stderr,
- _("Building a new Sun disklabel.\n"));
-#if BYTE_ORDER == LITTLE_ENDIAN
- other_endian = 1;
-#else
- other_endian = 0;
-#endif
-
- init();
- fdisk_mbr_zeroize(cxt);
-
- sunlabel->magic = SSWAP16(SUN_LABEL_MAGIC);
- sunlabel->sanity = SSWAP32(SUN_LABEL_SANE);
- sunlabel->version = SSWAP32(SUN_LABEL_VERSION);
- sunlabel->num_partitions = SSWAP16(SUN_NUM_PARTITIONS);
-
- res = blkdev_get_sectors(cxt->dev_fd, &llsectors);
- sec_fac = cxt->sector_size / 512;
-
-#ifdef HDIO_GETGEO
- if (!ioctl(cxt->dev_fd, HDIO_GETGEO, &geometry)) {
- cxt->geom.heads = geometry.heads;
- cxt->geom.sectors = geometry.sectors;
- if (res == 0) {
- llcyls = llsectors / (cxt->geom.heads * cxt->geom.sectors * sec_fac);
- cxt->geom.cylinders = llcyls;
- if (cxt->geom.cylinders != llcyls)
- cxt->geom.cylinders = ~0;
- } else {
- cxt->geom.cylinders = geometry.cylinders;
- fprintf(stderr,
- _("Warning: BLKGETSIZE ioctl failed on %s. "
- "Using geometry cylinder value of %llu.\n"
- "This value may be truncated for devices"
- " > 33.8 GB.\n"), cxt->dev_path, cxt->geom.cylinders);
- }
- } else
-#endif
- {
- cxt->geom.heads = read_int(cxt, 1,1,1024,0,_("Heads"));
- cxt->geom.sectors = read_int(cxt, 1,1,1024,0,_("Sectors/track"));
- cxt->geom.cylinders = read_int(cxt, 1,1,65535,0,_("Cylinders"));
- }
-
- sunlabel->acyl = SSWAP16(2);
- sunlabel->pcyl = SSWAP16(cxt->geom.cylinders);
- sunlabel->ncyl = SSWAP16(cxt->geom.cylinders - 2);
- sunlabel->rpm = SSWAP16(5400);
- sunlabel->intrlv = SSWAP16(1);
- sunlabel->apc = SSWAP16(0);
-
- sunlabel->nhead = SSWAP16(cxt->geom.heads);
- sunlabel->nsect = SSWAP16(cxt->geom.sectors);
- sunlabel->ncyl = SSWAP16(cxt->geom.cylinders);
-
- snprintf(sunlabel->label_id, sizeof(sunlabel->label_id),
- "Linux cyl %llu alt %d hd %d sec %llu",
- cxt->geom.cylinders, SSWAP16(sunlabel->acyl), cxt->geom.heads, cxt->geom.sectors);
-
- if (cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors >= 150 * 2048) {
- ndiv = cxt->geom.cylinders - (50 * 2048 / (cxt->geom.heads * cxt->geom.sectors)); /* 50M swap */
- } else
- ndiv = cxt->geom.cylinders * 2 / 3;
-
- set_sun_partition(cxt, 0, 0, ndiv * cxt->geom.heads * cxt->geom.sectors,
- SUN_TAG_LINUX_NATIVE);
- set_sun_partition(cxt, 1, ndiv * cxt->geom.heads * cxt->geom.sectors,
- cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors,
- SUN_TAG_LINUX_SWAP);
- sunlabel->part_tags[1].flag |= SSWAP16(SUN_FLAG_UNMNT);
-
- set_sun_partition(cxt, 2, 0, cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors, SUN_TAG_BACKUP);
-
- {
- unsigned short *ush = (unsigned short *)sunlabel;
- unsigned short csum = 0;
- while(ush < (unsigned short *)(&sunlabel->cksum))
- csum ^= *ush++;
- sunlabel->cksum = csum;
- }
-
- set_all_unchanged();
- set_changed(0);
-}
-
-void toggle_sunflags(struct fdisk_context *cxt, int i, uint16_t mask)
-{
- struct sun_tag_flag *p = &sunlabel->part_tags[i];
-
- p->flag ^= SSWAP16(mask);
-
- set_changed(i);
-}
-
-static void fetch_sun(struct fdisk_context *cxt, uint32_t *starts,
- uint32_t *lens, uint32_t *start, uint32_t *stop)
-{
- int i, continuous = 1;
-
- *start = 0;
- *stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors;
-
- for (i = 0; i < partitions; i++) {
- struct sun_partition *part = &sunlabel->partitions[i];
- struct sun_tag_flag *tag = &sunlabel->part_tags[i];
-
- if (part->num_sectors &&
- tag->tag != SSWAP16(SUN_TAG_UNASSIGNED) &&
- tag->tag != SSWAP16(SUN_TAG_BACKUP)) {
- starts[i] = (SSWAP32(part->start_cylinder) *
- cxt->geom.heads * cxt->geom.sectors);
- lens[i] = SSWAP32(part->num_sectors);
- if (continuous) {
- if (starts[i] == *start)
- *start += lens[i];
- else if (starts[i] + lens[i] >= *stop)
- *stop = starts[i];
- else
- continuous = 0;
- /* There will be probably more gaps
- than one, so lets check afterwards */
- }
- } else {
- starts[i] = 0;
- lens[i] = 0;
- }
- }
-}
-
-static unsigned int *verify_sun_starts;
-
-static int verify_sun_cmp(int *a, int *b)
-{
- if (*a == -1)
- return 1;
- if (*b == -1)
- return -1;
- if (verify_sun_starts[*a] > verify_sun_starts[*b])
- return 1;
- return -1;
-}
-
-void verify_sun(struct fdisk_context *cxt)
-{
- uint32_t starts[SUN_NUM_PARTITIONS], lens[SUN_NUM_PARTITIONS], start, stop;
- uint32_t i,j,k,starto,endo;
- int array[SUN_NUM_PARTITIONS];
-
- verify_sun_starts = starts;
-
- fetch_sun(cxt, starts, lens, &start, &stop);
-
- for (k = 0; k < 7; k++) {
- for (i = 0; i < SUN_NUM_PARTITIONS; i++) {
- if (k && (lens[i] % (cxt->geom.heads * cxt->geom.sectors))) {
- printf(_("Partition %d doesn't end on cylinder boundary\n"), i+1);
- }
- if (lens[i]) {
- for (j = 0; j < i; j++)
- if (lens[j]) {
- if (starts[j] == starts[i]+lens[i]) {
- starts[j] = starts[i]; lens[j] += lens[i];
- lens[i] = 0;
- } else if (starts[i] == starts[j]+lens[j]){
- lens[j] += lens[i];
- lens[i] = 0;
- } else if (!k) {
- if (starts[i] < starts[j]+lens[j] &&
- starts[j] < starts[i]+lens[i]) {
- starto = starts[i];
- if (starts[j] > starto)
- starto = starts[j];
- endo = starts[i]+lens[i];
- if (starts[j]+lens[j] < endo)
- endo = starts[j]+lens[j];
- printf(_("Partition %d overlaps with others in "
- "sectors %d-%d\n"), i+1, starto, endo);
- }
- }
- }
- }
- }
- }
- for (i = 0; i < SUN_NUM_PARTITIONS; i++) {
- if (lens[i])
- array[i] = i;
- else
- array[i] = -1;
- }
- qsort(array,ARRAY_SIZE(array),sizeof(array[0]),
- (int (*)(const void *,const void *)) verify_sun_cmp);
-
- if (array[0] == -1) {
- printf(_("No partitions defined\n"));
- return;
- }
- stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors;
- if (starts[array[0]])
- printf(_("Unused gap - sectors 0-%d\n"), starts[array[0]]);
- for (i = 0; i < 7 && array[i+1] != -1; i++) {
- printf(_("Unused gap - sectors %d-%d\n"),
- (starts[array[i]] + lens[array[i]]),
- starts[array[i+1]]);
- }
- start = (starts[array[i]] + lens[array[i]]);
- if (start < stop)
- printf(_("Unused gap - sectors %d-%d\n"), start, stop);
-}
-
-void add_sun_partition(struct fdisk_context *cxt, int n, int sys)
-{
- uint32_t starts[SUN_NUM_PARTITIONS], lens[SUN_NUM_PARTITIONS];
- struct sun_partition *part = &sunlabel->partitions[n];
- struct sun_tag_flag *tag = &sunlabel->part_tags[n];
- uint32_t start, stop, stop2;
- int whole_disk = 0;
-
- char mesg[256];
- int i;
- unsigned int first, last;
-
- if (part->num_sectors && tag->tag != SSWAP16(SUN_TAG_UNASSIGNED)) {
- printf(_("Partition %d is already defined. Delete "
- "it before re-adding it.\n"), n + 1);
- return;
- }
-
- fetch_sun(cxt, starts, lens, &start, &stop);
- if (stop <= start) {
- if (n == 2)
- whole_disk = 1;
- else {
- printf(_("Other partitions already cover the whole disk.\nDelete "
- "some/shrink them before retry.\n"));
- return;
- }
- }
- snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
- for (;;) {
- if (whole_disk)
- first = read_int(cxt, 0, 0, 0, 0, mesg);
- else
- first = read_int(cxt, scround(start), scround(stop)+1,
- scround(stop), 0, mesg);
- if (display_in_cyl_units)
- first *= units_per_sector;
- else {
- /* Starting sector has to be properly aligned */
- int cs = cxt->geom.heads * cxt->geom.sectors;
- int x = first % cs;
-
- if (x)
- first += cs - x;
- }
- if (n == 2 && first != 0)
- printf (_("\
-It is highly recommended that the third partition covers the whole disk\n\
-and is of type `Whole disk'\n"));
- /* ewt asks to add: "don't start a partition at cyl 0"
- However, edmundo@rano.demon.co.uk writes:
- "In addition to having a Sun partition table, to be able to
- boot from the disc, the first partition, /dev/sdX1, must
- start at cylinder 0. This means that /dev/sdX1 contains
- the partition table and the boot block, as these are the
- first two sectors of the disc. Therefore you must be
- careful what you use /dev/sdX1 for. In particular, you must
- not use a partition starting at cylinder 0 for Linux swap,
- as that would overwrite the partition table and the boot
- block. You may, however, use such a partition for a UFS
- or EXT2 file system, as these file systems leave the first
- 1024 bytes undisturbed. */
- /* On the other hand, one should not use partitions
- starting at block 0 in an md, or the label will
- be trashed. */
- for (i = 0; i < partitions; i++)
- if (lens[i] && starts[i] <= first
- && starts[i] + lens[i] > first)
- break;
- if (i < partitions && !whole_disk) {
- if (n == 2 && !first) {
- whole_disk = 1;
- break;
- }
- printf(_("Sector %d is already allocated\n"), first);
- } else
- break;
- }
- stop = cxt->geom.cylinders * cxt->geom.heads * cxt->geom.sectors; /* ancient */
- stop2 = stop;
- for (i = 0; i < partitions; i++) {
- if (starts[i] > first && starts[i] < stop)
- stop = starts[i];
- }
- snprintf(mesg, sizeof(mesg),
- _("Last %s or +size or +sizeM or +sizeK"),
- str_units(SINGULAR));
- if (whole_disk)
- last = read_int(cxt, scround(stop2), scround(stop2), scround(stop2),
- 0, mesg);
- else if (n == 2 && !first)
- last = read_int(cxt, scround(first), scround(stop2), scround(stop2),
- scround(first), mesg);
- else
- last = read_int(cxt, scround(first), scround(stop), scround(stop),
- scround(first), mesg);
- if (display_in_cyl_units)
- last *= units_per_sector;
- if (n == 2 && !first) {
- if (last >= stop2) {
- whole_disk = 1;
- last = stop2;
- } else if (last > stop) {
- printf (
- _("You haven't covered the whole disk with the 3rd partition, but your value\n"
- "%d %s covers some other partition. Your entry has been changed\n"
- "to %d %s\n"),
- scround(last), str_units(SINGULAR),
- scround(stop), str_units(SINGULAR));
- last = stop;
- }
- } else if (!whole_disk && last > stop)
- last = stop;
-
- if (whole_disk)
- sys = SUN_TAG_BACKUP;
-
- set_sun_partition(cxt, n, first, last, sys);
-}
-
-void sun_delete_partition(struct fdisk_context *cxt, int i)
-{
- struct sun_partition *part = &sunlabel->partitions[i];
- struct sun_tag_flag *tag = &sunlabel->part_tags[i];
- unsigned int nsec;
-
- if (i == 2 &&
- tag->tag == SSWAP16(SUN_TAG_BACKUP) &&
- !part->start_cylinder &&
- (nsec = SSWAP32(part->num_sectors))
- == cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders)
- printf(_("If you want to maintain SunOS/Solaris compatibility, "
- "consider leaving this\n"
- "partition as Whole disk (5), starting at 0, with %u "
- "sectors\n"), nsec);
- tag->tag = SSWAP16(SUN_TAG_UNASSIGNED);
- part->num_sectors = 0;
-}
-
-int sun_change_sysid(struct fdisk_context *cxt, int i, uint16_t sys)
-{
- struct sun_partition *part = &sunlabel->partitions[i];
- struct sun_tag_flag *tag = &sunlabel->part_tags[i];
-
- if (sys == SUN_TAG_LINUX_SWAP && !part->start_cylinder) {
- read_chars(
- _("It is highly recommended that the partition at offset 0\n"
- "is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n"
- "there may destroy your partition table and bootblock.\n"
- "Type YES if you're very sure you would like that partition\n"
- "tagged with 82 (Linux swap): "));
- if (strcmp (line_ptr, _("YES\n")))
- return 0;
- }
- switch (sys) {
- case SUN_TAG_SWAP:
- case SUN_TAG_LINUX_SWAP:
- /* swaps are not mountable by default */
- tag->flag |= SSWAP16(SUN_FLAG_UNMNT);
- break;
- default:
- /* assume other types are mountable;
- user can change it anyway */
- tag->flag &= ~SSWAP16(SUN_FLAG_UNMNT);
- break;
- }
- tag->tag = SSWAP16(sys);
- return 1;
-}
-
-void sun_list_table(struct fdisk_context *cxt, int xtra)
-{
- int i, w;
- char *type;
-
- w = strlen(cxt->dev_path);
- if (xtra)
- printf(
- _("\nDisk %s (Sun disk label): %u heads, %llu sectors, %d rpm\n"
- "%llu cylinders, %d alternate cylinders, %d physical cylinders\n"
- "%d extra sects/cyl, interleave %d:1\n"
- "Label ID: %s\n"
- "Volume ID: %s\n"
- "Units = %s of %d * 512 bytes\n\n"),
- cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, SSWAP16(sunlabel->rpm),
- cxt->geom.cylinders, SSWAP16(sunlabel->acyl),
- SSWAP16(sunlabel->pcyl),
- SSWAP16(sunlabel->apc),
- SSWAP16(sunlabel->intrlv),
- sunlabel->label_id,
- sunlabel->volume_id,
- str_units(PLURAL), units_per_sector);
- else
- printf(
- _("\nDisk %s (Sun disk label): %u heads, %llu sectors, %llu cylinders\n"
- "Units = %s of %d * 512 bytes\n\n"),
- cxt->dev_path, cxt->geom.heads, cxt->geom.sectors, cxt->geom.cylinders,
- str_units(PLURAL), units_per_sector);
-
- printf(_("%*s Flag Start End Blocks Id System\n"),
- w + 1, _("Device"));
- for (i = 0 ; i < partitions; i++) {
- struct sun_partition *part = &sunlabel->partitions[i];
- struct sun_tag_flag *tag = &sunlabel->part_tags[i];
-
- if (part->num_sectors) {
- uint32_t start = SSWAP32(part->start_cylinder) * cxt->geom.heads * cxt->geom.sectors;
- uint32_t len = SSWAP32(part->num_sectors);
- printf(
- "%s %c%c %9lu %9lu %9lu%c %2x %s\n",
-/* device */ partname(cxt->dev_path, i+1, w),
-/* flags */ (tag->flag & SSWAP16(SUN_FLAG_UNMNT)) ? 'u' : ' ',
- (tag->flag & SSWAP16(SUN_FLAG_RONLY)) ? 'r' : ' ',
-/* start */ (unsigned long) scround(start),
-/* end */ (unsigned long) scround(start+len),
-/* odd flag on end */ (unsigned long) len / 2, len & 1 ? '+' : ' ',
-/* type id */ SSWAP16(tag->tag),
-/* type name */ (type = partition_type(SSWAP16(tag->tag)))
- ? type : _("Unknown"));
- }
- }
-}
-
-void sun_set_alt_cyl(struct fdisk_context *cxt)
-{
- sunlabel->acyl =
- SSWAP16(read_int(cxt, 0,SSWAP16(sunlabel->acyl), 65535, 0,
- _("Number of alternate cylinders")));
-}
-
-void sun_set_ncyl(struct fdisk_context *cxt, int cyl)
-{
- sunlabel->ncyl = SSWAP16(cyl);
-}
-
-void sun_set_xcyl(struct fdisk_context *cxt)
-{
- sunlabel->apc =
- SSWAP16(read_int(cxt, 0, SSWAP16(sunlabel->apc), cxt->geom.sectors, 0,
- _("Extra sectors per cylinder")));
-}
-
-void sun_set_ilfact(struct fdisk_context *cxt)
-{
- sunlabel->intrlv =
- SSWAP16(read_int(cxt, 1, SSWAP16(sunlabel->intrlv), 32, 0,
- _("Interleave factor")));
-}
-
-void sun_set_rspeed(struct fdisk_context *cxt)
-{
- sunlabel->rpm =
- SSWAP16(read_int(cxt, 1, SSWAP16(sunlabel->rpm), 100000, 0,
- _("Rotation speed (rpm)")));
-}
-
-void sun_set_pcylcount(struct fdisk_context *cxt)
-{
- sunlabel->pcyl =
- SSWAP16(read_int(cxt, 0, SSWAP16(sunlabel->pcyl), 65535, 0,
- _("Number of physical cylinders")));
-}
-
-void sun_write_table(struct fdisk_context *cxt)
-{
- unsigned short *ush = (unsigned short *)sunlabel;
- unsigned short csum = 0;
-
- while(ush < (unsigned short *)(&sunlabel->cksum))
- csum ^= *ush++;
- sunlabel->cksum = csum;
- if (lseek(cxt->dev_fd, 0, SEEK_SET) < 0)
- fatal(cxt, unable_to_seek);
- if (write(cxt->dev_fd, sunlabel, SECTOR_SIZE) != SECTOR_SIZE)
- fatal(cxt, unable_to_write);
-}
-
-int sun_get_sysid(struct fdisk_context *cxt, int i)
-{
- return SSWAP16(sunlabel->part_tags[i].tag);
-}
diff --git a/fdisk/fdisksunlabel.h b/fdisk/fdisksunlabel.h
deleted file mode 100644
index abb29c3b5..000000000
--- a/fdisk/fdisksunlabel.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef FDISK_SUN_LABEL_H
-#define FDISK_SUN_LABEL_H
-
-#include <stdint.h>
-
-struct sun_partition {
- uint32_t start_cylinder;
- uint32_t num_sectors;
-};
-
-struct sun_tag_flag {
- uint16_t tag;
-#define SUN_TAG_UNASSIGNED 0x00 /* Unassigned partition */
-#define SUN_TAG_BOOT 0x01 /* Boot partition */
-#define SUN_TAG_ROOT 0x02 /* Root filesystem */
-#define SUN_TAG_SWAP 0x03 /* Swap partition */
-#define SUN_TAG_USR 0x04 /* /usr filesystem */
-#define SUN_TAG_BACKUP 0x05 /* Full-disk slice */
-#define SUN_TAG_STAND 0x06 /* Stand partition */
-#define SUN_TAG_VAR 0x07 /* /var filesystem */
-#define SUN_TAG_HOME 0x08 /* /home filesystem */
-#define SUN_TAG_ALTSCTR 0x09 /* Alt sector partition */
-#define SUN_TAG_CACHE 0x0a /* Cachefs partition */
-#define SUN_TAG_RESERVED 0x0b /* SMI reserved data */
-#define SUN_TAG_LINUX_SWAP 0x82 /* Linux SWAP */
-#define SUN_TAG_LINUX_NATIVE 0x83 /* Linux filesystem */
-#define SUN_TAG_LINUX_LVM 0x8e /* Linux LVM */
-#define SUN_TAG_LINUX_RAID 0xfd /* LInux RAID */
-
- uint16_t flag;
-#define SUN_FLAG_UNMNT 0x01 /* Unmountable partition*/
-#define SUN_FLAG_RONLY 0x10 /* Read only */
-};
-
-#define SUN_LABEL_SIZE 512
-
-#define SUN_LABEL_ID_SIZE 128
-#define SUN_VOLUME_ID_SIZE 8
-
-#define SUN_LABEL_VERSION 0x00000001
-#define SUN_LABEL_SANE 0x600ddeee
-#define SUN_NUM_PARTITIONS 8
-
-struct sun_disk_label {
- char label_id[SUN_LABEL_ID_SIZE];
- uint32_t version;
- char volume_id[SUN_VOLUME_ID_SIZE];
- uint16_t num_partitions;
- struct sun_tag_flag part_tags[SUN_NUM_PARTITIONS];
- uint32_t bootinfo[3];
- uint32_t sanity;
- uint32_t resv[10];
- uint32_t part_timestamps[SUN_NUM_PARTITIONS];
- uint32_t write_reinstruct;
- uint32_t read_reinstruct;
- uint8_t pad[148];
- uint16_t rpm;
- uint16_t pcyl;
- uint16_t apc;
- uint16_t resv1;
- uint16_t resv2;
- uint16_t intrlv;
- uint16_t ncyl;
- uint16_t acyl;
- uint16_t nhead;
- uint16_t nsect;
- uint16_t resv3;
- uint16_t resv4;
- struct sun_partition partitions[SUN_NUM_PARTITIONS];
- uint16_t magic;
- uint16_t cksum;
-};
-
-#define SUN_LABEL_MAGIC 0xDABE
-#define SUN_LABEL_MAGIC_SWAPPED 0xBEDA
-#define sunlabel ((struct sun_disk_label *)cxt->mbr)
-
-/* fdisksunlabel.c */
-extern struct systypes sun_sys_types[];
-extern int check_sun_label(struct fdisk_context *cxt);
-extern void create_sunlabel(struct fdisk_context *cxt);
-extern void sun_delete_partition(struct fdisk_context *cxt, int i);
-extern int sun_change_sysid(struct fdisk_context *cxt, int i, uint16_t sys);
-extern void sun_list_table(struct fdisk_context *cxt, int xtra);
-extern void verify_sun(struct fdisk_context *cxt);
-extern void add_sun_partition(struct fdisk_context *cxt, int n, int sys);
-extern void sun_write_table(struct fdisk_context *cxt);
-extern void sun_set_alt_cyl(struct fdisk_context *cxt);
-extern void sun_set_ncyl(struct fdisk_context *cxt, int cyl);
-extern void sun_set_xcyl(struct fdisk_context *cxt);
-extern void sun_set_ilfact(struct fdisk_context *cxt);
-extern void sun_set_rspeed(struct fdisk_context *cxt);
-extern void sun_set_pcylcount(struct fdisk_context *cxt);
-extern void toggle_sunflags(struct fdisk_context *cxt, int i, uint16_t mask);
-extern int sun_get_sysid(struct fdisk_context *cxt, int i);
-
-#endif /* FDISK_SUN_LABEL_H */
diff --git a/fdisk/gpt.c b/fdisk/gpt.c
deleted file mode 100644
index bb6911a21..000000000
--- a/fdisk/gpt.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- *
- * GPT (GUID Partition Table) signature detection. Based on libparted and
- * util-linux/partx.
- *
- * Warning: this code doesn't do all GPT checks (CRC32, Protective MBR, ..).
- * It's really GPT signature detection only.
- *
- * Copyright (C) 2007 Karel Zak <kzak@redhat.com>
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "gpt.h"
-#include "blkdev.h"
-#include "bitops.h"
-#include "closestream.h"
-
-#define GPT_HEADER_SIGNATURE 0x5452415020494645LL
-#define GPT_PRIMARY_PARTITION_TABLE_LBA 1
-
-typedef struct {
- uint32_t time_low;
- uint16_t time_mid;
- uint16_t time_hi_and_version;
- uint8_t clock_seq_hi_and_reserved;
- uint8_t clock_seq_low;
- uint8_t node[6];
-} /* __attribute__ ((packed)) */ efi_guid_t;
-/* commented out "__attribute__ ((packed))" to work around gcc bug (fixed
- * in gcc3.1): __attribute__ ((packed)) breaks addressing on initialized
- * data. It turns out we don't need it in this case, so it doesn't break
- * anything :)
- */
-
-typedef struct _GuidPartitionTableHeader_t {
- uint64_t Signature;
- uint32_t Revision;
- uint32_t HeaderSize;
- uint32_t HeaderCRC32;
- uint32_t Reserved1;
- uint64_t MyLBA;
- uint64_t AlternateLBA;
- uint64_t FirstUsableLBA;
- uint64_t LastUsableLBA;
- efi_guid_t DiskGUID;
- uint64_t PartitionEntryLBA;
- uint32_t NumberOfPartitionEntries;
- uint32_t SizeOfPartitionEntry;
- uint32_t PartitionEntryArrayCRC32;
- uint8_t Reserved2[512 - 92];
-} __attribute__ ((packed)) GuidPartitionTableHeader_t;
-
-static int
-_get_sector_size (int fd)
-{
- int sector_size;
-
- if (blkdev_get_sector_size(fd, &sector_size) == -1)
- return DEFAULT_SECTOR_SIZE;
- return sector_size;
-}
-
-static uint64_t
-_get_num_sectors(int fd)
-{
- unsigned long long bytes=0;
-
- if (blkdev_get_size(fd, &bytes) == -1)
- return 0;
- return bytes / _get_sector_size(fd);
-}
-
-static uint64_t
-last_lba(int fd)
-{
- int rc;
- uint64_t sectors = 0;
- struct stat s;
-
- memset(&s, 0, sizeof (s));
- rc = fstat(fd, &s);
- if (rc == -1)
- {
- fprintf(stderr, "last_lba() could not stat: %m\n");
- return 0;
- }
- if (S_ISBLK(s.st_mode))
- sectors = _get_num_sectors(fd);
- else if (S_ISREG(s.st_mode))
- sectors = s.st_size >> _get_sector_size(fd);
- else
- {
- fprintf(stderr,
- "last_lba(): I don't know how to handle files with mode %o\n",
- s.st_mode);
- sectors = 1;
- }
- return sectors - 1;
-}
-
-static ssize_t
-read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
-{
- int sector_size = _get_sector_size(fd);
- off_t offset = lba * sector_size;
-
- lseek(fd, offset, SEEK_SET);
- return read(fd, buffer, bytes);
-}
-
-static GuidPartitionTableHeader_t *
-alloc_read_gpt_header(int fd, uint64_t lba)
-{
- GuidPartitionTableHeader_t *gpt =
- (GuidPartitionTableHeader_t *) malloc(sizeof (GuidPartitionTableHeader_t));
- if (!gpt)
- return NULL;
- memset(gpt, 0, sizeof (*gpt));
- if (!read_lba(fd, lba, gpt, sizeof (GuidPartitionTableHeader_t)))
- {
- free(gpt);
- return NULL;
- }
- return gpt;
-}
-
-static int
-gpt_check_signature(int fd, uint64_t lba)
-{
- GuidPartitionTableHeader_t *gpt;
- int res=0;
-
- if ((gpt = alloc_read_gpt_header(fd, lba)))
- {
- if (gpt->Signature == cpu_to_le64(GPT_HEADER_SIGNATURE))
- res = 1;
- free(gpt);
- }
- return res;
-}
-
-/* returns:
- * 0 not found GPT
- * 1 for valid primary GPT header
- * 2 for valid alternative GPT header
- */
-int
-gpt_probe_signature_fd(int fd)
-{
- int res = 0;
-
- /* check primary GPT header */
- if (gpt_check_signature(fd, GPT_PRIMARY_PARTITION_TABLE_LBA))
- res = 1;
- else
- {
- /* check alternative GPT header */
- uint64_t lastlba = last_lba(fd);
- if (gpt_check_signature(fd, lastlba))
- res = 2;
- }
- return res;
-}
-
-int
-gpt_probe_signature_devname(char *devname)
-{
- int res, fd;
- if ((fd = open(devname, O_RDONLY)) < 0)
- return 0;
- res = gpt_probe_signature_fd(fd);
- close(fd);
- return res;
-}
-
-#ifdef GPT_TEST_MAIN
-int
-main(int argc, char **argv)
-{
- atexit(close_stdout);
- if (argc!=2)
- {
- fprintf(stderr, "usage: %s <dev>\n", argv[0]);
- exit(EXIT_FAILURE);
- }
- if (gpt_probe_signature_devname(argv[1]))
- printf("GPT (GUID Partition Table) detected on %s\n", argv[1]);
- exit(EXIT_SUCCESS);
-}
-#endif
diff --git a/fdisk/gpt.h b/fdisk/gpt.h
deleted file mode 100644
index e57c24a33..000000000
--- a/fdisk/gpt.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef FDISK_GPT_H
-#define FDISK_GPT_H
-
-extern int gpt_probe_signature_fd(int fd);
-extern int gpt_probe_signature_devname(char *devname);
-
-#endif /* FDISK_GPT_H */
-
diff --git a/fdisk/i386_sys_types.c b/fdisk/i386_sys_types.c
deleted file mode 100644
index 916daf68b..000000000
--- a/fdisk/i386_sys_types.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* DOS partition types */
-#include "common.h"
-#include "nls.h"
-
-struct systypes i386_sys_types[] = {
- {0x00, N_("Empty")},
- {0x01, N_("FAT12")},
- {0x02, N_("XENIX root")},
- {0x03, N_("XENIX usr")},
- {0x04, N_("FAT16 <32M")},
- {0x05, N_("Extended")}, /* DOS 3.3+ extended partition */
- {0x06, N_("FAT16")}, /* DOS 16-bit >=32M */
- {0x07, N_("HPFS/NTFS/exFAT")}, /* OS/2 IFS, eg, HPFS or NTFS or QNX or exFAT */
- {0x08, N_("AIX")}, /* AIX boot (AIX -- PS/2 port) or SplitDrive */
- {0x09, N_("AIX bootable")}, /* AIX data or Coherent */
- {0x0a, N_("OS/2 Boot Manager")},/* OS/2 Boot Manager */
- {0x0b, N_("W95 FAT32")},
- {0x0c, N_("W95 FAT32 (LBA)")},/* LBA really is `Extended Int 13h' */
- {0x0e, N_("W95 FAT16 (LBA)")},
- {0x0f, N_("W95 Ext'd (LBA)")},
- {0x10, N_("OPUS")},
- {0x11, N_("Hidden FAT12")},
- {0x12, N_("Compaq diagnostics")},
- {0x14, N_("Hidden FAT16 <32M")},
- {0x16, N_("Hidden FAT16")},
- {0x17, N_("Hidden HPFS/NTFS")},
- {0x18, N_("AST SmartSleep")},
- {0x1b, N_("Hidden W95 FAT32")},
- {0x1c, N_("Hidden W95 FAT32 (LBA)")},
- {0x1e, N_("Hidden W95 FAT16 (LBA)")},
- {0x24, N_("NEC DOS")},
- {0x27, N_("Hidden NTFS WinRE")},
- {0x39, N_("Plan 9")},
- {0x3c, N_("PartitionMagic recovery")},
- {0x40, N_("Venix 80286")},
- {0x41, N_("PPC PReP Boot")},
- {0x42, N_("SFS")},
- {0x4d, N_("QNX4.x")},
- {0x4e, N_("QNX4.x 2nd part")},
- {0x4f, N_("QNX4.x 3rd part")},
- {0x50, N_("OnTrack DM")},
- {0x51, N_("OnTrack DM6 Aux1")}, /* (or Novell) */
- {0x52, N_("CP/M")}, /* CP/M or Microport SysV/AT */
- {0x53, N_("OnTrack DM6 Aux3")},
- {0x54, N_("OnTrackDM6")},
- {0x55, N_("EZ-Drive")},
- {0x56, N_("Golden Bow")},
- {0x5c, N_("Priam Edisk")},
- {0x61, N_("SpeedStor")},
- {0x63, N_("GNU HURD or SysV")}, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
- {0x64, N_("Novell Netware 286")},
- {0x65, N_("Novell Netware 386")},
- {0x70, N_("DiskSecure Multi-Boot")},
- {0x75, N_("PC/IX")},
- {0x80, N_("Old Minix")}, /* Minix 1.4a and earlier */
- {0x81, N_("Minix / old Linux")},/* Minix 1.4b and later */
- {0x82, N_("Linux swap / Solaris")},
- {0x83, N_("Linux")},
- {0x84, N_("OS/2 hidden C: drive")},
- {0x85, N_("Linux extended")},
- {0x86, N_("NTFS volume set")},
- {0x87, N_("NTFS volume set")},
- {0x88, N_("Linux plaintext")},
- {0x8e, N_("Linux LVM")},
- {0x93, N_("Amoeba")},
- {0x94, N_("Amoeba BBT")}, /* (bad block table) */
- {0x9f, N_("BSD/OS")}, /* BSDI */
- {0xa0, N_("IBM Thinkpad hibernation")},
- {0xa5, N_("FreeBSD")}, /* various BSD flavours */
- {0xa6, N_("OpenBSD")},
- {0xa7, N_("NeXTSTEP")},
- {0xa8, N_("Darwin UFS")},
- {0xa9, N_("NetBSD")},
- {0xab, N_("Darwin boot")},
- {0xaf, N_("HFS / HFS+")},
- {0xb7, N_("BSDI fs")},
- {0xb8, N_("BSDI swap")},
- {0xbb, N_("Boot Wizard hidden")},
- {0xbe, N_("Solaris boot")},
- {0xbf, N_("Solaris")},
- {0xc1, N_("DRDOS/sec (FAT-12)")},
- {0xc4, N_("DRDOS/sec (FAT-16 < 32M)")},
- {0xc6, N_("DRDOS/sec (FAT-16)")},
- {0xc7, N_("Syrinx")},
- {0xda, N_("Non-FS data")},
- {0xdb, N_("CP/M / CTOS / ...")},/* CP/M or Concurrent CP/M or
- Concurrent DOS or CTOS */
- {0xde, N_("Dell Utility")}, /* Dell PowerEdge Server utilities */
- {0xdf, N_("BootIt")}, /* BootIt EMBRM */
- {0xe1, N_("DOS access")}, /* DOS access or SpeedStor 12-bit FAT
- extended partition */
- {0xe3, N_("DOS R/O")}, /* DOS R/O or SpeedStor */
- {0xe4, N_("SpeedStor")}, /* SpeedStor 16-bit FAT extended
- partition < 1024 cyl. */
- {0xeb, N_("BeOS fs")},
- {0xee, N_("GPT")}, /* Intel EFI GUID Partition Table */
- {0xef, N_("EFI (FAT-12/16/32)")},/* Intel EFI System Partition */
- {0xf0, N_("Linux/PA-RISC boot")},/* Linux/PA-RISC boot loader */
- {0xf1, N_("SpeedStor")},
- {0xf4, N_("SpeedStor")}, /* SpeedStor large partition */
- {0xf2, N_("DOS secondary")}, /* DOS 3.3+ secondary */
- {0xfb, N_("VMware VMFS")},
- {0xfc, N_("VMware VMKCORE")}, /* VMware kernel dump partition */
- {0xfd, N_("Linux raid autodetect")},/* New (2.2.x) raid partition with
- autodetect using persistent
- superblock */
- {0xfe, N_("LANstep")}, /* SpeedStor >1024 cyl. or LANstep */
- {0xff, N_("BBT")}, /* Xenix Bad Block Table */
- { 0, 0 }
-};
diff --git a/fdisk/partname.c b/fdisk/partname.c
deleted file mode 100644
index d2782dca1..000000000
--- a/fdisk/partname.c
+++ /dev/null
@@ -1,49 +0,0 @@
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "blkdev.h"
-#include "pathnames.h"
-#include "common.h"
-#include "c.h"
-
-/*
- * return partition name - uses static storage unless buf is supplied
- */
-char *
-partname(char *dev, int pno, int lth) {
- static char bufp[PATH_MAX];
- char *p;
- int w, wp;
-
- w = strlen(dev);
- p = "";
-
- if (isdigit(dev[w-1]))
- p = "p";
-
- /* devfs kludge - note: fdisk partition names are not supposed
- to equal kernel names, so there is no reason to do this */
- if (strcmp (dev + w - 4, "disc") == 0) {
- w -= 4;
- p = "part";
- }
-
- /* udev names partitions by appending -partN
- e.g. ata-SAMSUNG_SV8004H_0357J1FT712448-part1 */
- if ((strncmp(dev, _PATH_DEV_BYID, strlen(_PATH_DEV_BYID)) == 0) ||
- strncmp(dev, _PATH_DEV_BYPATH, strlen(_PATH_DEV_BYPATH)) == 0) {
- p = "-part";
- }
-
- wp = strlen(p);
-
- if (lth) {
- snprintf(bufp, sizeof(bufp), "%*.*s%s%-2u",
- lth-wp-2, w, dev, p, pno);
- } else {
- snprintf(bufp, sizeof(bufp), "%.*s%s%-2u", w, dev, p, pno);
- }
- return bufp;
-}
-
diff --git a/fdisk/sfdisk.8 b/fdisk/sfdisk.8
deleted file mode 100644
index 32907e3e9..000000000
--- a/fdisk/sfdisk.8
+++ /dev/null
@@ -1,603 +0,0 @@
-.\" Copyright 1995 Andries E. Brouwer (aeb@cwi.nl)
-.\" May be distributed under the GNU General Public License
-.\" The `DOS 6.x Warning' was taken from the old fdisk.8, which says
-.\" -- Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
-.\" -- May be distributed under the GNU General Public License
-.\" The `DRDOS Warning' was taken from a net post by Stephen Tweedie.
-.\"
-.TH SFDISK 8 "August 2011" "util-linux" "System Administration"
-.SH NAME
-sfdisk \- partition table manipulator for Linux
-.SH SYNOPSIS
-.B sfdisk
-.RI [ options ]
-.I device
-.br
-.B sfdisk \-s
-.RI [ partition ]
-.SH DESCRIPTION
-.B sfdisk
-has four (main) uses: list the size of a partition, list the partitions
-on a device, check the partitions on a device, and \- very dangerous \-
-repartition a device.
-
-.B sfdisk
-doesn't understand the GUID Partition Table (GPT) format and it is not
-designed for large partitions. In these cases use the more advanced GNU
-.BR parted (8).
-
-Note that
-.B sfdisk
-does not align partitions to block device I/O limits. This functionality is
-provided by
-.BR fdisk (8).
-
-.SS "List sizes"
-.BI "sfdisk \-s " partition
-gives the size of
-.I partition
-in blocks. This may be useful in connection with programs like
-.BR mkswap (8).
-Here
-.I partition
-is usually something like
-.I /dev/hda1
-or
-.IR /dev/sdb12 ,
-but may also be an entire disk, like
-.IR /dev/xda .
-
-.RS
-.nf
-.if t .ft CW
-% sfdisk \-s /dev/hda9
-81599
-.if t .ft R
-.fi
-.RE
-
-If the partition argument is omitted,
-.B sfdisk
-will list the sizes of all disks, and the total:
-
-.RS
-.nf
-.if t .ft CW
-% sfdisk \-s
-/dev/hda: 208896
-/dev/hdb: 1025136
-/dev/hdc: 1031063
-/dev/sda: 8877895
-/dev/sdb: 1758927
-total: 12901917 blocks
-.if t .ft R
-.fi
-.RE
-
-.SS "List partitions"
-The second type of invocation:
-.BI "sfdisk \-l " device
-will list the partitions on the specified device. If the
-.I device
-argument is omitted, the partitions on all hard disks are listed.
-
-.RS
-.nf
-.if t .ft CW
-% sfdisk \-l /dev/hdc
-
-Disk /dev/hdc: 16 heads, 63 sectors, 2045 cylinders
-Units = cylinders of 516096 bytes, blocks of 1024 bytes, counting from 0
-
- Device Boot Start End #cyls #blocks Id System
-/dev/hdc1 0+ 406 407\- 205096+ 83 Linux native
-/dev/hdc2 407 813 407 205128 83 Linux native
-/dev/hdc3 814 2044 1231 620424 83 Linux native
-/dev/hdc4 0 \- 0 0 0 Empty
-.if t .ft R
-.fi
-.RE
-
-The trailing \- and + signs indicate that rounding has taken place,
-and that the actual value is slightly less or more. To see the
-exact values, ask for a listing with sectors as unit (\fB\-u S\fR).
-
-.SS "Check partitions"
-The third type of invocation:
-.BI "sfdisk \-V " device
-will apply various consistency checks to the partition tables on
-.IR device .
-It prints `OK' or complains. The \fB\-V\fR option can be used
-together with \fB\-l\fR. In a shell script one might use
-.BI "sfdisk \-V \-q " device
-which only returns a status.
-
-.SS "Create partitions"
-The fourth type of invocation:
-.BI "sfdisk " device
-will cause
-.B sfdisk
-to read the specification for the desired partitioning of
-.I device
-from standard input, and then to change the partition tables
-on that disk. Thus it is possible to use
-.B sfdisk
-from a shell script. When
-.B sfdisk
-determines that its standard input is a terminal, it will be
-conversational; otherwise it will abort on any error.
-.LP
-BE EXTREMELY CAREFUL - ONE TYPING MISTAKE AND ALL YOUR DATA IS LOST
-.LP
-As a precaution, one can save the sectors changed by
-.BR sfdisk :
-
-.RS
-.nf
-.if t .ft CW
-% sfdisk /dev/hdd \-O hdd-partition-sectors.save
-\&...
-.if t .ft R
-.fi
-.RE
-
-.LP
-Then, if you discover that you did something stupid before anything
-else has been written to disk, it may be possible to recover
-the old situation with:
-
-.RS
-.nf
-.if t .ft CW
-% sfdisk /dev/hdd \-I hdd-partition-sectors.save
-.if t .ft R
-.fi
-.RE
-
-.LP
-(This is not the same as saving the old partition table:
-a readable version of the old partition table can be saved
-using the \fB\-d\fR option. However, if you create logical partitions,
-the sectors describing them are located somewhere on disk,
-possibly on sectors that were not part of the partition table
-before. Thus, the information the \fB\-O\fR option saves
-is not a binary version of the output of \fB\-d\fR.)
-
-There are many options.
-
-.SH OPTIONS
-.TP
-.BR \-v ", " \-\-version
-Print version number of
-.B sfdisk
-and exit immediately.
-.TP
-.BR \-h ", " \-\-help
-Print a usage message and exit immediately.
-.TP
-.BR \-T ", " \-\-list\-types
-Print the recognized types (system Id's).
-.TP
-.BR \-s ", " \-\-show\-size
-List the size of a partition.
-.TP
-.BR \-g ", " \-\-show\-geometry
-List the kernel's idea of the geometry of the indicated disk(s).
-.TP
-.BR \-G ", " \-\-show\-pt\-geometry
-List the geometry of the indicated disks guessed by looking at
-the partition table.
-.TP
-.BR \-l ", " \-\-list
-List the partitions of a device.
-.TP
-.BR \-d ", " \-\-dump
-Dump the partitions of a device in a format that is usable as input
-to /fBsfdisk/fR. For example,
-.br
-.nf
-.if t .ft CW
- % sfdisk -d /dev/hda > hda.out
- % sfdisk /dev/hda < hda.out
-.if t .ft R
-.fi
-will correct the bad last extended partition that the OS/2
-fdisk creates.
-.TP
-.BR \-V ", " \-\-verify
-Test whether partitions seem correct. (See the third invocation type above.)
-.TP
-.BR \-i ", " \-\-increment
-Number cylinders etc. starting from 1 instead of 0.
-.TP
-.BI \-N " number"
-Change only the single partition indicated. For example:
-.nf
-.if t .ft CW
- % sfdisk /dev/hdb \-N5
- ,,,*
-.if t .ft R
-.fi
-will make the fifth partition on /dev/hdb bootable (`active')
-and change nothing else. (Probably this fifth partition
-is called /dev/hdb5, but you are free to call it something else,
-like `/my_equipment/disks/2/5' or so).
-.TP
-.BR \-A ", " \-\-activate " \fInumber\fR"
-Make the indicated partition(s) active, and all others inactive.
-.TP
-.BR \-c ", " \-\-id " \fInumber\fR [\fIId\fR]"
-If no \fIId\fR argument given: print the partition Id of the indicated
-partition. If an \fIId\fR argument is present: change the type (Id) of
-the indicated partition to the given value.
-This option has two longer forms, \fB\-\-print\-id\fR and \fB\-\-change\-id\fR.
-For example:
-.br
-.nf
-.if t .ft CW
- % sfdisk --print-id /dev/hdb 5
- 6
- % sfdisk --change-id /dev/hdb 5 83
- OK
-.if t .ft R
-.fi
-first reports that /dev/hdb5 has Id 6, and then changes that into 83.
-.TP
-.BR \-u ", " \-\-unit " \fIletter\fR"
-Interpret the input and show the output in the units specified by
-.IR letter .
-This \fIletter\fR can be one of S, C, B or M, meaning Sectors, Cylinders,
-Blocks and Megabytes, respectively. The default is
-cylinders, at least when the geometry is known.
-.TP
-.BR \-x ", " \-\-show\-extended
-Also list non-primary extended partitions on output,
-and expect descriptors for them on input.
-.TP
-.BR \-C ", " \-\-cylinders " \fIcylinders\fR"
-Specify the number of cylinders, possibly overriding what the kernel thinks.
-.TP
-.BR \-H ", " \-\-heads " \fIheads\fR"
-Specify the number of heads, possibly overriding what the kernel thinks.
-.TP
-.BR \-S ", " \-\-sectors " \fIsectors\fR"
-Specify the number of sectors, possibly overriding what the kernel thinks.
-.TP
-.BR \-f ", " \-\-force
-Do what I say, even if it is stupid.
-.TP
-.BR \-q ", " \-\-quiet
-Suppress warning messages.
-.TP
-.BR \-L ", " \-\-Linux
-Do not complain about things irrelevant for Linux.
-.TP
-.BR \-D ", " \-\-DOS
-For DOS-compatibility: waste a little space.
-(More precisely: if a partition cannot contain sector 0,
-e.g. because that is the MBR of the device, or contains
-the partition table of an extended partition, then
-.B sfdisk
-would make it start the next sector. However, when this
-option is given it skips to the start of the next track,
-wasting for example 33 sectors (in case of 34 sectors/track),
-just like certain versions of DOS do.)
-Certain Disk Managers and boot loaders (such as OSBS, but not
-LILO or the OS/2 Boot Manager) also live in this empty space,
-so maybe you want this option if you use one.
-.TP
-.BR \-E ", " \-\-DOS\-extended
-Take the starting sector numbers of "inner" extended partitions
-to be relative to the starting cylinder boundary of the outer one
-(like some versions of DOS do), rather than relative to the actual
-starting sector (like Linux does).
-(The fact that there is a difference here means that one should
-always let extended partitions start at cylinder boundaries if
-DOS and Linux should interpret the partition table in the same way.
-Of course one can only know where cylinder boundaries are when
-one knows what geometry DOS will use for this disk.)
-.TP
-.BR \-\-IBM ", " \-\-leave\-last
-Certain IBM diagnostic programs assume that they can use the
-last cylinder on a disk for disk-testing purposes. If you think
-you might ever run such programs, use this option to tell
-.B sfdisk
-that it should not allocate the last cylinder.
-Sometimes the last cylinder contains a bad sector table.
-.TP
-.B \-n
-Go through all the motions, but do not actually write to disk.
-.TP
-.BR \-R ", " \-\-re-read
-Only execute the BLKRRPART ioctl (to make the kernel re-read
-the partition table). This can be useful for checking in advance
-that the final BLKRRPART will be successful, and also when you
-changed the partition table `by hand' (e.g., using dd from a backup).
-If the kernel complains (`device busy for revalidation (usage = 2)')
-then something still uses the device, and you still have to unmount
-some file system, or say swapoff to some swap partition.
-.TP
-.B \-\-no\-reread
-When starting a repartitioning of a disk, \fBsfdisk\fR checks that this disk
-is not mounted, or in use as a swap device, and refuses to continue
-if it is. This option suppresses the test. (On the other hand, the \fB\-f\fR
-option would force \fBsfdisk\fR to continue even when this test fails.)
-.TP
-.B \-\-in\-order
-Caution, see warning section. To be documented.
-.TP
-.B \-\-not\-in\-order
-Caution, see warning section. To be documented.
-.TP
-.B \-\-inside\-outer
-Caution, see warning section. Chaining order.
-.TP
-.B \-\-not\-inside\-outer
-Caution, see warning section. Chaining order.
-.TP
-.B \-\-nested
-Caution, see warning section. Every partition is contained in the
-surrounding partitions and is disjoint from all others.
-.TP
-.B \-\-chained
-Caution, see warning section. Every data partition is contained in
-the surrounding partitions and disjoint from all others, but
-extended partitions may lie outside (insofar as allowed by
-all_logicals_inside_outermost_extended).
-.TP
-.B \-\-onesector
-Caution, see warning section. All data partitions are mutually
-disjoint; extended partitions each use one sector only (except
-perhaps for the outermost one).
-.TP
-.BI \-O " file"
-Just before writing the new partition, output the sectors
-that are going to be overwritten to
-.I file
-(where hopefully
-.I file
-resides on another disk, or on a floppy).
-.TP
-.BI \-I " file"
-After destroying your filesystems with an unfortunate
-.B sfdisk
-command, you would have been able to restore the old situation
-if only you had preserved it using the \fB\-O\fR flag.
-
-.SH THEORY
-Block 0 of a disk (the Master Boot Record) contains among
-other things four partition descriptors. The partitions
-described here are called
-.I primary
-partitions.
-.LP
-A partition descriptor has 6 fields:
-.br
-.nf
-.RS
-struct partition {
- unsigned char bootable; /* 0 or 0x80 */
- hsc begin_hsc;
- unsigned char id;
- hsc end_hsc;
- unsigned int starting_sector;
- unsigned int nr_of_sectors;
-}
-.RE
-.fi
-.LP
-The two hsc fields indicate head, sector and cylinder of the
-begin and the end of the partition. Since each hsc field only
-takes 3 bytes, only 24 bits are available, which does not
-suffice for big disks (say > 8GB). In fact, due to the wasteful
-representation (that uses a byte for the number of heads, which
-is typically 16), problems already start with 0.5GB.
-However Linux does not use these fields, and problems can arise
-only at boot time, before Linux has been started. For more
-details, see the
-.B lilo
-documentation.
-.LP
-Each partition has a type, its `Id', and if this type is 5 or f
-.IR "" "(`" "extended partition" "')"
-the starting sector of the partition
-again contains 4 partition descriptors. MSDOS only uses the
-first two of these: the first one an actual data partition,
-and the second one again an extended partition (or empty).
-In this way one gets a chain of extended partitions.
-Other operating systems have slightly different conventions.
-Linux also accepts type 85 as equivalent to 5 and f - this can be
-useful if one wants to have extended partitions under Linux past
-the 1024 cylinder boundary, without DOS FDISK hanging.
-(If there is no good reason, you should just use 5, which is
-understood by other systems.)
-.LP
-Partitions that are not primary or extended are called
-.IR logical .
-Often, one cannot boot from logical partitions (because the
-process of finding them is more involved than just looking
-at the MBR).
-Note that of an extended partition only the Id and the start
-are used. There are various conventions about what to write
-in the other fields. One should not try to use extended partitions
-for data storage or swap.
-
-.SH "INPUT FORMAT"
-.B sfdisk
-reads lines of the form
-.br
-.RS
-<start> <size> <id> <bootable> <c,h,s> <c,h,s>
-.RE
-where each line fills one partition descriptor.
-.LP
-Fields are separated by whitespace, or comma or semicolon possibly
-followed by whitespace; initial and trailing whitespace is ignored.
-Numbers can be octal, decimal or hexadecimal, decimal is default.
-When a field is absent or empty, a default value is used.
-.LP
-The <c,h,s> parts can (and probably should) be omitted -
-.B sfdisk
-computes them from <start> and <size> and the disk geometry
-as given by the kernel or specified using the \-H, \-S, \-C flags.
-.LP
-Bootable is specified as [*|\-], with as default not-bootable.
-(The value of this field is irrelevant for Linux - when Linux
-runs it has been booted already - but might play a role for
-certain boot loaders and for other operating systems.
-For example, when there are several primary DOS partitions,
-DOS assigns C: to the first among these that is bootable.)
-.LP
-Id is given in hex, without the 0x prefix, or is [E|S|L|X], where
-L (LINUX_NATIVE (83)) is the default, S is LINUX_SWAP (82), E
-is EXTENDED_PARTITION (5), and X is LINUX_EXTENDED (85).
-.LP
-The default value of start is the first nonassigned sector/cylinder/...
-.LP
-The default value of size is as much as possible (until next
-partition or end-of-disk).
-.LP
-However, for the four partitions inside an extended partition,
-the defaults are: Linux partition, Extended partition, Empty, Empty.
-.LP
-But when the \-N option (change a single partition only) is given,
-the default for each field is its previous value.
-.LP
-A '+' can be specified instead of a number for size, which means
-as much as possible. This is useful with the \-N option.
-.SH EXAMPLE
-The command
-.RS
-.nf
-.if t .ft CW
-sfdisk /dev/hdc << EOF
-0,407
-,407
-;
-;
-EOF
-.if t .ft R
-.fi
-.RE
-will partition /dev/hdc just as indicated above.
-
-The command
-.RS
-.nf
-.if t .ft CW
-sfdisk /dev/hdb << EOF
-,3,L
-,60,L
-,19,S
-,,E
-,130,L
-,130,L
-,130,L
-,,L
-EOF
-.if t .ft R
-.fi
-.RE
-will partition /dev/hdb into two Linux partitions of 3 and 60
-cylinders, a swap space of 19 cylinders, and an extended partition
-covering the rest. Inside the extended partition there are four
-Linux logical partitions, three of 130 cylinders and one
-covering the rest.
-
-With the \-x option, the number of input lines must be a multiple of 4:
-you have to list the two empty partitions that you never want
-using two blank lines. Without the \-x option, you give one line
-for the partitions inside a extended partition, instead of four,
-and terminate with end-of-file (^D).
-(And
-.B sfdisk
-will assume that your input line represents the first of four,
-that the second one is extended, and the 3rd and 4th are empty.)
-.SH "CAUTION WARNINGS"
-
-The options marked with caution in the manual page are dangerous.
-For example not all functionality is completely implemented,
-which can be a reason for unexpected results.
-.SH "DOS 6.x WARNING"
-
-The DOS 6.x FORMAT command looks for some information in the first
-sector of the data area of the partition, and treats this information
-as more reliable than the information in the partition table. DOS
-FORMAT expects DOS FDISK to clear the first 512 bytes of the data area
-of a partition whenever a size change occurs. DOS FORMAT will look at
-this extra information even if the /U flag is given -- we consider
-this a bug in DOS FORMAT and DOS FDISK.
-.LP
-The bottom line is that if you use sfdisk to change the size of a
-DOS partition table entry, then you must also use
-.B dd
-to zero the first 512 bytes of that partition before using DOS FORMAT to
-format the partition. For example, if you were using sfdisk to make a DOS
-partition table entry for /dev/hda1, then (after exiting sfdisk and
-rebooting Linux so that the partition table information is valid) you
-would use the command "dd if=/dev/zero of=/dev/hda1 bs=512 count=1" to zero
-the first 512 bytes of the partition.
-.B BE EXTREMELY CAREFUL
-if you use the
-.B dd
-command, since a small typo can make all of the data on your disk useless.
-
-For best results, you should always use an OS-specific partition table
-program. For example, you should make DOS partitions with the DOS FDISK
-program and Linux partitions with the Linux sfdisk program.
-
-.SH "DRDOS WARNINGS"
-
-Stephen Tweedie reported (930515): `Most reports of superblock
-corruption turn out to be due to bad partitioning, with one filesystem
-overrunning the start of the next and corrupting its superblock.
-I have even had this problem with the supposedly-reliable DRDOS. This
-was quite possibly due to DRDOS-6.0's FDISK command. Unless I created
-a blank track or cylinder between the DRDOS partition and the
-immediately following one, DRDOS would happily stamp all over the
-start of the next partition. Mind you, as long as I keep a little
-free disk space after any DRDOS partition, I don't have any other
-problems with the two coexisting on the one drive.'
-
-A. V. Le Blanc writes in README.efdisk: `Dr. DOS 5.0 and 6.0 has been
-reported to have problems cooperating with Linux, and with this version
-of efdisk in particular. This efdisk sets the system type
-to hexadecimal 81. Dr. DOS seems to confuse
-this with hexadecimal 1, a DOS code. If you use Dr. DOS, use the
-efdisk command 't' to change the system code of any Linux partitions
-to some number less than hexadecimal 80; I suggest 41 and 42 for
-the moment.'
-
-A. V. Le Blanc writes in his README.fdisk: `DR-DOS 5.0 and 6.0
-are reported to have difficulties with partition ID codes of 80 or more.
-The Linux `fdisk' used to set the system type
-of new partitions to hexadecimal 81. DR-DOS seems to confuse this with
-hexadecimal 1, a DOS code. The values 82 for swap and 83 for file
-systems should not cause problems with DR-DOS. If they do, you may use
-the `fdisk' command `t' to change the system code of any Linux
-partitions to some number less than hexadecimal 80; I suggest 42 and 43
-for the moment.'
-
-In fact, it seems that only 4 bits are significant for the DRDOS FDISK,
-so that for example 11 and 21 are listed as DOS 2.0. However, DRDOS
-itself seems to use the full byte. I have not been able to reproduce
-any corruption with DRDOS or its fdisk.
-
-.SH BUGS
-There are too many options.
-.LP
-There is no support for non-DOS partition types.
-
-.\" .SH AUTHOR
-.\" A. E. Brouwer (aeb@cwi.nl)
-.\"
-.SH "SEE ALSO"
-.BR cfdisk (8),
-.BR fdisk (8),
-.BR mkfs (8),
-.BR parted (8),
-.BR partprobe (8),
-.BR kpartx (8)
-.SH AVAILABILITY
-The sfdisk command is part of the util-linux package and is available from
-ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/fdisk/sfdisk.c b/fdisk/sfdisk.c
deleted file mode 100644
index c9853867a..000000000
--- a/fdisk/sfdisk.c
+++ /dev/null
@@ -1,3242 +0,0 @@
-/*
- * sfdisk version 3.0 - aeb - 950813
- *
- * Copyright (C) 1995 Andries E. Brouwer (aeb@cwi.nl)
- *
- * This program is free software. You can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation: either Version 1
- * or (at your option) any later version.
- *
- * A.V. Le Blanc (LeBlanc@mcc.ac.uk) wrote Linux fdisk 1992-1994,
- * patched by various people (faith@cs.unc.edu, martin@cs.unc.edu,
- * leisner@sdsp.mc.xerox.com, esr@snark.thyrsus.com, aeb@cwi.nl)
- * 1993-1995, with version numbers (as far as I have seen) 0.93 - 2.0e.
- * This program had (head,sector,cylinder) as basic unit, and was
- * (therefore) broken in several ways for the use on larger disks -
- * for example, my last patch (from 2.0d to 2.0e) was required
- * to allow a partition to cross cylinder 8064, and to write an
- * extended partition past the 4GB mark.
- *
- * The current program is a rewrite from scratch, and I started a
- * version numbering at 3.0.
- * Andries Brouwer, aeb@cwi.nl, 950813
- *
- * Well, a good user interface is still lacking. On the other hand,
- * many configurations cannot be handled by any other fdisk.
- * I changed the name to sfdisk to prevent confusion. - aeb, 970501
- */
-
-#define PROGNAME "sfdisk"
-
-#include <stdio.h>
-#include <stdlib.h> /* atoi, free */
-#include <stdarg.h> /* varargs */
-#include <unistd.h> /* read, write */
-#include <fcntl.h> /* O_RDWR */
-#include <errno.h> /* ERANGE */
-#include <string.h> /* strchr(), strrchr() */
-#include <ctype.h>
-#include <getopt.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <limits.h>
-
-#include "c.h"
-#include "nls.h"
-#include "xalloc.h"
-#include "blkdev.h"
-#include "linux_version.h"
-#include "common.h"
-#include "wholedisk.h"
-#include "gpt.h"
-#include "pathnames.h"
-#include "canonicalize.h"
-#include "rpmatch.h"
-#include "closestream.h"
-#include "strutils.h"
-
-/*
- * Table of contents:
- * A. About seeking
- * B. About sectors
- * C. About heads, sectors and cylinders
- * D. About system Ids
- * E. About partitions
- * F. The standard input
- * G. The command line
- * H. Listing the current situation
- * I. Writing the new situation
- */
-int exit_status = 0;
-
-int force = 0; /* 1: do what I say, even if it is stupid ... */
-int quiet = 0; /* 1: suppress all warnings */
-/* IA-64 gcc spec file currently does -DLinux... */
-#undef Linux
-int Linux = 0; /* 1: suppress warnings irrelevant for Linux */
-int DOS = 0; /* 1: shift extended partitions by #sectors, not 1 */
-int DOS_extended = 0; /* 1: use starting cylinder boundary of extd partn */
-int dump = 0; /* 1: list in a format suitable for later input */
-int verify = 0; /* 1: check that listed partition is reasonable */
-int no_write = 0; /* 1: do not actually write to disk */
-int no_reread = 0; /* 1: skip the BLKRRPART ioctl test at startup */
-int leave_last = 0; /* 1: don't allocate the last cylinder */
-int opt_list = 0;
-char *save_sector_file = NULL;
-char *restore_sector_file = NULL;
-
-static void
-my_warn(char *s, ...) {
- va_list p;
-
- va_start(p, s);
- if (!quiet) {
- fflush(stdout);
- vfprintf(stderr, s, p);
- fflush(stderr);
- }
- va_end(p);
-}
-
-static void
-error(char *s, ...) {
- va_list p;
-
- va_start(p, s);
- fflush(stdout);
- fprintf(stderr, "\n" PROGNAME ": ");
- vfprintf(stderr, s, p);
- fflush(stderr);
- va_end(p);
-}
-
-/*
- * A. About seeking
- */
-
-/*
- * sseek: seek to specified sector - return 0 on failure
- *
- * Note: we use 512-byte sectors here, irrespective of the hardware ss.
- */
-
-static int
-sseek(char *dev, int fd, unsigned long s) {
- off_t in, out;
- in = ((off_t) s << 9);
-
- if ((out = lseek(fd, in, SEEK_SET)) != in) {
- perror("lseek");
- error(_("seek error on %s - cannot seek to %lu\n"), dev, s);
- return 0;
- }
-
- if (in != out) {
- error(_("seek error: wanted 0x%08x%08x, got 0x%08x%08x\n"),
- (unsigned int)(in >> 32), (unsigned int)(in & 0xffffffff),
- (unsigned int)(out >> 32), (unsigned int)(out & 0xffffffff));
- return 0;
- }
- return 1;
-}
-
-/*
- * B. About sectors
- */
-
-/*
- * We preserve all sectors read in a chain - some of these will
- * have to be modified and written back.
- */
-struct sector {
- struct sector *next;
- unsigned long long sectornumber;
- int to_be_written;
- char data[512];
-} *sectorhead;
-
-static void
-free_sectors(void) {
- struct sector *s;
-
- while (sectorhead) {
- s = sectorhead;
- sectorhead = s->next;
- free(s);
- }
-}
-
-static struct sector *
-get_sector(char *dev, int fd, unsigned long long sno) {
- struct sector *s;
-
- for (s = sectorhead; s; s = s->next)
- if (s->sectornumber == sno)
- return s;
-
- if (!sseek(dev, fd, sno))
- return 0;
-
- s = xmalloc(sizeof(struct sector));
-
- if (read(fd, s->data, sizeof(s->data)) != sizeof(s->data)) {
- if (errno) /* 0 in case we read past end-of-disk */
- perror("read");
- error(_("read error on %s - cannot read sector %lu\n"), dev, sno);
- free(s);
- return 0;
- }
-
- s->next = sectorhead;
- sectorhead = s;
- s->sectornumber = sno;
- s->to_be_written = 0;
-
- return s;
-}
-
-static int
-msdos_signature(struct sector *s) {
- unsigned char *data = (unsigned char *)s->data;
- if (data[510] == 0x55 && data[511] == 0xaa)
- return 1;
- return 0;
-}
-
-static int
-write_sectors(char *dev, int fd) {
- struct sector *s;
-
- for (s = sectorhead; s; s = s->next)
- if (s->to_be_written) {
- if (!sseek(dev, fd, s->sectornumber))
- return 0;
- if (write(fd, s->data, sizeof(s->data)) != sizeof(s->data)) {
- perror("write");
- error(_("write error on %s - cannot write sector %lu\n"),
- dev, s->sectornumber);
- return 0;
- }
- s->to_be_written = 0;
- }
- return 1;
-}
-
-static void
-ulong_to_chars(unsigned long u, char *uu) {
- int i;
-
- for (i = 0; i < 4; i++) {
- uu[i] = (u & 0xff);
- u >>= 8;
- }
-}
-
-static unsigned long
-chars_to_ulong(unsigned char *uu) {
- int i;
- unsigned long u = 0;
-
- for (i = 3; i >= 0; i--)
- u = (u << 8) | uu[i];
- return u;
-}
-
-static int
-save_sectors(char *dev, int fdin) {
- struct sector *s;
- char ss[516];
- int fdout = -1;
-
- fdout = open(save_sector_file, O_WRONLY | O_CREAT, 0444);
- if (fdout < 0) {
- perror(save_sector_file);
- error(_("cannot open partition sector save file (%s)\n"),
- save_sector_file);
- goto err;
- }
-
- for (s = sectorhead; s; s = s->next)
- if (s->to_be_written) {
- ulong_to_chars(s->sectornumber, ss);
- if (!sseek(dev, fdin, s->sectornumber))
- goto err;
- if (read(fdin, ss + 4, 512) != 512) {
- perror("read");
- error(_("read error on %s - cannot read sector %lu\n"),
- dev, s->sectornumber);
- goto err;
- }
- if (write(fdout, ss, sizeof(ss)) != sizeof(ss)) {
- perror("write");
- error(_("write error on %s\n"), save_sector_file);
- goto err;
- }
- }
-
- close(fdout);
- return 1;
-
- err:
- if (fdout >= 0)
- close(fdout);
- return 0;
-}
-
-static int reread_disk_partition(char *dev, int fd);
-
-static int
-restore_sectors(char *dev) {
- int fdin = -1, fdout = -1;
- int ct;
- struct stat statbuf;
- char *ss0 = NULL, *ss;
- unsigned long sno;
-
- if (stat(restore_sector_file, &statbuf) < 0) {
- perror(restore_sector_file);
- error(_("cannot stat partition restore file (%s)\n"),
- restore_sector_file);
- goto err;
- }
- if (statbuf.st_size % 516) {
- error(_("partition restore file has wrong size - not restoring\n"));
- goto err;
- }
-
- ss0 = xmalloc(statbuf.st_size);
- ss = ss0;
-
- fdin = open(restore_sector_file, O_RDONLY);
- if (fdin < 0) {
- perror(restore_sector_file);
- error(_("cannot open partition restore file (%s)\n"),
- restore_sector_file);
- goto err;
- }
- if (read(fdin, ss, statbuf.st_size) != statbuf.st_size) {
- perror("read");
- error(_("error reading %s\n"), restore_sector_file);
- goto err;
- }
-
- fdout = open(dev, O_WRONLY);
- if (fdout < 0) {
- perror(dev);
- error(_("cannot open device %s for writing\n"), dev);
- goto err;
- }
-
- ct = statbuf.st_size / 516;
- while (ct--) {
- sno = chars_to_ulong((unsigned char *)ss);
- if (!sseek(dev, fdout, sno))
- goto err;
- if (write(fdout, ss + 4, 512) != 512) {
- perror(dev);
- error(_("error writing sector %lu on %s\n"), sno, dev);
- goto err;
- }
- ss += 516;
- }
- free(ss0);
- ss0 = NULL;
-
- if (!reread_disk_partition(dev, fdout)) /* closes fdout */
- goto err;
- close(fdin);
-
- return 1;
-
- err:
- free(ss0);
- if (fdin >= 0)
- close(fdin);
- if (fdout >= 0)
- close(fdout);
-
- return 0;
-}
-
-/*
- * C. About heads, sectors and cylinders
- */
-
-/*
- * <linux/hdreg.h> defines HDIO_GETGEO and
- * struct hd_geometry {
- * unsigned char heads;
- * unsigned char sectors;
- * unsigned short cylinders;
- * unsigned long start;
- * };
- *
- * For large disks g.cylinders is truncated, so we use BLKGETSIZE.
- */
-
-/*
- * We consider several geometries for a disk:
- * B - the BIOS geometry, gotten from the kernel via HDIO_GETGEO
- * F - the fdisk geometry
- * U - the user-specified geometry
- *
- * 0 means unspecified / unknown
- */
-struct geometry {
- unsigned long long total_size; /* in sectors */
- unsigned long cylindersize; /* in sectors */
- unsigned long heads, sectors, cylinders;
- unsigned long start;
-} B, F, U;
-
-static struct geometry
-get_geometry(char *dev, int fd, int silent) {
- struct hd_geometry g;
- unsigned long cyls;
- unsigned long long sectors;
- struct geometry R;
-
-#ifdef HDIO_GETGEO
- if (ioctl(fd, HDIO_GETGEO, &g))
-#endif
- {
- g.heads = g.sectors = g.cylinders = g.start = 0;
- if (!silent)
- warnx(_("Disk %s: cannot get geometry\n"), dev);
- }
-
- R.start = g.start;
- R.heads = g.heads;
- R.sectors = g.sectors;
- R.cylindersize = R.heads * R.sectors;
- R.cylinders = 0;
- R.total_size = 0;
-
- if (blkdev_get_sectors(fd, &sectors) == -1) {
- /* maybe an ordinary file */
- struct stat s;
-
- if (fstat(fd, &s) == 0 && S_ISREG(s.st_mode))
- R.total_size = (s.st_size >> 9);
- else if (!silent)
- warnx(_("Disk %s: cannot get size\n"), dev);
- } else
- R.total_size = sectors;
-
- if (R.cylindersize && R.total_size) {
- sectors /= R.cylindersize;
- cyls = sectors;
- if (cyls != sectors)
- cyls = ~0;
- R.cylinders = cyls;
- }
-
- return R;
-}
-
-static void
-get_cylindersize(char *dev, int fd, int silent) {
- struct geometry R;
-
- R = get_geometry(dev, fd, silent);
-
- B.heads = (U.heads ? U.heads : R.heads ? R.heads : 255);
- B.sectors = (U.sectors ? U.sectors : R.sectors ? R.sectors : 63);
- B.cylinders = (U.cylinders ? U.cylinders : R.cylinders);
-
- B.cylindersize = B.heads * B.sectors;
- B.total_size = R.total_size;
-
- if (B.cylinders == 0 && B.cylindersize != 0)
- B.cylinders = B.total_size / B.cylindersize;
-
- if (R.start && !force) {
- my_warn(_("Warning: start=%lu - this looks like a partition rather than\n"
- "the entire disk. Using fdisk on it is probably meaningless.\n"
- "[Use the --force option if you really want this]\n"),
- R.start);
- exit(1);
- }
-#if 0
- if (R.heads && B.heads != R.heads)
- my_warn(_("Warning: HDIO_GETGEO says that there are %lu heads\n"),
- R.heads);
- if (R.sectors && B.sectors != R.sectors)
- my_warn(_("Warning: HDIO_GETGEO says that there are %lu sectors\n"),
- R.sectors);
- if (R.cylinders && B.cylinders != R.cylinders
- && B.cylinders < 65536 && R.cylinders < 65536)
- my_warn(_("Warning: BLKGETSIZE/HDIO_GETGEO says that there are %lu cylinders\n"),
- R.cylinders);
-#endif
-
- if (B.sectors > 63)
- my_warn(_("Warning: unlikely number of sectors (%lu) - usually at most 63\n"
- "This will give problems with all software that uses C/H/S addressing.\n"),
- B.sectors);
- if (!silent)
- printf(_("\nDisk %s: %lu cylinders, %lu heads, %lu sectors/track\n"),
- dev, B.cylinders, B.heads, B.sectors);
-}
-
-typedef struct {
- unsigned char h, s, c;
-} __attribute__ ((packed)) chs; /* has some c bits in s */
-chs zero_chs = { 0, 0, 0 };
-
-typedef struct {
- unsigned long h, s, c;
-} longchs;
-longchs zero_longchs;
-
-static chs
-longchs_to_chs(longchs aa, struct geometry G) {
- chs a;
-
- if (aa.h < 256 && aa.s < 64 && aa.c < 1024) {
- a.h = aa.h;
- a.s = aa.s | ((aa.c >> 2) & 0xc0);
- a.c = (aa.c & 0xff);
- } else if (G.heads && G.sectors) {
- a.h = G.heads - 1;
- a.s = G.sectors | 0xc0;
- a.c = 0xff;
- } else
- a = zero_chs;
- return a;
-}
-
-static longchs
-chs_to_longchs(chs a) {
- longchs aa;
-
- aa.h = a.h;
- aa.s = (a.s & 0x3f);
- aa.c = (a.s & 0xc0);
- aa.c = (aa.c << 2) + a.c;
- return aa;
-}
-
-static longchs
-ulong_to_longchs(unsigned long sno, struct geometry G) {
- longchs aa;
-
- if (G.heads && G.sectors && G.cylindersize) {
- aa.s = 1 + sno % G.sectors;
- aa.h = (sno / G.sectors) % G.heads;
- aa.c = sno / G.cylindersize;
- return aa;
- } else {
- return zero_longchs;
- }
-}
-
-static chs
-ulong_to_chs(unsigned long sno, struct geometry G) {
- return longchs_to_chs(ulong_to_longchs(sno, G), G);
-}
-
-#if 0
-static unsigned long
-longchs_to_ulong(longchs aa, struct geometry G) {
- return (aa.c * G.cylindersize + aa.h * G.sectors + aa.s - 1);
-}
-
-static unsigned long
-chs_to_ulong(chs a, struct geometry G) {
- return longchs_to_ulong(chs_to_longchs(a), G);
-}
-#endif
-
-static int
-is_equal_chs(chs a, chs b) {
- return (a.h == b.h && a.s == b.s && a.c == b.c);
-}
-
-static int
-chs_ok(chs a, char *v, char *w) {
- longchs aa = chs_to_longchs(a);
- int ret = 1;
-
- if (is_equal_chs(a, zero_chs))
- return 1;
- if (B.heads && aa.h >= B.heads) {
- my_warn(_("%s of partition %s has impossible value for head: "
- "%lu (should be in 0-%lu)\n"), w, v, aa.h, B.heads - 1);
- ret = 0;
- }
- if (B.sectors && (aa.s == 0 || aa.s > B.sectors)) {
- my_warn(_("%s of partition %s has impossible value for sector: "
- "%lu (should be in 1-%lu)\n"), w, v, aa.s, B.sectors);
- ret = 0;
- }
- if (B.cylinders && aa.c >= B.cylinders) {
- my_warn(_("%s of partition %s has impossible value for cylinders: "
- "%lu (should be in 0-%lu)\n"), w, v, aa.c, B.cylinders - 1);
- ret = 0;
- }
- return ret;
-}
-
-/*
- * D. About system Ids
- */
-
-#define EMPTY_PARTITION 0
-#define EXTENDED_PARTITION 5
-#define WIN98_EXTENDED 0x0f
-#define DM6_AUX1PARTITION 0x51
-#define DM6_AUX3PARTITION 0x53
-#define DM6_PARTITION 0x54
-#define EZD_PARTITION 0x55
-#define LINUX_SWAP 0x82
-#define LINUX_NATIVE 0x83
-#define LINUX_EXTENDED 0x85
-#define BSD_PARTITION 0xa5
-#define NETBSD_PARTITION 0xa9
-
-/* List of partition types now in i386_sys_types.c */
-
-static const char *
-sysname(unsigned char type) {
- struct systypes *s;
-
- for (s = i386_sys_types; s->name; s++)
- if (s->type == type)
- return _(s->name);
- return _("Unknown");
-}
-
-static void
-list_types(void) {
- struct systypes *s;
-
- printf(_("Id Name\n\n"));
- for (s = i386_sys_types; s->name; s++)
- printf("%2x %s\n", s->type, _(s->name));
-}
-
-static int
-is_extended(unsigned char type) {
- return (type == EXTENDED_PARTITION
- || type == LINUX_EXTENDED || type == WIN98_EXTENDED);
-}
-
-static int
-is_bsd(unsigned char type) {
- return (type == BSD_PARTITION || type == NETBSD_PARTITION);
-}
-
-/*
- * E. About partitions
- */
-
-/* MS/DOS partition */
-
-struct partition {
- unsigned char bootable; /* 0 or 0x80 */
- chs begin_chs;
- unsigned char sys_type;
- chs end_chs;
- unsigned int start_sect; /* starting sector counting from 0 */
- unsigned int nr_sects; /* nr of sectors in partition */
-} __attribute__ ((packed));
-
-/* Unfortunately, partitions are not aligned, and non-Intel machines
- are unhappy with non-aligned integers. So, we need a copy by hand. */
-static int
-copy_to_int(unsigned char *cp) {
- unsigned int m;
-
- m = *cp++;
- m += (*cp++ << 8);
- m += (*cp++ << 16);
- m += (*cp++ << 24);
- return m;
-}
-
-static void
-copy_from_int(int m, char *cp) {
- *cp++ = (m & 0xff);
- m >>= 8;
- *cp++ = (m & 0xff);
- m >>= 8;
- *cp++ = (m & 0xff);
- m >>= 8;
- *cp++ = (m & 0xff);
-}
-
-static void
-copy_to_part(char *cp, struct partition *p) {
- p->bootable = *cp++;
- p->begin_chs.h = *cp++;
- p->begin_chs.s = *cp++;
- p->begin_chs.c = *cp++;
- p->sys_type = *cp++;
- p->end_chs.h = *cp++;
- p->end_chs.s = *cp++;
- p->end_chs.c = *cp++;
- p->start_sect = copy_to_int((unsigned char *)cp);
- p->nr_sects = copy_to_int((unsigned char *)cp + 4);
-}
-
-static void
-copy_from_part(struct partition *p, char *cp) {
- *cp++ = p->bootable;
- *cp++ = p->begin_chs.h;
- *cp++ = p->begin_chs.s;
- *cp++ = p->begin_chs.c;
- *cp++ = p->sys_type;
- *cp++ = p->end_chs.h;
- *cp++ = p->end_chs.s;
- *cp++ = p->end_chs.c;
- copy_from_int(p->start_sect, cp);
- copy_from_int(p->nr_sects, cp + 4);
-}
-
-/* Roughly speaking, Linux doesn't use any of the above fields except
- for partition type, start sector and number of sectors. (However,
- see also linux/drivers/scsi/fdomain.c.)
- The only way partition type is used (in the kernel) is the comparison
- for equality with EXTENDED_PARTITION (and these Disk Manager types). */
-
-struct part_desc {
- unsigned long long start;
- unsigned long long size;
- unsigned long long sector, offset; /* disk location of this info */
- struct partition p;
- struct part_desc *ep; /* extended partition containing this one */
- int ptype;
-#define DOS_TYPE 0
-#define BSD_TYPE 1
-} zero_part_desc;
-
-static struct part_desc *
-outer_extended_partition(struct part_desc *p) {
- while (p->ep)
- p = p->ep;
- return p;
-}
-
-static int
-is_parent(struct part_desc *pp, struct part_desc *p) {
- while (p) {
- if (pp == p)
- return 1;
- p = p->ep;
- }
- return 0;
-}
-
-struct disk_desc {
- struct part_desc partitions[512];
- int partno;
-} oldp, newp;
-
-/* determine where on the disk this information goes */
-static void
-add_sector_and_offset(struct disk_desc *z) {
- int pno;
- struct part_desc *p;
-
- for (pno = 0; pno < z->partno; pno++) {
- p = &(z->partitions[pno]);
- p->offset = 0x1be + (pno % 4) * sizeof(struct partition);
- p->sector = (p->ep ? p->ep->start : 0);
- }
-}
-
-/* tell the kernel to reread the partition tables */
-static int
-reread_ioctl(int fd) {
-#ifdef BLKRRPART
- if (ioctl(fd, BLKRRPART))
-#else
- errno = ENOSYS;
-#endif
- {
- /* perror might change errno */
- int err = errno;
-
- perror("BLKRRPART");
-
- /* 2.6.8 returns EIO for a zero table */
- if (err == EBUSY)
- return -1;
- }
- return 0;
-}
-
-/* reread after writing */
-static int
-reread_disk_partition(char *dev, int fd) {
- printf(_("Re-reading the partition table ...\n"));
- fflush(stdout);
- sync();
-
- if (reread_ioctl(fd) && is_blkdev(fd)) {
- warnx(_("The command to re-read the partition table failed.\n"
- "Run partprobe(8), kpartx(8) or reboot your system now,\n"
- "before using mkfs\n"));
- return 0;
- }
-
- if (fsync(fd) || close(fd)) {
- perror(dev);
- warnx(_("Error closing %s\n"), dev);
- return 0;
- }
- printf("\n");
-
- return 1;
-}
-
-/* find Linux name of this partition, assuming that it will have a name */
-static int
-index_to_linux(int pno, struct disk_desc *z) {
- int i, ct = 1;
- struct part_desc *p = &(z->partitions[0]);
- for (i = 0; i < pno; i++, p++)
- if (i < 4 || (p->size > 0 && !is_extended(p->p.sys_type)))
- ct++;
- return ct;
-}
-
-static int
-linux_to_index(int lpno, struct disk_desc *z) {
- int i, ct = 0;
- struct part_desc *p = &(z->partitions[0]);
- for (i = 0; i < z->partno && ct < lpno; i++, p++)
- if ((i < 4 || (p->size > 0 && !is_extended(p->p.sys_type)))
- && ++ct == lpno)
- return i;
- return -1;
-}
-
-static int
-asc_to_index(char *pnam, struct disk_desc *z) {
- int pnum, pno;
-
- if (*pnam == '#') {
- pno = atoi(pnam + 1);
- } else {
- pnum = atoi(pnam);
- pno = linux_to_index(pnum, z);
- }
- if (!(pno >= 0 && pno < z->partno))
- errx(EXIT_FAILURE, _("%s: no such partition\n"), pnam);
- return pno;
-}
-
-/*
- * List partitions - in terms of sectors, blocks or cylinders
- */
-#define F_SECTOR 1
-#define F_BLOCK 2
-#define F_CYLINDER 3
-#define F_MEGABYTE 4
-
-int default_format = F_MEGABYTE;
-int specified_format = 0;
-int show_extended = 0;
-int one_only = 0;
-int one_only_pno;
-int increment = 0;
-
-static void
-set_format(char c) {
- switch (c) {
- default:
- warnx(_("unrecognized format - using sectors\n"));
- /* fallthrough */
- case 'S':
- specified_format = F_SECTOR;
- break;
- case 'B':
- specified_format = F_BLOCK;
- break;
- case 'C':
- specified_format = F_CYLINDER;
- break;
- case 'M':
- specified_format = F_MEGABYTE;
- break;
- }
-}
-
-static unsigned long
-unitsize(int format) {
- default_format = (B.cylindersize ? F_CYLINDER : F_MEGABYTE);
- if (!format && !(format = specified_format))
- format = default_format;
-
- switch (format) {
- default:
- case F_CYLINDER:
- if (B.cylindersize)
- return B.cylindersize;
- case F_SECTOR:
- return 1;
- case F_BLOCK:
- return 2;
- case F_MEGABYTE:
- return 2048;
- }
-}
-
-static unsigned long long
-get_disksize(int format) {
- if (B.total_size && leave_last)
- /* don't use last cylinder (--leave-last option) */
- return (B.total_size - B.cylindersize) / unitsize(format);
-
- return B.total_size / unitsize(format);
-}
-
-static void
-out_partition_header(char *dev, int format, struct geometry G) {
- if (dump) {
- printf("# partition table of %s\n", dev);
- printf("unit: sectors\n\n");
- return;
- }
-
- default_format = (G.cylindersize ? F_CYLINDER : F_MEGABYTE);
- if (!format && !(format = specified_format))
- format = default_format;
-
- switch (format) {
- default:
- warnx(_("unimplemented format - using %s\n"),
- G.cylindersize ? _("cylinders") : _("sectors"));
- case F_CYLINDER:
- if (G.cylindersize) {
- printf(_("Units: cylinders of %lu bytes, blocks of 1024 bytes"
- ", counting from %d\n\n"), G.cylindersize << 9, increment);
- printf(_(" Device Boot Start End #cyls #blocks Id System\n"));
- break;
- }
- /* fall through */
- case F_SECTOR:
- printf(_("Units: sectors of 512 bytes, counting from %d\n\n"),
- increment);
- printf(_(" Device Boot Start End #sectors Id System\n"));
- break;
- case F_BLOCK:
- printf(_("Units: blocks of 1024 bytes, counting from %d\n\n"),
- increment);
- printf(_(" Device Boot Start End #blocks Id System\n"));
- break;
- case F_MEGABYTE:
- printf(_("Units: 1MiB = 1024*1024 bytes, blocks of 1024 bytes"
- ", counting from %d\n\n"), increment);
- printf(_(" Device Boot Start End MiB #blocks Id System\n"));
- break;
- }
-}
-
-static void
-out_rounddown(int width, unsigned long long n, unsigned long unit, int inc) {
- printf("%*llu", width, inc + n / unit);
- if (unit != 1)
- putchar((n % unit) ? '+' : ' ');
- putchar(' ');
-}
-
-static void
-out_roundup(int width, unsigned long long n, unsigned long unit, int inc) {
- if (n == (unsigned long long)(-1))
- printf("%*s", width, "-");
- else
- printf("%*llu", width, inc + n / unit);
- if (unit != 1)
- putchar(((n + 1) % unit) ? '-' : ' ');
- putchar(' ');
-}
-
-static void
-out_roundup_size(int width, unsigned long long n, unsigned long unit) {
- printf("%*llu", width, (n + unit - 1) / unit);
- if (unit != 1)
- putchar((n % unit) ? '-' : ' ');
- putchar(' ');
-}
-
-static struct geometry
-get_fdisk_geometry_one(struct part_desc *p) {
- struct geometry G;
-
- memset(&G, 0, sizeof(struct geometry));
- chs b = p->p.end_chs;
- longchs bb = chs_to_longchs(b);
- G.heads = bb.h + 1;
- G.sectors = bb.s;
- G.cylindersize = G.heads * G.sectors;
- return G;
-}
-
-static int
-get_fdisk_geometry(struct disk_desc *z) {
- struct part_desc *p;
- int pno, agree;
- struct geometry G0, G;
-
- memset(&G0, 0, sizeof(struct geometry));
- agree = 0;
- for (pno = 0; pno < z->partno; pno++) {
- p = &(z->partitions[pno]);
- if (p->size != 0 && p->p.sys_type != 0) {
- G = get_fdisk_geometry_one(p);
- if (!G0.heads) {
- G0 = G;
- agree = 1;
- } else if (G.heads != G0.heads || G.sectors != G0.sectors) {
- agree = 0;
- break;
- }
- }
- }
- F = (agree ? G0 : B);
- return (F.sectors != B.sectors || F.heads != B.heads);
-}
-
-static void
-out_partition(char *dev, int format, struct part_desc *p,
- struct disk_desc *z, struct geometry G) {
- unsigned long long start, end, size;
- int pno, lpno;
-
- if (!format && !(format = specified_format))
- format = default_format;
-
- pno = p - &(z->partitions[0]); /* our index */
- lpno = index_to_linux(pno, z); /* name of next one that has a name */
- if (pno == linux_to_index(lpno, z)) /* was that us? */
- printf("%s", partname(dev, lpno, 10)); /* yes */
- else if (show_extended)
- printf(" - ");
- else
- return;
- putchar(dump ? ':' : ' ');
-
- start = p->start;
- end = p->start + p->size - 1;
- size = p->size;
-
- if (dump) {
- printf(" start=%9llu", start);
- printf(", size=%9llu", size);
- if (p->ptype == DOS_TYPE) {
- printf(", Id=%2x", p->p.sys_type);
- if (p->p.bootable == 0x80)
- printf(", bootable");
- }
- printf("\n");
- return;
- }
-
- if (p->ptype != DOS_TYPE || p->p.bootable == 0)
- printf(" ");
- else if (p->p.bootable == 0x80)
- printf(" * ");
- else
- printf(" ? "); /* garbage */
-
- switch (format) {
- case F_CYLINDER:
- if (G.cylindersize) {
- out_rounddown(6, start, G.cylindersize, increment);
- out_roundup(6, end, G.cylindersize, increment);
- out_roundup_size(6, size, G.cylindersize);
- out_rounddown(9, size, 2, 0);
- break;
- }
- /* fall through */
- default:
- case F_SECTOR:
- out_rounddown(9, start, 1, increment);
- out_roundup(9, end, 1, increment);
- out_rounddown(10, size, 1, 0);
- break;
- case F_BLOCK:
-#if 0
- printf("%8lu,%3lu ",
- p->sector / 2, ((p->sector & 1) ? 512 : 0) + p->offset);
-#endif
- out_rounddown(8, start, 2, increment);
- out_roundup(8, end, 2, increment);
- out_rounddown(9, size, 2, 0);
- break;
- case F_MEGABYTE:
- out_rounddown(5, start, 2048, increment);
- out_roundup(5, end, 2048, increment);
- out_roundup_size(5, size, 2048);
- out_rounddown(9, size, 2, 0);
- break;
- }
- if (p->ptype == DOS_TYPE) {
- printf(" %2x %s\n", p->p.sys_type, sysname(p->p.sys_type));
- } else {
- printf("\n");
- }
-
- /* Is chs as we expect? */
- if (!quiet && p->ptype == DOS_TYPE) {
- chs a, b;
- longchs aa, bb;
- a = (size ? ulong_to_chs(start, G) : zero_chs);
- b = p->p.begin_chs;
- aa = chs_to_longchs(a);
- bb = chs_to_longchs(b);
- if (a.s && !is_equal_chs(a, b))
- warnx(_("\t\tstart: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"),
- aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
- a = (size ? ulong_to_chs(end, G) : zero_chs);
- b = p->p.end_chs;
- aa = chs_to_longchs(a);
- bb = chs_to_longchs(b);
- if (a.s && !is_equal_chs(a, b))
- warnx(_("\t\tend: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"),
- aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
- if (G.cylinders && G.cylinders < 1024 && bb.c > G.cylinders)
- warnx(_("partition ends on cylinder %ld, beyond the end of the disk\n"),
- bb.c);
- }
-}
-
-static void
-out_partitions(char *dev, struct disk_desc *z) {
- int pno, format = 0;
-
- if (z->partno == 0) {
- if (!opt_list)
- warnx(_("No partitions found\n"));
- } else {
- if (get_fdisk_geometry(z) && !dump) {
- warnx(_("Warning: The partition table looks like it was made\n"
- " for C/H/S=*/%ld/%ld (instead of %ld/%ld/%ld).\n"
- "For this listing I'll assume that geometry.\n"),
- F.heads, F.sectors, B.cylinders, B.heads, B.sectors);
- }
-
- out_partition_header(dev, format, F);
- for (pno = 0; pno < z->partno; pno++) {
- out_partition(dev, format, &(z->partitions[pno]), z, F);
- if (show_extended && pno % 4 == 3)
- printf("\n");
- }
- }
-}
-
-static int
-disj(struct part_desc *p, struct part_desc *q) {
- return ((p->start + p->size <= q->start)
- || (is_extended(p->p.sys_type)
- && q->start + q->size <= p->start + p->size));
-}
-
-static char *
-pnumber(struct part_desc *p, struct disk_desc *z) {
- static char buf[20];
- int this, next;
- struct part_desc *p0 = &(z->partitions[0]);
-
- this = index_to_linux(p - p0, z);
- next = index_to_linux(p - p0 + 1, z);
-
- if (next > this)
- sprintf(buf, "%d", this);
- else
- sprintf(buf, "[%d]", this);
- return buf;
-}
-
-static int
-partitions_ok(int fd, struct disk_desc *z) {
- struct part_desc *partitions = &(z->partitions[0]), *p, *q;
- int partno = z->partno;
-
-#define PNO(p) pnumber(p, z)
-
- /* Have at least 4 partitions been defined? */
- if (partno < 4) {
- if (!partno)
- errx(EXIT_FAILURE, _("no partition table present."));
- else
- errx(EXIT_FAILURE, _("strange, only %d partitions defined."), partno);
- return 0;
- }
-
- /* Are the partitions of size 0 marked empty?
- And do they have start = 0? And bootable = 0? */
- for (p = partitions; p - partitions < partno; p++)
- if (p->size == 0) {
- if (p->p.sys_type != EMPTY_PARTITION)
- my_warn(_("Warning: partition %s has size 0 but is not marked Empty\n"),
- PNO(p));
- else if (p->p.bootable != 0)
- my_warn(_("Warning: partition %s has size 0 and is bootable\n"),
- PNO(p));
- else if (p->p.start_sect != 0)
- my_warn(_("Warning: partition %s has size 0 and nonzero start\n"),
- PNO(p));
- /* all this is probably harmless, no error return */
- }
-
- /* Are the logical partitions contained in their extended partitions? */
- for (p = partitions + 4; p < partitions + partno; p++)
- if (p->ptype == DOS_TYPE)
- if (p->size && !is_extended(p->p.sys_type)) {
- q = p->ep;
- if (p->start < q->start
- || p->start + p->size > q->start + q->size) {
- my_warn(_("Warning: partition %s is not contained in "
- "partition %s\n"), PNO(p), PNO(q));
- return 0;
- }
- }
-
- /* Are the data partitions mutually disjoint? */
- for (p = partitions; p < partitions + partno; p++)
- if (p->size && !is_extended(p->p.sys_type))
- for (q = p + 1; q < partitions + partno; q++)
- if (q->size && !is_extended(q->p.sys_type))
- if (!((p->start > q->start) ? disj(q, p) : disj(p, q))) {
- my_warn(_("Warning: partitions %s and %s overlap\n"),
- PNO(p), PNO(q));
- return 0;
- }
-
- /* Are the data partitions and the extended partition
- table sectors disjoint? */
- for (p = partitions; p < partitions + partno; p++)
- if (p->size && !is_extended(p->p.sys_type))
- for (q = partitions; q < partitions + partno; q++)
- if (is_extended(q->p.sys_type))
- if (p->start <= q->start && p->start + p->size > q->start) {
- my_warn(_("Warning: partition %s contains part of "
- "the partition table (sector %llu),\n"
- "and will destroy it when filled\n"),
- PNO(p), q->start);
- return 0;
- }
-
- /* Do they start past zero and end before end-of-disk? */
- {
- unsigned long long ds = get_disksize(F_SECTOR);
- for (p = partitions; p < partitions + partno; p++)
- if (p->size) {
- if (p->start == 0) {
- my_warn(_("Warning: partition %s starts at sector 0\n"),
- PNO(p));
- return 0;
- }
- if (p->size && p->start + p->size > ds) {
- my_warn(_("Warning: partition %s extends past end of disk\n"),
- PNO(p));
- return 0;
- }
- }
- }
-
- int sector_size;
- if (blkdev_get_sector_size(fd, &sector_size) == -1)
- sector_size = DEFAULT_SECTOR_SIZE;
-
- /* Is the size of partitions less than 2^32 sectors limit? */
- for (p = partitions; p < partitions + partno; p++)
- if (p->size > UINT_MAX) {
- unsigned long long bytes = p->size * sector_size;
- int giga = bytes / 1000000000;
- int hectogiga = (giga + 50) / 100;
- my_warn(_("Warning: partition %s has size %d.%d TB (%llu bytes),\n"
- "which is larger than the %llu bytes limit imposed\n"
- "by the DOS partition table for %d-byte sectors\n"),
- PNO(p), hectogiga / 10, hectogiga % 10,
- bytes,
- (unsigned long long) UINT_MAX * sector_size,
- sector_size);
- return 0;
- }
-
- /* Do the partitions start below the 2^32 sectors limit? */
- for (p = partitions; p < partitions + partno; p++)
- if (p->start > UINT_MAX) {
- unsigned long long bytes = p->start * sector_size;
- int giga = bytes / 1000000000;
- int hectogiga = (giga + 50) / 100;
- my_warn(_("Warning: partition %s starts at sector %llu (%d.%d TB for %d-byte sectors),\n"
- "which exceeds the DOS partition table limit of %llu sectors\n"),
- PNO(p),
- p->start,
- hectogiga / 10,
- hectogiga % 10,
- sector_size,
- (unsigned long long) UINT_MAX);
- return 0;
- }
-
- /* At most one chain of DOS extended partitions ? */
- /* It seems that the OS/2 fdisk has the additional requirement
- that the extended partition must be the fourth one */
- {
- int ect = 0;
- for (p = partitions; p < partitions + 4; p++)
- if (p->p.sys_type == EXTENDED_PARTITION)
- ect++;
- if (ect > 1 && !Linux) {
- my_warn(_("Among the primary partitions, at most one can be extended\n"
- " (although this is not a problem under Linux)\n"));
- return 0;
- }
- }
-
- /*
- * Do all partitions start at a cylinder boundary ?
- * (this is not required for Linux)
- * The first partition starts after MBR.
- * Logical partitions start slightly after the containing extended partn.
- */
- if (B.cylindersize && !Linux) {
- for (p = partitions; p < partitions + partno; p++)
- if (p->size) {
- if (p->start % B.cylindersize != 0
- && (!p->ep
- || p->start / B.cylindersize !=
- p->ep->start / B.cylindersize)
- && (p->p.start_sect >= B.cylindersize)) {
- my_warn(_("Warning: partition %s does not start "
- "at a cylinder boundary\n"), PNO(p));
- if (specified_format == F_CYLINDER)
- return 0;
- }
- if ((p->start + p->size) % B.cylindersize) {
- my_warn(_("Warning: partition %s does not end "
- "at a cylinder boundary\n"), PNO(p));
- if (specified_format == F_CYLINDER)
- return 0;
- }
- }
- }
-
- /* Usually, one can boot only from primary partitions. */
- /* In fact, from a unique one only. */
- /* do not warn about bootable extended partitions -
- often LILO is there */
- {
- int pno = -1;
- for (p = partitions; p < partitions + partno; p++)
- if (p->p.bootable) {
- if (pno == -1)
- pno = p - partitions;
- else if (p - partitions < 4) {
- my_warn(_("Warning: more than one primary partition is marked "
- "bootable (active)\n"
- "This does not matter for LILO, but the DOS MBR will "
- "not boot this disk.\n"));
- break;
- }
- if (p - partitions >= 4) {
- my_warn(_("Warning: usually one can boot from primary partitions "
- "only\nLILO disregards the `bootable' flag.\n"));
- break;
- }
- }
- if (pno == -1 || pno >= 4)
- my_warn(_("Warning: no primary partition is marked bootable (active)\n"
- "This does not matter for LILO, but the DOS MBR will "
- "not boot this disk.\n"));
- }
-
- /* Is chs as we expect? */
- for (p = partitions; p < partitions + partno; p++)
- if (p->ptype == DOS_TYPE) {
- chs a, b;
- longchs aa, bb;
- a = p->size ? ulong_to_chs(p->start, B) : zero_chs;
- b = p->p.begin_chs;
- aa = chs_to_longchs(a);
- bb = chs_to_longchs(b);
- if (!Linux && !chs_ok(b, PNO(p), _("start")))
- return 0;
- if (a.s && !is_equal_chs(a, b))
- my_warn(_("partition %s: start: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"),
- PNO(p), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
- a = p->size ? ulong_to_chs(p->start + p->size - 1, B) : zero_chs;
- b = p->p.end_chs;
- aa = chs_to_longchs(a);
- bb = chs_to_longchs(b);
- if (!Linux && !chs_ok(b, PNO(p), _("end")))
- return 0;
- if (a.s && !is_equal_chs(a, b))
- my_warn(_("partition %s: end: (c,h,s) expected (%ld,%ld,%ld) found (%ld,%ld,%ld)\n"),
- PNO(p), aa.c, aa.h, aa.s, bb.c, bb.h, bb.s);
- if (B.cylinders && B.cylinders < 1024 && bb.c > B.cylinders)
- my_warn(_("partition %s ends on cylinder %ld, beyond the end of the disk\n"),
- PNO(p), bb.c);
- }
-
- return 1;
-
-#undef PNO
-}
-
-static void
-extended_partition(char *dev, int fd, struct part_desc *ep, struct disk_desc *z) {
- char *cp;
- struct sector *s;
- unsigned long long start, here, next;
- int i, moretodo = 1;
- struct partition p;
- struct part_desc *partitions = &(z->partitions[0]);
- size_t pno = z->partno;
-
- here = start = ep->start;
-
- if (B.cylindersize && start % B.cylindersize) {
- /* This is BAD */
- if (DOS_extended) {
- here = start -= (start % B.cylindersize);
- warnx(_("Warning: shifted start of the extd partition "
- "from %lld to %lld\n"
- "(For listing purposes only. "
- "Do not change its contents.)\n"), ep->start, start);
- } else {
- warnx(_("Warning: extended partition does not start at a "
- "cylinder boundary.\n"
- "DOS and Linux will interpret the contents differently.\n"));
- }
- }
-
- while (moretodo) {
- moretodo = 0;
-
- if (!(s = get_sector(dev, fd, here)))
- break;
-
- if (!msdos_signature(s)) {
- error(_("ERROR: sector %lu does not have an msdos signature\n"),
- s->sectornumber);
- break;
- }
- cp = s->data + 0x1be;
-
- if (pno + 4 >= ARRAY_SIZE(z->partitions)) {
- warnx(_("too many partitions - ignoring those past nr (%ld)\n"),
- pno - 1);
- break;
- }
-
- next = 0;
-
- for (i = 0; i < 4; i++, cp += sizeof(struct partition)) {
- partitions[pno].sector = here;
- partitions[pno].offset = cp - s->data;
- partitions[pno].ep = ep;
- copy_to_part(cp, &p);
- if (is_extended(p.sys_type)) {
- partitions[pno].start = start + p.start_sect;
- if (next)
- warnx(_("tree of partitions?\n"));
- else
- next = partitions[pno].start; /* follow `upper' branch */
- moretodo = 1;
- } else {
- partitions[pno].start = here + p.start_sect;
- }
- partitions[pno].size = p.nr_sects;
- partitions[pno].ptype = DOS_TYPE;
- partitions[pno].p = p;
- pno++;
- }
- here = next;
- }
-
- z->partno = pno;
-}
-
-#define BSD_DISKMAGIC (0x82564557UL)
-#define BSD_MAXPARTITIONS 16
-#define BSD_FS_UNUSED 0
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-struct bsd_disklabel {
- u32 d_magic;
- char d_junk1[4];
- char d_typename[16];
- char d_packname[16];
- char d_junk2[92];
- u32 d_magic2;
- char d_junk3[2];
- u16 d_npartitions; /* number of partitions in following */
- char d_junk4[8];
- struct bsd_partition { /* the partition table */
- u32 p_size; /* number of sectors in partition */
- u32 p_offset; /* starting sector */
- u32 p_fsize; /* filesystem basic fragment size */
- u8 p_fstype; /* filesystem type, see below */
- u8 p_frag; /* filesystem fragments per block */
- u16 p_cpg; /* filesystem cylinders per group */
- } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
-};
-
-static void
-bsd_partition(char *dev, int fd, struct part_desc *ep, struct disk_desc *z) {
- struct bsd_disklabel *l;
- struct bsd_partition *bp, *bp0;
- unsigned long long start = ep->start;
- struct sector *s;
- struct part_desc *partitions = &(z->partitions[0]);
- size_t pno = z->partno;
-
- if (!(s = get_sector(dev, fd, start + 1)))
- return;
- l = (struct bsd_disklabel *)(s->data);
- if (l->d_magic != BSD_DISKMAGIC || l->d_magic2 != BSD_DISKMAGIC)
- return;
-
- bp = bp0 = &l->d_partitions[0];
- while (bp - bp0 < BSD_MAXPARTITIONS && bp - bp0 < l->d_npartitions) {
- if (pno + 1 >= ARRAY_SIZE(z->partitions)) {
- warnx(_("too many partitions - ignoring those "
- "past nr (%ld)\n"), pno - 1);
- break;
- }
- if (bp->p_fstype != BSD_FS_UNUSED) {
- partitions[pno].start = bp->p_offset;
- partitions[pno].size = bp->p_size;
- partitions[pno].sector = start + 1;
- partitions[pno].offset = (char *)bp - (char *)bp0;
- partitions[pno].ep = 0;
- partitions[pno].ptype = BSD_TYPE;
- pno++;
- }
- bp++;
- }
- z->partno = pno;
-}
-
-static int
-msdos_partition(char *dev, int fd, unsigned long start, struct disk_desc *z) {
- int i;
- char *cp;
- struct partition pt;
- struct sector *s;
- struct part_desc *partitions = &(z->partitions[0]);
- int pno = z->partno;
- int bsd_later = 1;
-#ifdef __linux__
- bsd_later = (get_linux_version() >= KERNEL_VERSION(2, 3, 40));
-#endif
-
- if (!(s = get_sector(dev, fd, start)))
- return 0;
-
- if (!msdos_signature(s))
- return 0;
-
- cp = s->data + 0x1be;
- copy_to_part(cp, &pt);
-
- /* If I am not mistaken, recent kernels will hide this from us,
- so we will never actually see traces of a Disk Manager */
- if (pt.sys_type == DM6_PARTITION
- || pt.sys_type == EZD_PARTITION
- || pt.sys_type == DM6_AUX1PARTITION
- || pt.sys_type == DM6_AUX3PARTITION) {
- warnx(_("detected Disk Manager - unable to handle that\n"));
- return 0;
- }
-
- unsigned int sig = *(unsigned short *)(s->data + 2);
- if (sig <= 0x1ae
- && *(unsigned short *)(s->data + sig) == 0x55aa
- && (1 & *(unsigned char *)(s->data + sig + 2))) {
- warnx(_("DM6 signature found - giving up\n"));
- return 0;
- }
-
- for (pno = 0; pno < 4; pno++, cp += sizeof(struct partition)) {
- partitions[pno].sector = start;
- partitions[pno].offset = cp - s->data;
- copy_to_part(cp, &pt);
- partitions[pno].start = start + pt.start_sect;
- partitions[pno].size = pt.nr_sects;
- partitions[pno].ep = 0;
- partitions[pno].p = pt;
- }
-
- z->partno = pno;
-
- for (i = 0; i < 4; i++) {
- if (is_extended(partitions[i].p.sys_type)) {
- if (!partitions[i].size) {
- warnx(_("strange..., an extended partition of size 0?\n"));
- continue;
- }
- extended_partition(dev, fd, &partitions[i], z);
- }
- if (!bsd_later && is_bsd(partitions[i].p.sys_type)) {
- if (!partitions[i].size) {
- warnx(_("strange..., a BSD partition of size 0?\n"));
- continue;
- }
- bsd_partition(dev, fd, &partitions[i], z);
- }
- }
-
- if (bsd_later) {
- for (i = 0; i < 4; i++) {
- if (is_bsd(partitions[i].p.sys_type)) {
- if (!partitions[i].size) {
- warnx(_("strange..., a BSD partition of size 0?\n"));
- continue;
- }
- bsd_partition(dev, fd, &partitions[i], z);
- }
- }
- }
-
- return 1;
-}
-
-static int
-osf_partition(char *dev __attribute__ ((__unused__)),
- int fd __attribute__ ((__unused__)),
- unsigned long start __attribute__ ((__unused__)),
- struct disk_desc *z __attribute__ ((__unused__))) {
- return 0;
-}
-
-static int
-sun_partition(char *dev __attribute__ ((__unused__)),
- int fd __attribute__ ((__unused__)),
- unsigned long start __attribute__ ((__unused__)),
- struct disk_desc *z __attribute__ ((__unused__))) {
- return 0;
-}
-
-static int
-amiga_partition(char *dev __attribute__ ((__unused__)),
- int fd __attribute__ ((__unused__)),
- unsigned long start __attribute__ ((__unused__)),
- struct disk_desc *z __attribute__ ((__unused__))) {
- return 0;
-}
-
-static void
-get_partitions(char *dev, int fd, struct disk_desc *z) {
- z->partno = 0;
-
- if (!msdos_partition(dev, fd, 0, z)
- && !osf_partition(dev, fd, 0, z)
- && !sun_partition(dev, fd, 0, z)
- && !amiga_partition(dev, fd, 0, z)) {
- if (!opt_list)
- warnx(_(" %s: unrecognized partition table type\n"), dev);
- return;
- }
-}
-
-static int
-write_partitions(char *dev, int fd, struct disk_desc *z) {
- struct sector *s;
- struct part_desc *partitions = &(z->partitions[0]), *p;
- int pno = z->partno;
-
- if (no_write) {
- warnx(_("-n flag was given: Nothing changed\n"));
- exit(0);
- }
-
- for (p = partitions; p < partitions + pno; p++) {
- s = get_sector(dev, fd, p->sector);
- if (!s)
- return 0;
- s->to_be_written = 1;
- if (p->ptype == DOS_TYPE) {
- copy_from_part(&(p->p), s->data + p->offset);
- s->data[510] = 0x55;
- s->data[511] = (unsigned char)0xaa;
- }
- }
- if (save_sector_file) {
- if (!save_sectors(dev, fd)) {
- errx(EXIT_FAILURE, _("Failed saving the old sectors - aborting\n"));
- return 0;
- }
- }
- if (!write_sectors(dev, fd)) {
- error(_("Failed writing the partition on %s\n"), dev);
- return 0;
- }
- if (fsync(fd)) {
- perror(dev);
- error(_("Failed writing the partition on %s\n"), dev);
- return 0;
- }
- return 1;
-}
-
-/*
- * F. The standard input
- */
-
-/*
- * Input format:
- * <start> <size> <type> <bootable> <c,h,s> <c,h,s>
- * Fields are separated by whitespace or comma or semicolon possibly
- * followed by whitespace; initial and trailing whitespace is ignored.
- * Numbers can be octal, decimal or hexadecimal, decimal is default
- * The <c,h,s> parts can (and probably should) be omitted.
- * Bootable is specified as [*|-], with as default not-bootable.
- * Type is given in hex, without the 0x prefix, or is [E|S|L|X], where
- * L (LINUX_NATIVE (83)) is the default, S is LINUX_SWAP (82), and E
- * is EXTENDED_PARTITION (5), X is LINUX_EXTENDED (85).
- * The default value of start is the first nonassigned sector/cylinder/...
- * The default value of size is as much as possible (until next
- * partition or end-of-disk).
- * .: end of chain of extended partitions.
- *
- * On interactive input an empty line means: all defaults.
- * Otherwise empty lines are ignored.
- */
-
-int eof, eob;
-
-struct dumpfld {
- int fldno;
- char *fldname;
- int is_bool;
-} dumpflds[] = {
- {
- 0, "start", 0}, {
- 1, "size", 0}, {
- 2, "Id", 0}, {
- 3, "bootable", 1}, {
- 4, "bh", 0}, {
- 5, "bs", 0}, {
- 6, "bc", 0}, {
- 7, "eh", 0}, {
- 8, "es", 0}, {
- 9, "ec", 0}
-};
-
-/*
- * Read a line, split it into fields
- *
- * (some primitive handwork, but a more elaborate parser seems
- * unnecessary)
- */
-#define RD_EOF (-1)
-#define RD_CMD (-2)
-
-static int
-read_stdin(char **fields, char *line, int fieldssize, int linesize) {
- char *lp, *ip;
- int c, fno;
-
- /* boolean true and empty string at start */
- line[0] = '*';
- line[1] = 0;
- for (fno = 0; fno < fieldssize; fno++)
- fields[fno] = line + 1;
- fno = 0;
-
- /* read a line from stdin */
- lp = fgets(line + 2, linesize - 2, stdin);
- if (lp == NULL) {
- eof = 1;
- return RD_EOF;
- }
- if (!(lp = strchr(lp, '\n')))
- errx(EXIT_FAILURE, _("long or incomplete input line - quitting"));
- *lp = 0;
-
- /* remove comments, if any */
- if ((lp = strchr(line + 2, '#')) != 0)
- *lp = 0;
-
- /* recognize a few commands - to be expanded */
- if (!strcmp(line + 2, "unit: sectors")) {
- specified_format = F_SECTOR;
- return RD_CMD;
- }
-
- /* dump style? - then bad input is fatal */
- if ((ip = strchr(line + 2, ':')) != 0) {
- struct dumpfld *d;
-
- nxtfld:
- ip++;
- while (isspace(*ip))
- ip++;
- if (*ip == 0)
- return fno;
- for (d = dumpflds; (size_t) (d - dumpflds) < ARRAY_SIZE(dumpflds); d++) {
- if (!strncmp(ip, d->fldname, strlen(d->fldname))) {
- ip += strlen(d->fldname);
- while (isspace(*ip))
- ip++;
- if (d->is_bool)
- fields[d->fldno] = line;
- else if (*ip == '=') {
- while (isspace(*++ip)) ;
- fields[d->fldno] = ip;
- while (isalnum(*ip)) /* 0x07FF */
- ip++;
- } else
- errx(EXIT_FAILURE, _("input error: `=' expected after %s field"),
- d->fldname);
- if (fno <= d->fldno)
- fno = d->fldno + 1;
- if (*ip == 0)
- return fno;
- if (*ip != ',' && *ip != ';')
- errx(EXIT_FAILURE, _("input error: unexpected character %c after %s field"),
- *ip, d->fldname);
- *ip = 0;
- goto nxtfld;
- }
- }
- errx(EXIT_FAILURE, _("unrecognized input: %s"), ip);
- }
-
- /* split line into fields */
- lp = ip = line + 2;
- fields[fno++] = lp;
- while ((c = *ip++) != 0) {
- if (!lp[-1] && (c == '\t' || c == ' ')) ;
- else if (c == '\t' || c == ' ' || c == ',' || c == ';') {
- *lp++ = 0;
- if (fno < fieldssize)
- fields[fno++] = lp;
- continue;
- } else
- *lp++ = c;
- }
-
- if (lp == fields[fno - 1])
- fno--;
- return fno;
-}
-
-/* read a number, use default if absent */
-/* a sign gives an offset from the default */
-static int
-get_ul(char *u, unsigned long *up, unsigned long def, int base) {
- char *nu;
- int sign = 0;
- unsigned long val;
-
- if (*u == '+') {
- sign = 1;
- u++;
- } else if (*u == '-') {
- sign = -1;
- u++;
- }
- if (*u) {
- errno = 0;
- val = strtoul(u, &nu, base);
- if (errno == ERANGE) {
- warnx(_("number too big\n"));
- return -1;
- }
- if (*nu) {
- warnx(_("trailing junk after number\n"));
- return -1;
- }
- if (sign == 1)
- val = def + val;
- else if (sign == -1)
- val = def - val;
- *up = val;
- } else
- *up = def;
- return 0;
-}
-
-
-/* read a number, use default if absent */
-/* a sign gives an offset from the default */
-static int
-get_ull(char *u, unsigned long long *up, unsigned long long def, int base) {
- char *nu;
- int sign = 0;
- unsigned long long val;
-
- if (*u == '+') {
- sign = 1;
- u++;
- } else if (*u == '-') {
- sign = -1;
- u++;
- }
- if (*u) {
- errno = 0;
- val = strtoull(u, &nu, base);
- if (errno == ERANGE) {
- warnx(_("number too big\n"));
- return -1;
- }
- if (*nu) {
- warnx(_("trailing junk after number\n"));
- return -1;
- }
- if (sign == 1)
- val = def + val;
- else if (sign == -1)
- val = def - val;
- *up = val;
- } else
- *up = def;
- return 0;
-}
-
-
-/* There are two common ways to structure extended partitions:
- as nested boxes, and as a chain. Sometimes the partitions
- must be given in order. Sometimes all logical partitions
- must lie inside the outermost extended partition.
-NESTED: every partition is contained in the surrounding partitions
- and is disjoint from all others.
-CHAINED: every data partition is contained in the surrounding partitions
- and disjoint from all others, but extended partitions may lie outside
- (insofar as allowed by all_logicals_inside_outermost_extended).
-ONESECTOR: all data partitions are mutually disjoint; extended partitions
- each use one sector only (except perhaps for the outermost one).
-*/
-int partitions_in_order = 0;
-int all_logicals_inside_outermost_extended = 1;
-enum { NESTED, CHAINED, ONESECTOR } boxes = NESTED;
-
-/* find the default value for <start> - assuming entire units */
-static unsigned long long
-first_free(int pno, int is_extended, struct part_desc *ep, int format,
- unsigned long long mid, struct disk_desc *z) {
- unsigned long long ff, fff;
- unsigned long unit = unitsize(format);
- struct part_desc *partitions = &(z->partitions[0]), *pp = 0;
-
- /* if containing ep undefined, look at its container */
- if (ep && ep->p.sys_type == EMPTY_PARTITION)
- ep = ep->ep;
-
- if (ep) {
- if (boxes == NESTED || (boxes == CHAINED && !is_extended))
- pp = ep;
- else if (all_logicals_inside_outermost_extended)
- pp = outer_extended_partition(ep);
- }
-#if 0
- ff = pp ? (pp->start + unit - 1) / unit : 0;
-#else
- /* rounding up wastes almost an entire cylinder - round down
- and leave it to compute_start_sect() to fix the difference */
- ff = pp ? pp->start / unit : 0;
-#endif
- /* MBR and 1st sector of an extended partition are never free */
- if (unit == 1)
- ff++;
-
- again:
- for (pp = partitions; pp < partitions + pno; pp++) {
- if (!is_parent(pp, ep) && pp->size > 0) {
- if ((partitions_in_order || pp->start / unit <= ff
- || (mid && pp->start / unit <= mid))
- && (fff = (pp->start + pp->size + unit - 1) / unit) > ff) {
- ff = fff;
- goto again;
- }
- }
- }
-
- return ff;
-}
-
-/* find the default value for <size> - assuming entire units */
-static unsigned long long
-max_length(int pno, int is_extended, struct part_desc *ep, int format,
- unsigned long long start, struct disk_desc *z) {
- unsigned long long fu;
- unsigned long unit = unitsize(format);
- struct part_desc *partitions = &(z->partitions[0]), *pp = 0;
-
- /* if containing ep undefined, look at its container */
- if (ep && ep->p.sys_type == EMPTY_PARTITION)
- ep = ep->ep;
-
- if (ep) {
- if (boxes == NESTED || (boxes == CHAINED && !is_extended))
- pp = ep;
- else if (all_logicals_inside_outermost_extended)
- pp = outer_extended_partition(ep);
- }
- fu = pp ? (pp->start + pp->size) / unit : get_disksize(format);
-
- for (pp = partitions; pp < partitions + pno; pp++)
- if (!is_parent(pp, ep) && pp->size > 0
- && pp->start / unit >= start && pp->start / unit < fu)
- fu = pp->start / unit;
-
- return (fu > start) ? fu - start : 0;
-}
-
-/* compute starting sector of a partition inside an extended one */
-/* return 0 on failure */
-/* ep is 0 or points to surrounding extended partition */
-static int
-compute_start_sect(struct part_desc *p, struct part_desc *ep) {
- unsigned long long base;
- int inc = (DOS && B.sectors) ? B.sectors : 1;
- long long delta;
-
- if (ep && p->start + p->size >= ep->start + 1)
- delta = p->start - ep->start - inc;
- else if (p->start == 0 && p->size > 0)
- delta = -inc;
- else
- delta = 0;
-
- if (delta < 0) {
- unsigned long long old_size = p->size;
- p->start -= delta;
- p->size += delta;
- if (is_extended(p->p.sys_type) && boxes == ONESECTOR)
- p->size = inc;
- else if ((long long) old_size <= -delta) {
- my_warn(_("no room for partition descriptor\n"));
- return 0;
- }
- }
- base = (!ep ? 0
- : (is_extended(p->p.sys_type) ?
- outer_extended_partition(ep) : ep)->start);
- p->ep = ep;
- if (p->p.sys_type == EMPTY_PARTITION && p->size == 0) {
- p->p.start_sect = 0;
- p->p.begin_chs = zero_chs;
- p->p.end_chs = zero_chs;
- } else {
- p->p.start_sect = p->start - base;
- p->p.begin_chs = ulong_to_chs(p->start, B);
- p->p.end_chs = ulong_to_chs(p->start + p->size - 1, B);
- }
- p->p.nr_sects = p->size;
- return 1;
-}
-
-/* build the extended partition surrounding a given logical partition */
-static int
-build_surrounding_extended(struct part_desc *p, struct part_desc *ep,
- struct disk_desc *z) {
- int inc = (DOS && B.sectors) ? B.sectors : 1;
- int format = F_SECTOR;
- struct part_desc *p0 = &(z->partitions[0]), *eep = ep->ep;
-
- if (boxes == NESTED) {
- ep->start = first_free(ep - p0, 1, eep, format, p->start, z);
- ep->size = max_length(ep - p0, 1, eep, format, ep->start, z);
- if (ep->start > p->start || ep->start + ep->size < p->start + p->size) {
- my_warn(_("cannot build surrounding extended partition\n"));
- return 0;
- }
- } else {
- ep->start = p->start;
- if (boxes == CHAINED)
- ep->size = p->size;
- else
- ep->size = inc;
- }
-
- ep->p.nr_sects = ep->size;
- ep->p.bootable = 0;
- ep->p.sys_type = EXTENDED_PARTITION;
- if (!compute_start_sect(ep, eep) || !compute_start_sect(p, ep)) {
- ep->p.sys_type = EMPTY_PARTITION;
- ep->size = 0;
- return 0;
- }
-
- return 1;
-}
-
-static int
-read_line(int pno, struct part_desc *ep, char *dev, int interactive,
- struct disk_desc *z) {
- char line[1000];
- char *fields[11];
- int fno, pct = pno % 4;
- struct part_desc p, *orig;
- unsigned long long ff, ff1, ul, ml, ml1, def;
- int format, lpno, is_extd;
-
- if (eof || eob)
- return -1;
-
- lpno = index_to_linux(pno, z);
-
- if (interactive) {
- if (pct == 0 && (show_extended || pno == 0))
- my_warn("\n");
- my_warn("%s:", partname(dev, lpno, 10));
- }
-
- /* read input line - skip blank lines when reading from a file */
- do {
- fno = read_stdin(fields, line, ARRAY_SIZE(fields), ARRAY_SIZE(line));
- } while (fno == RD_CMD || (fno == 0 && !interactive));
- if (fno == RD_EOF) {
- return -1;
- } else if (fno > 10 && *(fields[10]) != 0) {
- warnx(_("too many input fields\n"));
- return 0;
- }
-
- if (fno == 1 && !strcmp(fields[0], ".")) {
- eob = 1;
- return -1;
- }
-
- /* use specified format, but round to cylinders if F_MEGABYTE specified */
- format = 0;
- if (B.cylindersize && specified_format == F_MEGABYTE && !Linux)
- format = F_CYLINDER;
-
- orig = (one_only ? &(oldp.partitions[pno]) : 0);
-
- p = zero_part_desc;
- p.ep = ep;
-
- /* first read the type - we need to know whether it is extended */
- /* stop reading when input blank (defaults) and all is full */
- is_extd = 0;
- if (fno == 0) { /* empty line */
- if (orig && is_extended(orig->p.sys_type))
- is_extd = 1;
- ff = first_free(pno, is_extd, ep, format, 0, z);
- ml = max_length(pno, is_extd, ep, format, ff, z);
- if (ml == 0 && is_extd == 0) {
- is_extd = 1;
- ff = first_free(pno, is_extd, ep, format, 0, z);
- ml = max_length(pno, is_extd, ep, format, ff, z);
- }
- if (ml == 0 && pno >= 4) {
- /* no free blocks left - don't read any further */
- my_warn(_("No room for more\n"));
- return -1;
- }
- }
- if (fno < 3 || !*(fields[2]))
- ul = orig ? orig->p.sys_type :
- (is_extd || (pno > 3 && pct == 1 && show_extended))
- ? EXTENDED_PARTITION : LINUX_NATIVE;
- else if (!strcmp(fields[2], "L"))
- ul = LINUX_NATIVE;
- else if (!strcmp(fields[2], "S"))
- ul = LINUX_SWAP;
- else if (!strcmp(fields[2], "E"))
- ul = EXTENDED_PARTITION;
- else if (!strcmp(fields[2], "X"))
- ul = LINUX_EXTENDED;
- else if (get_ull(fields[2], &ul, LINUX_NATIVE, 16))
- return 0;
- if (ul > 255) {
- my_warn(_("Illegal type\n"));
- return 0;
- }
- p.p.sys_type = ul;
- is_extd = is_extended(ul);
-
- /* find start */
- ff = first_free(pno, is_extd, ep, format, 0, z);
- ff1 = ff * unitsize(format);
- def = orig ? orig->start : (pno > 4 && pct > 1) ? 0 : ff1;
- if (fno < 1 || !*(fields[0]))
- p.start = def;
- else {
- if (get_ull(fields[0], &ul, def / unitsize(0), 0))
- return 0;
- p.start = ul * unitsize(0);
- p.start -= (p.start % unitsize(format));
- }
-
- /* find length */
- ml = max_length(pno, is_extd, ep, format, p.start / unitsize(format), z);
- ml1 = ml * unitsize(format);
- def = orig ? orig->size : (pno > 4 && pct > 1) ? 0 : ml1;
- if (fno < 2 || !*(fields[1]))
- p.size = def;
- else if (!strcmp(fields[1], "+"))
- p.size = ml1;
- else {
- if (get_ull(fields[1], &ul, def / unitsize(0), 0))
- return 0;
- p.size = ul * unitsize(0) + unitsize(format) - 1;
- p.size -= (p.size % unitsize(format));
- }
- if (p.size > ml1) {
- my_warn(_("Warning: given size (%lu) exceeds max allowable size (%lu)\n"),
- (p.size + unitsize(0) - 1) / unitsize(0), ml1 / unitsize(0));
- if (!force)
- return 0;
- }
- if (p.size == 0 && pno >= 4 && (fno < 2 || !*(fields[1]))) {
- my_warn(_("Warning: empty partition\n"));
- if (!force)
- return 0;
- }
- p.p.nr_sects = p.size;
-
- if (p.size == 0 && !orig) {
- if (fno < 1 || !*(fields[0]))
- p.start = 0;
- if (fno < 3 || !*(fields[2]))
- p.p.sys_type = EMPTY_PARTITION;
- }
-
- if (p.start < ff1 && p.size > 0) {
- my_warn(_("Warning: bad partition start (earliest %lu)\n"),
- (ff1 + unitsize(0) - 1) / unitsize(0));
- if (!force)
- return 0;
- }
-
- if (fno < 4 || !*(fields[3]))
- ul = (orig ? orig->p.bootable : 0);
- else if (!strcmp(fields[3], "-"))
- ul = 0;
- else if (!strcmp(fields[3], "*") || !strcmp(fields[3], "+"))
- ul = 0x80;
- else {
- my_warn(_("unrecognized bootable flag - choose - or *\n"));
- return 0;
- }
- p.p.bootable = ul;
-
- if (ep && ep->p.sys_type == EMPTY_PARTITION) {
- if (!build_surrounding_extended(&p, ep, z))
- return 0;
- } else if (!compute_start_sect(&p, ep))
- return 0;
-
- {
- longchs aa = chs_to_longchs(p.p.begin_chs), bb;
-
- if (fno < 5) {
- bb = aa;
- } else if (fno < 7) {
- my_warn(_("partial c,h,s specification?\n"));
- return 0;
- } else if (get_ul(fields[4], &bb.c, aa.c, 0) ||
- get_ul(fields[5], &bb.h, aa.h, 0) ||
- get_ul(fields[6], &bb.s, aa.s, 0))
- return 0;
- p.p.begin_chs = longchs_to_chs(bb, B);
- }
- {
- longchs aa = chs_to_longchs(p.p.end_chs), bb;
-
- if (fno < 8) {
- bb = aa;
- } else if (fno < 10) {
- my_warn(_("partial c,h,s specification?\n"));
- return 0;
- } else if (get_ul(fields[7], &bb.c, aa.c, 0) ||
- get_ul(fields[8], &bb.h, aa.h, 0) ||
- get_ul(fields[9], &bb.s, aa.s, 0))
- return 0;
- p.p.end_chs = longchs_to_chs(bb, B);
- }
-
- if (pno > 3 && p.size && show_extended && p.p.sys_type != EMPTY_PARTITION
- && (is_extended(p.p.sys_type) != (pct == 1))) {
- my_warn(_("Extended partition not where expected\n"));
- if (!force)
- return 0;
- }
-
- z->partitions[pno] = p;
- if (pno >= z->partno)
- z->partno += 4; /* reqd for out_partition() */
-
- if (interactive)
- out_partition(dev, 0, &(z->partitions[pno]), z, B);
-
- return 1;
-}
-
-/* ep either points to the extended partition to contain this one,
- or to the empty partition that may become extended or is 0 */
-static int
-read_partition(char *dev, int interactive, int pno, struct part_desc *ep,
- struct disk_desc *z) {
- struct part_desc *p = &(z->partitions[pno]);
- int i;
-
- if (one_only) {
- *p = oldp.partitions[pno];
- if (one_only_pno != pno)
- goto ret;
- } else if (!show_extended && pno > 4 && pno % 4)
- goto ret;
-
- while (!(i = read_line(pno, ep, dev, interactive, z)))
- if (!interactive)
- errx(EXIT_FAILURE, _("bad input"));
- if (i < 0) {
- p->ep = ep;
- return 0;
- }
-
- ret:
- p->ep = ep;
- if (pno >= z->partno)
- z->partno += 4;
- return 1;
-}
-
-static void
-read_partition_chain(char *dev, int interactive, struct part_desc *ep,
- struct disk_desc *z) {
- int i;
- size_t base;
-
- eob = 0;
- while (1) {
- base = z->partno;
- if (base + 4 > ARRAY_SIZE(z->partitions)) {
- warnx(_("too many partitions\n"));
- break;
- }
- for (i = 0; i < 4; i++)
- if (!read_partition(dev, interactive, base + i, ep, z))
- return;
- for (i = 0; i < 4; i++) {
- ep = &(z->partitions[base + i]);
- if (is_extended(ep->p.sys_type) && ep->size)
- break;
- }
- if (i == 4) {
- /* nothing found - maybe an empty partition is going
- to be extended */
- if (one_only || show_extended)
- break;
- ep = &(z->partitions[base + 1]);
- if (ep->size || ep->p.sys_type != EMPTY_PARTITION)
- break;
- }
- }
-}
-
-static void
-read_input(char *dev, int interactive, struct disk_desc *z) {
- size_t i;
- struct part_desc *partitions = &(z->partitions[0]), *ep;
-
- for (i = 0; i < ARRAY_SIZE(z->partitions); i++)
- partitions[i] = zero_part_desc;
- z->partno = 0;
-
- if (interactive)
- my_warn(_("Input in the following format; absent fields get a default value.\n"
- "<start> <size> <type [E,S,L,X,hex]> <bootable [-,*]> <c,h,s> <c,h,s>\n"
- "Usually you only need to specify <start> and <size> (and perhaps <type>).\n"));
- eof = 0;
-
- for (i = 0; i < 4; i++)
- read_partition(dev, interactive, i, 0, z);
- for (i = 0; i < 4; i++) {
- ep = partitions + i;
- if (is_extended(ep->p.sys_type) && ep->size)
- read_partition_chain(dev, interactive, ep, z);
- }
- add_sector_and_offset(z);
-}
-
-/*
- * G. The command line
- */
-static void usage(FILE * out)
-{
- fputs(_("\nUsage:\n"), out);
- fprintf(out,
- _(" %s [options] <device> [...]\n"), program_invocation_short_name);
-
- fputs(_("\nOptions:\n"), out);
- fputs(_(" -s, --show-size list size of a partition\n"
- " -c, --id change or print partition Id\n"
- " --change-id change Id\n"
- " --print-id print Id\n"), out);
- fputs(_(" -l, --list list partitions of each device\n"
- " -d, --dump idem, but in a format suitable for later input\n"
- " -i, --increment number cylinders etc. from 1 instead of from 0\n"
- " -u, --unit <letter> units to be used; <letter> can be one of\n"
- " S (sectors), C (cylinders), B (blocks), or M (MB)\n"), out);
- fputs(_(" -1, --one-only reserved option that does nothing currently\n"
- " -T, --list-types list the known partition types\n"
- " -D, --DOS for DOS-compatibility: waste a little space\n"
- " -E, --DOS-extended DOS extended partition compatibility\n"
- " -R, --re-read make the kernel reread the partition table\n"), out);
- fputs(_(" -N <number> change only the partition with this <number>\n"
- " -n do not actually write to disk\n"
- " -O <file> save the sectors that will be overwritten to <file>\n"
- " -I <file> restore sectors from <file>\n"), out);
- fputs(_(" -V, --verify check that the listed partitions are reasonable\n"
- " -v, --version display version information and exit\n"
- " -h, --help display this help text and exit\n"), out);
-
- fputs(_("\nDangerous options:\n"), out);
- fputs(_(" -f, --force disable all consistency checking\n"
- " --no-reread do not check whether the partition is in use\n"
- " -q, --quiet suppress warning messages\n"
- " -L, --Linux do not complain about things irrelevant for Linux\n"), out);
- fputs(_(" -g, --show-geometry print the kernel's idea of the geometry\n"
- " -G, --show-pt-geometry print geometry guessed from the partition table\n"), out);
- fputs(_(" -A, --activate[=<device>] activate bootable flag\n"
- " -U, --unhide[=<dev>] set partition unhidden\n"
- " -x, --show-extended also list extended partitions in the output,\n"
- " or expect descriptors for them in the input\n"), out);
- fputs(_(" --leave-last do not allocate the last cylinder\n"
- " --IBM same as --leave-last\n"), out);
- fputs(_(" --in-order partitions are in order\n"
- " --not-in-order partitions are not in order\n"
- " --inside-outer all logicals inside outermost extended\n"
- " --not-inside-outer not all logicals inside outermost extended\n"), out);
- fputs(_(" --nested every partition is disjoint from all others\n"
- " --chained like nested, but extended partitions may lie outside\n"
- " --onesector partitions are mutually disjoint\n"), out);
-
- fputs(_("\nOverride the detected geometry using:\n"
- " -C, --cylinders <number> set the number of cylinders to use\n"
- " -H, --heads <number> set the number of heads to use\n"
- " -S, --sectors <number> set the number of sectors to use\n\n"), out);
-
- exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
-}
-
-static void
-activate_usage(char *progn) {
- puts(_("Usage:"));
- printf(_("%s device list active partitions on device\n"), progn);
- printf(_("%s device n1 n2 ... activate partitions n1 ..., inactivate the rest\n"),
- progn);
- printf(_("%s -An device activate partition n, inactivate the other ones\n"),
- PROGNAME);
- exit(1);
-}
-
-static void
-unhide_usage(char *progn __attribute__ ((__unused__))) {
- exit(1);
-}
-
-static const char short_opts[] = "cdfghilnqsu:vx1A::C:DGH:I:LN:O:RS:TU::V";
-
-#define PRINT_ID 0400
-#define CHANGE_ID 01000
-
-enum {
- OPT_NO_REREAD = CHAR_MAX + 1,
- OPT_LEAVE_LAST,
- OPT_IN_ORDER,
- OPT_NOT_IN_ORDER,
- OPT_INSIDE_OUTER,
- OPT_NOT_INSIDE_OUTER,
- OPT_NESTED,
- OPT_CHAINED,
- OPT_ONESECTOR
-};
-
-static const struct option long_opts[] = {
- { "change-id", no_argument, NULL, 'c' + CHANGE_ID },
- { "print-id", no_argument, NULL, 'c' + PRINT_ID },
- { "id", no_argument, NULL, 'c' },
- { "dump", no_argument, NULL, 'd' },
- { "force", no_argument, NULL, 'f' },
- { "show-geometry", no_argument, NULL, 'g' },
- { "help", no_argument, NULL, 'h' },
- { "increment", no_argument, NULL, 'i' },
- { "list", no_argument, NULL, 'l' },
- { "quiet", no_argument, NULL, 'q' },
- { "show-size", no_argument, NULL, 's' },
- { "unit", required_argument, NULL, 'u' },
- { "version", no_argument, NULL, 'v' },
- { "show-extended", no_argument, NULL, 'x' },
- { "one-only", no_argument, NULL, '1' },
- { "cylinders", required_argument, NULL, 'C' },
- { "heads", required_argument, NULL, 'H' },
- { "sectors", required_argument, NULL, 'S' },
- { "show-pt-geometry", no_argument, NULL, 'G' },
- { "activate", optional_argument, NULL, 'A' },
- { "DOS", no_argument, NULL, 'D' },
- { "DOS-extended", no_argument, NULL, 'E' },
- { "Linux", no_argument, NULL, 'L' },
- { "re-read", no_argument, NULL, 'R' },
- { "list-types", no_argument, NULL, 'T' },
- { "unhide", optional_argument, NULL, 'U' },
- { "no-reread", no_argument, NULL, OPT_NO_REREAD },
- { "IBM", no_argument, NULL, OPT_LEAVE_LAST },
- { "leave-last", no_argument, NULL, OPT_LEAVE_LAST },
-/* dangerous flags - not all completely implemented */
- { "in-order", no_argument, NULL, OPT_IN_ORDER },
- { "not-in-order", no_argument, NULL, OPT_NOT_IN_ORDER },
- { "inside-outer", no_argument, NULL, OPT_INSIDE_OUTER },
- { "not-inside-outer", no_argument, NULL, OPT_NOT_INSIDE_OUTER },
- { "nested", no_argument, NULL, OPT_NESTED },
- { "chained", no_argument, NULL, OPT_CHAINED },
- { "onesector", no_argument, NULL, OPT_ONESECTOR },
- { NULL, 0, NULL, 0 }
-};
-
-static int is_ide_cdrom_or_tape(char *device)
-{
- int fd, ret;
-
- if ((fd = open(device, O_RDONLY)) < 0)
- return 0;
- ret = blkdev_is_cdrom(fd);
-
- close(fd);
- return ret;
-}
-
-static char *
-nextproc(FILE * procf) {
- static char devname[256];
- char line[1024], ptname[128];
- int ma, mi;
- unsigned long long sz;
-
- if (procf == NULL)
- return NULL;
- while (fgets(line, sizeof(line), procf) != NULL) {
- if (sscanf(line, " %d %d %llu %128[^\n ]", &ma, &mi, &sz, ptname) != 4)
- continue;
- snprintf(devname, sizeof(devname), "/dev/%s", ptname);
- if (!is_whole_disk(devname))
- continue;
- return canonicalize_path(devname);
- }
-
- return NULL;
-}
-
-static void
-gpt_warning(char *dev, int warn_only) {
- if (force)
- warn_only = 1;
-
- if (dev && gpt_probe_signature_devname(dev)) {
- fflush(stdout);
- fprintf(stderr,
- _("\nWARNING: GPT (GUID Partition Table) detected on '%s'! "
- "The util sfdisk doesn't support GPT. Use GNU Parted.\n\n"),
- dev);
- if (!warn_only) {
- fprintf(stderr,
- _("Use the --force flag to overrule this check.\n"));
- exit(1);
- }
- }
-}
-
-static void do_list(char *dev, int silent);
-static void do_size(char *dev, int silent);
-static void do_geom(char *dev, int silent);
-static void do_pt_geom(char *dev, int silent);
-static void do_fdisk(char *dev);
-static void do_reread(char *dev);
-static void do_change_id(char *dev, char *part, char *id);
-static void do_unhide(char **av, int ac, char *arg);
-static void do_activate(char **av, int ac, char *arg);
-
-unsigned long long total_size;
-
-int
-main(int argc, char **argv) {
- char *progn;
- int c;
- char *dev;
- int opt_size = 0;
- int opt_out_geom = 0;
- int opt_out_pt_geom = 0;
- int opt_reread = 0;
- int activate = 0;
- int do_id = 0;
- int unhide = 0;
- int fdisk = 0;
- char *activatearg = 0;
- char *unhidearg = 0;
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
- atexit(close_stdout);
-
- if (argc < 1)
- errx(EXIT_FAILURE, _("no command?"));
- if ((progn = strrchr(argv[0], '/')) == NULL)
- progn = argv[0];
- else
- progn++;
- if (!strcmp(progn, "activate"))
- activate = 1; /* equivalent to `sfdisk -A' */
-#if 0 /* not important enough to deserve a name */
- else if (!strcmp(progn, "unhide"))
- unhide = 1; /* equivalent to `sfdisk -U' */
-#endif
- else
- fdisk = 1;
-
- while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
- switch (c) {
- case 'f':
- force = 1;
- break; /* does not imply quiet */
- case 'g':
- opt_out_geom = 1;
- break;
- case 'G':
- opt_out_pt_geom = 1;
- break;
- case 'i':
- increment = 1;
- break;
- case 'c':
- case 'c' + PRINT_ID:
- case 'c' + CHANGE_ID:
- do_id = c;
- break;
- case 'd':
- dump = 1; /* fall through */
- case 'l':
- opt_list = 1;
- break;
- case 'n':
- no_write = 1;
- break;
- case 'q':
- quiet = 1;
- break;
- case 's':
- opt_size = 1;
- break;
- case 'u':
- set_format(*optarg);
- break;
- case 'v':
- printf(_("%s from %s\n"), program_invocation_short_name,
- PACKAGE_STRING);
- return EXIT_SUCCESS;
- case 'h':
- usage(stdout);
- return EXIT_SUCCESS;
- case 'x':
- show_extended = 1;
- break;
- case 'A':
- activatearg = optarg;
- activate = 1;
- break;
- case 'C':
- U.cylinders = strtoul_or_err(optarg, _("invalid cylinders argument"));
- break;
- case 'D':
- DOS = 1;
- break;
- case 'E':
- DOS_extended = 1;
- break;
- case 'H':
- U.heads = strtoul_or_err(optarg, _("invalid heads argument"));
- break;
- case 'L':
- Linux = 1;
- break;
- case 'N':
- one_only = strtol_or_err(optarg, _("invalid number of partitions argument"));
- break;
- case 'I':
- restore_sector_file = optarg;
- break;
- case 'O':
- save_sector_file = optarg;
- break;
- case 'R':
- opt_reread = 1;
- break;
- case 'S':
- U.sectors = strtoul_or_err(optarg, _("invalid sectors argument"));
- break;
- case 'T':
- list_types();
- exit(0);
- case 'U':
- unhidearg = optarg;
- unhide = 1;
- break;
- case 'V':
- verify = 1;
- break;
- default:
- usage(stderr);
- break;
-
- /* dangerous flags */
- case OPT_IN_ORDER:
- partitions_in_order = 1;
- break;
- case OPT_NOT_IN_ORDER:
- partitions_in_order = 0;
- break;
- case OPT_INSIDE_OUTER:
- all_logicals_inside_outermost_extended = 1;
- break;
- case OPT_NOT_INSIDE_OUTER:
- all_logicals_inside_outermost_extended = 0;
- break;
- case OPT_NESTED:
- boxes = NESTED;
- break;
- case OPT_CHAINED:
- boxes = CHAINED;
- break;
- case OPT_ONESECTOR:
- boxes = ONESECTOR;
- break;
-
- /* more flags */
- case OPT_NO_REREAD:
- no_reread = 1;
- break;
- case OPT_LEAVE_LAST:
- leave_last = 1;
- break;
- }
- }
-
- if (optind == argc &&
- (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify)) {
- FILE *procf;
-
- /* try all known devices */
- total_size = 0;
-
- procf = fopen(_PATH_PROC_PARTITIONS, "r");
- if (!procf)
- fprintf(stderr, _("cannot open %s\n"), _PATH_PROC_PARTITIONS);
- else {
- while ((dev = nextproc(procf)) != NULL) {
- if (!is_ide_cdrom_or_tape(dev)) {
- gpt_warning(dev, 1);
- if (opt_out_geom)
- do_geom(dev, 1);
- if (opt_out_pt_geom)
- do_pt_geom(dev, 1);
- if (opt_size)
- do_size(dev, 1);
- if (opt_list || verify)
- do_list(dev, 1);
- }
- free(dev);
- }
- fclose(procf);
- }
-
- if (opt_size)
- printf(_("total: %llu blocks\n"), total_size);
-
- exit(exit_status);
- }
-
- if (optind == argc) {
- if (activate)
- activate_usage(fdisk ? "sfdisk -A" : progn);
- else if (unhide)
- unhide_usage(fdisk ? "sfdisk -U" : progn);
- else
- usage(stderr);
- }
-
- if (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify) {
- while (optind < argc) {
- gpt_warning(argv[optind], 1);
- if (opt_out_geom)
- do_geom(argv[optind], 0);
- if (opt_out_pt_geom)
- do_pt_geom(argv[optind], 0);
- if (opt_size)
- do_size(argv[optind], 0);
- if (opt_list || verify)
- do_list(argv[optind], 0);
- optind++;
- }
- exit(exit_status);
- }
-
- if (optind != argc - 1)
- gpt_warning(argv[optind], 0);
-
- if (activate) {
- do_activate(argv + optind, argc - optind, activatearg);
- exit(exit_status);
- }
- if (unhide) {
- do_unhide(argv + optind, argc - optind, unhidearg);
- exit(exit_status);
- }
- if (do_id) {
- if ((do_id & PRINT_ID) != 0 && optind != argc - 2)
- errx(EXIT_FAILURE, _("usage: sfdisk --print-id device partition-number"));
- else if ((do_id & CHANGE_ID) != 0 && optind != argc - 3)
- errx(EXIT_FAILURE, _("usage: sfdisk --change-id device partition-number Id"));
- else if (optind != argc - 3 && optind != argc - 2)
- errx(EXIT_FAILURE, _("usage: sfdisk --id device partition-number [Id]"));
- do_change_id(argv[optind], argv[optind + 1],
- (optind == argc - 2) ? 0 : argv[optind + 2]);
- exit(exit_status);
- }
-
- if (optind != argc - 1)
- errx(EXIT_FAILURE, _("can specify only one device (except with -l or -s)"));
- dev = argv[optind];
-
- if (opt_reread)
- do_reread(dev);
- else if (restore_sector_file)
- restore_sectors(dev);
- else
- do_fdisk(dev);
-
- return 0;
-}
-
-/*
- * H. Listing the current situation
- */
-
-static int
-my_open(char *dev, int rw, int silent) {
- int fd, mode;
-
- mode = (rw ? O_RDWR : O_RDONLY);
- fd = open(dev, mode);
- if (fd < 0 && !silent) {
- perror(dev);
- if (rw)
- errx(EXIT_FAILURE, _("cannot open %s read-write"), dev);
- else
- errx(EXIT_FAILURE, _("cannot open %s for reading"), dev);
- }
- return fd;
-}
-
-static void
-do_list(char *dev, int silent) {
- int fd;
- struct disk_desc *z;
-
- fd = my_open(dev, 0, silent);
- if (fd < 0)
- return;
-
- z = &oldp;
-
- free_sectors();
- get_cylindersize(dev, fd, dump ? 1 : opt_list ? 0 : 1);
- get_partitions(dev, fd, z);
-
- if (opt_list)
- out_partitions(dev, z);
-
- if (verify) {
- if (partitions_ok(fd, z))
- my_warn(_("%s: OK\n"), dev);
- else
- exit_status = 1;
- }
-
- close(fd);
-}
-
-static void
-do_geom(char *dev, int silent) {
- int fd;
- struct geometry R;
-
- fd = my_open(dev, 0, silent);
- if (fd < 0)
- return;
-
- R = get_geometry(dev, fd, silent);
- if (R.cylinders)
- printf(_("%s: %ld cylinders, %ld heads, %ld sectors/track\n"),
- dev, R.cylinders, R.heads, R.sectors);
-
- close(fd);
-}
-
-static void
-do_pt_geom(char *dev, int silent) {
- int fd;
- struct disk_desc *z;
- struct geometry R;
-
- fd = my_open(dev, 0, silent);
- if (fd < 0)
- return;
-
- z = &oldp;
-
- free_sectors();
- get_cylindersize(dev, fd, 1);
- get_partitions(dev, fd, z);
-
- R = B;
-
- if (z->partno != 0 && get_fdisk_geometry(z)) {
- R.heads = F.heads;
- R.sectors = F.sectors;
- R.cylindersize = R.heads * R.sectors;
- R.cylinders = (R.cylindersize == 0) ? 0 : R.total_size / R.cylindersize;
- }
-
- if (R.cylinders)
- printf(_("%s: %ld cylinders, %ld heads, %ld sectors/track\n"),
- dev, R.cylinders, R.heads, R.sectors);
-
- close(fd);
-}
-
-/* for compatibility with earlier fdisk: provide option -s */
-static void
-do_size(char *dev, int silent) {
- int fd;
- unsigned long long size;
-
- fd = my_open(dev, 0, silent);
- if (fd < 0)
- return;
-
- if (blkdev_get_sectors(fd, &size) == -1) {
- if (!silent) {
- perror(dev);
- errx(EXIT_FAILURE, _("Cannot get size of %s"), dev);
- }
- goto done;
- }
-
- size /= 2; /* convert sectors to blocks */
-
- /* a CDROM drive without mounted CD yields MAXINT */
- if (silent && size == ((1 << 30) - 1))
- goto done;
-
- if (silent)
- printf("%s: %9llu\n", dev, size);
- else
- printf("%llu\n", size);
-
- total_size += size;
-
-done:
- close(fd);
-}
-
-/*
- * Activate: usually one wants to have a single primary partition
- * to be active. OS/2 fdisk makes non-bootable logical partitions
- * active - I don't know what that means to OS/2 Boot Manager.
- *
- * Call: activate /dev/hda 2 5 7 make these partitions active
- * and the remaining ones inactive
- * Or: sfdisk -A /dev/hda 2 5 7
- *
- * If only a single partition must be active, one may also use the form
- * sfdisk -A2 /dev/hda
- *
- * With "activate /dev/hda" or "sfdisk -A /dev/hda" the active partitions
- * are listed but not changed. To get zero active partitions, use
- * "activate /dev/hda none" or "sfdisk -A /dev/hda none".
- * Use something like `echo ",,,*" | sfdisk -N2 /dev/hda' to only make
- * /dev/hda2 active, without changing other partitions.
- *
- * A warning will be given if after the change not precisely one primary
- * partition is active.
- *
- * The present syntax was chosen to be (somewhat) compatible with the
- * activate from the LILO package.
- */
-static void
-set_active(struct disk_desc *z, char *pnam) {
- int pno;
-
- pno = asc_to_index(pnam, z);
- if (z->partitions[pno].ptype == DOS_TYPE)
- z->partitions[pno].p.bootable = 0x80;
-}
-
-static void
-do_activate(char **av, int ac, char *arg) {
- char *dev = av[0];
- int fd;
- int rw, i, pno, lpno;
- struct disk_desc *z;
-
- z = &oldp;
-
- rw = (!no_write && (arg || ac > 1));
- fd = my_open(dev, rw, 0);
-
- free_sectors();
- get_cylindersize(dev, fd, 1);
- get_partitions(dev, fd, z);
-
- if (!arg && ac == 1) {
- /* list active partitions */
- for (pno = 0; pno < z->partno; pno++) {
- if (z->partitions[pno].p.bootable) {
- lpno = index_to_linux(pno, z);
- if (pno == linux_to_index(lpno, z))
- printf("%s\n", partname(dev, lpno, 0));
- else
- printf("%s#%d\n", dev, pno);
- if (z->partitions[pno].p.bootable != 0x80)
- my_warn(_("bad active byte: 0x%x instead of 0x80\n"),
- z->partitions[pno].p.bootable);
- }
- }
- } else {
- /* clear `active byte' everywhere */
- for (pno = 0; pno < z->partno; pno++)
- if (z->partitions[pno].ptype == DOS_TYPE)
- z->partitions[pno].p.bootable = 0;
-
- /* then set where desired */
- if (ac == 1)
- set_active(z, arg);
- else
- for (i = 1; i < ac; i++)
- set_active(z, av[i]);
-
- /* then write to disk */
- if (write_partitions(dev, fd, z))
- my_warn(_("Done\n\n"));
- else
- exit_status = 1;
- }
- i = 0;
- for (pno = 0; pno < z->partno && pno < 4; pno++)
- if (z->partitions[pno].p.bootable)
- i++;
- if (i != 1)
- my_warn(_("You have %d active primary partitions. This does not matter for LILO,\n"
- "but the DOS MBR will only boot a disk with 1 active partition.\n"),
- i);
-
- close(fd);
-}
-
-static void
-set_unhidden(struct disk_desc *z, char *pnam) {
- int pno;
- unsigned char id;
-
- pno = asc_to_index(pnam, z);
- id = z->partitions[pno].p.sys_type;
- if (id == 0x11 || id == 0x14 || id == 0x16 || id == 0x17)
- id -= 0x10;
- else
- errx(EXIT_FAILURE, _("partition %s has id %x and is not hidden"), pnam, id);
- z->partitions[pno].p.sys_type = id;
-}
-
-/*
- * maybe remove and make part of --change-id
- */
-static void
-do_unhide(char **av, int ac, char *arg) {
- char *dev = av[0];
- int fd, rw, i;
- struct disk_desc *z;
-
- z = &oldp;
-
- rw = !no_write;
- fd = my_open(dev, rw, 0);
-
- free_sectors();
- get_cylindersize(dev, fd, 1);
- get_partitions(dev, fd, z);
-
- /* unhide where desired */
- if (ac == 1)
- set_unhidden(z, arg);
- else
- for (i = 1; i < ac; i++)
- set_unhidden(z, av[i]);
-
- /* then write to disk */
- if (write_partitions(dev, fd, z))
- my_warn(_("Done\n\n"));
- else
- exit_status = 1;
-
- close(fd);
-}
-
-static void
-do_change_id(char *dev, char *pnam, char *id) {
- int fd, rw, pno;
- struct disk_desc *z;
- unsigned long i;
-
- z = &oldp;
-
- rw = !no_write;
- fd = my_open(dev, rw, 0);
-
- free_sectors();
- get_cylindersize(dev, fd, 1);
- get_partitions(dev, fd, z);
-
- pno = asc_to_index(pnam, z);
- if (id == 0) {
- printf("%x\n", z->partitions[pno].p.sys_type);
- goto done;
- }
- i = strtoul(id, NULL, 16);
- if (i > 255)
- errx(EXIT_FAILURE, _("Bad Id %lx"), i);
- z->partitions[pno].p.sys_type = i;
-
- if (write_partitions(dev, fd, z))
- my_warn(_("Done\n\n"));
- else
- exit_status = 1;
-
-done:
- close(fd);
-}
-
-static void
-do_reread(char *dev) {
- int fd;
-
- fd = my_open(dev, 0, 0);
- if (reread_ioctl(fd)) {
- warnx(_("This disk is currently in use.\n"));
- exit(1);
- }
-
- close(fd);
-}
-
-/*
- * I. Writing the new situation
- */
-
-static void
-do_fdisk(char *dev) {
- int fd;
- char answer[32];
- struct stat statbuf;
- int interactive = isatty(0);
- struct disk_desc *z;
-
- if (stat(dev, &statbuf) < 0) {
- perror(dev);
- errx(EXIT_FAILURE, _("Fatal error: cannot find %s"), dev);
- }
- if (!S_ISBLK(statbuf.st_mode)) {
- warnx(_("Warning: %s is not a block device\n"), dev);
- no_reread = 1;
- }
- fd = my_open(dev, !no_write, 0);
-
- if (!no_write && !no_reread) {
- my_warn(_("Checking that no-one is using this disk right now ...\n"));
- if (reread_ioctl(fd)) {
- warnx(_("\nThis disk is currently in use - repartitioning is probably a bad idea.\n"
- "Umount all file systems, and swapoff all swap partitions on this disk.\n"
- "Use the --no-reread flag to suppress this check.\n"));
- if (!force) {
- warnx(_("Use the --force flag to overrule all checks.\n"));
- exit(1);
- }
- } else
- my_warn(_("OK\n"));
- }
-
- z = &oldp;
-
- free_sectors();
- get_cylindersize(dev, fd, 0);
- get_partitions(dev, fd, z);
-
- printf(_("Old situation:\n"));
- out_partitions(dev, z);
-
- if (one_only && (one_only_pno = linux_to_index(one_only, z)) < 0)
- errx(EXIT_FAILURE, _("Partition %d does not exist, cannot change it"), one_only);
-
- z = &newp;
-
- while (1) {
-
- read_input(dev, interactive, z);
-
- printf(_("New situation:\n"));
- out_partitions(dev, z);
-
- if (!partitions_ok(fd, z) && !force) {
- if (!interactive)
- errx(EXIT_FAILURE, _("I don't like these partitions - nothing changed.\n"
- "(If you really want this, use the --force option.)"));
- else
- warnx(_("I don't like this - probably you should answer No\n"));
- }
- if (interactive) {
- ask:
- if (no_write)
- /* TRANSLATORS: sfdisk uses rpmatch which means the answers y and n
- * should be translated, but that is not the case with q answer. */
- printf(_("Are you satisfied with this? [ynq] "));
- else
- printf(_("Do you want to write this to disk? [ynq] "));
- ignore_result( fgets(answer, sizeof(answer), stdin) );
- if (answer[0] == 'q' || answer[0] == 'Q') {
- errx(EXIT_FAILURE, _("Quitting - nothing changed"));
- } else if (rpmatch(answer) == 1) {
- continue;
- } else if (rpmatch(answer) == 0) {
- break;
- } else {
- printf(_("Please answer one of y,n,q\n"));
- goto ask;
- }
- } else
- break;
- }
-
- if (write_partitions(dev, fd, z))
- printf(_("Successfully wrote the new partition table\n\n"));
- else
- exit_status = 1;
-
- if (!reread_disk_partition(dev, fd)) { /* close fd on success */
- close(fd);
- exit_status = 1;
- }
- my_warn(_("If you created or changed a DOS partition, /dev/foo7, say, then use dd(1)\n"
- "to zero the first 512 bytes: dd if=/dev/zero of=/dev/foo7 bs=512 count=1\n"
- "(See fdisk(8).)\n"));
-
- sync(); /* superstition */
- exit(exit_status);
-}
diff --git a/fdisk/utils.c b/fdisk/utils.c
deleted file mode 100644
index 04ad0a56e..000000000
--- a/fdisk/utils.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (C) 2012 Davidlohr Bueso <dave@gnu.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#ifdef HAVE_LIBBLKID
-#include <blkid.h>
-#endif
-
-#include "nls.h"
-#include "blkdev.h"
-#include "common.h"
-#include "fdisk.h"
-
-int fdisk_debug_mask;
-
-static int __init_mbr_buffer(struct fdisk_context *cxt)
-{
- DBG(TOPOLOGY, dbgprint("initialize MBR buffer"));
-
- cxt->mbr = calloc(1, MAX_SECTOR_SIZE);
- if (!cxt->mbr)
- goto fail;
-
- /* read MBR */
- if (512 != read(cxt->dev_fd, cxt->mbr, 512))
- goto fail;
-
- return 0;
-fail:
- return -1;
-}
-
-static unsigned long __get_sector_size(int fd)
-{
- int sect_sz;
-
- if (!blkdev_get_sector_size(fd, &sect_sz))
- return (unsigned long) sect_sz;
- return DEFAULT_SECTOR_SIZE;
-}
-
-/**
- * fdisk_geom_set_cyls
- * @cxt: fdisk context
- *
- * Sets the cylinders based on sectors and heads
- */
-void fdisk_geom_set_cyls(struct fdisk_context *cxt)
-{
- cxt->geom.cylinders = cxt->total_sectors /
- (cxt->geom.heads * cxt->geom.sectors);
-}
-
-static int __discover_geometry(struct fdisk_context *cxt)
-{
- sector_t nsects;
- unsigned int h = 0, s = 0;
-
- /* get number of 512-byte sectors, and convert it the real sectors */
- if (!blkdev_get_sectors(cxt->dev_fd, &nsects))
- cxt->total_sectors = (nsects / (cxt->sector_size >> 9));
-
- get_partition_table_geometry(cxt, &h, &s);
- if (h && s)
- goto hs_ok;
-
- /* what the kernel/bios thinks the geometry is */
- blkdev_get_geometry(cxt->dev_fd, &h, &s);
- if (h && s)
- goto hs_ok;
-
- /* unable to discover geometry, use default values */
- s = 63;
- h = 255;
-
-hs_ok: /* obtained heads and sectors */
- cxt->geom.heads = h;
- cxt->geom.sectors = s;
- fdisk_geom_set_cyls(cxt);
- update_sector_offset(cxt);
-
- DBG(GEOMETRY, dbgprint("geometry discovered for %s: C/H/S: %lld/%d/%lld",
- cxt->dev_path, cxt->geom.cylinders,
- cxt->geom.heads, cxt->geom.sectors));
-
- return 0;
-}
-
-static int __discover_topology(struct fdisk_context *cxt)
-{
-#ifdef HAVE_LIBBLKID
- blkid_probe pr;
-
- DBG(TOPOLOGY, dbgprint("initialize libblkid prober"));
-
- pr = blkid_new_probe();
- if (pr && blkid_probe_set_device(pr, cxt->dev_fd, 0, 0) == 0) {
- blkid_topology tp = blkid_probe_get_topology(pr);
-
- if (tp) {
- cxt->min_io_size = blkid_topology_get_minimum_io_size(tp);
- cxt->optimal_io_size = blkid_topology_get_optimal_io_size(tp);
- cxt->phy_sector_size = blkid_topology_get_physical_sector_size(tp);
- cxt->alignment_offset = blkid_topology_get_alignment_offset(tp);
-
- /* I/O size used by fdisk */
- cxt->io_size = cxt->optimal_io_size;
- if (!cxt->io_size)
- /* optimal IO is optional, default to minimum IO */
- cxt->io_size = cxt->min_io_size;
- }
- }
- blkid_free_probe(pr);
-#endif
-
- /* no blkid or error, use default values */
- if (!cxt->min_io_size)
- cxt->min_io_size = DEFAULT_SECTOR_SIZE;
- if (!cxt->io_size)
- cxt->io_size = DEFAULT_SECTOR_SIZE;
-
- cxt->sector_size = __get_sector_size(cxt->dev_fd);
- if (!cxt->phy_sector_size) /* could not discover physical size */
- cxt->phy_sector_size = cxt->sector_size;
-
- DBG(TOPOLOGY, dbgprint("topology discovered for %s:\n"
- "\tlogical/physical sector sizes: %ld/%ld\n"
- "\tfdisk/minimal/optimal io sizes: %ld/%ld/%ld\n",
- cxt->dev_path, cxt->sector_size, cxt->phy_sector_size,
- cxt->io_size, cxt->optimal_io_size, cxt->min_io_size));
- return 0;
-}
-
-/**
- * fdisk_mbr_zeroize:
- * @cxt: fdisk context
- *
- * Zero's MBR buffer
- */
-void fdisk_mbr_zeroize(struct fdisk_context *cxt)
-{
- if (cxt->mbr) {
- DBG(CONTEXT, dbgprint("zeroize in-memory MBR"));
- memset(cxt->mbr, 0, MAX_SECTOR_SIZE);
- }
-}
-
-/**
- * fdisk_dev_sectsz_is_default:
- * @cxt: fdisk context
- *
- * Returns 1 if the device's sector size is the default value, otherwise 0.
- */
-int fdisk_dev_sectsz_is_default(struct fdisk_context *cxt)
-{
- return cxt->sector_size == DEFAULT_SECTOR_SIZE;
-}
-
-/**
- * fdisk_dev_has_topology:
- * @cxt: fdisk context
- *
- * Returns 1 if the device provides topology information, otherwise 0.
- */
-int fdisk_dev_has_topology(struct fdisk_context *cxt)
-{
- /*
- * Assume that the device provides topology info if
- * optimal_io_size is set or alignment_offset is set or
- * minimum_io_size is not power of 2.
- */
- if (cxt->optimal_io_size || cxt->alignment_offset ||
- !is_power_of_2(cxt->min_io_size))
- return 1;
- return 0;
-}
-
-/**
- * fdisk_init_debug:
- * @mask: debug mask (0xffff to enable full debuging)
- *
- * If the @mask is not specified then this function reads
- * FDISK_DEBUG environment variable to get the mask.
- *
- * Already initialized debugging stuff cannot be changed. It does not
- * have effect to call this function twice.
- */
-void fdisk_init_debug(int mask)
-{
- if (fdisk_debug_mask & FDISK_DEBUG_INIT)
- return;
- if (!mask) {
- char *str = getenv("FDISK_DEBUG");
- if (str)
- fdisk_debug_mask = strtoul(str, 0, 0);
- } else
- fdisk_debug_mask = mask;
-
- if (fdisk_debug_mask)
- fprintf(stderr, "fdisk: debug mask set to 0x%04x.\n",
- fdisk_debug_mask);
- fdisk_debug_mask |= FDISK_DEBUG_INIT;
-}
-
-/**
- * fdisk_new_context:
- * @filename: path to the device to be handled
- * @readonly: how to open the device
- *
- * If the @readonly flag is set to false, fdisk will attempt to open
- * the device with read-write mode and will fallback to read-only if
- * unsuccessful.
- *
- * Returns: newly allocated fdisk context
- */
-struct fdisk_context *fdisk_new_context_from_filename(const char *fname, int readonly)
-{
- int fd, errsv = 0;
- struct fdisk_context *cxt = NULL;
-
- DBG(CONTEXT, dbgprint("initializing context for %s", fname));
-
- if (readonly == 1 || (fd = open(fname, O_RDWR)) < 0) {
- if ((fd = open(fname, O_RDONLY)) < 0)
- return NULL;
- readonly = 1;
- }
-
- cxt = calloc(1, sizeof(*cxt));
- if (!cxt)
- goto fail;
-
- cxt->dev_fd = fd;
- cxt->dev_path = strdup(fname);
- if (!cxt->dev_path)
- goto fail;
-
- if (__init_mbr_buffer(cxt) < 0)
- goto fail;
-
- __discover_topology(cxt);
- __discover_geometry(cxt);
-
- DBG(CONTEXT, dbgprint("context initialized for %s [%s]",
- fname, readonly ? "READ-ONLY" : "READ-WRITE"));
- return cxt;
-fail:
- errsv = errno;
- fdisk_free_context(cxt);
- errno = errsv;
-
- DBG(CONTEXT, dbgprint("failed to initialize context for %s: %m", fname));
- return NULL;
-}
-
-/**
- * fdisk_free_context:
- * @cxt: fdisk context
- *
- * Deallocates context struct.
- */
-void fdisk_free_context(struct fdisk_context *cxt)
-{
- if (!cxt)
- return;
-
- DBG(CONTEXT, dbgprint("freeing context for %s", cxt->dev_path));
- close(cxt->dev_fd);
- free(cxt->dev_path);
- free(cxt->mbr);
- free(cxt);
-}