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

📄 rescuept.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * rescuept - Andries Brouwer - aeb@cwi.nl - 1999 * * This may be distributed under the GPL. * * call: rescuept /dev/xxx * * The output is a proposed partition table, in the * form of input to sfdisk. Typical use: * *	./rescuept /dev/xxx > xxx.pt * now look at xxx.pt to see whether it resembles what * you expected, and possibly edit the partition types; * if you are satisfied, then *	sfdisk /dev/xxx < xxx.pt * will restore your partition table. If you are cautious, use *	sfdisk /dev/xxx -O xxx.old < xxx.pt * so that the original state can be retrieved using *	sfdisk /dev/xxx -I xxx.old * * Here xxx stands for hda or hdb or sda or sdb or ...  */#include <stdio.h>#include <fcntl.h>#include <string.h>#include <unistd.h>#include <sys/stat.h>#include <sys/ioctl.h>#ifndef BLKGETSIZE#define BLKGETSIZE _IO(0x12,96)#endifchar *progname;char *device;#define MAXPARTITIONS	100#define MAXPAGESZ	65536#define BUFSZ	1024000#define BUFSECS	(BUFSZ/512)char buf[BUFSZ];int bufstart = -1;typedef unsigned int uint32;typedef int sint32;typedef unsigned short uint16;typedef short sint16;typedef unsigned char uchar;void read_sectors(int fd, char *buf, int sectornr, int sectorct) {	extern long long llseek();	long long offset;	int n;	offset = sectornr;	offset *= 512;	if (llseek(fd, offset, SEEK_SET) != offset) {		fprintf(stderr, "%s: llseek error\n", progname);		exit(1);	}	n = read(fd, buf, sectorct*512);	if (n != sectorct*512) {		if (n == -1)			perror("read");		fprintf(stderr, "%s: error reading sectors %d-%d\n",			progname, sectornr, sectornr+sectorct-1);		exit(1);	}}/* * Partition table stuff */struct partition {    unsigned char bootable;		/* 0 or 0x80 */    uchar begin_chs[3];    unsigned char sys_type;    uchar end_chs[3];    unsigned int start_sect;		/* starting sector counting from 0 */    unsigned int nr_sects;		/* nr of sectors in partition */};intis_extended(unsigned char sys_type) {	return (sys_type == 0x5 || sys_type == 0xf || sys_type == 0x85);}/* * List of (extended) partition table sectors found */struct epts {	int secno;	char pt4[64];} epts[MAXPARTITIONS];int eptsct;void addepts(int secno, char *data) {	if (eptsct >= MAXPARTITIONS)		return;		/* ignore */	epts[eptsct].secno = secno;	memcpy(epts[eptsct].pt4, data+512-66, 64);	eptsct++;}/* * List of guessed partitions */struct pt {	int pno;	int start;	int size;	unsigned char type;} pts[MAXPARTITIONS];int partno;void addpart(int start, int size, unsigned char type) {	if (partno >= MAXPARTITIONS)		return;		/* ignore */	pts[partno].start = start;	pts[partno].size = size;	pts[partno].type = type;	partno++;}void outparts() {	int i;	for(i=0; i<partno; i++)		printf("%s%d : start=%9d, size=%8d, Id=%2x\n",		       device, pts[i].pno,		       pts[i].start, pts[i].size, pts[i].type);}void outmsg(char *msg, int start, int nextstart, unsigned char type) {	printf("# %5d MB %16s (type %2x): sectors %9d-%9d\n",	       ((nextstart-start)+1024)/2048, msg, type, start, nextstart-1);}intcreate_extended_partition(int fd, int secno, int size) {	int sec = secno;	int cursec = secno;	int pno = partno;	/* number of extd partition */	int ei = eptsct-1;	unsigned char type = 0x5;	int lastseen = secno;	int ok = 0;	if (epts[ei].secno != secno) {		fprintf(stderr, "%s: program bug\n", progname);		exit(1);	}	outmsg("candidate ext pt", secno, secno+1, type);	addpart(secno, 1, type);		/* size to be filled in later */		while(1) {		char buf[512];		struct partition *p1, *p2, *pr, *pe;		p1 = (struct partition *)(& epts[ei].pt4[0]);		p2 = (struct partition *)(& epts[ei].pt4[16]);		/* for the time being we just ignore the rest */		if (is_extended(p1->sys_type)) {			pr = p2;			pe = p1;		} else if (is_extended(p2->sys_type)) {			pr = p1;			pe = p2;		} else if (p1->sys_type == 0) {			pr = p2;			pe = 0;		} else if (p2->sys_type == 0) {			pr = p1;			pe = 0;		} else			break;		/* first handle the real partition, if any */		if (pr->sys_type != 0) {			int ss = cursec + pr->start_sect;			int es = ss + pr->nr_sects;			outmsg("found in ept", ss, es, pr->sys_type);			addpart(ss, pr->nr_sects, pr->sys_type);			if (lastseen < es - 1)				lastseen = es - 1;			if (lastseen >= size)				break;		}		/* then the extended link */		if (!pe) {			ok = 1;			break;		}		type = pe->sys_type;		cursec = sec + pe->start_sect;		if (cursec >= size)			break;		read_sectors(fd, buf, cursec, 1);		addepts(cursec, buf);		ei = eptsct-1;	}	if (!ok || lastseen == secno) {		printf("# retracted\n");		partno = pno;		return 0;	}	pts[pno].type = type;	pts[pno].size = lastseen+1-secno;	outmsg("extended part ok", secno, lastseen+1, type);	return lastseen;}					/* * Recognize an ext2 superblock */#define EXT2_SUPER_MAGIC	0xEF53struct ext2_super_block {	uint32  s_inodes_count;		 /* 0: Inodes count */	uint32  s_blocks_count;		 /* 4: Blocks count */	uint32  s_r_blocks_count;	 /* 8: Reserved blocks count */	uint32  s_free_blocks_count;	 /* 12: Free blocks count */	uint32  s_free_inodes_count;	 /* 16: Free inodes count */	uint32  s_first_data_block;	 /* 20: First Data Block */	uint32  s_log_block_size;	 /* 24: Block size */	sint32  s_log_frag_size;	 /* 28: Fragment size */	uint32  s_blocks_per_group;	 /* 32: # Blocks per group */	uint32  s_frags_per_group;	 /* 36: # Fragments per group */	uint32  s_inodes_per_group;	 /* 40: # Inodes per group */	uint32  s_mtime;		 /* 44: Mount time */	uint32  s_wtime;		 /* 48: Write time */	uint16  s_mnt_count;	   	 /* 52: Mount count */	sint16  s_max_mnt_count;	 /* 54: Maximal mount count */	uint16  s_magic;		 /* 56: Magic signature */	uint16  s_state;		 /* 58: File system state */	uint16  s_errors;	         /* 60: Behaviour when detecting errors */	uint16  s_minor_rev_level;	 /* 62: minor revision level */	uint32  s_lastcheck;	         /* 64: time of last check */	uint32  s_checkinterval;	 /* 68: max. time between checks */	uint32  s_creator_os;	         /* 72: OS */	uint32  s_rev_level;	         /* 76: Revision level */	uint16  s_def_resuid;	  	 /* 80: Default uid for reserved blocks */	uint16  s_def_resgid;	  	 /* 82: Default gid for reserved blocks */	/* more stuff in later versions - especially s_block_group_nr is useful */	uint32	s_first_ino;		 /* 84: First non-reserved inode */	uint16  s_inode_size;		 /* 88: size of inode structure */	uint16	s_block_group_nr;	 /* 90: block group # of this superblock */	uint32	s_feature_compat;	 /* 92: compatible feature set */	uint32	s_feature_incompat;	 /* 96: incompatible feature set */	uint32	s_feature_ro_compat;	 /* 100: readonly-compatible feature set */	uchar	s_uuid[16];		 /* 104: 128-bit uuid for volume */	char	s_volume_name[16];	 /* 120: volume name */	char	s_last_mounted[64];	 /* 136: directory where last mounted */	uint32	s_algorithm_usage_bitmap;/* 200: For compression */	uchar	s_prealloc_blocks;	 /* 204: Nr of blocks to try to preallocate*/	uchar	s_prealloc_dir_blocks;	 /* 205: Nr to preallocate for dirs */	uchar	s_reserved[818];	 /* 206-1023 */};/* * Heuristic to weed out false alarms for ext2 superblocks. * Recompile this after 2005, of if you destroy things that * have not been written the past ten years. */#define YEAR (60*60*24*365)#define LOWERLIMIT (1992-1970)*YEAR#define UPPERLIMIT (2005-1970)*YEARintis_time(uint32 t) {	return (t >= LOWERLIMIT && t <= UPPERLIMIT);}intis_ztime(uint32 t) {	return (t == 0 || (t >= LOWERLIMIT && t <= UPPERLIMIT));}/* * Recognize a FAT filesystem */struct fat_boot_sector_start {	uchar   jump_code[3];   /* 0: Bootstrap short or near jump */				/* usually jump code (e.g. eb 3e or eb 58) + nop (0x90) */	uchar   system_id[8];   /* 3: OEM Name */				/* fat16: MSDOS5.0 or MSWIN4.0 or ... */				/* fat32: MSWIN4.1 (=W95 OSR2) */	/* BIOS Parameter Block (BPB) */	uchar   sector_size[2]; /* 11: bytes/sector (usually 512 or 2048) */	uchar   cluster_size;   /* 13: sectors/cluster (a power of two in 1..128) */	uint16  reserved;       /* 14: reserved sectors (I see 1 for FAT16, 17 for FAT32) */				/* The # of sectors preceding the first FAT,				   including the boot sector, so at least 1 */	uchar   fats;	  	/* 16: # of copies of FAT (usually 2) */	uchar   dir_entries[2]; /* 17: max # of root directory entries (n/a for FAT32) */				/* (usually 512; 0 for FAT32) */	uchar   sectors[2];     /* 19: total # of sectors (in <32MB partn) or 0 */	uchar   media;	 	/* 21: media code (0xf8 for hard disks) */	uint16  fat_length;     /* 22: sectors/FAT (n/a: 0 for FAT32) */	uint16  secs_track;     /* 24: S = # sectors/track (in 1..63) */	uint16  heads;	 	/* 26: H = # of heads (in 1..255) */	uint32  hidden;		/* 28: # of hidden sectors in partition, before boot sector */				/* (offset from cyl boundary - often equal to S) */	uint32  total_sect;     /* 32: # of sectors (if sectors == 0) */};/* Media descriptor byte:   f8	hard disk   Floppy types:   f0   3.5"	36/2/80 2880k   f0	3.5"	18/2/80	1440k   f9	3.5"	9/2/80	720k   f9	5.25"	15/2/80	1200k   fa	both	9/1/80	320k   fb	both	9/2/80	640k   fc	5.25"	9/1/40	180k   fd	5.25"	9/2/40	360k   fe	5.25"	8/1/40	160k   ff	5.25"	8/2/40	320k   Conclusion: this byte does not differentiate between 3.5" and 5.25",   it does not give the capacity or the number of sectors per track.   However, maybe C and H can be derived.*/struct fat_boot_sector_middle { /* offset 36-61 for FAT16, 64-89 for FAT32 */	/* Extended BIOS Parameter Block */	uchar   drive_number;	/* 0: logical drive number of partition */				/* (typically 0 for floppy, 0x80 for each disk) */	uchar   current_head;	/* Originally: track containing boot record. (Usually 0)				   For WNT: bit 0: dirty: chkdsk must be run					    bit 1: also run surface scan */	uchar   extd_signature;	/* 2: extended signature (0x29) */				/* WNT requires either 0x28 or 0x29 */	uchar   serial_nr[4];	/* 3: serial number of partition */	uchar   volume_name[11];/* 7: volume name of partition */				/* WNT stores the volume label as a special file				   in the root directory */	uchar   fs_name[8];	/* 18: filesystem name (FAT12, FAT16, FAT32) */};struct fat16_boot_sector {	struct fat_boot_sector_start s;		/* 0-35 */	struct fat_boot_sector_middle m;	/* 36-61 */	uchar  boot_code[448];			/* 62-509 */	uchar  signature[2];			/* 510-511: aa55 */};struct fat32_boot_sector {	struct fat_boot_sector_start s;		/* 0-35 */	uint32  fat32_length;   /* 36: sectors/FAT */	uint16  flags;		/* 40: bit 7: fat mirroring, low 4: active fat */				/* If mirroring is disabled (bit8 set) the FAT				   info is only written to the active FAT copy. */	uchar   version[2];     /* 42: major, minor filesystem version */	uint32  root_cluster;   /* 44: first cluster in root directory */	uint16  info_sector;    /* 48: filesystem info sector # relative				   to partition start (usually 1) */	uint16  backup_boot;    /* 50: backup boot sector # relat. to part. start */	uint16  reserved2[6];   /* 52-63: Unused */	struct fat_boot_sector_middle m;	/* 64-89 */	uchar  boot_code[420];			/* 90-509 */	uchar  signature[2];			/* 510-511: aa55 */};/*

⌨️ 快捷键说明

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