summaryrefslogtreecommitdiff
path: root/src/hdb/hdbfix.cc
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
committerHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
commit5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch)
tree1a81af141708b826e9c61e8a04019994fcca8298 /src/hdb/hdbfix.cc
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/hdb/hdbfix.cc')
-rw-r--r--src/hdb/hdbfix.cc140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/hdb/hdbfix.cc b/src/hdb/hdbfix.cc
new file mode 100644
index 0000000..b82f151
--- /dev/null
+++ b/src/hdb/hdbfix.cc
@@ -0,0 +1,140 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <hdb/db.h>
21
22static fp_stream mout(stdout),merr(stderr);
23
24main(int argc,char* argv[]) try
25{
26 if(argc<2) {
27 mout<<"Usage: "<<argv[0]<<" [-s] <path>\n";
28 return -1;
29 }
30 mstring path; int silent;
31 if(argc>2) { silent=1; path=argv[2]; }
32 else { silent=0; path=argv[1]; }
33 mstring map; if(map.load(path)<0) THROW("hdbfix: could not open "<<path);
34 filemap::head_t head;
35 mstring version=First(sref(head.ident,sizeof(head.ident)));
36 memcpy(&head,map.data(),sizeof(head));
37 mstring cver=First(sref(head.ident,sizeof(head.ident)));
38 mstring answer;
39 int save=0;
40 if(version!=cver) {
41 merr<<path<<": Not a "<<version<<" file\n";
42 return -1;
43 }
44 else {
45 int top=head.frame.get(),last=0;
46 while(top<head.filetop.get()&&top<map.size()) {
47 filemap::rec_t* rec=(filemap::rec_t*)(map.data()+top);
48 if(rec->mem.get()<=0) {
49 if(!silent&&rec->mem.get()<0)
50 mout<<"ending mem: "<<rec->mem.get()<<"\n";
51 break;
52 }
53 last=top;
54 top+=rec->mem.get();
55 }
56 if(top==head.filetop.get()&&head.filesize.get()==map.size()) {
57 if(!silent) mout<<path<<": OK\n";
58 }
59 else {
60 mout<<path<<": CORRUPTED\n";
61 if(silent) return 0;
62 mout<<"\n";
63 mout<<"Head info:\n";
64 mout<<"Size: "<<head.filesize.get()<<"\n";
65 mout<<"Frame: "<<head.frame.get()<<"\n";
66 mout<<"Top: "<<head.filetop.get()<<"\n";
67 mout<<"\n";
68
69 mout<<"Actual sizes:\n";
70 mout<<"Size: "<<map.size()<<"\n";
71 mout<<"Last: "<<last<<"\n";
72 mout<<"End: "<<top<<"\n";
73 mout<<"\n";
74
75 if(map.size()!=head.filesize.get()) {
76 mout<<"Filesizes differ - do you want to set the filesize to "
77 <<head.filesize.get()<<"?\n";
78 getline(answer,stdin); answer.tolower();
79 if(*answer=='y') {
80 map.resize(head.filesize.get());
81 save=1;
82 mout<<"Done.\n";
83 }
84 else {
85 mout<<"No change - quitting.\n";
86 return 0;
87 }
88 }
89
90 int nend=0,end=head.filetop.get();
91 for(int p=head.filetop.get()-4;p>=last;p-=4){
92 int val=ntohl(*(long*)(map.data()+p));
93 if(p+val==end) { nend++; end=p; }
94 }
95 int gap=end-top;
96
97 mout<<"GAP DATA\n";
98 mout<<"==============================\n";
99 for(int i=top;i<end;i++) {
100 if(cset_printable.test(map[i])) mout.put(map[i]);
101 else mout<<"["<<(int)map[i]<<"]";
102 }
103 mout<<"\n==============================\n";
104 mout<<"\n";
105
106 mout<<"At-end sequence:\n";
107 mout<<"Start: "<<end<<"\n";
108 mout<<"Gap: "<<gap<<"\n";
109 mout<<"\n";
110
111 if(gap>0) {
112 mout<<"Do you want to mark the gap as deleted?\n";
113 getline(answer,stdin); answer.tolower();
114 if(*answer=='y') {
115 filemap::rec_t* rec=(filemap::rec_t*)(map.data()+top);
116 rec->mem.set(gap);
117 rec->caps.set(0);
118 save=1;
119 mout<<"Done.\n";
120 }
121 else {
122 mout<<"No change - quitting.\n";
123 return 0;
124 }
125 }
126 }
127 }
128
129 if(save) map.save(path);
130
131 return 0;
132}
133catch(const merror_t& e) {
134 merr<<e.desc<<"\n";
135 return -1;
136}
137catch(...) {
138 merr<<"FATAL ERROR\n";
139 return -1;
140}