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