|
|
1.1 root 1: /*************************************************************/
2: /** **/
3: /** Microsoft RPC Examples **/
4: /** Dictionary Application **/
1.1.1.2 ! root 5: /** Copyright(c) Microsoft Corp. 1992 **/
1.1 root 6: /** **/
7: /*************************************************************/
8:
9: /*************************************************************************
10: * *
11: * *
12: * Remote dictionary example: client side *
13: * *
14: * Created: Dov Harel 12/??/1990 *
15: * Modified to use context_handle Donna Liu 3/??/1991 *
1.1.1.2 ! root 16: * Further modifications / documentation Dov Harel 5/01/1991 *
! 17: * Revival for July 92 Preliminary Releaser Dov Harel 6/20/1992 *
1.1 root 18: * *
19: * Description: *
20: * This is the driver for the client side remote dictionary *
21: * (splay trees based) demo. This works as follows: *
22: * *
23: * o in main we bind to the dict interface, and call main_dict; *
24: * *
25: * o in dict_main we call VDict_New to initialize the dictionary *
26: * on the server side, and then call TestLoop. *
27: * *
28: * o in TestLoop we loop responding to user input of the form: *
29: * <one_letter_opcode> [<optional_arg>], *
30: * where <optional_arg> is a an integer constant followed by a *
31: * string. Type "?" for a detailed usage message. *
32: * *
33: *************************************************************************
34: */
35:
1.1.1.2 ! root 36: #define INCL_DOS
! 37:
1.1 root 38: #include <stdio.h>
39: #include <malloc.h>
40: #include <stdlib.h>
41: #include <string.h>
42: #include <ctype.h>
43:
44: #include <rpc.h>
1.1.1.2 ! root 45:
1.1 root 46: #include "dict0.h"
47: #include "replay.h"
48: #include "util0.h"
49:
50: #define TAB_STOPS 4
51:
52: #define RDICT_CURR_RECORD(dict) (((DictState*)dict->state)->curr_record)
53:
1.1.1.2 ! root 54: RPC_BINDING_HANDLE dict_bhandle;
1.1 root 55:
56: char * view = "normal";
57:
58: void Usage()
59: {
60: printf("Usage : client [-s] [-m<machine_name>] [-v<view_option>]\n");
61: exit(1);
62: }
63:
64: /*************************************************************************/
65: /*** Remote Dictionary Print ***/
66: /*************************************************************************/
67:
68: extern char spaces[];
69:
70: void
71: RevPrinTree(int lmargin, /* indentation of the root of the tree */
72: int indent, /* indentation of subsequent levels */
73: TreeNode *np, /* pointer to the root node */
74: PrintFun print) /* short, one line, record print routine */
75: {
1.1.1.2 ! root 76: int i;
1.1 root 77: static char lspaces[] =
78: " ";
79: if (np == NULL) return;
80:
1.1.1.2 ! root 81: // prinTree(lmargin+indent, indent, np->right, print);
1.1 root 82: RevPrinTree(lmargin+indent, indent, np->left, print);
83:
84: if (lmargin > sizeof(lspaces))
85: lmargin = sizeof(lspaces);;
86:
87: lspaces[lmargin] = 0;
88: printf(lspaces);
89: lspaces[lmargin] = ' ';
90:
91: (*print)(np->item);
92:
1.1.1.2 ! root 93: // prinTree(lmargin+indent, indent, np->left, print);
1.1 root 94: RevPrinTree(lmargin+indent, indent, np->right, print);
95:
96: }
97:
98: void
99: LinPrinTree(
100: TreeNode *np, /* pointer to the root node */
101: PrintFun print, /* short, one line, record print routine */
102: Record * local, /* local iterator point */
103: Record * global /* global iterator point */
104: )
105: {
1.1.1.2 ! root 106: int i;
1.1 root 107: if (np == NULL) return;
108:
109: LinPrinTree(np->left, print, local, global);
110:
111: if ( comp(np->item, local) == 0 ) {
112: if ( comp(np->item, global) == 0 )
113: printf(" ==>> ");
114: else
115: printf(" >> ");
116: }
117: else if ( comp(np->item, global) == 0 )
118: printf(" == ");
119: else
120: printf(" ");
121:
122: (*print)(np->item);
123:
124: LinPrinTree(np->right, print, local, global);
125:
126: }
127:
128: void
129: Clnt_Dict_Print(
130: VDict * pvd,
131: int indent,
132: Record * local,
133: Record * global
134: )
135: {
136: RDict DictT = {0, 0};
137: RDict *prd = &DictT;
138:
139: // first: get a new copy a from the server
140:
141: VDict_Get_Dict(*pvd, &prd);
142:
143: if ( !strcmp(view, "normal") )
144: prinTree(0, TAB_STOPS, (TreeNode *) prd->root, printRecord);
145: else if ( !strcmp(view, "reverse") || !strcmp(view, "rev") )
146: RevPrinTree(0, TAB_STOPS, (TreeNode *) prd->root, printRecord);
147: else if ( !strcmp(view, "flat") )
148: LinPrinTree( (TreeNode *) prd->root, printRecord, local,
149: RDICT_CURR_RECORD(prd));
150:
151: RDict_Free_Dict(prd);
152: }
153:
154: /*************************************************************************/
155: /*** Remote Dictionary Test Loop ***/
156: /*************************************************************************/
157:
158: void
159: Usage_Msg()
160: {
1.1.1.2 ! root 161: printf("\nUsage: \nType a single character, followed by an optional key as follows:\n\n");
! 162: printf(" i <key> :: Insert <key> into dictionary\n");
! 163: printf(" d <key> :: Delete <key> from dictionary\n");
! 164: printf(" f <key> :: Find <key> in dictionary\n");
! 165: printf(" N :: next of current item in dictionary\n");
! 166: printf(" P :: previous of current item in dictionary\n");
! 167: printf(" n :: Next of local current item in dictionary\n");
! 168: printf(" p :: Previous of local current item in dictionary\n");
! 169: printf(" h :: Head (first item) of dictionary\n");
! 170: printf(" t :: Tail (last item) of dictionary\n");
! 171: printf(" ? :: Print this message\n");
! 172: printf(" q :: Quit\n\n");
! 173: printf("where <key> is <integer> <string>\n");
1.1 root 174: }
175:
176: void
177: TestLoop( VDict * pvd );
178:
179: void
180: TestLoop( VDict * pvd )
181: {
1.1.1.2 ! root 182: int key;
1.1 root 183: char currName[80];
184: char name[80];
185: char op = 0;
186: char buffer[80];
187:
188: Record r, currRecord;
189: Record *pcurrRecord = &currRecord;
190: Record *pr = &r;
191: Record * pNullRecord = NULL;
192:
193: Dict_Status status;
194: pcurrRecord->name = currName;
195: pr->name = name;
196:
197: VDict_Curr_Item(*pvd, &pcurrRecord);
198: ItemCopy(pcurrRecord, pr);
199:
200: Clnt_Dict_Print(pvd, TAB_STOPS, pcurrRecord, pr);
201: Usage_Msg();
202:
203: while ( op != 'q' ) {
204:
205: printf("\nnext op (i d x f n N p P h t ? q): ");
206: gets(buffer);
207: op = buffer[0];
208:
209: if (op == 'i' || op == 'd' || op == 'f' || op == 'I')
210: sscanf(buffer+1, "%d %s", &pr->key, pr->name);
211:
1.1.1.2 ! root 212: // Obsolete Debug Prints:
! 213: //
! 214: // printf("\npr:: Key : %d, Name : %s \n", pr->key, pr->name);
! 215: // printf("\npcurrRecord:: Key : %d, Name : %s \n", pcurrRecord->key, pcurrRecord->name);
! 216: // printf("%c %d\n\n", (int)op, key);
! 217:
1.1 root 218: switch (op) {
219: case 'h':
220: // get Head of list (first record);
221:
222: status = VDict_Next(*pvd, &pNullRecord);
223: if (pNullRecord != NULL) {
224: ItemCopy(pNullRecord, pcurrRecord);
225: freeRecord(pNullRecord);
226: pNullRecord = NULL;
227: }
228: break;
229:
230: case 't':
231: // get Tail of list (last record)
232:
233: status = VDict_Prev(*pvd, &pNullRecord);
234: if (pNullRecord != NULL) {
235: ItemCopy(pNullRecord, pcurrRecord);
236: freeRecord(pNullRecord);
237: pNullRecord = NULL;
238: }
239: break;
240:
241: case 'f':
242: // Find <key>
243: status = VDict_Find(*pvd, &pr);
244: pr = &r;
245: break;
246:
247: case 'n':
248: // get next record (advance private (local) iterator)
249: status = VDict_Next(*pvd, &pcurrRecord);
250: break;
251:
252: case 'p':
253: // get previous record (retreat private (local) iterator)
254: status = VDict_Prev(*pvd, &pcurrRecord);
255: break;
256:
257: case 'r':
258: // Reset local iterator to global "current item"
259: status = VDict_Curr_Item(*pvd, &pcurrRecord);
260: break;
261:
262: case 'N':
263: // get Next record (advance global iterator)
264: status = VDict_Curr_Next(*pvd, &pr);
265: pr = &r;
266: break;
267:
268: case 'P':
269: // get Previous record (retreat global iterator)
270: status = VDict_Curr_Prev(*pvd, &pr);
271: pr = &r;
272: break;
273:
274: case 'i':
275: // Insert <key>
276: status = VDict_Insert(*pvd, pr);
277: break;
278:
279: case 'I':
280: // Insert (<num'>,"") for all num' s.t. 3 < num' < num
281: status = VDict_I_Dict(*pvd, pr->key);
282: break;
283:
284: case 'd':
285: // Delete <key>
286: status = VDict_Delete(*pvd, &pr);
287: if (status != ITEM_NOT_FOUND && status != EMPTY_DICTIONARY) {
288: pr = &r;
289: }
290: break;
291:
292: case 'x':
293: // Delete DICT_CURR_ITEM
294: status = VDict_Curr_Delete(*pvd, &pr);
295: if (pr == NULL) {
296: pr = &r;
297: }
298: break;
299:
300: case 'X':
301: // Empty the dictionary
302: status = VDict_X_Dict(*pvd);
303: break;
304:
305: case '?':
306: Usage_Msg();
307: break;
308: }
309: if (op != '?' && op != 'q')
310: Clnt_Dict_Print(pvd, TAB_STOPS, pcurrRecord, pr);
311: }
312: }
313:
314:
315: /*************************************************************************/
316: /*** Main Loop ***/
317: /*************************************************************************/
318:
319: void main_dict (short SharedDict)
320: {
321: VDict v_dict = (VDict)0;
322: VDict * pvdict;
323:
324: pvdict = &v_dict;
325:
1.1.1.2 ! root 326: printf ("Getting a new dict...");
1.1 root 327: VDict_New( SharedDict, pvdict );
1.1.1.2 ! root 328:
! 329: printf ("Done.\n");
1.1 root 330: TestLoop(pvdict);
331: }
332:
333: #define MAXPATH 300 // arbitrary large size for server, pipe path
334:
335: main(int argc, char *argv[])
336: {
337: int argscan;
338: char * pszSvrName = NULL;
1.1.1.2 ! root 339: char * pszSvrNetAddress = NULL;
1.1 root 340: char InterfaceAddress[MAXPATH]; // complete path
341: RPC_STATUS status;
342: short Shared_Dictionary = 0; // Share an existing dictionary?
1.1.1.2 ! root 343: unsigned char * StringBinding;
! 344:
! 345: printf ("Microsoft RPC demo Client - Splay (Binary) Tree DataBase\n");
1.1 root 346:
347: // initialize the default server path
348: // by default:
1.1.1.2 ! root 349:
! 350: strcpy(InterfaceAddress, "\\pipe\\dict");
1.1 root 351:
352: if (argc > 1)
353: for (argscan = 1; argscan < argc; argscan++)
354: {
355: if (argv[argscan][0] == '-')
356: {
357: switch (argv[argscan][1])
358: {
359: case 'm':
360: case 'M':
361: pszSvrName = &(argv[argscan][2]);
362: break;
363:
364: case 's':
365: case 'S':
366: Shared_Dictionary = 1;
367: break;
368:
369: case 'v':
370: case 'V':
371: view = &(argv[argscan][2]);
372: break;
373:
374: default:
375: Usage();
376: }
377: }
378: else
379: Usage();
380: }
381:
382: // Usage();
383:
384: /* The dict_ProtocolStack contains a partially initialized
385: * protocol stack for the dict interface. Fill in the remaining
386: * fields:
387: */
388:
1.1.1.2 ! root 389: #ifndef AUTOHANDLE
! 390:
! 391: if (pszSvrName != NULL)
! 392: {
! 393: pszSvrNetAddress = (char *)malloc(strlen(pszSvrName) + 5);
! 394: strcpy(pszSvrNetAddress, "\\\\");
! 395: strcat(pszSvrNetAddress, pszSvrName);
! 396: }
! 397:
! 398: status = RpcStringBindingCompose(0, (unsigned char *) "ncacn_np",
! 399: (unsigned char *)pszSvrNetAddress,
! 400: (unsigned char *) InterfaceAddress, 0,
! 401: &StringBinding);
! 402:
! 403: // printf("StringBinding: %s \n\n", StringBinding);
! 404:
! 405: status = RpcBindingFromStringBinding(StringBinding, &dict_bhandle);
! 406:
! 407: RpcStringFree(&StringBinding);
1.1 root 408:
409: if (status)
410: {
1.1.1.2 ! root 411: printf("Cannot bind to %s -> %x", InterfaceAddress, status);
1.1 root 412: return(1);
413: }
1.1.1.2 ! root 414: #endif
! 415:
1.1 root 416:
1.1.1.2 ! root 417: RpcTryExcept
! 418: {
! 419: main_dict(Shared_Dictionary);
! 420: }
! 421: RpcExcept(1)
! 422: {
! 423: printf("Exception - %u", RpcExceptionCode());
! 424: }
! 425: RpcEndExcept
1.1 root 426:
1.1.1.2 ! root 427: status = RpcBindingFree(&dict_bhandle);
1.1 root 428: if (status)
429: printf("RpcUnbind = %u\n",status);
430:
431: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.