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

📄 bsect.c

📁 linux 的引导程序源码The Microsoft&reg Windows&reg Software Development Kit (SDK) provides the documentation
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 + -