📄 fdisk.c
字号:
write_part_table_flag(pe->sectorbuffer); write_sector(fd, pe->offset, pe->sectorbuffer); } } } else if (sgi_label) { /* no test on change? the printf below might be mistaken */ sgi_write_table(); } else if (sun_label) { int needw = 0; for (i=0; i<8; i++) if (ptes[i].changed) needw = 1; if (needw) sun_write_table(); } printf(_("The partition table has been altered!\n\n")); reread_partition_table(1);}voidreread_partition_table(int leave) { int error = 0; int i; printf(_("Calling ioctl() to re-read partition table.\n")); sync(); sleep(2); if ((i = ioctl(fd, BLKRRPART)) != 0) { error = errno; } else { /* some kernel versions (1.2.x) seem to have trouble rereading the partition table, but if asked to do it twice, the second time works. - biro@yggdrasil.com */ sync(); sleep(2); if ((i = ioctl(fd, BLKRRPART)) != 0) error = errno; } if (i) { printf(_("\nWARNING: Re-reading the partition table " "failed with error %d: %s.\n" "The kernel still uses the old table.\n" "The new table will be used " "at the next reboot.\n"), error, strerror(error)); } if (dos_changed) printf( _("\nWARNING: If you have created or modified any DOS 6.x\n" "partitions, please see the fdisk manual page for additional\n" "information.\n")); if (leave) { close(fd); printf(_("Syncing disks.\n")); sync(); sleep(4); /* for sync() */ exit(!!i); }}#define MAX_PER_LINE 16static voidprint_buffer(char pbuffer[]) { int i, l; for (i = 0, l = 0; i < sector_size; i++, l++) { if (l == 0) printf("0x%03X:", i); printf(" %02X", (unsigned char) pbuffer[i]); if (l == MAX_PER_LINE - 1) { printf("\n"); l = -1; } } if (l > 0) printf("\n"); printf("\n");}static voidprint_raw(void) { int i; printf(_("Device: %s\n"), disk_device); if (sun_label || sgi_label) print_buffer(MBRbuffer); else for (i = 3; i < partitions; i++) print_buffer(ptes[i].sectorbuffer);}static voidmove_begin(int i) { struct pte *pe = &ptes[i]; struct partition *p = pe->part_table; unsigned int new, first; if (warn_geometry()) return; if (!p->sys_ind || !get_nr_sects(p) || IS_EXTENDED (p->sys_ind)) { printf(_("Partition %d has no data area\n"), i + 1); return; } first = get_partition_start(pe); new = read_int(first, first, first + get_nr_sects(p) - 1, first, _("New beginning of data")) - pe->offset; if (new != get_nr_sects(p)) { first = get_nr_sects(p) + get_start_sect(p) - new; set_nr_sects(p, first); set_start_sect(p, new); pe->changed = 1; }}static voidxselect(void) { char c; while(1) { putchar('\n'); c = tolower(read_char(_("Expert command (m for help): "))); switch (c) { case 'a': if (sun_label) sun_set_alt_cyl(); break; case 'b': if (dos_label) move_begin(get_partition(0, partitions)); break; case 'c': user_cylinders = cylinders = read_int(1, cylinders, 1048576, 0, _("Number of cylinders")); if (sun_label) sun_set_ncyl(cylinders); if (dos_label) warn_cylinders(); break; case 'd': print_raw(); break; case 'e': if (sgi_label) sgi_set_xcyl(); else if (sun_label) sun_set_xcyl(); else if (dos_label) x_list_table(1); break; case 'f': if (dos_label) fix_partition_table_order(); break; case 'g': create_sgilabel(); break; case 'h': user_heads = heads = read_int(1, heads, 256, 0, _("Number of heads")); update_units(); break; case 'i': if (sun_label) sun_set_ilfact(); break; case 'o': if (sun_label) sun_set_rspeed(); break; case 'p': if (sun_label) list_table(1); else x_list_table(0); break; case 'q': close(fd); printf("\n"); exit(0); case 'r': return; case 's': user_sectors = sectors = read_int(1, sectors, 63, 0, _("Number of sectors")); if (dos_compatible_flag) { sector_offset = sectors; fprintf(stderr, _("Warning: setting " "sector offset for DOS " "compatiblity\n")); } update_units(); break; case 'v': verify(); break; case 'w': write_table(); /* does not return */ break; case 'y': if (sun_label) sun_set_pcylcount(); break; default: xmenu(); } }}static intis_ide_cdrom_or_tape(char *device) { FILE *procf; char buf[100]; struct stat statbuf; int is_ide = 0; /* No device was given explicitly, and we are trying some likely things. But opening /dev/hdc may produce errors like "hdc: tray open or drive not ready" if it happens to be a CD-ROM drive. It even happens that the process hangs on the attempt to read a music CD. So try to be careful. This only works since 2.1.73. */ if (strncmp("/dev/hd", device, 7)) return 0; snprintf(buf, sizeof(buf), "/proc/ide/%s/media", device+5); procf = fopen(buf, "r"); if (procf != NULL && fgets(buf, sizeof(buf), procf)) is_ide = (!strncmp(buf, "cdrom", 5) || !strncmp(buf, "tape", 4)); else /* Now when this proc file does not exist, skip the device when it is read-only. */ if (stat(device, &statbuf) == 0) is_ide = ((statbuf.st_mode & 0222) == 0); if (procf) fclose(procf); return is_ide;}static voidtry(char *device, int user_specified) { int gb; disk_device = device; if (setjmp(listingbuf)) return; if (!user_specified) if (is_ide_cdrom_or_tape(device)) return; if ((fd = open(disk_device, type_open)) >= 0) { gb = get_boot(try_only); if (gb > 0) { /* I/O error */ } else if (gb < 0) { /* no DOS signature */ list_disk_geometry(); if (!aix_label && btrydev(device) < 0) fprintf(stderr, _("Disk %s doesn't contain a valid " "partition table\n"), device); } else { list_table(0); } close(fd); } else { /* Ignore other errors, since we try IDE and SCSI hard disks which may not be installed on the system. */ if (errno == EACCES) { fprintf(stderr, _("Cannot open %s\n"), device); return; } }}/* * for fdisk -l: * try all things in /proc/partitions that look like a full disk */static voidtryprocpt(void) { FILE *procpt; char line[100], ptname[100], devname[120]; int ma, mi, sz; procpt = fopen(PROC_PARTITIONS, "r"); if (procpt == NULL) { fprintf(stderr, _("cannot open %s\n"), PROC_PARTITIONS); return; } while (fgets(line, sizeof(line), procpt)) { if (sscanf (line, " %d %d %d %[^\n ]", &ma, &mi, &sz, ptname) != 4) continue; snprintf(devname, sizeof(devname), "/dev/%s", ptname); if (is_probably_full_disk(devname)) try(devname, 0); } fclose(procpt);}static voiddummy(int *kk) {}static voidunknown_command(int c) { printf(_("%c: unknown command\n"), c);}intmain(int argc, char **argv) { int j, c; int optl = 0, opts = 0; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); /* * Calls: * fdisk -v * fdisk -l [-b sectorsize] [-u] device ... * fdisk -s [partition] ... * fdisk [-b sectorsize] [-u] device * * Options -C, -H, -S set the geometry. * */ while ((c = getopt(argc, argv, "b:C:H:lsS:uvV")) != -1) { switch (c) { case 'b': /* Ugly: this sector size is really per device, so cannot be combined with multiple disks, and te same goes for the C/H/S options. */ sector_size = atoi(optarg); if (sector_size != 512 && sector_size != 1024 && sector_size != 2048) fatal(usage); sector_offset = 2; user_set_sector_size = 1; break; case 'C': user_cylinders = atoi(optarg); break; case 'H': user_heads = atoi(optarg); if (user_heads <= 0 || user_heads >= 256) user_heads = 0; break; case 'S': user_sectors = atoi(optarg); if (user_sectors <= 0 || user_sectors >= 64) user_sectors = 0; break; case 'l': optl = 1; break; case 's': opts = 1; break; case 'u': display_in_cyl_units = 0; break; case 'V': case 'v': printf("fdisk v" UTIL_LINUX_VERSION "\n"); exit(0); default: fatal(usage); } }#if 0 printf(_("This kernel finds the sector size itself - " "-b option ignored\n"));#else if (user_set_sector_size && argc-optind != 1) printf(_("Warning: the -b (set sector size) option should" " be used with one specified device\n"));#endif if (optl) { nowarn = 1; type_open = O_RDONLY; if (argc > optind) { int k; /* avoid gcc warning: variable `k' might be clobbered by `longjmp' */ dummy(&k); listing = 1; for (k = optind; k < argc; k++) try(argv[k], 1); } else { /* we no longer have default device names */ /* but we can use /proc/partitions instead */ tryprocpt(); } exit(0); } if (opts) { unsigned long long size; nowarn = 1; type_open = O_RDONLY; opts = argc - optind; if (opts <= 0) fatal(usage); for (j = optind; j < argc; j++) { disk_device = argv[j]; if ((fd = open(disk_device, type_open)) < 0) fatal(unable_to_open); if (disksize(fd, &size)) fatal(ioctl_error); close(fd); if (opts == 1) printf("%llu\n", size/2); else printf("%s: %llu\n", argv[j], size/2); } exit(0); } if (argc-optind == 1) disk_device = argv[optind]; else if (argc-optind != 0) fatal(usage); else fatal(usage2); get_boot(fdisk); if (osf_label) { /* OSF label, and no DOS label */ printf(_("Detected an OSF/1 disklabel on %s, entering " "disklabel mode.\n"), disk_device); bselect(); osf_label = 0; /* If we return we may want to make an empty DOS label? */ } while (1) { putchar('\n'); c = tolower(read_char(_("Command (m for help): "))); switch (c) { case 'a': if (dos_label) toggle_active(get_partition(1, partitions)); else if (sun_label) toggle_sunflags(get_partition(1, partitions), 0x01); else if (sgi_label) sgi_set_bootpartition( get_partition(1, partitions)); else unknown_command(c); break; case 'b': if (sgi_label) { printf(_("\nThe current boot file is: %s\n"), sgi_get_bootfile()); if (read_chars(_("Please enter the name of the " "new boot file: ")) == '\n') printf(_("Boot file unchanged\n")); else sgi_set_bootfile(line_ptr); } else bselect(); break; case 'c': if (dos_label) toggle_dos_compatibility_flag(); else if (sun_label) toggle_sunflags(get_partition(1, partitions), 0x10); else if (sgi_label) sgi_set_swappartition( get_partition(1, partitions)); else unknown_command(c); break; case 'd': /* If sgi_label then don't use get_existing_partition, let the user select a partition, since get_existing_partition() only works for Linux-like partition tables */ if (!sgi_label) { j = get_existing_partition(1, partitions); } else { j = get_partition(1, partitions); } if (j >= 0) delete_partition(j); break; case 'i': if (sgi_label) create_sgiinfo(); else unknown_command(c); case 'l': list_types(get_sys_types()); break; case 'm': menu(); break; case 'n': new_partition(); break; case 'o': create_doslabel(); break; case 'p': list_table(0); break; case 'q': close(fd); printf("\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -