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