/src/sleuthkit/tsk/fs/fs_inode.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * The Sleuth Kit |
3 | | * |
4 | | * Copyright (c) 2006-2011 Brian Carrier, Basis Technology. All Rights reserved |
5 | | * |
6 | | * LICENSE |
7 | | * This software is distributed under the IBM Public License. |
8 | | * AUTHOR(S) |
9 | | * Wietse Venema |
10 | | * IBM T.J. Watson Research |
11 | | * P.O. Box 704 |
12 | | * Yorktown Heights, NY 10598, USA |
13 | | --*/ |
14 | | |
15 | | /** |
16 | | * \file fs_inode.c |
17 | | * Contains functions to allocate, free, and process the generic inode |
18 | | * structures |
19 | | */ |
20 | | #include "tsk_fs_i.h" |
21 | | |
22 | | /** |
23 | | * Contains the short (1 character) name of the file type |
24 | | */ |
25 | | char tsk_fs_meta_type_str[TSK_FS_META_TYPE_STR_MAX][2] = |
26 | | { "-", "r", "d", "p", "c", "b", "l", "s", "h", "w", "v", "V" |
27 | | }; |
28 | | |
29 | | /** |
30 | | * \internal |
31 | | * Allocates a generic inode / metadata structure. |
32 | | * |
33 | | * @param a_buf_len Number of bytes needed to store fs-specific data regarding where content is stored. |
34 | | * @returns NULL on error |
35 | | */ |
36 | | TSK_FS_META * |
37 | | tsk_fs_meta_alloc(size_t a_buf_len) |
38 | 3.77M | { |
39 | 3.77M | TSK_FS_META *fs_meta; |
40 | | |
41 | 3.77M | if ((fs_meta = |
42 | 3.77M | (TSK_FS_META *) tsk_malloc(sizeof(TSK_FS_META))) == NULL) |
43 | 0 | return NULL; |
44 | | |
45 | 3.77M | fs_meta->attr_state = TSK_FS_META_ATTR_EMPTY; |
46 | | |
47 | 3.77M | if (a_buf_len > 0) { |
48 | 3.77M | if ((fs_meta->content_ptr = tsk_malloc(a_buf_len)) == NULL) { |
49 | 0 | free(fs_meta); |
50 | 0 | return NULL; |
51 | 0 | } |
52 | 3.77M | fs_meta->content_len = a_buf_len; |
53 | 3.77M | fs_meta->reset_content = NULL; |
54 | 3.77M | } |
55 | | |
56 | | // assign the id so we know the structure is still alloc |
57 | 3.77M | fs_meta->tag = TSK_FS_META_TAG; |
58 | | |
59 | 3.77M | return fs_meta; |
60 | 3.77M | } |
61 | | |
62 | | |
63 | | /** |
64 | | * \internal |
65 | | * Resize an existing TSK_FS_META structure -- changes the number of |
66 | | * block pointers. |
67 | | * |
68 | | * @param fs_meta Structure to resize |
69 | | * @param a_buf_len Size of file system specific data that is used to store references to file content |
70 | | * @return NULL on error |
71 | | */ |
72 | | TSK_FS_META * |
73 | | tsk_fs_meta_realloc(TSK_FS_META * a_fs_meta, size_t a_buf_len) |
74 | 0 | { |
75 | 0 | if (a_fs_meta->reset_content != NULL) { |
76 | 0 | a_fs_meta->reset_content(a_fs_meta->content_ptr); |
77 | 0 | } |
78 | |
|
79 | 0 | if (a_fs_meta->content_len != a_buf_len) { |
80 | 0 | a_fs_meta->content_len = a_buf_len; |
81 | 0 | a_fs_meta->content_ptr = |
82 | 0 | tsk_realloc((char *) a_fs_meta->content_ptr, a_buf_len); |
83 | 0 | if (a_fs_meta->content_ptr == NULL) { |
84 | 0 | return NULL; |
85 | 0 | } |
86 | 0 | } |
87 | 0 | return a_fs_meta; |
88 | 0 | } |
89 | | |
90 | | |
91 | | /** |
92 | | * \internal |
93 | | * Free the memory allocated to the TSK_FS_META structure. |
94 | | * |
95 | | * @param fs_meta Structure to free |
96 | | */ |
97 | | void |
98 | | tsk_fs_meta_close(TSK_FS_META * fs_meta) |
99 | 3.77M | { |
100 | 3.77M | TSK_FS_META_NAME_LIST *fs_name, *fs_name2; |
101 | | |
102 | 3.77M | if ((!fs_meta) || (fs_meta->tag != TSK_FS_META_TAG)) |
103 | 0 | return; |
104 | | |
105 | | // clear the tag so we know the structure isn't alloc |
106 | 3.77M | fs_meta->tag = 0; |
107 | | |
108 | 3.77M | if (fs_meta->content_ptr) { |
109 | 3.77M | if (fs_meta->reset_content) { |
110 | 1 | fs_meta->reset_content(fs_meta->content_ptr); |
111 | 1 | } |
112 | | |
113 | 3.77M | free((char *) fs_meta->content_ptr); |
114 | 3.77M | } |
115 | | |
116 | 3.77M | fs_meta->content_ptr = NULL; |
117 | 3.77M | fs_meta->content_len = 0; |
118 | | |
119 | 3.77M | if (fs_meta->attr) |
120 | 608k | tsk_fs_attrlist_free(fs_meta->attr); |
121 | 3.77M | fs_meta->attr = NULL; |
122 | | |
123 | 3.77M | free(fs_meta->link); |
124 | 3.77M | fs_meta->link = NULL; |
125 | | |
126 | 3.77M | fs_name = fs_meta->name2; |
127 | 3.86M | while (fs_name) { |
128 | 91.2k | fs_name2 = fs_name->next; |
129 | 91.2k | fs_name->next = NULL; |
130 | 91.2k | free(fs_name); |
131 | 91.2k | fs_name = fs_name2; |
132 | 91.2k | } |
133 | | |
134 | 3.77M | free(fs_meta); |
135 | 3.77M | } |
136 | | |
137 | | /** \internal |
138 | | * Reset the contents of a TSK_FS_META structure. |
139 | | * @param a_fs_meta Structure to reset |
140 | | */ |
141 | | void |
142 | | tsk_fs_meta_reset(TSK_FS_META * a_fs_meta) |
143 | 0 | { |
144 | 0 | void *content_ptr_tmp; |
145 | 0 | size_t content_len_tmp; |
146 | 0 | TSK_FS_ATTRLIST *attr_tmp; |
147 | 0 | TSK_FS_META_NAME_LIST *name2_tmp; |
148 | 0 | char *link_tmp; |
149 | | |
150 | | // Clear content |
151 | 0 | if (a_fs_meta->reset_content) { |
152 | 0 | a_fs_meta->reset_content(a_fs_meta->content_ptr); |
153 | 0 | } |
154 | | |
155 | | // backup pointers |
156 | 0 | content_ptr_tmp = a_fs_meta->content_ptr; |
157 | 0 | content_len_tmp = a_fs_meta->content_len; |
158 | 0 | attr_tmp = a_fs_meta->attr; |
159 | 0 | name2_tmp = a_fs_meta->name2; |
160 | 0 | link_tmp = a_fs_meta->link; |
161 | | |
162 | | // clear all data |
163 | 0 | memset(a_fs_meta, 0, sizeof(TSK_FS_META)); |
164 | 0 | a_fs_meta->tag = TSK_FS_META_TAG; |
165 | | |
166 | | // restore and clear the pointers |
167 | 0 | a_fs_meta->content_ptr = content_ptr_tmp; |
168 | 0 | a_fs_meta->content_len = content_len_tmp; |
169 | |
|
170 | 0 | a_fs_meta->attr = attr_tmp; |
171 | 0 | a_fs_meta->attr_state = TSK_FS_META_ATTR_EMPTY; |
172 | |
|
173 | 0 | a_fs_meta->name2 = name2_tmp; |
174 | |
|
175 | 0 | a_fs_meta->link = link_tmp; |
176 | 0 | if (a_fs_meta->link) |
177 | 0 | a_fs_meta->link[0] = '\0'; |
178 | | |
179 | |
|
180 | 0 | if (a_fs_meta->name2) { |
181 | 0 | name2_tmp = a_fs_meta->name2; |
182 | 0 | while (name2_tmp) { |
183 | 0 | name2_tmp->name[0] = '\0'; |
184 | 0 | name2_tmp->par_inode = 0; |
185 | 0 | name2_tmp->par_seq = 0; |
186 | 0 | name2_tmp = name2_tmp->next; |
187 | 0 | } |
188 | |
|
189 | 0 | } |
190 | 0 | } |
191 | | |
192 | | /** |
193 | | * \ingroup fslib |
194 | | * Walk a range of metadata structures and call a callback for each |
195 | | * structure that matches the flags supplied. For example, it can |
196 | | * call the callback on only allocated or unallocated entries. |
197 | | * |
198 | | * @param a_fs File system to process |
199 | | * @param a_start Metadata address to start walking from |
200 | | * @param a_end Metadata address to walk to |
201 | | * @param a_flags Flags that specify the desired metadata features |
202 | | * @param a_cb Callback function to call |
203 | | * @param a_ptr Pointer to pass to the callback |
204 | | * @returns 1 on error and 0 on success |
205 | | */ |
206 | | uint8_t |
207 | | tsk_fs_meta_walk(TSK_FS_INFO * a_fs, TSK_INUM_T a_start, |
208 | | TSK_INUM_T a_end, TSK_FS_META_FLAG_ENUM a_flags, |
209 | | TSK_FS_META_WALK_CB a_cb, void *a_ptr) |
210 | 12.4k | { |
211 | 12.4k | if ((a_fs == NULL) || (a_fs->tag != TSK_FS_INFO_TAG)) |
212 | 0 | return 1; |
213 | | |
214 | 12.4k | return a_fs->inode_walk(a_fs, a_start, a_end, a_flags, a_cb, a_ptr); |
215 | 12.4k | } |