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