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