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

📄 readfs.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* readfs - read a MINIX file system	Author: Paul Polderman *//* Command: readfs - read and extract a MINIX filesystem. * * Syntax:  readfs [-li] block-special [directory] * * Flags: -l:	Extract files and dirs and produce a mkfs-listing on stdout * 	  -i:	Information only: give the listing, but do not extract files. *	  -d:	Don't extract regular files, just the skeleton please. * * Examples: readfs /dev/fd1		# extract all files from /dev/fd1. * 	     readfs -i /dev/hd2		# see what's on /dev/hd2. * 	     readfs -l /dev/at0 rootfs	# extract and list the filesystem * 					# of /dev/at0 and put the tree * 					# in the directory `rootfs'. * *   Readfs reads a MINIX filesystem and extracts recursively all directories * and files, and (optionally) produces a mkfs-listing of them on stdout. * The root directory contents are placed in the current directory, unless * a directory is given as argument, in which case the contents are put there. * Readfs tries to restore the attributes (mode/uid/gid/time) of the files * extracted to those of the original files. * Special files are created as ordinary files, but the mkfs-listing * enables mkfs to restore them to original. */#include <sys/types.h>#include <sys/dir.h>#include <sys/stat.h>#include <sys/wait.h>#include <fcntl.h>#include <limits.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <utime.h>#include <minix/config.h>#include <minix/const.h>#include <minix/type.h>#include "../../fs/const.h"#include "../../fs/type.h"#include "../../fs/buf.h"#include "../../fs/super.h"#undef printf			/* Definition used only in the kernel */#include <stdio.h>/* Compile with -I/user0/ast/minix * (i.e. the directory containing the MINIX system sources) * *	Author: Paul Polderman (polder@cs.vu.nl) April 1987 */char verbose = 0;		/* give a mkfs-listing of the filesystem */ /* And extracts its contents. */char noaction = 0;		/* just give a mkfs-listing, do not extract			 * files. */char nofiles = 0;		/* only extract the skeleton FS structure */struct super_block sb;char pathname[1024];int inodes_per_block;_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(void get_flags, (char *flags));_PROTOTYPE(void readfs, (char *special_file, char *directory));_PROTOTYPE(int get_inode, (int fd, Ino_t inum, d1_inode * ip));_PROTOTYPE(void dump_dir, (int special, d1_inode * ip, char *directory));_PROTOTYPE(int dump_file, (int special, d1_inode * ip, char *filename));_PROTOTYPE(int get_fileblock, (int special, d1_inode * ip, block_t b, struct buf * bp));_PROTOTYPE(int get_block, (int fd, block_t block, struct buf * bp, int type));_PROTOTYPE(int get_rawblock, (int special, block_t blockno, char *bufp));_PROTOTYPE(void restore, (char *name, d1_inode * ip));_PROTOTYPE(void show_info, (char *name, d1_inode * ip, char *path));_PROTOTYPE(void do_indent, (int i));_PROTOTYPE(int Mkdir, (char *directory));int main(argc, argv)int argc;char **argv;{  switch (argc) {      case 2:	pathname[0] = '\0';	readfs(argv[1], pathname);	break;      case 3:	if (argv[1][0] == '-') {		get_flags(&argv[1][1]);		pathname[0] = '\0';		readfs(argv[2], pathname);	} else {		strcpy(pathname, argv[2]);		readfs(argv[1], pathname);	}	break;      case 4:	if (argv[1][0] == '-') {		get_flags(&argv[1][1]);		strcpy(pathname, argv[3]);		readfs(argv[2], pathname);		break;	}			/* else fall through .. */      default:	fprintf(stderr, "Usage: %s [-li] <special> [dirname]\n", argv[0]);	exit(1);  }  return(0);}void get_flags(flags)register char *flags;{  while (*flags) {	switch (*flags) {	    case 'L':	    case 'l':	verbose = 1;	break;	    case 'I':	    case 'i':		noaction = 1;		verbose = 1;		break;	    case 'D':	    case 'd':	nofiles = 1;	break;	    default:		fprintf(stderr, "Bad flag: %c\n", *flags);		break;	}	flags++;  }}#define	zone_shift	(sb.s_log_zone_size)	/* zone to block ratio */void readfs(special_file, directory)char *special_file, *directory;/* Readfs: opens the given special file (with MINIX filesystem), * and extracts its contents into the given directory. */{  d1_inode root_inode;  int special, magic;  off_t super_b;  umask(0);  /* Open the special file */  if ((special = open(special_file, O_RDONLY)) < 0) {	fprintf(stderr, "cannot open %s\n", special_file);	return;  }  /* Read the superblock */  super_b = (off_t) SUPER_BLOCK *(off_t) BLOCK_SIZE;  if (lseek(special, super_b, SEEK_SET) != super_b) {	fprintf(stderr, "cannot seek to superblock\n");	return;  }  if (read(special, (char *) &sb, sizeof(struct super_block))      != sizeof(struct super_block)) {	fprintf(stderr, "cannot read superblock\n");	return;  }  /* The number of inodes in a block differs in V1 and V2. */  magic = sb.s_magic;  if (magic == SUPER_MAGIC || magic == SUPER_REV) {	inodes_per_block = V1_INODES_PER_BLOCK;  } else {	inodes_per_block = V2_INODES_PER_BLOCK;  }  /* Is it really a MINIX filesystem ? */  if (magic != SUPER_MAGIC && magic != SUPER_V2) {	fprintf(stderr, "%s is not a valid MINIX filesystem\n", special_file);	return;  }  /* Fetch the inode of the root directory */  if (get_inode(special, (ino_t) ROOT_INODE, &root_inode) < 0) {	fprintf(stderr, "cannot get inode of root directory\n");	return;  }  /* Print number of blocks and inodes */  if (verbose) printf("boot\n%ld %d\n",	       (block_t) sb.s_nzones << zone_shift, sb.s_ninodes);  /* Extract (recursively) the root directory */  dump_dir(special, &root_inode, directory);}/* Different type of blocks:	(used in routine get_block for caching) */#define	B_INODE		0	/* Cache #0 is the inode cache */#define	B_INDIRECT	1	/* Cache #1 is the (dbl) indirect block cache */#define	B_DATA		2	/* No cache for data blocks (only read once) */int get_inode(fd, inum, ip)int fd;ino_t inum;d1_inode *ip;/* Get inode `inum' from the MINIX filesystem. (Uses the inode-cache) */{  struct buf bp;  block_t block;  block_t ino_block;  unsigned short ino_offset;  /* Calculate start of i-list */  block = SUPER_BLOCK + 1 + sb.s_imap_blocks + sb.s_zmap_blocks;  /* Calculate block with inode inum */  ino_block = ((inum - 1) / inodes_per_block);  ino_offset = ((inum - 1) % inodes_per_block);  block += ino_block;  /* Fetch the block */  if (get_block(fd, block, &bp, B_INODE) == 0) {	memcpy((void *) ip, (void *) &bp.b_v1_ino[ino_offset], sizeof(d1_inode));	return(0);  }  /* Oeps, foutje .. */  fprintf(stderr, "cannot find inode %d\n", inum);  return(-1);}static int indent = 0;		/* current indent (used for mkfs-listing) */void dump_dir(special, ip, directory)int special;d1_inode *ip;char *directory;/* Make the given directory (if non-NULL), * and recursively extract its contents. */{  register struct direct *dp;  register int n_entries;  register char *name;  block_t b = 0;  d1_inode dip;  struct buf bp;  if (verbose) {	show_info(directory, ip, "");	indent++;  }  if (!noaction && *directory) {	/* Try to make the directory if not already there */	if (Mkdir(directory) != 0 || chdir(directory) < 0) {		fprintf(stderr, "Mkdir %s failed\n", directory);		return;	}  }  for (name = directory; *name; name++)	/* Find end of pathname */	;  *name++ = '/';		/* Add trailing slash */  n_entries = (int) (ip->d1_size / (off_t) sizeof(struct direct));  while (n_entries > 0) {	/* Read next block of the directory */	if (get_fileblock(special, ip, b, &bp) < 0) return;	dp = &bp.b_dir[0];	if (b++ == (block_t) 0) {		dp += 2;	/* Skip "." and ".." */		n_entries -= 2;	}	/* Extract the files/directories listed in the block */	while (n_entries-- > 0 && dp < &bp.b_dir[NR_DIR_ENTRIES]) {		if (dp->d_ino != (ino_t) 0) {			if (get_inode(special, dp->d_ino, &dip) < 0) {				/* Bad luck */				dp++;				continue;			}			/* Add new pathname-component to `pathname'. */			strncpy(name, dp->d_name, (size_t) NAME_MAX);			name[NAME_MAX] = '\0';			/* Call the right routine */			if ((dip.d1_mode & I_TYPE) == I_DIRECTORY)				dump_dir(special, &dip, name);			else				dump_file(special, &dip, name);		}		dp++;		/* Next entry, please. */	}  }  *--name = '\0';		/* Restore `pathname' to what it was. */  if (!noaction && *directory) {	chdir("..");		/* Go back up. */	restore(directory, ip);	/* Restore mode/owner/accesstime */  }

⌨️ 快捷键说明

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