Annotation of sbbs/sbbs3/chksmb.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.