|
|
1.1 root 1: /* chksmb.c */
2:
3: /* Synchronet message base (SMB) validity checker */
4:
5: /* $Id: chksmb.c,v 1.6 2000/11/04 12:03:50 rswindell Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: /* ANSI */
39: #include <string.h> /* strrchr */
40: #include <time.h> /* ctime */
41:
42: /* SMB-specific */
43: #include "smblib.h"
44: #include "smbwrap.h"
45: #include "conwrap.h" /* getch */
46:
47: /****************************************************************************/
48: /* Returns in 'string' a character representation of the number in l with */
49: /* commas. */
50: /****************************************************************************/
51: char *ultoac(ulong l, char *string)
52: {
53: char str[256];
54: signed char i,j,k;
55:
56: sprintf(str,"%lu",l);
57: i=strlen(str)-1;
58: j=i/3+1+i;
59: string[j--]=0;
60: for(k=1;i>-1;k++) {
61: string[j--]=str[i--];
62: if(j>0 && !(k%3))
63: string[j--]=','; }
64: return(string);
65: }
66:
67: /****************************************************************************/
68: /* Returns an ASCII string for FidoNet address 'addr' */
69: /****************************************************************************/
70: char *faddrtoa(fidoaddr_t addr)
71: {
72: static char str[25];
73: char point[25];
74:
75: sprintf(str,"%u:%u/%u",addr.zone,addr.net,addr.node);
76: if(addr.point) {
77: sprintf(point,".%u",addr.point);
78: strcat(str,point); }
79: return(str);
80: }
81:
82: char *usage="\nusage: chksmb [/opts] <filespec.SHD>\n"
83: "\n"
84: " opts:\n"
85: " s - stop after errored message base\n"
86: " p - pause after errored messsage base\n"
87: " q - quiet mode (no beeps while checking)\n"
88: " a - don't check allocation files\n"
89: " t - don't check translation strings\n"
90: " e - display extended info on corrupted msgs\n";
91:
92: int main(int argc, char **argv)
93: {
94: char str[128],*p,*s,*beep="\7";
95: int i,j,x,y,lzh,errors,errlast,stop_on_error=0,pause_on_error=0
96: ,chkxlat=1,chkalloc=1,lzhmsg,extinfo=0,msgerr;
97: ushort xlat;
98: ulong l,m,n,length,size,total=0,orphan=0,deleted=0,headers=0
99: ,*offset,*number,xlaterr
100: ,delidx
101: ,delhdrblocks,deldatblocks,hdrerr=0,lockerr=0,hdrnumerr=0
102: ,acthdrblocks,actdatblocks
103: ,dfieldlength=0,dfieldoffset=0
104: ,dupenum=0,dupenumhdr=0,dupeoff=0,attr=0,actalloc=0
105: ,datactalloc=0,misnumbered=0,timeerr=0,idxofferr=0,idxerr
106: ,zeronum,idxzeronum,idxnumerr,packable=0L,totallzhsaved=0L
107: ,totalmsgs=0,totallzhmsgs=0,totaldelmsgs=0,totalmsgbytes=0L
108: ,lzhblocks,lzhsaved;
109: smb_t smb;
110: idxrec_t idx;
111: smbmsg_t msg;
112:
113: fprintf(stderr,"\nCHKSMB v2.10 - Check Synchronet Message Base - "
114: "Copyright 2000 Rob Swindell\n");
115:
116: if(argc<2) {
117: printf("%s",usage);
118: exit(1); }
119:
120: errlast=errors=0;
121: for(x=1;x<argc;x++) {
122: if(stop_on_error && errors)
123: break;
124: if(pause_on_error && errlast!=errors) {
125: fprintf(stderr,"\7\nHit any key to continue...");
126: if(!getch())
127: getch();
128: printf("\n"); }
129: errlast=errors;
130: if(argv[x][0]=='/') {
131: for(y=1;argv[x][y];y++)
132: switch(toupper(argv[x][y])) {
133: case 'Q':
134: beep="";
135: break;
136: case 'P':
137: pause_on_error=1;
138: break;
139: case 'S':
140: stop_on_error=1;
141: break;
142: case 'T':
143: chkxlat=0;
144: break;
145: case 'A':
146: chkalloc=0;
147: break;
148: case 'E':
149: extinfo=1;
150: break;
151: default:
152: printf("%s",usage);
153: exit(1); }
154: continue; }
155:
156: strcpy(smb.file,argv[x]);
157: p=strrchr(smb.file,'.');
158: s=strrchr(smb.file,'\\');
159: if(p>s) *p=0;
160:
161: sprintf(str,"%s.shd",smb.file);
162: if(!fexist(str)) {
163: printf("\n%s doesn't exist.\n",smb.file);
164: continue; }
165:
166: fprintf(stderr,"\nChecking %s Headers\n\n",smb.file);
167:
168: smb.retry_time=30;
169: if((i=smb_open(&smb))!=0) {
170: printf("smb_open returned %d\n",i);
171: errors++;
172: continue; }
173:
174: length=filelength(fileno(smb.shd_fp));
175: if(length<sizeof(smbhdr_t)) {
176: printf("Empty\n");
177: smb_close(&smb);
178: continue; }
179:
180: if((i=smb_locksmbhdr(&smb))!=0) {
181: smb_close(&smb);
182: printf("smb_locksmbhdr returned %d\n",i);
183: errors++;
184: continue; }
185:
186: if((length/SHD_BLOCK_LEN)*sizeof(ulong)) {
187: if((number=(ulong *)MALLOC(((length/SHD_BLOCK_LEN)+2)*sizeof(ulong)))
188: ==NULL) {
189: printf("Error allocating %lu bytes of memory\n"
190: ,(length/SHD_BLOCK_LEN)*sizeof(ulong));
191: return(++errors); } }
192: else
193: number=NULL;
194:
195: if(chkalloc && !(smb.status.attr&SMB_HYPERALLOC)) {
196: if((i=smb_open_ha(&smb))!=0) {
197: printf("smb_open_ha returned %d\n",i);
198: return(++errors); }
199:
200: if((i=smb_open_da(&smb))!=0) {
201: printf("smb_open_da returned %d\n",i);
202: return(++errors); } }
203:
204: headers=deleted=orphan=dupenumhdr=attr=zeronum=timeerr=lockerr=hdrerr=0;
205: actalloc=datactalloc=deldatblocks=delhdrblocks=xlaterr=0;
206: lzhblocks=lzhsaved=acthdrblocks=actdatblocks=0;
207:
208: for(l=smb.status.header_offset;l<length;l+=size) {
209: fprintf(stderr,"\r%2u%% ",(long)(100.0/((float)length/l)));
210: msg.idx.offset=l;
211: msgerr=0;
212: if((i=smb_lockmsghdr(&smb,&msg))!=0) {
213: printf("\n(%06lX) smb_lockmsghdr returned %d\n",l,i);
214: lockerr++;
215: headers++;
216: size=SHD_BLOCK_LEN;
217: continue; }
218: if((i=smb_getmsghdr(&smb,&msg))!=0) {
219: smb_unlockmsghdr(&smb,&msg);
220: if(chkalloc && !(smb.status.attr&SMB_HYPERALLOC)) {
221: fseek(smb.sha_fp
222: ,(l-smb.status.header_offset)/SHD_BLOCK_LEN,SEEK_SET);
223: j=fgetc(smb.sha_fp);
224: if(j) { /* Allocated block or at EOF */
225: printf("%s\n(%06lX) smb_getmsghdr returned %d\n",beep,l,i);
226: hdrerr++; }
227: else
228: delhdrblocks++; }
229: else {
230: /* printf("%s\n(%06lX) smb_getmsghdr returned %d\n",beep,l,i); */
231: delhdrblocks++; }
232: size=SHD_BLOCK_LEN;
233: continue; }
234: smb_unlockmsghdr(&smb,&msg);
235: fprintf(stderr,"#%-5lu (%06lX) %-25.25s ",msg.hdr.number,l,msg.from);
236:
237: lzhmsg=0;
238: if(msg.hdr.attr&MSG_DELETE) {
239: deleted++;
240: if(number)
241: number[headers]=0;
242: if(smb.status.attr&SMB_HYPERALLOC)
243: deldatblocks+=smb_datblocks(smb_getmsgdatlen(&msg)); }
244: else {
245: actdatblocks+=smb_datblocks(smb_getmsgdatlen(&msg));
246: if(msg.hdr.number>smb.status.last_msg) {
247: fprintf(stderr,"%sOut-Of-Range message number\n",beep);
248: msgerr=1;
249: if(extinfo)
250: printf("MSGERR: Header number (%lu) greater than last (%lu)\n"
251: ,msg.hdr.number,smb.status.last_msg);
252: hdrnumerr++; }
253:
254: if(smb_getmsgidx(&smb,&msg)) {
255: fprintf(stderr,"%sNot found in index\n",beep);
256: msgerr=1;
257: if(extinfo)
258: printf("MSGERR: Header number (%lu) not found in index\n"
259: ,msg.hdr.number);
260: orphan++; }
261: else if(msg.hdr.attr!=msg.idx.attr) {
262: fprintf(stderr,"%sAttributes mismatch index\n",beep);
263: msgerr=1;
264: if(extinfo)
265: printf("MSGERR: Header attributes (%04X) do not match index "
266: "attributes (%04X)\n"
267: ,msg.hdr.attr,msg.idx.attr);
268: attr++; }
269: else if(msg.hdr.when_imported.time!=msg.idx.time) {
270: fprintf(stderr,"%sImport date/time mismatch index\n",beep);
271: msgerr=1;
272: if(extinfo)
273: printf("MSGERR: Header import date/time does not match "
274: "index import date/time\n");
275: timeerr++; }
276:
277: if(msg.hdr.number==0) {
278: fprintf(stderr,"%sZero message number\n",beep);
279: msgerr=1;
280: if(extinfo)
281: printf("MSGERR: Header number is zero (invalid)\n");
282: zeronum++; }
283: if(number) {
284: for(m=0;m<headers;m++)
285: if(number[m] && msg.hdr.number==number[m]) {
286: fprintf(stderr,"%sDuplicate message number\n",beep);
287: msgerr=1;
288: if(extinfo)
289: printf("MSGERR: Header number (%lu) duplicated\n"
290: ,msg.hdr.number);
291: dupenumhdr++;
292: break; }
293: number[headers]=msg.hdr.number; }
294: if(chkxlat) { /* Check translation strings */
295: for(i=0;i<msg.hdr.total_dfields;i++) {
296: fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset,SEEK_SET);
297: if(!fread(&xlat,2,1,smb.sdt_fp))
298: xlat=0xffff;
299: lzh=0;
300: if(xlat==XLAT_LZH) {
301: lzh=1;
302: if(!fread(&xlat,2,1,smb.sdt_fp))
303: xlat=0xffff; }
304: if(xlat!=XLAT_NONE) {
305: fprintf(stderr,"%sUnsupported Xlat %04X dfield[%u]\n"
306: ,beep,xlat,i);
307: msgerr=1;
308: if(extinfo)
309: printf("MSGERR: Unsupported translation type (%04X) "
310: "in dfield[%u]\n"
311: ,xlat,i);
312: xlaterr++; }
313: else {
314: if(lzh) {
315: lzhmsg=1;
316: if(fread(&m,4,1,smb.sdt_fp)) { /* Get uncompressed len */
317: lzhsaved+=(smb_datblocks(m+2)
318: -smb_datblocks(msg.dfield[i].length))
319: *SDT_BLOCK_LEN;
320: lzhblocks+=smb_datblocks(msg.dfield[i].length);
321: } } } } } }
322:
323: size=smb_getmsghdrlen(&msg);
324: while(size%SHD_BLOCK_LEN) size++;
325:
326: if(chkalloc && !(smb.status.attr&SMB_HYPERALLOC)) {
327: fseek(smb.sha_fp,(l-smb.status.header_offset)/SHD_BLOCK_LEN,SEEK_SET);
328: for(m=0;m<size;m+=SHD_BLOCK_LEN) {
329: /***
330: if(msg.hdr.attr&MSG_DELETE && (i=fgetc(smb.sha_fp))!=0) {
331: fprintf(stderr,"%sDeleted Header Block %lu marked %02X\n"
332: ,beep,m/SHD_BLOCK_LEN,i);
333: msgerr=1;
334: delalloc++; }
335: ***/
336: if(!(msg.hdr.attr&MSG_DELETE) && (i=fgetc(smb.sha_fp))!=1) {
337: fprintf(stderr,"%sActive Header Block %lu marked %02X\n"
338: ,beep,m/SHD_BLOCK_LEN,i);
339: msgerr=1;
340: if(extinfo)
341: printf("MSGERR: Active header block %lu marked %02X "
342: "instead of 01\n"
343: ,m/SHD_BLOCK_LEN,i);
344: actalloc++; } }
345:
346: if(!(msg.hdr.attr&MSG_DELETE)) {
347: acthdrblocks+=(size/SHD_BLOCK_LEN);
348: for(n=0;n<msg.hdr.total_dfields;n++) {
349: if(msg.dfield[n].offset&0x80000000UL) {
350: msgerr=1;
351: if(extinfo)
352: printf("MSGERR: Invalid Data Field [%u] Offset: %lu\n"
353: ,n,msg.dfield[n].offset);
354: dfieldoffset++; }
355: if(msg.dfield[n].length&0x80000000UL) {
356: msgerr=1;
357: if(extinfo)
358: printf("MSGERR: Invalid Data Field [%u] Length: %lu\n"
359: ,n,msg.dfield[n].length);
360: dfieldlength++; }
361: fseek(smb.sda_fp
362: ,((msg.hdr.offset+msg.dfield[n].offset)/SDT_BLOCK_LEN)*2
363: ,SEEK_SET);
364: for(m=0;m<msg.dfield[n].length;m+=SDT_BLOCK_LEN) {
365: if(!fread(&i,2,1,smb.sda_fp) || !i) {
366: fprintf(stderr
367: ,"%sActive Data Block %lu.%lu marked free\n"
368: ,beep,n,m/SHD_BLOCK_LEN);
369: msgerr=1;
370: if(extinfo)
371: printf("MSGERR: Active Data Block %lu.%lu "
372: "marked free\n"
373: ,n,m/SHD_BLOCK_LEN);
374: datactalloc++; } } } }
375: else
376: delhdrblocks+=(size/SHD_BLOCK_LEN); }
377:
378: else { /* Hyper Alloc */
379: if(msg.hdr.attr&MSG_DELETE)
380: delhdrblocks+=(size/SHD_BLOCK_LEN);
381: else
382: acthdrblocks+=(size/SHD_BLOCK_LEN); }
383:
384: totallzhmsgs+=lzhmsg;
385: headers++;
386: if(msgerr && extinfo) {
387: printf("\n");
388: printf("%-20s: %s\n","Message Base",smb.file);
389: printf("%-20s: %lu (%lu)\n","Message Number"
390: ,msg.hdr.number,msg.offset+1);
391: printf("%-20s: %s\n","Subject",msg.subj);
392: printf("%-20s: %s","To",msg.to);
393: if(msg.to_net.type)
394: printf(" (%s)",msg.to_net.type==NET_FIDO
395: ? faddrtoa(*(fidoaddr_t *)msg.to_net.addr) : msg.to_net.addr);
396: printf("\n%-20s: %s","From",msg.from);
397: if(msg.from_net.type)
398: printf(" (%s)",msg.from_net.type==NET_FIDO
399: ? faddrtoa(*(fidoaddr_t *)msg.from_net.addr)
400: : msg.from_net.addr);
401: printf("\n");
402: printf("%-20s: %.24s\n","When Written"
403: ,ctime((time_t *)&msg.hdr.when_written.time));
404: printf("%-20s: %.24s\n","When Imported"
405: ,ctime((time_t *)&msg.hdr.when_imported.time));
406: printf("%-20s: %04hXh\n","Type"
407: ,msg.hdr.type);
408: printf("%-20s: %04hXh\n","Version"
409: ,msg.hdr.version);
410: printf("%-20s: %u\n","Length"
411: ,msg.hdr.length);
412: printf("%-20s: %04hXh\n","Attributes"
413: ,msg.hdr.attr);
414: printf("%-20s: %08lXh\n","Auxilary Attributes"
415: ,msg.hdr.auxattr);
416: printf("%-20s: %08lXh\n","Network Attributes"
417: ,msg.hdr.netattr);
418: printf("%-20s: %06lXh\n","Header Offset"
419: ,msg.idx.offset);
420: printf("%-20s: %06lXh\n","Data Offset"
421: ,msg.hdr.offset);
422: printf("%-20s: %u\n","Total Data Fields"
423: ,msg.hdr.total_dfields);
424: printf("\n"); }
425:
426: smb_freemsgmem(&msg); }
427:
428: if(number)
429: FREE(number);
430:
431: fprintf(stderr,"\r%79s\r100%%\n","");
432:
433:
434: if(chkalloc && !(smb.status.attr&SMB_HYPERALLOC)) {
435:
436: fprintf(stderr,"\nChecking %s Data Blocks\n\n",smb.file);
437:
438: length=filelength(fileno(smb.sda_fp));
439:
440: fseek(smb.sda_fp,0L,SEEK_SET);
441: for(l=0;l<length;l+=2) {
442: fprintf(stderr,"\r%2u%% ",l ? (long)(100.0/((float)length/l)) : 0);
443: i=0;
444: if(!fread(&i,2,1,smb.sda_fp))
445: break;
446: if(!i)
447: deldatblocks++; }
448:
449: fclose(smb.sha_fp);
450: fclose(smb.sda_fp);
451:
452: fprintf(stderr,"\r%79s\r100%%\n",""); }
453:
454: total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t);
455:
456: dupenum=dupeoff=misnumbered=idxzeronum=idxnumerr=idxofferr=idxerr=delidx=0;
457:
458: if(total) {
459:
460: fprintf(stderr,"\nChecking %s Index\n\n",smb.file);
461:
462: if((offset=(ulong *)MALLOC(total*sizeof(ulong)))==NULL) {
463: printf("Error allocating %lu bytes of memory\n",total*sizeof(ulong));
464: return(++errors); }
465: if((number=(ulong *)MALLOC(total*sizeof(ulong)))==NULL) {
466: printf("Error allocating %lu bytes of memory\n",total*sizeof(ulong));
467: return(++errors); }
468: fseek(smb.sid_fp,0L,SEEK_SET);
469:
470: for(l=0;l<total;l++) {
471: fprintf(stderr,"\r%2lu%% %5lu ",l ? (long)(100.0/((float)total/l)) : 0,l);
472: if(!fread(&idx,sizeof(idxrec_t),1,smb.sid_fp))
473: break;
474: fprintf(stderr,"#%-5lu (%06lX) 1st Pass ",idx.number,idx.offset);
475: if(idx.attr&MSG_DELETE) {
476: // fprintf(stderr,"%sMarked for deletion\n",beep);
477: delidx++; }
478: for(m=0;m<l;m++)
479: if(number[m]==idx.number) {
480: fprintf(stderr,"%sDuplicate message number\n",beep);
481: dupenum++;
482: break; }
483: for(m=0;m<l;m++)
484: if(offset[m]==idx.offset) {
485: fprintf(stderr,"%sDuplicate offset\n",beep,idx.offset);
486: dupeoff++;
487: break; }
488: if(idx.offset<smb.status.header_offset) {
489: fprintf(stderr,"%sInvalid offset\n",beep);
490: idxofferr++;
491: break; }
492: if(idx.number==0) {
493: fprintf(stderr,"%sZero message number\n",beep);
494: idxzeronum++;
495: break; }
496: if(idx.number>smb.status.last_msg) {
497: fprintf(stderr,"%sOut-Of-Range message number\n",beep);
498: idxnumerr++;
499: break; }
500: number[l]=idx.number;
501: offset[l]=idx.offset; }
502:
503: if(l<total) {
504: fprintf(stderr,"%sError reading index record\n",beep);
505: idxerr=1; }
506: else {
507: fprintf(stderr,"\r%79s\r","");
508: for(m=0;m<total;m++) {
509: fprintf(stderr,"\r%2lu%% %5lu ",m ? (long)(100.0/((float)total/m)) : 0,m);
510: fprintf(stderr,"#%-5lu (%06lX) 2nd Pass ",number[m],offset[m]);
511: for(n=0;n<m;n++)
512: if(number[m] && number[n] && number[m]<number[n]) {
513: fprintf(stderr,"%sMisordered message number\n",beep);
514: misnumbered++;
515: number[n]=0;
516: break; } }
517: fprintf(stderr,"\r%79s\r100%%\n",""); }
518: FREE(number);
519: FREE(offset);
520:
521: } /* if(total) */
522:
523: totalmsgs+=smb.status.total_msgs;
524: totalmsgbytes+=(acthdrblocks*SHD_BLOCK_LEN)+(actdatblocks*SDT_BLOCK_LEN);
525: totaldelmsgs+=deleted;
526: totallzhsaved+=lzhsaved;
527: printf("\n");
528: printf("%-35.35s (=): %lu\n"
529: ,"Status Total"
530: ,smb.status.total_msgs);
531: printf("%-35.35s (=): %lu\n"
532: ,"Total Indexes"
533: ,total);
534: printf("%-35.35s (=): %lu\n"
535: ,"Active Indexes"
536: ,total-delidx);
537: printf("%-35.35s (=): %lu\n"
538: ,"Active Headers"
539: ,headers-deleted);
540: printf("%-35.35s ( ): %-8lu %13s bytes used\n"
541: ,"Active Header Blocks"
542: ,acthdrblocks,ultoac(acthdrblocks*SHD_BLOCK_LEN,str));
543: printf("%-35.35s ( ): %-8lu %13s bytes used\n"
544: ,"Active Data Blocks"
545: ,actdatblocks,ultoac(actdatblocks*SDT_BLOCK_LEN,str));
546: if(lzhblocks)
547: printf("%-35.35s ( ): %-8lu %13s bytes saved\n"
548: ,"Active LZH Compressed Data Blocks"
549: ,lzhblocks,ultoac(lzhsaved,str));
550: printf("%-35.35s ( ): %lu\n"
551: ,"Header Records"
552: ,headers);
553: printf("%-35.35s ( ): %lu\n"
554: ,"Deleted Indexes"
555: ,delidx);
556: printf("%-35.35s ( ): %lu\n"
557: ,"Deleted Headers"
558: ,deleted);
559: printf("%-35.35s ( ): %-8lu %13s bytes used\n"
560: ,"Deleted Header Blocks"
561: ,delhdrblocks,ultoac(delhdrblocks*SHD_BLOCK_LEN,str));
562: packable+=(delhdrblocks*SHD_BLOCK_LEN);
563: printf("%-35.35s ( ): %-8lu %13s bytes used\n"
564: ,"Deleted Data Blocks"
565: ,deldatblocks,ultoac(deldatblocks*SDT_BLOCK_LEN,str));
566: packable+=(deldatblocks*SDT_BLOCK_LEN);
567:
568: if(orphan)
569: printf("%-35.35s (!): %lu\n"
570: ,"Orphaned Headers"
571: ,orphan);
572: if(idxzeronum)
573: printf("%-35.35s (!): %lu\n"
574: ,"Zeroed Index Numbers"
575: ,idxzeronum);
576: if(zeronum)
577: printf("%-35.35s (!): %lu\n"
578: ,"Zeroed Header Numbers"
579: ,zeronum);
580: if(idxofferr)
581: printf("%-35.35s (!): %lu\n"
582: ,"Invalid Index Offsets"
583: ,idxofferr);
584: if(dupenum)
585: printf("%-35.35s (!): %lu\n"
586: ,"Duplicate Index Numbers"
587: ,dupenum);
588: if(dupeoff)
589: printf("%-35.35s (!): %lu\n"
590: ,"Duplicate Index Offsets"
591: ,dupeoff);
592: if(dupenumhdr)
593: printf("%-35.35s (!): %lu\n"
594: ,"Duplicate Header Numbers"
595: ,dupenumhdr);
596: if(misnumbered)
597: printf("%-35.35s (!): %lu\n"
598: ,"Misordered Index Numbers"
599: ,misnumbered);
600: if(lockerr)
601: printf("%-35.35s (!): %lu\n"
602: ,"Unlockable Header Records"
603: ,lockerr);
604: if(hdrerr)
605: printf("%-35.35s (!): %lu\n"
606: ,"Unreadable Header Records"
607: ,hdrerr);
608: if(idxnumerr)
609: printf("%-35.35s (!): %lu\n"
610: ,"Out-Of-Range Index Numbers"
611: ,idxnumerr);
612: if(hdrnumerr)
613: printf("%-35.35s (!): %lu\n"
614: ,"Out-Of-Range Header Numbers"
615: ,hdrnumerr);
616: if(attr)
617: printf("%-35.35s (!): %lu\n"
618: ,"Mismatched Header Attributes"
619: ,attr);
620: if(timeerr)
621: printf("%-35.35s (!): %lu\n"
622: ,"Mismatched Header Import Time"
623: ,timeerr);
624: if(xlaterr)
625: printf("%-35.35s (!): %lu\n"
626: ,"Unsupported Translation Types"
627: ,xlaterr);
628: if(datactalloc)
629: printf("%-35.35s (!): %lu\n"
630: ,"Misallocated Active Data Blocks"
631: ,datactalloc);
632: if(actalloc)
633: printf("%-35.35s (!): %lu\n"
634: ,"Misallocated Active Header Blocks"
635: ,actalloc);
636: /***
637: if(delalloc)
638: printf("%-35.35s (!): %lu\n"
639: ,"Misallocated Deleted Header Blocks"
640: ,delalloc);
641: ***/
642:
643: if(dfieldoffset)
644: printf("%-35.35s (!): %lu\n"
645: ,"Invalid Data Field Offsets"
646: ,dfieldoffset);
647:
648: if(dfieldlength)
649: printf("%-35.35s (!): %lu\n"
650: ,"Invalid Data Field Lengths"
651: ,dfieldlength);
652:
653:
654: printf("\n%s Message Base ",smb.file);
655: if(/* (headers-deleted)!=smb.status.total_msgs || */
656: total!=smb.status.total_msgs
657: || (headers-deleted)!=total-delidx
658: || idxzeronum || zeronum
659: || orphan || dupenumhdr || dupenum || dupeoff || attr
660: || lockerr || hdrerr || hdrnumerr || idxnumerr || idxofferr
661: || actalloc || datactalloc || misnumbered || timeerr
662: || dfieldoffset || dfieldlength || xlaterr || idxerr) {
663: printf("%shas Errors!\n",beep);
664: errors++; }
665: else
666: printf("is OK\n");
667:
668: smb_unlocksmbhdr(&smb);
669: smb_close(&smb);
670: }
671:
672: if((totalmsgs && (totalmsgs!=smb.status.total_msgs || totallzhmsgs))
673: || packable)
674: printf("\n");
675: if(totalmsgs && totalmsgs!=smb.status.total_msgs)
676: printf("%-39.39s: %-8lu %13s bytes used\n"
677: ,"Total Active Messages"
678: ,totalmsgs,ultoac(totalmsgbytes,str));
679: if(totallzhmsgs && totalmsgs!=smb.status.total_msgs)
680: printf("%-39.39s: %-8lu %13s bytes saved\n"
681: ,"Total LZH Compressed Messages"
682: ,totallzhmsgs,ultoac(totallzhsaved,str));
683: if(packable)
684: printf("%-39.39s: %-8lu %13s bytes used\n"
685: ,"Total Deleted Messages"
686: ,totaldelmsgs,ultoac(packable,str));
687:
688: if(pause_on_error && errlast!=errors) {
689: fprintf(stderr,"\7\nHit any key to continue...");
690: if(!getch())
691: getch();
692: fprintf(stderr,"\n"); }
693:
694:
695: return(errors);
696: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.