📄 partition.c
字号:
void do_cr_auto(void){ GEOMETRY geo; struct stat st; char *table, *table2, *other; int partition, pfd, i, j; struct partition part_table[PART_MAX]; if (autoauto) has_partition = 0; other = identify ? cfg_get_strg(cf_identify, "other") : cfg_get_strg(cf_top, "other"); if (verbose > 4) printf("do_cr_auto: other=%s has_partition=%d\n", other, has_partition);#if 0 i = other[strlen(other)-1] - '0'; if (i>PART_MAX || i<1) return;#endif table = cfg_get_strg(cf_other,"table"); table2 = boot_mbr(other, 1); /* get possible default */ if (!table) table = table2; if (!table && autoauto) return; if (table && autoauto && !table2) cfg_error("TABLE may not be specified"); if (has_partition) cfg_error("AUTOMATIC must be before PARTITION"); if (!table) cfg_error("TABLE must be set to use AUTOMATIC"); /* */ if (stat(table,&st) < 0) die("stat %s: %s",table,strerror(errno)); geo_get(&geo,st.st_rdev & D_MASK(st.st_rdev),-1,1); partition = st.st_rdev & P_MASK(st.st_rdev); if (!S_ISBLK(st.st_mode) || partition) cfg_error("\"%s\" doesn't contain a primary partition table",table); pfd = open(table, O_RDONLY); if (pfd<0) die("Cannot open %s", table); if (lseek(pfd, PART_TABLE_OFFSET, SEEK_SET)!=PART_TABLE_OFFSET) die("Cannot seek to partition table of %s", table); if (read(pfd, part_table, sizeof(part_table))!=sizeof(part_table)) die("Cannot read Partition Table of %s", table); close(pfd); partition = other[strlen(other)-1] - '0'; if (verbose > 3) printf("partition = %d\n", partition); for (j=i=0; i<PART_MAX; i++) if (may_change(part_table[i].sys_ind)) j++; if (j>1)#if defined(LCF_REWRITE_TABLE) && !defined(LCF_READONLY) for (i=0; i<PART_MAX; i++) { CHANGE_RULE *cr; if ((cr=may_change(part_table[i].sys_ind))) { j = i*PARTITION_ENTRY + PART_TYPE_ENT_OFF; if (autoauto && !nowarn) { fflush(stdout); fprintf(errstd, "Warning: CHANGE AUTOMATIC assumed after \"other=%s\"\n", other); autoauto = 0; /* suppress further warnings */ } if (i == partition-1) add_rule(geo.device, j, cr->hidden, cr->normal); else add_rule(geo.device, j, cr->normal, cr->hidden); } }#else if (!nowarn) fprintf(errstd, "Warning: This LILO is compiled without REWRITE_TABLE;\n" " unable to generate CHANGE/AUTOMATIC change-rules\n");#endif}void do_cr_part(void){ GEOMETRY geo; struct stat st; char *tmp; int partition,part_base; tmp = cfg_get_strg(cf_change,"partition"); if (stat(tmp,&st) < 0) die("stat %s: %s",tmp,strerror(errno)); geo_get(&geo,st.st_rdev & D_MASK(st.st_rdev),-1,1); partition = st.st_rdev & P_MASK(st.st_rdev); if (!S_ISBLK(st.st_mode) || !partition || partition > PART_MAX) cfg_error("\"%s\" isn't a primary partition",tmp); part_base = (partition-1)*PARTITION_ENTRY; has_partition = 1; cfg_init(cf_change_dsc); (void) cfg_parse(cf_change_dsc); tmp = cfg_get_strg(cf_change_dsc,"set"); if (tmp) {#if defined(LCF_REWRITE_TABLE) && !defined(LCF_READONLY) CHANGE_RULE *walk; char *here; int hidden; here = (void*)NULL; /* quiet GCC */ hidden = 0; /* quiet GCC */ if (strlen(tmp) < 7 || !(here = strrchr(tmp,'_')) || ((hidden = strcasecmp(here+1,"normal")) && strcasecmp(here+1,"hidden"))) cfg_error("Type name must end with _normal or _hidden"); *here = 0; for (walk = change_rules; walk; walk = walk->next) if (!strcasecmp(walk->type,tmp)) break; if (!walk) cfg_error("Unrecognized type name"); add_rule(geo.device,part_base+PART_TYPE_ENT_OFF,hidden ? walk->normal : walk->hidden,hidden ? walk->hidden : walk->normal);#else die("This LILO is compiled without REWRITE_TABLE and doesn't support " "the SET option");#endif } if (cfg_get_flag(cf_change_dsc,"activate")) {#if defined(LCF_REWRITE_TABLE) && !defined(LCF_READONLY) add_rule(geo.device,part_base+PART_ACT_ENT_OFF,0x00,0x80); if (cfg_get_flag(cf_change_dsc,"deactivate")) cfg_error("ACTIVATE and DEACTIVATE are incompatible");#else die("This LILO is compiled without REWRITE_TABLE and doesn't support " "the ACTIVATE option");#endif } if (cfg_get_flag(cf_change_dsc,"deactivate"))#if defined(LCF_REWRITE_TABLE) && !defined(LCF_READONLY) add_rule(geo.device,part_base+PART_ACT_ENT_OFF,0x80,0x00);#else die("This LILO is compiled without REWRITE_TABLE and doesn't support " "the DEACTIVATE option");#endif cfg_unset(cf_change,"partition");}void do_change(void){ cfg_init(cf_change); has_partition = 0; (void) cfg_parse(cf_change);}void preload_types(void){#if 0 /* don't know if it makes sense to add these too */ add_type("Netware", 0x64, 0x74); add_type("OS2_BM", 0x0a, 0x1a);#endif add_type("OS2_HPFS", 0x07, 0x17); add_type("FAT16_lba", PART_FAT16_LBA, -1); add_type("FAT32_lba", PART_FAT32_LBA, -1); add_type("FAT32", PART_FAT32, -1); add_type("NTFS", PART_NTFS, -1); add_type("DOS16_big", PART_DOS16_BIG, -1); add_type("DOS16_small", PART_DOS16_SMALL, -1); add_type("DOS12", PART_DOS12, -1);}#define PART_BEGIN 0x1be#define PART_NUM 4#define PART_SIZE 16#define PART_ACTIVE 0x80#define PART_INACTIVE 0void do_activate(char *part, char *which){#if 1 int part_max, count, number, fd; struct partition pt [PART_MAX_MAX+1]; long long daddr [PART_MAX_MAX+1]; int modify=0; part_max = read_partitions(part, extended_pt ? PART_MAX_MAX : 0, NULL, pt, daddr);/* printf("part_max=%d\n", part_max); */ if (!which) { /* one argument: display active partition */ for (count=0; count < part_max; count++) { if (pt[count].boot_ind) { printf("%s%d\n",part,count+1); exit(0); } } printf("No active partition found on %s\n",part); exit(0); } number = to_number(which); if (number < 0 || number > part_max) die("%s: not a valid partition number (1-%d)",which,part_max); if (number && !pt[number-1].sys_ind) die("Cannot activate an empty partition"); number--; /* we are zero-based from here on */ if ((fd = open(part, O_RDWR)) < 0) die("open %s: %s",part,strerror(errno)); for (count=0; count<part_max; count++) { unsigned char flag = count==number ? PART_ACTIVE : PART_INACTIVE; if (pt[count].sys_ind && pt[count].boot_ind != flag) { pt[count].boot_ind = flag; printf("pt[%d] -> %2x\n", count+1, (int)flag); if (lseek64(fd, daddr[count], SEEK_SET) < 0) die("PT lseek64 failed"); if (!test) if (write(fd, &pt[count], sizeof(pt[0])) != sizeof(pt[0]) ) die("PT write failure"); modify++; } } close(fd); if (modify) printf("The partition table has%s been updated.\n", test ? " *NOT*" : ""); else printf("No partition table modifications are needed.\n");#else struct stat st; int fd,number,count; unsigned char flag, ptype; if ((fd = open(part, !which ? O_RDONLY : O_RDWR)) < 0) die("open %s: %s",part,strerror(errno)); if (fstat(fd,&st) < 0) die("stat %s: %s",part,strerror(errno)); if (!S_ISBLK(st.st_mode)) die("%s: not a block device",part); if (verbose >= 1) { printf("st.st_dev = %04X, st.st_rdev = %04X\n", (int)st.st_dev, (int)st.st_rdev); } if ((st.st_rdev & has_partitions(st.st_rdev)) != st.st_rdev) die("%s is not a master device with a primary partition table", part); if (!which) { /* one argument: display active partition */ for (count = 1; count <= PART_NUM; count++) { if (lseek(fd,PART_BEGIN+(count-1)*PART_SIZE,SEEK_SET) < 0) die("lseek: %s",strerror(errno)); if (read(fd,&flag,1) != 1) die("read: %s",strerror(errno)); if (flag == PART_ACTIVE) { printf("%s%d\n",part,count); exit(0); } } die("No active partition found on %s",part); } number = to_number(which); if (number < 0 || number > 4) die("%s: not a valid partition number (1-4)",which); for (count = 1; count <= PART_NUM; count++) { if (lseek(fd,PART_BEGIN+(count-1)*PART_SIZE+4,SEEK_SET) < 0) die("lseek: %s",strerror(errno)); if (read(fd,&ptype,1) != 1) die("read: %s",strerror(errno)); if (count == number && ptype==0) die("Cannot activate an empty partition"); } if (test) { printf("The partition table of %s has *NOT* been updated\n",part); } else for (count = 1; count <= PART_NUM; count++) { if (lseek(fd,PART_BEGIN+(count-1)*PART_SIZE,SEEK_SET) < 0) die("lseek: %s",strerror(errno)); flag = count == number ? PART_ACTIVE : PART_INACTIVE; if (write(fd,&flag,1) != 1) die("write: %s",strerror(errno)); }#endif exit(0);}void do_install_mbr(char *part, char *what){ int fd, i;#ifndef LCF_BUILTIN int nfd;#endif struct stat st; BOOT_SECTOR buf; char *cp; if (!what) what = DFL_MBR; extended_pt |= !!strchr(what,'x') || !!strchr(what,'X') || !!strchr(what,'2'); if ((fd=open(part,O_RDWR)) < 0) die("Cannot open %s: %s", part,strerror(errno)); if (fstat(fd,&st) < 0) die("stat: %s : %s", part,strerror(errno)); if (!S_ISBLK(st.st_mode) && !force_fs) die("%s not a block device",part); if (st.st_rdev != (st.st_rdev & has_partitions(st.st_rdev))) die("%s is not a master device with a primary parition table",part); if (read(fd,&buf,SECTOR_SIZE) != SECTOR_SIZE) die("read %s: %s",part, strerror(errno)); cp = cfg_get_strg(cf_options,"force-backup"); i = (cp!=NULL); if (!cp) cp = cfg_get_strg(cf_options,"backup"); make_backup(cp, i, &buf, st.st_rdev, part); #ifndef LCF_BUILTIN if ((nfd=open(what,O_RDONLY)) < 0) die("Cannot open %s: %s",what,strerror(errno)); if (read(nfd,buf,MAX_BOOT_SIZE) != MAX_BOOT_SIZE) die("read %s: %s",what,strerror(errno));#else memcpy(&buf, extended_pt ? Mbr2.data : Mbr.data, MAX_BOOT_SIZE);#endif buf.boot.boot_ind = BOOT_SIGNATURE; if (zflag) { buf.boot.mbz = buf.boot.marker = buf.boot.volume_id = 0;#if BETA_TEST || 1 if ((cp=cfg_get_strg(cf_options,RAID_EXTRA_BOOT))) { buf.boot.volume_id = strtoul(cp, NULL, 16); }#endif } else if (buf.boot.volume_id == 0) {#if 0 i = st.st_rdev; i %= PRIME; /* modulo a prime number; eg, 2551, 9091 */ i += SMALL_PRIME; srand(time(NULL)); /* seed the random number generator */ while (i--) rand(); *(int*)&buf[PART_TABLE_OFFSET - 6] = rand(); /* insert serial number */ if (*(short*)&buf[PART_TABLE_OFFSET - 2] == 0) *(short*)&buf[PART_TABLE_OFFSET - 2] = MAGIC_SERIAL;#else buf.boot.volume_id = new_serial(st.st_rdev); buf.boot.marker = MAGIC_SERIAL;#endif } if (lseek(fd,0,SEEK_SET) != 0) die("seek %s; %s", part, strerror(errno)); if (!test) { if (write(fd,&buf,SECTOR_SIZE) != SECTOR_SIZE) die("write %s: %s",part,strerror(errno)); } close(fd);#ifndef LCF_BUILTIN close(nfd);#endif printf("The Master Boot Record of %s has %sbeen updated.\n", part, test ? "*NOT* " : ""); exit(0);}/* partition table read */int read_partitions(char *part, int max, int *volid, struct partition *p, long long *where){ int fd, i; unsigned int second, base; unsigned short boot_sig; struct partition pt[PART_MAX]; BOOT_PARAMS_1 hdr; struct stat st; long long daddr; if ((fd=open(part,O_RDONLY))<0) die("Cannot open '%s'", part); if (fstat(fd,&st)<0) die("Cannot fstat '%s'", part); if (!S_ISBLK(st.st_mode)) die("Not a block device '%s'", part); i = st.st_rdev; if (!has_partitions(i) || (P_MASK(i)&i) ) die("Not a device with partitions '%s'", part); if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) die("read header"); if (!strncmp(hdr.signature, "LILO", 4) && hdr.stage == STAGE_MBR2 && max == 0) max = PART_MAX_MAX; else if (max == 0) max = PART_MAX; if (lseek(fd, PART_TABLE_OFFSET, SEEK_SET)<0) die("lseek failed"); if (read(fd, pt, sizeof(pt)) != sizeof(pt)) die("read pt failed"); if ( read(fd, &boot_sig, sizeof(boot_sig)) != sizeof(boot_sig) || boot_sig != BOOT_SIGNATURE ) die("read boot signature failed"); if (volid) { if (lseek(fd, MAX_BOOT_SIZE+2, SEEK_SET)<0) die("lseek vol-ID failed"); if (read(fd, volid, sizeof(*volid)) != sizeof(*volid)) die("read vol-ID failed");/* printf(" vol-ID: %08X\n", second); */ }/* printf("%s\n", phead); */ second=base=0; if (max>=4) for (i=0; i<PART_MAX; i++) {/* print_pt(i+1, pt[i]); */ if (is_extd_part(pt[i].sys_ind)) { if (!base) base = pt[i].start_sect; else die("invalid partition table: second extended partition found"); } if (where) *where++ = PART_TABLE_OFFSET + i*sizeof(*p); *p++ = pt[i]; } max -= (i=4); if (max>0) while (base) { daddr = LLSECTORSIZE*(base+second) + PART_TABLE_OFFSET; if (lseek64(fd, daddr, SEEK_SET) < 0) die("secondary lseek64 failed"); if (read(fd, pt, sizeof(pt)) != sizeof(pt)) die("secondary read pt failed"); if ( read(fd, &boot_sig, sizeof(boot_sig)) != sizeof(boot_sig) || boot_sig != BOOT_SIGNATURE ) die("read second boot signature failed");/* print_pt(i++, pt[0]); */ if (is_extd_part(pt[1].sys_ind)) second=pt[1].start_sect; else base = 0; if (max-- > 0) { *p++ = pt[0]; if (where) *where++ = daddr; i++; } } if (max > 0) { p->sys_ind = 0; if (where) *where = 0; } close(fd); return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -