📄 bsect.c
字号:
/* bsect.c - Boot sector handling *//*Copyright 1992-1998 Werner Almesberger.Copyright 1999-2002 John Coffman.All rights reserved.Licensed under the terms contained in the file 'COPYING' in the source directory.*/#include <unistd.h>#include <sys/types.h>#include <sys/statfs.h>#include <sys/stat.h>#include <stdio.h>#include <fcntl.h>#include <errno.h>#ifdef _SYS_STATFS_H#define _I386_STATFS_H /* two versions of statfs is not good ... */#endif#include <linux/fs.h>#include <linux/hdreg.h>#include <linux/fd.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include <limits.h>#include <assert.h>#include "config.h"#include "common.h"#include "cfg.h"#include "lilo.h"#include "device.h"#include "geometry.h"#include "map.h"#include "temp.h"#include "partition.h"#include "boot.h"#include "bsect.h"#include "bitmap.h"#include "loader.h"#include "edit.h"#ifdef SHS_PASSWORDS#include "shs2.h"#endif#if defined(LCF_UNIFY) || defined(LCF_BUILTIN)#define EARLY_MAP#endifint boot_dev_nr;static BOOT_SECTOR bsect,bsect_orig;static DESCR_SECTORS descrs;static char secondary_map[SECTOR_SIZE];static unsigned char table[SECTOR_SIZE]; /* keytable & params */static DEVICE dev;static char *boot_devnam,*map_name;static int fd;static int image_base = 0,image = 0;static char temp_map[PATH_MAX+1];static char *fallback[MAX_IMAGES];static int fallbacks = 0;static unsigned short stage_flags;static int image_menu_space = MAX_IMAGES;static char *getval_user;typedef struct Pass { long crc[MAX_PW_CRC]; char *unique; char *label; struct Pass *next; } PASSWORD;static PASSWORD *pwsave = NULL;#ifdef LCF_BUILTINBUILTIN_FILE *select_loader(void){ BUILTIN_FILE *loader = &Third; /* MENU interface is the default */ char *install = cfg_get_strg(cf_options,"install"); char *bitmap = cfg_get_strg(cf_options,"bitmap"); if (!install) { if (bitmap) loader = &Bitmap; } else if (strstr(install,"text")) loader = &Second; /* text interface */ else if (strstr(install,"menu")) loader = &Third; else if (bitmap) loader = &Bitmap; /* menu interface (MDA, EGA, VGA) */ return loader;}#endif/* kludge: 'append="..."' may not contain keywords acted upon by the LILO boot loader -- except "mem=XXX" */#define MEM_OKAY 1static void check_options(char *options){static char *disallow[] = { #if !MEM_OKAY "mem=",#endif "vga=", "kbd=", "lock", "nobd", NULL }; char *here, **dis = disallow; int error = 0; if (verbose >= 5) printf("check_options: \"%s\"\n", options); while (*dis) { here = strstr(options, *dis); if (here) { if (here[3] != '=' && (here[4]==' ' || here[4]==0) ) error=2;#if !MEM_OKAY if (*dis == disallow[0] && here[4]>='0' && here[4]<='9') error = 1 /* + (cfg_get_strg(cf_kernel,"initrd") != NULL || cfg_get_strg(cf_options,"initrd") != NULL) */ ;#endif } if (error>1) die ("APPEND or LITERAL may not contain \"%s\"", *dis);#if !MEM_OKAY if (error==1 && !nowarn) { fprintf(errstd, "Warning: APPEND or LITERAL may not contain \"mem=\"\n"); error = 0; }#endif ++dis; } }static int getval(char **cp, int low, int high, int default_value, int factor){ int temp; if (!**cp) { if (factor && eflag) { if (low==1) default_value--; default_value *= factor; } } else if (ispunct(**cp)) { (*cp)++; if (factor && eflag) { if (low==1) default_value--; default_value *= factor; } } else { temp = strtol(*cp, cp, 0); if (!factor) default_value = temp; else { if (**cp == 'p' || **cp == 'P') { (*cp)++; default_value = temp; temp /= factor; if (low==1) temp++; } else { default_value = (low==1 ? temp-1 : temp)*factor; } } if (temp < low || temp > high) die("%s: value out of range [%d,%d]", getval_user, low, high); if (**cp && !ispunct(**cp)) die("Invalid character: \"%c\"", **cp); if (**cp) (*cp)++; } if (verbose>=5) printf("getval: %d\n", default_value); return default_value;}void bmp_do_timer(char *cp, MENUTABLE *menu){ if (!cp) { if (eflag) menu->t_row = menu->t_col = -1; /* there is none, if not specified during edit */ } else if (strcasecmp(cp,"none")==0) { menu->t_row = menu->t_col = -1; /* there is none, if specified as "none" */ } else { getval_user = "bmp-timer"; menu->t_col = getval(&cp, 1, 76, menu->t_col, 8); menu->t_row = getval(&cp, 1, 30, menu->t_row, 16); if (!*cp && !eflag) return; menu->t_fg = getval(&cp, 0, 15, menu->fg, 0); menu->t_bg = getval(&cp, 0, 15, eflag?15^menu->t_fg:menu->t_bg, 0); menu->t_sh = getval(&cp, 0, 15, menu->t_fg, 0); }}void bmp_do_table(char *cp, MENUTABLE *menu){ if (!cp) { if (eflag) cp = ""; else return; /* dont change anything */ } getval_user = "bmp-table"; menu->col = getval(&cp, 1, 80-MAX_IMAGE_NAME, menu->col/8 + 1, 8); menu->row = getval(&cp, 1, 29, menu->row/16 + 1, 16);#if 0 menu->ncol = getval(&cp, 1, 80/(MAX_IMAGE_NAME+2), 1, 0); menu->maxcol = getval(&cp, 3, MAX_IMAGES, (MAX_IMAGES+menu->ncol-1)/menu->ncol, 0); menu->xpitch = getval(&cp, MAX_IMAGE_NAME+2, 80/menu->ncol, MAX_IMAGE_NAME+6, 8);#else menu->ncol = getval(&cp, 1, 80/(MAX_IMAGE_NAME+1), menu->ncol, 0); menu->maxcol = getval(&cp, 2, 30 - menu->row/16, eflag?30 - menu->row/16:menu->maxcol, 0); menu->xpitch = getval(&cp, MAX_IMAGE_NAME+1, menu->ncol==1?80-menu->col/8:(80-menu->col/8-MAX_IMAGE_NAME*menu->ncol)/(menu->ncol-1)+MAX_IMAGE_NAME, menu->xpitch/8, 8); menu->mincol = getval(&cp, 1, menu->maxcol, menu->mincol, 0);#endif if ((menu->row + menu->maxcol*16 > 480 || menu->col + (MAX_IMAGE_NAME+1)*8 + (menu->ncol-1)*menu->xpitch > 640) && !nowarn) fprintf(errstd,"Warning: 'bmp-table' may spill off screen\n");}void bmp_do_colors(char *cp, MENUTABLE *menu){ if (!cp) { if (eflag) cp = ""; else return; /* dont change anything */ } getval_user = "bmp-colors"; menu->fg = getval(&cp, 0, 15, menu->fg, 0); if (!*cp && !eflag) return; menu->bg = getval(&cp, 0, 15, menu->fg, 0); menu->sh = getval(&cp, 0, 15, menu->fg, 0); menu->h_fg = getval(&cp, 0, 15, menu->h_fg, 0); if (!*cp && !eflag) return; menu->h_bg = getval(&cp, 0, 15, menu->h_fg, 0); menu->h_sh = getval(&cp, 0, 15, menu->h_fg, 0); }void pw_file_update(int passw){ PASSWORD *walk; int i; if (verbose>=4) printf("pw_file_update: passw=%d\n", passw); if (passw && !test && pw_file) { if (fseek(pw_file,0L,SEEK_SET)) perror("pw_file_update"); for (walk=pwsave; walk; walk=walk->next) { fprintf(pw_file, "label=<\"%s\">", walk->label); for (i=0; i<MAX_PW_CRC; i++) fprintf(pw_file, " 0x%08lX", walk->crc[i]); fprintf(pw_file, "\n"); } } if (pw_file) fclose(pw_file);}void pw_fill_cache(void){ char line[MAX_TOKEN+1]; char *brace; char *label; PASSWORD *new; int i; if (verbose>=5) printf("pw_fill_cache\n"); if (fseek(pw_file,0L,SEEK_SET)) perror("pw_fill_cache"); while (fgets(line,MAX_TOKEN,pw_file)) { if (verbose>=5) printf(" %s\n", line); brace = strrchr(line,'>'); label = strchr(line,'<'); if (label && label[1]=='"' && brace && brace[-1]=='"') { brace[-1] = 0; if ( !(new = alloc_t(PASSWORD)) ) pdie("Out of memory"); new->next = pwsave; pwsave = new; new->unique = NULL; new->label = stralloc(label+2); if (verbose>=2) printf("Password file: label=%s\n", new->label); brace++; for (i=0; i<MAX_PW_CRC; i++) { new->crc[i] = strtoul(brace,&label,0); brace = label; } } else die("Ill-formed line in .crc file"); } if (verbose >=5) printf("end pw_fill_cache\n");}static void hash_password(char *password, long crcval[]){#ifdef CRC_PASSWORDS static long poly[] = {CRC_POLY1, CRC_POLY2, CRC_POLY3, CRC_POLY4, CRC_POLY5};#endif long crc; int j; int i = strlen(password); #ifdef SHS_PASSWORDS shsInit(); shsUpdate(password, i); shsFinal();#endif for (j=0; j<MAX_PW_CRC; j++) { crcval[j] = crc =#ifdef CRC_PASSWORDS crc32(password, i, poly[j]); #define PWTYPE "CRC-32"#else shsInfo.digest[j]; #define PWTYPE "SHS-160"#endif if(verbose >= 2) { if (j==0) printf("Password " PWTYPE " ="); printf(" %08lX", crc); } } if (verbose >= 2) printf("\n");}void pw_wipe(char *pass){ int i; if (!pass) return; i = strlen(pass); while (i) pass[--i]=0; free(pass);}char *pw_input(void)#if 1{ char *cp = getpass(""); int i = strlen(cp); char *acp = stralloc(cp); while (i) cp[i--] = 0; return acp; }#else{ char *pass; char buf[MAX_TOKEN+1]; int i, ch; i = 0; fflush(stdout); while((ch=getchar())!='\n') if (i<MAX_TOKEN) buf[i++]=ch; buf[i]=0; pass = stralloc(buf); while (i) buf[--i]=0; return pass;}#endifstatic void pw_get(char *pass, long crcval[], int option){ PASSWORD *walk; char *pass2; char *label; label = cfg_get_strg(cf_all, "label"); if (!label) label = cfg_get_strg(cf_top, "image"); if (!label) label = cfg_get_strg(cf_top, "other"); if (!label) die("Need label to get password"); if ((pass2 = strrchr(pass,'/'))) label = pass2+1; for (walk=pwsave; walk; walk=walk->next) { if (pass == walk->unique || (!walk->unique && !strcmp(walk->label,label) && (walk->unique=pass)) ) { memcpy(crcval, walk->crc, MAX_PW_CRC*sizeof(long)); return; } } walk = alloc_t(PASSWORD); if (!walk) die("Out of memory"); walk->next = pwsave; pwsave = walk; walk->unique = pass; walk->label = stralloc(label); printf("\nEntry for %s used null password\n", label); pass = pass2 = NULL; do { if (pass) { printf(" *** Phrases don't match ***\n"); pw_wipe(pass); pw_wipe(pass2); } printf("Type passphrase: "); pass2 = pw_input(); printf("Please re-enter: "); pass = pw_input(); } while (strcmp(pass,pass2)); printf("\n"); pw_wipe(pass2); hash_password(pass, walk->crc); pw_wipe(pass); memcpy(crcval, walk->crc, MAX_PW_CRC*sizeof(long));}static void retrieve_crc(long crcval[]){ int i; char *pass; if (!pwsave) { if (cfg_pw_open()) pw_fill_cache(); } pass = cfg_get_strg(cf_all,"password"); if (pass) pw_get(pass,crcval,0); else pw_get(cfg_get_strg(cf_options,"password"),crcval,1); if (verbose >= 1) { printf("Password found is"); for (i=0; i<MAX_PW_CRC; i++) printf(" %08lX", crcval[i]); printf("\n"); }}static void open_bsect(char *boot_dev){ struct stat st; if (verbose > 0) printf("Reading boot sector from %s\n",boot_dev ? boot_dev : "current root."); boot_devnam = boot_dev; if (boot_dev) { if ((fd = open(boot_dev,O_RDWR)) < 0) die("open %s: %s",boot_dev,strerror(errno)); if (fstat(fd,&st) < 0) die("stat %s: %s",boot_dev,strerror(errno)); if (!S_ISBLK(st.st_mode)) boot_dev_nr = 0; else boot_dev_nr = st.st_rdev; } else { if (stat("/",&st) < 0) pdie("stat /");#if 0 if ((st.st_dev & PART_MASK) > PART_MAX)#else if (MAJOR(st.st_dev) != MAJOR_MD && (st.st_dev & P_MASK(st.st_dev)) > PART_MAX)#endif die("Can't put the boot sector on logical partition 0x%04X", (int)st.st_dev); fd = dev_open(&dev,boot_dev_nr = st.st_dev,O_RDWR); } if (boot_dev_nr && !is_first(boot_dev_nr) && !nowarn) fprintf(errstd,"Warning: %s is not on the first disk\n",boot_dev ? boot_dev : "current root"); if (read(fd,(char *) &bsect,SECTOR_SIZE) != SECTOR_SIZE) die("read %s: %s",boot_dev ? boot_dev : dev.name,strerror(errno)); bsect_orig = bsect; ireloc = part_nowrite(boot_dev);}void bsect_read(char *boot_dev,BOOT_SECTOR *buffer){ open_bsect(boot_dev); *buffer = bsect; (void) close(fd);}static void menu_do_scheme(char *scheme, MENUTABLE *menu){ static char khar[] = "kbgcrmywKBGCRMYW"; unsigned int fg, bg; int i; unsigned char *at; /* order of color attributes is:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -