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

📄 device.c

📁 LINUX lilo-22.7.1 源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (!dir) dir = backup_file;	name = strrchr(dir, '.');	if (name) {  /* there is a '.' in the name */	    if (strcmp(name+1, suffix)==0) ; /* do nothing */	    else if (strlen(name+1)==4) {  /* && the suffix doesn't match */	    	strcpy(name+1,suffix);	    }	    else if (name[1]==0) strcat(name,suffix);	/* ended with '.' */	    else {		strcat(name+1,".");		strcat(backup_file,suffix);	    }	  /* we now have the filename with the correct suffix */	}	else {    /* no '.' in the name, take it as a template */	    strcat(backup_file,".");	    strcat(backup_file,suffix);	}    }    else  /*  if (!backup_file) */ {	sprintf(temp_name, BACKUP_DIR "/%s.%04X", filename, device);	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)	    printf("%s exists - no %s backup copy made.\n", backup_file, id);    }    else {    	if (dev_listed(device)) {	    if (verbose)		printf("Backup copy of %s has already been made in %s\n",			id, backup_file);    	}    	else if (!test) {	    if ((bck_file = creat(backup_file, 0644)) < 0)		die("creat %s: %s",backup_file, strerror(errno));	    if (write(bck_file, (char *)bsect, SECTOR_SIZE) != SECTOR_SIZE)		die("write %s: %s", backup_file, strerror(errno));	    if (verbose)		printf("Backup copy of %s in %s\n", id, backup_file);	    if (fstat(bck_file, &st) < 0)		die("fstat %s: %s",backup_file,strerror(errno));	    timestamp = st.st_mtime;	}	else {	    if (verbose)		printf("Backup copy of %s in %s (test mode)\n", id, backup_file);	}    }    if (bck_file >= 0 && close(bck_file) < 0) die("close %s: %s",backup_file,strerror(errno));        return timestamp;}int serial_valid(unsigned int serial, int disk_bios){#if 1    return (serial != 0);#elif 1    if (serial == -1 || serial == 0) return 0;    return 1;#else/* if ID is replicated characters, it is invalid *//*	Examples of invalid Volume ID's are:		00000000		6C6C6C6C		FFFFFFFFBUT: any Volume ID (except 0 or -1) is valid on drive C: - - - - - - - - - - - - - - - - - - - - - - - - - - */    unsigned int temp;        temp = serial & 0xFF;    temp |= temp << 8;    temp |= temp << 16;    return (serial != temp ||    		(serial!=0 && serial!=0xFFFFFFFFUL && disk_bios==0x80));#endif}int new_serial(int dev){static int inited = 0;       if (!inited) {	struct stat st;	int fd, random;#define RANDOM "/dev/urandom"		inited = time(NULL);	if ( stat(RANDOM, &st)==0 && S_ISCHR(st.st_mode)	    && (fd = open(RANDOM, O_RDONLY)) > 0	    && read(fd, &random, sizeof(random)) == sizeof(random) )  {#if BETA_TESTif(verbose>=5) printf("Using " RANDOM " for seeding random number generator\n");	    #endif		close(fd);		inited ^= random;	}	srand(inited);    }    dev = dev % PRIME + SMALL_PRIME;    while(dev--) inited = rand();        return inited;#undef RANDOM}static int inited = 0;unsigned int serial_no[MAX_BIOS_DEVICES];static int device_code[MAX_BIOS_DEVICES];/*  register references to various bios devices *  compiles the list of volume IDs *    returns volume ID on success *	0 = no volume ID *	-1 = error */unsigned int register_bios(int bios, int device){    int i, fd, valid, disk_bios;    DEVICE dev;    BOOT_SECTOR buff;    unsigned int serial = -1;    #if 0    if (!inited) {	for (i=0; i<MAX_BIOS_DEVICES; i++) {	    device_code[i] = 0;	    serial_no[i] = 0;	}	inited = 1;	srand(time(NULL));    }#else    inited = 1;#endif    if (!do_md_install && cfg_get_flag(cf_options, "static-bios-codes")) return 0;        if (verbose>=4) {	printf("registering bios=0x%02X  device=0x%04X\n", bios, device);    }        disk_bios = bios;    if (bios>=0x80 && bios<0x80+MAX_BIOS_DEVICES &&				(i=has_partitions(device))) {	bios &= 0x7F;	/* mask to index */	device &= i;	/* mask to master device */	if (device_code[bios]==0 && serial_no[bios]==0) {  /* slot empty */	    fd = dev_open(&dev, device, O_RDWR);	    if (lseek(fd, 0L, SEEK_SET) < 0)		die("master boot record seek %04X: %s", device, strerror(errno));	    if (read(fd, (char*)&buff, SECTOR_SIZE)!=SECTOR_SIZE)		die("read master boot record %04X: %s", device, strerror(errno));	    serial = *(int*)&buff.sector[PART_TABLE_OFFSET-6];	    valid = serial_valid(serial, disk_bios);	    if ((!valid || (VERSION_MINOR>=50)) && !test)		    make_backup(NULL, 0, &buff, device,					"master disk volume ID record");	    if (!valid) {		i = device % PRIME + SMALL_PRIME;		while(i--) serial = rand();		for (; i<5 && !serial_valid(serial, disk_bios); i++) serial = rand();		if (!serial_valid(serial, disk_bios)) die("Volume ID generation error");		*(int*)&buff.sector[PART_TABLE_OFFSET-6] = serial;		if (*(short*)&buff.sector[PART_TABLE_OFFSET - 2] == 0)		    *(short*)&buff.sector[PART_TABLE_OFFSET - 2] = MAGIC_SERIAL;		if (verbose)		    printf("Assigning new Volume ID to (%04X) '%s'  ID = %08X\n",		    			device, dev.name, (int)serial);		if (!test) {		    i = lseek(fd, 0L, SEEK_SET);		    if (i<0) die("master boot record2 seek %04X: %s", device, strerror(errno));		    if (write(fd, (char*)&buff, SECTOR_SIZE)!=SECTOR_SIZE)			die("write master boot record %04X: %s", device, strerror(errno));		}	    }	    dev_close(&dev);	    for (i=0; i<MAX_BIOS_DEVICES; i++) {		if (device_code[i]==device)		    die("register_bios: device code duplicated: %04X", device);		if (serial_no[i]==serial)		    die("register_bios: volume ID serial no. duplicated: %08lX", serial);	    }	    device_code[bios] = device;	    serial_no[bios] = serial;	}	if (device_code[bios]==device) serial = serial_no[bios];	else {	    DEVICE dev, deva;	    	    dev_open(&dev, device_code[bios], O_BYPASS);	    dev_open(&deva, device, O_BYPASS);#if 0	    fprintf(errstd,	    	"\nLILO is unable to correctly determine the device codes assigned to two\n"	    	"of your disks by the System BIOS.  Consequently, it seems to have guessed\n"	    	"wrong.  The following conflict needs to be resolved with explicit\n"		"    \"disk=/dev/...  bios=0x\?\?\" lines in '%s'.\n\n", DFL_CONFIG);	    #endif	    die("Bios device code 0x%02X is being used by two disks\n\t%s (0x%04X)  and  %s (0x%04X)",	    	bios|0x80, dev.name, device_code[bios], deva.name, device);	}	if (verbose>=3) {	    printf("Using Volume ID %08X on bios %02X\n", (int)serial, bios+0x80);	}    }    else if (bios>=0 && bios <=3) serial = 0;    else serial = -1;        return serial;}void dump_serial_nos(void){    int i,j;        printf(" BIOS   VolumeID   Device\n");    if (!inited) return;    for (j=nelem(serial_no); serial_no[--j]==0; )   ;    for (i=0; i<=j; i++)	printf("  %02X    %08X    %04X\n",		i+0x80,		(int)serial_no[i],		(int)device_code[i]	);}enum {ID_GET=0, ID_SET};static int volid_get_set(int device, int vol_in, int option){    BOOT_SECTOR buf;    DEVICE dev;    int fd;    int temp;    unsigned short word;        if (!has_partitions(device) && (device & P_MASK(device)) )	die("VolumeID set/get bad device %04X\n", device);	    fd = dev_open(&dev, device, option ? O_RDWR : O_RDONLY);    if (read(fd, &buf, sizeof(buf)) != sizeof(buf))	die("VolumeID read error: sector 0 of %s not readable", dev.name);    if (option==ID_SET) {	make_backup(NULL, 0, &buf, device,					"master disk volume ID record");	word = temp = buf.boot.volume_id & 0xFF;	/* one char */	word |= word << 8;	temp = word;	temp |= temp << 16;	if (buf.boot.mbz==word 		&& buf.boot.volume_id==temp		&& buf.boot.marker==word) {	    buf.boot.mbz = buf.boot.marker = 0;	}	buf.boot.volume_id = vol_in;	if (buf.boot.marker == 0) buf.boot.marker = MAGIC_SERIAL;	if (!test) {	    if (lseek(fd, 0L, SEEK_SET) != 0L  ||		    write(fd, &buf, PART_TABLE_OFFSET) != PART_TABLE_OFFSET )		die("volid write error");	}    }    dev_close(&dev);    sync(); /* critical that this be done here */        return buf.boot.volume_id;}/* count the number of slashes in a pathname */static int slashes(char *cp){    int n = 0;        while ( (cp=strchr(++cp,'/')) )  n++;        return n;}static int ndevs=0;enum {INVALID=1, DUPLICATE=2, REGENERATE=3, NTCAUTION=4};struct VolumeMgmt {    char *name;		/* the name of the disk; e.g.  "/dev/hda" */    int device;		/* the device number (major, minor) */    int sort;		/* the device number used for sorting */    int flag;		/* various flag bits */    char nt[PART_MAX];	/* flag partitions which might be NT */    DT_ENTRY *dt;	/* pointer to any disktab entry */    struct {	int kernel;	/* volume ID as read using kernel I/O */	int probe;	/* volume ID as probed */    } vol_id;    struct {    	int user;	/* user used a disk= bios= section */    	int probe;	/* passed in from the BIOS data check */    	int actual;	/* this is what we finally decide upon */    } bios;		/* BIOS device codes */};#ifdef LCF_ATARAID/* return boolean if VM is a component drive of ATA */static int is_ata(struct VolumeMgmt *vm, struct VolumeMgmt *ata){    int ata_fd;    DEVICE dev;    struct ata_array_info_s raid;    struct ata_version_s version;    int ret=0;        if ((ata_fd=dev_open(&dev, ata->device, O_NOACCESS) ) < 0)	die("Unable to open %s", ata->name);    if (ioctl(ata_fd, ATA_RAID_VERSION, &version) < 0) ret = -1;    else if (version.major != ATA_MAJOR_VERSION ||		version.minor < ATA_MINOR_VERSION ) {	ret = -2;	fprintf(errstd, "Warning: "	    "ATAraid driver version (kernel %d.%d.%d) <> (lilo %d.%d.%d)",		version.major, version.minor, version.patchlevel,		ATA_MAJOR_VERSION, ATA_MINOR_VERSION, ATA_PATCHLEVEL );    }    else if (ioctl(ata_fd, ATA_GET_ARRAY_INFO, &raid) < 0) ret = -1;    else {	struct ata_disk_info_s disk;	int i;	for (i=0; ret==0 && i<raid.active_disks; i++) {	    disk.number = i;	    if (ioctl(ata_fd, ATA_GET_DISK_INFO, &disk) < 0) ret = -1;	    if (vm->device == MKDEV(disk.major, disk.minor)) ret = 1;	}    }    dev_close(&dev);    return ret;}#endif/*    Returns 0 if not an NT, 2000, or XP boot disk (query user)   returns 1 if it is an NT ... boot disk; abort if fatal set*/static int winnt_check(struct VolumeMgmt *vm, int fatal){    int dev, ret;        if ( !(vm->flag & NTCAUTION) ) return 0;        dev = vm->device;    fflush(stdout);    fflush(stderr);        fprintf(stderr, "\n\nReference:  disk \"%s\"  (%d,%d)  %04X\n\n""LILO wants to assign a new Volume ID to this disk drive.  However, changing\n""the Volume ID of a Windows NT, 2000, or XP boot disk is a fatal Windows error.\n""This caution does not apply to Windows 95 or 98, or to NT data disks.\n"				, vm->name, MAJOR(dev), MINOR(dev), dev);										    ret = yesno("\nIs the above disk an NT boot disk? ", 1);    if (ret && fatal) {	fprintf(stderr, "Aborting ...\n");	exit(0);    }        return ret;}#define SORT(d) (MAJOR(d)==MAJOR_SD?MKDEV(MAJOR_SD_SORT,MINOR(d)):\		 MAJOR(d)==MAJOR_HPT370?MKDEV(MAJOR_HPT370_SORT,MINOR(d)):\		 (d))int pf_hard_disk_scan(void){    struct VolumeMgmt vm [MAX_DEVICES];static int warned = 0, called = 0;    char *line, *next, *name;    int major, minor, i, ipart;    int dev, device, mask, bios;    size_t n;    DEVICE Dev;    DT_ENTRY *walk;    struct stat st;    int duplicate = 0, invalid = 0, ret = 0, ntcaution = 0;    long codes = 0L;/* called from  raid_setup  &  from  geo_open *//* allow only 1 call */    if (called || cfg_get_flag(cf_options,"static-bios-codes")) return ret;    called = 1;    memset(vm,0,sizeof(vm));	/* for consistency */            #if 1    if (!pp_fd  &&  (pp_fd = fopen(PARTITIONS, "r"))==NULL) {#else    if ((pp_fd = fopen(PARTITIONS, "r"))==NULL || fetch()) {#endif	fprintf(errstd, "Warning: '" PARTITIONS "' does not exist, disk scan bypassed\n");	return 1;    }    n = 0;    line = NULL;    while (!feof(pp_fd)) {    	if (line) {	    free(line);	    line = NULL;	    n = 0;    	}	if (getline(&line, &n, pp_fd) <= 0) break;	major = strtoul(line, &next, 10);	if (major==0 || line==next) continue;	minor = strtoul(next, &name, 10);

⌨️ 快捷键说明

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