DOCTORC.C

/**************************************************************************** 
Microsoft RPC Version 2.0
Copyright Microsoft Corp. 1992, 1993, 1994- 1996
Doctor Example

FILE: doctorc.c

USAGE: doctorc -n network_address
-p protocol_sequence
-e endpoint
-o options

PURPOSE: Client side of RPC distributed application

FUNCTIONS: main() - binds to server and calls remote procedure

COMMENTS: This version of the distributed application prints
strings from the Doctor server. Doctor is an Eliza-like
personal therapist program that works by simple
pattern-matching.

****************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "doctor.h" // header file generated by MIDL compiler

#define PURPOSE \
"This Microsoft RPC Version 2.0 sample program demonstrates\n\
the use of the [string] and [size_is] attributes. For more\n\
information about attributes and RPC API functions, see the\n\
RPC programming guide and reference.\n\n"

#define GREETING \
"The doctor is in.\n\
I am at your service; just tell me anything that troubles\n\
or concerns you. Please end your sentences with a period,\n\
a question mark, or an exclamation point, and then press\n\
the RETURN or ENTER key. When you are ready to quit our\n\
session, just enter \"bye\" and press RETURN or ENTER.\n\n\
What is your name? >"

#define FAREWELL \
"I hope I have been of some service to you.\n\
Let's get together again some time.\n\n"


void Usage(char * pszProgramName)
{
fprintf(stderr, "%s", PURPOSE);
fprintf(stderr, "Usage: %s\n", pszProgramName);
fprintf(stderr, " -p protocol_sequence\n");
fprintf(stderr, " -n network_address\n");
fprintf(stderr, " -e endpoint\n");
fprintf(stderr, " -o options\n");
exit(1);
}

void _CRTAPI1 main(int argc, char **argv)
{
RPC_STATUS status; // returned by RPC API function
unsigned char pszName[STRSIZE]; // patient name
unsigned char achIn[STRSIZE]; // patient input

unsigned char * pszUuid = NULL;
unsigned char * pszProtocolSequence = "ncacn_np";
unsigned char * pszNetworkAddress = NULL;
unsigned char * pszEndpoint = "\\pipe\\doctor";
unsigned char * pszOptions = NULL;
unsigned char * pszStringBinding = NULL;
int i;

/* allow the user to override settings with command line switches */
for (i = 1; i < argc; i++) {
if ((*argv[i] == '-') || (*argv[i] == '/')) {
switch (tolower(*(argv[i]+1))) {
case 'p': // protocol sequence
pszProtocolSequence = argv[++i];
break;
case 'n': // network address
pszNetworkAddress = argv[++i];
break;
case 'e':
pszEndpoint = argv[++i];
break;
case 'o':
pszOptions = argv[++i];
break;
case 'h':
case '?':
default:
Usage(argv[0]);
}
}
else
Usage(argv[0]);
}

/* Use a convenience function to concatenate the elements of */
/* the string binding into the proper sequence. */
status = RpcStringBindingCompose(pszUuid,
pszProtocolSequence,
pszNetworkAddress,
pszEndpoint,
pszOptions,
&pszStringBinding);
if (status) {
printf("RpcStringBindingCompose returned 0x%x\n", status);
printf("pszStringBinding = %s\n", pszStringBinding);
exit(status);
}

/* Set the binding handle that will be used to bind to the server. */
status = RpcBindingFromStringBinding(pszStringBinding,
&doctor_IfHandle);
if (status) {
printf("RpcBindingFromStringBinding returned 0x%x\n", status);
exit(status);
}

/* RPC is now initialized. Call remote procedures as if */
/* they were local procedures. */

/* The doctor program consists of patient statements and doctor */
/* responses. The patient string is transmitted to the server, */
/* and all processing is performed on the server. */

printf("%s", GREETING);
gets(pszName);
printf("\n%s>", pszName);

while (gets(achIn)) {
if (strncmp(achIn, "bye", 3) == 0) // end of session?
break;
RpcTryExcept {
Analyze(&achIn[0]);
}
RpcExcept(1) {
printf("Runtime reported exception %ld\n", RpcExceptionCode() );
break;
}
RpcEndExcept

printf("%s%s>", achIn, pszName); // no, continue
}

RpcTryExcept {
Shutdown(); // yes, shutdown the server
}
RpcExcept(1) {
printf("Runtime reported exception %ld\n", RpcExceptionCode() );
}
RpcEndExcept

/* The calls to the remote procedure are complete. */
/* Free the binding handle. */
status = RpcBindingFree(&doctor_IfHandle); // remote calls done; unbind
if (status) {
printf("RpcBindingFree returned 0x%x\n", status);
exit(status);
}

printf("%s", FAREWELL);

exit(0);

} // end main()


/*********************************************************************/
/* MIDL allocate and free */
/*********************************************************************/

void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
return(malloc(len));
}

void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
free(ptr);
}

/* end file doctorc.c */