Annotation of 43BSD/contrib/xns/xnslib/bdt.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * This file contains routines useful to the applications developer who
                      3:  * must read or write BDT data.
                      4:  */
                      5: 
                      6: /*
                      7:  $Log: bdt.c,v $
                      8:  * Revision 2.0  85/11/21  07:22:02  jqj
                      9:  * 4.3BSD standard release
                     10:  * 
                     11:  * Revision 1.4  85/03/11  16:36:38  jqj
                     12:  * *** empty log message ***
                     13:  * 
                     14:  * Revision 1.4  85/03/11  16:36:38  jqj
                     15:  * Public alpha-test version, released 11 March 1985
                     16:  * 
                     17:  * Revision 1.3  85/03/11  16:34:19  jqj
                     18:  * Public alpha-test version, released 11 March 1985
                     19:  * 
                     20:  * Revision 1.2  85/01/27  07:37:06  jqj
                     21:  * finished but undebugged version
                     22:  * 
                     23:  */
                     24: 
                     25: #ifndef lint
                     26: static char rcsid[] = "$Header: bdt.c,v 2.0 85/11/21 07:22:02 jqj Exp $";
                     27: #endif
                     28: 
                     29: #include <stdio.h>
                     30: #include <sys/time.h>
                     31: #include <sys/types.h>         /* for socket.h and xn.h */
                     32: #include <sys/socket.h>
                     33: #include <sys/uio.h>           /* for scatter/gather io */
                     34: #include <netns/ns.h>          /* for XNS addresses and courierconnection.h */
                     35: #include <netns/idp.h>
                     36: #include <netns/sp.h>          /* for spphdr */
                     37: #include "courier.h"
                     38: #include "realcourierconnection.h"
                     39: 
                     40: #define MAKEVEC(idx, addr, len) our_iovec[idx].iov_base = (caddr_t)addr;\
                     41:                                our_iovec[idx].iov_len = len;
                     42: 
                     43: 
                     44: 
                     45: int
                     46: BDTwrite(f,buffer,nbytes)
                     47: /* Call with CourierConnection*, not *(CourierConnection*) */
                     48: /* Semantics are much like write(), except that it returns -1
                     49:  * if a BDT abort message arrives from receiver.
                     50:  * Returns # of bytes actually written.
                     51:  */
                     52:        register CourierConnection *f;
                     53:        char *buffer;
                     54:        int nbytes;
                     55: {
                     56:        register int n, w;
                     57:        struct iovec our_iovec[2];
                     58: 
                     59:        MAKEVEC(0, &(f->sphdrOpts), sizeof(f->sphdrOpts));
                     60:        MAKEVEC(1, buffer, SPPMAXDATA);
                     61: 
                     62:        if (f->bdtstate == wantdata) {
                     63:                        /* stream=BDT, EOM=FALSE, Attn=FALSE */
                     64:                f->sphdrOpts.sp_dt = SPPSST_BDT;
                     65:                f->sphdrOpts.sp_cc &= ~SP_EM;
                     66:                f->bdtstate = established;
                     67:        }
                     68:        if (BDTabortSeen(f)) {
                     69:                BDTabort(f);    /* send end (abort) */
                     70:                f->abortseen = FALSE;   /* clear abort */
                     71:                f->bdtstate = bdteomseen;
                     72:                return(-1);     /* truncate the stream */
                     73:        }
                     74:        /* ### if nbytes > SPPMAXDATA, do something intelligent? */
                     75:        for(n = nbytes; n > SPPMAXDATA; n -= SPPMAXDATA) {
                     76:                w = writev(f->fd, our_iovec, 2);
                     77:                if(w < SPPMAXDATA)
                     78:                        return( w + nbytes - n);
                     79:                our_iovec[1].iov_base += SPPMAXDATA;
                     80:        }
                     81:        our_iovec[1].iov_len = n;
                     82:        w = writev(f->fd, our_iovec, 2);
                     83:        return( w + nbytes - n);
                     84: }
                     85: 
                     86: 
                     87: int
                     88: BDTclosewrite(f)
                     89: /* call with CourierConnection*, not *(CourierConnection*) */
                     90: /* End a BDT connection.  Returns 0 on success, -1 on failure.
                     91:  */
                     92:        register CourierConnection *f;
                     93: {
                     94: 
                     95:        f->bdtstate = bdteomseen;
                     96:        if (BDTabortSeen(f)) {
                     97:                BDTabort(f);
                     98:                f->abortseen = FALSE;
                     99:                return(-1);
                    100:        }
                    101:        /* stream=BDT, EOM=TRUE, Attn=FALSE */
                    102:        f->sphdrOpts.sp_dt = SPPSST_BDT;
                    103:        f->sphdrOpts.sp_cc |= SP_EM;
                    104:        /* finally, send normal end in a packet of its own */
                    105:        write(f->fd,(char*)&f->sphdrOpts,sizeof(struct sphdr));
                    106:        return(0);
                    107: }
                    108: 
                    109: 
                    110: int
                    111: BDTread(f, buffer, nbytes)
                    112: /* Call with CourierConnection*, not *(CourierConnection*) */
                    113: /* Semantics are much like read(), except that it returns -1 on
                    114:  * more conditions.  Returns number of characters actually read,
                    115:  * or 0 on end of message.
                    116:  */
                    117:        register CourierConnection *f;
                    118:        char *buffer;
                    119:        int nbytes;
                    120: {
                    121:        register int count;
                    122:        struct {
                    123:                struct sphdr hdr;
                    124:                char data[SPPMAXDATA];
                    125:        } packbuf;
                    126:        struct iovec our_iovec[2];
                    127: 
                    128:        switch (f->state) {
                    129:        case closed:
                    130:        case calldone:
                    131:                fprintf(stderr,"BDTread() called while connection state = %s\n",
                    132:                        (f->state == closed) ? "closed" : "calldone");
                    133:                exit(1);
                    134:                /* NOTREACHED */
                    135:        case wantversion:
                    136:                count = recv(f->fd, (char*) &packbuf, sizeof(packbuf), MSG_PEEK)
                    137:                                - sizeof(struct sphdr);
                    138:                while (count == 0
                    139:                       && packbuf.hdr.sp_dt == SPPSST_RPC) {
                    140:                        read(f->fd, (char*) &packbuf, sizeof(packbuf));
                    141:                        count = recv(f->fd, (char*) &packbuf, sizeof(packbuf),
                    142:                                        MSG_PEEK)
                    143:                                        - sizeof(struct sphdr);
                    144:                }
                    145:                if (count == 0)
                    146:                        /* streamtype != SPPSST_RPC, so we can't */
                    147:                        /* have a version number */
                    148:                        break;
                    149:                        /* fall out of switch, still wantversion */
                    150:                /* ### N.B. we don't handle count==2 */
                    151:                else if (count != (2*sizeof(Cardinal)))
                    152:                        /* must be a REJECT or ABORT message */
                    153:                        /* let someone else handle it! */
                    154:                        return(-1);
                    155:                else {
                    156:                        /* must be a Courier version number */
                    157:                        /* read it and throw it away */
                    158:                        read(f->fd, (char*) &packbuf, sizeof(packbuf));
                    159:                        f->state = inprogress;
                    160:                        /* fall into case inprogress */
                    161:                }
                    162:        case inprogress:
                    163:                switch (f->bdtstate) {
                    164:                case wantdata:
                    165:                        count = recv(f->fd, (char*) &packbuf, sizeof(packbuf),
                    166:                                        MSG_PEEK)
                    167:                                        - sizeof(struct sphdr);
                    168:                        if (packbuf.hdr.sp_dt == SPPSST_RPC)
                    169:                                return(-1);
                    170:                        f->bdtstate = established;
                    171:                        /* fall through to case established */
                    172:                case established:
                    173:                        break;
                    174:                        /* fall out of inner (and outer!) switch */
                    175:                case bdteomseen:
                    176:                        return(0);
                    177:                }
                    178:                break;
                    179:        }
                    180:        MAKEVEC(0,&packbuf.hdr,sizeof(struct sphdr));
                    181:        MAKEVEC(1,buffer,nbytes);
                    182:        count = readv(f->fd,our_iovec,2) - sizeof(struct sphdr);
                    183:        /* at this point, we've read a packet that isn't SPPSST_RPC */
                    184:        while (TRUE) {
                    185:                if (packbuf.hdr.sp_dt == SPPSST_END) {
                    186:                        (void) sppclosereply(f->fd);
                    187:                        f->state = closed;
                    188:                        fprintf(stderr,"SPP END received during BDT\n");
                    189:                        exit(1);
                    190:                }
                    191:                if (packbuf.hdr.sp_dt != SPPSST_BDT) {
                    192:                        fprintf(stderr,
                    193:                                "wrong stream type, %d, seen during BDT\n",
                    194:                                packbuf.hdr.sp_dt);
                    195:                        exit(1);
                    196:                        /* NOTREACHED */
                    197:                }
                    198:                if (f->abortseen || (packbuf.hdr.sp_cc & SP_OB)) {
                    199:                        f->abortseen = TRUE;
                    200:                        return(-1);
                    201:                }
                    202:                if (packbuf.hdr.sp_cc & SP_EM) {
                    203:                        f->bdtstate = bdteomseen;
                    204:                        /* next read will return 0 */
                    205:                        return(count);
                    206:                }
                    207:                if (count > 0)
                    208:                        return(count);
                    209:                count = readv(f->fd,our_iovec,2) - sizeof(struct sphdr);
                    210:        }
                    211: }
                    212: 
                    213: BDTabort(f)
                    214:        register CourierConnection *f;
                    215: {
                    216:        static struct handy {
                    217:                struct sphdr hdr;
                    218:                char value;
                    219:        } data;
                    220:        /* stream=BDT, EOM=FALSE, Attn=TRUE */
                    221:        data.hdr.sp_dt = SPPSST_BDT;
                    222:        data.hdr.sp_cc = SP_EM;
                    223:        data.value = 1; /* BDT abort data value */
                    224:        send(f->fd, &data, sizeof(data), MSG_OOB);
                    225:        f->bdtstate = bdteomseen;
                    226:        f->abortseen = TRUE;
                    227: }
                    228: 
                    229: 
                    230: BDTabortSeen(f)
                    231:        register CourierConnection *f;
                    232: {
                    233:        struct {
                    234:                struct sphdr hdr;
                    235:                Unspecified data[MAXWORDS];
                    236:        } packbuf;
                    237:        int fdmask;
                    238:        register int count;
                    239:        static struct timeval timeout = {0,0};
                    240: 
                    241:        fdmask = 1<<(f->fd);
                    242:        /* ### code here for OOB signalling! */
                    243:        while (select(f->fd+1,&fdmask,(int*)NULL,(int*)NULL,&timeout) > 0
                    244:            && (count = recv(f->fd,(char*)&packbuf, sizeof(packbuf),
                    245:                                MSG_PEEK) - sizeof(struct sphdr)) > 0) {
                    246:                if (packbuf.hdr.sp_dt == SPPSST_BDT
                    247:                    && (packbuf.hdr.sp_dt & SP_OB)
                    248:                    && count == 1) {
                    249:                        read(f->fd, (char*)&packbuf, sizeof(packbuf));
                    250:                        f->abortseen = TRUE;
                    251:                        return(TRUE);
                    252:                }
                    253:                else if (count == 0)
                    254:                        read(f->fd, (char*)&packbuf, sizeof(packbuf));
                    255:                else return(FALSE);
                    256:        }
                    257:        return(FALSE);
                    258: }

unix.superglobalmegacorp.com

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