FreeCalypso > hg > freecalypso-reveng
comparison pirollback/journal.c @ 46:78ac405716db
pirollback: journal parsing implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 07 Jul 2013 06:14:40 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
45:18472a2ccf55 | 46:78ac405716db |
---|---|
1 #include <sys/types.h> | |
2 #include <endian.h> | |
3 #include <stdio.h> | |
4 #include <string.h> | |
5 #include <strings.h> | |
6 #include <stdlib.h> | |
7 #include <unistd.h> | |
8 #include "types.h" | |
9 #include "struct.h" | |
10 | |
11 extern u8 image[0x480000]; | |
12 extern struct inode_info inode[]; | |
13 extern int last_inode; | |
14 extern u8 blank_flash_line[16]; | |
15 | |
16 int journal_start_ino; | |
17 | |
18 find_journal() | |
19 { | |
20 int ino; | |
21 struct inode_info *inf; | |
22 | |
23 for (ino = 2; ino <= last_inode; ino++) { | |
24 inf = inode + ino; | |
25 if (inf->type == 0xE1 && inf->parent == 1 && | |
26 !strcmp(inf->dataptr, ".journal")) | |
27 return(ino); | |
28 } | |
29 fprintf(stderr, "error: cannot find /.journal\n"); | |
30 exit(1); | |
31 } | |
32 | |
33 parse_journal() | |
34 { | |
35 struct inode_info *inf; | |
36 struct journal_entry *jr, *endp; | |
37 int ino = 0; | |
38 u16 tempu16; | |
39 s16 temps16; | |
40 | |
41 inf = inode + find_journal(); | |
42 if (inf->len != 0x4010) { | |
43 fprintf(stderr, | |
44 "error: /.journal file length differs from expected\n"); | |
45 exit(1); | |
46 } | |
47 jr = (struct journal_entry *)(inf->dataptr + 0xC); | |
48 for (endp = jr + 0x3FF; jr < endp; jr++) { | |
49 if (!bcmp(jr, blank_flash_line, 16)) | |
50 break; | |
51 if (jr->status != 0xF1) { | |
52 fprintf(stderr, | |
53 "journal record at %x: status byte != F1\n", | |
54 (u8 *) jr - image); | |
55 exit(1); | |
56 } | |
57 tempu16 = le16toh(jr->this_ino); | |
58 if (ino) { | |
59 ino++; | |
60 if (ino != tempu16) { | |
61 fprintf(stderr, | |
62 "journal record at %x: break in inode # sequence\n", | |
63 (u8 *) jr - image); | |
64 exit(1); | |
65 } | |
66 } else { | |
67 ino = tempu16; | |
68 journal_start_ino = ino; | |
69 } | |
70 if (ino < 3 || ino > last_inode) { | |
71 fprintf(stderr, | |
72 "journal record at %x: inode # out of range\n", | |
73 (u8 *) jr - image); | |
74 exit(1); | |
75 } | |
76 inf = inode + ino; | |
77 inf->jflash = jr; | |
78 if (inf->type) { | |
79 if (jr->objtype != inf->type) { | |
80 fprintf(stderr, | |
81 "journal record at %x: type mismatch\n", | |
82 (u8 *) jr - image); | |
83 exit(1); | |
84 } | |
85 } else { | |
86 switch (jr->objtype) { | |
87 case 0xE1: | |
88 case 0xF1: | |
89 case 0xF2: | |
90 case 0xF4: | |
91 break; | |
92 default: | |
93 fprintf(stderr, | |
94 "journal record at %x: unexpected type byte value\n", | |
95 (u8 *) jr - image); | |
96 exit(1); | |
97 } | |
98 inf->type = jr->objtype; | |
99 } | |
100 if (le32toh(jr->location) != inf->rawloc) { | |
101 fprintf(stderr, | |
102 "journal record at %x: location field mismatch\n", | |
103 (u8 *) jr - image); | |
104 exit(1); | |
105 } | |
106 if (le16toh(jr->size) != inf->len) { | |
107 fprintf(stderr, | |
108 "journal record at %x: size field mismatch\n", | |
109 (u8 *) jr - image); | |
110 exit(1); | |
111 } | |
112 temps16 = le16toh(jr->link_ptr); | |
113 if (temps16 < -last_inode || temps16 > last_inode) { | |
114 fprintf(stderr, | |
115 "journal record at %x: linkptr field out of range\n", | |
116 (u8 *) jr - image); | |
117 exit(1); | |
118 } | |
119 inf->j_unlink_ptr = temps16; | |
120 temps16 = le16toh(jr->replacee); | |
121 if (temps16 < 0 || temps16 > last_inode) { | |
122 fprintf(stderr, | |
123 "journal record at %x: replacee field out of range\n", | |
124 (u8 *) jr - image); | |
125 exit(1); | |
126 } | |
127 inf->j_oldver = temps16; | |
128 if (jr->repli) { | |
129 fprintf(stderr, | |
130 "journal record at %x: last 16-bit word is not zero as expected\n", | |
131 (u8 *) jr - image); | |
132 exit(1); | |
133 } | |
134 } | |
135 if (!ino) { | |
136 fprintf(stderr, "error: journal is empty!\n"); | |
137 exit(1); | |
138 } | |
139 if (ino != last_inode) { | |
140 fprintf(stderr, "error: journal end != inode block end\n"); | |
141 exit(1); | |
142 } | |
143 } |