1: /* 2: * This file implements client functions for the XNS courier library 3: */ 4: 5: /* 6: $Log: client.c,v $ 7: * Revision 2.0 85/11/21 07:22:04 jqj 8: * 4.3BSD standard release 9: * 10: * Revision 1.3 85/03/11 16:36:46 jqj 11: * *** empty log message *** 12: * 13: * Revision 1.3 85/03/11 16:36:46 jqj 14: * Public alpha-test version, released 11 March 1985 15: * 16: * Revision 1.2 85/01/27 07:37:10 jqj 17: * finished but undebugged version 18: * 19: * Revision 1.1 84/12/30 10:14:30 jqj 20: * Initial revision -- Mogul's tcp-based version 21: */ 22: 23: #ifndef lint 24: static char rcsid[] = "$Header: client.c,v 2.0 85/11/21 07:22:04 jqj Exp $"; 25: #endif 26: 27: #include <stdio.h> 28: #include <sys/types.h> /* for xn.h, and socket.h */ 29: #include <sys/socket.h> 30: #include <netns/ns.h> /* for XNS addresses and courierconnection.h */ 31: #include <netns/sp.h> /* for XNS addresses and courierconnection.h */ 32: #include "courier.h" 33: #include "realcourierconnection.h" 34: #include <except.h> 35: 36: #if DEBUG 37: int CourierClientDebuggingFlag = 0; 38: #endif 39: 40: 41: 42: CourierConnection * 43: CourierOpen( addr ) 44: struct ns_addr *addr; 45: { 46: extern char *malloc(); 47: CourierConnection *conn; 48: 49: conn = (CourierConnection*) malloc(sizeof(CourierConnection)); 50: conn->host.sns_family = AF_NS; 51: conn->host.sns_addr = *addr; 52: /* unknown socket? */ 53: if (conn->host.sns_addr.x_port == 0) 54: conn->host.sns_addr.x_port = htons(IDPPORT_COURIER); 55: #if DEBUG 56: if (CourierClientDebuggingFlag) 57: fprintf(stderr, 58: "[CourierOpen: connect to %x#%x.%x.%x.%x.%x.%x#%x]\n", 59: ns_netof(conn->host.sns_addr), 60: conn->host.sns_addr.x_host.c_host[0], 61: conn->host.sns_addr.x_host.c_host[1], 62: conn->host.sns_addr.x_host.c_host[2], 63: conn->host.sns_addr.x_host.c_host[3], 64: conn->host.sns_addr.x_host.c_host[4], 65: conn->host.sns_addr.x_host.c_host[5], 66: ntohs(conn->host.sns_addr.x_port)); 67: #endif 68: if ((conn->fd = openSPPConnection(&conn->host)) >= 0) { 69: conn->abortseen = FALSE; 70: conn->bdtstate = wantdata; 71: conn->state = wantversion; 72: conn->sphdrOpts.sp_dt = 0; 73: conn->sphdrOpts.sp_cc = 0; 74: return(conn); 75: } 76: else { 77: free((char*)conn); 78: return(NULL); 79: } 80: } 81: 82: 83: SendCallMessage(f, program, version, procedure, nwords, arguments) 84: CourierConnection *f; /* socket descriptor */ 85: LongCardinal program; /* Courier program number */ 86: Cardinal version, /* Courier program version */ 87: procedure, /* Courier procedure number */ 88: nwords; /* number of words in argument buffer */ 89: Unspecified *arguments; /* prepacked argument buffer */ 90: { 91: static Cardinal ourCVersion = COURIERVERSION; 92: static Cardinal msgtype = 0; 93: static Unspecified tid = 0; 94: #define HDRLEN 8 95: Unspecified *_bp, hdrbuf[HDRLEN]; 96: 97: #if DEBUG 98: if (CourierClientDebuggingFlag) 99: fprintf(stderr, "[SendCallMessage program %D procedure %d, arglen %d]\n", 100: program, procedure, nwords); 101: #endif 102: _bp = hdrbuf; 103: if (f->state == wantversion) { 104: /* exchange version numbers */ 105: _bp += externalize_Cardinal(&ourCVersion, _bp); 106: _bp += externalize_Cardinal(&ourCVersion, _bp); 107: } 108: _bp += externalize_Cardinal(&msgtype, _bp); /* call message type */ 109: _bp += externalize_Unspecified(&tid, _bp); /* transaction id */ 110: _bp += externalize_LongCardinal(&program, _bp); 111: _bp += externalize_Cardinal(&version, _bp); 112: _bp += externalize_Cardinal(&procedure, _bp); 113: (void) CheckEND(f); 114: CourierWrite(f, (_bp-hdrbuf), hdrbuf, nwords, arguments); 115: if (f->state == calldone) 116: f->state = inprogress; 117: } 118: 119: 120: Unspecified * 121: ReceiveReturnMessage(f, abortedFlag) 122: CourierConnection *f; /* socket descriptor */ 123: Boolean *abortedFlag; /* TRUE iff abort received */ 124: /* returns a pointer to a block of data to be freed after unpacking 125: * procResults or [errorValue, errorArgs] 126: */ 127: { 128: #define RETHDRLEN 2 129: Unspecified *bp, *buf, hdrbuf[RETHDRLEN]; 130: Cardinal msgtype, tid; 131: rejectionDetails *rdetails; 132: extern char *malloc(); 133: 134: buf = ReadMessage(f, hdrbuf, RETHDRLEN); 135: bp = hdrbuf; 136: f->state = calldone; 137: bp += internalize_Cardinal(&msgtype, bp); 138: bp += internalize_Unspecified(&tid, bp); 139: #if DEBUG 140: if (CourierClientDebuggingFlag) 141: fprintf(stderr, "[ReceiveReturnMessage type %d]\n", msgtype); 142: #endif 143: switch (msgtype) { 144: case RETURN: 145: *abortedFlag = FALSE; 146: break; 147: case REJECT: 148: bp = buf; 149: rdetails = (rejectionDetails*)malloc(sizeof(rejectionDetails)); 150: bp += internalize_enumeration(&(rdetails->designator), bp); 151: if (rdetails->designator == noSuchVersionNumber) { 152: bp += internalize_Cardinal( &(rdetails->noSuchVersionNumber_case.lowest), bp); 153: bp += internalize_Cardinal( &(rdetails->noSuchVersionNumber_case.highest), bp); 154: } 155: Deallocate(buf); 156: raise(REJECT_ERROR, (char*) rdetails); 157: /*NOTREACHED*/ 158: case ABORT: 159: *abortedFlag = TRUE; 160: break; 161: } 162: return(buf); 163: } 164: 165: 166: MaybeCallBDTHandler(f, BDTproc) 167: /* called by RPC stub from Foo_client.c */ 168: CourierConnection *f; /* socket descriptor */ 169: int (*BDTproc)(); 170: { 171: /* can't look ahead here, since server may be expecting us to send 172: * lots of data before he does anything 173: */ 174: f->abortseen = FALSE; 175: /* ### setup interrupt handler for URGENT messages */ 176: if (BDTproc != NULL) 177: (*BDTproc)(f); 178: /* ### clear interrupt handler */ 179: f->bdtstate = wantdata; 180: }