13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
257dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o * read_bb_file.c --- read a list of bad blocks from a FILE *
33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *
457dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o * Copyright (C) 1994, 1995, 2000 Theodore Ts'o.
519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o *
619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header%
7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library
8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2.
919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header%
103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h>
144cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h>
164cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif
173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <fcntl.h>
183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <time.h>
191d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#if HAVE_SYS_STAT_H
203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/stat.h>
211d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#endif
221d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#if HAVE_SYS_TYPES_H
233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/types.h>
241d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#endif
253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
26b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h"
273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "ext2fs.h"
283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Reads a list of bad blocks from  a FILE *
313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
32efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f,
3357dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o			       ext2_badblocks_list *bb_list,
3450cd7e06e26d8cb232819b3d94b67e37ade80c0fTheodore Ts'o			       void *priv_data,
3557dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o			       void (*invalid)(ext2_filsys fs,
3657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o					       blk_t blk,
3757dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o					       char *badstr,
3850cd7e06e26d8cb232819b3d94b67e37ade80c0fTheodore Ts'o					       void *priv_data))
393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	errcode_t	retval;
41e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t		blockno;
423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int		count;
43f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	char		buf[128];
44f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
4557dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o	if (fs)
4657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o		EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (!*bb_list) {
4919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o		retval = ext2fs_badblocks_list_create(bb_list, 10);
503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (retval)
513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			return retval;
523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	while (!feof (f)) {
55f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		if (fgets(buf, sizeof(buf), f) == NULL)
563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			break;
57e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		count = sscanf(buf, "%llu", &blockno);
58f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		if (count <= 0)
59f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o			continue;
60e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		/* Badblocks isn't going to be updated for 64bit */
61e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		if (blockno >> 32)
62e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			return EOVERFLOW;
6357dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o		if (fs &&
6457dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o		    ((blockno < fs->super->s_first_data_block) ||
65e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		     (blockno >= ext2fs_blocks_count(fs->super)))) {
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			if (invalid)
6750cd7e06e26d8cb232819b3d94b67e37ade80c0fTheodore Ts'o				(invalid)(fs, blockno, buf, priv_data);
683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			continue;
693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
7019c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o		retval = ext2fs_badblocks_list_add(*bb_list, blockno);
71f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		if (retval)
72f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o			return retval;
733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return 0;
753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
779b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'ostruct compat_struct {
789b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o	void (*invalid)(ext2_filsys, blk_t);
799b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o};
809b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o
8157dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'ostatic void call_compat_invalid(ext2_filsys fs, blk_t blk,
82efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o				char *badstr EXT2FS_ATTR((unused)),
83544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o				void *priv_data)
8457dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o{
859b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o	struct compat_struct *st;
8657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o
879b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o	st = (struct compat_struct *) priv_data;
889b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o	if (st->invalid)
899b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o		(st->invalid)(fs, blk);
9057dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o}
9157dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o
9257dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o
9357dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o/*
9457dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o * Reads a list of bad blocks from  a FILE *
9557dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o */
96efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
9757dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o			      ext2_badblocks_list *bb_list,
9857dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o			      void (*invalid)(ext2_filsys fs, blk_t blk))
9957dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o{
1009b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o	struct compat_struct st;
1019b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o
1029b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o	st.invalid = invalid;
1039b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o
1049b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o	return ext2fs_read_bb_FILE2(fs, f, bb_list, &st,
10557dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o				    call_compat_invalid);
10657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o}
10757dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o
1083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
109