Пример #1
0
int main(int argc,char **argv)
{
    char *name,*config_file,*reboot_arg,*identify,*ident_opt,*new_root;
    char *uninst_dev;
    int query,more,version,uninstall,validate,do_md_install,pass;
    BOOT_SECTOR dummy;
    IMAGE_DESCR dummy2;
    struct stat st;
    int fd, md_fd;
    md_array_info_t md_array_info;
    md_disk_info_t md_disk_info;
    char md_boot_name[MAX_TOKEN+1];
    char md_boot_map[MAX_TOKEN+1];
    DT_ENTRY md_disk;
    DT_ENTRY *disk;

    config_file = DFL_CONFIG;
    reboot_arg = identify = ident_opt = new_root = uninst_dev = NULL;
    pass = do_md_install = query = version = uninstall = validate = 0;
    name = *argv++;
    argc--;
    cfg_init(cf_options);
    while (argc && **argv == '-') {
	argc--;
	if (argv[0][2]) usage(name);
	switch ((*argv++)[1]) {
	    case 'b':
		if (!argc) usage(name);
		cfg_set(cf_options,"boot",*argv++,NULL);
		argc--;
		break;
	    case 'c':
		cfg_set(cf_options,"compact",NULL,NULL);
		compact = 1;
		break;
	    case 'd':
		if (!argc) usage(name);
		cfg_set(cf_options,"delay",*argv++,NULL);
		argc--;
		break;
	    case 'D':
		if (!argc) usage(name);
		cfg_set(cf_options,"default",*argv++,NULL);
		argc--;
		break;
	    case 'f':
		if (!argc) usage(name);
		cfg_set(cf_options,"disktab",*argv++,NULL);
		argc--;
		break;
	    case 'l':
		cfg_set(cf_options,"linear",NULL,NULL);
		linear = 1;
		break;
	    case 'm':
		if (!argc) usage(name);
		cfg_set(cf_options,"map",*argv++,NULL);
		argc--;
		break;
	    case 'i':
		if (!argc) usage(name);
		cfg_set(cf_options,"install",*argv++,NULL);
		argc--;
		break;
	    case 'I':
		if (!argc) usage(name);
		identify = *argv++;
		if (--argc) {
		    ident_opt = *argv++;
		    argc--;
		}
		break;
	    case 'X':
		printf("-DIMAGES=%d -DCODE_START_1=%d -DCODE_START_2=%d "
		  "-DDESCR_SIZE=%d -DDSC_OFF=%d -DDSC_OFF2=%d -DDFCMD_OFF=%d "
		  "-DMSG_OFF=%d -DFLAGS_OFF=%d\n",MAX_IMAGES,
		  sizeof(BOOT_PARAMS_1),sizeof(BOOT_PARAMS_2),
		  sizeof(IMAGE_DESCR),
		  (void *) &dummy.par_1.descr[0]-(void *) &dummy,
		  (void *) &dummy.par_1.descr[1]-(void *) &dummy,
		  (void *) &dummy.par_1.descr[2]-(void *) &dummy,
		  (void *) &dummy.par_1.msg_len-(void *) &dummy,
		  (void *) &dummy2.flags-(void *) &dummy2);
		exit(0);
	    case 'C':
		if (!argc) usage(name);
		config_file = *argv++;
		argc--;
		break;
	    case 'S':
		if (!argc) usage(name);
		cfg_set(cf_options,"force-backup",*argv++,NULL);
		argc--;
		break;
	    case 's':
		if (!argc) usage(name);
		cfg_set(cf_options,"backup",*argv++,NULL);
		argc--;
		break;
	    case 'P':
		if (!argc) usage(name);
		if (!strcmp(*argv,"fix"))
		    cfg_set(cf_options,"fix-table",NULL,NULL);
		else if (!strcmp(*argv,"ignore"))
			cfg_set(cf_options,"ignore-table",NULL,NULL);
		    else usage(name);
		argv++;
		argc--;
		break;
	    case 'q':
		query = 1;
		break;
	    case 'r':
		if (!argc) usage(name);
		new_root = *argv++;
		argc--;
		break;
	    case 'R':
		if (!argc) reboot_arg = "";
		else while (argc) {
			if (!reboot_arg)
			    *(reboot_arg = alloc(strlen(*argv)+1)) = 0;
			else strcat(reboot_arg = ralloc(reboot_arg,
			      strlen(reboot_arg)+strlen(*argv)+2)," ");
			strcat(reboot_arg,*argv++);
			argc--;
		    }
		break;
	    case 't':
		test = 1;
		break;
	    case 'u':
		validate = 1;
		/* fall through */
	    case 'U':
		uninstall = 1;
		if (argc) {
		    if (argc-- > 1) usage(name);
		    uninst_dev = *argv;
		}
		break;
	    case 'v':
		verbose++;
		break;
	    case 'V':
		version = 1;
		break;
	    case 'w':
		cfg_set(cf_options,"nowarn",NULL,NULL);
		nowarn = 1;
		break;
	    default:
		usage(name);
	}
    }
    if (!new_root) new_root = getenv("ROOT");
    if (new_root && *new_root) {
	if (chroot(new_root) < 0) die("chroot %s: %s",new_root,strerror(errno));
	if (chdir("/") < 0) die("chdir /: %s",strerror(errno));
    }
    if (atexit(temp_remove)) die("atexit() failed");
    if (verbose > 0 || version) {
	printf("LILO version 21%s",version ? "\n" : "");
	if (version) return 0;
	printf(", Copyright 1992-1998 Werner Almesberger\n\n");
    }
#if 0
    if (((install || test || boot_device || disktab_file || compact) && !argc)
      || (compact && linear && 0)) usage(name);
#endif
    if (!nowarn && compact && linear)
	fprintf(stderr,"Warning: COMPACT may conflict with LINEAR on some "
	  "systems\n");
    preload_types();
    fd = cfg_open(config_file);
    more = cfg_parse(cf_options);
    if (!nowarn) {
	if (fstat(fd,&st) < 0) {
	    fprintf(stderr,"fstat %s: %s\n",config_file,strerror(errno));
	    exit(1);
	}
	if (S_ISREG(st.st_mode)) {
	    if (st.st_uid)
		fprintf(stderr,"Warning: %s should be owned by root\n",
		  config_file);
	    else if (st.st_mode & (S_IWGRP | S_IWOTH))
		    fprintf(stderr,"Warning: %s should be writable only for "
		      "root\n",config_file);
		else if ((cfg_get_strg(cf_all,"password") || cfg_get_strg(
		      cf_options,"password")) && (st.st_mode & (S_IRGRP |
		      S_IROTH)))
			fprintf(stderr,"Warning: %s should be readable only "
			  "for root if using PASSWORD\n",config_file);
	}
    }
    preload_dev_cache();
    if (identify) identify_image(identify,ident_opt);
    if (strncmp("/dev/md",cfg_get_strg(cf_options,"boot"),7) == 0) {
	if ((md_fd=open(cfg_get_strg(cf_options,"boot"),O_NOACCESS)) < 0)
	    die("Unable to open %s",cfg_get_strg(cf_options,"boot"));
	if (fstat(md_fd,&st) < 0)
	    die("Unable to stat %s",cfg_get_strg(cf_options,"boot"));
	if (!S_ISBLK(st.st_mode))
	    die("%s is not a block device",cfg_get_strg(cf_options,"boot"));
	if (ioctl(md_fd,GET_ARRAY_INFO,&md_array_info) < 0)
	    die("Unable to get RAID info on %s",cfg_get_strg(cf_options,"boot"));
	if ((md_array_info.major_version == 0) && (md_array_info.minor_version < 90))
	    die("Raid versions < 0.90 are not supported");
	if (md_array_info.level != 1)
	    die("Only RAID1 devices are supported as boot devices");
	do_md_install = 1;
	strcpy(md_boot_name,cfg_get_strg(cf_options,"boot"));
	if (cfg_get_strg(cf_options,"map"))
	    strcpy(md_boot_map,cfg_get_strg(cf_options,"map"));
	else
	    strcpy(md_boot_map,MAP_FILE);
	md_disk.device = (MD_MAJOR << 8) | md_array_info.md_minor;
	md_disk.bios = 0x80;
	md_disk.next = disktab;
	disktab = &md_disk;
    }
    while( (pass == 0) || (do_md_install && (pass < md_array_info.nr_disks)) ) {
	if(do_md_install) {
	    GEOMETRY geo;
	    DEVICE dev;
	    int device,disk_fd;
	    char new_name[MAX_TOKEN+1];

	    if(pass > 0) {
		close(fd);
		cfg_init(cf_options);
		fd = cfg_open(config_file);
		more = cfg_parse(cf_options);
	    }
	    md_disk_info.number = pass;
	    if (ioctl(md_fd,GET_DISK_INFO,&md_disk_info) < 0)
		die("main: GET_DISK_INFO: %s", strerror(errno));
	    device = (md_disk_info.major << 8) | md_disk_info.minor;
	    disk_fd = dev_open(&dev,device,O_NOACCESS);
	    if (md_disk_info.state == MD_DISK_FAULTY) {
		printf("disk %s marked as faulty, skipping\n",dev.name);
		pass++;
		continue;
	    }
	    geo_query_dev(&geo,device,1);
	    disk = alloc_t(DT_ENTRY);
	    disk->bios = 0x80;
	    disk->device = device & 0xfff0;
	    disk->sectors = geo.sectors;
	    disk->heads = geo.heads;
	    disk->cylinders = geo.cylinders;
	    disk->start = geo.start;
	    disk->next = disktab;
	    disktab = disk;
	    if (cfg_get_strg(cf_options,"boot")) cfg_unset(cf_options,"boot");
	    if (cfg_get_strg(cf_options,"map")) cfg_unset(cf_options,"map");
	    strncpy(new_name,dev.name,8);
	    new_name[8] = '\0';
	    cfg_set(cf_options,"boot",new_name,NULL);
	    snprintf(new_name,MAX_TOKEN,"%s.%04x",md_boot_map,device);
	    cfg_set(cf_options,"map",new_name,NULL);
	    printf("boot = %s, map = %s\n", cfg_get_strg(cf_options,"boot"),
		cfg_get_strg(cf_options,"map"));
	    md_disk.sectors = geo.sectors;
	    md_disk.heads = geo.heads;
	    md_disk.cylinders = geo.cylinders;
	    md_disk.start = geo.start;
	}
	    
	pass++;
	if (uninstall)
	    bsect_uninstall(uninst_dev ? uninst_dev : cfg_get_strg(cf_options,
	      "boot"),cfg_get_strg(cf_options,"backup"),validate);
	compact = cfg_get_flag(cf_options,"compact");
	linear = cfg_get_flag(cf_options,"linear");
	nowarn = cfg_get_flag(cf_options,"nowarn");
	if (cfg_get_strg(cf_options,"verbose"))
	    verbose += to_number(cfg_get_strg(cf_options,"verbose"));
	if (reboot_arg) {
	    map_patch_first(cfg_get_strg(cf_options,"map") ? cfg_get_strg(
	      cf_options,"map") : MAP_FILE,reboot_arg);
	    exit(0);
	}
	if (argc) usage(name);
	geo_init(cfg_get_strg(cf_options,"disktab"));
	if (query)
	    show_images(!cfg_get_strg(cf_options,"map") ? MAP_FILE :
	      cfg_get_strg(cf_options,"map"));
	bsect_open(cfg_get_strg(cf_options,"boot"),cfg_get_strg(cf_options,"map") ?
	  cfg_get_strg(cf_options,"map") : MAP_FILE,cfg_get_strg(cf_options,
	  "install"),cfg_get_strg(cf_options,"delay") ? to_number(cfg_get_strg(
	  cf_options,"delay")) : 0,cfg_get_strg(cf_options,"timeout") ?
	  to_number(cfg_get_strg(cf_options,"timeout")) : -1);
	if (more) {
            cfg_init(cf_top);
            if (cfg_parse(cf_top)) cfg_error("Syntax error");
	}
	if (!bsect_number()) die("No images have been defined.");
	check_fallback();
	if (!test)
	    if (cfg_get_strg(cf_options,"force-backup"))
		bsect_update(cfg_get_strg(cf_options,"force-backup"),1);
	    else bsect_update(cfg_get_strg(cf_options,"backup"),0);
	else {
	    bsect_cancel();
	    fprintf(stderr,"The boot sector and the map file have *NOT* been "
	      "altered.\n");
	}
    }
    return 0;
}
Пример #2
0
	int main(int argc,char **argv)
	{
		char *name,*reboot_arg,*ident_opt,*new_root;
		char *tell_param, *uninst_dev, *param, *act1, *act2, ch;
		static char *bitmap_file;
		int more,version,uninstall,validate,activate,instmbr,geom;
		int fd, temp=0, tell_early=0;
		int raid_offset;
#if !__MSDOS__
		struct stat st;
#endif /* !__MSDOS__ */

		errstd = stderr;
#if VERSION_MINOR>=50
		if (sizeof(MENUTABLE)!=256) die("MENUTABLE is not 256 bytes (common.h)");
#if !__MSDOS__
		cfg_alpha_check();
#endif /* !__MSDOS__ */
#endif
		config_file = DFL_CONFIG;
		act1 = act2 = tell_param = 
			reboot_arg = identify = ident_opt = new_root = uninst_dev = NULL;
		do_md_install = zflag =
			version = uninstall = validate = activate = instmbr = 0;
		verbose = -1;
#if !__MSDOS__
		name = *argv;
#else  /* __MSDOS__ */
		name = "lilo";
#endif /* __MSDOS__ */
		argc--;

#if !__MSDOS__    
		if (atexit( (void(*)(void)) sync)) die("atexit(sync)");
		if (atexit( (void(*)(void)) purge)) die("atexit(purge)");
#endif /* !__MSDOS__ */

		cfg_init(cf_options);
		while (argc && **++argv == '-') {
			argc--;
			/* first those options with a mandatory parameter */
			/* Notably absent are "RuUvw" */
			if (strchr("AbBCdDEfiImMPrsSTxZ", ch=(*argv)[1])) {
				if ((*argv)[2]) param = (*argv)+2;
				else {
					param = *++argv;
					if(argc-- <= 0) usage(name);
				}
			} else { 
				param = NULL;
				if (strchr("cFglLpqtVXz", ch)	/* those with no args */
						&& (*argv)[2]) usage(name);
			}
#if 0
			fprintf(errstd,"argc=%d, *argv=%s, ch=%c param=%s\n", argc, *argv, ch, param);
#endif
			switch (ch) {
#if !__MSDOS__
				case 'A':
					activate = 1;
					act1 = param;
					if (argc && argv[1][0] != '-') {
						act2 = *++argv;
						argc--;
					}
					break;
				case 'b':
					cfg_set(cf_options,"boot",param,NULL);
					break;
				case 'B':
					cfg_set(cf_options,"bitmap",param,NULL);
					break;
				case 'c':
					cfg_set(cf_options,"compact",NULL,NULL);
					compact = 1;
					break;
#endif /* !__MSDOS */
				case 'C':
					config_file = param;
					break;
#if !__MSDOS__
				case 'd':
					cfg_set(cf_options,"delay",param,NULL);
					break;
				case 'D':
					cfg_set(cf_options,"default",param,NULL);
					break;
				case 'E':
					eflag=1;
					bitmap_file = param;
					break;
				case 'f':
					cfg_set(cf_options,"disktab",param,NULL);
					break;
				case 'F':
					force_fs=1;
					break;
				case 'g':
					geometric |= AD_GEOMETRIC;
					break;
				case 'H':
					force_raid=1;
					break;
				case 'i':
					cfg_set(cf_options,"install",param,NULL);
					break;
				case 'I':
					identify = param;
					if (argc && *argv[1] != '-') {
						ident_opt = *++argv;
						argc--;
					} else {
						ident_opt = "i";
					}
					break;
				case 'l':
					geometric |= AD_LINEAR;
					break;
				case 'L':
					geometric |= AD_LBA32;
					break;
#endif /* !__MSDOS__ */
				case 'm':
					cfg_set(cf_options,"map",param,NULL);
					break;
#if !__MSDOS__
				case 'M':
					instmbr = 1;
					act1 = param;
#if !defined LCF_BUILTIN	|| 1
					if (argc && argv[1][0] != '-') {
						act2 = *++argv;
						argc--;
					}
#endif
					break;
				case 'p':
					passw = 1;	/* force re-gen of password file */
					break;
				case 'P':
					if ((act1=strchr(param,'='))) {
						*act1++ = 0;	/* null terminate */
						cfg_set(cf_options,param,act1,NULL);
					}
					else if (!strcasecmp(param,"fix"))
						cfg_set(cf_options,"fix-table",NULL,NULL);
					else if (!strcasecmp(param,"ignore"))
						cfg_set(cf_options,"ignore-table",NULL,NULL);
					else if (!strcasecmp(param,"x"))
						extended_pt = 1;
					else
						cfg_set(cf_options,param,NULL,NULL);
					break;
#endif /* !__MSDOS__ */
				case 'q':
					query = 1;
					break;
#if !__MSDOS__
				case 'r':
					new_root = param;
					break;
#endif /* !__MSDOS__ */
				case 'R':
					if (*(param = (*argv)+2)) argc++;
					else if (argc) param = *++argv;
					else reboot_arg = "";

					while (argc) {
						if (!reboot_arg)
							*(reboot_arg = alloc(strlen(param)+1)) = 0;
						else {
							param = *++argv;
							strcat(reboot_arg = ralloc(reboot_arg,
										strlen(reboot_arg)+strlen(param)+2)," ");
						}
						strcat(reboot_arg, param);
						argc--;
					}
#if 0
					fprintf(errstd,"REBOOT=\"%s\"\n", reboot_arg);		    
#endif
					break;
#if !__MSDOS__
				case 's':
					cfg_set(cf_options,"backup",param,NULL);
					break;
				case 'S':
					cfg_set(cf_options,"force-backup",param,NULL);
					break;
				case 't':
					test = 1;
					break;
				case 'T':
					tell_param = param;
					break;
				case 'u':
					validate = 1;
					/* fall through */
				case 'U':	/* argument to -u or -U is optional */
					uninstall = 1;
					if ((*argv)[2]) param = (*argv)+2;
					else if (argc && argv[1][0] != '-') {
						param = *++argv;
						argc--;
					}
					uninst_dev = param;
					break;
#endif /* !__MSDOS__ */
				case 'v':
					if ((*argv)[2]) param = (*argv)+2;
					else if (argc && argv[1][0]>='0' && argv[1][0]<='9') {
						param = *++argv;
						argc--;
					}
					if (param) 
						verbose = to_number(param);
					else
						if (verbose<0) verbose = 1;
						else verbose++;
					if (verbose) errstd = stdout;
					break;
				case 'V':
					version = 1;
					break;
#if !__MSDOS__
				case 'w':
					cfg_set(cf_options,"nowarn",NULL,NULL);
					nowarn = 1;
					if ( (*argv)[2] == '+' ) nowarn = -1;
					break;
				case 'x':
					cfg_set(cf_options,RAID_EXTRA_BOOT,param,NULL);
					break;
#endif /* !__MSDOS__ */
				case 'X':
					configuration();
					exit(0);
#if !__MSDOS__
				case 'z':
					zflag++;	/* force zero of MBR 8-byte area */
					break;
				case 'Z':
					cfg_set(cf_options,"bios-passes-dl",param,NULL);
					break;
#endif /* !__MSDOS__ */
				default:
					usage(name);
			}
		}
		if (argc) usage(name);
#if !__MSDOS__
		if (!new_root) new_root = getenv("ROOT");
		if (new_root && *new_root) {
			pp_fd = fopen(PARTITIONS, "r");
			if (chroot(new_root) < 0) die("chroot %s: %s",new_root,strerror(errno));
			if (chdir("/dev") < 0)
				warn("root at %s has no /dev directory", new_root);
			if (chdir("/") < 0) die("chdir /: %s",strerror(errno));
		}
		if (atexit(temp_remove)) die("atexit() failed");
		if (version+activate+instmbr+(tell_param!=NULL) > 1) usage(name);
		if (activate) do_activate(act1, act2);
#endif /* !__MSDOS__ */

		if (verbose > 0 || version) {
			printf("LILO version %d.%d%s", VERSION_MAJOR, VERSION_MINOR, VERSION_EDIT);
			if (test)
				printf(" (test mode)\n");
			else
				printf(" (released %s)\n", VERSION_DATE);
			if (version && verbose<=0) {
				/* exit if user asks for version and no verbose */
				return 0;
			}
			printf("  * Copyright (C) 1992-1998 Werner Almesberger  (until v20)\n"
					"  * Copyright (C) 1999-2007 John Coffman  (until v22)\n"
					"  * Copyright (C) 2009-2011 Joachim Wiedorn  (since v23)\n"
					"This program comes with ABSOLUTELY NO WARRANTY. This is free software \n"
					"distributed under the BSD License (3-clause). Details can be found in \n"
					"the file COPYING, which is distributed with this software.\n"
				  );
			if (verbose>0) {
#if !__MSDOS__
#include <sys/utsname.h>
				struct utsname buf;
#endif
				printf("Compiled at %s on %s%s\n", __TIME__, __DATE__, semi);
#if !__MSDOS__
				if (verbose>=2 && uname(&buf)==0) {
					printf("Running %s kernel %s on %s\n",
							buf.sysname, buf.release, buf.machine);
				}
#endif
			}
			printf("\n");
			if (version) {
				if (verbose>=2) configuration();
				return 0;
			}
		}

		if (verbose > 0) errstd = stdout;
#if !__MSDOS__
		preload_types();
		if (geometric & (geometric-1))
			die ("Only one of '-g', '-l', or '-L' may be specified");

		if (tell_param) tell_early = strcasecmp(tell_param, "chrul")
			&& strcasecmp(tell_param, "ebda");
		if (eflag) do_bitmap_edit(bitmap_file);
		if (tell_param && tell_early) probe_tell(tell_param);
		if (instmbr) do_install_mbr(act1, act2);
#endif /* !__MSDOS__ */    

		fd = cfg_open(config_file);
		more = fd<0 ? 0 : cfg_parse(cf_options);

#if !__MSDOS__
		temp = cfg_get_flag(cf_options,"nowarn");
		if (nowarn < 0) nowarn = 0;
		else nowarn = temp;
		/* All warnings appear if very verbose modes used */
		if (verbose>=3) nowarn = 0;
#endif /* !__MSDOS__ */

		if (verbose>=6) printf("main: cfg_parse returns %d\n", more);

#if !__MSDOS__
		if (tell_param && !tell_early) probe_tell(tell_param);

		if (fstat(fd,&st) < 0)
			die("fstat %s: %s", config_file, strerror(errno) );

		if (S_ISREG(st.st_mode)) {
			if (st.st_uid)
				warn("%s should be owned by root", config_file);
			else if (st.st_mode & (S_IWGRP | S_IWOTH))
				warn("%s should be writable only for root", config_file);
			config_read = !!(st.st_mode & (S_IRGRP | S_IROTH));
		}

		if (!cfg_get_flag(cf_options,"nodevcache"))  preload_dev_cache();

		if (verbose<0 && cfg_get_strg(cf_options,"verbose"))
			verbose = to_number(cfg_get_strg(cf_options,"verbose"));
		if (verbose<0) verbose = 0;
		if (verbose) errstd = stdout;

		compact = cfg_get_flag(cf_options,"compact");
		geom = cfg_get_flag(cf_options,"geometric");
		linear = cfg_get_flag(cf_options,"linear");
		lba32  = cfg_get_flag(cf_options,"lba32");

		if (geom+linear+lba32 > 1)
			die("May specify only one of GEOMETRIC, LINEAR or LBA32");
		if (geometric) {
			if (geom+linear+lba32 > 0)  
				warn("Ignoring entry '%s'", geom ? "geometric" :
						linear ? "linear" : "lba32");
			geom = linear = lba32 = 0;
			if (geometric==AD_LBA32) lba32 = 1;
			else if (geometric==AD_LINEAR) linear = 1;
			else if (geometric==AD_GEOMETRIC) geom = 1;
		}    
		if (geom+linear+lba32 == 0) {
			warn("LBA32 addressing assumed");
			lba32 = 1;
		}
		if (linear) warn(
				"LINEAR is deprecated in favor of LBA32:  LINEAR specifies 24-bit\n"
				"  disk addresses below the 1024 cylinder limit; LBA32 specifies 32-bit disk\n"
				"  addresses not subject to cylinder limits on systems with EDD-BIOS extensions;\n"
				"  use LINEAR only if you are aware of its limitations.");

		if (identify) identify_image(identify,ident_opt);

		if (uninstall)
			bsect_uninstall(uninst_dev ? uninst_dev : cfg_get_strg(cf_options,
						"boot"),cfg_get_strg(cf_options,"backup"),validate);
#endif /* !__MSDOS__ */

		if (reboot_arg) {
			map_patch_first(cfg_get_strg(cf_options,"map") ? cfg_get_strg(
						cf_options,"map") : MAP_FILE, reboot_arg);
			exit(0);
		}

#if !__MSDOS__
		if ( (param = cfg_get_strg(cf_options,"bios-passes-dl")) ) {
			if (strchr("YyTt1", *param)) bios_passes_dl = DL_GOOD;
			if (strchr("NnFf0", *param)) bios_passes_dl = DL_BAD;
		}
		if (bios_passes_dl == DL_NOT_SET) 	check_bios();	/* in probe.c */

		if (compact && (linear || lba32) && verbose>=4)
			warn("COMPACT may conflict with %s on some "
					"systems", lba32 ? "LBA32" : "LINEAR");

		geo_init(cfg_get_strg(cf_options,"disktab"));
#endif /* !__MSDOS__ */
		if (query)
			show_images(!cfg_get_strg(cf_options,"map") ? MAP_FILE :
					cfg_get_strg(cf_options,"map"));

#if !__MSDOS__
		/*************************************************/
		/*  Doing a real install (may be test mode)      */
		/*************************************************/

		/* test for a RAID installation */
		raid_offset = raid_setup();
		if (verbose >= 2) {
			printf("raid_setup returns offset = %08X  ndisk = %d\n", raid_offset, ndisk);
			dump_serial_nos();    
		}

		if (verbose >=2 && do_md_install)
			printf("raid flags: at bsect_open  0x%02X\n", raid_flags);

		bsect_open(
				cfg_get_strg(cf_options,"boot"),
				cfg_get_strg(cf_options,"map") ?
				cfg_get_strg(cf_options,"map") : MAP_FILE,
				cfg_get_strg(cf_options,"install"),
				cfg_get_strg(cf_options,"delay") ?
				timer_number(cfg_get_strg(cf_options,"delay")) : 0,
				cfg_get_strg(cf_options,"timeout") ?
				timer_number(cfg_get_strg(cf_options,"timeout")) : -1,
				raid_offset );
		if (more) {
			cfg_init(cf_top);
			if (cfg_parse(cf_top)) cfg_error("Syntax error");
		}

		temp = bsect_number();
		if (temp==0) die("No images have been defined.");
		else if (temp<0) die("Default image doesn't exist.");

#ifdef LCF_VIRTUAL
		check_vmdefault();
#endif
#ifdef LCF_NOKEYBOARD
		check_nokbdefault();
#endif
		check_fallback();
		check_unattended();

		if (verbose>=2) dump_serial_nos();
		if (do_md_install) raid_final();
		else if (!test) {
			char *cp;

			if (verbose) printf("Writing boot sector.\n");

			cp = cfg_get_strg(cf_options,"force-backup");
			if (cp) bsect_update(cp,1,0);
			else bsect_update(cfg_get_strg(cf_options,"backup"),0,0);

		} 
		else {
			bsect_cancel();
			if (passw)
				printf("The password crc file has *NOT* been updated.\n");

			printf("The boot sector and the map file have *NOT* been "
					"altered.\n");
		}
		if (verbose>=4) dump_serial_nos();
		if (warnings) {
			if (warnings>1)
				printf("%d warnings were ", warnings);
			else printf("One warning was ");
			printf("%sed.\n", nowarn ? "suppress" : "issu");
		}
#else  /* __MSDOS__ */
		die("No option switches specified:  -q, -R, or -V");
#endif /* __MSDOS__ */

		return 0;
	}