1 /*
2 
3     File: ext2p.c
4 
5     Copyright (C) 2007-2008 Christophe GRENIER <grenier@cgsecurity.org>
6 
7     This software is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License along
18     with this program; if not, write the Free Software Foundation, Inc., 51
19     Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 
21  */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdio.h>
26 #ifdef HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29 #ifdef HAVE_STRING_H
30 #include <string.h>
31 #endif
32 #include "types.h"
33 #include "common.h"
34 #include "list.h"
35 #include "filegen.h"
36 #include "intrf.h"
37 #include "dir.h"
38 #ifdef HAVE_EXT2FS_EXT2_FS_H
39 #include "ext2fs/ext2_fs.h"
40 #endif
41 #ifdef HAVE_EXT2FS_EXT2FS_H
42 #include "ext2fs/ext2fs.h"
43 #endif
44 #include "ext2p.h"
45 #include "ext2_inc.h"
46 #include "ext2_dir.h"
47 #include "log.h"
48 #include "log_part.h"
49 
50 #ifdef HAVE_LIBEXT2FS
ext2_remove_used_space(disk_t * disk,const partition_t * partition,alloc_data_t * list_search_space)51 unsigned int ext2_remove_used_space(disk_t *disk, const partition_t *partition, alloc_data_t *list_search_space)
52 {
53   dir_data_t dir_data;
54   switch(dir_partition_ext2_init(disk, partition, &dir_data, 0))
55   {
56     case DIR_PART_ENOIMP:
57     case DIR_PART_ENOSYS:
58       return 0;
59     case DIR_PART_EIO:
60       log_partition(disk, partition);
61       log_error("Can't open filesystem. Filesystem seems damaged.\n");
62       return 0;
63     case DIR_PART_OK:
64       break;
65   }
66   {
67     const unsigned int sizeof_buffer=512;
68     struct ext2_dir_struct *ls=(struct ext2_dir_struct *)dir_data.private_dir_data;
69     unsigned char *buffer;
70     uint64_t start_free=0;
71     uint64_t end_free=0;
72     unsigned long int block;
73     unsigned long int start,end;
74     const unsigned int blocksize=ls->current_fs->blocksize;
75     ext2fs_block_bitmap bitmap;
76     if(ext2fs_read_block_bitmap(ls->current_fs))
77     {
78       log_error("ext2fs_read_block_bitmap failed\n");
79       return 0;
80     }
81     bitmap=ls->current_fs->block_map;
82     if(bitmap==NULL)
83       return 0;
84 #ifdef HAVE_EXT2FS_GET_GENERIC_BITMAP_START
85     start=ext2fs_get_generic_bitmap_start(bitmap);
86     end=ext2fs_get_generic_bitmap_end(bitmap);
87 #else
88     start=bitmap->start;
89     end=bitmap->end;
90 #endif
91     log_trace("ext2_remove_used_space %lu-%lu\n", start, end);
92     buffer=(unsigned char *)MALLOC(sizeof_buffer);
93     for(block=start;block<=end;block++)
94     {
95 #ifdef HAVE_EXT2FS_GET_GENERIC_BITMAP_START
96       if(ext2fs_test_generic_bitmap(bitmap,block)!=0)
97 #else
98       if(ext2fs_test_bit(block - bitmap->start, bitmap->bitmap)!=0)
99 #endif
100       {
101 	/* Not free */
102 	if(end_free+1==partition->part_offset+(uint64_t)block*blocksize)
103 	  end_free+=blocksize;
104 	else
105 	{
106 	  if(start_free != end_free)
107 	    del_search_space(list_search_space, start_free, end_free);
108 	  start_free=partition->part_offset+(uint64_t)block*blocksize;
109 	  end_free=start_free+(uint64_t)blocksize-1;
110 	}
111       }
112     }
113     free(buffer);
114     if(start_free != end_free)
115       del_search_space(list_search_space, start_free, end_free);
116     dir_data.close(&dir_data);
117     return blocksize;
118   }
119 }
120 #endif
121