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