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

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

unix.superglobalmegacorp.com

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