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

📄 genext2fs.c

📁 genext2fs
💻 C
📖 第 1 页 / 共 3 页
字号:
	fs->sb.s_magic = EXT2_MAGIC_NUMBER;	// set up groupdescriptors	fs->sb.s_free_blocks_count -= 5 + fs->sb.s_inodes_count * sizeof(inode) / BLOCKSIZE;	fs->gd.bg_free_blocks_count = fs->sb.s_free_blocks_count;	fs->gd.bg_free_inodes_count = fs->sb.s_free_inodes_count;	fs->gd.bg_used_dirs_count = 1;	fs->gd.bg_block_bitmap = 3;	fs->gd.bg_inode_bitmap = 4;	fs->gd.bg_inode_table = 5;	// mark non-filesystem blocks and inodes as allocated	for(i = fs->sb.s_blocks_count; i <= BLOCKSIZE * 8; i++)		allocate(fs->bbm, i);	for(i = fs->sb.s_inodes_count + 1; i <= BLOCKSIZE * 8; i++)		allocate(fs->ibm, i);	// mark system blocsk and inodes as allocated	for(i = 1; i <= 4 + fs->sb.s_inodes_count * sizeof(inode) / BLOCKSIZE; i++)		allocate(fs->bbm, i);	for(i = 1; i < EXT2_FIRST_INO; i++)		allocate(fs->ibm, i);	// make root inode and directory	fs->itab[EXT2_ROOT_INO-1].i_mode = FM_IFDIR | FM_IRWXU | FM_IRWXG | FM_IRWXO;	fs->itab[EXT2_ROOT_INO-1].i_size = BLOCKSIZE;	fs->itab[EXT2_ROOT_INO-1].i_links_count = 2;	b = get_workblk();	d = (directory*)b;	d->d_inode = EXT2_ROOT_INO;	d->d_rec_len = sizeof(directory)+4;	d->d_name_len = 1;	strcpy(d->d_name, ".");	d = (directory*)(b + d->d_rec_len);	d->d_inode = EXT2_ROOT_INO;	d->d_rec_len = BLOCKSIZE - (sizeof(directory)+4);	d->d_name_len = 2;	strcpy(d->d_name, "..");	extend_blk(fs, EXT2_ROOT_INO, b, 1);	// make lost+found directory and reserve blocks	if(fs->sb.s_r_blocks_count)	{		nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU | FM_IRWXG | FM_IRWXO);		memset(b, 0, BLOCKSIZE);		((directory*)b)->d_rec_len = BLOCKSIZE;		for(i = 1; i < fs->sb.s_r_blocks_count; i++)			extend_blk(fs, nod, b, 1);		get_nod(fs, nod)->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE;	}	free_workblk(b);	// administrative info	fs->sb.s_state = 1;	fs->sb.s_max_mnt_count = 20;	// options for me	if(holes)		fs->sb.s_reserved[200] |= OP_HOLES;		return fs;}// loads a filesystem from diskfilesystem * load_fs(FILE * fh, int swapit){	size_t fssize;	filesystem *fs;	if((fseek(fh, 0, SEEK_END) < 0) || ((fssize = ftell(fh)) < 0))		pexit("input filesystem image");	rewind(fh);	fssize = (fssize + BLOCKSIZE - 1) / BLOCKSIZE;	if(fssize < 16) // totally arbitrary		errexit("too small filesystem");	if(fssize > BLOCKS_PER_GROUP) // I build only one group		errexit("too big filesystem");	if(!(fs = (filesystem*)calloc(fssize, BLOCKSIZE)))		errexit("not enough memory for filesystem");	if(fread(fs, BLOCKSIZE, fssize, fh) != fssize)		pexit("input filesystem image");	if(swapit)		swap_badfs(fs);	if(fs->sb.s_rev_level || (fs->sb.s_magic != EXT2_MAGIC_NUMBER))		errexit("not a suitable ext2 filesystem");	return fs;}void free_fs(filesystem *fs){	free(fs);}// just walk through blocks listvoid flist_blocks(filesystem *fs, uint32 nod, FILE *fh){	blockwalker bw;	uint32 bk;	init_bw(fs, nod, &bw);	while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)		fprintf(fh, " %d", bk);	fprintf(fh, "\n");}// walk through blocks listvoid list_blocks(filesystem *fs, uint32 nod){	int bn = 0;	blockwalker bw;	uint32 bk;	init_bw(fs, nod, &bw);	printf("blocks in inode %d:", nod);	while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)		printf(" %d", bk), bn++;	printf("\n%d blocks (%d bytes)\n", bn, bn * BLOCKSIZE);}// saves blocks to FILE*void write_blocks(filesystem *fs, uint32 nod, FILE* f){	blockwalker bw;	uint32 bk;	int32 fsize = get_nod(fs, nod)->i_size;	init_bw(fs, nod, &bw);	while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)	{		if(fsize <= 0)			errexit("wrong size while saving inode %d", nod);		if(fwrite(get_blk(fs, bk), (fsize > BLOCKSIZE) ? BLOCKSIZE : fsize, 1, f) != 1)			errexit("error while saving inode %d", nod);		fsize -= BLOCKSIZE;	}}// hexdumps blocks to a FILE*void hexdump_blocks(filesystem *fs, uint32 nod, FILE* f){	blockwalker bw;	uint32 bk;	uint8 *b;	int32 fsize = get_nod(fs, nod)->i_size;	init_bw(fs, nod, &bw);	printf("block: offset: data:                                ascii:\n");	while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)	{		int i, j;		if(fsize <= 0)			errexit("wrong size while saving inode %d", nod);		b = get_blk(fs, bk);		for(i = 0; i < 64; i++)		{			int dmp = 0;			for(j = 0; j < 4; j++)				if(*(int32*)&b[i * 16 + j * 4])					dmp = 1;			if(!dmp)				continue;			printf("%5d:    %03X:", bk, i * 16);			for(j = 0; j < 4; j++)				printf(" %08x", *(int32*)&b[i * 16 + j * 4]);			printf("  ");			for(j = 0; j < 16; j++)				printf("%c", (b[i * 16 + j] >= ' ' && b[i * 16 + j] < 127) ? b[i * 16 + j] : ' ');			printf("\n");		}		fsize -= BLOCKSIZE;	}}// print block/char device minor and majorvoid print_dev(filesystem *fs, uint32 nod){	int minor, major;	minor = ((uint8*)get_nod(fs, nod)->i_block)[0];	major = ((uint8*)get_nod(fs, nod)->i_block)[1];	printf("major: %d, minor: %d\n", major, minor);}// print an inode as a directoryvoid print_dir(filesystem *fs, uint32 nod){	blockwalker bw;	uint32 bk;	init_bw(fs, nod, &bw);	printf("directory for inode %d:\n", nod);	while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)	{		directory *d;		uint8 *b;		b = get_blk(fs, bk);		for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))			if(d->d_inode)			{				int i;				printf("entry '");				for(i = 0; i < d->d_name_len; i++)					putchar(d->d_name[i]);				printf("' (inode %d): rec_len: %d (name_len: %d)\n", d->d_inode, d->d_rec_len, d->d_name_len);			}	}}// print a symbolic linkvoid print_link(filesystem *fs, uint32 nod){	if(!get_nod(fs, nod)->i_blocks)		printf("links to '%s'\n", (char*)get_nod(fs, nod)->i_block);	else	{		printf("links to '");		write_blocks(fs, nod, stdout);		printf("'\n");	}}// make a ls-like printout of permissionsvoid make_perms(uint32 mode, char perms[11]){	strcpy(perms, "----------");	if(mode & FM_IRUSR)		perms[1] = 'r';	if(mode & FM_IWUSR)		perms[2] = 'w';	if(mode & FM_IXUSR)		perms[3] = 'x';	if(mode & FM_IRGRP)		perms[4] = 'r';	if(mode & FM_IWGRP)		perms[5] = 'w';	if(mode & FM_IXGRP)		perms[6] = 'x';	if(mode & FM_IROTH)		perms[7] = 'r';	if(mode & FM_IWOTH)		perms[8] = 'w';	if(mode & FM_IXOTH)		perms[9] = 'x';	if(mode & FM_ISUID)		perms[3] = 's';	if(mode & FM_ISGID)		perms[6] = 's';	if(mode & FM_ISVTX)		perms[9] = 't';	switch(mode & FM_IFMT)	{		case 0:			*perms = '0';			break;		case FM_IFSOCK:			*perms = 's';			break;		case FM_IFLNK:			*perms = 'l';			break;		case FM_IFREG:			*perms = '-';			break;		case FM_IFBLK:			*perms = 'b';			break;		case FM_IFDIR:			*perms = 'd';			break;		case FM_IFCHR:			*perms = 'c';			break;		case FM_IFIFO:			*perms = 'p';			break;		default:			*perms = '?';	}}// print an inodevoid print_inode(filesystem *fs, uint32 nod){	char *s;	char perms[11];	if(!get_nod(fs, nod)->i_mode)		return;	switch(nod)	{		case EXT2_BAD_INO:			s = "bad blocks";			break;		case EXT2_ROOT_INO:			s = "root";			break;		case EXT2_ACL_IDX_INO:		case EXT2_ACL_DATA_INO:			s = "ACL";			break;		case EXT2_BOOT_LOADER_INO:			s = "boot loader";			break;		case EXT2_UNDEL_DIR_INO:			s = "undelete directory";			break;		default:			s = (nod >= EXT2_FIRST_INO) ? "normal" : "unknown reserved"; 	}	printf("inode %d (%s, %d links): ", nod, s, get_nod(fs, nod)->i_links_count);	if(!allocated(fs->ibm, nod))	{		printf("unallocated\n");		return;	}	make_perms(get_nod(fs, nod)->i_mode, perms);	printf("%s,  size: %d byte%s (%d block%s)\n", perms, plural(get_nod(fs, nod)->i_size), plural(get_nod(fs, nod)->i_blocks / INOBLK));	switch(get_nod(fs, nod)->i_mode & FM_IFMT)	{		case FM_IFSOCK:			list_blocks(fs, nod);			break;		case FM_IFLNK:			print_link(fs, nod);			break;		case FM_IFREG:			list_blocks(fs, nod);			break;		case FM_IFBLK:			print_dev(fs, nod);			break;		case FM_IFDIR:			list_blocks(fs, nod);			print_dir(fs, nod);			break;		case FM_IFCHR:			print_dev(fs, nod);			break;		case FM_IFIFO:			list_blocks(fs, nod);			break;		default:			list_blocks(fs, nod);	}}// describes various fields in a filesystemvoid print_fs(filesystem *fs){	int i;	printf("%d blocks (%d free, %d reserved), first data block: %d\n", fs->sb.s_blocks_count, fs->sb.s_free_blocks_count, fs->sb.s_r_blocks_count, fs->sb.s_first_data_block);	printf("%d inodes (%d free)\n", fs->sb.s_inodes_count, fs->sb.s_free_inodes_count);	printf("block size = %d, frag size = %d\n", fs->sb.s_log_block_size ? (fs->sb.s_log_block_size << 11) : 1024, fs->sb.s_log_frag_size ? (fs->sb.s_log_frag_size << 11) : 1024);	printf("%d blocks per group, %d frags per group, %d inodes per group\n", fs->sb.s_blocks_per_group, fs->sb.s_frags_per_group, fs->sb.s_inodes_per_group);	printf("block bitmap: block %d, inode bitmap: block %d, inode table: block %d\n", fs->gd.bg_block_bitmap, fs->gd.bg_inode_bitmap, fs->gd.bg_inode_table);	printf("block bitmap allocation:\n");	print_bm(fs->bbm, fs->sb.s_blocks_count);	printf("inode bitmap allocation:\n");	print_bm(fs->ibm, fs->sb.s_inodes_count);	for(i=1; i<=fs->sb.s_inodes_count; i++)		if(allocated(fs->ibm, i))			print_inode(fs, i);}void dump_fs(filesystem *fs, FILE * fh, int swapit){	int nbblocks = fs->sb.s_blocks_count;	fs->sb.s_reserved[200] = 0;	if(swapit)		swap_goodfs(fs);	if(fwrite(fs, BLOCKSIZE, nbblocks, fh) < nbblocks)		pexit("output filesystem image");	if(swapit)		swap_badfs(fs);}void showhelp(void){	fprintf(stderr, "Usage: %s [options] image\n"	"Create an ext2 filesystem image from directories/files\n\n"	"  -x image                Use this image as a starting point\n"	"  -d directory            Add this directory as source\n"	"  -f file                 Add nodes (e.g. devices) from this spec file\n"	"  -b blocks               Size in blocks\n"	"  -i inodes               Number of inodes\n"	"  -r reserved             Number of reserved blocks\n"	"  -g path                 Generate a block map file for this path\n"	"  -e value                Fill unallocated blocks with value\n"	"  -z                      Make files with holes\n"	"  -v                      Print resulting filesystem structure\n"	"  -h                      Show this help\n\n"	"Example of spec file:\n"	"drwx            /dev\n"	"crw-    10,190  /dev/lcd\n"	"brw-    1,0     /dev/ram0\n\n"	"Report bugs to xavier.bestel@free.fr\n", argv0);}#define MAX_DOPT 128#define MAX_GOPT 128#define MAX_FILENAME 255extern char* optarg;extern int optind, opterr, optopt;int main(int argc, char **argv){	int nbblocks = -1;	int nbinodes = -1;	int nbresrvd = -1;	char * fsout = "-";	char * fsin = 0;	char * dopt[MAX_DOPT];	int didx = 0;	char * gopt[MAX_GOPT];	int gidx = 0;	int verbose = 0;	int holes = 0;	int emptyval = 0;	uint16 endian = 1;	int bigendian = !*(char*)&endian;	filesystem *fs;	int i;	int c;	argv0 = argv[0];	if(argc <= 1)	{		showhelp();		exit(1);	}	while((c = getopt(argc, argv, "x:f:d:b:i:r:g:e:zvh")) != EOF)		switch(c)		{			case 'x':				fsin = optarg;				break;			case 'd':			case 'f':				dopt[didx++] = optarg;				break;			case 'b':				nbblocks = atoi(optarg);				break;			case 'i':				nbinodes = atoi(optarg);				break;			case 'r':				nbresrvd = atoi(optarg);				break;			case 'g':				gopt[gidx++] = optarg;				break;			case 'e':				emptyval = atoi(optarg);				break;			case 'z':				holes = 1;				break;			case 'v':				verbose = 1;				break;			case 'h':				showhelp();				exit(0);			default:				exit(1);		}	if(optind < (argc - 1))		errexit("too many arguments");	if(optind == (argc - 1))		fsout = argv[optind];	if(fsin)	{		if(strcmp(fsin, "-"))		{			FILE * fh = fopen(fsin, "r");			if(!fh)				pexit(fsin);			fs = load_fs(fh, bigendian);			fclose(fh);		}		else			fs = load_fs(stdin, bigendian);	}	else	{		if(nbblocks == -1)			errexit("filesystem size unspecified");		if(nbinodes == -1)			nbinodes = nbblocks * BLOCKSIZE / rndup(BYTES_PER_INODE, BLOCKSIZE);		if(nbresrvd == -1)			nbresrvd = nbblocks * RESERVED_INODES;		fs = init_fs(nbblocks, nbinodes, nbresrvd, holes);	}	for(i = 0; i < didx; i++)	{		struct stat st;		FILE *fh;		char *pdir;		stat(dopt[i], &st);		switch(st.st_mode & S_IFMT)		{			case S_IFREG:				if(!(fh = fopen(dopt[i], "r")))					pexit(dopt[i]);				add2fs_from_file(fs, EXT2_ROOT_INO, fh);				fclose(fh);				break;			case S_IFDIR:				if(!(pdir = getcwd(0, GETCWD_SIZE)))					pexit(dopt[i]);				if(chdir(dopt[i]) < 0)					pexit(dopt[i]);				add2fs_from_dir(fs, EXT2_ROOT_INO);				if(chdir(pdir) < 0)					pexit(pdir);				free(pdir);				break;			default:				errexit("%s in neither a file nor a directory", dopt[i]);		}	}	if(emptyval)		for(i = 1; i < fs->sb.s_blocks_count; i++)			if(!allocated(fs->bbm, i))				memset(get_blk(fs, i), emptyval, BLOCKSIZE);	if(verbose)		print_fs(fs);	for(i = 0; i < gidx; i++)	{		uint32 nod;		char fname[MAX_FILENAME];		char *p;		FILE *fh;		if(!(nod = find_path(fs, EXT2_ROOT_INO, gopt[i])))			errexit("path %s not found in filesystem", gopt[i]);		while((p = strchr(gopt[i], '/')))			*p = '_';		snprintf(fname, MAX_FILENAME-1, "%s.blk", gopt[i]);		if(!(fh = fopen(fname, "w")))			pexit(fname);		fprintf(fh, "%d:", get_nod(fs, nod)->i_size);		flist_blocks(fs, nod, fh);		fclose(fh);	}	if(strcmp(fsout, "-"))	{		FILE * fh = fopen(fsout, "w");		if(!fh)			pexit(fsout);		dump_fs(fs, fh, bigendian);		fclose(fh);	}	else		dump_fs(fs, stdout, bigendian);	return 0;}

⌨️ 快捷键说明

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