📄 fdisk.c
字号:
p->end_sector = 0; p->end_cyl = 0; set_start_sect(p,0); set_nr_sects(p,0);}static voidset_partition(int i, int doext, unsigned int start, unsigned int stop, int sysid) { struct partition *p; unsigned int offset; if (doext) { p = ptes[i].ext_pointer; offset = extended_offset; } else { p = ptes[i].part_table; offset = ptes[i].offset; } p->boot_ind = 0; p->sys_ind = sysid; set_start_sect(p, start - offset); set_nr_sects(p, stop - start + 1); if (dos_compatible_flag && (start/(sectors*heads) > 1023)) start = heads*sectors*1024 - 1; set_hsc(p->head, p->sector, p->cyl, start); if (dos_compatible_flag && (stop/(sectors*heads) > 1023)) stop = heads*sectors*1024 - 1; set_hsc(p->end_head, p->end_sector, p->end_cyl, stop); ptes[i].changed = 1;}static inttest_c(char **m, char *mesg) { int val = 0; if (!*m) fprintf(stderr, _("You must set")); else { fprintf(stderr, " %s", *m); val = 1; } *m = mesg; return val;}static intwarn_geometry(void) { char *m = NULL; int prev = 0; if (!heads) prev = test_c(&m, _("heads")); if (!sectors) prev = test_c(&m, _("sectors")); if (!cylinders) prev = test_c(&m, _("cylinders")); if (!m) return 0; fprintf(stderr, _("%s%s.\nYou can do this from the extra functions menu.\n"), prev ? _(" and ") : " ", m); return 1;}void update_units(void){ int cyl_units = heads * sectors; if (display_in_cyl_units && cyl_units) units_per_sector = cyl_units; else units_per_sector = 1; /* in sectors */}static voidwarn_cylinders(void) { if (dos_label && cylinders > 1024 && !nowarn) fprintf(stderr, _("\n""The number of cylinders for this disk is set to %d.\n""There is nothing wrong with that, but this is larger than 1024,\n""and could in certain setups cause problems with:\n""1) software that runs at boot time (e.g., old versions of LILO)\n""2) booting and partitioning software from other OSs\n"" (e.g., DOS FDISK, OS/2 FDISK)\n"), cylinders);}static voidread_extended(int ext) { int i; struct pte *pex; struct partition *p, *q; ext_index = ext; pex = &ptes[ext]; pex->ext_pointer = pex->part_table; p = pex->part_table; if (!get_start_sect(p)) { fprintf(stderr, _("Bad offset in primary extended partition\n")); return; } while (IS_EXTENDED (p->sys_ind)) { struct pte *pe = &ptes[partitions]; if (partitions >= MAXIMUM_PARTS) { /* This is not a Linux restriction, but this program uses arrays of size MAXIMUM_PARTS. Do not try to `improve' this test. */ struct pte *pre = &ptes[partitions-1]; fprintf(stderr, _("Warning: omitting partitions after %d\n"), partitions); clear_partition(pre->ext_pointer); pre->changed = 1; return; } read_pte(fd, partitions, extended_offset + get_start_sect(p)); if (!extended_offset) extended_offset = get_start_sect(p); q = p = pt_offset(pe->sectorbuffer, 0); for (i = 0; i < 4; i++, p++) if (get_nr_sects(p)) { if (IS_EXTENDED (p->sys_ind)) { if (pe->ext_pointer) fprintf(stderr, _("Warning: extra link " "pointer in partition table" " %d\n"), partitions + 1); else pe->ext_pointer = p; } else if (p->sys_ind) { if (pe->part_table) fprintf(stderr, _("Warning: ignoring extra " "data in partition table" " %d\n"), partitions + 1); else pe->part_table = p; } } /* very strange code here... */ if (!pe->part_table) { if (q != pe->ext_pointer) pe->part_table = q; else pe->part_table = q + 1; } if (!pe->ext_pointer) { if (q != pe->part_table) pe->ext_pointer = q; else pe->ext_pointer = q + 1; } p = pe->ext_pointer; partitions++; } /* remove empty links */ remove: for (i = 4; i < partitions; i++) { struct pte *pe = &ptes[i]; if (!get_nr_sects(pe->part_table) && (partitions > 5 || ptes[4].part_table->sys_ind)) { printf("omitting empty partition (%d)\n", i+1); delete_partition(i); goto remove; /* numbering changed */ } }}static voidcreate_doslabel(void) { int i; fprintf(stderr, _("Building a new DOS disklabel. Changes will remain in memory only,\n" "until you decide to write them. After that, of course, the previous\n" "content won't be recoverable.\n\n")); sun_nolabel(); /* otherwise always recognised as sun */ sgi_nolabel(); /* otherwise always recognised as sgi */ aix_label = osf_label = possibly_osf_label = 0; partitions = 4; for (i = 510-64; i < 510; i++) MBRbuffer[i] = 0; write_part_table_flag(MBRbuffer); extended_offset = 0; set_all_unchanged(); set_changed(0); get_boot(create_empty_dos);}#include <sys/utsname.h>#define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))static intlinux_version_code(void) { static int kernel_version = 0; struct utsname my_utsname; int p, q, r; if (!kernel_version && uname(&my_utsname) == 0) { p = atoi(strtok(my_utsname.release, ".")); q = atoi(strtok(NULL, ".")); r = atoi(strtok(NULL, ".")); kernel_version = MAKE_VERSION(p,q,r); } return kernel_version;}static voidget_sectorsize(int fd) {#if defined(BLKSSZGET) if (!user_set_sector_size && linux_version_code() >= MAKE_VERSION(2,3,3)) { int arg; if (ioctl(fd, BLKSSZGET, &arg) == 0) sector_size = arg; if (sector_size != DEFAULT_SECTOR_SIZE) printf(_("Note: sector size is %d (not %d)\n"), sector_size, DEFAULT_SECTOR_SIZE); }#else /* maybe the user specified it; and otherwise we still have the DEFAULT_SECTOR_SIZE default */#endif}static voidget_kernel_geometry(int fd) {#ifdef HDIO_GETGEO struct hd_geometry geometry; if (!ioctl(fd, HDIO_GETGEO, &geometry)) { kern_heads = geometry.heads; kern_sectors = geometry.sectors; /* never use geometry.cylinders - it is truncated */ }#endif}static intis_probably_full_disk(char *name) {#ifdef HDIO_GETGEO struct hd_geometry geometry; int fd, i = 0; fd = open(name, O_RDONLY); if (fd >= 0) { i = ioctl(fd, HDIO_GETGEO, &geometry); close(fd); } return (fd >= 0 && i == 0 && geometry.start == 0);#else /* silly heuristic */ while (*name) name++; return !isdigit(name[-1]);#endif}static voidget_partition_table_geometry(void) { unsigned char *bufp = MBRbuffer; struct partition *p; int i, h, s, hh, ss; int first = 1; int bad = 0; if (!(valid_part_table_flag(bufp))) return; hh = ss = 0; for (i=0; i<4; i++) { p = pt_offset(bufp, i); if (p->sys_ind != 0) { h = p->end_head + 1; s = (p->end_sector & 077); if (first) { hh = h; ss = s; first = 0; } else if (hh != h || ss != s) bad = 1; } } if (!first && !bad) { pt_heads = hh; pt_sectors = ss; }}voidget_geometry(int fd, struct geom *g) { int sec_fac; unsigned long long llsectors, llcyls; get_sectorsize(fd); sec_fac = sector_size / 512; guess_device_type(fd); heads = cylinders = sectors = 0; kern_heads = kern_sectors = 0; pt_heads = pt_sectors = 0; get_kernel_geometry(fd); get_partition_table_geometry(); 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; if (disksize(fd, &llsectors)) llsectors = 0; total_number_of_sectors = llsectors; sector_offset = 1; if (dos_compatible_flag) sector_offset = sectors; llcyls = total_number_of_sectors / (heads * sectors * sec_fac); cylinders = llcyls; if (cylinders != llcyls) /* truncated? */ cylinders = ~0; if (!cylinders) cylinders = user_cylinders; if (g) { g->heads = heads; g->sectors = sectors; g->cylinders = cylinders; }}/* * Read MBR. Returns: * -1: no 0xaa55 flag present (possibly entire disk BSD) * 0: found or created label * 1: I/O error */intget_boot(enum action what) { int i; partitions = 4; ext_index = 0; extended_offset = 0; for (i = 0; i < 4; i++) { struct pte *pe = &ptes[i]; pe->part_table = pt_offset(MBRbuffer, i); pe->ext_pointer = NULL; pe->offset = 0; pe->sectorbuffer = MBRbuffer; pe->changed = (what == create_empty_dos); } if (what == create_empty_sun && check_sun_label()) return 0; memset(MBRbuffer, 0, 512); if (what == create_empty_dos) goto got_dos_table; /* skip reading disk */ if ((fd = open(disk_device, type_open)) < 0) { if ((fd = open(disk_device, O_RDONLY)) < 0) { if (what == try_only) return 1; fatal(unable_to_open); } else printf(_("You will not be able to write " "the partition table.\n")); } if (512 != read(fd, MBRbuffer, 512)) { if (what == try_only) return 1; fatal(unable_to_read); } get_geometry(fd, NULL); update_units(); if (check_sun_label()) return 0; if (check_sgi_label()) return 0; if (check_aix_label()) return 0; if (check_osf_label()) { possibly_osf_label = 1; if (!valid_part_table_flag(MBRbuffer)) { osf_label = 1; return 0; } printf(_("This disk has both DOS and BSD magic.\n" "Give the 'b' command to go to BSD mode.\n")); }got_dos_table: if (!valid_part_table_flag(MBRbuffer)) { switch(what) { case fdisk: fprintf(stderr, _("Device contains neither a valid DOS " "partition table, nor Sun, SGI or OSF " "disklabel\n"));#ifdef __sparc__ create_sunlabel();#else create_doslabel();#endif return 0; case require: return -1; case try_only: return -1; case create_empty_dos: case create_empty_sun: break; default: fprintf(stderr, _("Internal error\n")); exit(1); } } warn_cylinders(); warn_geometry(); for (i = 0; i < 4; i++) { struct pte *pe = &ptes[i]; if (IS_EXTENDED (pe->part_table->sys_ind)) { if (partitions != 4) fprintf(stderr, _("Ignoring extra extended " "partition %d\n"), i + 1); else read_extended(i); } } for (i = 3; i < partitions; i++) { struct pte *pe = &ptes[i]; if (!valid_part_table_flag(pe->sectorbuffer)) { fprintf(stderr, _("Warning: invalid flag 0x%04x of partition " "table %d will be corrected by w(rite)\n"), part_table_flag(pe->sectorbuffer), i + 1); pe->changed = 1; } } return 0;}/* read line; return 0 or first char */intread_line(void){ static int got_eof = 0; line_ptr = line_buffer; if (!fgets(line_buffer, LINE_LENGTH, stdin)) { if (feof(stdin)) got_eof++; /* user typed ^D ? */ if (got_eof >= 3) { fflush(stdout); fprintf(stderr, _("\ngot EOF thrice - exiting..\n")); exit(1); } return 0; } while (*line_ptr && !isgraph(*line_ptr)) line_ptr++; return *line_ptr;}charread_char(char *mesg){ do { fputs(mesg, stdout); fflush (stdout); /* requested by niles@scyld.com */ } while (!read_line()); return *line_ptr;}charread_chars(char *mesg){ fputs(mesg, stdout); fflush (stdout); /* niles@scyld.com */ if (!read_line()) { *line_ptr = '\n'; line_ptr[1] = 0; } return *line_ptr;}intread_hex(struct systypes *sys){ int hex; while (1) { read_char(_("Hex code (type L to list codes): ")); if (tolower(*line_ptr) == 'l') list_types(sys); else if (isxdigit (*line_ptr)) { hex = 0; do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -