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: }

Defined functions

ExecCourierProgram defined in line 150; never used
LookAheadCallMsg defined in line 47; never used
NoSuchProcedureValue defined in line 267; never used
SendAbortMessage defined in line 242; never used
SendRejectMessage defined in line 220; used 5 times

Defined variables

rcsid defined in line 19; never used

Defined macros

ABORTHDRLEN defined in line 248; used 1 times
COURLIB defined in line 34; used 2 times
MAKEVEC defined in line 37; used 3 times
REJECTHDRLEN defined in line 225; used 1 times
Last modified: 1986-03-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1614
Valid CSS Valid XHTML 1.0 Strict