Annotation of sbbs/sbbs2/smb/121a/smbutil.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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