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

unix.superglobalmegacorp.com

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