|
|
1.1 ! root 1: /* SMBLIB.C */ ! 2: ! 3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ ! 4: ! 5: #include "smblib.h" ! 6: #include "lzh.h" ! 7: ! 8: int SMBCALL smb_ver(void) ! 9: { ! 10: return(SMB_VERSION); ! 11: } ! 12: ! 13: char * SMBCALL smb_lib_ver(void) ! 14: { ! 15: return(SMBLIB_VERSION); ! 16: } ! 17: ! 18: /****************************************************************************/ ! 19: /* Open a message base of name 'smb->file' */ ! 20: /* Opens files for READing messages or updating message indices only */ ! 21: /****************************************************************************/ ! 22: int SMBCALL smb_open(smb_t *smb) ! 23: { ! 24: int file; ! 25: char str[128]; ! 26: smbhdr_t hdr; ! 27: ! 28: if(!smb->retry_time) ! 29: smb->retry_time=10; ! 30: smb->shd_fp=smb->sdt_fp=smb->sid_fp=NULL; ! 31: sprintf(str,"%s.SHD",smb->file); ! 32: if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO,S_IWRITE|S_IREAD))==-1 ! 33: || (smb->shd_fp=fdopen(file,"r+b"))==NULL) { ! 34: if(file!=-1) ! 35: close(file); ! 36: return(2); } ! 37: ! 38: if(filelength(file)>=sizeof(smbhdr_t)) { ! 39: setvbuf(smb->shd_fp,smb->shd_buf,_IONBF,SHD_BLOCK_LEN); ! 40: if(smb_locksmbhdr(smb)) { ! 41: smb_close(smb); ! 42: return(-1); } ! 43: memset(&hdr,0,sizeof(smbhdr_t)); ! 44: fread(&hdr,sizeof(smbhdr_t),1,smb->shd_fp); ! 45: if(memcmp(hdr.id,"SMB\x1a",4)) { ! 46: smb_close(smb); ! 47: return(-2); } ! 48: if(hdr.version<0x110) { /* Compatibility check */ ! 49: smb_close(smb); ! 50: return(-3); } ! 51: if(fread(&(smb->status),1,sizeof(smbstatus_t),smb->shd_fp) ! 52: !=sizeof(smbstatus_t)) { ! 53: smb_close(smb); ! 54: return(-4); } ! 55: smb_unlocksmbhdr(smb); ! 56: rewind(smb->shd_fp); } ! 57: ! 58: setvbuf(smb->shd_fp,smb->shd_buf,_IOFBF,SHD_BLOCK_LEN); ! 59: ! 60: sprintf(str,"%s.SDT",smb->file); ! 61: if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO,S_IWRITE|S_IREAD))==-1 ! 62: || (smb->sdt_fp=fdopen(file,"r+b"))==NULL) { ! 63: if(file!=-1) ! 64: close(file); ! 65: smb_close(smb); ! 66: return(1); } ! 67: setvbuf(smb->sdt_fp,NULL,_IOFBF,2*1024); ! 68: ! 69: sprintf(str,"%s.SID",smb->file); ! 70: if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO,S_IWRITE|S_IREAD))==-1 ! 71: || (smb->sid_fp=fdopen(file,"r+b"))==NULL) { ! 72: if(file!=-1) ! 73: close(file); ! 74: smb_close(smb); ! 75: return(3); } ! 76: setvbuf(smb->sid_fp,NULL,_IOFBF,2*1024); ! 77: ! 78: return(0); ! 79: } ! 80: ! 81: /****************************************************************************/ ! 82: /* Closes the currently open message base */ ! 83: /****************************************************************************/ ! 84: void SMBCALL smb_close(smb_t *smb) ! 85: { ! 86: if(smb->shd_fp!=NULL) { ! 87: smb_unlocksmbhdr(smb); /* In case it's been locked */ ! 88: fclose(smb->shd_fp); } ! 89: if(smb->sid_fp!=NULL) ! 90: fclose(smb->sid_fp); ! 91: if(smb->sdt_fp!=NULL) ! 92: fclose(smb->sdt_fp); ! 93: smb->sid_fp=smb->shd_fp=smb->sdt_fp=NULL; ! 94: } ! 95: ! 96: /****************************************************************************/ ! 97: /* Opens the data block allocation table message base 'smb->file' */ ! 98: /* Retrys for retry_time number of seconds */ ! 99: /* Return 0 on success, non-zero otherwise */ ! 100: /****************************************************************************/ ! 101: int SMBCALL smb_open_da(smb_t *smb) ! 102: { ! 103: int file; ! 104: char str[128]; ! 105: ulong start=0; ! 106: ! 107: sprintf(str,"%s.SDA",smb->file); ! 108: while(1) { ! 109: if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYRW,S_IWRITE|S_IREAD))!=-1) ! 110: break; ! 111: if(errno!=EACCES) ! 112: return(-1); ! 113: if(!start) ! 114: start=time(NULL); ! 115: else ! 116: if(time(NULL)-start>=smb->retry_time) ! 117: return(-2); } ! 118: if((smb->sda_fp=fdopen(file,"r+b"))==NULL) { ! 119: close(file); ! 120: return(-3); } ! 121: setvbuf(smb->sda_fp,NULL,_IOFBF,2*1024); ! 122: return(0); ! 123: } ! 124: ! 125: void SMBCALL smb_close_da(smb_t *smb) ! 126: { ! 127: if(smb->sda_fp!=NULL) ! 128: fclose(smb->sda_fp); ! 129: smb->sda_fp=NULL; ! 130: } ! 131: ! 132: /****************************************************************************/ ! 133: /* Opens the header block allocation table for message base 'smb.file' */ ! 134: /* Retrys for smb.retry_time number of seconds */ ! 135: /* Return 0 on success, non-zero otherwise */ ! 136: /****************************************************************************/ ! 137: int SMBCALL smb_open_ha(smb_t *smb) ! 138: { ! 139: int file; ! 140: char str[128]; ! 141: ulong start=0; ! 142: ! 143: sprintf(str,"%s.SHA",smb->file); ! 144: while(1) { ! 145: if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYRW,S_IWRITE|S_IREAD))!=-1) ! 146: break; ! 147: if(errno!=EACCES) ! 148: return(-1); ! 149: if(!start) ! 150: start=time(NULL); ! 151: else ! 152: if(time(NULL)-start>=smb->retry_time) ! 153: return(-2); } ! 154: if((smb->sha_fp=fdopen(file,"r+b"))==NULL) { ! 155: close(file); ! 156: return(-3); } ! 157: setvbuf(smb->sha_fp,NULL,_IOFBF,2*1024); ! 158: return(0); ! 159: } ! 160: ! 161: void SMBCALL smb_close_ha(smb_t *smb) ! 162: { ! 163: if(smb->sha_fp!=NULL) ! 164: fclose(smb->sha_fp); ! 165: smb->sha_fp=NULL; ! 166: } ! 167: ! 168: ! 169: /****************************************************************************/ ! 170: /* If the parameter 'push' is non-zero, this function stores the currently */ ! 171: /* open message base to the "virtual" smb stack. Up to SMB_STACK_LEN */ ! 172: /* message bases may be stored (defined in SMBDEFS.H). */ ! 173: /* The parameter 'op' is the operation to perform on the stack. Either */ ! 174: /* SMB_STACK_PUSH, SMB_STACK_POP, or SMB_STACK_XCHNG */ ! 175: /* If the operation is SMB_STACK_POP, this function restores a message base */ ! 176: /* previously saved with a SMB_STACK_PUSH call to this same function. */ ! 177: /* If the operation is SMB_STACK_XCHNG, then the current message base is */ ! 178: /* exchanged with the message base on the top of the stack (most recently */ ! 179: /* pushed. */ ! 180: /* If the current message base is not open, the SMB_STACK_PUSH and */ ! 181: /* SMB_STACK_XCHNG operations do nothing */ ! 182: /* Returns 0 on success, non-zero if stack full. */ ! 183: /* If operation is SMB_STACK_POP or SMB_STACK_XCHNG, it always returns 0. */ ! 184: /****************************************************************************/ ! 185: int SMBCALL smb_stack(smb_t *smb, int op) ! 186: { ! 187: static char stack_file[SMB_STACK_LEN][128]; ! 188: static FILE *stack_sdt[SMB_STACK_LEN], ! 189: *stack_shd[SMB_STACK_LEN], ! 190: *stack_sid[SMB_STACK_LEN], ! 191: *stack_sda[SMB_STACK_LEN], ! 192: *stack_sha[SMB_STACK_LEN]; ! 193: static int stack_idx; ! 194: char tmp_file[128]; ! 195: FILE *tmp_sdt, ! 196: *tmp_shd, ! 197: *tmp_sid, ! 198: *tmp_sda, ! 199: *tmp_sha; ! 200: ! 201: if(op==SMB_STACK_PUSH) { ! 202: if(stack_idx>=SMB_STACK_LEN) ! 203: return(1); ! 204: if(smb->shd_fp==NULL || smb->sdt_fp==NULL || smb->sid_fp==NULL) ! 205: return(0); /* Msg base not open */ ! 206: memcpy(stack_file[stack_idx],smb->file,128); ! 207: stack_sdt[stack_idx]=smb->sdt_fp; ! 208: stack_shd[stack_idx]=smb->shd_fp; ! 209: stack_sid[stack_idx]=smb->sid_fp; ! 210: stack_sda[stack_idx]=smb->sda_fp; ! 211: stack_sha[stack_idx]=smb->sha_fp; ! 212: stack_idx++; ! 213: return(0); } ! 214: /* pop or xchng */ ! 215: if(!stack_idx) /* Nothing on the stack, so do nothing */ ! 216: return(0); ! 217: if(op==SMB_STACK_XCHNG) { ! 218: if(!smb->shd_fp) ! 219: return(0); ! 220: memcpy(tmp_file,smb->file,128); ! 221: tmp_sdt=smb->sdt_fp; ! 222: tmp_shd=smb->shd_fp; ! 223: tmp_sid=smb->sid_fp; ! 224: tmp_sda=smb->sda_fp; ! 225: tmp_sha=smb->sha_fp; } ! 226: ! 227: stack_idx--; ! 228: memcpy(smb->file,stack_file[stack_idx],128); ! 229: smb->sdt_fp=stack_sdt[stack_idx]; ! 230: smb->shd_fp=stack_shd[stack_idx]; ! 231: smb->sid_fp=stack_sid[stack_idx]; ! 232: smb->sda_fp=stack_sda[stack_idx]; ! 233: smb->sha_fp=stack_sha[stack_idx]; ! 234: if(op==SMB_STACK_XCHNG) { ! 235: stack_idx++; ! 236: memcpy(stack_file[stack_idx-1],tmp_file,128); ! 237: stack_sdt[stack_idx-1]=tmp_sdt; ! 238: stack_shd[stack_idx-1]=tmp_shd; ! 239: stack_sid[stack_idx-1]=tmp_sid; ! 240: stack_sda[stack_idx-1]=tmp_sda; ! 241: stack_sha[stack_idx-1]=tmp_sha; } ! 242: return(0); ! 243: } ! 244: ! 245: /****************************************************************************/ ! 246: /* Truncates header file */ ! 247: /* Retrys for smb.retry_time number of seconds */ ! 248: /* Return 0 on success, non-zero otherwise */ ! 249: /****************************************************************************/ ! 250: int SMBCALL smb_trunchdr(smb_t *smb) ! 251: { ! 252: ulong start=0; ! 253: ! 254: rewind(smb->shd_fp); ! 255: while(1) { ! 256: if(!chsize(fileno(smb->shd_fp),0L)) ! 257: break; ! 258: if(errno!=EACCES) ! 259: return(-1); ! 260: if(!start) ! 261: start=time(NULL); ! 262: else ! 263: if(time(NULL)-start>=smb->retry_time) /* Time-out */ ! 264: return(-2); } ! 265: return(0); ! 266: } ! 267: ! 268: /*********************************/ ! 269: /* Message Base Header Functions */ ! 270: /*********************************/ ! 271: ! 272: /****************************************************************************/ ! 273: /* Attempts for smb.retry_time number of seconds to lock the msg base hdr */ ! 274: /****************************************************************************/ ! 275: int SMBCALL smb_locksmbhdr(smb_t *smb) ! 276: { ! 277: ulong start=0; ! 278: ! 279: while(1) { ! 280: if(!lock(fileno(smb->shd_fp),0L,sizeof(smbhdr_t)+sizeof(smbstatus_t))) ! 281: return(0); ! 282: if(!start) ! 283: start=time(NULL); ! 284: else ! 285: if(time(NULL)-start>=smb->retry_time) ! 286: break; /* Incase we've already locked it */ ! 287: unlock(fileno(smb->shd_fp),0L,sizeof(smbhdr_t)+sizeof(smbstatus_t)); } ! 288: return(-1); ! 289: } ! 290: ! 291: /****************************************************************************/ ! 292: /* Read the SMB header from the header file and place into smb.status */ ! 293: /****************************************************************************/ ! 294: int SMBCALL smb_getstatus(smb_t *smb) ! 295: { ! 296: int i; ! 297: ! 298: setvbuf(smb->shd_fp,smb->shd_buf,_IONBF,SHD_BLOCK_LEN); ! 299: clearerr(smb->shd_fp); ! 300: fseek(smb->shd_fp,sizeof(smbhdr_t),SEEK_SET); ! 301: i=fread(&(smb->status),1,sizeof(smbstatus_t),smb->shd_fp); ! 302: setvbuf(smb->shd_fp,smb->shd_buf,_IOFBF,SHD_BLOCK_LEN); ! 303: if(i==sizeof(smbstatus_t)) ! 304: return(0); ! 305: return(1); ! 306: } ! 307: ! 308: /****************************************************************************/ ! 309: /* Writes message base header */ ! 310: /****************************************************************************/ ! 311: int SMBCALL smb_putstatus(smb_t *smb) ! 312: { ! 313: int i; ! 314: ! 315: clearerr(smb->shd_fp); ! 316: fseek(smb->shd_fp,sizeof(smbhdr_t),SEEK_SET); ! 317: i=fwrite(&(smb->status),1,sizeof(smbstatus_t),smb->shd_fp); ! 318: fflush(smb->shd_fp); ! 319: if(i==sizeof(smbstatus_t)) ! 320: return(0); ! 321: return(1); ! 322: } ! 323: ! 324: /****************************************************************************/ ! 325: /* Unlocks previously locks message base header */ ! 326: /****************************************************************************/ ! 327: int SMBCALL smb_unlocksmbhdr(smb_t *smb) ! 328: { ! 329: return(unlock(fileno(smb->shd_fp),0L,sizeof(smbhdr_t)+sizeof(smbstatus_t))); ! 330: } ! 331: ! 332: /********************************/ ! 333: /* Individual Message Functions */ ! 334: /********************************/ ! 335: ! 336: /****************************************************************************/ ! 337: /* Attempts for smb.retry_time number of seconds to lock the hdr for 'msg' */ ! 338: /****************************************************************************/ ! 339: int SMBCALL smb_lockmsghdr(smb_t *smb, smbmsg_t *msg) ! 340: { ! 341: ulong start=0; ! 342: ! 343: while(1) { ! 344: if(!lock(fileno(smb->shd_fp),msg->idx.offset,sizeof(msghdr_t))) ! 345: return(0); ! 346: if(!start) ! 347: start=time(NULL); ! 348: else ! 349: if(time(NULL)-start>=smb->retry_time) ! 350: break; ! 351: unlock(fileno(smb->shd_fp),msg->idx.offset,sizeof(msghdr_t)); } ! 352: return(-1); ! 353: } ! 354: ! 355: /****************************************************************************/ ! 356: /* Fills msg->idx with message index based on msg->hdr.number */ ! 357: /* OR if msg->hdr.number is 0, based on msg->offset (record offset). */ ! 358: /* if msg.hdr.number does not equal 0, then msg->offset is filled too. */ ! 359: /* Either msg->hdr.number or msg->offset must be initialized before */ ! 360: /* calling this function */ ! 361: /* Returns 1 if message number wasn't found, 0 if it was */ ! 362: /****************************************************************************/ ! 363: int SMBCALL smb_getmsgidx(smb_t *smb, smbmsg_t *msg) ! 364: { ! 365: idxrec_t idx; ! 366: ulong l,length,total,bot,top; ! 367: ! 368: clearerr(smb->sid_fp); ! 369: if(!msg->hdr.number) { ! 370: fseek(smb->sid_fp,msg->offset*sizeof(idxrec_t),SEEK_SET); ! 371: if(!fread(&msg->idx,sizeof(idxrec_t),1,smb->sid_fp)) ! 372: return(1); ! 373: return(0); } ! 374: ! 375: length=filelength(fileno(smb->sid_fp)); ! 376: if(!length) ! 377: return(1); ! 378: total=length/sizeof(idxrec_t); ! 379: if(!total) ! 380: return(1); ! 381: ! 382: bot=0; ! 383: top=total; ! 384: l=total/2; /* Start at middle index */ ! 385: while(1) { ! 386: fseek(smb->sid_fp,l*sizeof(idxrec_t),SEEK_SET); ! 387: if(!fread(&idx,sizeof(idxrec_t),1,smb->sid_fp)) ! 388: return(1); ! 389: if(bot==top-1 && idx.number!=msg->hdr.number) ! 390: return(1); ! 391: if(idx.number>msg->hdr.number) { ! 392: top=l; ! 393: l=bot+((top-bot)/2); ! 394: continue; } ! 395: if(idx.number<msg->hdr.number) { ! 396: bot=l; ! 397: l=top-((top-bot)/2); ! 398: continue; } ! 399: break; } ! 400: msg->idx=idx; ! 401: msg->offset=l; ! 402: return(0); ! 403: } ! 404: ! 405: /****************************************************************************/ ! 406: /* Reads the last index record in the open message base */ ! 407: /****************************************************************************/ ! 408: int SMBCALL smb_getlastidx(smb_t *smb, idxrec_t *idx) ! 409: { ! 410: long length; ! 411: ! 412: clearerr(smb->sid_fp); ! 413: length=filelength(fileno(smb->sid_fp)); ! 414: if(length<sizeof(idxrec_t)) ! 415: return(-1); ! 416: fseek(smb->sid_fp,length-sizeof(idxrec_t),SEEK_SET); ! 417: if(!fread(idx,sizeof(idxrec_t),1,smb->sid_fp)) ! 418: return(-2); ! 419: return(0); ! 420: } ! 421: ! 422: /****************************************************************************/ ! 423: /* Figures out the total length of the header record for 'msg' */ ! 424: /* Returns length */ ! 425: /****************************************************************************/ ! 426: uint SMBCALL smb_getmsghdrlen(smbmsg_t *msg) ! 427: { ! 428: int i; ! 429: ! 430: /* fixed portion */ ! 431: msg->hdr.length=sizeof(msghdr_t); ! 432: /* data fields */ ! 433: msg->hdr.length+=msg->hdr.total_dfields*sizeof(dfield_t); ! 434: /* header fields */ ! 435: for(i=0;i<msg->total_hfields;i++) { ! 436: msg->hdr.length+=sizeof(hfield_t); ! 437: msg->hdr.length+=msg->hfield[i].length; } ! 438: return(msg->hdr.length); ! 439: } ! 440: ! 441: /****************************************************************************/ ! 442: /* Figures out the total length of the data buffer for 'msg' */ ! 443: /* Returns length */ ! 444: /****************************************************************************/ ! 445: ulong SMBCALL smb_getmsgdatlen(smbmsg_t *msg) ! 446: { ! 447: int i; ! 448: ulong length=0L; ! 449: ! 450: for(i=0;i<msg->hdr.total_dfields;i++) ! 451: length+=msg->dfield[i].length; ! 452: return(length); ! 453: } ! 454: ! 455: /****************************************************************************/ ! 456: /* Read header information into 'msg' structure */ ! 457: /* msg->idx.offset must be set before calling this function */ ! 458: /* Must call smb_freemsgmem() to free memory allocated for var len strs */ ! 459: /* Returns 0 on success, non-zero if error */ ! 460: /****************************************************************************/ ! 461: int SMBCALL smb_getmsghdr(smb_t *smb, smbmsg_t *msg) ! 462: { ! 463: void *vp,**vpp; ! 464: ushort i; ! 465: ulong l,offset; ! 466: idxrec_t idx; ! 467: ! 468: rewind(smb->shd_fp); ! 469: fseek(smb->shd_fp,msg->idx.offset,SEEK_SET); ! 470: idx=msg->idx; ! 471: offset=msg->offset; ! 472: memset(msg,0,sizeof(smbmsg_t)); ! 473: msg->idx=idx; ! 474: msg->offset=offset; ! 475: if(!fread(&msg->hdr,sizeof(msghdr_t),1,smb->shd_fp)) ! 476: return(-1); ! 477: if(memcmp(msg->hdr.id,"SHD\x1a",4)) ! 478: return(-2); ! 479: if(msg->hdr.version<0x110) ! 480: return(-9); ! 481: l=sizeof(msghdr_t); ! 482: if(msg->hdr.total_dfields && (msg->dfield ! 483: =(dfield_t *)MALLOC(sizeof(dfield_t)*msg->hdr.total_dfields))==NULL) { ! 484: smb_freemsgmem(msg); ! 485: return(-3); } ! 486: i=0; ! 487: while(i<msg->hdr.total_dfields && l<msg->hdr.length) { ! 488: if(!fread(&msg->dfield[i],sizeof(dfield_t),1,smb->shd_fp)) { ! 489: smb_freemsgmem(msg); ! 490: return(-4); } ! 491: i++; ! 492: l+=sizeof(dfield_t); } ! 493: if(i<msg->hdr.total_dfields) { ! 494: smb_freemsgmem(msg); ! 495: return(-8); } ! 496: ! 497: while(l<msg->hdr.length) { ! 498: i=msg->total_hfields; ! 499: if((vpp=(void **)REALLOC(msg->hfield_dat,sizeof(void *)*(i+1)))==NULL) { ! 500: smb_freemsgmem(msg); ! 501: return(-3); } ! 502: msg->hfield_dat=vpp; ! 503: if((vp=(hfield_t *)REALLOC(msg->hfield,sizeof(hfield_t)*(i+1)))==NULL) { ! 504: smb_freemsgmem(msg); ! 505: return(-3); } ! 506: msg->hfield=vp; ! 507: msg->total_hfields++; ! 508: if(!fread(&msg->hfield[i],sizeof(hfield_t),1,smb->shd_fp)) { ! 509: smb_freemsgmem(msg); ! 510: return(-5); } ! 511: l+=sizeof(hfield_t); ! 512: if((msg->hfield_dat[i]=(char *)MALLOC(msg->hfield[i].length+1)) ! 513: ==NULL) { /* Allocate 1 extra for NULL terminator */ ! 514: smb_freemsgmem(msg); /* or 0 length field */ ! 515: return(-3); } ! 516: memset(msg->hfield_dat[i],0,msg->hfield[i].length+1); /* init to NULL */ ! 517: if(msg->hfield[i].length ! 518: && !fread(msg->hfield_dat[i],msg->hfield[i].length,1,smb->shd_fp)) { ! 519: smb_freemsgmem(msg); ! 520: return(-6); } ! 521: ! 522: switch(msg->hfield[i].type) { /* convenience variables */ ! 523: case SENDER: ! 524: if(!msg->from) { ! 525: msg->from=msg->hfield_dat[i]; ! 526: break; } ! 527: case FORWARDED: /* fall through */ ! 528: msg->forwarded=1; ! 529: break; ! 530: case SENDERAGENT: ! 531: if(!msg->forwarded) ! 532: msg->from_agent=*(ushort *)msg->hfield_dat[i]; ! 533: break; ! 534: case SENDEREXT: ! 535: if(!msg->forwarded) ! 536: msg->from_ext=msg->hfield_dat[i]; ! 537: break; ! 538: case SENDERNETTYPE: ! 539: if(!msg->forwarded) ! 540: msg->from_net.type=*(ushort *)msg->hfield_dat[i]; ! 541: break; ! 542: case SENDERNETADDR: ! 543: if(!msg->forwarded) ! 544: msg->from_net.addr=msg->hfield_dat[i]; ! 545: break; ! 546: case REPLYTO: ! 547: msg->replyto=msg->hfield_dat[i]; ! 548: break; ! 549: case REPLYTOEXT: ! 550: msg->replyto_ext=msg->hfield_dat[i]; ! 551: break; ! 552: case REPLYTOAGENT: ! 553: msg->replyto_agent=*(ushort *)msg->hfield_dat[i]; ! 554: break; ! 555: case REPLYTONETTYPE: ! 556: msg->replyto_net.type=*(ushort *)msg->hfield_dat[i]; ! 557: break; ! 558: case REPLYTONETADDR: ! 559: msg->replyto_net.addr=msg->hfield_dat[i]; ! 560: break; ! 561: case RECIPIENT: ! 562: msg->to=msg->hfield_dat[i]; ! 563: break; ! 564: case RECIPIENTEXT: ! 565: msg->to_ext=msg->hfield_dat[i]; ! 566: break; ! 567: case RECIPIENTAGENT: ! 568: msg->to_agent=*(ushort *)msg->hfield_dat[i]; ! 569: break; ! 570: case RECIPIENTNETTYPE: ! 571: msg->to_net.type=*(ushort *)msg->hfield_dat[i]; ! 572: break; ! 573: case RECIPIENTNETADDR: ! 574: msg->to_net.addr=msg->hfield_dat[i]; ! 575: break; ! 576: case SUBJECT: ! 577: msg->subj=msg->hfield_dat[i]; ! 578: break; } ! 579: l+=msg->hfield[i].length; } ! 580: ! 581: if(!msg->from || !msg->to || !msg->subj) { ! 582: smb_freemsgmem(msg); ! 583: return(-7); } ! 584: return(0); ! 585: } ! 586: ! 587: /****************************************************************************/ ! 588: /* Frees memory allocated for 'msg' */ ! 589: /****************************************************************************/ ! 590: void SMBCALL smb_freemsgmem(smbmsg_t *msg) ! 591: { ! 592: ushort i; ! 593: ! 594: if(msg->dfield) ! 595: FREE(msg->dfield); ! 596: for(i=0;i<msg->total_hfields;i++) ! 597: if(msg->hfield_dat[i]) ! 598: FREE(msg->hfield_dat[i]); ! 599: if(msg->hfield) ! 600: FREE(msg->hfield); ! 601: if(msg->hfield_dat) ! 602: FREE(msg->hfield_dat); ! 603: } ! 604: ! 605: /****************************************************************************/ ! 606: /* Unlocks header for 'msg' */ ! 607: /****************************************************************************/ ! 608: int SMBCALL smb_unlockmsghdr(smb_t *smb, smbmsg_t *msg) ! 609: { ! 610: return(unlock(fileno(smb->shd_fp),msg->idx.offset,sizeof(msghdr_t))); ! 611: } ! 612: ! 613: ! 614: /****************************************************************************/ ! 615: /* Adds a header field to the 'msg' structure (in memory only) */ ! 616: /****************************************************************************/ ! 617: int SMBCALL smb_hfield(smbmsg_t *msg, ushort type, ushort length, void *data) ! 618: { ! 619: void *vp,**vpp; ! 620: int i; ! 621: ! 622: i=msg->total_hfields; ! 623: if((vp=(hfield_t *)REALLOC(msg->hfield,sizeof(hfield_t)*(i+1)))==NULL) ! 624: return(1); ! 625: msg->hfield=vp; ! 626: if((vpp=(void **)REALLOC(msg->hfield_dat,sizeof(void *)*(i+1)))==NULL) ! 627: return(2); ! 628: msg->hfield_dat=vpp; ! 629: msg->total_hfields++; ! 630: msg->hfield[i].type=type; ! 631: msg->hfield[i].length=length; ! 632: if(length) { ! 633: if((msg->hfield_dat[i]=(void *)MALLOC(length))==NULL) ! 634: return(4); ! 635: memcpy(msg->hfield_dat[i],data,length); } ! 636: else ! 637: msg->hfield_dat[i]=NULL; ! 638: return(0); ! 639: } ! 640: ! 641: /****************************************************************************/ ! 642: /* Adds a data field to the 'msg' structure (in memory only) */ ! 643: /* Automatically figures out the offset into the data buffer from existing */ ! 644: /* dfield lengths */ ! 645: /****************************************************************************/ ! 646: int SMBCALL smb_dfield(smbmsg_t *msg, ushort type, ulong length) ! 647: { ! 648: void *vp; ! 649: int i,j; ! 650: ! 651: i=msg->hdr.total_dfields; ! 652: if((vp=(dfield_t *)REALLOC(msg->dfield,sizeof(dfield_t)*(i+1)))==NULL) ! 653: return(1); ! 654: msg->dfield=vp; ! 655: msg->hdr.total_dfields++; ! 656: msg->dfield[i].type=type; ! 657: msg->dfield[i].length=length; ! 658: for(j=msg->dfield[i].offset=0;j<i;j++) ! 659: msg->dfield[i].offset+=msg->dfield[j].length; ! 660: return(0); ! 661: } ! 662: ! 663: /****************************************************************************/ ! 664: /* Checks CRC history file for duplicate crc. If found, returns 1. */ ! 665: /* If no dupe, adds to CRC history and returns 0, or negative if error. */ ! 666: /****************************************************************************/ ! 667: int SMBCALL smb_addcrc(smb_t *smb, ulong crc) ! 668: { ! 669: char str[128]; ! 670: int file; ! 671: long length; ! 672: ulong l,*buf; ! 673: ulong start=0; ! 674: ! 675: if(!smb->status.max_crcs) ! 676: return(0); ! 677: ! 678: sprintf(str,"%s.SCH",smb->file); ! 679: while(1) { ! 680: if((file=sopen(str,O_RDWR|O_CREAT|O_BINARY,SH_DENYRW,S_IWRITE|S_IREAD))!=-1) ! 681: break; ! 682: if(errno!=EACCES) ! 683: return(-1); ! 684: if(!start) ! 685: start=time(NULL); ! 686: else ! 687: if(time(NULL)-start>=smb->retry_time) ! 688: return(-2); } ! 689: ! 690: length=filelength(file); ! 691: if(length<0L) { ! 692: close(file); ! 693: return(-4); } ! 694: if((buf=(ulong *)MALLOC(smb->status.max_crcs*4))==NULL) { ! 695: close(file); ! 696: return(-3); } ! 697: if(length>=smb->status.max_crcs*4) { /* Reached or exceeds max crcs */ ! 698: read(file,buf,smb->status.max_crcs*4); ! 699: for(l=0;l<smb->status.max_crcs;l++) ! 700: if(crc==buf[l]) ! 701: break; ! 702: if(l<smb->status.max_crcs) { /* Dupe CRC found */ ! 703: close(file); ! 704: FREE(buf); ! 705: return(1); } ! 706: chsize(file,0L); /* truncate it */ ! 707: lseek(file,0L,SEEK_SET); ! 708: write(file,buf+4,(smb->status.max_crcs-1)*4); } ! 709: ! 710: else if(length/4) { /* Less than max crcs */ ! 711: read(file,buf,length); ! 712: for(l=0;l<length/4;l++) ! 713: if(crc==buf[l]) ! 714: break; ! 715: if(l<length/4) { /* Dupe CRC found */ ! 716: close(file); ! 717: FREE(buf); ! 718: return(1); } } ! 719: ! 720: lseek(file,0L,SEEK_END); ! 721: write(file,&crc,4); /* Write to the end */ ! 722: FREE(buf); ! 723: close(file); ! 724: return(0); ! 725: } ! 726: ! 727: ! 728: /****************************************************************************/ ! 729: /* Creates a new message header record in the header file. */ ! 730: /* If storage is SMB_SELFPACK, self-packing conservative allocation is used */ ! 731: /* If storage is SMB_FASTALLOC, fast allocation is used */ ! 732: /* If storage is SMB_HYPERALLOC, no allocation tables are used (fastest) */ ! 733: /****************************************************************************/ ! 734: int SMBCALL smb_addmsghdr(smb_t *smb, smbmsg_t *msg, int storage) ! 735: { ! 736: int i; ! 737: long l; ! 738: ! 739: if(smb_locksmbhdr(smb)) ! 740: return(1); ! 741: if(smb_getstatus(smb)) ! 742: return(2); ! 743: ! 744: if(storage!=SMB_HYPERALLOC && (i=smb_open_ha(smb))!=0) ! 745: return(i); ! 746: ! 747: msg->hdr.length=smb_getmsghdrlen(msg); ! 748: if(storage==SMB_HYPERALLOC) ! 749: l=smb_hallochdr(smb); ! 750: else if(storage==SMB_FASTALLOC) ! 751: l=smb_fallochdr(smb,msg->hdr.length); ! 752: else ! 753: l=smb_allochdr(smb,msg->hdr.length); ! 754: if(l==-1L) { ! 755: smb_unlocksmbhdr(smb); ! 756: smb_close_ha(smb); ! 757: return(-1); } ! 758: ! 759: smb->status.last_msg++; ! 760: msg->idx.number=msg->hdr.number=smb->status.last_msg; ! 761: msg->idx.offset=smb->status.header_offset+l; ! 762: msg->idx.time=msg->hdr.when_imported.time; ! 763: msg->idx.attr=msg->hdr.attr; ! 764: msg->offset=smb->status.total_msgs; ! 765: smb->status.total_msgs++; ! 766: smb_putstatus(smb); ! 767: ! 768: if(storage!=SMB_HYPERALLOC) ! 769: smb_close_ha(smb); ! 770: i=smb_putmsg(smb,msg); ! 771: smb_unlocksmbhdr(smb); ! 772: return(i); ! 773: } ! 774: ! 775: /****************************************************************************/ ! 776: /* Writes both header and index information for msg 'msg' */ ! 777: /****************************************************************************/ ! 778: int SMBCALL smb_putmsg(smb_t *smb, smbmsg_t *msg) ! 779: { ! 780: int i; ! 781: ! 782: i=smb_putmsghdr(smb,msg); ! 783: if(i) ! 784: return(i); ! 785: return(smb_putmsgidx(smb,msg)); ! 786: } ! 787: ! 788: /****************************************************************************/ ! 789: /* Writes index information for 'msg' */ ! 790: /* msg->idx */ ! 791: /* and msg->offset must be set prior to calling to this function */ ! 792: /* Returns 0 if everything ok */ ! 793: /****************************************************************************/ ! 794: int SMBCALL smb_putmsgidx(smb_t *smb, smbmsg_t *msg) ! 795: { ! 796: ! 797: clearerr(smb->sid_fp); ! 798: fseek(smb->sid_fp,msg->offset*sizeof(idxrec_t),SEEK_SET); ! 799: if(!fwrite(&msg->idx,sizeof(idxrec_t),1,smb->sid_fp)) ! 800: return(1); ! 801: fflush(smb->sid_fp); ! 802: return(0); ! 803: } ! 804: ! 805: /****************************************************************************/ ! 806: /* Writes header information for 'msg' */ ! 807: /* msg->hdr.length */ ! 808: /* msg->idx.offset */ ! 809: /* and msg->offset must be set prior to calling to this function */ ! 810: /* Returns 0 if everything ok */ ! 811: /****************************************************************************/ ! 812: int SMBCALL smb_putmsghdr(smb_t *smb, smbmsg_t *msg) ! 813: { ! 814: ushort i; ! 815: ulong l; ! 816: ! 817: clearerr(smb->shd_fp); ! 818: if(fseek(smb->shd_fp,msg->idx.offset,SEEK_SET)) ! 819: return(-1); ! 820: ! 821: /************************************************/ ! 822: /* Write the fixed portion of the header record */ ! 823: /************************************************/ ! 824: if(!fwrite(&msg->hdr,sizeof(msghdr_t),1,smb->shd_fp)) ! 825: return(-2); ! 826: ! 827: /************************************************/ ! 828: /* Write the data fields (each is fixed length) */ ! 829: /************************************************/ ! 830: for(i=0;i<msg->hdr.total_dfields;i++) ! 831: if(!fwrite(&msg->dfield[i],sizeof(dfield_t),1,smb->shd_fp)) ! 832: return(-3); ! 833: ! 834: /*******************************************/ ! 835: /* Write the variable length header fields */ ! 836: /*******************************************/ ! 837: for(i=0;i<msg->total_hfields;i++) { ! 838: if(!fwrite(&msg->hfield[i],sizeof(hfield_t),1,smb->shd_fp)) ! 839: return(-4); ! 840: if(msg->hfield[i].length /* more then 0 bytes long */ ! 841: && !fwrite(msg->hfield_dat[i],msg->hfield[i].length,1,smb->shd_fp)) ! 842: return(-5); } ! 843: ! 844: l=smb_getmsghdrlen(msg); ! 845: while(l%SHD_BLOCK_LEN) { ! 846: if(fputc(0,smb->shd_fp)==EOF) ! 847: return(-6); /* pad block with NULL */ ! 848: l++; } ! 849: fflush(smb->shd_fp); ! 850: return(0); ! 851: } ! 852: ! 853: /****************************************************************************/ ! 854: /* Creates a sub-board's initial header file */ ! 855: /* Truncates and deletes other associated SMB files */ ! 856: /****************************************************************************/ ! 857: int SMBCALL smb_create(smb_t *smb) ! 858: { ! 859: char str[128]; ! 860: smbhdr_t hdr; ! 861: ! 862: if(filelength(fileno(smb->shd_fp))>=sizeof(smbhdr_t)+sizeof(smbstatus_t) ! 863: && smb_locksmbhdr(smb)) /* header exists, so lock it */ ! 864: return(1); ! 865: memset(&hdr,0,sizeof(smbhdr_t)); ! 866: memcpy(hdr.id,"SMB\x1a",4); /* <S> <M> <B> <^Z> */ ! 867: hdr.version=SMB_VERSION; ! 868: hdr.length=sizeof(smbhdr_t)+sizeof(smbstatus_t); ! 869: smb->status.last_msg=smb->status.total_msgs=0; ! 870: smb->status.header_offset=sizeof(smbhdr_t)+sizeof(smbstatus_t); ! 871: rewind(smb->shd_fp); ! 872: fwrite(&hdr,1,sizeof(smbhdr_t),smb->shd_fp); ! 873: fwrite(&(smb->status),1,sizeof(smbstatus_t),smb->shd_fp); ! 874: rewind(smb->shd_fp); ! 875: chsize(fileno(smb->shd_fp),sizeof(smbhdr_t)+sizeof(smbstatus_t)); ! 876: fflush(smb->shd_fp); ! 877: ! 878: rewind(smb->sdt_fp); ! 879: chsize(fileno(smb->sdt_fp),0L); ! 880: rewind(smb->sid_fp); ! 881: chsize(fileno(smb->sid_fp),0L); ! 882: ! 883: sprintf(str,"%s.SDA",smb->file); ! 884: remove(str); /* if it exists, delete it */ ! 885: sprintf(str,"%s.SHA",smb->file); ! 886: remove(str); /* if it exists, delete it */ ! 887: sprintf(str,"%s.SCH",smb->file); ! 888: remove(str); ! 889: smb_unlocksmbhdr(smb); ! 890: return(0); ! 891: } ! 892: ! 893: /****************************************************************************/ ! 894: /* Returns number of data blocks required to store "length" amount of data */ ! 895: /****************************************************************************/ ! 896: ulong SMBCALL smb_datblocks(ulong length) ! 897: { ! 898: ulong blocks; ! 899: ! 900: blocks=length/SDT_BLOCK_LEN; ! 901: if(length%SDT_BLOCK_LEN) ! 902: blocks++; ! 903: return(blocks); ! 904: } ! 905: ! 906: /****************************************************************************/ ! 907: /* Returns number of header blocks required to store "length" size header */ ! 908: /****************************************************************************/ ! 909: ulong SMBCALL smb_hdrblocks(ulong length) ! 910: { ! 911: ulong blocks; ! 912: ! 913: blocks=length/SHD_BLOCK_LEN; ! 914: if(length%SHD_BLOCK_LEN) ! 915: blocks++; ! 916: return(blocks); ! 917: } ! 918: ! 919: /****************************************************************************/ ! 920: /* Finds unused space in data file based on block allocation table and */ ! 921: /* marks space as used in allocation table. */ ! 922: /* File must be opened read/write DENY ALL */ ! 923: /* Returns offset to beginning of data (in bytes, not blocks) */ ! 924: /* Assumes smb_open_da() has been called */ ! 925: /* smb_close_da() should be called after */ ! 926: /* Returns negative on error */ ! 927: /****************************************************************************/ ! 928: long SMBCALL smb_allocdat(smb_t *smb, ulong length, ushort headers) ! 929: { ! 930: ushort i,j; ! 931: ulong l,blocks,offset=0L; ! 932: ! 933: blocks=smb_datblocks(length); ! 934: j=0; /* j is consecutive unused block counter */ ! 935: fflush(smb->sda_fp); ! 936: rewind(smb->sda_fp); ! 937: while(!feof(smb->sda_fp)) { ! 938: if(!fread(&i,2,1,smb->sda_fp)) ! 939: break; ! 940: offset+=SDT_BLOCK_LEN; ! 941: if(!i) j++; ! 942: else j=0; ! 943: if(j==blocks) { ! 944: offset-=(blocks*SDT_BLOCK_LEN); ! 945: break; } } ! 946: clearerr(smb->sda_fp); ! 947: fseek(smb->sda_fp,(offset/SDT_BLOCK_LEN)*2L,SEEK_SET); ! 948: for(l=0;l<blocks;l++) ! 949: if(!fwrite(&headers,2,1,smb->sda_fp)) ! 950: return(-1); ! 951: fflush(smb->sda_fp); ! 952: return(offset); ! 953: } ! 954: ! 955: /****************************************************************************/ ! 956: /* Allocates space for data, but doesn't search for unused blocks */ ! 957: /* Returns negative on error */ ! 958: /****************************************************************************/ ! 959: long SMBCALL smb_fallocdat(smb_t *smb, ulong length, ushort headers) ! 960: { ! 961: ulong l,blocks,offset; ! 962: ! 963: fflush(smb->sda_fp); ! 964: clearerr(smb->sda_fp); ! 965: blocks=smb_datblocks(length); ! 966: fseek(smb->sda_fp,0L,SEEK_END); ! 967: offset=(ftell(smb->sda_fp)/2L)*SDT_BLOCK_LEN; ! 968: for(l=0;l<blocks;l++) ! 969: if(!fwrite(&headers,2,1,smb->sda_fp)) ! 970: break; ! 971: fflush(smb->sda_fp); ! 972: if(l<blocks) ! 973: return(-1L); ! 974: return(offset); ! 975: } ! 976: ! 977: /****************************************************************************/ ! 978: /* De-allocates space for data */ ! 979: /* Returns non-zero on error */ ! 980: /****************************************************************************/ ! 981: int SMBCALL smb_freemsgdat(smb_t *smb, ulong offset, ulong length ! 982: , ushort headers) ! 983: { ! 984: ushort i; ! 985: ulong l,blocks; ! 986: ! 987: blocks=smb_datblocks(length); ! 988: ! 989: clearerr(smb->sda_fp); ! 990: for(l=0;l<blocks;l++) { ! 991: if(fseek(smb->sda_fp,((offset/SDT_BLOCK_LEN)+l)*2L,SEEK_SET)) ! 992: return(1); ! 993: if(!fread(&i,2,1,smb->sda_fp)) ! 994: return(2); ! 995: if(headers>i) ! 996: i=0; /* don't want to go negative */ ! 997: else ! 998: i-=headers; ! 999: if(fseek(smb->sda_fp,-2L,SEEK_CUR)) ! 1000: return(3); ! 1001: if(!fwrite(&i,2,1,smb->sda_fp)) ! 1002: return(4); } ! 1003: fflush(smb->sda_fp); ! 1004: return(0); ! 1005: } ! 1006: ! 1007: /****************************************************************************/ ! 1008: /* Adds to data allocation records for blocks starting at 'offset' */ ! 1009: /* Returns non-zero on error */ ! 1010: /****************************************************************************/ ! 1011: int SMBCALL smb_incdat(smb_t *smb, ulong offset, ulong length, ushort headers) ! 1012: { ! 1013: ushort i; ! 1014: ulong l,blocks; ! 1015: ! 1016: clearerr(smb->sda_fp); ! 1017: blocks=smb_datblocks(length); ! 1018: for(l=0;l<blocks;l++) { ! 1019: fseek(smb->sda_fp,((offset/SDT_BLOCK_LEN)+l)*2L,SEEK_SET); ! 1020: if(!fread(&i,2,1,smb->sda_fp)) ! 1021: return(1); ! 1022: i+=headers; ! 1023: fseek(smb->sda_fp,-2L,SEEK_CUR); ! 1024: if(!fwrite(&i,2,1,smb->sda_fp)) ! 1025: return(2); } ! 1026: fflush(smb->sda_fp); ! 1027: return(0); ! 1028: } ! 1029: ! 1030: /****************************************************************************/ ! 1031: /* De-allocates blocks for header record */ ! 1032: /* Returns non-zero on error */ ! 1033: /****************************************************************************/ ! 1034: int SMBCALL smb_freemsghdr(smb_t *smb, ulong offset, ulong length) ! 1035: { ! 1036: uchar c=0; ! 1037: ulong l,blocks; ! 1038: ! 1039: clearerr(smb->sha_fp); ! 1040: blocks=smb_hdrblocks(length); ! 1041: fseek(smb->sha_fp,offset/SHD_BLOCK_LEN,SEEK_SET); ! 1042: for(l=0;l<blocks;l++) ! 1043: if(!fwrite(&c,1,1,smb->sha_fp)) ! 1044: return(1); ! 1045: fflush(smb->sha_fp); ! 1046: return(0); ! 1047: } ! 1048: ! 1049: /****************************************************************************/ ! 1050: /* Frees all allocated header and data blocks for 'msg' */ ! 1051: /****************************************************************************/ ! 1052: int SMBCALL smb_freemsg(smb_t *smb, smbmsg_t *msg) ! 1053: { ! 1054: int i; ! 1055: ushort x; ! 1056: ! 1057: if(smb->status.attr&SMB_HYPERALLOC) /* Nothing to do */ ! 1058: return(0); ! 1059: ! 1060: for(x=0;x<msg->hdr.total_dfields;x++) { ! 1061: if((i=smb_freemsgdat(smb,msg->hdr.offset+msg->dfield[x].offset ! 1062: ,msg->dfield[x].length,1))!=0) ! 1063: return(i); } ! 1064: return(smb_freemsghdr(smb,msg->idx.offset-smb->status.header_offset ! 1065: ,msg->hdr.length)); ! 1066: } ! 1067: ! 1068: /****************************************************************************/ ! 1069: /* Finds unused space in header file based on block allocation table and */ ! 1070: /* marks space as used in allocation table. */ ! 1071: /* File must be opened read/write DENY ALL */ ! 1072: /* Returns offset to beginning of header (in bytes, not blocks) */ ! 1073: /* Assumes smb_open_ha() has been called */ ! 1074: /* smb_close_ha() should be called after */ ! 1075: /* Returns -1L on error */ ! 1076: /****************************************************************************/ ! 1077: long SMBCALL smb_allochdr(smb_t *smb, ulong length) ! 1078: { ! 1079: uchar c; ! 1080: ushort i; ! 1081: ulong l,blocks,offset=0; ! 1082: ! 1083: blocks=smb_hdrblocks(length); ! 1084: i=0; /* i is consecutive unused block counter */ ! 1085: fflush(smb->sha_fp); ! 1086: rewind(smb->sha_fp); ! 1087: while(!feof(smb->sha_fp)) { ! 1088: if(!fread(&c,1,1,smb->sha_fp)) ! 1089: break; ! 1090: offset+=SHD_BLOCK_LEN; ! 1091: if(!c) i++; ! 1092: else i=0; ! 1093: if(i==blocks) { ! 1094: offset-=(blocks*SHD_BLOCK_LEN); ! 1095: break; } } ! 1096: clearerr(smb->sha_fp); ! 1097: fseek(smb->sha_fp,offset/SHD_BLOCK_LEN,SEEK_SET); ! 1098: c=1; ! 1099: for(l=0;l<blocks;l++) ! 1100: if(!fwrite(&c,1,1,smb->sha_fp)) ! 1101: return(-1L); ! 1102: fflush(smb->sha_fp); ! 1103: return(offset); ! 1104: } ! 1105: ! 1106: /****************************************************************************/ ! 1107: /* Allocates space for index, but doesn't search for unused blocks */ ! 1108: /* Returns -1L on error */ ! 1109: /****************************************************************************/ ! 1110: long SMBCALL smb_fallochdr(smb_t *smb, ulong length) ! 1111: { ! 1112: uchar c=1; ! 1113: ulong l,blocks,offset; ! 1114: ! 1115: blocks=smb_hdrblocks(length); ! 1116: fflush(smb->sha_fp); ! 1117: clearerr(smb->sha_fp); ! 1118: fseek(smb->sha_fp,0L,SEEK_END); ! 1119: offset=ftell(smb->sha_fp)*SHD_BLOCK_LEN; ! 1120: for(l=0;l<blocks;l++) ! 1121: if(!fwrite(&c,1,1,smb->sha_fp)) ! 1122: return(-1L); ! 1123: fflush(smb->sha_fp); ! 1124: return(offset); ! 1125: } ! 1126: ! 1127: /************************************************************************/ ! 1128: /* Allocate header blocks using Hyper Allocation */ ! 1129: /* this function should be most likely not be called from anywhere but */ ! 1130: /* smb_addmsghdr() */ ! 1131: /************************************************************************/ ! 1132: long SMBCALL smb_hallochdr(smb_t *smb) ! 1133: { ! 1134: long l; ! 1135: ! 1136: fflush(smb->shd_fp); ! 1137: fseek(smb->shd_fp,0L,SEEK_END); ! 1138: l=ftell(smb->shd_fp); ! 1139: if(l<smb->status.header_offset) /* Header file truncated?!? */ ! 1140: return(smb->status.header_offset); ! 1141: while((l-smb->status.header_offset)%SHD_BLOCK_LEN) /* Even block boundry */ ! 1142: l++; ! 1143: return(l-smb->status.header_offset); ! 1144: } ! 1145: ! 1146: /************************************************************************/ ! 1147: /* Allocate data blocks using Hyper Allocation */ ! 1148: /* smb_locksmbhdr() should be called before this function and not */ ! 1149: /* unlocked until all data fields for this message have been written */ ! 1150: /* to the SDT file */ ! 1151: /************************************************************************/ ! 1152: long SMBCALL smb_hallocdat(smb_t *smb) ! 1153: { ! 1154: long l; ! 1155: ! 1156: fflush(smb->sdt_fp); ! 1157: fseek(smb->sdt_fp,0L,SEEK_END); ! 1158: l=ftell(smb->sdt_fp); ! 1159: if(l<=0) ! 1160: return(l); ! 1161: while(l%SDT_BLOCK_LEN) /* Make sure even block boundry */ ! 1162: l++; ! 1163: return(l); ! 1164: } ! 1165: ! 1166: ! 1167: int SMBCALL smb_feof(FILE *fp) ! 1168: { ! 1169: return(feof(fp)); ! 1170: } ! 1171: ! 1172: int SMBCALL smb_ferror(FILE *fp) ! 1173: { ! 1174: return(ferror(fp)); ! 1175: } ! 1176: ! 1177: int SMBCALL smb_fflush(FILE *fp) ! 1178: { ! 1179: return(fflush(fp)); ! 1180: } ! 1181: ! 1182: int SMBCALL smb_fgetc(FILE *fp) ! 1183: { ! 1184: return(fgetc(fp)); ! 1185: } ! 1186: ! 1187: int SMBCALL smb_fputc(int ch, FILE *fp) ! 1188: { ! 1189: return(fputc(ch,fp)); ! 1190: } ! 1191: ! 1192: int SMBCALL smb_fseek(FILE *fp, long offset, int whence) ! 1193: { ! 1194: return(fseek(fp,offset,whence)); ! 1195: } ! 1196: ! 1197: long SMBCALL smb_ftell(FILE *fp) ! 1198: { ! 1199: return(ftell(fp)); ! 1200: } ! 1201: ! 1202: long SMBCALL smb_fgetlength(FILE *fp) ! 1203: { ! 1204: return(filelength(fileno(fp))); ! 1205: } ! 1206: ! 1207: int SMBCALL smb_fsetlength(FILE *fp, long length) ! 1208: { ! 1209: return(chsize(fileno(fp),length)); ! 1210: } ! 1211: ! 1212: void SMBCALL smb_rewind(FILE *fp) ! 1213: { ! 1214: rewind(fp); ! 1215: } ! 1216: ! 1217: void SMBCALL smb_clearerr(FILE *fp) ! 1218: { ! 1219: clearerr(fp); ! 1220: } ! 1221: ! 1222: long SMBCALL smb_fread(char HUGE16 *buf, long bytes, FILE *fp) ! 1223: { ! 1224: #ifdef __FLAT__ ! 1225: return(fread(buf,1,bytes,fp)); ! 1226: #else ! 1227: long count; ! 1228: ! 1229: for(count=bytes;count>0x7fff;count-=0x7fff,buf+=0x7fff) ! 1230: if(fread((char *)buf,1,0x7fff,fp)!=0x7fff) ! 1231: return(bytes-count); ! 1232: if(fread((char *)buf,1,(int)count,fp)!=count) ! 1233: return(bytes-count); ! 1234: return(bytes); ! 1235: #endif ! 1236: } ! 1237: ! 1238: long SMBCALL smb_fwrite(char HUGE16 *buf, long bytes, FILE *fp) ! 1239: { ! 1240: #ifdef __FLAT__ ! 1241: return(fwrite(buf,1,bytes,fp)); ! 1242: #else ! 1243: long count; ! 1244: ! 1245: for(count=bytes;count>0x7fff;count-=0x7fff,buf+=0x7fff) ! 1246: if(fwrite((char *)buf,1,0x7fff,fp)!=0x7fff) ! 1247: return(bytes-count); ! 1248: if(fwrite((char *)buf,1,(int)count,fp)!=count) ! 1249: return(bytes-count); ! 1250: return(bytes); ! 1251: #endif ! 1252: } ! 1253: ! 1254: #ifdef SMB_GETMSGTXT ! 1255: ! 1256: char HUGE16 * SMBCALL smb_getmsgtxt(smb_t *smb, smbmsg_t *msg, ulong mode) ! 1257: { ! 1258: char HUGE16 *buf=NULL,HUGE16 *lzhbuf,HUGE16 *p; ! 1259: ushort xlat; ! 1260: int i,j,lzh; ! 1261: long l=0,lzo,lzhlen,length; ! 1262: ! 1263: for(i=0;i<msg->hdr.total_dfields;i++) { ! 1264: if(!(msg->dfield[i].type==TEXT_BODY ! 1265: || (mode&GETMSGTXT_TAILS && msg->dfield[i].type==TEXT_TAIL)) ! 1266: || msg->dfield[i].length<=2L) ! 1267: continue; ! 1268: fseek(smb->sdt_fp,msg->hdr.offset+msg->dfield[i].offset ! 1269: ,SEEK_SET); ! 1270: fread(&xlat,2,1,smb->sdt_fp); ! 1271: lzh=0; ! 1272: if(xlat==XLAT_LZH) { ! 1273: lzh=1; ! 1274: fread(&xlat,2,1,smb->sdt_fp); } ! 1275: if(xlat!=XLAT_NONE) /* no other translations currently supported */ ! 1276: continue; ! 1277: ! 1278: length=msg->dfield[i].length-2L; ! 1279: if(lzh) { ! 1280: length-=2; ! 1281: if(length<1) ! 1282: continue; ! 1283: if((lzhbuf=LMALLOC(length))==NULL) ! 1284: return(buf); ! 1285: smb_fread(lzhbuf,length,smb->sdt_fp); ! 1286: lzhlen=*(long *)lzhbuf; ! 1287: if((p=REALLOC(buf,l+lzhlen+3L))==NULL) { ! 1288: FREE(lzhbuf); ! 1289: return(buf); } ! 1290: buf=p; ! 1291: lzh_decode((char *)lzhbuf,length,(char *)buf+l); ! 1292: FREE(lzhbuf); ! 1293: l+=lzhlen; } ! 1294: else { ! 1295: if((p=REALLOC(buf,l+length+3L))==NULL) ! 1296: return(buf); ! 1297: buf=p; ! 1298: p=buf+l; ! 1299: l+=fread(p,1,length,smb->sdt_fp); ! 1300: } ! 1301: if(!l) ! 1302: continue; ! 1303: l--; ! 1304: while(l && buf[l]==0) l--; ! 1305: l++; ! 1306: *(buf+l)=CR; ! 1307: l++; ! 1308: *(buf+l)=LF; ! 1309: l++; ! 1310: *(buf+l)=0; } ! 1311: return(buf); ! 1312: } ! 1313: ! 1314: void SMBCALL smb_freemsgtxt(char HUGE16 *buf) ! 1315: { ! 1316: if(buf!=NULL) ! 1317: FREE(buf); ! 1318: } ! 1319: ! 1320: #endif ! 1321: ! 1322: /* End of SMBLIB.C */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.