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

unix.superglobalmegacorp.com

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