paul@181 | 1 | /* |
paul@181 | 2 | * read_bb_file.c --- read a list of bad blocks from a FILE * |
paul@181 | 3 | * |
paul@181 | 4 | * Copyright (C) 1994, 1995, 2000 Theodore Ts'o. |
paul@181 | 5 | * |
paul@181 | 6 | * %Begin-Header% |
paul@181 | 7 | * This file may be redistributed under the terms of the GNU Library |
paul@181 | 8 | * General Public License, version 2. |
paul@181 | 9 | * %End-Header% |
paul@181 | 10 | */ |
paul@181 | 11 | |
paul@181 | 12 | #include "config.h" |
paul@181 | 13 | #include <stdio.h> |
paul@181 | 14 | #include <string.h> |
paul@181 | 15 | #if HAVE_UNISTD_H |
paul@181 | 16 | #include <unistd.h> |
paul@181 | 17 | #endif |
paul@181 | 18 | #include <fcntl.h> |
paul@181 | 19 | #include <time.h> |
paul@181 | 20 | #if HAVE_SYS_STAT_H |
paul@181 | 21 | #include <sys/stat.h> |
paul@181 | 22 | #endif |
paul@181 | 23 | #if HAVE_SYS_TYPES_H |
paul@181 | 24 | #include <sys/types.h> |
paul@181 | 25 | #endif |
paul@181 | 26 | |
paul@181 | 27 | #include "ext2_fs.h" |
paul@181 | 28 | #include "ext2fs.h" |
paul@181 | 29 | |
paul@181 | 30 | /* |
paul@181 | 31 | * Reads a list of bad blocks from a FILE * |
paul@181 | 32 | */ |
paul@181 | 33 | errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f, |
paul@181 | 34 | ext2_badblocks_list *bb_list, |
paul@181 | 35 | void *priv_data, |
paul@181 | 36 | void (*invalid)(ext2_filsys fs, |
paul@181 | 37 | blk_t blk, |
paul@181 | 38 | char *badstr, |
paul@181 | 39 | void *priv_data)) |
paul@181 | 40 | { |
paul@181 | 41 | errcode_t retval; |
paul@212 | 42 | unsigned long long blockno; |
paul@181 | 43 | int count; |
paul@181 | 44 | char buf[128]; |
paul@181 | 45 | |
paul@181 | 46 | if (fs) |
paul@181 | 47 | EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); |
paul@181 | 48 | |
paul@181 | 49 | if (!*bb_list) { |
paul@181 | 50 | retval = ext2fs_badblocks_list_create(bb_list, 10); |
paul@181 | 51 | if (retval) |
paul@181 | 52 | return retval; |
paul@181 | 53 | } |
paul@181 | 54 | |
paul@181 | 55 | while (!feof (f)) { |
paul@181 | 56 | if (fgets(buf, sizeof(buf), f) == NULL) |
paul@181 | 57 | break; |
paul@181 | 58 | count = sscanf(buf, "%llu", &blockno); |
paul@181 | 59 | if (count <= 0) |
paul@181 | 60 | continue; |
paul@181 | 61 | /* Badblocks isn't going to be updated for 64bit */ |
paul@181 | 62 | if (blockno >> 32) |
paul@181 | 63 | return EOVERFLOW; |
paul@181 | 64 | if (fs && |
paul@181 | 65 | ((blockno < fs->super->s_first_data_block) || |
paul@181 | 66 | (blockno >= ext2fs_blocks_count(fs->super)))) { |
paul@181 | 67 | if (invalid) |
paul@212 | 68 | (invalid)(fs, (blk64_t) blockno, buf, priv_data); |
paul@181 | 69 | continue; |
paul@181 | 70 | } |
paul@212 | 71 | retval = ext2fs_badblocks_list_add(*bb_list, (blk64_t) blockno); |
paul@181 | 72 | if (retval) |
paul@181 | 73 | return retval; |
paul@181 | 74 | } |
paul@181 | 75 | return 0; |
paul@181 | 76 | } |
paul@181 | 77 | |
paul@181 | 78 | struct compat_struct { |
paul@181 | 79 | void (*invalid)(ext2_filsys, blk_t); |
paul@181 | 80 | }; |
paul@181 | 81 | |
paul@181 | 82 | static void call_compat_invalid(ext2_filsys fs, blk_t blk, |
paul@181 | 83 | char *badstr EXT2FS_ATTR((unused)), |
paul@181 | 84 | void *priv_data) |
paul@181 | 85 | { |
paul@181 | 86 | struct compat_struct *st; |
paul@181 | 87 | |
paul@181 | 88 | st = (struct compat_struct *) priv_data; |
paul@181 | 89 | if (st->invalid) |
paul@181 | 90 | (st->invalid)(fs, blk); |
paul@181 | 91 | } |
paul@181 | 92 | |
paul@181 | 93 | |
paul@181 | 94 | /* |
paul@181 | 95 | * Reads a list of bad blocks from a FILE * |
paul@181 | 96 | */ |
paul@181 | 97 | errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f, |
paul@181 | 98 | ext2_badblocks_list *bb_list, |
paul@181 | 99 | void (*invalid)(ext2_filsys fs, blk_t blk)) |
paul@181 | 100 | { |
paul@181 | 101 | struct compat_struct st; |
paul@181 | 102 | |
paul@181 | 103 | st.invalid = invalid; |
paul@181 | 104 | |
paul@181 | 105 | return ext2fs_read_bb_FILE2(fs, f, bb_list, &st, |
paul@181 | 106 | call_compat_invalid); |
paul@181 | 107 | } |
paul@181 | 108 | |
paul@181 | 109 | |