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