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

📄 fdisksgilabel.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * 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 */#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 <linux/major.h>        /* FLOPPY_MAJOR */#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 voidsetfreelist(int i, unsigned int f, unsigned int l) {	freelist[i].first = f;	freelist[i].last = l;}static voidadd2freelist(unsigned int f, unsigned int l) {	int i = 0;	for ( ; i < 17 ; i++)		if (freelist[i].last == 0)			break;	setfreelist(i, f, l);}static voidclearfreelist(void) {	int i;	for (i = 0; i < 17 ; i++)		setfreelist(i, 0, 0);}static unsigned intisinfreelist(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 inline unsigned short__swap16(unsigned short x) {        return (((__u16)(x) & 0xFF) << 8) | (((__u16)(x) & 0xFF00) >> 8);}static inline __u32__swap32(__u32 x) {        return (((x & 0xFF) << 24) |		((x & 0xFF00) << 8) |		((x & 0xFF0000) >> 8) |		((x & 0xFF000000) >> 24));}static intsgi_get_nsect(void) {	return SSWAP16(sgilabel->devparam.nsect);}static intsgi_get_ntrks(void) {	return SSWAP16(sgilabel->devparam.ntrks);}#if 0static intsgi_get_head_vol0(void) {	return SSWAP16(sgilabel->devparam.head_vol0);}static intsgi_get_bytes(void) {	return SSWAP16(sgilabel->devparam.bytes);}static intsgi_get_pcylcount(void) {	return SSWAP16(sgilabel->devparam.pcylcount);}#endifvoidsgi_nolabel() {	sgilabel->magic = 0;	sgi_label = 0;	partitions = 4;}static unsigned inttwo_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;}intcheck_sgi_label() {	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) {		sgi_label = 0;		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();	sgi_label = 1;	partitions= 16;	volumes = 15;	return 1;}voidsgi_list_table(int xtra) {	int i, w;	int kpi = 0;		/* kernel partition ID */	char *type;	w = strlen(disk_device);	if (xtra) {		printf(_("\nDisk %s (SGI disk label): %d heads, %d sectors\n"			 "%d cylinders, %d physical cylinders\n"			 "%d extra sects/cyl, interleave %d:1\n"			 "%s\n"			 "Units = %s of %d * 512 bytes\n\n"),		       disk_device, heads, sectors, cylinders,		       SSWAP16(sgiparam.pcylcount),		       SSWAP16(sgiparam.sparecyl),		       SSWAP16(sgiparam.ilfact),		       (char *)sgilabel,		       str_units(PLURAL), units_per_sector);	} else {		printf(_("\nDisk %s (SGI disk label): "			 "%d heads, %d sectors, %d cylinders\n"			 "Units = %s of %d * 512 bytes\n\n"),		       disk_device, heads, sectors, cylinders,		       str_units(PLURAL), units_per_sector);	}	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(i) || debug) {			__u32 start = sgi_get_start_sector(i);			__u32 len = sgi_get_num_sectors(i);			kpi++;		/* only count nonempty partitions */			printf(				"%2d: %s %4s %9ld %9ld %9ld  %2x  %s\n",/* fdisk part number */   i+1,/* device */              partname(disk_device, kpi, w+2),/* flags */               (sgi_get_swappartition() == i) ? "swap" :/* flags */               (sgi_get_bootpartition() == i) ? "boot" : "    ", /* start */               (long) scround(start),/* end */                 (long) scround(start+len)-1,/* no odd flag on end */  (long) len, /* type id */             sgi_get_sysid(i),/* type name */           (type = partition_type(sgi_get_sysid(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) {			__u32 start = SSWAP32(sgilabel->directory[i].vol_file_start);			__u32 len = SSWAP32(sgilabel->directory[i].vol_file_size);			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 intsgi_get_start_sector(int i) {	return SSWAP32(sgilabel->partitions[i].start_sector);}unsigned intsgi_get_num_sectors(int i) {	return SSWAP32(sgilabel->partitions[i].num_sectors);}intsgi_get_sysid(int i){	return SSWAP32(sgilabel->partitions[i].id);}intsgi_get_bootpartition(void){	return SSWAP16(sgilabel->boot_part);}intsgi_get_swappartition(void){	return SSWAP16(sgilabel->swap_part);}voidsgi_set_bootpartition(int i){	sgilabel->boot_part = SSWAP16(((short)i));}static unsigned intsgi_get_lastblock(void) {	return heads * sectors * cylinders;}voidsgi_set_swappartition(int i) {	sgilabel->swap_part = SSWAP16(((short)i));}static intsgi_check_bootfile(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, 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 */}const char *sgi_get_bootfile(void) {	return sgilabel->boot_file;}voidsgi_set_bootfile(const char* aFile) {	int i = 0;	if (sgi_check_bootfile(aFile)) {		while (i < 16) {			if ((aFile[i] != '\n')	/* in principle caught again by next line */			    &&  (strlen(aFile) > i))				sgilabel->boot_file[i] = aFile[i];			else				sgilabel->boot_file[i] = 0;			i++;		}		printf(_("\n\tBootfile is changed to \"%s\".\n"),		       sgilabel->boot_file);	}}voidcreate_sgiinfo(void) {	/* 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(sgilabel->directory[0].vol_file_name, "sgilabel", 8);}sgiinfo *fill_sgiinfo(void);voidsgi_write_table(void) {	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(fd, 0, SEEK_SET) < 0)		fatal(unable_to_seek);	if (write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE)		fatal(unable_to_write);	if (! strncmp(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 (ext2_llseek(fd, (long long)infostartblock*				SECTOR_SIZE, SEEK_SET) < 0)			fatal(unable_to_seek);		if (write(fd, info, SECTOR_SIZE) != SECTOR_SIZE)			fatal(unable_to_write);		free(info);	}}static intcompare_start(int *x, int *y) {	/*	 * sort according to start sectors	 * and prefers largest partition:	 * entry zero is entire disk entry	 */	unsigned int i = *x;	unsigned int j = *y;	unsigned int a = sgi_get_start_sector(i);	unsigned int b = sgi_get_start_sector(j);	unsigned int c = sgi_get_num_sectors(i);	unsigned int d = sgi_get_num_sectors(j);	if (a == b)		return (d > c) ? 1 : (d == c) ? 0 : -1;	return (a > b) ? 1 : -1;}static intsgi_gaps(void) {	/*	 * 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(0);}intverify_sgi(int verbose){	int Index[16];		/* list of valid partitions */

⌨️ 快捷键说明

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