fdisk.c

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

C
2,469
字号
	ped_geometry_init (&probe_start_region, (*disk)->dev,			   PED_MAX(start - fuzz, 0),			   PED_MIN(2 * fuzz, ((*disk)->dev)->length - (start - fuzz)));	ped_geometry_init (&probe_end_region, (*disk)->dev,			   PED_MAX(end - fuzz, 0),			   PED_MIN(2 * fuzz, (*disk)->dev->length - (end - fuzz)));	if (!_rescue_pass (*disk, &probe_start_region, &probe_end_region))		goto error;	return 1;error:	return 0;#endif}static intdo_resize (PedDisk** disk){	Option query_opts[] = {		{ 's', _("don't move the beginning of the partition") },		{ 'b', _("place it at the beginning of the free space before it") },		{ 'e', _("place it at the end") },		{ 'c', _("select custom start and end") },		{ '\0', NULL }			};	PartPos pos;	PedPartition *part = NULL, *temp;	PedSector first,last;	PedConstraint *constraint = NULL;	PedPartitionType desired;	UIOpts ui_opts = UI_WARN_COMMIT;	if (!get_partition (_("Partition"), *disk, &part))                	return 0;	/* TODO: Almost shared between fdisk and cfdisk, move to common */	if (part->fs_type) {		if (!part->fs_type->ops->resize) {			ped_exception_throw(PED_EXCEPTION_ERROR,			                    PED_EXCEPTION_CANCEL,			                    _("You can't resize this filesystem type."));			return 0;		}		else {			PedFileSystem *fs = ped_file_system_open(&part->geom);			constraint = ped_file_system_get_resize_constraint(fs);			if (!constraint || constraint->min_size == constraint->max_size)			{				ped_exception_throw(PED_EXCEPTION_ERROR,				                    PED_EXCEPTION_CANCEL,				       _("We can't resize this filesystem type"));				if (constraint) ped_constraint_destroy(constraint);				if (fs) ped_file_system_close (fs);				return 0;			}			if (fs) ped_file_system_close (fs);		}	}	else if (part->type != PED_PARTITION_EXTENDED) {		ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,		                    _("No filesystem detected on the partition."));		return 0; 	}	pos.start.sector = part->geom.start;	pos.end.sector = part->geom.end;	desired = PED_PARTITION_FREESPACE |	                           (part->type & PED_PARTITION_LOGICAL);		temp = part_list_prev(part,PED_PARTITION_METADATA);	if (temp && (temp->type & desired))		first = temp->geom.start;	else		first = part->geom.start;	temp = part_list_next(part,PED_PARTITION_METADATA);		if (temp && (temp->type & desired))		last = temp->geom.end;	else 		last = part->geom.end;	if(!query_part_position(_("Place for the resized partition"),	                        query_opts,&pos,first,last,(*disk)->dev,	                        constraint,&ui_opts)) {		if (constraint) ped_constraint_destroy (constraint);		return 0;	}	if (!perform_resize (*disk, part, &pos, ui_opts)) {		ped_exception_throw(PED_EXCEPTION_ERROR,		                    PED_EXCEPTION_CANCEL,		         _("Resize of the partition failed"));		if (!(ui_opts & UI_NO_FS_RESIZE) && uiquery.need_commit)				_disk_reread(disk);		return 0;	}	return 1;#if 0	PedPartition		*part = NULL;	PedFileSystem		*fs;	PedConstraint		*constraint;	PedSector		start, end;	PedGeometry             *range_start = NULL, *range_end = NULL;	PedGeometry		new_geom;	if (!*disk)		goto error;	if (!command_line_prompt_boolean_question 	(_("WARNING: resize writes all data to disk automatically, continue")))	        return 1;	if (!fdisk_command_line_get_partition (_("Partition number?"), *disk, &part))		goto error;	if (part->type != PED_PARTITION_EXTENDED) {		if (!_partition_warn_busy (part))			goto error;	}	start = part->geom.start;	end = part->geom.end;	if (!fdisk_command_line_get_sector (_("Start?"), (*disk)->dev, &start, &range_start))		goto error;	if (!fdisk_command_line_get_sector (_("End?"), (*disk)->dev, &end, &range_end))		goto error;	if (!ped_geometry_init (&new_geom, (*disk)->dev, start, end - start + 1))		goto error;	snap_to_boundaries (&new_geom, &part->geom, *disk,			    range_start, range_end);	if (part->type == PED_PARTITION_EXTENDED) {		constraint = constraint_from_start_end ((*disk)->dev,				range_start, range_end);		if (!ped_disk_set_partition_geom (*disk, part, constraint,						  new_geom.start, new_geom.end))			goto error_destroy_constraint;		ped_partition_set_system (part, NULL);	} else {		fs = ped_file_system_open (&part->geom);		if (!fs)			goto error;		constraint = constraint_intersect_and_destroy (				ped_file_system_get_resize_constraint (fs),				constraint_from_start_end (					(*disk)->dev, range_start, range_end));		if (!ped_disk_set_partition_geom (*disk, part, constraint,						  new_geom.start, new_geom.end))			goto error_close_fs;		if (!ped_file_system_resize (fs, &part->geom, timer))			goto error_close_fs;		/* may have changed... eg fat16 -> fat32 */		ped_partition_set_system (part, fs->type);		ped_file_system_close (fs);	}	ped_constraint_destroy (constraint);	if (range_start != NULL)		ped_geometry_destroy (range_start);	if (range_end != NULL)		ped_geometry_destroy (range_end);	return 1;error_close_fs:	ped_file_system_close (fs);error_destroy_constraint:	ped_constraint_destroy (constraint);error:	if (range_start != NULL)		ped_geometry_destroy (range_start);	if (range_end != NULL)		ped_geometry_destroy (range_end);	return 0;#endif}static intdo_rm (PedDisk** disk){	return perform_rm (*disk, NULL);}static intdo_select (PedDisk** disk){	PedDevice*      dev;	if (!get_device (_("New device?"), &dev))		return 0;	if (!ped_device_open (dev))		return 0;	if (uiquery.need_commit) 	        if (!command_line_prompt_boolean_question 		(_("WARNING: changes were made to the disk, "		   "are you sure you want to discard them")))	                return 1;	/* Destroy the current disk and open the new.*/	ped_disk_destroy (*disk);	if (!(*disk = ped_disk_new (dev)))	        return 0;		/* Tell the user we are using the new device. */	fdisk_print_using_dev (dev);	if (uiquery.need_commit) uiquery.need_commit = 0;	return 1;}static intdo_set (PedDisk** disk){	return perform_set (*disk, NULL, 0, UI_DEFAULT);}static intdo_toggle_boot_flag (PedDisk** disk){			return perform_set (*disk, NULL, PED_PARTITION_BOOT, UI_FLAG_TOGGLE);}static intdo_unit (PedDisk** disk){	if (cylinder_unit) {		printf ("%s\n", _("Changing display/entry units to sectors"));		ped_unit_set_default(PED_UNIT_SECTOR);		cylinder_unit = 0;		return 1;	} else {		printf ("%s\n", _("Changing display/entry units to cylinders"));		ped_unit_set_default(PED_UNIT_CYLINDER);		cylinder_unit = 1;		return 1;	}}/* * do_commit: write all configuration changes to disk. */static int do_commit (PedDisk **disk){  	/* TODO: Move these to common! */	if ((*disk)->dev->boot_dirty && (*disk)->dev->type != PED_DEVICE_FILE) {	        ped_exception_throw (				     PED_EXCEPTION_WARNING,				     PED_EXCEPTION_OK,				     _("You should reinstall your boot loader before "				       "rebooting.  Read section 4 of the Parted User "				       "documentation for more information."));	}	/* TODO: dev->type is deprecated, use is_blockdevice instead */	if ((*disk)->dev->type != PED_DEVICE_FILE && !fdisk_opt_script_mode) {	        ped_exception_throw (				     PED_EXCEPTION_INFORMATION, PED_EXCEPTION_OK,				     _("Don't forget to update /etc/fstab, if "				       "necessary.\n"));	}	printf (_("\nWriting all changes to %s.\n"), _((*disk)->dev->path));	if (!ped_disk_commit (*disk))	        goto error;	/* FIXME: This is not needed */	if (!ped_disk_commit_to_os (*disk))                goto error;	/* After writing changes exit. */  	if (!in_menu)		do_quit (disk);        return 1;        error:	return 0;}static intdo_copy(PedDisk** disk){	if (!perform_cp (*disk, NULL, UI_WARN_COMMIT)) {		ped_exception_throw(PED_EXCEPTION_ERROR,		                    PED_EXCEPTION_CANCEL,		         _("Partition copy failed"));		if (uiquery.need_commit)				_disk_reread(disk);		return 0;	}	return 1;}static intdo_ex_menu (PedDisk** disk) {	int status,old_menu;        old_menu = in_menu;	in_menu = 1;	status = fdisk_interactive_menu (disk, 		fdisk_ex_menu_commands, 0);	in_menu = old_menu;	return status;}static intdo_list_systypes (PedDisk** disk){	SysType* types = get_disklabel_system_types((*disk)->type);	if (!types) {		printf(_("System types for this disk label type are not "		         "available.\n"));		return 1;	}	int count, per_row = 4, per_col, i, j = 0;	/* We calculate the system types count */	for (count = 0; types[count].name; count++);	/* We calculate the number of columns for the currect screen size */	per_row = fdisk_screen_width()/20;	/* We calculate the maximum number of elements per column */	per_col = count/per_row + 1;	/* We arrange the types in columns */	for (i = 0; i <  per_col; i++) {		for (j = 0; j < per_row; j++) {			if (i+j*per_col >= count)				break;			printf("%2x  %-15.15s ",				(unsigned int) types[i+j*per_col].type,				_(types[i+j*per_col].name));		}		printf("\n");	}	return 1;}/* This changes the filesystem type. For now, only on msdos partition type */static intdo_change_system_type (PedDisk **disk){	int type = 0, i;	PedPartition *part = NULL;	char *input = NULL;	const char *type_name = NULL;	SysType *types = get_disklabel_system_types((*disk)->type);	if (!types) {		if (!command_line_prompt_boolean_question 			(_("WARNING: System types for this disk label type "			    "seem unavailable, continue?"))) 			return 0;	}	const char prompt[] = "Hex code (type L to list codes)";	if(!get_partition(_("Partition"), *disk, &part) || !part)		return 0;	do {		input = fdisk_command_line_get_word (prompt, NULL, NULL, 1);		if (!input)			return 0;		if (!strcmp(input,"L")) {			free(input);			do_list_systypes(disk);		}		else			break;	} while(1);	if (!sscanf(input,"%x",&type)) {		free(input);		return 0;	}	set_disk_specific_system_type(part,type);	if (types)		for (i = 0; types[i].name; i++) {			if (types[i].type == type)				type_name = _(types[i].name);		}	if (!type_name)		type_name = _("Unknown");		printf(_("Changed type of partition %d to %x (%s)\n"),		part->num, type, type_name);	return 1;}static intdo_fix_partition_order (PedDisk **disk){	fix_partition_order(*disk);}/* The next three are for lfdisk compatibility with fdisk */static intdo_change_sectors(PedDisk **disk){	int sectors = (*disk)->dev->bios_geom.sectors;	if (fdisk_command_line_get_integer(_("Number of sectors"), &sectors)) {		(*disk)->dev->bios_geom.sectors = sectors;		return 1;	}	else		return 0;}static intdo_change_heads(PedDisk **disk){	int heads = (*disk)->dev->bios_geom.heads;	if (fdisk_command_line_get_integer(_("Number of heads"), &heads)) {		(*disk)->dev->bios_geom.heads = heads;		return 1;	}	else		return 0;}static intdo_change_cylinders(PedDisk **disk){	int cylinders = (*disk)->dev->bios_geom.cylinders;	if (fdisk_command_line_get_integer(_("Number of cylinders"), &cylinders)) {		(*disk)->dev->bios_geom.cylinders = cylinders;		return 1;	}	else		return 0;}static intdo_move_partition_beginning(PedDisk **disk){	PedPartition *part = NULL;	PartPos pos;	if (!get_partition(_("Partition"), *disk, &part))		return 0;	pos.start.sector = part->geom.start;	pos.end.sector = part->geom.end;	pos.start.range = NULL;	pos.end.range = NULL;		/* This gets the new start in sectors */	while (1) {		if (!fdisk_command_line_get_llinteger(_("New beginning of data"),						 &pos.start.sector))			return 0;		if (pos.start.sector < part->geom.start || 				pos.start.sector >= part->geom.end) 			printf(_("Value out of range."));		else			break;	}	return perform_resize(*disk,part,&pos,UI_NO_FS_RESIZE);}static intdo_verify(PedDisk **disk){	verify_partition_table (*disk);	return 1;}static void_init_messages (){	StrList*		list;	int			first;	PedFileSystemType*	fs_type;	PedDiskType*		disk_type;	PedPartitionFlag	part_flag;	PedUnit			unit;/* flags */	first = 1;	list = str_list_create (_(flag_msg_start), NULL);	for (part_flag = ped_partition_flag_next (0); part_flag;	     		part_flag = ped_partition_flag_next (part_flag)) {

⌨️ 快捷键说明

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