📄 common.c
字号:
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 + -