|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.