⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdisk.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* fdisk.c -- Partition table manipulator for Linux. * * Copyright (C) 1992  A. V. Le Blanc (LeBlanc@mcc.ac.uk) * * 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 <setjmp.h>#include <errno.h>#include <getopt.h>#include <sys/stat.h>#include "nls.h"#include "common.h"#include "fdisk.h"#include "fdisksunlabel.h"#include "fdisksgilabel.h"#include "fdiskaixlabel.h"#include "../defines.h"#ifdef HAVE_blkpg_h#include <linux/blkpg.h>#endifstatic void delete_partition(int i);#define hex_val(c)	({ \				char _c = (c); \				isdigit(_c) ? _c - '0' : \				tolower(_c) + 10 - 'a'; \			})#define LINE_LENGTH	800#define pt_offset(b, n)	((struct partition *)((b) + 0x1be + \				(n) * sizeof(struct partition)))#define sector(s)	((s) & 0x3f)#define cylinder(s, c)	((c) | (((s) & 0xc0) << 2))#define hsc2sector(h,s,c) (sector(s) - 1 + sectors * \				((h) + heads * cylinder(s,c)))#define set_hsc(h,s,c,sector) { \				s = sector % sectors + 1;	\				sector /= sectors;	\				h = sector % heads;	\				sector /= heads;	\				c = sector & 0xff;	\				s |= (sector >> 2) & 0xc0;	\			}/* A valid partition table sector ends in 0x55 0xaa */static unsigned intpart_table_flag(char *b) {	return ((unsigned int) b[510]) + (((unsigned int) b[511]) << 8);}intvalid_part_table_flag(unsigned char *b) {	return (b[510] == 0x55 && b[511] == 0xaa);}static voidwrite_part_table_flag(char *b) {	b[510] = 0x55;	b[511] = 0xaa;}/* start_sect and nr_sects are stored little endian on all machines *//* moreover, they are not aligned correctly */static voidstore4_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 intread4_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 voidset_start_sect(struct partition *p, unsigned int start_sect) {	store4_little_endian(p->start4, start_sect);}unsigned intget_start_sect(struct partition *p) {	return read4_little_endian(p->start4);}static voidset_nr_sects(struct partition *p, unsigned int nr_sects) {	store4_little_endian(p->size4, nr_sects);}unsigned intget_nr_sects(struct partition *p) {	return read4_little_endian(p->size4);}/* normally O_RDWR, -l option gives O_RDONLY */static int type_open = O_RDWR;/* * Raw disk label. For DOS-type partition tables the MBR, * with descriptions of the primary partitions. */char MBRbuffer[MAX_SECTOR_SIZE];/* * 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 */	unsigned int offset;		/* disk sector number */	char *sectorbuffer;		/* disk sector contents */} ptes[MAXIMUM_PARTS];char	*disk_device,			/* must be specified */	*line_ptr,			/* interactive input */	line_buffer[LINE_LENGTH];int	fd,				/* the disk */	ext_index,			/* the prime extended partition */	listing = 0,			/* no aborts for fdisk -l */	nowarn = 0,			/* no warnings for fdisk -l/-s */	dos_compatible_flag = ~0,	dos_changed = 0,	partitions = 4;			/* maximum partition + 1 */unsigned int	user_cylinders, user_heads, user_sectors;unsigned int	pt_heads, pt_sectors;unsigned int	kern_heads, kern_sectors;unsigned int	heads,	sectors,	cylinders,	sector_size = DEFAULT_SECTOR_SIZE,	user_set_sector_size = 0,	sector_offset = 1,	units_per_sector = 1,	display_in_cyl_units = 1,	extended_offset = 0;		/* offset of link pointers */unsigned long long total_number_of_sectors;#define dos_label (!sun_label && !sgi_label && !aix_label && !osf_label)int     sun_label = 0;                  /* looking at sun disklabel */int	sgi_label = 0;			/* looking at sgi disklabel */int	aix_label = 0;			/* looking at aix disklabel */int	osf_label = 0;			/* looking at OSF/1 disklabel */int	possibly_osf_label = 0;jmp_buf listingbuf;void fatal(enum failure why) {	char	error[LINE_LENGTH],		*message = error;	if (listing) {		close(fd);		longjmp(listingbuf, 1);	}	switch (why) {		case usage: message = _("Usage: fdisk [-b SSZ] [-u] DISK     Change partition table\n""       fdisk -l [-b SSZ] [-u] DISK  List partition table(s)\n""       fdisk -s PARTITION           Give partition size(s) in blocks\n""       fdisk -v                     Give fdisk version\n""Here DISK is something like /dev/hdb or /dev/sda\n""and PARTITION is something like /dev/hda7\n""-u: give Start and End in sector (instead of cylinder) units\n""-b 2048: (for certain MO disks) use 2048-byte sectors\n");			break;		case usage2:		  /* msg in cases where fdisk used to probe */			message = _("Usage: fdisk [-l] [-b SSZ] [-u] device\n""E.g.: fdisk /dev/hda  (for the first IDE disk)\n""  or: fdisk /dev/sdc  (for the third SCSI disk)\n""  or: fdisk /dev/eda  (for the first PS/2 ESDI drive)\n""  or: fdisk /dev/rd/c0d0  or: fdisk /dev/ida/c0d0  (for RAID devices)\n""  ...\n");			break;		case unable_to_open:			snprintf(error, sizeof(error),				 _("Unable to open %s\n"), disk_device);			break;		case unable_to_read:			snprintf(error, sizeof(error),				 _("Unable to read %s\n"), disk_device);			break;		case unable_to_seek:			snprintf(error, sizeof(error),				_("Unable to seek on %s\n"),disk_device);			break;		case unable_to_write:			snprintf(error, sizeof(error),				_("Unable to write %s\n"), disk_device);			break;		case ioctl_error:			snprintf(error, sizeof(error),				 _("BLKGETSIZE ioctl failed on %s\n"),				disk_device);			break;		case out_of_memory:			message = _("Unable to allocate any more memory\n");			break;		default:			message = _("Fatal error\n");	}	fputc('\n', stderr);	fputs(message, stderr);	exit(1);}static voidseek_sector(int fd, unsigned int secno) {	long long offset = (long long) secno * sector_size;	if (ext2_llseek(fd, offset, SEEK_SET) == (long long) -1)		fatal(unable_to_seek);}static voidread_sector(int fd, unsigned int secno, char *buf) {	seek_sector(fd, secno);	if (read(fd, buf, sector_size) != sector_size)		fatal(unable_to_read);}static voidwrite_sector(int fd, unsigned int secno, char *buf) {	seek_sector(fd, secno);	if (write(fd, buf, sector_size) != sector_size)		fatal(unable_to_write);}/* Allocate a buffer and read a partition table sector */static voidread_pte(int fd, int pno, unsigned int offset) {	struct pte *pe = &ptes[pno];	pe->offset = offset;	pe->sectorbuffer = (char *) malloc(sector_size);	if (!pe->sectorbuffer)		fatal(out_of_memory);	read_sector(fd, offset, pe->sectorbuffer);	pe->changed = 0;	pe->part_table = pe->ext_pointer = NULL;}static unsigned intget_partition_start(struct pte *pe) {	return pe->offset + get_start_sect(pe->part_table);}struct partition *get_part_table(int i) {	return ptes[i].part_table;}voidset_all_unchanged(void) {	int i;	for (i = 0; i < MAXIMUM_PARTS; i++)		ptes[i].changed = 0;}voidset_changed(int i) {	ptes[i].changed = 1;}static intis_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;}/* * 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". */static intis_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 voidmenu(void) {	if (sun_label) {	   puts(_("Command action"));	   puts(_("   a   toggle a read only flag")); 		/* sun */	   puts(_("   b   edit bsd disklabel"));	   puts(_("   c   toggle the mountable flag"));		/* sun */	   puts(_("   d   delete a partition"));	   puts(_("   l   list known partition types"));	   puts(_("   m   print this menu"));	   puts(_("   n   add a new partition"));	   puts(_("   o   create a new empty DOS partition table"));	   puts(_("   p   print the partition table"));	   puts(_("   q   quit without saving changes"));	   puts(_("   s   create a new empty Sun disklabel"));	/* sun */	   puts(_("   t   change a partition's system id"));	   puts(_("   u   change display/entry units"));	   puts(_("   v   verify the partition table"));	   puts(_("   w   write table to disk and exit"));	   puts(_("   x   extra functionality (experts only)"));	}	else if (sgi_label) {	   puts(_("Command action"));	   puts(_("   a   select bootable partition"));    /* sgi flavour */	   puts(_("   b   edit bootfile entry"));          /* sgi */	   puts(_("   c   select sgi swap partition"));    /* sgi flavour */	   puts(_("   d   delete a partition"));	   puts(_("   l   list known partition types"));	   puts(_("   m   print this menu"));	   puts(_("   n   add a new partition"));	   puts(_("   o   create a new empty DOS partition table"));	   puts(_("   p   print the partition table"));	   puts(_("   q   quit without saving changes"));	   puts(_("   s   create a new empty Sun disklabel"));	/* sun */	   puts(_("   t   change a partition's system id"));	   puts(_("   u   change display/entry units"));	   puts(_("   v   verify the partition table"));	   puts(_("   w   write table to disk and exit"));	}	else if (aix_label) {	   puts(_("Command action"));	   puts(_("   m   print this menu"));	   puts(_("   o   create a new empty DOS partition table"));	   puts(_("   q   quit without saving changes"));	   puts(_("   s   create a new empty Sun disklabel"));	/* sun */	}	else {	   puts(_("Command action"));	   puts(_("   a   toggle a bootable flag"));	   puts(_("   b   edit bsd disklabel"));	   puts(_("   c   toggle the dos compatibility flag"));	   puts(_("   d   delete a partition"));	   puts(_("   l   list known partition types"));	   puts(_("   m   print this menu"));	   puts(_("   n   add a new partition"));	   puts(_("   o   create a new empty DOS partition table"));	   puts(_("   p   print the partition table"));	   puts(_("   q   quit without saving changes"));	   puts(_("   s   create a new empty Sun disklabel"));	/* sun */	   puts(_("   t   change a partition's system id"));	   puts(_("   u   change display/entry units"));	   puts(_("   v   verify the partition table"));	   puts(_("   w   write table to disk and exit"));	   puts(_("   x   extra functionality (experts only)"));	}}static voidxmenu(void) {	if (sun_label) {	   puts(_("Command action"));	   puts(_("   a   change number of alternate cylinders"));      /*sun*/	   puts(_("   c   change number of cylinders"));	   puts(_("   d   print the raw data in the partition table"));	   puts(_("   e   change number of extra sectors per cylinder"));/*sun*/	   puts(_("   h   change number of heads"));	   puts(_("   i   change interleave factor"));			/*sun*/	   puts(_("   o   change rotation speed (rpm)"));		/*sun*/	   puts(_("   m   print this menu"));	   puts(_("   p   print the partition table"));	   puts(_("   q   quit without saving changes"));	   puts(_("   r   return to main menu"));	   puts(_("   s   change number of sectors/track"));	   puts(_("   v   verify the partition table"));	   puts(_("   w   write table to disk and exit"));	   puts(_("   y   change number of physical cylinders"));	/*sun*/	}	else if (sgi_label) {	   puts(_("Command action"));	   puts(_("   b   move beginning of data in a partition")); /* !sun */	   puts(_("   c   change number of cylinders"));	   puts(_("   d   print the raw data in the partition table"));	   puts(_("   e   list extended partitions"));		/* !sun */	   puts(_("   g   create an IRIX (SGI) partition table"));/* sgi */	   puts(_("   h   change number of heads"));	   puts(_("   m   print this menu"));	   puts(_("   p   print the partition table"));	   puts(_("   q   quit without saving changes"));	   puts(_("   r   return to main menu"));	   puts(_("   s   change number of sectors/track"));	   puts(_("   v   verify the partition table"));	   puts(_("   w   write table to disk and exit"));	}	else if (aix_label) {	   puts(_("Command action"));	   puts(_("   b   move beginning of data in a partition")); /* !sun */	   puts(_("   c   change number of cylinders"));	   puts(_("   d   print the raw data in the partition table"));	   puts(_("   e   list extended partitions"));		/* !sun */	   puts(_("   g   create an IRIX (SGI) partition table"));/* sgi */	   puts(_("   h   change number of heads"));	   puts(_("   m   print this menu"));	   puts(_("   p   print the partition table"));	   puts(_("   q   quit without saving changes"));	   puts(_("   r   return to main menu"));	   puts(_("   s   change number of sectors/track"));	   puts(_("   v   verify the partition table"));	   puts(_("   w   write table to disk and exit"));	}	else {	   puts(_("Command action"));	   puts(_("   b   move beginning of data in a partition")); /* !sun */	   puts(_("   c   change number of cylinders"));	   puts(_("   d   print the raw data in the partition table"));	   puts(_("   e   list extended partitions"));		/* !sun */	   puts(_("   f   fix partition order"));		/* !sun, !aix, !sgi */	   puts(_("   g   create an IRIX (SGI) partition table"));/* sgi */	   puts(_("   h   change number of heads"));	   puts(_("   m   print this menu"));	   puts(_("   p   print the partition table"));	   puts(_("   q   quit without saving changes"));	   puts(_("   r   return to main menu"));	   puts(_("   s   change number of sectors/track"));	   puts(_("   v   verify the partition table"));	   puts(_("   w   write table to disk and exit"));	}}static intget_sysid(int i) {	return (		sun_label ? sunlabel->infos[i].id :		sgi_label ? sgi_get_sysid(i) :		ptes[i].part_table->sys_ind);}static struct systypes *get_sys_types(void) {	return (		sun_label ? sun_sys_types :		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 {		printf("%c%2x  %-15.15s", i ? ' ' : '\n',		        sys[next].type, _(sys[next].name)); 		next = last[i++] + done;		if (i > 3 || next >= last[i]) {			i = 0;			next = ++done;		}	} while (done < last[0]);	putchar('\n');}static intis_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));}static voidclear_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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -