diff options
Diffstat (limited to 'e2fsprogs/ext2fs/imager.c')
-rw-r--r-- | e2fsprogs/ext2fs/imager.c | 377 |
1 files changed, 0 insertions, 377 deletions
diff --git a/e2fsprogs/ext2fs/imager.c b/e2fsprogs/ext2fs/imager.c deleted file mode 100644 index e82321efa..000000000 --- a/e2fsprogs/ext2fs/imager.c +++ /dev/null | |||
@@ -1,377 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * image.c --- writes out the critical parts of the filesystem as a | ||
4 | * flat file. | ||
5 | * | ||
6 | * Copyright (C) 2000 Theodore Ts'o. | ||
7 | * | ||
8 | * Note: this uses the POSIX IO interfaces, unlike most of the other | ||
9 | * functions in this library. So sue me. | ||
10 | * | ||
11 | * %Begin-Header% | ||
12 | * This file may be redistributed under the terms of the GNU Public | ||
13 | * License. | ||
14 | * %End-Header% | ||
15 | */ | ||
16 | |||
17 | #include <stdio.h> | ||
18 | #include <string.h> | ||
19 | #if HAVE_UNISTD_H | ||
20 | #include <unistd.h> | ||
21 | #endif | ||
22 | #if HAVE_ERRNO_H | ||
23 | #include <errno.h> | ||
24 | #endif | ||
25 | #include <fcntl.h> | ||
26 | #include <time.h> | ||
27 | #if HAVE_SYS_STAT_H | ||
28 | #include <sys/stat.h> | ||
29 | #endif | ||
30 | #if HAVE_SYS_TYPES_H | ||
31 | #include <sys/types.h> | ||
32 | #endif | ||
33 | |||
34 | #include "ext2_fs.h" | ||
35 | #include "ext2fs.h" | ||
36 | |||
37 | #ifndef HAVE_TYPE_SSIZE_T | ||
38 | typedef int ssize_t; | ||
39 | #endif | ||
40 | |||
41 | /* | ||
42 | * This function returns 1 if the specified block is all zeros | ||
43 | */ | ||
44 | static int check_zero_block(char *buf, int blocksize) | ||
45 | { | ||
46 | char *cp = buf; | ||
47 | int left = blocksize; | ||
48 | |||
49 | while (left > 0) { | ||
50 | if (*cp++) | ||
51 | return 0; | ||
52 | left--; | ||
53 | } | ||
54 | return 1; | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * Write the inode table out as a single block. | ||
59 | */ | ||
60 | #define BUF_BLOCKS 32 | ||
61 | |||
62 | errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags) | ||
63 | { | ||
64 | unsigned int group, left, c, d; | ||
65 | char *buf, *cp; | ||
66 | blk_t blk; | ||
67 | ssize_t actual; | ||
68 | errcode_t retval; | ||
69 | |||
70 | buf = xmalloc(fs->blocksize * BUF_BLOCKS); | ||
71 | |||
72 | for (group = 0; group < fs->group_desc_count; group++) { | ||
73 | blk = fs->group_desc[(unsigned)group].bg_inode_table; | ||
74 | if (!blk) | ||
75 | return EXT2_ET_MISSING_INODE_TABLE; | ||
76 | left = fs->inode_blocks_per_group; | ||
77 | while (left) { | ||
78 | c = BUF_BLOCKS; | ||
79 | if (c > left) | ||
80 | c = left; | ||
81 | retval = io_channel_read_blk(fs->io, blk, c, buf); | ||
82 | if (retval) | ||
83 | goto errout; | ||
84 | cp = buf; | ||
85 | while (c) { | ||
86 | if (!(flags & IMAGER_FLAG_SPARSEWRITE)) { | ||
87 | d = c; | ||
88 | goto skip_sparse; | ||
89 | } | ||
90 | /* Skip zero blocks */ | ||
91 | if (check_zero_block(cp, fs->blocksize)) { | ||
92 | c--; | ||
93 | blk++; | ||
94 | left--; | ||
95 | cp += fs->blocksize; | ||
96 | lseek(fd, fs->blocksize, SEEK_CUR); | ||
97 | continue; | ||
98 | } | ||
99 | /* Find non-zero blocks */ | ||
100 | for (d=1; d < c; d++) { | ||
101 | if (check_zero_block(cp + d*fs->blocksize, fs->blocksize)) | ||
102 | break; | ||
103 | } | ||
104 | skip_sparse: | ||
105 | actual = write(fd, cp, fs->blocksize * d); | ||
106 | if (actual == -1) { | ||
107 | retval = errno; | ||
108 | goto errout; | ||
109 | } | ||
110 | if (actual != (ssize_t) (fs->blocksize * d)) { | ||
111 | retval = EXT2_ET_SHORT_WRITE; | ||
112 | goto errout; | ||
113 | } | ||
114 | blk += d; | ||
115 | left -= d; | ||
116 | cp += fs->blocksize * d; | ||
117 | c -= d; | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | retval = 0; | ||
122 | |||
123 | errout: | ||
124 | free(buf); | ||
125 | return retval; | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * Read in the inode table and stuff it into place | ||
130 | */ | ||
131 | errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, | ||
132 | int flags EXT2FS_ATTR((unused))) | ||
133 | { | ||
134 | unsigned int group, c, left; | ||
135 | char *buf; | ||
136 | blk_t blk; | ||
137 | ssize_t actual; | ||
138 | errcode_t retval; | ||
139 | |||
140 | buf = xmalloc(fs->blocksize * BUF_BLOCKS); | ||
141 | |||
142 | for (group = 0; group < fs->group_desc_count; group++) { | ||
143 | blk = fs->group_desc[(unsigned)group].bg_inode_table; | ||
144 | if (!blk) { | ||
145 | retval = EXT2_ET_MISSING_INODE_TABLE; | ||
146 | goto errout; | ||
147 | } | ||
148 | left = fs->inode_blocks_per_group; | ||
149 | while (left) { | ||
150 | c = BUF_BLOCKS; | ||
151 | if (c > left) | ||
152 | c = left; | ||
153 | actual = read(fd, buf, fs->blocksize * c); | ||
154 | if (actual == -1) { | ||
155 | retval = errno; | ||
156 | goto errout; | ||
157 | } | ||
158 | if (actual != (ssize_t) (fs->blocksize * c)) { | ||
159 | retval = EXT2_ET_SHORT_READ; | ||
160 | goto errout; | ||
161 | } | ||
162 | retval = io_channel_write_blk(fs->io, blk, c, buf); | ||
163 | if (retval) | ||
164 | goto errout; | ||
165 | |||
166 | blk += c; | ||
167 | left -= c; | ||
168 | } | ||
169 | } | ||
170 | retval = ext2fs_flush_icache(fs); | ||
171 | |||
172 | errout: | ||
173 | free(buf); | ||
174 | return retval; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * Write out superblock and group descriptors | ||
179 | */ | ||
180 | errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, | ||
181 | int flags EXT2FS_ATTR((unused))) | ||
182 | { | ||
183 | char *buf, *cp; | ||
184 | ssize_t actual; | ||
185 | errcode_t retval; | ||
186 | |||
187 | buf = xmalloc(fs->blocksize); | ||
188 | |||
189 | /* | ||
190 | * Write out the superblock | ||
191 | */ | ||
192 | memset(buf, 0, fs->blocksize); | ||
193 | memcpy(buf, fs->super, SUPERBLOCK_SIZE); | ||
194 | actual = write(fd, buf, fs->blocksize); | ||
195 | if (actual == -1) { | ||
196 | retval = errno; | ||
197 | goto errout; | ||
198 | } | ||
199 | if (actual != (ssize_t) fs->blocksize) { | ||
200 | retval = EXT2_ET_SHORT_WRITE; | ||
201 | goto errout; | ||
202 | } | ||
203 | |||
204 | /* | ||
205 | * Now write out the block group descriptors | ||
206 | */ | ||
207 | cp = (char *) fs->group_desc; | ||
208 | actual = write(fd, cp, fs->blocksize * fs->desc_blocks); | ||
209 | if (actual == -1) { | ||
210 | retval = errno; | ||
211 | goto errout; | ||
212 | } | ||
213 | if (actual != (ssize_t) (fs->blocksize * fs->desc_blocks)) { | ||
214 | retval = EXT2_ET_SHORT_WRITE; | ||
215 | goto errout; | ||
216 | } | ||
217 | |||
218 | retval = 0; | ||
219 | |||
220 | errout: | ||
221 | free(buf); | ||
222 | return retval; | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * Read the superblock and group descriptors and overwrite them. | ||
227 | */ | ||
228 | errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, | ||
229 | int flags EXT2FS_ATTR((unused))) | ||
230 | { | ||
231 | char *buf; | ||
232 | ssize_t actual, size; | ||
233 | errcode_t retval; | ||
234 | |||
235 | size = fs->blocksize * (fs->group_desc_count + 1); | ||
236 | buf = xmalloc(size); | ||
237 | |||
238 | /* | ||
239 | * Read it all in. | ||
240 | */ | ||
241 | actual = read(fd, buf, size); | ||
242 | if (actual == -1) { | ||
243 | retval = errno; | ||
244 | goto errout; | ||
245 | } | ||
246 | if (actual != size) { | ||
247 | retval = EXT2_ET_SHORT_READ; | ||
248 | goto errout; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * Now copy in the superblock and group descriptors | ||
253 | */ | ||
254 | memcpy(fs->super, buf, SUPERBLOCK_SIZE); | ||
255 | |||
256 | memcpy(fs->group_desc, buf + fs->blocksize, | ||
257 | fs->blocksize * fs->group_desc_count); | ||
258 | |||
259 | retval = 0; | ||
260 | |||
261 | errout: | ||
262 | free(buf); | ||
263 | return retval; | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * Write the block/inode bitmaps. | ||
268 | */ | ||
269 | errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags) | ||
270 | { | ||
271 | char *ptr; | ||
272 | int c, size; | ||
273 | char zero_buf[1024]; | ||
274 | ssize_t actual; | ||
275 | errcode_t retval; | ||
276 | |||
277 | if (flags & IMAGER_FLAG_INODEMAP) { | ||
278 | if (!fs->inode_map) { | ||
279 | retval = ext2fs_read_inode_bitmap(fs); | ||
280 | if (retval) | ||
281 | return retval; | ||
282 | } | ||
283 | ptr = fs->inode_map->bitmap; | ||
284 | size = (EXT2_INODES_PER_GROUP(fs->super) / 8); | ||
285 | } else { | ||
286 | if (!fs->block_map) { | ||
287 | retval = ext2fs_read_block_bitmap(fs); | ||
288 | if (retval) | ||
289 | return retval; | ||
290 | } | ||
291 | ptr = fs->block_map->bitmap; | ||
292 | size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; | ||
293 | } | ||
294 | size = size * fs->group_desc_count; | ||
295 | |||
296 | actual = write(fd, ptr, size); | ||
297 | if (actual == -1) { | ||
298 | retval = errno; | ||
299 | goto errout; | ||
300 | } | ||
301 | if (actual != size) { | ||
302 | retval = EXT2_ET_SHORT_WRITE; | ||
303 | goto errout; | ||
304 | } | ||
305 | size = size % fs->blocksize; | ||
306 | memset(zero_buf, 0, sizeof(zero_buf)); | ||
307 | if (size) { | ||
308 | size = fs->blocksize - size; | ||
309 | while (size) { | ||
310 | c = size; | ||
311 | if (c > (int) sizeof(zero_buf)) | ||
312 | c = sizeof(zero_buf); | ||
313 | actual = write(fd, zero_buf, c); | ||
314 | if (actual == -1) { | ||
315 | retval = errno; | ||
316 | goto errout; | ||
317 | } | ||
318 | if (actual != c) { | ||
319 | retval = EXT2_ET_SHORT_WRITE; | ||
320 | goto errout; | ||
321 | } | ||
322 | size -= c; | ||
323 | } | ||
324 | } | ||
325 | retval = 0; | ||
326 | errout: | ||
327 | return retval; | ||
328 | } | ||
329 | |||
330 | |||
331 | /* | ||
332 | * Read the block/inode bitmaps. | ||
333 | */ | ||
334 | errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags) | ||
335 | { | ||
336 | char *ptr, *buf = 0; | ||
337 | int size; | ||
338 | ssize_t actual; | ||
339 | errcode_t retval; | ||
340 | |||
341 | if (flags & IMAGER_FLAG_INODEMAP) { | ||
342 | if (!fs->inode_map) { | ||
343 | retval = ext2fs_read_inode_bitmap(fs); | ||
344 | if (retval) | ||
345 | return retval; | ||
346 | } | ||
347 | ptr = fs->inode_map->bitmap; | ||
348 | size = (EXT2_INODES_PER_GROUP(fs->super) / 8); | ||
349 | } else { | ||
350 | if (!fs->block_map) { | ||
351 | retval = ext2fs_read_block_bitmap(fs); | ||
352 | if (retval) | ||
353 | return retval; | ||
354 | } | ||
355 | ptr = fs->block_map->bitmap; | ||
356 | size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; | ||
357 | } | ||
358 | size = size * fs->group_desc_count; | ||
359 | |||
360 | buf = xmalloc(size); | ||
361 | |||
362 | actual = read(fd, buf, size); | ||
363 | if (actual == -1) { | ||
364 | retval = errno; | ||
365 | goto errout; | ||
366 | } | ||
367 | if (actual != size) { | ||
368 | retval = EXT2_ET_SHORT_WRITE; | ||
369 | goto errout; | ||
370 | } | ||
371 | memcpy(ptr, buf, size); | ||
372 | |||
373 | retval = 0; | ||
374 | errout: | ||
375 | free(buf); | ||
376 | return retval; | ||
377 | } | ||