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

📄 cfdisk.c

📁 fdisk 实现源码,可以查询Linux下系统的分区信息
💻 C
📖 第 1 页 / 共 5 页
字号:
	char keys[TINYBUF];	int res,i,k = 0;	char *title;	switch (ex->type) {		case PED_EXCEPTION_INFORMATION:			title = _("Information");			break;		case PED_EXCEPTION_WARNING:			title = _("Warning!");			break;		case PED_EXCEPTION_ERROR:			title = _("Error!");			break;		case PED_EXCEPTION_FATAL:			title = _("Fatal exception!");			break;		case PED_EXCEPTION_BUG:			title = _("Bug in the program");			break;		case PED_EXCEPTION_NO_FEATURE:			title = _("Unsupported");			break;	}	for (i = 0; ex_keys[i].key; i++)		if (ex->options & ex_keys[i].option) {#if 0			/* NOTE: This is not needed now, but have in mind */			if (k >= TINYBUF) break; #endif			keys[k++] = ex_keys[i].key;		}#if 0	if (k < TINYBUF)#endif	keys[k] = '\0';	display_message(title,ex->message);	res = do_menu(ex_choices, 8, MENU_BUTTON, keys, NULL);	for (i = 0; ex_keys[i].key; i++)		if (ex_keys[i].key == res)			return ex_keys[i].option;	return PED_EXCEPTION_UNHANDLED;}typedef struct {	time_t	last_update;	time_t	predicted_time_left;} TimerContext;static TimerContext timer_context;static void_timer_handler (PedTimer* timer, void* context) {	char buf[SMALLBUF];	TimerContext*	tcontext = (TimerContext*) context;	int		draw;	if (tcontext->last_update != timer->now && timer->now > timer->start) {		tcontext->predicted_time_left = timer->predicted_end - timer->now;		tcontext->last_update = timer->now;		draw = 1;	} else {		draw = 0;	}        if (draw) {		if(timer->state_name)			snprintf(buf,SMALLBUF,_("We are now %s."), timer->state_name);		else			snprintf(buf,SMALLBUF,_("An operation is now taking place."));		set_status(buf,0);		snprintf(buf,SMALLBUF,_("Progress: %3.1f%%   Time left: %4.2d:%.2d"),		         100.0 * timer->frac,		         tcontext->predicted_time_left / 60,		         tcontext->predicted_time_left % 60); 		set_status(buf,1);		refresh();        }}static voidinit_calls() {	uiquery.getbool = getbool;	uiquery.getstring = getstring;	uiquery.getpart = getpart;	uiquery.getpartpos = getpartpos;	uiquery.getparttype = NULL;	uiquery.getdisktype = NULL;	uiquery.getint = NULL;	uiquery.getdev = NULL;	uiquery.getfstype = NULL;	uiquery.need_commit = 0;	uiquery.timer = ped_timer_new (_timer_handler, &timer_context);	ped_exception_set_handler(exception_handler);	set_uicalls(&uiquery);	init_fs_type_str ();	init_disk_type_str ();}static voidnotice_waitkey(const char *warning) {	static MenuItem waitkey[] = {		{ 'k', "", N_("Press any key to continue") },		{ 0, NULL, NULL }	};	if (warning)		waitkey[0].name = warning;	do_menu(waitkey,COLS-MENUDIV*2,MENU_ANYKEY | MENU_NOHIGHLIGHT,"k",NULL);}static voidwarning_waitkey(const char *warning) {	putchar(BELL);	notice_waitkey(warning);}/* Emergency function. If some copy, move or resize fail, reread the disk from the device   They commited it before failing, anyway. It is a bit like a hack, I might make the functions   make it themselves. I actually did, but I had a little trouble with the UI, so for now it is this way *//* FIXME: It would be better if we created a copy of the disk, or implemented queuing */static int_disk_reread(Context *c, PedPartition **part) {	int partnum;	if (*part) {		partnum = (*part)->num;	}	ped_disk_destroy(c->disk);	c->disk = ped_disk_new(c->dev);	uiquery.need_commit = 0;	if (part) {		*part = ped_disk_get_partition(c->disk,partnum);	}}/* Here we define our menu operations */static intdo_new (Context *c, PedPartition **part) {	char bsd_disklabel = 0x00;	PedPartition *temp = disk_get_prev_nmd_partition (c->disk,*part);	static MenuItem part_position[] = {		{ 's', N_("Begining"), N_("Create the partition at the begining of the free space") },		{ 'e', N_("End"), N_("Create the partition at the end of the free space") },		{ 'c', N_("Custom"), N_("Select custom start and end position of the partition") },		{ ESC, N_("Cancel"), N_("Do not create a partition") },		{ 0, NULL, NULL }	};	static MenuItem part_type[] = {		{ 'p', N_("Primary"), N_("Create primary partition") },		{ 'e', N_("Extended"), N_("Create extended partition") },		{ 'b', N_("BSD disklabel"), N_("Create a new BSD disklabel") },		{ ESC, N_("Cancel"), N_("Do not create a partition") },		{ 0, NULL, NULL }	};	static MenuItem bsd_type[] = {		{ 'f', N_("FreeBSD"), N_("Create a FreeBSD partition type") },		{ 'o', N_("OpenBSD"), N_("Create a OpenBSD partition type") },		{ 'n', N_("NetBSD"), N_("Create a NetBSD partition type") },		{ ESC, N_("Cancel"), N_("Do not create a partition") },		{ 0, NULL, NULL }	};	int i = 0;	const char bsd_keys[] = { 'f', 'o', 'n', ESC, '\0' };	char type_keys[5];	type_keys[i++] = ESC;	type_keys[i++] = 'p'; /* We can always create a regular partition */	type_keys[i++] = 'b'; /* The BSD disklabel can be counted as a regular partition */	PedPartitionType type = 0;	PartPos pos;	int key,success = 1,done;	UIOpts opts = UI_DEFAULT;	if (!((*part)->type & PED_PARTITION_FREESPACE)) {		warning_waitkey(N_("Report a bug in the function menu_new and win a cookie."));		return 0;	}	/* If the free space rests inside the extended partition, this is true, make use of it */	if((*part)->type & PED_PARTITION_LOGICAL) 		type = PED_PARTITION_LOGICAL;	else {		if(!can_create_primary(c->disk)) {			warning_waitkey(N_("Cannot create more primary partitions"));			return 0;		}		else if (can_create_extended(c->disk)) {			type_keys[i++] = 'e';		}		type_keys[i] = '\0';			menu_title(_("Type of partition you want to create"));			key = do_menu(part_type, 8, MENU_BUTTON | MENU_TITLE, type_keys, NULL);			if (key == ESC)	return 1;			else if (key == 'p') type = PED_PARTITION_NORMAL;			else if (key == 'e') type = PED_PARTITION_EXTENDED;		else if (key == 'b') {			type = PED_PARTITION_NORMAL;			key = do_menu(bsd_type, 8, MENU_BUTTON | MENU_TITLE, bsd_keys, NULL);			if (key == ESC) return 1;			else if (key == 'f') bsd_disklabel = 0xa5;			else if (key == 'o') bsd_disklabel = 0xa6;			else if (key == 'n') bsd_disklabel = 0xa9;		}	}	pos.start.sector = (*part)->geom.start;	pos.end.sector = (*part)->geom.end;	if(!query_part_position(_("Where do you want to put the partition"),	                        part_position,&pos,pos.start.sector,	                        pos.end.sector,c->dev,NULL,&opts))		return 0;	PedFileSystemType *fs_type = ped_file_system_type_get("ext2");	if (!perform_mkpart(c->disk,&pos,type,bsd_disklabel ? fs_type : NULL,part,opts)) {		if (!*part) {			do {				temp = ped_disk_next_partition(c->disk,temp);			} while (temp && temp->type & PED_PARTITION_METADATA);			*part = temp;		}		warning_waitkey(N_("Can't create partition."));		return 0;	}	if (bsd_disklabel) {		(*part)->fs_type = NULL;		set_disk_specific_system_type(*part, bsd_disklabel);	}	return 1;	}do_edit (Context *c, PedPartition **part) {	char devname[SMALLBUF];	PedDevice *dev;	if (uiquery.need_commit) {	        ped_exception_throw (				     PED_EXCEPTION_ERROR,				     PED_EXCEPTION_CANCEL,				     _("Editing a BSD label, before writing the msdos "			               "partition table is not supported in GNU fdisk."));		return 0;	}	if (!ped_device_begin_external_access(c->disk->dev))		return 0;	/* Warn if there is a filesystem on the partition */	if (ped_file_system_probe(&((*part)->geom))) {		if (ped_exception_throw(PED_EXCEPTION_WARNING,					PED_EXCEPTION_YES_NO,		     _("This partition seems to contain a filesystem. "		       "This is going to destroy it. "		       "Are you sure you want to continue?")) 			== PED_EXCEPTION_NO) {			ped_device_end_external_access(c->disk->dev);			return 0;		}	}	/* If there is no already created BSD label created,	   we warn the user about it */	else if (!is_bsd_partition(c->disk->dev->path, 		(*part)->geom.start * c->disk->dev->sector_size, 		c->disk->dev->sector_size)) {		if (ped_exception_throw(PED_EXCEPTION_WARNING,					PED_EXCEPTION_YES_NO,		     _("There is no BSD label on this partition. "		       "Do you want to create one?")) 			== PED_EXCEPTION_NO) {			ped_device_end_external_access(c->disk->dev);			return 0;		}	}	get_partition_device(devname, SMALLBUF, *part, 0);	Context * bsd_context = init_disk(0, devname, NULL, ped_disk_type_get ("bsd"));	show_info(bsd_context);	do_plist(bsd_context,NULL,0,0);	/* We reset this back to its default state */	uiquery.need_commit = 0;	ped_device_end_external_access(c->disk->dev);}static intdo_resize (Context *c, PedPartition **part) {	static MenuItem part_position[] = {		{ 's', N_("Fixed start"), N_("Don't move the beginning of the partition") },		/* FIXME: Wording. */		{ 'b', N_("Begining"), N_("Place it as back as possible on partitions that support it") },		{ 'e', N_("End"), N_("Place it as forward as possible on partitions that support it") },		{ 'c', N_("Custom"), N_("Select custom start and end position of the partition") },		{ ESC, N_("Cancel"), N_("Do not resize the partition") },		{ 0, NULL, NULL }	};	static MenuItem resize_menu[] = {		{ 'r', N_("Resize"), N_("Resize the filesystem") },		{ 'c', N_("Change size"), N_("Change the size of the partition (if you know what you are doing)") },		{ ESC, N_("Cancel"), N_("Do not resize the partition") },		{ 0, NULL, NULL }	};	const char resize_keys[] = { 'r', 'c', ESC, '\0' };	int key;	PedConstraint *constraint = NULL;	PedFileSystem *fs = NULL;	PedSector first,last;	PartPos pos;	UIOpts opts = UI_WARN_COMMIT;	if (!((*part)->type & PED_PARTITION_EXTENDED)) {		if ((*part)->fs_type && (*part)->fs_type->ops->resize) {			menu_title(_("What do you want to do?"));			key = do_menu(resize_menu, 11, MENU_BUTTON | MENU_TITLE,resize_keys, NULL);		}		else {			key = 0;			getbool(_("Can't resize the partition. Alter the size? (For experts only)"),&key);			key = (key ? 'c' : ESC);		}		if (key == ESC)			return 0;		if (key == 'r') {			fs = ped_file_system_open(&(*part)->geom);			if (!fs) {				warning_waitkey(_("Could not open the filesystem for resizing"));				return 0;			}			constraint = ped_file_system_get_resize_constraint(fs);			if (!constraint || constraint->min_size == constraint->max_size) {				warning_waitkey(_("We can't resize this filesystem type"));				ped_file_system_close (fs);				if (constraint) ped_constraint_destroy(constraint);				return 0;			}			ped_file_system_close (fs);		} else {			opts |= UI_NO_FS_RESIZE;		}	}	char buf[SMALLBUF];	pos.start.sector = (*part)->geom.start;	pos.end.sector = (*part)->geom.end;	PedPartition *temp;	/* We want to look for free space fo the same type */	PedPartitionType 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(_("Where to place the resized partition"),	                        part_position,&pos,first,last,c->dev,	                        constraint,&opts)) {		if (constraint) ped_constraint_destroy (constraint);		return 0;	}	if (constraint) ped_constraint_destroy (constraint);		if (opts & UI_CUSTOM_VALUES || pos.start.sector != (*part)->geom.start 			|| pos.end.sector != (*part)->geom.end)		if (!perform_resize(c->disk,*part,&pos,opts)) {			warning_waitkey(N_("Couldn't resize partition."));			/* Ooopsy */			if (!(opts & UI_NO_FS_RESIZE) && uiquery.need_commit)				_disk_reread(c, part);			return 0;		}	return 1;}static intdo_move (Context *c, PedPartition **part) {	/* Combine this with new partition? */	static MenuItem part_position[] = {		{ 's', N_("Begining"), N_("Move the partition to the begining of the free space") },		{ 'e', N_("End"), N_("Move the partition to the end of the free space") },		{ 'c', N_("Custom"), N_("Select custom start and end position of the partition") },		{ ESC, N_("Cancel"), N_("Do not move the partition") },		{ 0, NULL, NULL }	};	PedPartition *dst = NULL;	PedSector start,end,length;	PartPos pos;	PedConstraint *constraint = NULL;	PedFileSystem *fs = NULL;	UIOpts opts = UI_WARN_COMMIT;	fs = ped_file_system_open(&(*part)->geom);	if (!fs) {		warning_waitkey(N_("Can't open the filesystem"));		return 0;	}	constraint = ped_file_system_get_copy_constraint(fs,c->dev);	if (!constraint) {		warning_waitkey(N_("We can't move this partition"));		return 0;	}	ped_file_system_close (fs);	menu_title(_("Select free space to move the partition to"));	if (!do_plist(c, &dst, PED_PARTITION_FREESPACE, 0)) {		ped_constraint_destroy (constraint);		return 0;	}	if (!dst) {		ped_constraint_destroy (constraint);		return 0; 	}	start = dst->geom.start;	end = dst->geom.end;	length = dst->geom.length;		if (length < constraint->min_size) {		ped_constraint_destroy (constraint);		warning_waitkey(N_("You can't move this partition here"));		return 0;	}	length = MIN(length,(*part)->geom.length);	length = MAX(length,constraint->min_size);	end = start+length-1;	pos.start.sector = start;	pos.end.sector = end;	if(!query_part_position(_("Where do you want to move the partition"),	                        part_position,&pos,start,dst->geom.end,	                        c->dev,constraint,&opts)) {		ped_constraint_destroy (constraint);		return 0;	}	ped_constraint_destroy (constraint);	if (!perform_move(c->disk,*part,&pos,opts)) {		warning_waitkey(N_("Partition move failed"));		/* Oooops */		if (uiquery.need_commit) _disk_reread(c, part);		return 0;	}	return 1;}static intdo_mkfs (Context *c, PedPartition **part) {	char buf[SMALLBUF];	const PedFileSystemType *type = NULL;	int go;	if ((*part)->fs_type) {		/* If we have an fs_type, we hope we can create it */		if ((*part)->fs_type->ops->create != NULL) {			go = 1;			snprintf(buf,SMALLBUF,_("The partition has %s set as a filesystem. Use it?"),			         (*part)->fs_type->name);			getbool(buf,&go);			if (go) type = (*part)->fs_type;		}		else {			snprintf(buf,SMALLBUF, N_("Can't create filesystem %s, you'll have to choose another"), (*part)->fs_type->name);			warning_waitkey(buf);		}	}	if (!perform_mkfs (c->disk, *part, type, UI_WARN_COMMIT)) {		warning_waitkey(N_("The filesystem was not created successfully"));		return 0;	}	notice_waitkey(N_("The filesystem was created successfully."));	return 1;}

⌨️ 快捷键说明

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