📄 cfdisk.c
字号:
#ifdef HAVE_rpmatch char reply[2]; int yn; reply[0] = answer; reply[1] = 0; yn = rpmatch(reply); /* 1: yes, 0: no, -1: ? */ if (yn >= 0) return yn;#endif return (answer == 'y' || answer == 'Y');}static voidget_partition_table_geometry(partition_table *bufp) { struct partition *p; int i,h,s,hh,ss; int first = TRUE; int bad = FALSE; for (i=0; i<66; i++) if (bufp->c.b[446+i]) goto nonz; /* zero table */ if (!curses_started) { fatal(_("No partition table.\n"), 3); return; } else { mvaddstr(WARNING_START, 0, _("No partition table. Starting with zero table.")); putchar(BELL); refresh(); zero_table = TRUE; return; } nonz: if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 || bufp->p.magicflag[1] != PART_TABLE_FLAG1) { if (!curses_started) fatal(_("Bad signature on partition table"), 3); /* Matthew Wilcox */ mvaddstr(WARNING_START, 0, _("Unknown partition table type")); mvaddstr(WARNING_START+1, 0, _("Do you wish to start with a zero table [y/N] ?")); putchar(BELL); refresh(); { int cont = getch(); if (cont == EOF || !said_yes(cont)) die_x(3); } zero_table = TRUE; return; } hh = ss = 0; for (i=0; i<4; i++) { p = &(bufp->p.part[i]); if (p->sys_ind != 0) { h = p->end_head + 1; s = (p->end_sector & 077); if (first) { hh = h; ss = s; first = FALSE; } else if (hh != h || ss != s) bad = TRUE; } } if (!first && !bad) { pt_heads = hh; pt_sectors = ss; }}static voiddecide_on_geometry(void) { heads = (user_heads ? user_heads : pt_heads ? pt_heads : kern_heads ? kern_heads : 255); sectors = (user_sectors ? user_sectors : pt_sectors ? pt_sectors : kern_sectors ? kern_sectors : 63); cylinder_size = heads*sectors; cylinders = actual_size/cylinder_size; if (user_cylinders > 0) cylinders = user_cylinders; total_size = cylinder_size*cylinders; if (total_size > actual_size) print_warning(_("You specified more cylinders than fit on disk"));}static voidclear_p_info(void) { num_parts = 1; p_info[0].first_sector = 0; p_info[0].last_sector = total_size - 1; p_info[0].offset = 0; p_info[0].flags = 0; p_info[0].id = FREE_SPACE; p_info[0].num = PRI_OR_LOG; ext_info.first_sector = 0; ext_info.last_sector = 0; ext_info.offset = 0; ext_info.flags = 0; ext_info.id = FREE_SPACE; ext_info.num = PRIMARY;}static voidfill_p_info(void) { int pn, i; long long bs, bsz; unsigned long long llsectors; struct partition *p; partition_table buffer; partition_info tmp_ext = { 0, 0, 0, 0, FREE_SPACE, PRIMARY }; if ((fd = open(disk_device, O_RDWR)) < 0) { if ((fd = open(disk_device, O_RDONLY)) < 0) fatal(_("Cannot open disk drive"), 2); opentype = O_RDONLY; print_warning(_("Opened disk read-only - you have no permission to write")); if (curses_started) { refresh(); getch(); clear_warning(); } } else opentype = O_RDWR; opened = TRUE; /* Blocks are visible in more than one way: e.g. as block on /dev/hda and as block on /dev/hda3 By a bug in the Linux buffer cache, we will see the old contents of /dev/hda when the change was made to /dev/hda3. In order to avoid this, discard all blocks on /dev/hda. Note that partition table blocks do not live in /dev/hdaN, so this only plays a role if we want to show volume labels. */ ioctl(fd, BLKFLSBUF); /* ignore errors */ /* e.g. Permission Denied */ if (disksize(fd, &llsectors)) fatal(_("Cannot get disk size"), 3); actual_size = llsectors; read_sector(buffer.c.b, 0); get_kernel_geometry(); if (!zero_table || use_partition_table_geometry) get_partition_table_geometry(& buffer); decide_on_geometry(); clear_p_info(); if (!zero_table) { char *errmsg = ""; for (i = 0; i < 4; i++) { p = & buffer.p.part[i]; bs = get_start_sect(p); bsz = get_nr_sects(p); if (p->sys_ind > 0 && add_part(i, p->sys_ind, p->boot_ind, ((bs <= sectors) ? 0 : bs), bs + bsz - 1, ((bs <= sectors) ? bs : 0), 1, &errmsg)) { char *bad = _("Bad primary partition"); char *msg = (char *) xmalloc(strlen(bad) + strlen(errmsg) + 30); sprintf(msg, "%s %d: %s", bad, i, errmsg); fatal(msg, 4); } if (is_extended(buffer.p.part[i].sys_ind)) tmp_ext = ext_info; } if (is_extended(tmp_ext.id)) { ext_info = tmp_ext; logical_sectors[logical] = ext_info.first_sector + ext_info.offset; read_sector(buffer.c.b, logical_sectors[logical++]); i = 4; do { for (pn = 0; pn < 4 && (!buffer.p.part[pn].sys_ind || is_extended(buffer.p.part[pn].sys_ind)); pn++); if (pn < 4) { p = & buffer.p.part[pn]; bs = get_start_sect(p); bsz = get_nr_sects(p); if (add_part(i++, p->sys_ind, p->boot_ind, logical_sectors[logical-1], logical_sectors[logical-1] + bs + bsz - 1, bs, 1, &errmsg)) { char *bad = _("Bad logical partition"); char *msg = (char *) xmalloc(strlen(bad) + strlen(errmsg) + 30); sprintf(msg, "%s %d: %s", bad, i, errmsg); fatal(msg, 4); } } for (pn = 0; pn < 4 && !is_extended(buffer.p.part[pn].sys_ind); pn++); if (pn < 4) { p = & buffer.p.part[pn]; bs = get_start_sect(p); logical_sectors[logical] = ext_info.first_sector + ext_info.offset + bs; read_sector(buffer.c.b, logical_sectors[logical++]); } } while (pn < 4 && logical < MAXIMUM_PARTS-4); } }}static voidfill_part_table(struct partition *p, partition_info *pi) { long long begin; p->boot_ind = pi->flags; p->sys_ind = pi->id; begin = pi->first_sector + pi->offset; if (IS_LOGICAL(pi->num)) set_start_sect(p,pi->offset); else set_start_sect(p,begin); set_nr_sects(p, pi->last_sector - begin + 1); set_hsc_begin(p, begin); set_hsc_end(p, pi->last_sector);}static voidfill_primary_table(partition_table *buffer) { int i; /* Zero out existing table */ for (i = 0x1BE; i < SECTOR_SIZE; i++) buffer->c.b[i] = 0; for (i = 0; i < num_parts; i++) if (IS_PRIMARY(p_info[i].num)) fill_part_table(&(buffer->p.part[p_info[i].num]), &(p_info[i])); if (is_extended(ext_info.id)) fill_part_table(&(buffer->p.part[ext_info.num]), &ext_info); buffer->p.magicflag[0] = PART_TABLE_FLAG0; buffer->p.magicflag[1] = PART_TABLE_FLAG1;}static voidfill_logical_table(partition_table *buffer, partition_info *pi) { struct partition *p; int i; for (i = 0; i < logical && pi->first_sector != logical_sectors[i]; i++); if (i == logical || buffer->p.magicflag[0] != PART_TABLE_FLAG0 || buffer->p.magicflag[1] != PART_TABLE_FLAG1) for (i = 0; i < SECTOR_SIZE; i++) buffer->c.b[i] = 0; /* Zero out existing table */ for (i = 0x1BE; i < SECTOR_SIZE; i++) buffer->c.b[i] = 0; fill_part_table(&(buffer->p.part[0]), pi); for (i = 0; i < num_parts && pi->num != p_info[i].num - 1; i++); if (i < num_parts) { p = &(buffer->p.part[1]); pi = &(p_info[i]); p->boot_ind = 0; p->sys_ind = DOS_EXTENDED; set_start_sect(p, pi->first_sector - ext_info.first_sector - ext_info.offset); set_nr_sects(p, pi->last_sector - pi->first_sector + 1); set_hsc_begin(p, pi->first_sector); set_hsc_end(p, pi->last_sector); } buffer->p.magicflag[0] = PART_TABLE_FLAG0; buffer->p.magicflag[1] = PART_TABLE_FLAG1;}static voidwrite_part_table(void) { int i, ct, done = FALSE, len; partition_table buffer; struct stat s; int is_bdev; char response[LINE_LENGTH]; if (opentype == O_RDONLY) { print_warning(_("Opened disk read-only - you have no permission to write")); refresh(); getch(); clear_warning(); return; } is_bdev = 0; if(fstat(fd, &s) == 0 && S_ISBLK(s.st_mode)) is_bdev = 1; if (is_bdev) { print_warning(_("Warning!! This may destroy data on your disk!")); while (!done) { mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, _("Are you sure you want write the partition table " "to disk? (yes or no): ")); len = get_string(response, LINE_LENGTH, NULL); clear_warning(); if (len == GS_ESCAPE) return; else if (strcasecmp(response, _("no")) == 0) { print_warning(_("Did not write partition table to disk")); return; } else if (strcasecmp(response, _("yes")) == 0) done = TRUE; else print_warning(_("Please enter `yes' or `no'")); } clear_warning(); print_warning(_("Writing partition table to disk...")); refresh(); } read_sector(buffer.c.b, 0); fill_primary_table(&buffer); write_sector(buffer.c.b, 0); for (i = 0; i < num_parts; i++) if (IS_LOGICAL(p_info[i].num)) { read_sector(buffer.c.b, p_info[i].first_sector); fill_logical_table(&buffer, &(p_info[i])); write_sector(buffer.c.b, p_info[i].first_sector); } if (is_bdev) { sync(); sleep(2); if (!ioctl(fd,BLKRRPART)) changed = TRUE; sync(); sleep(4); clear_warning(); if (changed) print_warning(_("Wrote partition table to disk")); else print_warning(_("Wrote partition table, but re-read table failed. Reboot to update table.")); } else print_warning(_("Wrote partition table to disk")); /* Check: unique bootable primary partition? */ ct = 0; for (i = 0; i < num_parts; i++) if (IS_PRIMARY(i) && p_info[i].flags == ACTIVE_FLAG) ct++; if (ct == 0) print_warning(_("No primary partitions are marked bootable. DOS MBR cannot boot this.")); if (ct > 1) print_warning(_("More than one primary partition is marked bootable. DOS MBR cannot boot this."));}static voidfp_printf(FILE *fp, char *format, ...) { va_list args; char buf[1024]; int y, x; va_start(args, format); vsnprintf(buf, sizeof(buf), format, args); va_end(args); if (fp == NULL) { /* The following works best if the string to be printed has at most only one newline. */ printw("%s", buf); getyx(stdscr, y, x); if (y >= COMMAND_LINE_Y-2) { menuContinue(); erase(); move(0, 0); } } else fprintf(fp, "%s", buf);}#define MAX_PER_LINE 16static voidprint_file_buffer(FILE *fp, char *buffer) { int i,l; for (i = 0, l = 0; i < SECTOR_SIZE; i++, l++) { if (l == 0) fp_printf(fp, "0x%03X:", i); fp_printf(fp, " %02X", (unsigned char) buffer[i]); if (l == MAX_PER_LINE - 1) { fp_printf(fp, "\n"); l = -1; } } if (l > 0) fp_printf(fp, "\n"); fp_printf(fp, "\n");}static voidprint_raw_table(void) { int i, to_file; partition_table buffer; char fname[LINE_LENGTH]; FILE *fp; if (print_only) { fp = stdout; to_file = TRUE; } else { mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, _("Enter filename or press RETURN to display on screen: ")); if ((to_file = get_string(fname, LINE_LENGTH, NULL)) < 0) return; if (to_file) { if ((fp = fopen(fname, "w")) == NULL) { char errstr[LINE_LENGTH]; snprintf(errstr, sizeof(errstr), _("Cannot open file '%s'"), fname); print_warning(errstr); return; } } else { fp = NULL; erase(); move(0, 0); } } fp_printf(fp, _("Disk Drive: %s\n"), disk_device); fp_printf(fp, _("Sector 0:\n")); read_sector(buffer.c.b, 0); fill_primary_table(&buffer); print_file_buffer(fp, buffer.c.b); for (i = 0; i < num_parts; i++) if (IS_LOGICAL(p_info[i].num)) { fp_printf(fp, _("Sector %d:\n"), p_info[i].first_sector); read_sector(buffer.c.b, p_info[i].first_sector); fill_logical_table(&buffer, &(p_info[i])); print_file_buffer(fp, buffer.c.b); } if (to_file) { if (!print_only) fclose(fp); } else { menuContinue(); }}static voidprint_p_info_entry(FILE *fp, partition_info *p) { long long size; char part_str[40]; if (p->id == UNUSABLE) fp_printf(fp, _(" None ")); else if (p->id == FREE_SPACE && p->num == PRI_OR_LOG) fp_printf(fp, _(" Pri/Log")); else if (p->id == FREE_SPACE && p->num == PRIMARY) fp_printf(fp, _(" Primary")); else if (p->id == FREE_SPACE && p->num == LOGICAL) fp_printf(fp, _(" Logical"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -