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

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

unix.superglobalmegacorp.com

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