📄 bsect.c
字号:
"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 + -