• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "fsmap.h"
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include "support/nls-enable.h"
7 
8 struct walk_ext_priv_data {
9 	char			*path;
10 	ext2_filsys		fs;
11 	struct fsmap_format	*format;
12 };
13 
walk_block(ext2_filsys fs EXT2FS_ATTR ((unused)),blk64_t * blocknr,e2_blkcnt_t blockcnt,blk64_t ref64_blk EXT2FS_ATTR ((unused)),int ref_offset EXT2FS_ATTR ((unused)),void * priv)14 static int walk_block(ext2_filsys fs  EXT2FS_ATTR((unused)), blk64_t *blocknr,
15 		      e2_blkcnt_t blockcnt,
16 		      blk64_t ref64_blk EXT2FS_ATTR((unused)),
17 		      int ref_offset EXT2FS_ATTR((unused)),
18 		      void *priv)
19 {
20 	struct walk_ext_priv_data *pdata = priv;
21 	struct fsmap_format *format = pdata->format;
22 
23 	return format->add_block(fs, *blocknr, blockcnt < 0, format->private);
24 }
25 
ino_iter_blocks(ext2_filsys fs,ext2_ino_t ino,struct walk_ext_priv_data * pdata)26 static errcode_t ino_iter_blocks(ext2_filsys fs, ext2_ino_t ino,
27 				 struct walk_ext_priv_data *pdata)
28 {
29 	errcode_t retval;
30 	struct ext2_inode inode;
31 	struct fsmap_format *format = pdata->format;
32 
33 	retval = ext2fs_read_inode(fs, ino, &inode);
34 	if (retval)
35 		return retval;
36 
37 	if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
38 		return format->inline_data(&(inode.i_block[0]),
39 					   format->private);
40 
41 	retval = ext2fs_block_iterate3(fs, ino, 0, NULL, walk_block, pdata);
42 	if (retval)
43 		com_err(__func__, retval, _("listing blocks of ino \"%u\""),
44 			ino);
45 	return retval;
46 }
47 
is_dir(ext2_filsys fs,ext2_ino_t ino)48 static int is_dir(ext2_filsys fs, ext2_ino_t ino)
49 {
50 	struct ext2_inode inode;
51 
52 	if (ext2fs_read_inode(fs, ino, &inode))
53 		return 0;
54 	return S_ISDIR(inode.i_mode);
55 }
56 
walk_ext_dir(ext2_ino_t dir EXT2FS_ATTR ((unused)),int flags EXT2FS_ATTR ((unused)),struct ext2_dir_entry * de,int offset EXT2FS_ATTR ((unused)),int blocksize EXT2FS_ATTR ((unused)),char * buf EXT2FS_ATTR ((unused)),void * priv_data)57 static int walk_ext_dir(ext2_ino_t dir EXT2FS_ATTR((unused)),
58 			int flags EXT2FS_ATTR((unused)),
59 			struct ext2_dir_entry *de,
60 			int offset EXT2FS_ATTR((unused)),
61 			int blocksize EXT2FS_ATTR((unused)),
62 			char *buf EXT2FS_ATTR((unused)), void *priv_data)
63 {
64 	errcode_t retval;
65 	struct ext2_inode inode;
66 	char *filename, *cur_path, *name = de->name;
67 	int name_len = de->name_len & 0xff;
68 	struct walk_ext_priv_data *pdata = priv_data;
69 	struct fsmap_format *format = pdata->format;
70 
71 	if (!strncmp(name, ".", name_len)
72 	    || !strncmp(name, "..", name_len)
73 	    || !strncmp(name, "lost+found", 10))
74 		return 0;
75 
76 	if (asprintf(&filename, "%s/%.*s", pdata->path, name_len, name) < 0)
77 		return -ENOMEM;
78 
79 	retval = ext2fs_read_inode(pdata->fs, de->inode, &inode);
80 	if (retval) {
81 		com_err(__func__, retval, _("reading ino \"%u\""), de->inode);
82 		goto end;
83 	}
84 	format->start_new_file(filename, de->inode, &inode, format->private);
85 	retval = ino_iter_blocks(pdata->fs, de->inode, pdata);
86 	if (retval)
87 		return retval;
88 	format->end_new_file(format->private);
89 
90 	retval = 0;
91 	if (is_dir(pdata->fs, de->inode)) {
92 		cur_path = pdata->path;
93 		pdata->path = filename;
94 		retval = ext2fs_dir_iterate2(pdata->fs, de->inode, 0, NULL,
95 				    walk_ext_dir, pdata);
96 		pdata->path = cur_path;
97 	}
98 
99 end:
100 	free(filename);
101 	return retval;
102 }
103 
fsmap_iter_filsys(ext2_filsys fs,struct fsmap_format * format,const char * file,const char * mountpoint)104 errcode_t fsmap_iter_filsys(ext2_filsys fs, struct fsmap_format *format,
105 			    const char *file, const char *mountpoint)
106 {
107 	struct walk_ext_priv_data pdata;
108 	errcode_t retval;
109 
110 	format->private = format->init(file, mountpoint);
111 	pdata.fs = fs;
112 	pdata.path = "";
113 	pdata.format = format;
114 
115 	retval = ext2fs_dir_iterate2(fs, EXT2_ROOT_INO, 0, NULL, walk_ext_dir, &pdata);
116 
117 	format->cleanup(format->private);
118 	return retval;
119 }
120