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

📄 bsect.c

📁 linux 的引导程序源码The Microsoft&reg Windows&reg Software Development Kit (SDK) provides the documentation
💻 C
📖 第 1 页 / 共 3 页
字号:
      "read-write")) || (cfg_get_flag(cf_options,"read-only") && cfg_get_flag(      cf_options,"read-write")))	die("Conflicting READONLY and READ_WRITE settings.");    if (cfg_get_flag(cf_kernel,"read-only") || cfg_get_flag(cf_options,      "read-only")) strcat(options,"ro ");    if (cfg_get_flag(cf_kernel,"read-write") || cfg_get_flag(cf_options,      "read-write")) strcat(options,"rw ");    if ((root = cfg_get_strg(cf_kernel,"root")) || (root = cfg_get_strg(      cf_options,"root")))  {	if (strcasecmp(root,"current")) 	    sprintf(strchr(options,0),"root=%x ",dev_number(root));	else {	    if (stat("/",&st) < 0) pdie("stat /");	    sprintf(strchr(options,0),"root=%x ",(unsigned int) st.st_dev);	}      }	    if ((ram_disk = cfg_get_strg(cf_kernel,"ramdisk")) || (ram_disk =      cfg_get_strg(cf_options,"ramdisk")))	sprintf(strchr(options,0),"ramdisk=%d ",to_number(ram_disk));    if ((vga = cfg_get_strg(cf_kernel,"vga")) || (vga = cfg_get_strg(cf_options,      "vga"))) {#ifndef NORMAL_VGA	if (!nowarn)	    fprintf(errstd,"Warning: VGA mode presetting is not supported; ignoring 'vga='\n");#else	descr->flags |= FLAG_VGA;	     if (!strcasecmp(vga,"normal")) descr->vga_mode = NORMAL_VGA;	else if (!strcasecmp(vga,"ext") || !strcasecmp(vga,"extended"))		descr->vga_mode = EXTENDED_VGA;	else if (!strcasecmp(vga,"ask")) descr->vga_mode = ASK_VGA;	else descr->vga_mode = to_number(vga);#endif    }#ifdef LCF_BOOT_FILE    if ((append = cfg_get_strg(cf_top, "image"))) {	strcat(options, "BOOT_FILE=");	strcat(options, append);	strcat(options, " ");    }#endif    if ((append = cfg_get_strg(cf_kernel,"append")) || (append =      cfg_get_strg(cf_options,"append"))) strcat(options,append);} /* end of section specific to 'image=' */    literal = cfg_get_strg(cf_kernel,"literal");    if (literal) strcpy(options,literal);    if (*options) {	here = strchr(options,0);	if (here[-1] == ' ') here[-1] = 0;    }    check_options(options);    if (cfg_get_flag(cf_kernel,"lock") || cfg_get_flag(cf_options,"lock")) {#ifdef LCF_READONLY	die("This LILO is compiled READONLY and doesn't support the LOCK "	  "option");#else	descr->flags |= FLAG_LOCK;#endif    }    if ((cfg_get_flag(cf_options,"restricted") &&              cfg_get_flag(cf_options,"mandatory")) ||        (cfg_get_flag(cf_all,"restricted") &&              cfg_get_flag(cf_all,"mandatory")))         die("MANDATORY and RESTRICTED are mutually exclusive");    if (cfg_get_flag(cf_all,"bypass")) {        if (cfg_get_flag(cf_all,"mandatory"))             die("MANDATORY and BYPASS are mutually exclusive");        if (cfg_get_flag(cf_all,"restricted"))             die("RESTRICTED and BYPASS are mutually exclusive");        if (!cfg_get_strg(cf_options,"password"))             die("BYPASS only valid if global PASSWORD is set");    }    if ((password = cfg_get_strg(cf_all,"password")) && cfg_get_flag(cf_all,"bypass"))        die("PASSWORD and BYPASS not valid together");    if (password ||         ( (password = cfg_get_strg(cf_options,"password")) &&          !cfg_get_flag(cf_all,"bypass")  ) ) {	if (!*password) {	/* null password triggers interaction */	    retrieve_crc((long*)descr->password_crc);	} else {	    hash_password(password, (long*)descr->password_crc );	}	descr->flags |= FLAG_PASSWORD;    }#ifdef LCF_VIRTUAL    if (cfg_get_flag(cf_all,"vmwarn")) descr->flags |= FLAG_VMWARN;    if (cfg_get_flag(cf_all,"vmdisable")) descr->flags |= FLAG_VMDISABLE;    if ( (descr->flags & FLAG_VMWARN) && (descr->flags & FLAG_VMDISABLE) )	die ("VMWARN and VMDISABLE are not valid together");#endif#if 1    if (cfg_get_flag(cf_all,"mandatory") || cfg_get_flag(cf_options,      "mandatory")) {	if (!password) die("MANDATORY is only valid if PASSWORD is set.");    }    if (cfg_get_flag(cf_all,"restricted") || cfg_get_flag(cf_options,      "restricted")) {	if (!password) die("RESTRICTED is only valid if PASSWORD is set.");	if ((descr->flags & FLAG_PASSWORD) && !cfg_get_flag(cf_all,"mandatory"))	    descr->flags |= FLAG_RESTR;    }    if (password && *password && config_read) {	fprintf(errstd,"Warning: %s should be readable only "	  "for root if using PASSWORD\n",config_file);	config_read = 0;	/* suppress further warnings */    }#else    if (cfg_get_flag(cf_all,"restricted") || cfg_get_flag(cf_options,      "restricted")) {	if (!password) die("RESTRICTED is only valid if PASSWORD is set.");	descr->flags |= FLAG_RESTR;    }#endif    if (cfg_get_flag(cf_all,"single-key") ||      cfg_get_flag(cf_options,"single-key")) descr->flags |= FLAG_SINGLE;    fback = cfg_get_strg(cf_kernel,"fallback");    if (fback) {#ifdef LCF_READONLY	die("This LILO is compiled READONLY and doesn't support the FALLBACK "	  "option");#else	if (descr->flags & FLAG_LOCK)	    die("LOCK and FALLBACK are mutually exclusive");	else descr->flags |= FLAG_FALLBACK;	*(unsigned short *) fallback_buf = DC_MAGIC;	strcpy(fallback_buf+2,fback);	fallback[fallbacks++] = stralloc(fback);#endif    }#if 0#if 1    *(unsigned long *) descr->rd_size = 0; /* no RAM disk */#else    descr->rd_size = 0; /* no RAM disk */#endif    descr->start_page = 0; /* load low */#endif    map_begin_section();    map_add_sector(fallback_buf);    map_add_sector(options);}static void bsect_done(char *name,IMAGE_DESCR *descr){    char *alias;    int this_image,this;    if (!*name) die("Invalid image name.");    alias = cfg_get_strg(cf_all,"alias");    this = alias ? get_image(NULL,alias,descr) : -1;    this_image = get_image(name,cfg_get_strg(cf_all,"label"),descr);    if ((descr->flags & FLAG_SINGLE) &&      strlen(descrs.d.descr[this_image].name) > 1 &&      (!alias || strlen(alias) > 1))	die("SINGLE-KEYSTROKE requires the label or the alias to be only "	  "a single character");    if (verbose >= 0) {	printf("Added %s",descrs.d.descr[this_image].name);	if (alias) printf(" (alias %s)",alias);#ifdef LCF_VIRTUAL	if (descrs.d.descr[this_image].flags & FLAG_VMDEFAULT ||		(this>=0 && (descrs.d.descr[this].flags & FLAG_VMDEFAULT)) )	    printf(" @");#endif	if (this_image && this) putchar('\n');	else printf(" *\n");    }    if (verbose >= 3) {	printf("%4s<dev=0x%02x,hd=%d,cyl=%d,sct=%d>\n","",	  descr->start.device,descr->start.head,descr->start.track,	  descr->start.sector);	if (*options) printf("%4s\"%s\"\n","",options);    }    if (verbose >= 1) putchar('\n');   /* makes for nicer spacing */}int bsect_number(void){    return image_base ? 0 : image;}static void unbootable(void){    fflush(stdout);    fprintf(errstd,"\nWARNING: The system is unbootable !\n");    fprintf(errstd,"%9sRun LILO again to correct this.","");}void check_fallback(void){    char *start,*end;    int i,image;    for (i = 0; i < fallbacks; i++) {	for (start = fallback[i]; *start && *start == ' '; start++);	if (*start) {	    for (end = start; *end && *end != ' '; end++);	    if (*end) *end = 0;	    for (image = 0; image < MAX_IMAGES; image++)#ifdef LCF_IGNORECASE		if (!strcasecmp(descrs.d.descr[image].name,start)) break;#else		if (!strcmp(descrs.d.descr[image].name,start)) break;#endif	    if (image == MAX_IMAGES) die("No image \"%s\" is defined",start);	}    }}void bsect_update(char *backup_file, int force_backup, int pass){    struct stat st;    char temp_name[PATH_MAX+1];    int bck_file;    BOOT_SECTOR bsect_wr;    if (!backup_file) {	sprintf(temp_name, BACKUP_DIR "/boot.%04X", boot_dev_nr);	backup_file = temp_name;    }    bck_file = open(backup_file, O_RDONLY);    if (bck_file >= 0 && force_backup) {	(void) close(bck_file);	bck_file = -1;    }    if (bck_file >= 0) {	if (verbose > 0)	    printf("%s exists - no backup copy made.\n",backup_file);    }    else {	if ((bck_file = creat(backup_file, 0644)) < 0)	    die("creat %s: %s",backup_file, strerror(errno));	if (write(bck_file, (char *)&bsect_orig, SECTOR_SIZE) != SECTOR_SIZE)	    die("write %s: %s", backup_file, strerror(errno));	if (verbose > 0)	    printf("Backup copy of boot sector in %s\n", backup_file);	if (fstat(bck_file, &st) < 0)	    die("fstat %s: %s",backup_file,strerror(errno));	bsect.par_1.timestamp = st.st_mtime;    }    if (close(bck_file) < 0) die("close %s: %s",backup_file,strerror(errno));    if (pass==0) {	MENUTABLE *menu = (void*)&table[256];#if 0		map_begin_section();	map_add_sector(secondary_map);	(void) map_write(&bsect.par_1.secondary,1,0);#endif/*	map_descrs(&descrs, bsect.par_1.descr, &bsect.par_1.dflcmd);  */	map_descrs(&descrs, menu->mt_descr, &bsect.par_1.dflcmd);	((long*)table)[SECTOR_SIZE/sizeof(long)-2] = crc32(table, SECTOR_SIZE-2*sizeof(long), CRC_POLY1);	map_begin_section();	map_add_sector(table);	(void) map_write(&bsect.par_1.keytab,1,0);	map_close();    }    if (lseek(fd,0,0) < 0)	die("lseek %s: %s",boot_devnam ? boot_devnam : dev.name,	  strerror(errno));    if (verbose > 0) printf("Writing boot sector.\n");#if 1/*    if ( MAJOR(boot_dev_nr)==MAJOR_FD  && */    if (ireloc &&    	  bsect.par_1.cli == 0xFA#if 0    	  	  &&  bsect.par_1.call_ins == 0xE8#endif    	 						 ) {/* perform the relocation of the boot sector */	int len = bsect.par_1.code_length;	int space = BOOT_SIG_OFFSET - len;	space &= 0xFFF0;	/* roll back to paragraph boundary */        bsect_wr = bsect_orig;	memcpy(&bsect_wr.sector[space], &bsect, len);	if (space <= 0x80) {	    bsect_wr.sector[0] = 0xEB;		/* jmp short */	    bsect_wr.sector[1] = space - 2;	    bsect_wr.sector[2] = 0x90;		/* nop */	} else {	    bsect_wr.sector[0] = 0xE9;		/* jmp near */	    *(short*)&bsect_wr.sector[1] = space - 3;	}/***	bsect = bsect_orig;  ***/	if (verbose >= 1) printf("Boot sector relocation performed\n");    }    else bsect_wr = bsect;#endif    	 /* failsafe check */#if 1    if (verbose >= 3) printf("Failsafe check:  boot_dev_nr = 0x%04x 0x%04x\n", boot_dev_nr, has_partitions(boot_dev_nr));#endif    if (      has_partitions(boot_dev_nr) &&      (P_MASK(boot_dev_nr)&boot_dev_nr)==0 &&      memcmp(bsect.sector+MAX_BOOT_SIZE, bsect_wr.sector+MAX_BOOT_SIZE, 64+8)      )    	die("LILO internal error:  Would overwrite Partition Table"); /* failsafe check */    	    if (write(fd, (char *)&bsect_wr, SECTOR_SIZE) != SECTOR_SIZE)	die("write %s: %s",boot_devnam ? boot_devnam : dev.name,	  strerror(errno));    if (!boot_devnam) dev_close(&dev);    else if (close(fd) < 0) {	    unbootable();	    die("close %s: %s",boot_devnam,strerror(errno));	}    if (pass==0) {	pw_file_update(passw);	temp_unregister(temp_map);	if (rename(temp_map,map_name) < 0) {	    unbootable();	    die("rename %s %s: %s",temp_map,map_name,strerror(errno));	}    }    (void) sync();}void bsect_cancel(void){#if 0    map_descrs(&descrs, bsect.par_1.descr, &bsect.par_1.dflcmd);#endif    map_close();    if (boot_devnam) (void) close(fd);    else dev_close(&dev);    temp_unregister(temp_map);    if (verbose<9) (void) remove(temp_map);}static int present(char *var){    char *path;    if (!(path = cfg_get_strg(cf_top,var))) die("No variable \"%s\"",var);    if (!access(path,F_OK)) return 1;    if (!cfg_get_flag(cf_all,"optional") && !cfg_get_flag(cf_options,      "optional")) return 1;    if (verbose >= 0) printf("Skipping %s\n",path);    return 0;}static int initrd_present(void){    char *path;    path = cfg_get_strg(cf_kernel, "initrd");    if (!path) path = cfg_get_strg(cf_options, "initrd");    if (!path) return 1;    if (!access(path,F_OK)) return 1;    if (!cfg_get_flag(cf_all,"optional") && !cfg_get_flag(cf_options,      "optional")) return 1;    if (verbose >= 0) printf("Skipping %s\n", cfg_get_strg(cf_top, "image"));    return 0;}void do_image(void){    IMAGE_DESCR descr;    char *name;/*    memset(&descr, 0, sizeof(descr));  	Done in "bsect_common" */    cfg_init(cf_image);    (void) cfg_parse(cf_image);    if (present("image") && initrd_present()) {	bsect_common(&descr, 1);	descr.flags |= FLAG_KERNEL;	name = cfg_get_strg(cf_top,"image");	if (!cfg_get_strg(cf_image,"range")) boot_image(name,&descr);	else boot_device(name,cfg_get_strg(cf_image,"range"),&descr);	bsect_done(name,&descr);    }    cfg_init(cf_top);}void do_other(void){    IMAGE_DESCR descr;    char *name, *loader;/*    memset(&descr, 0, sizeof(descr));  	Done in "bsect_common" */    cfg_init(cf_other);    cfg_init(cf_kernel); /* clear kernel parameters */    curr_drv_map = curr_prt_map = 0;    (void) cfg_parse(cf_other);    if (present("other")) {	bsect_common(&descr, 0);	name = cfg_get_strg(cf_top,"other");	loader = cfg_get_strg(cf_other,"loader");	if (!loader) loader = cfg_get_strg(cf_options,"loader");	boot_other(loader,name,cfg_get_strg(cf_other,"table"),&descr);	bsect_done(name,&descr);    }    cfg_init(cf_top);}void bsect_uninstall(char *boot_dev,char *backup_file,int validate){    struct stat st;    char temp_name[PATH_MAX+1];    int bck_file;    open_bsect(boot_dev);    if (*(unsigned short *) &bsect.sector[BOOT_SIG_OFFSET] != BOOT_SIGNATURE)	die("Boot sector of %s does not have a boot signature",boot_dev ?	  boot_dev : dev.name);    if (!strncmp(bsect.par_1.signature-4,"LILO",4))	die("Boot sector of %s has a pre-21 LILO signature",boot_dev ?	  boot_dev : dev.name);    if (strncmp(bsect.par_1.signature,"LILO",4))	die("Boot sector of %s doesn't have a LILO signature",boot_dev ?	  boot_dev : dev.name);    if (!backup_file) {	sprintf(temp_name,BACKUP_DIR "/boot.%04X",boot_dev_nr);	backup_file = temp_name;    }    if ((bck_file = open(backup_file,O_RDONLY)) < 0)	die("open %s: %s",backup_file,strerror(errno));    if (fstat(bck_file,&st) < 0)	die("fstat %s: %s",backup_file,strerror(errno));    if (validate && st.st_mtime != bsect.par_1.timestamp)	die("Timestamp in boot sector of %s differs from date of %s\n"	  "Try using the -U option if you know what you're doing.",boot_dev ?	  boot_dev : dev.name,backup_file);    if (verbose > 0) printf("Reading old boot sector.\n");    if (read(bck_file,(char *) &bsect,PART_TABLE_OFFSET) != PART_TABLE_OFFSET)	die("read %s: %s",backup_file,strerror(errno));    if (lseek(fd,0,0) < 0)	die("lseek %s: %s",boot_dev ? boot_dev : dev.name,strerror(errno));    if (verbose > 0) printf("Restoring old boot sector.\n");    if (write(fd,(char *) &bsect,PART_TABLE_OFFSET) != PART_TABLE_OFFSET)	die("write %s: %s",boot_dev ? boot_dev : dev.name,strerror(errno));    if (!boot_devnam) dev_close(&dev);    else if (close(fd) < 0) {	    unbootable();	    die("close %s: %s",boot_devnam,strerror(errno));	}    exit(0);}void bsect_raid_update(char *boot_dev, unsigned long raid_offset, 	char *backup_file, int force_backup, int pass){    BOOT_SECTOR bsect_save;    if (pass > 0) {    	bsect_save = bsect;			/* save the generated boot sector */        open_bsect(boot_dev);        memcpy(&bsect, &bsect_save, MAX_BOOT_SIZE);	/* update the subject boot sector */        bsect.par_1.raid_offset = raid_offset;	/* put in the new partition offset */        bsect.par_1.prompt &= FLAG_SAVE;	/* clear all RAID flags */        bsect.par_1.prompt |= raid_flags;	/* update the raid flags */        *(unsigned short *) &bsect.sector[BOOT_SIG_OFFSET] = BOOT_SIGNATURE;    }    bsect_update(backup_file, force_backup, pass);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -