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