Annotation of 43BSDTahoe/new/xns/xnslib/lookahead.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * This file implements functions used by both server and daemon
                      3:  * for the XNS courier library
                      4:  */
                      5: 
                      6: /*
                      7:  $Log: lookahead.c,v $
                      8:  * Revision 2.1  86/11/19  06:24:48  jqj
                      9:  * Per Ed Flint:  in LookAheadCallMsg, don't decrement byteswanted when
                     10:  * skipping non-RPC packets.
                     11:  * 
                     12:  * Revision 2.0  85/11/21  07:22:10  jqj
                     13:  * 4.3BSD standard release
                     14:  * 
                     15:  * Revision 1.4  85/09/28  06:54:25  jqj
                     16:  * 1/ 4.3 version.
                     17:  * 2/ fix bug in error reporting -- it had always reported NoSuchVersionNumber
                     18:  * even when NoSuchProgram was appropriate.
                     19:  * 
                     20:  */
                     21: 
                     22: #ifndef lint
                     23: static char rcsid[] = "$Header: lookahead.c,v 2.1 86/11/19 06:24:48 jqj Exp $";
                     24: #endif
                     25: 
                     26: #include <stdio.h>
                     27: #include <sys/time.h>
                     28: #include <sys/types.h>         /* for xn.h */
                     29: #include <sys/socket.h>
                     30: #include <sys/uio.h>
                     31: #include <netns/ns.h>          /* for XNS addresses and courierconnectin.h */
                     32: #include <netns/idp.h>
                     33: #include <netns/sp.h>          /* for spphdr */
                     34: #include "courier.h"
                     35: #include "realcourierconnection.h"
                     36: #include "courierdb.h"
                     37: #ifndef COURLIB
                     38: #define COURLIB "/usr/new/lib/xnscourier"
                     39: #endif
                     40: 
                     41: #define MAKEVEC(idx, addr, len) our_iovec[idx].iov_base = (caddr_t)addr;\
                     42:                                our_iovec[idx].iov_len = len;
                     43: 
                     44: #if DEBUG
                     45: extern int CourierServerDebuggingFlag;
                     46: #endif
                     47: 
                     48: extern CourierConnection *_serverConnection;
                     49: extern Unspecified tid;
                     50: 
                     51: int
                     52: LookAheadCallMsg(progptr, versionptr, skippedwords)
                     53:        LongCardinal *progptr;
                     54:        Cardinal *versionptr;
                     55:        Unspecified skippedwords[];
                     56: /* Returns number of words set in skippedwords i.e. from packets we
                     57:  * had to read to get to the program/version pair.  Sets *progptr
                     58:  * to the program number, and *versionptr to the version number.
                     59:  */
                     60: /* Returns -1 if timeout expired.  SPP connection is closed. */
                     61: {
                     62:        register CourierConnection *f = _serverConnection;
                     63:        static struct timeval timeout = {90,0}; /* 90sec. timeout */
                     64:        int     fdmask,
                     65:                count,
                     66:                byteswanted,
                     67:                bytesread;
                     68:        struct sphdr hdrbuf;
                     69:        Unspecified databuf[MAXWORDS];
                     70:        Unspecified *bp;
                     71:        Cardinal msgtype;
                     72:        Unspecified msgtid;
                     73:        static Cardinal ourversion = COURIERVERSION;
                     74:        Cardinal versionl, versionh;
                     75:        static struct iovec our_iovec[3];       
                     76:        static struct msghdr ourmsg = {0, 0, our_iovec, 3, 0, 0};
                     77: 
                     78:        fdmask = 1<<(f->fd);
                     79:        count = 0;
                     80:        bytesread = 0;
                     81:        byteswanted = 14;       /* CverL, CverH, CALL, tid, Prg1, Prg2, Ver */
                     82:        MAKEVEC(0, &hdrbuf, sizeof(struct sphdr));
                     83:        MAKEVEC(1, skippedwords, byteswanted);
                     84:        MAKEVEC(2, databuf, SPPMAXDATA);
                     85:        /* wantversion =df need to read a courier version # from stream */
                     86:        if (f->state != wantversion) {
                     87:                /* pretend we've gotten a version */
                     88:                bp = skippedwords;
                     89:                bp += externalize_Cardinal(&ourversion, bp);
                     90:                bp += externalize_Cardinal(&ourversion, bp);
                     91:                bytesread += 4;
                     92:                byteswanted -= 4;
                     93:                our_iovec[1].iov_len -= 4;
                     94:                our_iovec[1].iov_base += 4;
                     95:                /* tell other routines there is a version */
                     96:                f->state = wantversion;
                     97:        }
                     98:        if (select(f->fd+1,&fdmask,(int*)NULL,(int*)NULL,&timeout) <= 0) {
                     99:                (void) sppclose(f->fd);
                    100:                f->state = closed;
                    101:                return(-1);
                    102:        }
                    103:        while (byteswanted > 0) {
                    104:                count = recvmsg(f->fd, &ourmsg, MSG_PEEK)
                    105:                  - sizeof(struct sphdr);
                    106:                if (count < 0 || hdrbuf.sp_dt == SPPSST_END) {
                    107:                        (void) sppclosereply(f->fd);
                    108:                        f->state = closed;
                    109:                        return(-1);
                    110:                }
                    111:                if (hdrbuf.sp_dt != SPPSST_RPC &&
                    112:                    (bytesread > 0 || count != 4)) {
                    113:                                /* throw away bad packets */
                    114:                        (void) readv(f->fd, our_iovec, 3);
                    115:                        continue;       /* don't decrement byteswanted */
                    116:                }
                    117:                else if (count <= byteswanted) {
                    118:                                /* actually read the packet we peeked */
                    119:                        count = readv(f->fd, our_iovec, 3) -
                    120:                          sizeof(struct sphdr);
                    121:                        bytesread += count;
                    122:                        our_iovec[1].iov_len -= count;
                    123:                        our_iovec[1].iov_base += count;
                    124:                }
                    125:                byteswanted -= count;
                    126:        }
                    127:        bp = skippedwords;
                    128:        bp += internalize_Cardinal(&versionl, bp);
                    129:        bp += internalize_Cardinal(&versionh, bp);
                    130:        if (versionl > COURIERVERSION || versionh < COURIERVERSION) {
                    131:                (void) sppclose(f->fd);
                    132:                f->state = closed;
                    133:                return(-1);
                    134:                /*NOTREACHED*/
                    135:        }
                    136:        /*
                    137:         * note we haven't actually read the packet containing the
                    138:         * remote procedure number, though we may have PEEKed it.
                    139:         */
                    140:        bp += internalize_Cardinal(&msgtype, bp);
                    141:        if (msgtype != CALL) {
                    142:                SendRejectMessage(unspecifiedError, 0, NULL);
                    143:                (void) sppclose(f->fd);
                    144:                f->state = closed;
                    145:                return(-1);
                    146:                /*NOTREACHED*/
                    147:        }
                    148:        bp += internalize_Unspecified(&msgtid, bp);
                    149:        bp += internalize_LongCardinal(progptr, bp);
                    150:        bp += internalize_Cardinal(versionptr, bp);
                    151:        return(bytesread/sizeof(Unspecified));
                    152:        /* all that work, and we have to do it over again */
                    153: }
                    154: 
                    155: ExecCourierProgram(programnum, versionnum, skipcount, skippedwords)
                    156:        LongCardinal programnum;
                    157:        Cardinal versionnum;
                    158:        int skipcount;
                    159:        Unspecified skippedwords[];
                    160: /*
                    161:  * Exec the appropriate courier program, passing it asciized skippedwords
                    162:  * in the argument list.
                    163:  * Does not return unless the exec failed or the server was not found.
                    164:  * If the server cannot be EXECed, then the appropriate message is sent
                    165:  * back on the wire and the current message is flushed.
                    166:  */
                    167: {
                    168:        struct courierdbent *cdbent;
                    169:        char *argv[12];
                    170:        int i, argc;
                    171:        extern char *malloc();
                    172:        char tmpbuf[1024];
                    173: 
                    174:        cdbent = getcourierservice(programnum, versionnum);
                    175:        if (cdbent != NULL &&
                    176:            (cdbent->cr_serverbin == NULL || *cdbent->cr_serverbin == '\0')) {
                    177:                sprintf(tmpbuf,"%s/%s%dd",
                    178:                        COURLIB,
                    179:                        cdbent->cr_programname, cdbent->cr_version);
                    180:                if (access(tmpbuf,1) == 0)
                    181:                        cdbent->cr_serverbin = tmpbuf;
                    182:        }
                    183:        if (cdbent == NULL || cdbent->cr_serverbin == NULL ||
                    184:            *cdbent->cr_serverbin == '\0') {
                    185:                register Cardinal curval;
                    186:                Cardinal range[2];
                    187:                range[0] = 077777; range[1] = curval = 0;
                    188:                setcourierdbent();
                    189:                while ((cdbent = getcourierdbent()) != NULL) {
                    190:                        if (cdbent->cr_programnumber != programnum) continue;
                    191:                        curval = cdbent->cr_version;
                    192:                        if (curval < range[0]) range[0] = curval;
                    193:                        if (curval > range[1]) range[1] = curval;
                    194:                }
                    195:                Deallocate(ReadMessage(_serverConnection, NULL, 0));
                    196:                /* flush message */
                    197:                if (curval > 0)
                    198:                  SendRejectMessage(noSuchVersionNumber, 2, range);
                    199:                else SendRejectMessage(noSuchProgramNumber, 0, NULL);
                    200: #if DEBUG
                    201:                (void) fprintf(stderr, "xnscourierd: no program %d(%d)\n",
                    202:                               programnum, versionnum);
                    203: #endif
                    204:                return;         /* can't find server */
                    205:        }
                    206:        argc = 0;
                    207:        argv[argc] = malloc(4); /* allow 3 digits per file descriptor */
                    208:        sprintf(argv[argc++],"%d",(int)_serverConnection->fd);
                    209:        for (i = 0; i < skipcount; i++) {
                    210:                argv[argc] = malloc(8); /* allow 7 digits per Unspecified */
                    211:                sprintf(argv[argc++],"%d",(int) skippedwords[i]);
                    212:        }
                    213:        argv[argc] = (char *) 0;
                    214:        execv(cdbent->cr_serverbin, argv);
                    215:        Deallocate(ReadMessage(_serverConnection, NULL, 0));/* flush message */
                    216:        SendRejectMessage(unspecifiedError, 0, NULL);
                    217: #if DEBUG
                    218:        (void) fprintf(stderr, "xnscourierd: can't exec %s\n",
                    219:                       cdbent->cr_serverbin);
                    220: #endif
                    221:        return;
                    222: }
                    223: 
                    224: 
                    225: SendRejectMessage(rejecttype, nwords, arguments)
                    226:        Cardinal rejecttype;
                    227:        Cardinal nwords;
                    228:        Unspecified *arguments;
                    229: {
                    230: #define REJECTHDRLEN 3
                    231:        static Cardinal msgtype = REJECT;
                    232:        Unspecified *bp, buf[REJECTHDRLEN];
                    233: 
                    234: #if DEBUG
                    235:        if (CourierServerDebuggingFlag)
                    236:                fprintf(stderr, "[SendRejectMessage %d, length %d]\n",
                    237:                        rejecttype, nwords);
                    238: #endif
                    239:        bp = buf;
                    240:        bp += externalize_Cardinal(&msgtype, bp);
                    241:        bp += externalize_Unspecified(&tid, bp);
                    242:        bp += externalize_Cardinal(&rejecttype, bp);
                    243:        CourierWrite(_serverConnection, (bp-buf), buf, nwords, arguments);
                    244: }
                    245: 
                    246: 
                    247: SendAbortMessage(errorvalue, nwords, arguments)
                    248:        LongCardinal errorvalue;
                    249:        Cardinal nwords;
                    250:        Unspecified *arguments;
                    251: /* note that arguments does NOT include the error value */
                    252: {
                    253: #define ABORTHDRLEN 3
                    254:        Cardinal shorterror;
                    255:        static Cardinal msgtype = ABORT;
                    256:        Unspecified *bp, buf[ABORTHDRLEN];
                    257: 
                    258: #if DEBUG
                    259:        if (CourierServerDebuggingFlag)
                    260:                fprintf(stderr, "[SendAbortMessage %d %d]\n",
                    261:                                errorvalue, nwords);
                    262: #endif
                    263:        bp = buf;
                    264:        bp += externalize_Cardinal(&msgtype, bp);
                    265:        bp += externalize_Unspecified(&tid, bp);
                    266:        shorterror = (Cardinal) (errorvalue - ERROR_OFFSET);
                    267:        bp += externalize_Cardinal(&shorterror, bp);
                    268:        CourierWrite(_serverConnection, (bp-buf), buf, nwords, arguments);
                    269: }
                    270: 
                    271: /*ARGSUSED*/
                    272: NoSuchProcedureValue(prog_name, proc)
                    273:        String prog_name;
                    274:        Cardinal proc;
                    275: {
                    276:        SendRejectMessage(noSuchProcedureValue, 0, (Unspecified*) NULL);
                    277: #if DEBUG
                    278:        if (CourierServerDebuggingFlag)
                    279:                fprintf(stderr, "[NoSuchProcedureValue %d in %s]\n",
                    280:                        proc, prog_name);
                    281: #endif
                    282: }

unix.superglobalmegacorp.com

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