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

📄 common.c

📁 fdisk 实现源码,可以查询Linux下系统的分区信息
💻 C
📖 第 1 页 / 共 5 页
字号:
			fs_type_name = (char *) calloc(n,sizeof(char));			strncpy(fs_type_name,(*value)->name,n);		}		if (!uiquery->getstring(prompt, &fs_type_name,		                        mkfs ? fs_type_mkfs : fs_type_list,		                        NULL, -1))			return 0;		if (!fs_type_name) {			ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,					     _("Expecting a file system type."));			return 0;		}		fs_type = ped_file_system_type_get (fs_type_name);		if (!fs_type) {			ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,					     _("Unknown file system type \"%s\"."),					     fs_type_name);			return 0;		}		free (fs_type_name);	}	else {		if (!uiquery->getfstype(prompt, &fs_type)) return 0;	}	*value = fs_type;	return 1;}intget_part_flag (const char* prompt, PedPartition *part, PedPartitionFlag *value){	StrList			*opts = NULL, *locopts = NULL;	char*			flag_name = NULL;	PedPartitionFlag	flag = 0;	while ( (flag = ped_partition_flag_next (flag)) ) {		if (ped_partition_is_flag_available (part, flag)) {			const char*	walk_name;			walk_name = ped_partition_flag_get_name (flag);			opts = str_list_append (opts, walk_name);			locopts = str_list_append (locopts, P_(walk_name));		}	}	if(*value)		flag_name = strdup(ped_partition_flag_get_name(*value));	if (!uiquery->getstring(prompt,&flag_name,opts,locopts,-1))		return 0;	if (!flag_name) {		ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,					_("Expecting a flag."));		return 0;	}	flag = ped_partition_flag_get_by_name (flag_name);	if (!flag) {		ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,					_("Unknown flag \"%s\"."),					flag_name);		return 0;	}	free (flag_name);		*value = flag;	return 1;}/* GET_SECT should have the same value as UI_CUSTOM_VALUES, as   we want to query sector when UI_CUSTOM_VALUES is specified */typedef enum {	/* Query the user for a new sector */	GET_SECT = UI_CUSTOM_VALUES, 	/* Initialise the range */	NO_RANGE = UI_CUSTOM_VALUES*2,	/* We are looking where to place the start of a new partition */	//PLACE_START_NEWPART = UI_CUSTOM_VALUES*4,	/* We are looking where to place the end of a new partition */	PLACE_END_NEWPART = UI_CUSTOM_VALUES*8} GSOpts;/* This function gets sector. The prev option specifies   the previous selected sector, used if the user    wants to specify a size, not a position */static intget_sector (const char* prompt, PedDevice* dev, SectPos *value,            PedSector prev, GSOpts opts){	char*	def_str;	char*	input = NULL;	char*	buf;	int	valid;		/* If the user should be queried about the sector and a range needs to	   be initialised, initialise one with a length of 1 sector, but please,	   when using this function, NOTE that this is not always enough */	if (!(opts & GET_SECT)) {		if (!value->range && !(opts & NO_RANGE)) {			value->range = ped_geometry_new(dev,value->sector,1);			return value->range != NULL;		}		return 1;	}	def_str = ped_unit_format (dev, value->sector);	if (def_str) 		input = strdup(def_str);	uiquery->getstring(prompt,&input,NULL,NULL,1);		/* def_str might have rounded sector a little bit.  If the user picked	 * the default, make sure the selected sector is identical to the	 * default.	 */	if (input && def_str && !strcmp (input, def_str)) {		if (!(opts & NO_RANGE)) {			if (!value->range)				value->range = ped_geometry_new (dev,value->sector,1);			ped_free (def_str);			ped_free (input);			return value->range != NULL;		}		ped_free (def_str);		ped_free(input);		return 1;	}	ped_free (def_str);	if (!input) {		value->sector = 0;		if (!(opts & NO_RANGE)) {			if (value->range)				ped_geometry_destroy(value->range);			value->range = NULL;		}		return 0;	}	/* If the string starts with +, interpret as size */	if (prev >= 0 && input[0] == '+') {		/* TODO: Improve */		SectPos pos; 		/* We parse it into a SectPos */		buf = calloc(128,sizeof(char));		valid = sscanf(input, "+%127s", buf);		free(input);		if (!valid) {			free(buf);			return 0;		}		valid = ped_unit_parse(buf, dev, &(pos.sector), &(pos.range));		free(buf);		if (!valid) {			if (pos.range) ped_geometry_destroy(pos.range);			return 0;		}		/* We move the sector, so it represents the end sector */		valid = move_sector(dev,&pos,prev-1LL);		if (valid) {			if (!(opts & NO_RANGE))				value->range = pos.range;			value->sector = pos.sector;		} else {			ped_geometry_destroy(pos.range);		}			} else {		valid = ped_unit_parse(input, dev, &(value->sector),		                                   &(value->range));		ped_free (input);	}	return valid;}/* Looks for the first suitable free space for a new partition */place_part_start(PedDisk *disk, PartPos *pos, PedPartitionType type) {	PedPartition *part = NULL;	type = (type & PED_PARTITION_LOGICAL) | PED_PARTITION_FREESPACE; 	for (part = ped_disk_next_partition(disk, NULL);	     part; part = ped_disk_next_partition(disk,part)) {		if (part->type == type) {			pos->start.sector = part->geom.start;			pos->start.range = ped_geometry_new (disk->dev,				 		part->geom.start, 8LL);			return 1;		}	}	return 0;}/* This function looks where to place the end of a new partition */static intplace_part_end(PedDisk *disk, PartPos *pos) {	PedPartition *part = ped_disk_get_partition_by_sector(disk,							pos->start.sector); 	if (part->type & PED_PARTITION_FREESPACE) {		pos->end.sector = part->geom.end;		pos->end.range = ped_geometry_new (disk->dev,				 	part->geom.end - 7LL, 8LL);		return 1;		}	else		return 0;}/* Do not confuse this with query_part_position, this queries the user for   start and end of the partition and is called from the functions in here */ static intget_position(PartPos* pos, PedDisk *disk, GSOpts opts){	char *start;	char *end;	if (ped_unit_get_default() == PED_UNIT_CYLINDER) {		start = _("First cylinder");		end = _("Last cylinder or +size or +sizeMB or +sizeKB");	}	else if (ped_unit_get_default() == PED_UNIT_SECTOR) {		start = _("First sector");		end = _("Last sector or +size or +sizeMB or +sizeKB");	}	else {		start = _("Start");		end = _("End or +size");	}        if (!get_sector (start, disk->dev, &(pos->start), -1LL, opts))                return 0;	/* If we are creating a new partition and want to look where to           place its end ... */	if (opts & PLACE_END_NEWPART)		place_part_end(disk,pos);	/* We give the sector from the first query, so that the user can           specify size */        if (!get_sector (end, disk->dev, &(pos->end), pos->start.sector, opts))                return 0;	return 1;}static intask_boolean_question(const char* prompt) {	int answer = 0;	uiquery->getbool(prompt,&answer);	return answer;}/* Check partition consistency */intperform_check (PedDisk* disk, PedPartition* part){        PedFileSystem*  fs;	if (!part) {		if (!get_partition (_("Partition"),disk, &part))			return 0;	}        if (!_partition_warn_busy (part))                return 0;        if (!ped_disk_check (disk))                return 0;        fs = ped_file_system_open (&part->geom);        if (!fs)                return 0;        if (!ped_file_system_check (fs, uiquery->timer)) {		ped_file_system_close (fs);		return 0;		}        ped_file_system_close (fs);        return 1;}/* Copy a partition.   The parameters specify the destination partition.   The source partition is get using a callback function prompt.   Writes partition table to disk *//* If warn is set to 1, warns the user TODO: get rid of warn */intperform_cp (PedDisk* dst_disk, PedPartition* dst, UIOpts opts){        PedDisk*                src_disk = NULL;        PedPartition*           src = NULL;        PedFileSystem*          src_fs;        PedFileSystem*          dst_fs;        PedFileSystemType*      dst_fs_type;		if (!dst_disk)                goto error;	if (opts & UI_WARN_COMMIT)		if (!ask_boolean_question 		(_("WARNING: This writes all data to disk automatically, continue?"))) 			return 0;	/* It doesn't hurt to commit at that point, right? */	if (uiquery->need_commit && !perform_commit(dst_disk,UI_DEFAULT)) goto error;                src_disk = dst_disk;	if (!get_disk (_("Source device"), &src_disk))		goto error_destroy_disk;                if (!get_partition (_("Source partition"),src_disk, &src))                goto error_destroy_disk;        if (src->type == PED_PARTITION_EXTENDED) {                ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,                        _("Can't copy an extended partition."));                goto error_destroy_disk;        }        if (!_partition_warn_busy (src))                goto error_destroy_disk;	if (!dst) {		if (!get_partition (_("Destination partition"),dst_disk, &dst))			goto error_destroy_disk;	}        if (!_partition_warn_busy (dst))                goto error_destroy_disk;/* do the copy */        src_fs = ped_file_system_open (&src->geom);        if (!src_fs)                goto error_destroy_disk;	/* At this point we do something worth commiting. If we fail, the caller should clean the mess */	uiquery->need_commit = 1;        dst_fs = ped_file_system_copy (src_fs, &dst->geom, uiquery->timer);        if (!dst_fs)                goto error_close_src_fs;        dst_fs_type = dst_fs->type;     /* may be different to src_fs->type */        ped_file_system_close (src_fs);        ped_file_system_close (dst_fs);/* update the partition table, close disks */        if (!ped_partition_set_system (dst, dst_fs_type))                goto error_destroy_disk;        if (!ped_disk_commit (dst_disk)) {		//if (uiquery->need_commit) uiquery->need_commit = -1;                goto error_destroy_disk;	}	uiquery->need_commit = 0;        if (src_disk != dst_disk)                ped_disk_destroy (src_disk);        /*ped_disk_destroy (dst_disk);*/        return 1;error_close_src_fs:        ped_file_system_close (src_fs);error_destroy_disk:        if (src_disk && src_disk != dst_disk)                ped_disk_destroy (src_disk);        /*ped_disk_destroy (dst_disk);*/error:        return 0;}/* Create a new partition table. Takes dev and disk as parameters,   in addition it takes a label type, if NULL, queries... */intperform_mklabel (PedDevice* dev, PedDisk** disk, const PedDiskType* type){	/*        ped_exception_fetch_all ();        if (!*disk) ped_exception_catch ();        ped_exception_leave_all ();*/        if (*disk) {                if (!_disk_warn_busy (*disk)) {                        ped_disk_destroy (*disk);                        goto error;                }                ped_disk_destroy (*disk);        }	if (!type) {        	if (!get_disk_type (_("New disk label type"), &type))                	goto error;	}        *disk = ped_disk_new_fresh (dev, type);        if (!*disk)                goto error;	        /*if (!ped_disk_commit (*disk))                goto error;*/	uiquery->need_commit = 1;        return 1;error:        return 0;}/* Create a filesystem. Takes filesystem type as an optional parameter *//* If warn is set to 1, warns the user TODO: get rid of warn */intperform_mkfs (PedDisk* disk, PedPartition* part, const PedFileSystemType* type, UIOpts opts){        PedFileSystem*          fs;	PedConstraint*		constraint = NULL;	if (opts & UI_WARN_COMMIT) {		if (!ask_boolean_question 		(_("WARNING: This writes all data to disk automatically, continue?"))) 			return 0;	}        if (!disk)                return 0;	if (!part) {		if (!get_partition (_("Partition"),disk, &part))			return 0;	}        if (!_partition_warn_busy (part))                return 0;	if (!type) {		type = ped_file_system_type_get ("ext2");        	if (!get_fs_type (_("File system"), &type, 1))	                return 0;	}	/* We check whether we can create this partition here */	constraint = ped_file_system_get_create_constraint(type,disk->dev);	//if (!constraint) return 0;	if (constraint)		if (!ped_constraint_is_solution(constraint,&(part->geom))) {			if (part->geom.length < constraint->min_size) {				ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,				_("The partition is too small to create %s filesystem on it."), type->name);				ped_constraint_destroy(constraint);				return 0;

⌨️ 快捷键说明

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