fdisk.c
来自「fdisk 实现源码,可以查询Linux下系统的分区信息」· C语言 代码 · 共 2,469 行 · 第 1/5 页
C
2,469 行
"Units = cylinders of %lld * %d = %s bytes\n"), heads, sectors, cylinders, (heads * sectors), sect_size, cyl_size); printf ("\n"); has_extended = ped_disk_type_check_feature ((*disk)->type, PED_DISK_TYPE_EXTENDED); unsigned int i; unsigned int pathlen; /* TODO: Make this output the same output as util-linux fdisk(?), possibly split into seperate functions */ if (fdisk_compatibility_mode && !strcmp((*disk)->type->name,"bsd")) { printf ("%s %+10s %+11s %+11s %+4s %+7s ", _("# "), _("start"), _("end"), _("blocks"), _("id"), _("system")); printf ("\n"); } else { pathlen = strlen ((*disk)->dev->path); unsigned int fix = 3 - !isdigit((*disk)->dev->path[pathlen-1]); pathlen += fix; for (i = 0; i < (pathlen - 5 - fix); i++) printf (" "); printf ("%s %s %+10s %+11s %+11s %+4s %+7s ", _("Device"), _("Boot"), _("Start"), _("End"), _("Blocks"), _("Id"), _("System")); printf ("\n"); } PedSector total_cyl = heads * sectors; for (part = ped_disk_next_partition (*disk, NULL); part; part = ped_disk_next_partition (*disk, part)) { cyl_start = (part->geom.start / (total_cyl)) + 1; cyl_end = (part->geom.end / (total_cyl)) + 1; if (unit == PED_UNIT_SECTOR) { /* In Linux fdisk compatibility mode, display exact */ if (fdisk_compatibility_mode) { start = part->geom.start; end = part->geom.end; } /* In fdisk, round up the sectors to cylinders */ else { start = (part->geom.start / total_cyl * total_cyl) + sectors; end = part->geom.end / total_cyl * total_cyl; } blocks = ((cyl_end * total_cyl) - ((part->num == 1) ? (cyl_start * sectors) : (cyl_start * total_cyl))) / (1024 / sect_size); } else { start = cyl_start; end = cyl_end; blocks = ((end * total_cyl) - ((part->num == 1) ? (start * sectors) : (start * total_cyl))) / (1024 / sect_size); } if (!ped_partition_is_active (part)) continue; if (fdisk_compatibility_mode && !strcmp((*disk)->type->name,"bsd")) { printf(" %c: ", 'a' + part->num - 1); } else { get_partition_device(buf, sizeof(buf), part, logical_offset); printf("%2$-*1$.*1$s", pathlen, buf); if (ped_partition_get_flag(part,PED_PARTITION_BOOT)) printf(" * "); else printf(" "); } printf ("%10lld %11lld %11lu ", start, end, blocks); int type_size; unsigned int part_type = get_disk_specific_system_type (part, &type_size); type_size *= 2; char *type_name = _(get_disk_specific_system_name(part,0)); if (type_size) printf(" %*x %s", type_size, part_type, type_name); else if(type_name) printf(" %s", type_name); /* FIXME: This should not be here anymore */ else { ped_device_begin_external_access((*disk)->dev); char *type = (char *)ped_partition_type_get_name (part->type); if (part->fs_type && !strcmp (part->fs_type->name, "linux-swap")) printf ("%+4s %+21s ", _("82"), _("Linux Swap / Solaris")); else if (is_bsd_partition ((*disk)->dev->path, part->geom.start * sect_size, sect_size)) printf ("%+4s %+17s ", _("a5"), _("Free/Net/OpenBSD")); else if (!strcmp (type, "primary")) printf ("%+4s %+6s ", _("83"), _("Linux")); else if (!strcmp (type, "extended")) printf ("%+4s %+9s ", _("5"), _("Extended")); ped_device_end_external_access((*disk)->dev); } printf ("\n"); start = end = blocks = 0; /* At the end we check the partition consistency for lfdisk */ if (fdisk_compatibility_mode) check_partition_consistency(part); } ped_free (cyl_size); /*if (fdisk_list_table == 1) do_quit (disk);*/ return 1;error: return 0;}#define sector(s) ((s) & 0x3f)#define cylinder(s, c) ((c) | (((s) & 0xc0) << 2))voidpart_xprint (PedDisk **disk, int extend){ PedPartition *part; PedDevice *dev = (*disk)->dev; PedCHSGeometry *chs = &(dev->bios_geom); int is_boot, start_cyl, start_head, start_sector, end_cyl, end_head, end_sector; char *part_chs = NULL; printf(_("\nDisk %s: %d heads, %d sectors, %d cylinders\n\n"), dev->path, chs->heads, chs->sectors, chs->cylinders); printf(_("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n")); for (part = ped_disk_next_partition (*disk, NULL); part; part = ped_disk_next_partition (*disk, part)) { if (!ped_partition_is_active(part)) continue; /* We skip primary partitions, if needed */ if (extend && !part->type) continue; /* TODO: Calculate, instead of parsing the string */ part_chs = ped_unit_format_custom(dev, part->geom.start, PED_UNIT_CHS); sscanf(part_chs, "%d,%d,%d", &start_cyl, &start_head, &start_sector); ped_free(part_chs); part_chs = ped_unit_format_custom(dev, part->geom.end, PED_UNIT_CHS); sscanf(part_chs, "%d,%d,%d", &end_cyl, &end_head, &end_sector); ped_free(part_chs); is_boot = ped_partition_get_flag(part,PED_PARTITION_BOOT); printf("%2d %02x%4d%4d%8d%4d%4d%8d%11lld%11lld %02x\n", part->num, is_boot ? 0x80 : 0, start_head, start_sector, start_cyl, end_head, end_sector, end_cyl, part->geom.start, part->geom.length, get_disk_specific_system_type(part, NULL)); check_partition_consistency(part); }}/* This is only run in Linux fdisk compatibility mode */static intdo_xprint (PedDisk **disk){ part_xprint(disk,0); return 1;}static intdo_eprint (PedDisk **disk){ part_xprint(disk,1); return 1;}/* This prints a sector, in the style Linux fdisk prints raw partition tables, in hex, with 16 bytes per line */static voidprint_sector (PedDevice *dev, PedSector sector){ char *buf; int size = dev->sector_size, i, pos = 0; buf = malloc(size); if (ped_device_read(dev, buf, sector, 1)) { for (i = 0; i < size; i++) { /* We print the line prefix */ if (pos == 0) printf("0x%03X:", i); printf(" %02hhX", buf[i]); /* We print the line suffix */ if (pos == 15) { printf("\n"); pos = 0; } else pos++; } if (pos != 0) printf("\n"); printf("\n"); } free(buf);}static intdo_raw (PedDisk **disk) { /* TODO: Make this for other disklabels, too */ if (strcmp((*disk)->type->name, "msdos")) { fprintf(stderr, _("Raw printing on %s not supported\n"), (*disk)->type->name); return 0; } printf(_("Device: %s\n"), (*disk)->dev->path); /* This is for DOS partition table */ PedPartition *part; int i; /* First we print the MBR */ print_sector((*disk)->dev,0); /* Then we print the partition table sectors for the logical partitions */ for (part = ped_disk_get_partition(*disk, i = 5); part; part = ped_disk_get_partition(*disk, ++i)) { print_sector((*disk)->dev, part->prev->geom.start); } }static voidprint_partition_size(PedDisk *disk){ PedPartition *part = ped_disk_get_partition(disk,fdisk_partsize_part); if (!part) { printf(_("There is no partition %d on %s\n"), fdisk_partsize_part, disk->dev->path); exit(1); } else { PedCHSGeometry* chs; PedSector sectors; PedSector cyl_size; PedSector cyl_start; PedSector cyl_end; PedSector sect_size; PedSector heads; PedSector total_cyl; chs = &(disk->dev)->bios_geom; sectors = chs->sectors; heads = chs->heads; total_cyl = heads * sectors; sect_size = disk->dev->sector_size; cyl_start = (part->geom.start / (total_cyl)) + 1; cyl_end = (part->geom.end / (total_cyl)) + 1; //ped_unit_set_default(PED_UNIT_CYLINDER); printf("%lld\n", ((cyl_end * total_cyl) - ((part->num == 1) ? (cyl_start * sectors) : (cyl_start * total_cyl))) / (1024 / sect_size) ); exit(0); } }static void do_list_devices (PedDisk* disk) { if (disk == NULL) { PedDevice* dev = NULL; ped_device_probe_all (); while ((dev = ped_device_get_next (dev))) { if (!ped_device_open(dev)) break; PedDisk *disk = ped_disk_new(dev); if (!disk) // Not fatal error continue; if (fdisk_print_raw) do_raw (&disk); else do_print (&disk); ped_disk_destroy(disk); } } else { if (fdisk_print_raw) do_raw(&disk); else do_print(&disk); } exit(0);}static PedPartitionType_disk_get_part_type_for_sector (PedDisk* disk, PedSector sector){ PedPartition* extended; extended = ped_disk_extended_partition (disk); if (!extended || !ped_geometry_test_sector_inside (&extended->geom, sector)) return 0; return PED_PARTITION_LOGICAL;}#if 0/* This function checks if "part" contains a file system, and returs * 0 if either no file system was found, or the user declined to add it. * 1 if a file system was found, and the user chose to add it. * -1 if the user chose to cancel the entire search. */static int_rescue_add_partition (PedPartition* part){ const PedFileSystemType* fs_type; PedGeometry* probed; PedExceptionOption ex_opt; PedConstraint* constraint; char* found_start; char* found_end; fs_type = ped_file_system_probe (&part->geom); if (!fs_type) return 0; probed = ped_file_system_probe_specific (fs_type, &part->geom); if (!probed) return 0; if (!ped_geometry_test_inside (&part->geom, probed)) { ped_geometry_destroy (probed); return 0; } constraint = ped_constraint_exact (probed); if (!ped_disk_set_partition_geom (part->disk, part, constraint, probed->start, probed->end)) { ped_constraint_destroy (constraint); return 0; } ped_constraint_destroy (constraint); found_start = ped_unit_format (probed->dev, probed->start); found_end = ped_unit_format (probed->dev, probed->end); ex_opt = ped_exception_throw ( PED_EXCEPTION_INFORMATION, PED_EXCEPTION_YES_NO_CANCEL, _("A %s %s partition was found at %s -> %s. " "Do you want to add it to the partition table?"), fs_type->name, ped_partition_type_get_name (part->type), found_start, found_end); ped_geometry_destroy (probed); ped_free (found_start); ped_free (found_end); switch (ex_opt) { case PED_EXCEPTION_CANCEL: return -1; case PED_EXCEPTION_NO: return 0; } ped_partition_set_system (part, fs_type); ped_disk_commit (part->disk); return 1;}/* hack: we only iterate through the start, since most (all) fs's have their * superblocks at the start. We'll need to change this if we generalize * for RAID, or something... */static int_rescue_pass (PedDisk* disk, PedGeometry* start_range, PedGeometry* end_range){ PedSector start; PedGeometry start_geom_exact; PedGeometry entire_dev; PedConstraint constraint; PedPartition* part; PedPartitionType part_type; part_type = _disk_get_part_type_for_sector ( disk, (start_range->start + end_range->end) / 2); ped_geometry_init (&entire_dev, disk->dev, 0, disk->dev->length); ped_timer_reset (timer); ped_timer_set_state_name (timer, _("searching for file systems")); for (start = start_range->start; start <= start_range->end; start++) { ped_timer_update (timer, 1.0 * (start - start_range->start) / start_range->length); ped_geometry_init (&start_geom_exact, disk->dev, start, 1); ped_constraint_init ( &constraint, ped_alignment_any, ped_alignment_any, &start_geom_exact, &entire_dev, 1, disk->dev->length); part = ped_partition_new (disk, part_type, NULL, start, end_range->end); if (!part) { ped_constraint_done (&constraint); continue; } ped_exception_fetch_all (); if (ped_disk_add_partition (disk, part, &constraint)) { ped_exception_leave_all (); switch (_rescue_add_partition (part)) { case 1: ped_constraint_done (&constraint); return 1; case 0: ped_disk_remove_partition (disk, part); break; case -1: goto error_remove_partition; } } else { ped_exception_leave_all (); } ped_partition_destroy (part); ped_constraint_done (&constraint); } ped_timer_update (timer, 1.0); return 1;error_remove_partition: ped_disk_remove_partition (disk, part);error_partition_destroy: ped_partition_destroy (part);error_constraint_done: ped_constraint_done (&constraint);error: return 0;}#endifstatic intdo_rescue (PedDisk** disk){ return perform_rescue(*disk, 0LL, 0LL, UI_CUSTOM_VALUES | UI_WARN_COMMIT);#if 0 PedSector start = 0, end = 0; PedSector fuzz; PedGeometry probe_start_region; PedGeometry probe_end_region; if (!*disk) goto error; if (!command_line_prompt_boolean_question (_("WARNING: rescue writes all data to disk automatically, continue"))) return 1; if (!fdisk_command_line_get_sector (_("Start?"), (*disk)->dev, &start, NULL)) goto error; if (!fdisk_command_line_get_sector (_("End?"), (*disk)->dev, &end, NULL)) goto error; fuzz = PED_MAX (PED_MIN ((end - start) / 10, MEGABYTE_SECTORS), MEGABYTE_SECTORS * 16);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?