comparison pirollback/rollback.c @ 50:40b1ae2ab2d7

pirollback: actual rollback utility implemented, compiles
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Wed, 24 Jul 2013 19:50:24 +0000
parents
children e516128db432
comparison
equal deleted inserted replaced
49:18fa570685de 50:40b1ae2ab2d7
1 #include <sys/types.h>
2 #include <sys/file.h>
3 #include <endian.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <strings.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include "types.h"
10 #include "struct.h"
11 #include "pathname.h"
12
13 extern char *imgfile;
14 extern u8 image[0x480000];
15 extern struct inode_info inode[];
16 extern int last_inode;
17 extern int journal_start_ino;
18
19 report_inode(ino)
20 {
21 struct inode_info *inf = inode + ino;
22 char pathname[PATHNAME_BUF_SIZE];
23 int typechar;
24
25 switch (inf->type) {
26 case 0xF1:
27 typechar = 'f';
28 break;
29 case 0xF2:
30 typechar = 'd';
31 break;
32 case 0xF4:
33 typechar = '.';
34 break;
35 default:
36 fprintf(stderr, "inode #%x: unexpected type %02X\n",
37 ino, inf->type);
38 exit(1);
39 }
40 if (pathname_of_inode(ino, pathname) < 0)
41 strcpy(pathname, "-nopath-");
42 printf("reverting #%04X %c %s\n", ino, typechar, pathname);
43 }
44
45 unlink_inode(oldino, newino, is_sibling)
46 {
47 struct inode_info *inf = inode + oldino;
48 struct inode_flash *fl = inf->flash;
49 u16 *flashp;
50
51 if (is_sibling)
52 flashp = &fl->sibling;
53 else
54 flashp = &fl->descend;
55 if (le16toh(*flashp) != newino) {
56 fprintf(stderr,
57 "fail: %s pointer of inode #%x does not point to #%x as expected\n",
58 is_sibling ? "sibling" : "descend", oldino, newino);
59 exit(1);
60 }
61 /* unprogram it! */
62 *flashp = 0xFFFF;
63 }
64
65 resurrect_old_ver(oldino, newino)
66 {
67 struct inode_info *old = inode + oldino;
68 struct inode_info *new = inode + newino;
69 u8 *typebyte;
70
71 if (old->type != new->type || old->parent != new->parent ||
72 strcmp(old->dataptr, new->dataptr)) {
73 fprintf(stderr, "inode #%x replacing #%x: mismatch error\n",
74 newino, oldino);
75 exit(1);
76 }
77 /* the item of interest is the old in-flash type byte */
78 typebyte = &old->flash->type;
79 if (*typebyte) {
80 fprintf(stderr,
81 "inode #%x to be resurrected: not in deleted state\n",
82 oldino);
83 exit(1);
84 }
85 /* undo the zeroing */
86 *typebyte = old->type;
87 }
88
89 roll_back_inode(ino)
90 {
91 struct inode_info *inf = inode + ino;
92
93 report_inode(ino);
94 if (!inf->flash->type)
95 printf("NOTE: object is already in deleted state\n");
96 /* first order of business: unlink it */
97 if (inf->j_unlink_ptr < 0)
98 unlink_inode(-inf->j_unlink_ptr, ino, 0);
99 else
100 unlink_inode(inf->j_unlink_ptr, ino, 1);
101 /* resurrect the previous version */
102 if (inf->type != 0xF4) {
103 if (inf->j_oldver)
104 resurrect_old_ver(inf->j_oldver, ino);
105 else
106 printf("NOTE: no previous version to resurrect\n");
107 } else if (inf->j_oldver) {
108 fprintf(stderr,
109 "error: unexpected oldver on inode #%x of type F4\n",
110 ino);
111 exit(1);
112 }
113 /* reblank the 3 flash areas programmed with this inode */
114 memset(inf->flash, 0xFF, 16);
115 memset(inf->jflash, 0xFF, 16);
116 memset(inf->dataptr, 0xFF, inf->len);
117 }
118
119 write_new_img(outfilename)
120 char *outfilename;
121 {
122 int fd, cc;
123
124 fd = open(outfilename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
125 if (fd < 0) {
126 perror(outfilename);
127 exit(1);
128 }
129 cc = write(fd, image, sizeof image);
130 close(fd);
131 if (cc != sizeof image) {
132 fprintf(stderr, "error writing to %s\n", outfilename);
133 exit(1);
134 }
135 }
136
137 main(argc, argv)
138 char **argv;
139 {
140 int ino, keep_ino;
141 char *strtoul_endp;
142
143 if (argc != 4) {
144 usage: fprintf(stderr,
145 "usage: %s ffs-image inode-to-keep new-image\n",
146 argv[0]);
147 exit(1);
148 }
149 imgfile = argv[1];
150 keep_ino = strtoul(argv[2], &strtoul_endp, 16);
151 if (!argv[2][0] || *strtoul_endp)
152 goto usage;
153
154 read_img_file();
155 read_inodes();
156 walk_tree();
157 check_object_names();
158 parse_journal();
159 check_object_names(); /* rerun for "undeleted" objects */
160 if (keep_ino < journal_start_ino || keep_ino > last_inode) {
161 fprintf(stderr, "%s: bad inode number specified\n", argv[0]);
162 exit(1);
163 }
164 for (ino = last_inode; ino > keep_ino; ino--)
165 roll_back_inode(ino);
166 write_new_img(argv[3]);
167 exit(0);
168 }