Annotation of sbbs/sbbs2/smb/smblib.c, revision 1.1.1.2

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 */

unix.superglobalmegacorp.com

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