diff options
Diffstat (limited to 'src/hdb/hdbfix.cc')
| -rw-r--r-- | src/hdb/hdbfix.cc | 140 |
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 | |||
| 22 | static fp_stream mout(stdout),merr(stderr); | ||
| 23 | |||
| 24 | main(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 | } | ||
| 133 | catch(const merror_t& e) { | ||
| 134 | merr<<e.desc<<"\n"; | ||
| 135 | return -1; | ||
| 136 | } | ||
| 137 | catch(...) { | ||
| 138 | merr<<"FATAL ERROR\n"; | ||
| 139 | return -1; | ||
| 140 | } | ||
