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

📄 fdisk.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 5 页
字号:
		 hex = hex << 4 | hex_val(*line_ptr++);	      while (isxdigit(*line_ptr));	      return hex;	   }        }}/* * 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 intread_int(unsigned int low, unsigned int dflt, unsigned int high,	 unsigned int base, char *mesg){	unsigned int i;	int default_ok = 1;	static char *ms = NULL;	static int mslen = 0;	if (!ms || strlen(mesg)+100 > mslen) {		mslen = strlen(mesg)+200;		if (!(ms = realloc(ms,mslen)))			fatal(out_of_memory);	}	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 absolute = 0;			i = atoi(line_ptr+1); 			while (isdigit(*++line_ptr))				use_default = 0;			switch (*line_ptr) {				case 'c':				case 'C':					if (!display_in_cyl_units)						i *= heads * sectors;					break;				case 'K':					absolute = 1024;					break;				case 'k':					absolute = 1000;					break;				case 'm':				case 'M':					absolute = 1000000;					break;				case 'g':				case 'G':					absolute = 1000000000;					break;				default:					break;			}			if (absolute) {				unsigned long long bytes;				unsigned long unit;				bytes = (unsigned long long) i * absolute;				unit = sector_size * units_per_sector;				bytes += unit/2;	/* round */				bytes /= unit;				i = bytes;			}			if (minus)				i = -i;			i += base;		} else {			i = atoi(line_ptr);			while (isdigit(*line_ptr)) {				line_ptr++;				use_default = 0;			}		}		if (use_default)			printf(_("Using default value %u\n"), i = dflt);		if (i >= low && i <= high)			break;		else			printf(_("Value out of range.\n"));	}	return i;}intget_partition(int warn, int max) {	struct pte *pe;	int i;	i = read_int(1, 0, max, 0, _("Partition number")) - 1;	pe = &ptes[i];	if (warn) {		if ((!sun_label && !sgi_label && !pe->part_table->sys_ind)		    || (sun_label &&			(!sunlabel->partitions[i].num_sectors ||			 !sunlabel->infos[i].id))		    || (sgi_label && (!sgi_get_num_sectors(i)))		   )			fprintf(stderr,				_("Warning: partition %d has empty type\n"),				i+1);	}	return i;}static intget_existing_partition(int warn, int max) {	int pno = -1;	int i;	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_unique:	return get_partition(warn, max);}static intget_nonexisting_partition(int warn, int max) {	int pno = -1;	int i;	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(_("All primary partitions have been defined already!\n"));	return -1; not_unique:	return get_partition(warn, max);}char * conststr_units(int n) {	/* n==1: use singular */	if (n == 1)		return display_in_cyl_units ? _("cylinder") : _("sector");	else		return display_in_cyl_units ? _("cylinders") : _("sectors");}void change_units(void){	display_in_cyl_units = !display_in_cyl_units;	update_units();	printf(_("Changing display/entry units to %s\n"),		str_units(PLURAL));}static voidtoggle_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 voidtoggle_dos_compatibility_flag(void) {	dos_compatible_flag = ~dos_compatible_flag;	if (dos_compatible_flag) {		sector_offset = sectors;		printf(_("DOS Compatibility flag is set\n"));	}	else {		sector_offset = 1;		printf(_("DOS Compatibility flag is not set\n"));	}}static voiddelete_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 (warn_geometry())		return;		/* C/H/S not set */	pe->changed = 1;	if (sun_label) {		sun_delete_partition(i);		return;	}	if (sgi_label) {		sgi_delete_partition(i);		return;	}	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);		return;	}	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);	}}static voidchange_sysid(void) {	char *temp;	int i, sys, origsys;	struct partition *p;	/* If sgi_label then don't use get_existing_partition,	   let the user select a partition, since get_existing_partition()	   only works for Linux like partition tables. */	if (!sgi_label) { 		i = get_existing_partition(0, partitions);	} else {		i = get_partition(0, partitions);	}	if (i == -1)		return;	p = ptes[i].part_table;	origsys = sys = get_sysid(i);	/* if changing types T to 0 is allowed, then	   the reverse change must be allowed, too */	if (!sys && !sgi_label && !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 && !sgi_label && !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 (!sun_label && !sgi_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 (sun_label && i == 2 && sys != WHOLE_DISK)				printf(_("Consider leaving partition 3 "				       "as Whole disk (5),\n"				       "as SunOS/Solaris expects it and "				       "even Linux likes it.\n\n"));			if (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 (sun_label) {				sun_change_sysid(i, sys);			} else			if (sgi_label) {				sgi_change_sysid(i, sys);			} else				p->sys_ind = sys;                        printf (_("Changed system type of partition %d "                                "to %x (%s)\n"), i + 1, sys,                                (temp = partition_type(sys)) ? temp :                                _("Unknown"));                        ptes[i].changed = 1;			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 voidlong2chs(ulong ls, unsigned int *c, unsigned int *h, unsigned int *s) {	int spc = heads * sectors;	*c = ls / spc;	ls = ls % spc;	*h = ls / sectors;	*s = ls % sectors + 1;	/* sectors count from 1 */}static void check_consistency(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 (!heads || !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(get_start_sect(p), &lbc, &lbh, &lbs);/* compute logical ending (c, h, s) */	long2chs(get_start_sect(p) + get_nr_sects(p) - 1, &lec, &leh, &les);/* Same physical / logical beginning? */	if (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 (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);	}#if 0/* Beginning on cylinder boundary? */	if (pbh != !pbc || pbs != 1) {		printf(_("Partition %i does not start on cylinder "			"boundary:\n"), partition + 1);		printf(_("     phys=(%d, %d, %d) "), pbc, pbh, pbs);		printf(_("should be (%d, %d, 1)\n"), pbc, !pbc);	}#endif/* Ending on cylinder boundary? */	if (peh != (heads - 1) || pes != sectors) {		printf(_("Partition %i does not end on cylinder boundary.\n"),			partition + 1);#if 0		printf(_("     phys=(%d, %d, %d) "), pec, peh, pes);		printf(_("should be (%d, %d, %d)\n"),		pec, heads - 1, sectors);#endif	}}static voidlist_disk_geometry(void) {	long long bytes = (total_number_of_sectors << 9);	long megabytes = bytes/1000000;	if (megabytes < 10000)		printf(_("\nDisk %s: %ld MB, %lld bytes\n"),		       disk_device, megabytes, bytes);	else		printf(_("\nDisk %s: %ld.%ld GB, %lld bytes\n"),		       disk_device, megabytes/1000, (megabytes/100)%10, bytes);	printf(_("%d heads, %d sectors/track, %d cylinders"),	       heads, sectors, cylinders);	if (units_per_sector == 1)		printf(_(", total %llu sectors"),		       total_number_of_sectors / (sector_size/512));	printf("\n");	printf(_("Units = %s of %d * %d = %d bytes\n\n"),	       str_units(PLURAL),	       units_per_sector, sector_size, units_per_sector * sector_size);}/* * 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 intwrong_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 doesnt 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 voidfix_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;

⌨️ 快捷键说明

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