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

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

unix.superglobalmegacorp.com

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