Annotation of 43BSD/contrib/xns/xnslib/bdt.c, revision 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.