Home | History | Annotate | Download | only in android
      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 
     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 
     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 
     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 
     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 
    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