Annotation of sbbs/sbbs3/smbutil.c, revision 1.1.1.1

1.1       root        1: /* smbutil.c */
                      2: 
                      3: /* Synchronet message base (SMB) utility */
                      4: 
                      5: /* $Id: smbutil.c,v 1.12 2000/11/28 02:46:10 rswindell Exp $ */
                      6: 
                      7: /****************************************************************************
                      8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                     10:  *                                                                                                                                                     *
                     11:  * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html         *
                     12:  *                                                                                                                                                     *
                     13:  * This program is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU General Public License                         *
                     15:  * as published by the Free Software Foundation; either version 2                      *
                     16:  * of the License, or (at your option) any later version.                                      *
                     17:  * See the GNU General Public License for more details: gpl.txt or                     *
                     18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
                     19:  *                                                                                                                                                     *
                     20:  * Anonymous FTP access to the most recent released source is available at     *
                     21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     22:  *                                                                                                                                                     *
                     23:  * Anonymous CVS access to the development source and modification history     *
                     24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     26:  *     (just hit return, no password is necessary)                                                     *
                     27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     28:  *                                                                                                                                                     *
                     29:  * For Synchronet coding style and modification guidelines, see                                *
                     30:  * http://www.synchro.net/source.html                                                                          *
                     31:  *                                                                                                                                                     *
                     32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     33:  * format) via e-mail to [email protected]                                                                      *
                     34:  *                                                                                                                                                     *
                     35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     36:  ****************************************************************************/
                     37: 
                     38: #define SMBUTIL_VER "2.20"
                     39: 
                     40: #define NOANALYSIS             (1L<<0)
                     41: 
                     42: #ifdef __WATCOMC__
                     43:        #define ffblk find_t
                     44:     #define findfirst(x,y,z) _dos_findfirst(x,z,y)
                     45:        #define findnext(x) _dos_findnext(x)
                     46: #endif
                     47: 
                     48: #if defined(_WIN32)
                     49:        #include <ctype.h>      /* isdigit() */
                     50:        #include <conio.h>      /* getch() */
                     51: #endif
                     52: 
                     53: /* ANSI */
                     54: #include <time.h>      /* time */
                     55: #include <errno.h>     /* errno */
                     56: #include <string.h>    /* strrchr */
                     57: 
                     58: #include "smblib.h"
                     59: #include "smbwrap.h"
                     60: #include "crc32.h"
                     61: 
                     62: #ifdef __WATCOMC__
                     63:        #include <dos.h>
                     64: #endif
                     65: 
                     66: /* gets is dangerous */
                     67: #define gets(str)  fgets((str), sizeof(str) - 1, stdin)
                     68: 
                     69: /********************/
                     70: /* Global variables */
                     71: /********************/
                     72: 
                     73: smb_t smb;
                     74: ulong mode=0L;
                     75: ushort tzone=PST;
                     76: char filein[128];
                     77: char attach[128];
                     78: 
                     79: /************************/
                     80: /* Program usage/syntax */
                     81: /************************/
                     82: 
                     83: char *usage=
                     84: "usage: smbutil [-opts] cmd <filespec.shd>\n"
                     85: "\n"
                     86: "cmd:\n"
                     87: "       l[n] = list msgs starting at number n\n"
                     88: "       r[n] = read msgs starting at number n\n"
                     89: "       v[n] = view msg headers starting at number n\n"
                     90: "       i<f> = import msg from text file f\n"
                     91: "       e<f> = import e-mail from text file f\n"
                     92: "       n<f> = import netmail from text file f\n"
                     93: "       s    = display msg base status\n"
                     94: "       c    = change msg base status\n"
                     95: "       m    = maintain msg base - delete old msgs and msgs over max\n"
                     96: "       p[k] = pack msg base (k specifies minimum packable Kbytes)\n"
                     97: "opts:\n"
                     98: "       c    = create message base if it doesn't exist\n"
                     99: "       a    = always pack msg base (disable compression analysis)\n"
                    100: "       z[n] = set time zone (n=min +/- from UT or 'EST','EDT','CST',etc)\n"
                    101: ;
                    102: 
                    103: char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
                    104: char *mon[]={"Jan","Feb","Mar","Apr","May","Jun"
                    105:             ,"Jul","Aug","Sep","Oct","Nov","Dec"};
                    106: 
                    107: /****************************************************************************/
                    108: /* Updates 16-bit "rcrc" with character 'ch'                                */
                    109: /****************************************************************************/
                    110: void ucrc16(uchar ch, ushort *rcrc) {
                    111:        ushort i, cy;
                    112:     uchar nch=ch;
                    113:  
                    114:        for (i=0; i<8; i++) {
                    115:                cy=*rcrc & 0x8000;
                    116:                *rcrc<<=1;
                    117:                if (nch & 0x80) *rcrc |= 1;
                    118:                nch<<=1;
                    119:                if (cy) *rcrc ^= 0x1021; }
                    120: }
                    121: 
                    122: /****************************************************************************/
                    123: /* Returns CRC-16 of string (not including terminating NULL)                           */
                    124: /****************************************************************************/
                    125: ushort crc16(char *str)
                    126: {
                    127:        int     i=0;
                    128:        ushort  crc=0;
                    129: 
                    130:        ucrc16(0,&crc);
                    131:        while(str[i])
                    132:                ucrc16(str[i++],&crc);
                    133:        ucrc16(0,&crc);
                    134:        ucrc16(0,&crc);
                    135:        return(crc);
                    136: }
                    137: 
                    138: void remove_re(char *str)
                    139: {
                    140:        while(!strnicmp(str,"RE:",3)) {
                    141:                strcpy(str,str+3);
                    142:                while(str[0]==SP)
                    143:                        strcpy(str,str+1); 
                    144:        }
                    145: }
                    146: 
                    147: /************************************************/
                    148: /* Truncates white-space chars off end of 'str' */
                    149: /************************************************/
                    150: static void truncsp(char *str)
                    151: {
                    152:        uint c;
                    153: 
                    154:        c=strlen(str);
                    155:        while(c && (uchar)str[c-1]<=' ') c--;
                    156:        str[c]=0;
                    157: }
                    158: 
                    159: 
                    160: 
                    161: /****************************************************************************/
                    162: /* Adds a new message to the message base                                                                      */
                    163: /****************************************************************************/
                    164: void postmsg(char type)
                    165: {
                    166:        char    str[128],buf[SDT_BLOCK_LEN];
                    167:        ushort  xlat,net;
                    168:        int     i,j,k,file;
                    169:        long    length;
                    170:        ulong   offset,crc=0xffffffffUL;
                    171:        FILE    *instream;
                    172:        smbmsg_t        msg;
                    173: 
                    174:        length=flength(filein);
                    175:        if(length<1L) {
                    176:                printf("\n\7!Invalid file size for '%s'\n",filein);
                    177:                exit(1); }
                    178:        length+=2;      /* for translation string */
                    179:        if(!(smb.status.attr&SMB_HYPERALLOC)) {
                    180:                i=smb_open_da(&smb);
                    181:                if(i) {
                    182:                        printf("\n\7!smb_open_da returned %d\n",i);
                    183:                        exit(1); }
                    184:                offset=smb_allocdat(&smb,length,1);
                    185:                smb_close_da(&smb); }
                    186:        else
                    187:                offset=smb_hallocdat(&smb);
                    188: 
                    189:        if((file=open(filein,O_RDONLY|O_BINARY))==-1
                    190:                || (instream=fdopen(file,"rb"))==NULL) {
                    191:                printf("\n\7!Error opening %s for read\n",filein);
                    192:                smb_freemsgdat(&smb,offset,length,1);
                    193:                exit(1); }
                    194:        setvbuf(instream,NULL,_IOFBF,32*1024);
                    195:        fseek(smb.sdt_fp,offset,SEEK_SET);
                    196:        xlat=XLAT_NONE;
                    197:        fwrite(&xlat,2,1,smb.sdt_fp);
                    198:        k=SDT_BLOCK_LEN-2;
                    199:        while(!feof(instream)) {
                    200:                memset(buf,0,k);
                    201:                j=fread(buf,1,k,instream);
                    202:                if(smb.status.max_crcs)
                    203:                        for(i=0;i<j;i++)
                    204:                                crc=ucrc32(buf[i],crc);
                    205:                fwrite(buf,k,1,smb.sdt_fp);
                    206:                k=SDT_BLOCK_LEN; }
                    207:        fflush(smb.sdt_fp);
                    208:        fclose(instream);
                    209:        crc=~crc;
                    210: 
                    211:        memset(&msg,0,sizeof(smbmsg_t));
                    212:        memcpy(msg.hdr.id,"SHD\x1a",4);
                    213:        msg.hdr.version=smb_ver();
                    214:        msg.hdr.when_written.time=time(NULL);
                    215:        msg.hdr.when_written.zone=tzone;
                    216:        msg.hdr.when_imported=msg.hdr.when_written;
                    217: 
                    218:        if(smb.status.max_crcs) {
                    219:                i=smb_addcrc(&smb,crc);
                    220:                if(i) {
                    221:                        printf("\n\7!smb_addcrc returned %d\n",i);
                    222:                        smb_freemsgdat(&smb,offset,length,1);
                    223:                        exit(1); } }
                    224: 
                    225:        msg.hdr.offset=offset;
                    226: 
                    227:        printf("To User Name: ");
                    228:        fgets(str,sizeof(str)-1,stdin);
                    229:        truncsp(str);
                    230:        i=smb_hfield(&msg,RECIPIENT,(ushort)strlen(str),str);
                    231:        if(i) {
                    232:                printf("\n\7!smb_hfield returned %d\n",i);
                    233:                smb_freemsgdat(&smb,offset,length,1);
                    234:                exit(1); }
                    235:        if(type=='E' || type=='N')
                    236:                smb.status.attr|=SMB_EMAIL;
                    237:        if(smb.status.attr&SMB_EMAIL) {
                    238:                printf("To User Number (0=QWKnet or Internet): ");
                    239:                gets(str);
                    240:                truncsp(str);
                    241:                i=smb_hfield(&msg,RECIPIENTEXT,(ushort)strlen(str),str);
                    242:                if(i) {
                    243:                        printf("\n\7!smb_hfield returned %d\n",i);
                    244:                        smb_freemsgdat(&smb,offset,length,1);
                    245:                        exit(1); }
                    246:                msg.idx.to=atoi(str); }
                    247:        else {
                    248:                strlwr(str);
                    249:                msg.idx.to=crc16(str); }
                    250: 
                    251:        if(smb.status.attr&SMB_EMAIL && (type=='N' || !msg.idx.to)) {
                    252:                printf("To Address: ");
                    253:                gets(str);
                    254:                truncsp(str);
                    255:                if(*str) {
                    256:                        if(strchr(str,'.'))
                    257:                                net=NET_INTERNET;
                    258:                        else
                    259:                                net=NET_QWK;
                    260:                        i=smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net);
                    261:                        if(i) {
                    262:                                printf("\n\7!smb_hfield returned %d\n",i);
                    263:                                smb_freemsgdat(&smb,offset,length,1);
                    264:                                exit(1); }
                    265:                        i=smb_hfield(&msg,RECIPIENTNETADDR,(ushort)strlen(str),str);
                    266:                        if(i) {
                    267:                                printf("\n\7!smb_hfield returned %d\n",i);
                    268:                                smb_freemsgdat(&smb,offset,length,1);
                    269:                                exit(1); } } }
                    270: 
                    271:        printf("From User Name: ");
                    272:        gets(str);
                    273:        truncsp(str);
                    274:        i=smb_hfield(&msg,SENDER,(ushort)strlen(str),str);
                    275:        if(i) {
                    276:                printf("\n\7!smb_hfield returned %d\n",i);
                    277:                smb_freemsgdat(&smb,offset,length,1);
                    278:                exit(1); }
                    279:        if(smb.status.attr&SMB_EMAIL) {
                    280:                printf("From User Number: ");
                    281:                gets(str);
                    282:                truncsp(str);
                    283:                i=smb_hfield(&msg,SENDEREXT,(ushort)strlen(str),str);
                    284:                if(i) {
                    285:                        printf("\n\7!smb_hfield returned %d\n",i);
                    286:                        smb_freemsgdat(&smb,offset,length,1);
                    287:                        exit(1); }
                    288:                msg.idx.from=atoi(str); }
                    289:        else {
                    290:                strlwr(str);
                    291:                msg.idx.from=crc16(str); }
                    292: 
                    293:        printf("Subject: ");
                    294:        gets(str);
                    295:        truncsp(str);
                    296:        i=smb_hfield(&msg,SUBJECT,(ushort)strlen(str),str);
                    297:        if(i) {
                    298:                printf("\n\7!smb_hfield returned %d\n",i);
                    299:                smb_freemsgdat(&smb,offset,length,1);
                    300:                exit(1); }
                    301:        remove_re(str);
                    302:        strlwr(str);
                    303:        msg.idx.subj=crc16(str);
                    304: 
                    305:        i=smb_dfield(&msg,TEXT_BODY,length);
                    306:        if(i) {
                    307:                printf("\n\7!smb_dfield returned %d\n",i);
                    308:                smb_freemsgdat(&smb,offset,length,1);
                    309:                exit(1); }
                    310: 
                    311:        i=smb_addmsghdr(&smb,&msg,smb.status.attr&SMB_HYPERALLOC);
                    312: 
                    313:        if(i) {
                    314:                printf("\n\7!smb_addmsghdr returned %d\n",i);
                    315:                smb_freemsgdat(&smb,offset,length,1);
                    316:                exit(1); }
                    317:        smb_freemsgmem(&msg);
                    318: 
                    319: }
                    320: 
                    321: /****************************************************************************/
                    322: /* Shows the message base header                                                                                       */
                    323: /****************************************************************************/
                    324: void showstatus(void)
                    325: {
                    326:        int i;
                    327: 
                    328:        i=smb_locksmbhdr(&smb);
                    329:        if(i) {
                    330:                printf("\n\7!smb_locksmbhdr returned %d\n",i);
                    331:                return; }
                    332:        i=smb_getstatus(&smb);
                    333:        smb_unlocksmbhdr(&smb);
                    334:        if(i) {
                    335:                printf("\n\7!smb_getstatus returned %d\n",i);
                    336:                return; }
                    337:        printf("last_msg        =%lu\n"
                    338:                   "total_msgs      =%lu\n"
                    339:                   "header_offset   =%lu\n"
                    340:                   "max_crcs        =%lu\n"
                    341:                   "max_msgs        =%lu\n"
                    342:                   "max_age         =%u\n"
                    343:                   "attr            =%04Xh\n"
                    344:                   ,smb.status.last_msg
                    345:                   ,smb.status.total_msgs
                    346:                   ,smb.status.header_offset
                    347:                   ,smb.status.max_crcs
                    348:                   ,smb.status.max_msgs
                    349:                   ,smb.status.max_age
                    350:                   ,smb.status.attr
                    351:                   );
                    352: }
                    353: 
                    354: /****************************************************************************/
                    355: /* Configure message base header                                                                                       */
                    356: /****************************************************************************/
                    357: void config(void)
                    358: {
                    359:        char max_msgs[128],max_crcs[128],max_age[128],header_offset[128],attr[128];
                    360:        int i;
                    361: 
                    362:        i=smb_locksmbhdr(&smb);
                    363:        if(i) {
                    364:                printf("\n\7!smb_locksmbhdr returned %d\n",i);
                    365:                return; }
                    366:        i=smb_getstatus(&smb);
                    367:        smb_unlocksmbhdr(&smb);
                    368:        if(i) {
                    369:                printf("\n\7!smb_getstatus returned %d\n",i);
                    370:                return; }
                    371:        printf("Header offset =%-5lu  New value (CR=No Change): "
                    372:                ,smb.status.header_offset);
                    373:        gets(header_offset);
                    374:        printf("Max msgs      =%-5lu  New value (CR=No Change): "
                    375:                ,smb.status.max_msgs);
                    376:        gets(max_msgs);
                    377:        printf("Max crcs      =%-5lu  New value (CR=No Change): "
                    378:                ,smb.status.max_crcs);
                    379:        gets(max_crcs);
                    380:        printf("Max age       =%-5u  New value (CR=No Change): "
                    381:                ,smb.status.max_age);
                    382:        gets(max_age);
                    383:        printf("Attributes    =%-5u  New value (CR=No Change): "
                    384:                ,smb.status.attr);
                    385:        gets(attr);
                    386:        i=smb_locksmbhdr(&smb);
                    387:        if(i) {
                    388:                printf("\n\7!smb_locksmbhdr returned %d\n",i);
                    389:                return; }
                    390:        i=smb_getstatus(&smb);
                    391:        if(i) {
                    392:                printf("\n\7!smb_getstatus returned %d\n",i);
                    393:                smb_unlocksmbhdr(&smb);
                    394:                return; }
                    395:        if(isdigit(max_msgs[0]))
                    396:                smb.status.max_msgs=atol(max_msgs);
                    397:        if(isdigit(max_crcs[0]))
                    398:                smb.status.max_crcs=atol(max_crcs);
                    399:        if(isdigit(max_age[0]))
                    400:                smb.status.max_age=atoi(max_age);
                    401:        if(isdigit(header_offset[0]))
                    402:                smb.status.header_offset=atol(header_offset);
                    403:        if(isdigit(attr[0]))
                    404:                smb.status.attr=atoi(attr);
                    405:        i=smb_putstatus(&smb);
                    406:        smb_unlocksmbhdr(&smb);
                    407:        if(i)
                    408:                printf("\n\7!smb_putstatus returned %d\n",i);
                    409: }
                    410: 
                    411: /****************************************************************************/
                    412: /* Lists messages' to, from, and subject                                    */
                    413: /****************************************************************************/
                    414: void listmsgs(ulong start, ulong count)
                    415: {
                    416:        int i;
                    417:        ulong l=0;
                    418:        smbmsg_t msg;
                    419: 
                    420:        if(!start)
                    421:                start=1;
                    422:        fseek(smb.sid_fp,(start-1L)*sizeof(idxrec_t),SEEK_SET);
                    423:        while(l<count) {
                    424:                if(!fread(&msg.idx,1,sizeof(idxrec_t),smb.sid_fp))
                    425:                        break;
                    426:                i=smb_lockmsghdr(&smb,&msg);
                    427:                if(i) {
                    428:                        printf("\n\7!smb_lockmsghdr returned %d\n",i);
                    429:                        break; }
                    430:                i=smb_getmsghdr(&smb,&msg);
                    431:                smb_unlockmsghdr(&smb,&msg);
                    432:                if(i) {
                    433:                        printf("\n\7!smb_getmsghdr returned %d\n",i);
                    434:                        break; }
                    435:                printf("%4lu %-25.25s %-25.25s %.20s\n"
                    436:                        ,msg.hdr.number,msg.from,msg.to,msg.subj);
                    437:                smb_freemsgmem(&msg);
                    438:                l++; }
                    439: }
                    440: 
                    441: /****************************************************************************/
                    442: /* Returns an ASCII string for FidoNet address 'addr'                       */
                    443: /****************************************************************************/
                    444: char *faddrtoa(fidoaddr_t addr)
                    445: {
                    446:        static char str[25];
                    447:        char point[25];
                    448: 
                    449:        sprintf(str,"%u:%u/%u",addr.zone,addr.net,addr.node);
                    450:        if(addr.point) {
                    451:                sprintf(point,".%u",addr.point);
                    452:                strcat(str,point); }
                    453:        return(str);
                    454: }
                    455: 
                    456: char *binstr(uchar *buf, ushort length)
                    457: {
                    458:        static char str[512];
                    459:        char tmp[128];
                    460:        int i;
                    461: 
                    462:        str[0]=0;
                    463:        for(i=0;i<length;i++)
                    464:                if(buf[i] && (buf[i]<SP || buf[i]>=0x7f) && buf[i]!=CR && buf[i]!=LF)
                    465:                        break;
                    466:        if(i==length)           /* not binary */
                    467:                return(buf);
                    468:        for(i=0;i<length;i++) {
                    469:                sprintf(tmp,"%02X ",buf[i]);
                    470:                strcat(str,tmp); 
                    471:                if(i>=100) {
                    472:                        strcat(str,"...");
                    473:                        break;
                    474:                }
                    475:        }
                    476:        return(str);
                    477: }
                    478: 
                    479: /****************************************************************************/
                    480: /* Generates a 24 character ASCII string that represents the time_t pointer */
                    481: /* Used as a replacement for ctime()                                        */
                    482: /****************************************************************************/
                    483: char *timestr(time_t *intime)
                    484: {
                    485:     static char str[256];
                    486:     char mer[3],hour;
                    487:     struct tm *gm;
                    488: 
                    489:        gm=localtime(intime);
                    490:        if(gm==NULL) {
                    491:                strcpy(str,"Invalid Time");
                    492:                return(str); }
                    493:        if(gm->tm_hour>=12) {
                    494:                if(gm->tm_hour==12)
                    495:                        hour=12;
                    496:                else
                    497:                        hour=gm->tm_hour-12;
                    498:                strcpy(mer,"pm"); }
                    499:        else {
                    500:                if(gm->tm_hour==0)
                    501:                        hour=12;
                    502:                else
                    503:                        hour=gm->tm_hour;
                    504:                strcpy(mer,"am"); }
                    505:        sprintf(str,"%s %s %02d %4d %02d:%02d %s"
                    506:                ,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year
                    507:                ,hour,gm->tm_min,mer);
                    508:        return(str);
                    509: }
                    510: 
                    511: 
                    512: /****************************************************************************/
                    513: /* Converts when_t.zone into ASCII format                                                                      */
                    514: /****************************************************************************/
                    515: char *zonestr(short zone)
                    516: {
                    517:        static char str[32];
                    518: 
                    519:        switch((ushort)zone) {
                    520:                case 0:         return("UT");
                    521:                case AST:       return("AST");
                    522:                case EST:       return("EST");
                    523:                case CST:       return("CST");
                    524:                case MST:       return("MST");
                    525:                case PST:       return("PST");
                    526:                case YST:       return("YST");
                    527:                case HST:       return("HST");
                    528:                case BST:       return("BST");
                    529:                case ADT:       return("ADT");
                    530:                case EDT:       return("EDT");
                    531:                case CDT:       return("CDT");
                    532:                case MDT:       return("MDT");
                    533:                case PDT:       return("PDT");
                    534:                case YDT:       return("YDT");
                    535:                case HDT:       return("HDT");
                    536:                case BDT:       return("BDT");
                    537:                case MID:       return("MID");
                    538:                case VAN:       return("VAN");
                    539:                case EDM:       return("EDM");
                    540:                case WIN:       return("WIN");
                    541:                case BOG:       return("BOG");
                    542:                case CAR:       return("CAR");
                    543:                case RIO:       return("RIO");
                    544:                case FER:       return("FER");
                    545:                case AZO:       return("AZO");
                    546:                case LON:       return("LON");
                    547:                case BER:       return("BER");
                    548:                case ATH:       return("ATH");
                    549:                case MOS:       return("MOS");
                    550:                case DUB:       return("DUB");
                    551:                case KAB:       return("KAB");
                    552:                case KAR:       return("KAR");
                    553:                case BOM:       return("BOM");
                    554:                case KAT:       return("KAT");
                    555:                case DHA:       return("DHA");
                    556:                case BAN:       return("BAN");
                    557:                case HON:       return("HON");
                    558:                case TOK:       return("TOK");
                    559:                case SYD:       return("SYD");
                    560:                case NOU:       return("NOU");
                    561:                case WEL:       return("WEL");
                    562:                }
                    563: 
                    564:        sprintf(str,"%02d:%02u",zone/60,zone<0 ? (-zone)%60 : zone%60);
                    565:        return(str);
                    566: }
                    567:                         
                    568: 
                    569: /****************************************************************************/
                    570: /* Displays message header information                                                                         */
                    571: /****************************************************************************/
                    572: void viewmsgs(ulong start, ulong count)
                    573: {
                    574:        char when_written[128]
                    575:                ,when_imported[128];
                    576:        int i;
                    577:        ulong l=0;
                    578:        smbmsg_t msg;
                    579: 
                    580:        if(!start)
                    581:                start=1;
                    582:        fseek(smb.sid_fp,(start-1L)*sizeof(idxrec_t),SEEK_SET);
                    583:        while(l<count) {
                    584:                if(!fread(&msg.idx,1,sizeof(idxrec_t),smb.sid_fp))
                    585:                        break;
                    586:                i=smb_lockmsghdr(&smb,&msg);
                    587:                if(i) {
                    588:                        printf("\n\7!smb_lockmsghdr returned %d\n",i);
                    589:                        break; }
                    590:                i=smb_getmsghdr(&smb,&msg);
                    591:                smb_unlockmsghdr(&smb,&msg);
                    592:                if(i) {
                    593:                        printf("\n\7!smb_getmsghdr returned %d\n",i);
                    594:                        break; }
                    595: 
                    596:                sprintf(when_written,"%.24s %s"
                    597:                        ,timestr((time_t*)&msg.hdr.when_written.time)
                    598:                        ,zonestr(msg.hdr.when_written.zone));
                    599:                sprintf(when_imported,"%.24s %s"
                    600:                        ,timestr((time_t*)&msg.hdr.when_imported.time)
                    601:                        ,zonestr(msg.hdr.when_imported.zone));
                    602: 
                    603:                printf( "%-20.20s %s\n"
                    604:                                "%-20.20s %s\n"
                    605:                                "%-20.20s %s\n"
                    606:                                "%-20.20s %04Xh\n"
                    607:                                "%-20.20s %04Xh\n"
                    608:                                "%-20.20s %u\n"
                    609:                                "%-20.20s %04Xh\n"
                    610:                                "%-20.20s %08lXh\n"
                    611:                                "%-20.20s %08lXh\n"
                    612:                                "%-20.20s %s\n"
                    613:                                "%-20.20s %s\n"
                    614:                                "%-20.20s %ld (%ld)\n"
                    615:                                "%-20.20s %ld\n"
                    616:                                "%-20.20s %ld\n"
                    617:                                "%-20.20s %ld\n"
                    618:                                "%-20.20s %s\n"
                    619:                                "%-20.20s %06lXh\n"
                    620:                                "%-20.20s %u\n",
                    621: 
                    622:                        "subj",
                    623:                        msg.subj,
                    624: 
                    625:                        "from",
                    626:                        msg.from,
                    627: 
                    628:                        "to",
                    629:                        msg.to,
                    630: 
                    631:                        "type",
                    632:                        msg.hdr.type,
                    633: 
                    634:                        "version",
                    635:                        msg.hdr.version,
                    636: 
                    637:                        "length",
                    638:                        msg.hdr.length,
                    639: 
                    640:                        "attr",
                    641:                        msg.hdr.attr,
                    642: 
                    643:                        "auxattr",
                    644:                        msg.hdr.auxattr,
                    645: 
                    646:                        "netattr",
                    647:                        msg.hdr.netattr,
                    648: 
                    649:                        "when_written",
                    650:                        when_written,
                    651: 
                    652:                        "when_imported",
                    653:                        when_imported,
                    654: 
                    655:                        "number",
                    656:                        msg.hdr.number,
                    657:                        ftell(smb.sid_fp)/sizeof(idxrec_t),
                    658: 
                    659:                        "thread_orig",
                    660:                        msg.hdr.thread_orig,
                    661: 
                    662:                        "thread_next",
                    663:                        msg.hdr.thread_next,
                    664: 
                    665:                        "thread_first",
                    666:                        msg.hdr.thread_first,
                    667: 
                    668:                        "reserved[16]",
                    669:                        binstr(msg.hdr.reserved,16),
                    670: 
                    671:                        "offset",
                    672:                        msg.hdr.offset,
                    673: 
                    674:                        "total_dfields",
                    675:                        msg.hdr.total_dfields
                    676:                        );
                    677:                for(i=0;i<msg.hdr.total_dfields;i++)
                    678:                        printf("dfield[%02u].type      %02Xh\n"
                    679:                                   "dfield[%02u].offset    %lu\n"
                    680:                                   "dfield[%02u].length    %lu\n"
                    681:                                   ,i,msg.dfield[i].type
                    682:                                   ,i,msg.dfield[i].offset
                    683:                                   ,i,msg.dfield[i].length);
                    684: 
                    685:                for(i=0;i<msg.total_hfields;i++)
                    686:                        printf("hfield[%02u].type      %02Xh\n"
                    687:                                   "hfield[%02u].length    %d\n"
                    688:                                   "hfield[%02u]_dat       %s\n"
                    689:                                   ,i,msg.hfield[i].type
                    690:                                   ,i,msg.hfield[i].length
                    691:                                   ,i,binstr(msg.hfield_dat[i],msg.hfield[i].length));
                    692: 
                    693:                if(msg.from_net.type)
                    694:                        printf("from_net.type        %02Xh\n"
                    695:                                   "from_net.addr        %s\n"
                    696:                                ,msg.from_net.type
                    697:                                ,msg.from_net.type==NET_FIDO
                    698:                                ? faddrtoa(*(fidoaddr_t *)msg.from_net.addr) : msg.from_net.addr);
                    699: 
                    700:                if(msg.to_net.type)
                    701:                        printf("to_net.type          %02Xh\n"
                    702:                                   "to_net.addr          %s\n"
                    703:                                ,msg.to_net.type
                    704:                                ,msg.to_net.type==NET_FIDO
                    705:                                ? faddrtoa(*(fidoaddr_t *)msg.to_net.addr) : msg.to_net.addr);
                    706: 
                    707:                if(msg.replyto_net.type)
                    708:                        printf("replyto_net.type     %02Xh\n"
                    709:                                   "replyto_net.addr     %s\n"
                    710:                                ,msg.replyto_net.type
                    711:                                ,msg.replyto_net.type==NET_FIDO
                    712:                                ? faddrtoa(*(fidoaddr_t *)msg.replyto_net.addr)
                    713:                                        : msg.replyto_net.addr);
                    714: 
                    715:                printf("from_agent           %02Xh\n"
                    716:                           "to_agent             %02Xh\n"
                    717:                           "replyto_agent        %02Xh\n"
                    718:                           ,msg.from_agent
                    719:                           ,msg.to_agent
                    720:                           ,msg.replyto_agent);
                    721: 
                    722:                printf("\n");
                    723:                smb_freemsgmem(&msg);
                    724:                l++; }
                    725: }
                    726: 
                    727: /****************************************************************************/
                    728: /* Maintain message base - deletes messages older than max age (in days)       */
                    729: /* or messages that exceed maximum                                                                                     */
                    730: /****************************************************************************/
                    731: void maint(void)
                    732: {
                    733:        int i;
                    734:        ulong l,m,n,f,flagged=0;
                    735:        time_t now;
                    736:        smbmsg_t msg;
                    737:        idxrec_t HUGE16 *idx;
                    738: 
                    739:        printf("Maintaining %s\r\n",smb.file);
                    740:        now=time(NULL);
                    741:        i=smb_locksmbhdr(&smb);
                    742:        if(i) {
                    743:                printf("\n\7!smb_locksmbhdr returned %d\n",i);
                    744:                return; }
                    745:        i=smb_getstatus(&smb);
                    746:        if(i) {
                    747:                smb_unlocksmbhdr(&smb);
                    748:                printf("\n\7!smb_getstatus returned %d\n",i);
                    749:                return; }
                    750:        if(!smb.status.total_msgs) {
                    751:                smb_unlocksmbhdr(&smb);
                    752:                printf("Empty\n");
                    753:                return; }
                    754:        printf("Loading index...\n");
                    755:        if((idx=(idxrec_t *)LMALLOC(sizeof(idxrec_t)*smb.status.total_msgs))
                    756:                ==NULL) {
                    757:                smb_unlocksmbhdr(&smb);
                    758:                printf("\n\7!Error allocating %lu bytes of memory\n"
                    759:                        ,sizeof(idxrec_t)*smb.status.total_msgs);
                    760:                return; }
                    761:        fseek(smb.sid_fp,0L,SEEK_SET);
                    762:        for(l=0;l<smb.status.total_msgs;l++) {
                    763:                printf("%lu of %lu\r"
                    764:                        ,l+1,smb.status.total_msgs);
                    765:                if(!fread(&idx[l],1,sizeof(idxrec_t),smb.sid_fp))
                    766:                        break; }
                    767:        printf("\nDone.\n\n");
                    768: 
                    769:        printf("Scanning for pre-flagged messages...\n");
                    770:        for(m=0;m<l;m++) {
                    771:                printf("\r%2u%%",m ? (long)(100.0/((float)l/m)) : 0);
                    772:                if(idx[m].attr&MSG_DELETE)
                    773:                        flagged++; }
                    774:        printf("\r100%% (%lu pre-flagged for deletion)\n",flagged);
                    775: 
                    776:        if(smb.status.max_age) {
                    777:                printf("Scanning for messages more than %u days old...\n"
                    778:                        ,smb.status.max_age);
                    779:                for(m=f=0;m<l;m++) {
                    780:                        printf("\r%2u%%",m ? (long)(100.0/((float)l/m)) : 0);
                    781:                        if(idx[m].attr&(MSG_PERMANENT|MSG_DELETE))
                    782:                                continue;
                    783:                        if((ulong)now>idx[m].time && (now-idx[m].time)/(24L*60L*60L)
                    784:                                >smb.status.max_age) {
                    785:                                f++;
                    786:                                flagged++;
                    787:                                idx[m].attr|=MSG_DELETE; } }  /* mark for deletion */
                    788:                printf("\r100%% (%lu flagged for deletion)\n",f); }
                    789: 
                    790:        printf("Scanning for read messages to be killed...\n");
                    791:        for(m=f=0;m<l;m++) {
                    792:                printf("\r%2u%%",m ? (long)(100.0/((float)l/m)) : 0);
                    793:                if(idx[m].attr&(MSG_PERMANENT|MSG_DELETE))
                    794:                        continue;
                    795:                if((idx[m].attr&(MSG_READ|MSG_KILLREAD))==(MSG_READ|MSG_KILLREAD)) {
                    796:                        f++;
                    797:                        flagged++;
                    798:                        idx[m].attr|=MSG_DELETE; } }
                    799:        printf("\r100%% (%lu flagged for deletion)\n",f);
                    800: 
                    801:        if(l-flagged>smb.status.max_msgs) {
                    802:                printf("Flagging excess messages for deletion...\n");
                    803:                for(m=n=0,f=flagged;l-flagged>smb.status.max_msgs && m<l;m++) {
                    804:                        if(idx[m].attr&(MSG_PERMANENT|MSG_DELETE))
                    805:                                continue;
                    806:                        printf("%lu of %lu\r",++n,(l-f)-smb.status.max_msgs);
                    807:                        flagged++;
                    808:                        idx[m].attr|=MSG_DELETE; }                      /* mark for deletion */
                    809:                printf("\nDone.\n\n"); }
                    810: 
                    811:        if(!flagged) {                          /* No messages to delete */
                    812:                LFREE(idx);
                    813:                smb_unlocksmbhdr(&smb);
                    814:                return; }
                    815: 
                    816:        if(!(mode&NOANALYSIS)) {
                    817: 
                    818:                printf("Freeing allocated header and data blocks for deleted messages...\n");
                    819:                if(!(smb.status.attr&SMB_HYPERALLOC)) {
                    820:                        i=smb_open_da(&smb);
                    821:                        if(i) {
                    822:                                smb_unlocksmbhdr(&smb);
                    823:                                printf("\n\7!smb_open_da returned %d\n",i);
                    824:                                exit(1); }
                    825:                        i=smb_open_ha(&smb);
                    826:                        if(i) {
                    827:                                smb_unlocksmbhdr(&smb);
                    828:                                printf("\n\7!smb_open_ha returned %d\n",i);
                    829:                                exit(1); } }
                    830: 
                    831:                for(m=n=0;m<l;m++) {
                    832:                        if(idx[m].attr&MSG_DELETE) {
                    833:                                printf("%lu of %lu\r",++n,flagged);
                    834:                                msg.idx=idx[m];
                    835:                                msg.hdr.number=msg.idx.number;
                    836:                                if((i=smb_getmsgidx(&smb,&msg))!=0) {
                    837:                                        printf("\n\7!smb_getmsgidx returned %d\n",i);
                    838:                                        continue; }
                    839:                                i=smb_lockmsghdr(&smb,&msg);
                    840:                                if(i) {
                    841:                                        printf("\n\7!smb_lockmsghdr returned %d\n",i);
                    842:                                        break; }
                    843:                                if((i=smb_getmsghdr(&smb,&msg))!=0) {
                    844:                                        smb_unlockmsghdr(&smb,&msg);
                    845:                                        printf("\n\7!smb_getmsghdr returned %d\n",i);
                    846:                                        break; }
                    847:                                msg.hdr.attr|=MSG_DELETE;                       /* mark header as deleted */
                    848:                                if((i=smb_putmsg(&smb,&msg))!=0) {
                    849:                                        smb_freemsgmem(&msg);
                    850:                                        smb_unlockmsghdr(&smb,&msg);
                    851:                                        printf("\n\7!smb_putmsg returned %d\n",i);
                    852:                                        break; }
                    853:                                smb_unlockmsghdr(&smb,&msg);
                    854:                                if((i=smb_freemsg(&smb,&msg))!=0) {
                    855:                                        smb_freemsgmem(&msg);
                    856:                                        printf("\n\7!smb_freemsg returned %d\n",i);
                    857:                                        break; }
                    858:                                smb_freemsgmem(&msg); } }
                    859:                if(!(smb.status.attr&SMB_HYPERALLOC)) {
                    860:                        smb_close_ha(&smb);
                    861:                        smb_close_da(&smb); }
                    862:                printf("\nDone.\n\n"); }
                    863: 
                    864:        printf("Re-writing index...\n");
                    865:        rewind(smb.sid_fp);
                    866:        if(chsize(fileno(smb.sid_fp),0L))
                    867:                printf("chsize failed!\n");
                    868:        for(m=n=0;m<l;m++) {
                    869:                if(idx[m].attr&MSG_DELETE)
                    870:                        continue;
                    871:                printf("%lu of %lu\r",++n,l-flagged);
                    872:                fwrite(&idx[m],sizeof(idxrec_t),1,smb.sid_fp); }
                    873:        printf("\nDone.\n\n");
                    874:        fflush(smb.sid_fp);
                    875: 
                    876:        LFREE(idx);
                    877:        smb.status.total_msgs-=flagged;
                    878:        smb_putstatus(&smb);
                    879:        smb_unlocksmbhdr(&smb);
                    880: }
                    881: 
                    882: 
                    883: typedef struct {
                    884:        ulong old,new;
                    885:        } datoffset_t;
                    886: 
                    887: /****************************************************************************/
                    888: /* Removes all unused blocks from SDT and SHD files                                            */
                    889: /****************************************************************************/
                    890: void packmsgs(ulong packable)
                    891: {
                    892:        uchar str[128],buf[SDT_BLOCK_LEN],ch,fname[128],tmpfname[128];
                    893:        int i,size;
                    894:        ulong l,m,n,datoffsets=0,length,total,now;
                    895:        FILE *tmp_sdt,*tmp_shd,*tmp_sid;
                    896:        smbhdr_t        hdr;
                    897:        smbmsg_t        msg;
                    898:        datoffset_t *datoffset=NULL;
                    899: 
                    900:        now=time(NULL);
                    901:        printf("Packing %s\n",smb.file);
                    902:        i=smb_locksmbhdr(&smb);
                    903:        if(i) {
                    904:                printf("\n\7!smb_locksmbhdr returned %d\n",i);
                    905:                return; }
                    906:        i=smb_getstatus(&smb);
                    907:        if(i) {
                    908:                smb_unlocksmbhdr(&smb);
                    909:                printf("\n\7!smb_getstatus returned %d\n",i);
                    910:                return; }
                    911: 
                    912:        if(!(smb.status.attr&SMB_HYPERALLOC)) {
                    913:                i=smb_open_ha(&smb);
                    914:                if(i) {
                    915:                        smb_unlocksmbhdr(&smb);
                    916:                        printf("\n\7!smb_open_ha returned %d\n",i);
                    917:                        return; }
                    918:                i=smb_open_da(&smb);
                    919:                if(i) {
                    920:                        smb_unlocksmbhdr(&smb);
                    921:                        smb_close_ha(&smb);
                    922:                        printf("\n\7!smb_open_da returned %d\n",i);
                    923:                        return; } }
                    924: 
                    925:        if(!smb.status.total_msgs) {
                    926:                printf("Empty\n");
                    927:                rewind(smb.shd_fp);
                    928:                chsize(fileno(smb.shd_fp),smb.status.header_offset);
                    929:                rewind(smb.sdt_fp);
                    930:                chsize(fileno(smb.sdt_fp),0L);
                    931:                rewind(smb.sid_fp);
                    932:                chsize(fileno(smb.sid_fp),0L);
                    933:                if(!(smb.status.attr&SMB_HYPERALLOC)) {
                    934:                        rewind(smb.sha_fp);
                    935:                        chsize(fileno(smb.sha_fp),0L);
                    936:                        rewind(smb.sda_fp);
                    937:                        chsize(fileno(smb.sda_fp),0L);
                    938:                        smb_close_ha(&smb);
                    939:                        smb_close_da(&smb); }
                    940:                smb_unlocksmbhdr(&smb);
                    941:                return; }
                    942: 
                    943: 
                    944:        if(!(smb.status.attr&SMB_HYPERALLOC) && !(mode&NOANALYSIS)) {
                    945:                printf("Analyzing data blocks...\n");
                    946: 
                    947:                length=filelength(fileno(smb.sda_fp));
                    948: 
                    949:                fseek(smb.sda_fp,0L,SEEK_SET);
                    950:                for(l=m=0;l<length;l+=2) {
                    951:                        printf("\r%2u%%  ",l ? (long)(100.0/((float)length/l)) : 0);
                    952:                        i=0;
                    953:                        if(!fread(&i,2,1,smb.sda_fp))
                    954:                                break;
                    955:                        if(!i)
                    956:                                m++; }
                    957: 
                    958:                printf("\rAnalyzing header blocks...\n");
                    959: 
                    960:                length=filelength(fileno(smb.sha_fp));
                    961: 
                    962:                fseek(smb.sha_fp,0L,SEEK_SET);
                    963:                for(l=n=0;l<length;l++) {
                    964:                        printf("\r%2u%%  ",l ? (long)(100.0/((float)length/l)) : 0);
                    965:                        ch=0;
                    966:                        if(!fread(&ch,1,1,smb.sha_fp))
                    967:                                break;
                    968:                        if(!ch)
                    969:                                n++; }
                    970: 
                    971:                if(!m && !n) {
                    972:                        printf("\rAlready compressed.\n\n");
                    973:                        smb_close_ha(&smb);
                    974:                        smb_close_da(&smb);
                    975:                        smb_unlocksmbhdr(&smb);
                    976:                        return; }
                    977: 
                    978:                if(packable && (m*SDT_BLOCK_LEN)+(n*SHD_BLOCK_LEN)<packable*1024L) {
                    979:                        printf("\rLess than %luk compressable bytes.\n\n",packable);
                    980:                        smb_close_ha(&smb);
                    981:                        smb_close_da(&smb);
                    982:                        smb_unlocksmbhdr(&smb);
                    983:                        return; }
                    984: 
                    985:                printf("\rCompressing %lu data blocks (%lu bytes)\n"
                    986:                                 "        and %lu header blocks (%lu bytes)\n"
                    987:                                  ,m,m*SDT_BLOCK_LEN,n,n*SHD_BLOCK_LEN); }
                    988: 
                    989:        if(!(smb.status.attr&SMB_HYPERALLOC)) {
                    990:                rewind(smb.sha_fp);
                    991:                chsize(fileno(smb.sha_fp),0L);          /* Reset both allocation tables */
                    992:                rewind(smb.sda_fp);
                    993:                chsize(fileno(smb.sda_fp),0L); }
                    994: 
                    995:        if(smb.status.attr&SMB_HYPERALLOC && !(mode&NOANALYSIS)) {
                    996:                printf("Analyzing %s\n",smb.file);
                    997: 
                    998:                length=filelength(fileno(smb.shd_fp));
                    999:                m=n=0;
                   1000:                for(l=smb.status.header_offset;l<length;l+=size) {
                   1001:                        printf("\r%2u%%  ",(long)(100.0/((float)length/l)));
                   1002:                        msg.idx.offset=l;
                   1003:                        if((i=smb_lockmsghdr(&smb,&msg))!=0) {
                   1004:                                printf("\n(%06lX) smb_lockmsghdr returned %d\n",l,i);
                   1005:                                size=SHD_BLOCK_LEN;
                   1006:                                continue; }
                   1007:                        if((i=smb_getmsghdr(&smb,&msg))!=0) {
                   1008:                                smb_unlockmsghdr(&smb,&msg);
                   1009:                                m++;
                   1010:                                size=SHD_BLOCK_LEN;
                   1011:                                continue; }
                   1012:                        smb_unlockmsghdr(&smb,&msg);
                   1013:                        if(msg.hdr.attr&MSG_DELETE) {
                   1014:                                m+=smb_hdrblocks(msg.hdr.length);
                   1015:                                total=0;
                   1016:                                for(i=0;i<msg.hdr.total_dfields;i++)
                   1017:                                        total+=msg.dfield[i].length;
                   1018:                                n+=smb_datblocks(total); }
                   1019:                        size=smb_getmsghdrlen(&msg);
                   1020:                        if(size<1) size=SHD_BLOCK_LEN;
                   1021:                        while(size%SHD_BLOCK_LEN)
                   1022:                                size++;
                   1023:                        smb_freemsgmem(&msg); }
                   1024: 
                   1025: 
                   1026:                if(!m && !n) {
                   1027:                        printf("\rAlready compressed.\n\n");
                   1028:                        smb_unlocksmbhdr(&smb);
                   1029:                        return; }
                   1030: 
                   1031:                if(packable && (n*SDT_BLOCK_LEN)+(m*SHD_BLOCK_LEN)<packable*1024L) {
                   1032:                        printf("\rLess than %luk compressable bytes.\n\n",packable);
                   1033:                        smb_unlocksmbhdr(&smb);
                   1034:                        return; }
                   1035: 
                   1036:                printf("\rCompressing %lu data blocks (%lu bytes)\n"
                   1037:                                 "        and %lu header blocks (%lu bytes)\n"
                   1038:                                  ,n,n*SDT_BLOCK_LEN,m,m*SHD_BLOCK_LEN); }
                   1039: 
                   1040:        sprintf(fname,"%s.sd$",smb.file);
                   1041:        tmp_sdt=fopen(fname,"wb");
                   1042:        sprintf(fname,"%s.sh$",smb.file);
                   1043:        tmp_shd=fopen(fname,"wb");
                   1044:        sprintf(fname,"%s.si$",smb.file);
                   1045:        tmp_sid=fopen(fname,"wb");
                   1046:        if(!tmp_sdt || !tmp_shd || !tmp_sid) {
                   1047:                smb_unlocksmbhdr(&smb);
                   1048:                if(!(smb.status.attr&SMB_HYPERALLOC)) {
                   1049:                        smb_close_ha(&smb);
                   1050:                        smb_close_da(&smb); }
                   1051:                printf("\n\7!Error opening temp files\n");
                   1052:                return; }
                   1053:        setvbuf(tmp_sdt,NULL,_IOFBF,2*1024);
                   1054:        setvbuf(tmp_shd,NULL,_IOFBF,2*1024);
                   1055:        setvbuf(tmp_sid,NULL,_IOFBF,2*1024);
                   1056:        if(!(smb.status.attr&SMB_HYPERALLOC)
                   1057:                && (datoffset=(datoffset_t *)LMALLOC(sizeof(datoffset_t)*smb.status.total_msgs))
                   1058:                ==NULL) {
                   1059:                smb_unlocksmbhdr(&smb);
                   1060:                smb_close_ha(&smb);
                   1061:                smb_close_da(&smb);
                   1062:                fclose(tmp_sdt);
                   1063:                fclose(tmp_shd);
                   1064:                fclose(tmp_sid);
                   1065:                printf("\n\7!Error allocating memory\n");
                   1066:                return; }
                   1067:        fseek(smb.shd_fp,0L,SEEK_SET);
                   1068:        fread(&hdr,1,sizeof(smbhdr_t),smb.shd_fp);
                   1069:        fwrite(&hdr,1,sizeof(smbhdr_t),tmp_shd);
                   1070:        fwrite(&(smb.status),1,sizeof(smbstatus_t),tmp_shd);
                   1071:        for(l=sizeof(smbhdr_t)+sizeof(smbstatus_t);l<smb.status.header_offset;l++) {
                   1072:                fread(&ch,1,1,smb.shd_fp);                      /* copy additional base header records */
                   1073:                fwrite(&ch,1,1,tmp_shd); }
                   1074:        fseek(smb.sid_fp,0L,SEEK_SET);
                   1075:        total=0;
                   1076:        for(l=0;l<smb.status.total_msgs;l++) {
                   1077:                printf("%lu of %lu\r",l+1,smb.status.total_msgs);
                   1078:                if(!fread(&msg.idx,1,sizeof(idxrec_t),smb.sid_fp))
                   1079:                        break;
                   1080:                if(msg.idx.attr&MSG_DELETE) {
                   1081:                        printf("\nDeleted index.\n");
                   1082:                        continue; }
                   1083:                i=smb_lockmsghdr(&smb,&msg);
                   1084:                if(i) {
                   1085:                        printf("\n\7!smb_lockmsghdr returned %d\n",i);
                   1086:                        continue; }
                   1087:                i=smb_getmsghdr(&smb,&msg);
                   1088:                smb_unlockmsghdr(&smb,&msg);
                   1089:                if(i) {
                   1090:                        printf("\n\7!smb_getmsghdr returned %d\n",i);
                   1091:                        continue; }
                   1092:                if(msg.hdr.attr&MSG_DELETE) {
                   1093:                        printf("\nDeleted header.\n");
                   1094:                        smb_freemsgmem(&msg);
                   1095:                        continue; }
                   1096:                if(msg.expiration.time && msg.expiration.time<=now) {
                   1097:                        printf("\nExpired message.\n");
                   1098:                        smb_freemsgmem(&msg);
                   1099:                        continue; }
                   1100:                for(m=0;m<datoffsets;m++)
                   1101:                        if(msg.hdr.offset==datoffset[m].old)
                   1102:                                break;
                   1103:                if(m<datoffsets) {                              /* another index pointed to this data */
                   1104:                        printf("duplicate index\n");
                   1105:                        msg.hdr.offset=datoffset[m].new;
                   1106:                        smb_incdat(&smb,datoffset[m].new,smb_getmsgdatlen(&msg),1); }
                   1107:                else {
                   1108: 
                   1109:                        if(!(smb.status.attr&SMB_HYPERALLOC))
                   1110:                                datoffset[datoffsets].old=msg.hdr.offset;
                   1111: 
                   1112:                        fseek(smb.sdt_fp,msg.hdr.offset,SEEK_SET);
                   1113: 
                   1114:                        m=smb_getmsgdatlen(&msg);
                   1115:                        if(m>16L*1024L*1024L) {
                   1116:                                printf("\n\7!Invalid data length (%lu)\n",m);
                   1117:                                continue; }
                   1118: 
                   1119:                        if(!(smb.status.attr&SMB_HYPERALLOC)) {
                   1120:                                datoffset[datoffsets].new=msg.hdr.offset
                   1121:                                        =smb_fallocdat(&smb,m,1);
                   1122:                                datoffsets++;
                   1123:                                fseek(tmp_sdt,msg.hdr.offset,SEEK_SET); }
                   1124:                        else {
                   1125:                                fseek(tmp_sdt,0L,SEEK_END);
                   1126:                                msg.hdr.offset=ftell(tmp_sdt); }
                   1127: 
                   1128:                        /* Actually copy the data */
                   1129: 
                   1130:                        n=smb_datblocks(m);
                   1131:                        for(m=0;m<n;m++) {
                   1132:                                fread(buf,1,SDT_BLOCK_LEN,smb.sdt_fp);
                   1133:                                if(!m && *(ushort *)buf!=XLAT_NONE && *(ushort *)buf!=XLAT_LZH) {
                   1134:                                        printf("\nUnsupported translation type (%04X)\n"
                   1135:                                                ,*(ushort *)buf);
                   1136:                                        break; }
                   1137:                                fwrite(buf,1,SDT_BLOCK_LEN,tmp_sdt); }
                   1138:                        if(m<n)
                   1139:                                continue; }
                   1140: 
                   1141:                /* Write the new index entry */
                   1142:                length=smb_getmsghdrlen(&msg);
                   1143:                if(smb.status.attr&SMB_HYPERALLOC)
                   1144:                        msg.idx.offset=ftell(tmp_shd);
                   1145:                else
                   1146:                        msg.idx.offset=smb_fallochdr(&smb,length)+smb.status.header_offset;
                   1147:                msg.idx.number=msg.hdr.number;
                   1148:                msg.idx.attr=msg.hdr.attr;
                   1149:                msg.idx.time=msg.hdr.when_imported.time;
                   1150:                sprintf(str,"%.128s",msg.subj);
                   1151:                strlwr(str);
                   1152:                remove_re(str);
                   1153:                msg.idx.subj=crc16(str);
                   1154:                if(smb.status.attr&SMB_EMAIL) {
                   1155:                        if(msg.to_ext)
                   1156:                                msg.idx.to=atoi(msg.to_ext);
                   1157:                        else
                   1158:                                msg.idx.to=0;
                   1159:                        if(msg.from_ext)
                   1160:                                msg.idx.from=atoi(msg.from_ext);
                   1161:                        else
                   1162:                                msg.idx.from=0; }
                   1163:                else {
                   1164:                        sprintf(str,"%.128s",msg.to);
                   1165:                        strlwr(str);
                   1166:                        msg.idx.to=crc16(str);
                   1167:                        sprintf(str,"%.128s",msg.from);
                   1168:                        strlwr(str);
                   1169:                        msg.idx.from=crc16(str); }
                   1170:                fwrite(&msg.idx,1,sizeof(idxrec_t),tmp_sid);
                   1171: 
                   1172:                /* Write the new header entry */
                   1173:                fseek(tmp_shd,msg.idx.offset,SEEK_SET);
                   1174:                fwrite(&msg.hdr,1,sizeof(msghdr_t),tmp_shd);
                   1175:                for(n=0;n<msg.hdr.total_dfields;n++)
                   1176:                        fwrite(&msg.dfield[n],1,sizeof(dfield_t),tmp_shd);
                   1177:                for(n=0;n<msg.total_hfields;n++) {
                   1178:                        fwrite(&msg.hfield[n],1,sizeof(hfield_t),tmp_shd);
                   1179:                        fwrite(msg.hfield_dat[n],1,msg.hfield[n].length,tmp_shd); }
                   1180:                while(length%SHD_BLOCK_LEN) {   /* pad with NULLs */
                   1181:                        fputc(0,tmp_shd);
                   1182:                        length++; }
                   1183:                total++;
                   1184:                smb_freemsgmem(&msg); }
                   1185: 
                   1186:        if(datoffset)
                   1187:                LFREE(datoffset);
                   1188:        if(!(smb.status.attr&SMB_HYPERALLOC)) {
                   1189:                smb_close_ha(&smb);
                   1190:                smb_close_da(&smb); }
                   1191: 
                   1192:        /* Change *.sh$ into *.shd */
                   1193:        fclose(smb.shd_fp);
                   1194:        fclose(tmp_shd);
                   1195:        sprintf(fname,"%s.shd",smb.file);
                   1196:        if(remove(fname)!=0)
                   1197:                printf("\n\7!Error %d removing %s\n",errno,fname);
                   1198:        sprintf(tmpfname,"%s.sh$",smb.file);
                   1199:        if(rename(tmpfname,fname)!=0)
                   1200:                printf("\n\7!Error %d renaming %s to %s\n",errno,tmpfname,fname);
                   1201: 
                   1202: 
                   1203:        /* Change *.sd$ into *.sdt */
                   1204:        fclose(smb.sdt_fp);
                   1205:        fclose(tmp_sdt);
                   1206:        sprintf(fname,"%s.sdt",smb.file);
                   1207:        if(remove(fname)!=0)
                   1208:                printf("\n\7!Error %d removing %s\n",errno,fname);
                   1209: 
                   1210:        sprintf(tmpfname,"%s.sd$",smb.file);
                   1211:        if(rename(tmpfname,fname)!=0)
                   1212:                printf("\n\7!Error %d renaming %s to %s\n",errno,tmpfname,fname);
                   1213: 
                   1214:        /* Change *.si$ into *.sid */
                   1215:        fclose(smb.sid_fp);
                   1216:        fclose(tmp_sid);
                   1217:        sprintf(fname,"%s.sid",smb.file);
                   1218:        if(remove(fname)!=0)
                   1219:                printf("\n\7!Error %d removing %s\n",errno,fname);
                   1220: 
                   1221:        sprintf(tmpfname,"%s.si$",smb.file);
                   1222:        if(rename(tmpfname,fname)!=0)
                   1223:                printf("\n\7!Error %d renaming %s to %s\n",errno,tmpfname,fname);
                   1224: 
                   1225:        if((i=smb_open(&smb))!=0) {
                   1226:                printf("\n\7!Error %d reopening %s\n",i,smb.file);
                   1227:                return; }
                   1228: 
                   1229:        smb.status.total_msgs=total;
                   1230:        if((i=smb_putstatus(&smb))!=0)
                   1231:                printf("\n\7!smb_putstatus returned %d\n",i);
                   1232:        printf("\nDone.\n\n");
                   1233: }
                   1234: 
                   1235: 
                   1236: /****************************************************************************/
                   1237: /* Read messages in message base                                                                                       */
                   1238: /****************************************************************************/
                   1239: void readmsgs(ulong start)
                   1240: {
                   1241:        char    HUGE16 *inbuf;
                   1242:        int     i,done=0,domsg=1;
                   1243:        smbmsg_t msg;
                   1244: 
                   1245:        if(start)
                   1246:                msg.offset=start-1;
                   1247:        else
                   1248:                msg.offset=0;
                   1249:        while(!done) {
                   1250:                if(domsg) {
                   1251:                        fseek(smb.sid_fp,msg.offset*sizeof(idxrec_t),SEEK_SET);
                   1252:                        if(!fread(&msg.idx,1,sizeof(idxrec_t),smb.sid_fp))
                   1253:                                break;
                   1254:                        i=smb_lockmsghdr(&smb,&msg);
                   1255:                        if(i) {
                   1256:                                printf("\n\7!smb_lockmsghdr returned %d\n",i);
                   1257:                                break; }
                   1258:                        i=smb_getmsghdr(&smb,&msg);
                   1259:                        if(i) {
                   1260:                                printf("\n\7!smb_getmsghdr returned %d\n",i);
                   1261:                                break; }
                   1262: 
                   1263:                        printf("\n%lu (%lu)\n",msg.hdr.number,msg.offset+1);
                   1264:                        printf("Subj : %s\n",msg.subj);
                   1265:                        printf("To   : %s",msg.to);
                   1266:                        if(msg.to_net.type)
                   1267:                                printf(" (%s)",msg.to_net.type==NET_FIDO
                   1268:                                        ? faddrtoa(*(fidoaddr_t *)msg.to_net.addr) : msg.to_net.addr);
                   1269:                        printf("\nFrom : %s",msg.from);
                   1270:                        if(msg.from_net.type)
                   1271:                                printf(" (%s)",msg.from_net.type==NET_FIDO
                   1272:                                        ? faddrtoa(*(fidoaddr_t *)msg.from_net.addr)
                   1273:                                                : msg.from_net.addr);
                   1274:                        printf("\nDate : %.24s %s"
                   1275:                                ,timestr((time_t*)&msg.hdr.when_written.time)
                   1276:                                ,zonestr(msg.hdr.when_written.zone));
                   1277: 
                   1278:                        printf("\n\n");
                   1279: 
                   1280:                        if((inbuf=smb_getmsgtxt(&smb,&msg,GETMSGTXT_TAILS))!=NULL) {
                   1281:                                printf("%s",inbuf);
                   1282:                                FREE(inbuf); }
                   1283: 
                   1284:                        i=smb_unlockmsghdr(&smb,&msg);
                   1285:                        if(i) {
                   1286:                                printf("\n\7!smb_unlockmsghdr returned %d\n",i);
                   1287:                                break; }
                   1288:                        smb_freemsgmem(&msg); }
                   1289:                domsg=1;
                   1290:                printf("\nReading %s (?=Menu): ",smb.file);
                   1291:                switch(toupper(getch())) {
                   1292:                        case '?':
                   1293:                                printf("\n"
                   1294:                                           "\n"
                   1295:                                           "(R)e-read current message\n"
                   1296:                                           "(L)ist messages\n"
                   1297:                                           "(T)en more titles\n"
                   1298:                                           "(V)iew message headers\n"
                   1299:                                           "(Q)uit\n"
                   1300:                                           "(+/-) Forward/Backward\n"
                   1301:                                           "\n");
                   1302:                                domsg=0;
                   1303:                                break;
                   1304:                        case 'Q':
                   1305:                                printf("Quit\n");
                   1306:                                done=1;
                   1307:                                break;
                   1308:                        case 'R':
                   1309:                                printf("Re-read\n");
                   1310:                                break;
                   1311:                        case '-':
                   1312:                                printf("Backwards\n");
                   1313:                                if(msg.offset)
                   1314:                                        msg.offset--;
                   1315:                                break;
                   1316:                        case 'T':
                   1317:                                printf("Ten titles\n");
                   1318:                                listmsgs(msg.offset+2,10);
                   1319:                                msg.offset+=10;
                   1320:                                domsg=0;
                   1321:                                break;
                   1322:                        case 'L':
                   1323:                                printf("List messages\n");
                   1324:                                listmsgs(1,-1);
                   1325:                                domsg=0;
                   1326:                                break;
                   1327:                        case 'V':
                   1328:                                printf("View message headers\n");
                   1329:                                viewmsgs(1,-1);
                   1330:                                domsg=0;
                   1331:                                break;
                   1332:                        case CR:
                   1333:                        case '+':
                   1334:                                printf("Next\n");
                   1335:                                msg.offset++;
                   1336:                                break; } }
                   1337: }
                   1338: 
                   1339: time_t checktime(void)
                   1340: {
                   1341:        struct tm tm;
                   1342: 
                   1343:     memset(&tm,0,sizeof(tm));
                   1344:     tm.tm_year=94;
                   1345:     tm.tm_mday=1;
                   1346:     return(mktime(&tm)-0x2D24BD00L);
                   1347: }
                   1348: 
                   1349: /***************/
                   1350: /* Entry point */
                   1351: /***************/
                   1352: int main(int argc, char **argv)
                   1353: {
                   1354:        char    cmd[128]="",*p,*s;
                   1355:        int             i,j,x,y;
                   1356:        time_t  t;
                   1357:        BOOL    create=FALSE;
                   1358: 
                   1359:        setvbuf(stdout,0,_IONBF,0);
                   1360: 
                   1361:        smb.file[0]=0;
                   1362:        printf("\nSMBUTIL Version %s (%s) SMBLIB %s - Synchronet Message Base "\
                   1363:                "Utility\n\n"
                   1364:                ,SMBUTIL_VER
                   1365: #if defined(__linux__)
                   1366:                ,"Linux"
                   1367: #elif defined(__unix__)
                   1368:                ,"Unix"
                   1369: #elif defined(__OS2__)
                   1370:                ,"OS/2"
                   1371: #elif defined(_WIN32)
                   1372:                ,"Win32"
                   1373: #elif defined(__DOS4G__)
                   1374:                ,"DOS4G"
                   1375: #elif defined(__FLAT__)
                   1376:                ,"DOS32"
                   1377: #else
                   1378:                ,"DOS16"
                   1379: #endif
                   1380:                ,smb_lib_ver()
                   1381:                );
                   1382: 
                   1383:        putenv("TZ=UCT0");
                   1384:        tzset();
                   1385: 
                   1386:        if((t=checktime())!=0) {
                   1387:                fprintf(stderr,"!TIME PROBLEM (%ld)\n",t);
                   1388:                return(-1);
                   1389:        }
                   1390: 
                   1391:        for(x=1;x<argc;x++) {
                   1392:                if(
                   1393: #ifndef __unix__
                   1394:                        argv[x][0]=='/' ||              /* for backwards compatibilty */
                   1395: #endif
                   1396:                        argv[x][0]=='-') {
                   1397:                        for(j=1;argv[x][j];j++)
                   1398:                                switch(toupper(argv[x][j])) {
                   1399:                                        case 'A':
                   1400:                                                mode|=NOANALYSIS;
                   1401:                                                break;
                   1402:                                        case 'Z':
                   1403:                                                if(isdigit(argv[x][j+1]))
                   1404:                                                        tzone=atoi(argv[x]+j+1);
                   1405:                                                else if(!stricmp(argv[x]+j+1,"EST"))
                   1406:                                                        tzone=EST;
                   1407:                                                else if(!stricmp(argv[x]+j+1,"EDT"))
                   1408:                                                        tzone=EDT;
                   1409:                                                else if(!stricmp(argv[x]+j+1,"CST"))
                   1410:                                                        tzone=CST;
                   1411:                                                else if(!stricmp(argv[x]+j+1,"CDT"))
                   1412:                                                        tzone=CDT;
                   1413:                                                else if(!stricmp(argv[x]+j+1,"MST"))
                   1414:                                                        tzone=MST;
                   1415:                                                else if(!stricmp(argv[x]+j+1,"MDT"))
                   1416:                                                        tzone=MDT;
                   1417:                                                else if(!stricmp(argv[x]+j+1,"PST"))
                   1418:                                                        tzone=PST;
                   1419:                                                else if(!stricmp(argv[x]+j+1,"PDT"))
                   1420:                                                        tzone=PDT;
                   1421:                                                j=strlen(argv[x])-1;
                   1422:                                                break;
                   1423:                                        case 'C':
                   1424:                                                create=TRUE;
                   1425:                                                break;
                   1426:                                        default:
                   1427:                                                printf("\nUnknown opt '%c'\n",argv[x][j]);
                   1428:                                        case '?':
                   1429:                                                printf("%s",usage);
                   1430:                                                exit(1);
                   1431:                                                break; } }
                   1432:                else {
                   1433:                        if(!cmd[0])
                   1434:                                strcpy(cmd,argv[x]);
                   1435:                        else {
                   1436:                                sprintf(smb.file,"%.64s",argv[x]);
                   1437:                                p=strrchr(smb.file,'.');
                   1438:                                s=strrchr(smb.file,'/');
                   1439:                                if(s==NULL)
                   1440:                                        s=strrchr(smb.file,'\\');
                   1441:                                if(p>s) *p=0;
                   1442:                                smb.retry_time=30;
                   1443:                                printf("Opening %s\r\n",smb.file);
                   1444:                                if((i=smb_open(&smb))!=0) {
                   1445:                                        printf("\n\7!Error %d opening %s message base\n",i,smb.file);
                   1446:                                        exit(1); }
                   1447:                                if(!filelength(fileno(smb.shd_fp))) {
                   1448:                                        if(!create) {
                   1449:                                                printf("Empty\n");
                   1450:                                                smb_close(&smb);
                   1451:                                                continue; }
                   1452:                                        smb.status.max_crcs=0;
                   1453:                                        smb.status.max_age=0;
                   1454:                                        smb.status.max_msgs=1000;
                   1455:                                        smb.status.attr=0;
                   1456:                                        if((i=smb_create(&smb))!=0) {
                   1457:                                                smb_close(&smb);
                   1458:                                                printf("!Error %d (%s) creating %s\n",i,smb.last_error,smb.file);
                   1459:                                                continue; 
                   1460:                                        } 
                   1461:                                }
                   1462:                                for(y=0;cmd[y];y++)
                   1463:                                        switch(toupper(cmd[y])) {
                   1464:                                                case 'I':
                   1465:                                                case 'E':
                   1466:                                                case 'N':
                   1467:                                                        strcpy(filein,cmd+1);
                   1468:                                                        i=smb_locksmbhdr(&smb);
                   1469:                                                        if(i) {
                   1470:                                                                printf("\n\7!smb_locksmbhdr returned %d\n",i);
                   1471:                                                                return(1); }
                   1472:                                                        postmsg((char)toupper(cmd[y]));
                   1473:                                                        y=strlen(cmd)-1;
                   1474:                                                        break;
                   1475:                                                case 'S':
                   1476:                                                        showstatus();
                   1477:                                                        break;
                   1478:                                                case 'C':
                   1479:                                                        config();
                   1480:                                                        break;
                   1481:                                                case 'L':
                   1482:                                                        listmsgs(atol(cmd+1),-1L);
                   1483:                                                        y=strlen(cmd)-1;
                   1484:                                                        break;
                   1485:                                                case 'P':
                   1486:                                                        packmsgs(atol(cmd+y+1));
                   1487:                                                        y=strlen(cmd)-1;
                   1488:                                                        break;
                   1489:                                                case 'R':
                   1490:                                                        readmsgs(atol(cmd+1));
                   1491:                                                        y=strlen(cmd)-1;
                   1492:                                                        break;
                   1493:                                                case 'V':
                   1494:                                                        viewmsgs(atol(cmd+1),-1L);
                   1495:                                                        y=strlen(cmd)-1;
                   1496:                                                        break;
                   1497:                                                case 'M':
                   1498:                                                        maint();
                   1499:                                                        break;
                   1500:                                                default:
                   1501:                                                        printf("%s",usage);
                   1502:                                                        break; }
                   1503:                                smb_close(&smb); } } }
                   1504:        if(!cmd[0])
                   1505:                printf("%s",usage);
                   1506:        return(0);
                   1507: }

unix.superglobalmegacorp.com

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