Import of omfsprogs 0.0.5
[omfsprogs.git] / check.c
blob676e3caff4cdf8177ee9d8aa1a7b8f066ca1af80
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include "omfs.h"
7 #include "dirscan.h"
8 #include "check.h"
9 #include "crc.h"
10 #include "fix.h"
11 #include "bits.h"
12 #include "io.h"
15 * TODO:
17 * - check hash table index
18 * - clear extents from free bitmap and make sure free bitmap is null
19 * - sanity check block size, sys block size, mirrors, etc
20 * - check that extent count is valid
21 * - check that terminator matches
22 * - make sure file sizes match up
25 int check_crc(u8 *blk)
27 u16 crc;
28 size_t hdr_size = sizeof(struct omfs_header);
29 struct omfs_inode *oi;
31 oi = (struct omfs_inode *) blk;
33 crc = crc_ccitt_msb(0, blk + hdr_size,
34 swap_be32(oi->head.body_size));
36 return (crc == swap_be16(oi->head.crc));
39 int check_header(u8 *blk)
41 int i;
42 int xor;
43 struct omfs_inode *oi;
45 oi = (struct omfs_inode *) blk;
47 xor = blk[0];
48 for (i = 1; i < OMFS_XOR_COUNT; i++)
49 xor ^= blk[i];
51 return (xor == oi->head.check_xor);
54 int check_sanity(check_context_t *ctx)
56 omfs_inode_t *inode = ctx->current_inode;
57 if (inode->head.body_size > ctx->omfs_info->super->sys_blocksize)
58 return 0;
59 // check device size here too.
60 return 1;
63 int check_inode(check_context_t *ctx)
65 int ret = 1;
66 omfs_inode_t *inode = ctx->current_inode;
67 if (!check_sanity(ctx))
69 fix_problem(E_INSANE, ctx);
70 return 0;
72 if (!check_header(inode->data))
74 fix_problem(E_HEADER_XOR, ctx);
76 if (!check_crc(inode->data))
78 fix_problem(E_HEADER_CRC, ctx);
80 if (inode->head.self != ctx->block)
82 fix_problem(E_SELF_PTR, ctx);
83 ret = 0;
85 if (inode->parent != ctx->parent)
87 fix_problem(E_PARENT_PTR, ctx);
88 ret = 0;
90 if (omfs_compute_hash(ctx->omfs_info, inode->name) != ctx->hash)
92 fix_problem(E_HASH_WRONG, ctx);
93 ret = 0;
95 if (ctx->bitmap && !test_bit(ctx->bitmap, inode->head.self))
97 fix_problem(E_BIT_CLEAR, ctx);
98 ret = 0;
100 clear_bit(ctx->bitmap, inode->head.self);
101 if (inode->type == OMFS_FILE)
103 // TODO check its extents here
106 return ret;
109 int check_fs(FILE *fp)
111 check_context_t ctx;
112 omfs_super_t super;
113 omfs_root_t root;
114 omfs_info_t info = {
115 .dev = fp,
116 .super = &super,
117 .root = &root
120 if (omfs_read_super(fp, &super))
122 fix_problem(E_READ_SUPER, 0);
123 return 0;
125 if (omfs_read_root_block(fp, &super, &root))
127 fix_problem(E_READ_ROOT, 0);
128 return 0;
131 dirscan_entry_t *entry;
132 ctx.omfs_info = &info;
133 ctx.bitmap = omfs_get_bitmap(&info);
135 dirscan_t *scan = dirscan_begin(&info);
136 if (!scan)
138 fix_problem(E_SCAN, 0);
139 return 0;
142 while ((entry = dirscan_next(scan)))
144 char *name = escape(entry->inode->name);
145 printf("inode: %*c%s %llx %d %llx %llx\n",
146 entry->level*2, ' ', name,
147 entry->inode->head.self, entry->hindex,
148 entry->parent, entry->block);
149 free(name);
151 ctx.current_inode = entry->inode;
152 ctx.block = entry->block;
153 ctx.parent = entry->parent;
154 ctx.hash = entry->hindex;
155 check_inode(&ctx);
157 dirscan_release_entry(entry);
159 dirscan_end(scan);
161 // TODO check all set bits for real inodes. If they are there,
162 // move them to root directory with a found-<name>
163 if (ctx.bitmap)
164 free(ctx.bitmap);
165 return 1;