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 }