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

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

unix.superglobalmegacorp.com

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