1: /* 2: * This file implements server functions for the XNS courier library 3: */ 4: 5: /* 6: $Log: server.c,v $ 7: * Revision 2.0 85/11/21 07:22:19 jqj 8: * 4.3BSD standard release 9: * 10: * Revision 1.3 85/03/11 16:37:39 jqj 11: * *** empty log message *** 12: * 13: * Revision 1.3 85/03/11 16:37:39 jqj 14: * Public alpha-test version, released 11 March 1985 15: * 16: * Revision 1.2 85/01/27 07:37:43 jqj 17: * finished but undebugged version 18: * 19: * Revision 1.1 85/1/4 2:40:00 jqj 20: * Initial revision -- Mogul's tcp-based version 21: */ 22: #ifndef lint 23: static char rcsid[] = "$Header: server.c,v 2.0 85/11/21 07:22:19 jqj Exp $"; 24: #endif 25: 26: #include <stdio.h> 27: #include <sys/time.h> 28: #include <sys/types.h> /* for ns.h */ 29: #include <sys/socket.h> 30: #include <netns/ns.h> /* for XNS addresses and courierconnectin.h */ 31: #include <netns/sp.h> /* for spphdr */ 32: #include "courier.h" 33: #include "realcourierconnection.h" 34: #include <except.h> 35: #include <ctype.h> 36: 37: #if DEBUG 38: int CourierServerDebuggingFlag = 0; 39: #endif 40: 41: /* 42: * Message stream handle. 43: */ 44: CourierConnection *_serverConnection = 0; 45: Unspecified tid; /* transaction ID */ 46: 47: 48: /* CALL, transaction id, prognumh, prognuml, version, procedurenum */ 49: #define CALLHDRLEN 6 50: 51: 52: Unspecified * 53: ReceiveCallMessage(procp, skipcount, skippedwords) 54: Cardinal *procp; 55: int skipcount; 56: Unspecified *skippedwords; 57: { 58: Cardinal msgtype, version; 59: LongCardinal programnumber; 60: Unspecified *buf, *bp, hdrbuf[CALLHDRLEN]; 61: int i; 62: 63: if (skipcount > 1 && _serverConnection->state == wantversion) { 64: skipcount -= 2; 65: _serverConnection->state = calldone; 66: skippedwords += 2; 67: } 68: if (skipcount > CALLHDRLEN) { 69: fprintf(stderr,"ReceiveCallMessage: skipcount=%d, too big\n", 70: skipcount); 71: exit(1); 72: } 73: for (i=0; i < skipcount; i++) 74: hdrbuf[i] = skippedwords[i]; 75: buf = ReadMessage(_serverConnection, hdrbuf+skipcount, 76: CALLHDRLEN-skipcount); 77: bp = hdrbuf; 78: bp += internalize_Cardinal(&msgtype, bp); 79: bp += internalize_Unspecified(&tid, bp); 80: bp += internalize_LongCardinal(&programnumber, bp); 81: bp += internalize_Cardinal(&version, bp); 82: bp += internalize_Cardinal(procp, bp); 83: #if DEBUG 84: if (CourierServerDebuggingFlag) 85: fprintf(stderr, "[ReceiveCallMessage %D %d %d]\n", 86: programnumber, version, *procp); 87: #endif 88: return(buf); 89: } 90: 91: 92: SendReturnMessage(nwords, results) 93: Cardinal nwords; 94: Unspecified *results; 95: { 96: #define RETHDRLEN 2 97: Unspecified *bp, buf[RETHDRLEN]; 98: static Cardinal msgtype = RETURN; 99: 100: #if DEBUG 101: if (CourierServerDebuggingFlag) 102: fprintf(stderr, "[SendReturnMessage %d]\n", nwords); 103: #endif 104: bp = buf; 105: bp += externalize_Cardinal(&msgtype, bp); 106: bp += externalize_Unspecified(&tid, bp); 107: CourierWrite(_serverConnection, (bp-buf), buf, nwords, results); 108: _serverConnection->bdtstate = wantdata; 109: } 110: 111: 112: static int 113: ServerInit(argc, argv, skippedwords) 114: int argc; 115: char *argv[]; 116: Unspecified skippedwords[]; 117: { 118: extern char *malloc(); 119: int skipcount; 120: #if DEBUG 121: int namelen; 122: #endif 123: int i; 124: 125: _serverConnection = (CourierConnection *) 126: malloc(sizeof(CourierConnection)); 127: _serverConnection->bdtstate = wantdata; 128: /* we normally don't bother to set up host, since the server will 129: * never reopen a closed connection 130: */ 131: #if DEBUG 132: namelen = sizeof(struct sockaddr_ns); 133: getpeername(_serverConnection->fd, &_serverConnection->host, &namelen); 134: fprintf(stderr,"[ServerInit: argc=%d]\n",argc); 135: for (i=0; i<argc; i++) fprintf(stderr,"\targv[%d]=%s\n", i,argv[i]); 136: 137: #endif 138: skipcount = -1; 139: while (argc-- > 0) { 140: #if DEBUG 141: if (strcmp(argv[0],"-d") == 0) 142: CourierServerDebuggingFlag = 1; 143: else 144: #endif 145: if (isdigit(*argv[0])) { 146: if (skipcount < 0) { 147: _serverConnection->fd = atoi(argv[0]); 148: skipcount++; 149: } 150: else if (skipcount < 8) 151: skippedwords[skipcount++] = atoi(argv[0]); 152: } 153: argv++; 154: } 155: if (skipcount < 0 || skipcount == 1) { 156: fprintf(stderr,"in ServerInit, skipcount=%d\n",skipcount); 157: exit(1); 158: } 159: _serverConnection->state = wantversion; 160: return(skipcount); 161: } 162: 163: 164: main(argc, argv) 165: int argc; 166: char *argv[]; 167: { 168: /* 169: * The caller may need to read a packet before getting to the 170: * program/version which it needs for dispatching. Data so read 171: * is passed in the argv list, and used to set skipcount and 172: * skippedwords. 173: */ 174: int skipcount; /* actual length of skippedwords */ 175: Unspecified skippedwords[8]; 176: 177: /* ServerInit() contains server-independent startup code */ 178: skipcount = ServerInit(argc, argv, skippedwords); 179: 180: /* Server() may terminate in 2 ways: 181: * (1) normally, with a return(0) and a closed connection, 182: * either from our timeout or from END sent by client. 183: * (2) abnormally, with an exit(1) indicating a protocol 184: * violation. We do not currently close down the 185: * connection in all such cases, but we should. 186: * Note that Server may also exec() a different server if 187: * a remote procedure for a different program arrives. 188: */ 189: Server(skipcount, skippedwords); 190: exit(0); 191: }