fdisk.c

来自「fdisk 实现源码,可以查询Linux下系统的分区信息」· C语言 代码 · 共 2,469 行 · 第 1/5 页

C
2,469
字号
		  	"Units = cylinders of %lld * %d = %s bytes\n"),			heads, sectors, cylinders, (heads * sectors), 			sect_size, cyl_size);        printf ("\n");        	has_extended = ped_disk_type_check_feature ((*disk)->type,			       		 PED_DISK_TYPE_EXTENDED);  	unsigned int i;		unsigned int pathlen;		/* TODO: Make this output the same output as util-linux fdisk(?), 	   possibly split into seperate functions */	if (fdisk_compatibility_mode && !strcmp((*disk)->type->name,"bsd")) {		printf ("%s %+10s %+11s %+11s %+4s %+7s ", _("#   "), 		      _("start"), _("end"), _("blocks"), _("id"), _("system"));		printf ("\n");	}	else {		pathlen  = strlen ((*disk)->dev->path);		unsigned int fix = 3 - !isdigit((*disk)->dev->path[pathlen-1]);		pathlen += fix;		for (i = 0; i < (pathlen - 5 - fix); i++)  		printf (" ");		printf ("%s %s %+10s %+11s %+11s %+4s %+7s ", _("Device"),			 _("Boot"), _("Start"), _("End"), _("Blocks"), _("Id"),			 _("System"));	printf ("\n");	}	PedSector total_cyl = heads * sectors;	for (part = ped_disk_next_partition (*disk, NULL); part;	     part = ped_disk_next_partition (*disk, part)) {				cyl_start     = (part->geom.start / (total_cyl)) + 1; 		cyl_end       = (part->geom.end   / (total_cyl)) + 1;	  	if (unit == PED_UNIT_SECTOR) {			/* In Linux fdisk compatibility mode, display exact */			if (fdisk_compatibility_mode) {				start = part->geom.start;				end = part->geom.end; 			}			/* In fdisk, round up the sectors to cylinders */			else {					start = (part->geom.start / total_cyl 				    		* total_cyl) + sectors; 		        	end   = part->geom.end / total_cyl * total_cyl;			}			blocks    = ((cyl_end * total_cyl) 						- ((part->num == 1) ? 			(cyl_start * sectors) : (cyl_start * total_cyl))) 					/ (1024 / sect_size);		} else {		  	start     = cyl_start;			end       = cyl_end;			blocks    = ((end * total_cyl) - ((part->num == 1) ? 			(start * sectors) : (start * total_cyl))) / (1024 / sect_size);		}			if (!ped_partition_is_active (part))	       		continue;			if (fdisk_compatibility_mode && !strcmp((*disk)->type->name,"bsd")) {			printf("  %c: ", 'a' + part->num - 1);		}		else {			get_partition_device(buf, sizeof(buf), part, logical_offset);			printf("%2$-*1$.*1$s", pathlen, buf);		if (ped_partition_get_flag(part,PED_PARTITION_BOOT))			printf("  *  ");		else			printf("     ");				}		printf ("%10lld %11lld %11lu ", start, end, blocks);		int type_size;		unsigned int part_type = get_disk_specific_system_type (part, &type_size);		type_size *= 2;		char *type_name = _(get_disk_specific_system_name(part,0)); 		if (type_size)			printf("  %*x  %s", type_size, part_type, type_name);		else if(type_name)			printf("  %s", type_name);		/* FIXME: This should not be here anymore */		else {			ped_device_begin_external_access((*disk)->dev);			char *type = (char *)ped_partition_type_get_name (part->type);			if (part->fs_type 				&& !strcmp (part->fs_type->name, "linux-swap"))				printf ("%+4s %+21s ", _("82"), _("Linux Swap / Solaris"));			else if (is_bsd_partition ((*disk)->dev->path, 				part->geom.start * sect_size, sect_size))				printf ("%+4s %+17s ", _("a5"), _("Free/Net/OpenBSD"));			else if (!strcmp (type, "primary")) 				printf ("%+4s %+6s ", _("83"), _("Linux"));			else if (!strcmp (type, "extended"))				printf ("%+4s %+9s ", _("5"), _("Extended"));			ped_device_end_external_access((*disk)->dev);		}		printf ("\n");		start = end = blocks = 0;		/* At the end we check the partition consistency for lfdisk */		if (fdisk_compatibility_mode)			check_partition_consistency(part);	}	ped_free (cyl_size);        	/*if (fdisk_list_table == 1)	  do_quit (disk);*/	return 1;error:	return 0;}#define sector(s)	((s) & 0x3f)#define cylinder(s, c)	((c) | (((s) & 0xc0) << 2))voidpart_xprint (PedDisk **disk, int extend){	PedPartition *part;	PedDevice *dev = (*disk)->dev;	PedCHSGeometry *chs = &(dev->bios_geom);	int is_boot, start_cyl, start_head, start_sector, 	             end_cyl, end_head, end_sector;	char *part_chs = NULL;	printf(_("\nDisk %s: %d heads, %d sectors, %d cylinders\n\n"),	       dev->path, chs->heads, chs->sectors, chs->cylinders);	printf(_("Nr AF  Hd Sec     Cyl  Hd Sec     Cyl      Start       Size ID\n"));	for (part = ped_disk_next_partition (*disk, NULL); part;	     part = ped_disk_next_partition (*disk, part)) {		if (!ped_partition_is_active(part))			continue;				/* We skip primary partitions, if needed */		if (extend && !part->type)			continue;  		/* TODO: Calculate, instead of parsing the string */		part_chs = ped_unit_format_custom(dev, part->geom.start,	                                          PED_UNIT_CHS);		sscanf(part_chs, "%d,%d,%d", &start_cyl, &start_head, &start_sector);		ped_free(part_chs);		part_chs = ped_unit_format_custom(dev, part->geom.end,	                                          PED_UNIT_CHS);		sscanf(part_chs, "%d,%d,%d", &end_cyl, &end_head, &end_sector);		ped_free(part_chs);		is_boot = ped_partition_get_flag(part,PED_PARTITION_BOOT);				printf("%2d %02x%4d%4d%8d%4d%4d%8d%11lld%11lld %02x\n",		       part->num, is_boot ? 0x80 : 0, 		       start_head, start_sector, start_cyl,		       end_head, end_sector, end_cyl,		       part->geom.start, part->geom.length, 		       get_disk_specific_system_type(part, NULL)); 							check_partition_consistency(part);	}}/* This is only run in Linux fdisk compatibility mode */static intdo_xprint (PedDisk **disk){	part_xprint(disk,0);	return 1;}static intdo_eprint (PedDisk **disk){	part_xprint(disk,1);	return 1;}/* This prints a sector, in the style Linux fdisk prints raw partition   tables, in hex, with 16 bytes per line */static voidprint_sector (PedDevice *dev, PedSector sector){	char *buf;	int size = dev->sector_size, i, pos = 0;	buf = malloc(size);	if (ped_device_read(dev, buf, sector, 1)) {		for (i = 0; i < size; i++) {			/* We print the line prefix */			if (pos == 0)				printf("0x%03X:", i);			printf(" %02hhX", buf[i]);			/* We print the line suffix */			if (pos == 15) {				printf("\n");				pos = 0;			}			else				pos++;		}		if (pos != 0)			printf("\n");		printf("\n");	}	free(buf);}static intdo_raw (PedDisk **disk) {	/* TODO: Make this for other disklabels, too */	if (strcmp((*disk)->type->name, "msdos")) {		fprintf(stderr,		        _("Raw printing on %s not supported\n"),		        (*disk)->type->name);		return 0;	}	printf(_("Device: %s\n"), (*disk)->dev->path);	/* This is for DOS partition table */	PedPartition *part;	int i;	/* First we print the MBR */	print_sector((*disk)->dev,0);		/* Then we print the partition table sectors for the logical partitions */	for (part = ped_disk_get_partition(*disk, i = 5); part;	     part = ped_disk_get_partition(*disk, ++i))	{		print_sector((*disk)->dev, part->prev->geom.start);	} }static voidprint_partition_size(PedDisk *disk){	PedPartition *part = ped_disk_get_partition(disk,fdisk_partsize_part);	if (!part) {		printf(_("There is no partition %d on %s\n"), fdisk_partsize_part, disk->dev->path);		exit(1);	}	else {		PedCHSGeometry* 	chs;		PedSector               sectors;		PedSector		cyl_size;		PedSector		cyl_start;		PedSector		cyl_end;		PedSector		sect_size;		PedSector		heads;		PedSector		total_cyl;			chs          = &(disk->dev)->bios_geom;		sectors      = chs->sectors;		heads        = chs->heads;		total_cyl    = heads * sectors;		sect_size    = disk->dev->sector_size;		cyl_start     = (part->geom.start / (total_cyl)) + 1; 		cyl_end       = (part->geom.end   / (total_cyl)) + 1;		//ped_unit_set_default(PED_UNIT_CYLINDER);		printf("%lld\n",			((cyl_end * total_cyl) - ((part->num == 1) ? 			(cyl_start * sectors) : (cyl_start * total_cyl))) / 			(1024 / sect_size)		);		exit(0);	}	}static void do_list_devices (PedDisk* disk) {        if (disk == NULL) {                PedDevice* dev = NULL;                    ped_device_probe_all ();                    while ((dev = ped_device_get_next (dev))) {                        if (!ped_device_open(dev))	                        break;                             PedDisk *disk = ped_disk_new(dev);			if (!disk) // Not fatal error				continue;			if (fdisk_print_raw)				do_raw (&disk);			else                        	do_print (&disk);                        ped_disk_destroy(disk);                }        } else {		if (fdisk_print_raw)			do_raw(&disk);		else                	do_print(&disk);	}        exit(0);}static PedPartitionType_disk_get_part_type_for_sector (PedDisk* disk, PedSector sector){	PedPartition*	extended;	extended = ped_disk_extended_partition (disk);	if (!extended	    || !ped_geometry_test_sector_inside (&extended->geom, sector))		return 0;	return PED_PARTITION_LOGICAL;}#if 0/* This function checks if "part" contains a file system, and returs * 	0 if either no file system was found, or the user declined to add it. * 	1 if a file system was found, and the user chose to add it. * 	-1 if the user chose to cancel the entire search. */static int_rescue_add_partition (PedPartition* part){	const PedFileSystemType*	fs_type;	PedGeometry*			probed;	PedExceptionOption		ex_opt;	PedConstraint*			constraint;	char*				found_start;	char*				found_end;	fs_type = ped_file_system_probe (&part->geom);	if (!fs_type)		return 0;	probed = ped_file_system_probe_specific (fs_type, &part->geom);	if (!probed)		return 0;	if (!ped_geometry_test_inside (&part->geom, probed)) {		ped_geometry_destroy (probed);		return 0;	}	constraint = ped_constraint_exact (probed);	if (!ped_disk_set_partition_geom (part->disk, part, constraint,					  probed->start, probed->end)) {		ped_constraint_destroy (constraint);		return 0;	}	ped_constraint_destroy (constraint);	found_start = ped_unit_format (probed->dev, probed->start);	found_end = ped_unit_format (probed->dev, probed->end);	ex_opt = ped_exception_throw (		PED_EXCEPTION_INFORMATION,		PED_EXCEPTION_YES_NO_CANCEL,		_("A %s %s partition was found at %s -> %s.  "		  "Do you want to add it to the partition table?"),		fs_type->name, ped_partition_type_get_name (part->type),		found_start, found_end);	ped_geometry_destroy (probed);	ped_free (found_start);	ped_free (found_end);	switch (ex_opt) {		case PED_EXCEPTION_CANCEL: return -1;		case PED_EXCEPTION_NO: return 0;	}	ped_partition_set_system (part, fs_type);	ped_disk_commit (part->disk);	return 1;}/* hack: we only iterate through the start, since most (all) fs's have their * superblocks at the start.  We'll need to change this if we generalize * for RAID, or something... */static int_rescue_pass (PedDisk* disk, PedGeometry* start_range, PedGeometry* end_range){	PedSector		start;	PedGeometry		start_geom_exact;	PedGeometry		entire_dev;	PedConstraint		constraint;	PedPartition*		part;	PedPartitionType	part_type;	part_type = _disk_get_part_type_for_sector (			disk, (start_range->start + end_range->end) / 2);	ped_geometry_init (&entire_dev, disk->dev, 0, disk->dev->length);	ped_timer_reset (timer);	ped_timer_set_state_name (timer, _("searching for file systems"));	for (start = start_range->start; start <= start_range->end; start++) {		ped_timer_update (timer, 1.0 * (start - start_range->start)					 / start_range->length);		ped_geometry_init (&start_geom_exact, disk->dev, start, 1);		ped_constraint_init (			&constraint, ped_alignment_any, ped_alignment_any,			&start_geom_exact, &entire_dev,			1, disk->dev->length);		part = ped_partition_new (disk, part_type, NULL, start,				end_range->end);		if (!part) {			ped_constraint_done (&constraint);			continue;		}		ped_exception_fetch_all ();		if (ped_disk_add_partition (disk, part, &constraint)) {			ped_exception_leave_all ();			switch (_rescue_add_partition (part)) {			case 1:				ped_constraint_done (&constraint);				return 1;			case 0:				ped_disk_remove_partition (disk, part);				break;			case -1:				goto error_remove_partition;			}		} else {			ped_exception_leave_all ();		}		ped_partition_destroy (part);		ped_constraint_done (&constraint);	}	ped_timer_update (timer, 1.0);	return 1;error_remove_partition:	ped_disk_remove_partition (disk, part);error_partition_destroy:	ped_partition_destroy (part);error_constraint_done:	ped_constraint_done (&constraint);error:	return 0;}#endifstatic intdo_rescue (PedDisk** disk){	return perform_rescue(*disk, 0LL, 0LL,	                      UI_CUSTOM_VALUES | UI_WARN_COMMIT);#if 0	PedSector		start = 0, end = 0;	PedSector		fuzz;	PedGeometry		probe_start_region;	PedGeometry		probe_end_region;	if (!*disk)		goto error;	if (!command_line_prompt_boolean_question 	(_("WARNING: rescue writes all data to disk automatically, continue")))		return 1;	if (!fdisk_command_line_get_sector (_("Start?"), (*disk)->dev, &start, NULL))		goto error;	if (!fdisk_command_line_get_sector (_("End?"), (*disk)->dev, &end, NULL))		goto error;	fuzz = PED_MAX (PED_MIN ((end - start) / 10, MEGABYTE_SECTORS),		        MEGABYTE_SECTORS * 16);

⌨️ 快捷键说明

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