⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 partition.c

📁 LINUX lilo-22.7 源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
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 + -