|
|
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.