|
|
1.1 ! root 1: /* chksmb.c */ ! 2: ! 3: /* Synchronet message base (SMB) validity checker */ ! 4: ! 5: /* $Id: chksmb.c,v 1.43 2005/10/02 23:00:45 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 2005 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 <stdio.h> ! 40: #include <stdlib.h> /* exit */ ! 41: #include <string.h> /* strrchr */ ! 42: #include <time.h> /* ctime */ ! 43: #include <ctype.h> /* toupper */ ! 44: ! 45: /* SMB-specific */ ! 46: #include "genwrap.h" ! 47: #include "conwrap.h" /* getch */ ! 48: #include "dirwrap.h" /* fexist */ ! 49: #include "filewrap.h" /* filelength */ ! 50: #include "smblib.h" ! 51: ! 52: /****************************************************************************/ ! 53: /* Returns in 'string' a character representation of the number in l with */ ! 54: /* commas. */ ! 55: /****************************************************************************/ ! 56: char *ultoac(ulong l, char *string) ! 57: { ! 58: char str[256]; ! 59: signed char i,j,k; ! 60: ! 61: sprintf(str,"%lu",l); ! 62: i=strlen(str)-1; ! 63: j=i/3+1+i; ! 64: string[j--]=0; ! 65: for(k=1;i>-1;k++) { ! 66: string[j--]=str[i--]; ! 67: if(j>0 && !(k%3)) ! 68: string[j--]=','; ! 69: } ! 70: return(string); ! 71: } ! 72: ! 73: /****************************************************************************/ ! 74: /* Returns an ASCII string for FidoNet address 'addr' */ ! 75: /****************************************************************************/ ! 76: char *faddrtoa(fidoaddr_t addr) ! 77: { ! 78: static char str[25]; ! 79: char point[25]; ! 80: ! 81: sprintf(str,"%hu:%hu/%hu",addr.zone,addr.net,addr.node); ! 82: if(addr.point) { ! 83: sprintf(point,".%u",addr.point); ! 84: strcat(str,point); ! 85: } ! 86: return(str); ! 87: } ! 88: ! 89: char* DLLCALL strip_ctrl(char *str) ! 90: { ! 91: char tmp[1024]; ! 92: int i,j; ! 93: ! 94: for(i=j=0;str[i] && j<sizeof(tmp)-1;i++) { ! 95: if(str[i]==CTRL_A && str[i+1]!=0) ! 96: i++; ! 97: else if((uchar)str[i]>=' ') ! 98: tmp[j++]=str[i]; ! 99: } ! 100: if(i!=j) { ! 101: tmp[j]=0; ! 102: strcpy(str,tmp); ! 103: } ! 104: return(str); ! 105: } ! 106: ! 107: char *usage="\nusage: chksmb [-opts] <filespec.SHD>\n" ! 108: "\n" ! 109: " opts:\n" ! 110: " b - beep on error\n" ! 111: " s - stop after errored message base\n" ! 112: " p - pause after errored messsage base\n" ! 113: " h - don't check hash file\n" ! 114: " a - don't check allocation files\n" ! 115: " t - don't check translation strings\n" ! 116: " e - display extended info on corrupted msgs\n"; ! 117: ! 118: int main(int argc, char **argv) ! 119: { ! 120: char str[128],*p,*s,*beep=""; ! 121: char* body; ! 122: char* tail; ! 123: int h,i,j,x,y,lzh,errors,errlast; ! 124: BOOL stop_on_error=FALSE,pause_on_error=FALSE,chkxlat=TRUE,chkalloc=TRUE,chkhash=TRUE ! 125: ,lzhmsg,extinfo=FALSE,msgerr; ! 126: ushort xlat; ! 127: ulong l,m,n,length,size,total=0,orphan,deleted,headers ! 128: ,*offset,*number,xlaterr ! 129: ,delidx ! 130: ,delhdrblocks,deldatblocks,hdrerr,lockerr,hdrnumerr,hdrlenerr ! 131: ,getbodyerr,gettailerr ! 132: ,hasherr ! 133: ,acthdrblocks,actdatblocks ! 134: ,dfieldlength,dfieldoffset ! 135: ,dupenum,dupenumhdr,dupeoff,attr,actalloc ! 136: ,datactalloc,misnumbered,timeerr,idxofferr,idxerr ! 137: ,subjcrc,fromcrc,tocrc ! 138: ,intransit,unvalidated ! 139: ,zeronum,idxzeronum,idxnumerr,packable=0L,totallzhsaved=0L ! 140: ,totalmsgs=0,totallzhmsgs=0,totaldelmsgs=0,totalmsgbytes=0L ! 141: ,lzhblocks,lzhsaved; ! 142: smb_t smb; ! 143: idxrec_t idx; ! 144: smbmsg_t msg; ! 145: hash_t** hashes; ! 146: char revision[16]; ! 147: ! 148: sscanf("$Revision: 1.43 $", "%*s %s", revision); ! 149: ! 150: fprintf(stderr,"\nCHKSMB v2.20-%s (rev %s) SMBLIB %s - Check Synchronet Message Base\n" ! 151: ,PLATFORM_DESC,revision,smb_lib_ver()); ! 152: ! 153: if(argc<2) { ! 154: printf("%s",usage); ! 155: exit(1); ! 156: } ! 157: ! 158: errlast=errors=0; ! 159: for(x=1;x<argc;x++) { ! 160: if(stop_on_error && errors) ! 161: break; ! 162: if(pause_on_error && errlast!=errors) { ! 163: fprintf(stderr,"\7\nHit any key to continue..."); ! 164: if(!getch()) ! 165: getch(); ! 166: printf("\n"); ! 167: } ! 168: errlast=errors; ! 169: if(argv[x][0]=='-' ! 170: #if !defined(__unix__) /* just for backwards compatibility */ ! 171: || argv[x][0]=='/' ! 172: #endif ! 173: ) { ! 174: for(y=1;argv[x][y];y++) ! 175: switch(toupper(argv[x][y])) { ! 176: case 'Q': ! 177: beep=""; ! 178: break; ! 179: case 'B': ! 180: beep="\a"; ! 181: break; ! 182: case 'P': ! 183: pause_on_error=TRUE; ! 184: break; ! 185: case 'S': ! 186: stop_on_error=TRUE; ! 187: break; ! 188: case 'T': ! 189: chkxlat=FALSE; ! 190: break; ! 191: case 'A': ! 192: chkalloc=FALSE; ! 193: break; ! 194: case 'H': ! 195: chkhash=FALSE; ! 196: break; ! 197: case 'E': ! 198: extinfo=TRUE; ! 199: break; ! 200: default: ! 201: printf("%s",usage); ! 202: exit(1); ! 203: } ! 204: continue; ! 205: } ! 206: ! 207: SAFECOPY(smb.file,argv[x]); ! 208: p=strrchr(smb.file,'.'); ! 209: s=strrchr(smb.file,'\\'); ! 210: if(p>s) *p=0; ! 211: ! 212: sprintf(str,"%s.shd",smb.file); ! 213: if(!fexist(str)) { ! 214: printf("\n%s doesn't exist.\n",smb.file); ! 215: continue; ! 216: } ! 217: ! 218: fprintf(stderr,"\nChecking %s Headers\n\n",smb.file); ! 219: ! 220: smb.retry_time=30; ! 221: if((i=smb_open(&smb))!=0) { ! 222: printf("smb_open returned %d: %s\n",i,smb.last_error); ! 223: errors++; ! 224: continue; ! 225: } ! 226: ! 227: length=filelength(fileno(smb.shd_fp)); ! 228: if(length<sizeof(smbhdr_t)) { ! 229: printf("Empty\n"); ! 230: smb_close(&smb); ! 231: continue; ! 232: } ! 233: ! 234: if((i=smb_locksmbhdr(&smb))!=0) { ! 235: smb_close(&smb); ! 236: printf("smb_locksmbhdr returned %d: %s\n",i,smb.last_error); ! 237: errors++; ! 238: continue; ! 239: } ! 240: ! 241: if((length/SHD_BLOCK_LEN)*sizeof(ulong)) { ! 242: if((number=(ulong *)malloc(((length/SHD_BLOCK_LEN)+2)*sizeof(ulong))) ! 243: ==NULL) { ! 244: printf("Error allocating %lu bytes of memory\n" ! 245: ,(length/SHD_BLOCK_LEN)*sizeof(ulong)); ! 246: return(++errors); ! 247: } ! 248: } ! 249: else ! 250: number=NULL; ! 251: ! 252: if(chkalloc && !(smb.status.attr&SMB_HYPERALLOC)) { ! 253: if((i=smb_open_ha(&smb))!=0) { ! 254: printf("smb_open_ha returned %d: %s\n",i,smb.last_error); ! 255: return(++errors); ! 256: } ! 257: ! 258: if((i=smb_open_da(&smb))!=0) { ! 259: printf("smb_open_da returned %d: %s\n",i,smb.last_error); ! 260: return(++errors); ! 261: } ! 262: } ! 263: ! 264: headers=deleted=orphan=dupenumhdr=attr=zeronum=timeerr=lockerr=hdrerr=0; ! 265: subjcrc=fromcrc=tocrc=0; ! 266: hdrnumerr=hdrlenerr=0; ! 267: actalloc=datactalloc=deldatblocks=delhdrblocks=xlaterr=0; ! 268: lzhblocks=lzhsaved=acthdrblocks=actdatblocks=0; ! 269: getbodyerr=gettailerr=0; ! 270: hasherr=0; ! 271: unvalidated=0; ! 272: intransit=0; ! 273: acthdrblocks=actdatblocks=0; ! 274: dfieldlength=dfieldoffset=0; ! 275: ! 276: for(l=smb.status.header_offset;l<length;l+=size) { ! 277: size=SHD_BLOCK_LEN; ! 278: fprintf(stderr,"\r%2lu%% ",(long)(100.0/((float)length/l))); ! 279: memset(&msg,0,sizeof(msg)); ! 280: msg.idx.offset=l; ! 281: msgerr=FALSE; ! 282: if((i=smb_lockmsghdr(&smb,&msg))!=0) { ! 283: printf("\n(%06lX) smb_lockmsghdr returned %d: %s\n",l,i,smb.last_error); ! 284: lockerr++; ! 285: headers++; ! 286: continue; ! 287: } ! 288: if((i=smb_getmsghdr(&smb,&msg))!=0) { ! 289: smb_unlockmsghdr(&smb,&msg); ! 290: if(chkalloc && !(smb.status.attr&SMB_HYPERALLOC)) { ! 291: fseek(smb.sha_fp ! 292: ,(l-smb.status.header_offset)/SHD_BLOCK_LEN,SEEK_SET); ! 293: j=fgetc(smb.sha_fp); ! 294: if(j) { /* Allocated block or at EOF */ ! 295: printf("%s\n(%06lX) smb_getmsghdr returned %d: %s\n",beep,l,i,smb.last_error); ! 296: hdrerr++; ! 297: } ! 298: else ! 299: delhdrblocks++; ! 300: } ! 301: else { ! 302: /* printf("%s\n(%06lX) smb_getmsghdr returned %d\n",beep,l,i); */ ! 303: delhdrblocks++; ! 304: } ! 305: continue; ! 306: } ! 307: smb_unlockmsghdr(&smb,&msg); ! 308: size=smb_hdrblocks(smb_getmsghdrlen(&msg))*SHD_BLOCK_LEN; ! 309: ! 310: truncsp(msg.from); ! 311: strip_ctrl(msg.from); ! 312: fprintf(stderr,"#%-5lu (%06lX) %-25.25s ",msg.hdr.number,l,msg.from); ! 313: ! 314: if(msg.hdr.length!=smb_getmsghdrlen(&msg)) { ! 315: fprintf(stderr,"%sHeader length mismatch\n",beep); ! 316: msgerr=TRUE; ! 317: if(extinfo) ! 318: printf("MSGERR: Header length (%hu) does not match calculcated length (%lu)\n" ! 319: ,msg.hdr.length,smb_getmsghdrlen(&msg)); ! 320: hdrlenerr++; ! 321: } ! 322: ! 323: /* Test reading of the message text (body and tails) */ ! 324: if(msg.hdr.attr&MSG_DELETE) ! 325: body=tail=NULL; ! 326: else { ! 327: if((body=smb_getmsgtxt(&smb,&msg,GETMSGTXT_BODY_ONLY))==NULL) { ! 328: fprintf(stderr,"%sGet text body failure\n",beep); ! 329: msgerr=TRUE; ! 330: if(extinfo) ! 331: printf("MSGERR: %s\n", smb.last_error); ! 332: getbodyerr++; ! 333: } ! 334: if((tail=smb_getmsgtxt(&smb,&msg,GETMSGTXT_TAIL_ONLY))==NULL) { ! 335: fprintf(stderr,"%sGet text tail failure\n",beep); ! 336: msgerr=TRUE; ! 337: if(extinfo) ! 338: printf("MSGERR: %s\n", smb.last_error); ! 339: gettailerr++; ! 340: } ! 341: } ! 342: ! 343: if(!(smb.status.attr&SMB_EMAIL) && chkhash) { ! 344: /* Look-up the message hashes */ ! 345: hashes=smb_msghashes(&msg,body); ! 346: if(hashes!=NULL ! 347: && hashes[0]!=NULL ! 348: && (i=smb_findhash(&smb,hashes,NULL,SMB_HASH_SOURCE_ALL,/* mark */TRUE )) ! 349: !=SMB_SUCCESS) { ! 350: for(h=0;hashes[h]!=NULL;h++) { ! 351: if(hashes[h]->flags&SMB_HASH_MARKED) ! 352: continue; ! 353: fprintf(stderr,"%sFailed to find %s hash\n" ! 354: ,beep,smb_hashsourcetype(hashes[h]->source)); ! 355: msgerr=TRUE; ! 356: if(extinfo) { ! 357: printf("MSGERR: %d searching for %s: %s\n" ! 358: ,i ! 359: ,smb_hashsourcetype(hashes[h]->source) ! 360: ,smb_hashsource(&msg,hashes[h]->source)); ! 361: #ifdef _DEBUG ! 362: printf("\n"); ! 363: printf("%-10s: %s\n", "Source", smb_hashsourcetype(hashes[h]->source)); ! 364: printf("%-10s: %lu\n", "Length", hashes[h]->length); ! 365: printf("%-10s: %x\n", "Flags", hashes[h]->flags); ! 366: if(hashes[h]->flags&SMB_HASH_CRC16) ! 367: printf("%-10s: %04x\n", "CRC-16", hashes[h]->crc16); ! 368: if(hashes[h]->flags&SMB_HASH_CRC32) ! 369: printf("%-10s: %08lx\n","CRC-32", hashes[h]->crc32); ! 370: if(hashes[h]->flags&SMB_HASH_MD5) ! 371: printf("%-10s: %s\n", "MD5", MD5_hex(str,hashes[h]->md5)); ! 372: ! 373: #endif ! 374: } ! 375: hasherr++; ! 376: } ! 377: } ! 378: ! 379: smb_close_hash(&smb); /* just incase */ ! 380: ! 381: FREE_LIST(hashes,i); ! 382: } ! 383: FREE_AND_NULL(body); ! 384: FREE_AND_NULL(tail); ! 385: ! 386: lzhmsg=FALSE; ! 387: if(msg.hdr.attr&MSG_DELETE) { ! 388: deleted++; ! 389: if(number) ! 390: number[headers]=0; ! 391: if(smb.status.attr&SMB_HYPERALLOC) ! 392: deldatblocks+=smb_datblocks(smb_getmsgdatlen(&msg)); ! 393: } ! 394: else { ! 395: actdatblocks+=smb_datblocks(smb_getmsgdatlen(&msg)); ! 396: if(msg.hdr.number>smb.status.last_msg) { ! 397: fprintf(stderr,"%sOut-Of-Range message number\n",beep); ! 398: msgerr=TRUE; ! 399: if(extinfo) ! 400: printf("MSGERR: Header number (%lu) greater than last (%lu)\n" ! 401: ,msg.hdr.number,smb.status.last_msg); ! 402: hdrnumerr++; ! 403: } ! 404: if(smb_getmsgidx(&smb,&msg)) { ! 405: fprintf(stderr,"%sNot found in index\n",beep); ! 406: msgerr=TRUE; ! 407: if(extinfo) ! 408: printf("MSGERR: Header number (%lu) not found in index\n" ! 409: ,msg.hdr.number); ! 410: orphan++; ! 411: } ! 412: else { ! 413: if(msg.hdr.attr!=msg.idx.attr) { ! 414: fprintf(stderr,"%sAttributes mismatch\n",beep); ! 415: msgerr=TRUE; ! 416: if(extinfo) ! 417: printf("MSGERR: Header attributes (%04X) do not match index " ! 418: "attributes (%04X)\n" ! 419: ,msg.hdr.attr,msg.idx.attr); ! 420: attr++; ! 421: } ! 422: if(msg.hdr.when_imported.time!=msg.idx.time) { ! 423: fprintf(stderr,"%sImport date/time mismatch\n",beep); ! 424: msgerr=TRUE; ! 425: if(extinfo) ! 426: printf("MSGERR: Header import date/time does not match " ! 427: "index import date/time\n"); ! 428: timeerr++; ! 429: } ! 430: if(msg.idx.subj!=smb_subject_crc(msg.subj)) { ! 431: fprintf(stderr,"%sSubject CRC mismatch\n",beep); ! 432: msgerr=TRUE; ! 433: if(extinfo) ! 434: printf("MSGERR: Subject (%04X) does not match index " ! 435: "CRC (%04X)\n" ! 436: ,smb_subject_crc(msg.subj),msg.idx.subj); ! 437: subjcrc++; ! 438: } ! 439: if(smb.status.attr&SMB_EMAIL ! 440: && (msg.from_ext!=NULL || msg.idx.from) ! 441: && (msg.from_ext==NULL || msg.idx.from!=atoi(msg.from_ext))) { ! 442: fprintf(stderr,"%sFrom extension mismatch\n",beep); ! 443: msgerr=TRUE; ! 444: if(extinfo) ! 445: printf("MSGERR: From extension (%s) does not match index " ! 446: "(%u)\n" ! 447: ,msg.from_ext,msg.idx.from); ! 448: fromcrc++; ! 449: } ! 450: if(!(smb.status.attr&SMB_EMAIL) ! 451: && msg.idx.from!=smb_name_crc(msg.from)) { ! 452: fprintf(stderr,"%sFrom CRC mismatch\n",beep); ! 453: msgerr=TRUE; ! 454: if(extinfo) ! 455: printf("MSGERR: From (%04X) does not match index " ! 456: "CRC (%04X)\n" ! 457: ,smb_name_crc(msg.from),msg.idx.from); ! 458: fromcrc++; ! 459: } ! 460: if(smb.status.attr&SMB_EMAIL ! 461: && (msg.to_ext!=NULL || msg.idx.to) ! 462: && (msg.to_ext==NULL || msg.idx.to!=atoi(msg.to_ext))) { ! 463: fprintf(stderr,"%sTo extension mismatch\n",beep); ! 464: msgerr=TRUE; ! 465: if(extinfo) ! 466: printf("MSGERR: To extension (%s) does not match index " ! 467: "(%u)\n" ! 468: ,msg.to_ext,msg.idx.to); ! 469: tocrc++; ! 470: } ! 471: if(!(smb.status.attr&SMB_EMAIL) ! 472: && msg.to_ext==NULL && msg.idx.to!=smb_name_crc(msg.to)) { ! 473: fprintf(stderr,"%sTo CRC mismatch\n",beep); ! 474: msgerr=TRUE; ! 475: if(extinfo) ! 476: printf("MSGERR: To (%04X) does not match index " ! 477: "CRC (%04X)\n" ! 478: ,smb_name_crc(msg.to),msg.idx.to); ! 479: tocrc++; ! 480: } ! 481: if(msg.hdr.netattr&MSG_INTRANSIT) { ! 482: fprintf(stderr,"%sIn transit\n",beep); ! 483: msgerr=TRUE; ! 484: if(extinfo) ! 485: printf("MSGERR: Flagged 'in transit'\n"); ! 486: intransit++; ! 487: } ! 488: if((msg.hdr.attr&(MSG_MODERATED|MSG_VALIDATED)) == MSG_MODERATED) { ! 489: fprintf(stderr,"%sUnvalidated\n",beep); ! 490: msgerr=TRUE; ! 491: if(extinfo) ! 492: printf("MSGERR: Flagged 'moderated', but not yet 'validated'\n"); ! 493: unvalidated++; ! 494: } ! 495: } ! 496: if(msg.hdr.number==0) { ! 497: fprintf(stderr,"%sZero message number\n",beep); ! 498: msgerr=TRUE; ! 499: if(extinfo) ! 500: printf("MSGERR: Header number is zero (invalid)\n"); ! 501: zeronum++; ! 502: } ! 503: if(number) { ! 504: for(m=0;m<headers;m++) ! 505: if(number[m] && msg.hdr.number==number[m]) { ! 506: fprintf(stderr,"%sDuplicate message number\n",beep); ! 507: msgerr=TRUE; ! 508: if(extinfo) ! 509: printf("MSGERR: Header number (%lu) duplicated\n" ! 510: ,msg.hdr.number); ! 511: dupenumhdr++; ! 512: break; ! 513: } ! 514: number[headers]=msg.hdr.number; ! 515: } ! 516: if(chkxlat) { /* Check translation strings */ ! 517: for(i=0;i<msg.hdr.total_dfields;i++) { ! 518: fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset,SEEK_SET); ! 519: if(!fread(&xlat,2,1,smb.sdt_fp)) ! 520: xlat=0xffff; ! 521: lzh=0; ! 522: if(xlat==XLAT_LZH) { ! 523: lzh=1; ! 524: if(!fread(&xlat,2,1,smb.sdt_fp)) ! 525: xlat=0xffff; ! 526: } ! 527: if(xlat!=XLAT_NONE) { ! 528: fprintf(stderr,"%sUnsupported Xlat %04X dfield[%u]\n" ! 529: ,beep,xlat,i); ! 530: msgerr=TRUE; ! 531: if(extinfo) ! 532: printf("MSGERR: Unsupported translation type (%04X) " ! 533: "in dfield[%u] (offset %ld)\n" ! 534: ,xlat,i,msg.dfield[i].offset); ! 535: xlaterr++; ! 536: } ! 537: else { ! 538: if(lzh) { ! 539: lzhmsg=TRUE; ! 540: if(fread(&m,4,1,smb.sdt_fp)) { /* Get uncompressed len */ ! 541: lzhsaved+=(smb_datblocks(m+2) ! 542: -smb_datblocks(msg.dfield[i].length)) ! 543: *SDT_BLOCK_LEN; ! 544: lzhblocks+=smb_datblocks(msg.dfield[i].length); ! 545: } ! 546: } ! 547: } ! 548: } ! 549: } ! 550: } ! 551: ! 552: if(chkalloc && !(smb.status.attr&SMB_HYPERALLOC)) { ! 553: fseek(smb.sha_fp,(l-smb.status.header_offset)/SHD_BLOCK_LEN,SEEK_SET); ! 554: for(m=0;m<size;m+=SHD_BLOCK_LEN) { ! 555: /*** ! 556: if(msg.hdr.attr&MSG_DELETE && (i=fgetc(smb.sha_fp))!=0) { ! 557: fprintf(stderr,"%sDeleted Header Block %lu marked %02X\n" ! 558: ,beep,m/SHD_BLOCK_LEN,i); ! 559: msgerr=TRUE; ! 560: delalloc++; ! 561: } ! 562: ***/ ! 563: if(!(msg.hdr.attr&MSG_DELETE) && (i=fgetc(smb.sha_fp))!=1) { ! 564: fprintf(stderr,"%sActive Header Block %lu marked %02X\n" ! 565: ,beep,m/SHD_BLOCK_LEN,i); ! 566: msgerr=TRUE; ! 567: if(extinfo) ! 568: printf("MSGERR: Active header block %lu marked %02X " ! 569: "instead of 01\n" ! 570: ,m/SHD_BLOCK_LEN,i); ! 571: actalloc++; ! 572: } ! 573: } ! 574: ! 575: if(!(msg.hdr.attr&MSG_DELETE)) { ! 576: acthdrblocks+=(size/SHD_BLOCK_LEN); ! 577: for(n=0;n<msg.hdr.total_dfields;n++) { ! 578: if(msg.dfield[n].offset&0x80000000UL) { ! 579: msgerr=TRUE; ! 580: if(extinfo) ! 581: printf("MSGERR: Invalid Data Field [%lu] Offset: %lu\n" ! 582: ,n,msg.dfield[n].offset); ! 583: dfieldoffset++; ! 584: } ! 585: if(msg.dfield[n].length&0x80000000UL) { ! 586: msgerr=TRUE; ! 587: if(extinfo) ! 588: printf("MSGERR: Invalid Data Field [%lu] Length: %lu\n" ! 589: ,n,msg.dfield[n].length); ! 590: dfieldlength++; ! 591: } ! 592: fseek(smb.sda_fp ! 593: ,((msg.hdr.offset+msg.dfield[n].offset)/SDT_BLOCK_LEN)*2 ! 594: ,SEEK_SET); ! 595: for(m=0;m<msg.dfield[n].length;m+=SDT_BLOCK_LEN) { ! 596: if(!fread(&i,2,1,smb.sda_fp) || !i) { ! 597: fprintf(stderr ! 598: ,"%sActive Data Block %lu.%lu marked free\n" ! 599: ,beep,n,m/SHD_BLOCK_LEN); ! 600: msgerr=TRUE; ! 601: if(extinfo) ! 602: printf("MSGERR: Active Data Block %lu.%lu " ! 603: "marked free\n" ! 604: ,n,m/SHD_BLOCK_LEN); ! 605: datactalloc++; ! 606: } ! 607: } ! 608: } ! 609: } ! 610: else ! 611: delhdrblocks+=(size/SHD_BLOCK_LEN); ! 612: } ! 613: ! 614: else { /* Hyper Alloc */ ! 615: if(msg.hdr.attr&MSG_DELETE) ! 616: delhdrblocks+=(size/SHD_BLOCK_LEN); ! 617: else ! 618: acthdrblocks+=(size/SHD_BLOCK_LEN); ! 619: } ! 620: ! 621: totallzhmsgs+=lzhmsg; ! 622: headers++; ! 623: if(msgerr && extinfo) { ! 624: printf("\n"); ! 625: printf("%-20s %s\n","message base",smb.file); ! 626: smb_dump_msghdr(stdout,&msg); ! 627: printf("\n"); ! 628: } ! 629: ! 630: smb_freemsgmem(&msg); ! 631: } ! 632: ! 633: FREE_AND_NULL(number); ! 634: ! 635: fprintf(stderr,"\r%79s\r100%%\n",""); ! 636: ! 637: if(chkalloc && !(smb.status.attr&SMB_HYPERALLOC)) { ! 638: ! 639: fprintf(stderr,"\nChecking %s Data Blocks\n\n",smb.file); ! 640: ! 641: length=filelength(fileno(smb.sda_fp)); ! 642: ! 643: fseek(smb.sda_fp,0L,SEEK_SET); ! 644: for(l=0;l<length;l+=2) { ! 645: if((l%10)==0) ! 646: fprintf(stderr,"\r%2lu%% ",l ? (long)(100.0/((float)length/l)) : 0); ! 647: i=0; ! 648: if(!fread(&i,2,1,smb.sda_fp)) ! 649: break; ! 650: if(!i) ! 651: deldatblocks++; ! 652: } ! 653: ! 654: smb_close_ha(&smb); ! 655: smb_close_da(&smb); ! 656: ! 657: fprintf(stderr,"\r%79s\r100%%\n",""); ! 658: } ! 659: ! 660: total=filelength(fileno(smb.sid_fp))/sizeof(idxrec_t); ! 661: ! 662: dupenum=dupeoff=misnumbered=idxzeronum=idxnumerr=idxofferr=idxerr=delidx=0; ! 663: ! 664: if(total) { ! 665: ! 666: fprintf(stderr,"\nChecking %s Index\n\n",smb.file); ! 667: ! 668: if((offset=(ulong *)malloc(total*sizeof(ulong)))==NULL) { ! 669: printf("Error allocating %lu bytes of memory\n",total*sizeof(ulong)); ! 670: return(++errors); ! 671: } ! 672: if((number=(ulong *)malloc(total*sizeof(ulong)))==NULL) { ! 673: printf("Error allocating %lu bytes of memory\n",total*sizeof(ulong)); ! 674: return(++errors); ! 675: } ! 676: fseek(smb.sid_fp,0L,SEEK_SET); ! 677: ! 678: for(l=0;l<total;l++) { ! 679: fprintf(stderr,"\r%2lu%% %5lu ",l ? (long)(100.0/((float)total/l)) : 0,l); ! 680: if(!fread(&idx,sizeof(idxrec_t),1,smb.sid_fp)) ! 681: break; ! 682: fprintf(stderr,"#%-5lu (%06lX) 1st Pass ",idx.number,idx.offset); ! 683: if(idx.attr&MSG_DELETE) { ! 684: /* Message Disabled... why? ToDo */ ! 685: /* fprintf(stderr,"%sMarked for deletion\n",beep); */ ! 686: delidx++; ! 687: } ! 688: for(m=0;m<l;m++) ! 689: if(number[m]==idx.number) { ! 690: fprintf(stderr,"%sDuplicate message number\n",beep); ! 691: dupenum++; ! 692: break; ! 693: } ! 694: for(m=0;m<l;m++) ! 695: if(offset[m]==idx.offset) { ! 696: fprintf(stderr,"%sDuplicate offset: %lu\n",beep,idx.offset); ! 697: dupeoff++; ! 698: break; ! 699: } ! 700: if(idx.offset<smb.status.header_offset) { ! 701: fprintf(stderr,"%sInvalid offset\n",beep); ! 702: idxofferr++; ! 703: break; ! 704: } ! 705: if(idx.number==0) { ! 706: fprintf(stderr,"%sZero message number\n",beep); ! 707: idxzeronum++; ! 708: break; ! 709: } ! 710: if(idx.number>smb.status.last_msg) { ! 711: fprintf(stderr,"%sOut-Of-Range message number\n",beep); ! 712: idxnumerr++; ! 713: break; ! 714: } ! 715: number[l]=idx.number; ! 716: offset[l]=idx.offset; ! 717: } ! 718: ! 719: if(l<total) { ! 720: fprintf(stderr,"%sError reading index record\n",beep); ! 721: idxerr=1; ! 722: } ! 723: else { ! 724: fprintf(stderr,"\r%79s\r",""); ! 725: for(m=0;m<total;m++) { ! 726: fprintf(stderr,"\r%2lu%% %5lu ",m ? (long)(100.0/((float)total/m)) : 0,m); ! 727: fprintf(stderr,"#%-5lu (%06lX) 2nd Pass ",number[m],offset[m]); ! 728: for(n=0;n<m;n++) ! 729: if(number[m] && number[n] && number[m]<number[n]) { ! 730: fprintf(stderr,"%sMisordered message number\n",beep); ! 731: misnumbered++; ! 732: number[n]=0; ! 733: break; ! 734: } ! 735: } ! 736: fprintf(stderr,"\r%79s\r100%%\n",""); ! 737: } ! 738: FREE_AND_NULL(number); ! 739: FREE_AND_NULL(offset); ! 740: ! 741: } /* if(total) */ ! 742: ! 743: totalmsgs+=smb.status.total_msgs; ! 744: totalmsgbytes+=(acthdrblocks*SHD_BLOCK_LEN)+(actdatblocks*SDT_BLOCK_LEN); ! 745: totaldelmsgs+=deleted; ! 746: totallzhsaved+=lzhsaved; ! 747: printf("\n"); ! 748: printf("%-35.35s (=): %lu\n" ! 749: ,"Status Total" ! 750: ,smb.status.total_msgs); ! 751: printf("%-35.35s (=): %lu\n" ! 752: ,"Total Indexes" ! 753: ,total); ! 754: printf("%-35.35s (=): %lu\n" ! 755: ,"Active Indexes" ! 756: ,total-delidx); ! 757: printf("%-35.35s (=): %lu\n" ! 758: ,"Active Headers" ! 759: ,headers-deleted); ! 760: printf("%-35.35s ( ): %-8lu %13s bytes used\n" ! 761: ,"Active Header Blocks" ! 762: ,acthdrblocks,ultoac(acthdrblocks*SHD_BLOCK_LEN,str)); ! 763: printf("%-35.35s ( ): %-8lu %13s bytes used\n" ! 764: ,"Active Data Blocks" ! 765: ,actdatblocks,ultoac(actdatblocks*SDT_BLOCK_LEN,str)); ! 766: if(lzhblocks) ! 767: printf("%-35.35s ( ): %-8lu %13s bytes saved\n" ! 768: ,"Active LZH Compressed Data Blocks" ! 769: ,lzhblocks,ultoac(lzhsaved,str)); ! 770: printf("%-35.35s ( ): %lu\n" ! 771: ,"Header Records" ! 772: ,headers); ! 773: printf("%-35.35s ( ): %lu\n" ! 774: ,"Deleted Indexes" ! 775: ,delidx); ! 776: printf("%-35.35s ( ): %lu\n" ! 777: ,"Deleted Headers" ! 778: ,deleted); ! 779: printf("%-35.35s ( ): %-8lu %13s bytes used\n" ! 780: ,"Deleted Header Blocks" ! 781: ,delhdrblocks,ultoac(delhdrblocks*SHD_BLOCK_LEN,str)); ! 782: packable+=(delhdrblocks*SHD_BLOCK_LEN); ! 783: printf("%-35.35s ( ): %-8lu %13s bytes used\n" ! 784: ,"Deleted Data Blocks" ! 785: ,deldatblocks,ultoac(deldatblocks*SDT_BLOCK_LEN,str)); ! 786: packable+=(deldatblocks*SDT_BLOCK_LEN); ! 787: ! 788: if(orphan) ! 789: printf("%-35.35s (!): %lu\n" ! 790: ,"Orphaned Headers" ! 791: ,orphan); ! 792: if(idxzeronum) ! 793: printf("%-35.35s (!): %lu\n" ! 794: ,"Zeroed Index Numbers" ! 795: ,idxzeronum); ! 796: if(zeronum) ! 797: printf("%-35.35s (!): %lu\n" ! 798: ,"Zeroed Header Numbers" ! 799: ,zeronum); ! 800: if(idxofferr) ! 801: printf("%-35.35s (!): %lu\n" ! 802: ,"Invalid Index Offsets" ! 803: ,idxofferr); ! 804: if(dupenum) ! 805: printf("%-35.35s (!): %lu\n" ! 806: ,"Duplicate Index Numbers" ! 807: ,dupenum); ! 808: if(dupeoff) ! 809: printf("%-35.35s (!): %lu\n" ! 810: ,"Duplicate Index Offsets" ! 811: ,dupeoff); ! 812: if(dupenumhdr) ! 813: printf("%-35.35s (!): %lu\n" ! 814: ,"Duplicate Header Numbers" ! 815: ,dupenumhdr); ! 816: if(misnumbered) ! 817: printf("%-35.35s (!): %lu\n" ! 818: ,"Misordered Index Numbers" ! 819: ,misnumbered); ! 820: if(lockerr) ! 821: printf("%-35.35s (!): %lu\n" ! 822: ,"Unlockable Header Records" ! 823: ,lockerr); ! 824: if(hdrerr) ! 825: printf("%-35.35s (!): %lu\n" ! 826: ,"Unreadable Header Records" ! 827: ,hdrerr); ! 828: if(idxnumerr) ! 829: printf("%-35.35s (!): %lu\n" ! 830: ,"Out-Of-Range Index Numbers" ! 831: ,idxnumerr); ! 832: if(hdrnumerr) ! 833: printf("%-35.35s (!): %lu\n" ! 834: ,"Out-Of-Range Header Numbers" ! 835: ,hdrnumerr); ! 836: if(hdrlenerr) ! 837: printf("%-35.35s (!): %lu\n" ! 838: ,"Mismatched Header Lengths" ! 839: ,hdrlenerr); ! 840: #define INDXERR "Index/Header Mismatch: " ! 841: if(attr) ! 842: printf("%-35.35s (!): %lu\n" ! 843: ,INDXERR "Attributes" ! 844: ,attr); ! 845: if(timeerr) ! 846: printf("%-35.35s (!): %lu\n" ! 847: ,INDXERR "Import Time" ! 848: ,timeerr); ! 849: if(subjcrc) ! 850: printf("%-35.35s (!): %lu\n" ! 851: ,INDXERR "Subject CRCs" ! 852: ,subjcrc); ! 853: if(fromcrc) ! 854: printf("%-35.35s (!): %lu\n" ! 855: ,smb.status.attr&SMB_EMAIL ? INDXERR "From Ext" : INDXERR "From CRCs" ! 856: ,fromcrc); ! 857: if(tocrc) ! 858: printf("%-35.35s (!): %lu\n" ! 859: ,smb.status.attr&SMB_EMAIL ? INDXERR "To Ext" : INDXERR "To CRCs" ! 860: ,tocrc); ! 861: if(intransit) ! 862: printf("%-35.35s (?): %lu\n" ! 863: ,"Message flagged as 'In Transit'" ! 864: ,intransit); ! 865: if(unvalidated) ! 866: printf("%-35.35s (?): %lu\n" ! 867: ,"Moderated message not yet validated" ! 868: ,unvalidated); ! 869: if(getbodyerr) ! 870: printf("%-35.35s (!): %lu\n" ! 871: ,"Message Body Text Read Failures" ! 872: ,getbodyerr); ! 873: if(gettailerr) ! 874: printf("%-35.35s (!): %lu\n" ! 875: ,"Message Tail Text Read Failures" ! 876: ,gettailerr); ! 877: if(xlaterr) ! 878: printf("%-35.35s (!): %lu\n" ! 879: ,"Unsupported Translation Types" ! 880: ,xlaterr); ! 881: if(hasherr) ! 882: printf("%-35.35s (!): %lu\n" ! 883: ,"Missing Hash Records" ! 884: ,hasherr); ! 885: if(datactalloc) ! 886: printf("%-35.35s (!): %lu\n" ! 887: ,"Misallocated Active Data Blocks" ! 888: ,datactalloc); ! 889: if(actalloc) ! 890: printf("%-35.35s (!): %lu\n" ! 891: ,"Misallocated Active Header Blocks" ! 892: ,actalloc); ! 893: /*** ! 894: if(delalloc) ! 895: printf("%-35.35s (!): %lu\n" ! 896: ,"Misallocated Deleted Header Blocks" ! 897: ,delalloc); ! 898: ***/ ! 899: ! 900: if(dfieldoffset) ! 901: printf("%-35.35s (!): %lu\n" ! 902: ,"Invalid Data Field Offsets" ! 903: ,dfieldoffset); ! 904: ! 905: if(dfieldlength) ! 906: printf("%-35.35s (!): %lu\n" ! 907: ,"Invalid Data Field Lengths" ! 908: ,dfieldlength); ! 909: ! 910: ! 911: printf("\n%s Message Base ",smb.file); ! 912: if(/* (headers-deleted)!=smb.status.total_msgs || */ ! 913: total!=smb.status.total_msgs ! 914: || (headers-deleted)!=total-delidx ! 915: || idxzeronum || zeronum ! 916: || hdrlenerr || hasherr ! 917: || getbodyerr || gettailerr ! 918: || orphan || dupenumhdr || dupenum || dupeoff || attr ! 919: || lockerr || hdrerr || hdrnumerr || idxnumerr || idxofferr ! 920: || actalloc || datactalloc || misnumbered || timeerr ! 921: || intransit || unvalidated ! 922: || subjcrc || fromcrc || tocrc ! 923: || dfieldoffset || dfieldlength || xlaterr || idxerr) { ! 924: printf("%shas Errors!\n",beep); ! 925: errors++; ! 926: } ! 927: else ! 928: printf("is OK\n"); ! 929: ! 930: smb_unlocksmbhdr(&smb); ! 931: smb_close(&smb); ! 932: } ! 933: ! 934: if((totalmsgs && (totalmsgs!=smb.status.total_msgs || totallzhmsgs)) ! 935: || packable) ! 936: printf("\n"); ! 937: if(totalmsgs && totalmsgs!=smb.status.total_msgs) ! 938: printf("%-39.39s: %-8lu %13s bytes used\n" ! 939: ,"Total Active Messages" ! 940: ,totalmsgs,ultoac(totalmsgbytes,str)); ! 941: if(totallzhmsgs && totalmsgs!=smb.status.total_msgs) ! 942: printf("%-39.39s: %-8lu %13s bytes saved\n" ! 943: ,"Total LZH Compressed Messages" ! 944: ,totallzhmsgs,ultoac(totallzhsaved,str)); ! 945: if(packable) ! 946: printf("%-39.39s: %-8lu %13s bytes used\n" ! 947: ,"Total Deleted Messages" ! 948: ,totaldelmsgs,ultoac(packable,str)); ! 949: ! 950: if(pause_on_error && errlast!=errors) { ! 951: fprintf(stderr,"\7\nHit any key to continue..."); ! 952: if(!getch()) ! 953: getch(); ! 954: fprintf(stderr,"\n"); ! 955: } ! 956: ! 957: if(errors) ! 958: printf("\n'fixsmb' can be used to repair most message base problems.\n"); ! 959: ! 960: return(errors); ! 961: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.