(file) Return to wsmanparser.c CVS log (file) (dir) Up to [OMI] / omi / wsman

   1 mike  1.1 /*
   2           **==============================================================================
   3           **
   4           ** Open Management Infrastructure (OMI)
   5           **
   6           ** Copyright (c) Microsoft Corporation
   7           ** 
   8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
   9           ** use this file except in compliance with the License. You may obtain a copy 
  10           ** of the License at 
  11           **
  12           **     http://www.apache.org/licenses/LICENSE-2.0 
  13           **
  14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
  16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
  17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
  18           **
  19           ** See the Apache 2 License for the specific language governing permissions 
  20           ** and limitations under the License.
  21           **
  22 mike  1.1 **==============================================================================
  23           */
  24           
  25           #include <assert.h>
  26           #include <ctype.h>
  27           #include "wsmanparser.h"
  28           #include "wsbuf.h"
  29           //#include "http.h"
  30           //#include "time.h"
  31           //#include <xml/xml.h>
  32           //#include <base/buf.h>
  33           #include <base/log.h>
  34           #include <base/result.h>
  35           #include <base/strings.h>
  36           
  37           #include "wstags.h"
  38           #include "wstags.inc"
  39           #include <wsman/uri.h>
  40           
  41           #define T MI_T
  42           
  43 mike  1.1 #if 0
  44           #define ENABLE_TRACING
  45           #endif
  46           
  47           #ifdef  ENABLE_TRACING
  48           #define PRINTF(a)  printf a
  49           #else
  50           #define PRINTF(a)
  51           #endif
  52           
  53           #if defined(TRACE_RETURN)
  54           # define RETURN(X) \
  55               do \
  56               { \
  57                   printf("RETURN[%d]\n", __LINE__); \
  58                   return X; \
  59               } \
  60               while (0)
  61           #else
  62           # define RETURN(X) return X
  63           #endif
  64 mike  1.1 
  65           /*
  66           **==============================================================================
  67           **
  68           ** Local definitions:
  69           **
  70           **==============================================================================
  71           */
  72           static int _GetInstance(
  73               XML* xml, 
  74               XML_Elem *start,
  75               Batch*  dynamicBatch,
  76               MI_Instance** dynamicInstanceParams);
  77           
  78           /****************************************************************************************/
  79           /* soap processing */
  80           
  81           static int _MustUnderstandCanBeIgnored(
  82               const XML_Elem* e)
  83           {
  84               size_t i;
  85 mike  1.1     for (i = 0; i < e->attrsSize; i++)
  86               {
  87                   if (strcmp(e->attrs[i].name, "s:mustUnderstand") == 0 &&
  88                       strcmp(e->attrs[i].value, "true") == 0)
  89                   {
  90                       RETURN(-1);
  91                   }
  92               }
  93               return 0;
  94           }
  95           
  96           #if 1
  97           static MI_Boolean IsValidClassname(const char* classname)
  98           {
  99               const char* p = classname;
 100           
 101               if (!isalpha((unsigned char)(*p)) && *p != '_')
 102                   return MI_FALSE;
 103           
 104               p++;
 105           
 106 mike  1.1     for (; *p; p++)
 107               {
 108                   if (!isalnum((unsigned char)(*p)) && *p != '_')
 109                       return MI_FALSE;
 110               }
 111           
 112               return MI_TRUE;
 113           }
 114           #endif
 115           
 116           static int _GetSelector(
 117               XML* xml,
 118               XML_Elem *e,
 119               const char** ns,
 120               const char* classname,
 121               MI_Instance** instance,
 122               Batch** batch)
 123           {
 124               size_t i;
 125           
 126               /* expecting namespace or key */
 127 mike  1.1     for (i = 0; i < e->attrsSize; i++)
 128               {
 129           #if 1
 130                   /* To support GetClass */
 131                   if (strcmp(e->attrs[i].name, "Name") == 0 &&
 132                       strcmp(e->attrs[i].value, "ClassName") == 0)
 133                   {
 134                       if (XML_Expect(xml, e, XML_CHARS, NULL) != 0)
 135                           RETURN(-1);
 136           
 137                       PRINTF(("a:Selector:ClassName{%s}\n", e->data));
 138           
 139                       if (!IsValidClassname(e->data))
 140                           RETURN(-1);
 141           
 142                       classname = e->data;
 143                   }
 144                   else 
 145           #endif
 146                   if (strcmp(e->attrs[i].name, "Name") == 0 &&
 147                       strcmp(e->attrs[i].value, "__cimnamespace") == 0)
 148 mike  1.1         {
 149                       /* namespace */
 150                       if (XML_Expect(xml, e, XML_CHARS, NULL) != 0)
 151                           RETURN(-1);
 152           
 153                       PRINTF(("a:Selector:namespace{%s}\n", e->data));
 154                       *ns = e->data;
 155                   }
 156                   else if (strcmp(e->attrs[i].name, "Name") == 0)
 157                   {
 158                       /* keys */
 159                       const char* propName = e->attrs[i].value;
 160           
 161                       if (XML_Expect(xml, e, XML_CHARS, NULL) != 0)
 162                           RETURN(-1);
 163           
 164                       PRINTF(("a:Selector:namespace{%s}\n", e->data));
 165           
 166                       /* allocate batch and instance if needed */
 167                       if (!(*instance))
 168                       {
 169 mike  1.1                 MI_Result r;
 170                           MI_Char* cn;
 171           
 172                           /* verify that we already received classname */
 173                           if (!classname)
 174                           {
 175                               XML_Raise(xml, "class-name was not found during selector parsing");
 176                               RETURN(-1);
 177                           }
 178           
 179                           /* Destroy old batch if it exists (from previous operation) */
 180                           if (*batch)
 181                           {
 182                               Batch_Destroy(*batch);
 183                           }
 184           
 185                           *batch = Batch_New(BATCH_MAX_PAGES);
 186           
 187                           if (!(*batch))
 188                               RETURN(-1);
 189           
 190 mike  1.1                 cn = Batch_Strdup2(*batch, classname);
 191           
 192                           r = Instance_NewDynamic(instance, cn, MI_FLAG_CLASS, *batch);
 193                           if (MI_RESULT_OK != r)
 194                               RETURN(-1);
 195                       }
 196           
 197                       /* add next property to the instance */
 198                       {
 199                           const MI_Char* wpropName = Batch_Strdup2(*batch, propName);
 200                           MI_Result r;
 201                           MI_Value value;
 202           
 203                           value.string = Batch_Strdup2(*batch, e->data);
 204           
 205                           // Set the property.
 206                           r = MI_Instance_AddElement(*instance, wpropName, &value, 
 207                               MI_STRING, MI_FLAG_BORROW | MI_FLAG_KEY);
 208           
 209                           if (MI_RESULT_OK != r)
 210                               RETURN(-1);
 211 mike  1.1             }
 212                   }
 213                   else
 214                       continue;
 215           
 216                   if (XML_Expect(xml, e, XML_END, "w:Selector") != 0)
 217                       RETURN(-1);
 218           
 219                   break;
 220               }
 221           
 222               return 0;
 223           }
 224           
 225           static int _GetSelectorSet(
 226               XML* xml,
 227               WSMAN_WSHeader* wsheader)
 228           {
 229               XML_Elem e;
 230           
 231               if (XML_Expect(xml, &e, XML_START, "w:Selector") != 0)
 232 mike  1.1         RETURN(-1);
 233           
 234               /* iterate through all selector tags */
 235               for (;;)
 236               {
 237                   if (0 != _GetSelector(
 238                       xml, 
 239                       &e, 
 240                       &wsheader->rqtNamespace,
 241                       wsheader->rqtClassname,
 242                       &wsheader->instance,
 243                       &wsheader->instanceBatch))
 244                       RETURN(-1);
 245           
 246                   /**/
 247                   if (XML_Next(xml, &e) != 0)
 248                       RETURN(-1);
 249           
 250                   if (XML_END == e.type)
 251                       break;
 252           
 253 mike  1.1     }
 254           
 255               return 0;
 256           }
 257           
 258           static int _GetReferenceParameters(
 259               XML* xml, 
 260               Batch*  dynamicBatch,
 261               MI_Instance** dynamicInstanceParams)
 262           {
 263               XML_Elem e;
 264               const char* classname = 0;
 265               const char* nameSpace = NULL;
 266           
 267               /* extract ResourceURI and SelectorSet */
 268               for (;;)
 269               {
 270                   if (XML_Next(xml, &e) != 0)
 271                       RETURN(-1);
 272           
 273                   if (XML_END == e.type)
 274 mike  1.1             break;
 275           
 276                   if (0 == strcmp("w:ResourceURI", e.data))
 277                   {
 278                       if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
 279                           RETURN(-1);
 280           
 281                       classname = strrchr(e.data, '/');
 282                       /* skip '/' */
 283                       if (classname) 
 284                           classname++;
 285           
 286                       if (XML_Expect(xml, &e, XML_END, "w:ResourceURI") != 0)
 287                           RETURN(-1);
 288           
 289                       continue;
 290                   }
 291           
 292                   if (0 == strcmp("w:SelectorSet", e.data))
 293                   {
 294                       /* Allocate an instance */
 295 mike  1.1             if (!*dynamicInstanceParams)
 296                       {
 297                           MI_Result r;
 298                           const MI_Char* cn;
 299           
 300                           if (!classname)
 301                           {
 302                               XML_Raise(xml, "ResourceURI tag expected");
 303                               RETURN(-1);
 304                           }
 305           
 306                           cn = Batch_Strdup2(dynamicBatch, classname);
 307           
 308                           r = Instance_NewDynamic(dynamicInstanceParams, cn, MI_FLAG_CLASS, dynamicBatch);
 309                           if (MI_RESULT_OK != r)
 310                               RETURN(-1);
 311                       }
 312           
 313                       /* iterate through all selector tags */
 314                       for (;;)
 315                       {
 316 mike  1.1                 const char* ns = NULL;
 317           
 318                           if (_GetSelector(
 319                               xml, 
 320                               &e, 
 321                               &ns, 
 322                               classname, 
 323                               dynamicInstanceParams, 
 324                               &dynamicBatch) != 0)
 325                           {
 326                               RETURN(-1);
 327                           }
 328           
 329                           if (ns)
 330                           {
 331                               nameSpace = ns;
 332                           }
 333           
 334                           /**/
 335                           if (XML_Next(xml, &e) != 0)
 336                               RETURN(-1);
 337 mike  1.1 
 338                           if (XML_END == e.type)
 339                               break;
 340           
 341                       }
 342                       continue;
 343                   }
 344               }
 345           
 346               if (nameSpace)
 347                   (*dynamicInstanceParams)->nameSpace = nameSpace;
 348           
 349               return 0;
 350           }
 351           
 352           static int _GetReference(
 353               XML* xml, 
 354               XML_Elem *start,
 355               Batch*  dynamicBatch,
 356               MI_Instance** dynamicInstanceParams)
 357           {
 358 mike  1.1     XML_Elem e;
 359           
 360               e = *start;
 361           
 362               /* extract all parameters */
 363               for (;;)
 364               {
 365                   if (0 != strcmp("a:ReferenceParameters", e.data))
 366                   {
 367                       if (XML_Skip(xml) != 0)
 368                           RETURN(-1);
 369           
 370                       if (XML_Next(xml, &e) != 0)
 371                           RETURN(-1);
 372           
 373                       if (e.type == XML_END)
 374                           break;
 375           
 376                       continue;
 377                   }
 378           
 379 mike  1.1         if (0 != _GetReferenceParameters(xml, dynamicBatch, dynamicInstanceParams))
 380                       RETURN(-1);
 381           
 382                   if (XML_Next(xml, &e) != 0)
 383                       RETURN(-1);
 384           
 385                   if (e.type == XML_END)
 386                       break;
 387               }
 388           
 389               return 0;
 390           }
 391           
 392           static int _GetSingleProperty(
 393               XML* xml,
 394               Batch*  dynamicBatch,
 395               const char* propNameChar,
 396               MI_Value* value,
 397               MI_Type* type)
 398           {
 399               XML_Elem e;
 400 mike  1.1 
 401               if (XML_Next(xml, &e) != 0)
 402                   RETURN(-1);
 403           
 404               if (e.type == XML_CHARS)
 405               {
 406                   /* Plain string property */
 407                   value->string = Batch_Strdup2(dynamicBatch, e.data);
 408                   *type = MI_STRING;
 409           
 410                   if (XML_Expect(xml, &e, XML_END, propNameChar) != 0)
 411                       RETURN(-1);
 412               }
 413               else if ('a' == e.data[0])
 414               {
 415                   /* Reference as </adddress></ReferenceParameters>*/
 416                   value->instance = 0;
 417                   if (0 != _GetReference(xml, &e, dynamicBatch, &value->instance))
 418                       RETURN(-1);
 419           
 420                   *type = MI_REFERENCE;
 421 mike  1.1     }
 422               else
 423               {
 424                   /* Embedded instance */
 425                   value->instance = 0;
 426                   if (0 != _GetInstance(xml, &e, dynamicBatch, &value->instance))
 427                       RETURN(-1);
 428           
 429                   *type = MI_INSTANCE;
 430           
 431                   if (XML_Expect(xml, &e, XML_END, propNameChar) != 0)
 432                       RETURN(-1);
 433               }
 434           
 435           
 436               return 0;
 437           }
 438           
 439           static int _AddValueToArray(
 440               Batch*  dynamicBatch,
 441               MI_Value* valueA,
 442 mike  1.1     MI_Type typeA,
 443               const MI_Value* value,
 444               MI_Type type)
 445           {
 446               /* does type match? */
 447               if ((type | MI_ARRAY_BIT) != typeA)
 448                   RETURN(-1);
 449           
 450               /* do we need to realloc array? */
 451               if ((valueA->array.size % 16) == 0)
 452               {
 453                   void* newData = Batch_Get(dynamicBatch, (valueA->array.size + 16) * sizeof(void*));
 454           
 455                   if (!newData)
 456                       RETURN(-1);
 457           
 458                   if (valueA->array.size)
 459                       memcpy(newData, valueA->array.data, valueA->array.size * sizeof(void*));
 460           
 461                   valueA->array.data = newData;
 462               }
 463 mike  1.1 
 464               if (type == MI_STRING)
 465                   valueA->stringa.data[valueA->stringa.size] = value->string;
 466               else
 467                   valueA->instancea.data[valueA->instancea.size] = value->instance;
 468           
 469               valueA->array.size++;
 470               return 0;
 471           }
 472           
 473           static int _GetInstance(
 474               XML* xml, 
 475               XML_Elem *start,
 476               Batch*  dynamicBatch,
 477               MI_Instance** dynamicInstanceParams)
 478           {
 479               XML_Elem e;
 480               const MI_Char* propNameA = 0;
 481               MI_Value valueA;
 482               MI_Type typeA = MI_BOOLEAN;
 483               const MI_Char* propNamePrev = 0;
 484 mike  1.1     MI_Value valuePrev;
 485               MI_Type typePrev = MI_BOOLEAN;
 486           
 487               memset(&valueA, 0, sizeof(valueA));
 488           
 489               /* extract all parameters */
 490               for (;;)
 491               {
 492                   if (XML_Next(xml, &e) != 0)
 493                       RETURN(-1);
 494           
 495                   if (e.type == XML_END)
 496                       break;
 497           
 498                   /* skip possible comments */
 499                   if (e.type != XML_START)
 500                       continue;
 501           
 502                   /* allocate new instance if needed */
 503                   if (!*dynamicInstanceParams)
 504                   {
 505 mike  1.1             MI_Result r;
 506                       const MI_Char* cn = Batch_Strdup2(dynamicBatch, start->data + 2);
 507           
 508                       r = Instance_NewDynamic(dynamicInstanceParams, cn, MI_FLAG_CLASS, dynamicBatch);
 509                       if (MI_RESULT_OK != r)
 510                           RETURN(-1);
 511                   }
 512           
 513                   /* add next property to the instance */
 514                   if (e.size > 2) /* ?:<name> */
 515                   {
 516                       MI_Result r;
 517                       MI_Value value;
 518                       MI_Type type = MI_BOOLEAN;
 519                       const char* propNameChar;
 520                       const MI_Char* propName;
 521           
 522                       propNameChar = e.data;
 523 mike  1.2 
 524                       /* Position propName one beyond ':' character */
 525                       {
 526                           const MI_Char* p = strchr(propNameChar, ':');
 527           
 528                           if (!p)
 529                               RETURN(-1);
 530           
 531                           propName = Batch_Strdup2(dynamicBatch, p + 1);
 532                       }
 533 mike  1.1 
 534                       type = MI_BOOLEAN;
 535           
 536                       if (0 != _GetSingleProperty(xml, dynamicBatch, propNameChar, &value, &type))
 537                           RETURN(-1);
 538           
 539                       /* Did we collect array's items? */
 540                       if (propNameA)
 541                       {
 542                           /* if we have array and new property matches array - add new item to the array */
 543                           if (0 == Zcmp(propNameA, propName))
 544                           {
 545                               if (0 != _AddValueToArray(dynamicBatch, &valueA, typeA, &value, type))
 546                                   RETURN(-1);
 547                           }
 548                           else
 549                           {
 550                               r = MI_Instance_AddElement(*dynamicInstanceParams, propNameA, &valueA, 
 551                                   typeA, MI_FLAG_BORROW);
 552           
 553                               if (MI_RESULT_OK != r)
 554 mike  1.1                         RETURN(-1);
 555           
 556                               /* Clear array prop name */
 557                               propNameA = 0;
 558           
 559                               propNamePrev = propName;
 560                               valuePrev = value;
 561                               typePrev = type;
 562                           }
 563                       }
 564                       else if (propNamePrev)
 565                       {
 566                           /* Check if name is the same and we need to create an array */
 567                           if (0 == Zcmp(propNamePrev, propName))
 568                           {
 569                               /* create array */
 570                               valueA.array.size = 0;
 571                               valueA.array.data = 0;
 572           
 573                               typeA = type | MI_ARRAY_BIT;
 574                               propNameA = propName;
 575 mike  1.1 
 576                               if (0 != _AddValueToArray(dynamicBatch, &valueA, typeA, &valuePrev, typePrev))
 577                                   RETURN(-1);
 578           
 579                               if (0 != _AddValueToArray(dynamicBatch, &valueA, typeA, &value, type))
 580                                   RETURN(-1);
 581           
 582                           }
 583                           else
 584                           {
 585                               r = MI_Instance_AddElement(*dynamicInstanceParams, propNamePrev, &valuePrev, 
 586                                   typePrev, MI_FLAG_BORROW);
 587           
 588 mike  1.2                     /* Note that the MI_RESULT_ALREADY_EXISTS error is okay
 589                                * for key properties added when the selector set was
 590                                * parsed earlier.
 591                                */
 592                               if (r != MI_RESULT_OK && r != MI_RESULT_ALREADY_EXISTS)
 593                               {
 594 mike  1.1                         RETURN(-1);
 595 mike  1.2                     }
 596 mike  1.1 
 597                               propNamePrev = propName;
 598                               valuePrev = value;
 599                               typePrev = type;
 600                          }
 601           
 602                       }
 603                       else
 604                       {
 605                           /* collecting first item */
 606                           propNamePrev = propName;
 607                           valuePrev = value;
 608                           typePrev = type;
 609                       }
 610                   }
 611               }
 612           
 613               /* if last property was array - add it */
 614               if (propNameA)
 615               {
 616                   MI_Result r;
 617 mike  1.1 
 618                   r = MI_Instance_AddElement(*dynamicInstanceParams, propNameA, &valueA, 
 619                       typeA, MI_FLAG_BORROW);
 620           
 621                   if (MI_RESULT_OK != r)
 622                       RETURN(-1);
 623               }
 624               else if (propNamePrev)
 625               {
 626                   MI_Result r;
 627           
 628                   r = MI_Instance_AddElement(*dynamicInstanceParams, propNamePrev, &valuePrev, 
 629                       typePrev, MI_FLAG_BORROW);
 630           
 631                   if (MI_RESULT_OK != r)
 632                       RETURN(-1);
 633               }
 634           
 635               /* check closing tag */
 636               if (strcmp(e.data, start->data) != 0)
 637                   RETURN(-1);
 638 mike  1.1 
 639               return 0;
 640           }
 641           
 642           int WS_ParseWSHeader(
 643               XML* xml,
 644               WSMAN_WSHeader* wsheader)
 645           {
 646               XML_Elem e;
 647           
 648               memset(wsheader, 0, sizeof(WSMAN_WSHeader));
 649           
 650               /* Expect <s:Header> */
 651               if (XML_Expect(xml, &e, XML_START, "s:Header") != 0)
 652                   RETURN(-1);
 653           
 654               for (;;)
 655               {
 656                   if (XML_Next(xml, &e) != 0)
 657                       RETURN(-1);
 658           
 659 mike  1.1         if (e.type == XML_END)// && strcmp(e.data, "s:Header") == 0)
 660                   {
 661                       int tag = HashStr(e.data, e.size);
 662           
 663                       if (WSMANTAG_HEADER != tag)
 664                       {
 665                           LOGW_CHAR(("wsman: unexpected close tag [%s] in incoming xml", e.data ));
 666                           RETURN(-1);
 667                       }
 668                       //printf("DONE\n");
 669                       break;
 670                   }
 671           
 672                   /* skip possible comments */
 673                   if (e.type != XML_START)
 674                       continue;
 675           
 676                   switch (HashStr(e.data, e.size))
 677                   {
 678                       case WSMANTAG_TO:
 679                       {
 680 mike  1.1                 if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
 681                               RETURN(-1);
 682           
 683                           PRINTF(("a:To{%s}\n", e.data));
 684           
 685                           if (XML_Expect(xml, &e, XML_END, "a:To") != 0)
 686                               RETURN(-1);
 687                       }
 688                       break;
 689           
 690                       case WSMANTAG_RESOURCE_URI:
 691                       {
 692                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
 693                               RETURN(-1);
 694           
 695                           PRINTF(("w:ResourceURI{%s}\n", e.data));
 696                           wsheader->rqtClassname = strrchr(e.data, '/');
 697                           /* skip '/' */
 698                           if (wsheader->rqtClassname) 
 699                               wsheader->rqtClassname++;
 700           
 701 mike  1.1                 if (XML_Expect(xml, &e, XML_END, "w:ResourceURI") != 0)
 702                               RETURN(-1);
 703                       }
 704                       break;
 705           
 706                       case WSMANTAG_REPLY_TO:
 707                       {
 708                           if (XML_Expect(xml, &e, XML_START, "a:Address") != 0)
 709                               RETURN(-1);
 710           
 711                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
 712                               RETURN(-1);
 713           
 714                           if (XML_Expect(xml, &e, XML_END, "a:Address") != 0)
 715                               RETURN(-1);
 716           
 717                           if (XML_Expect(xml, &e, XML_END, "a:ReplyTo") != 0)
 718                               RETURN(-1);
 719                       }
 720                       break;
 721           
 722 mike  1.1             case WSMANTAG_ACTION:
 723                       {
 724                           wsheader->foundAction = MI_TRUE;
 725           
 726                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
 727                               RETURN(-1);
 728           
 729                           wsheader->rqtAction = HashStr(e.data, e.size);
 730           
 731                           if (0 == wsheader->rqtAction)
 732                           {
 733                               char* s;
 734                               /* DSP0226; 9: Custom Actions (Methods) just need to have unique URI.
 735                                   We are assuming it has format like http://<server>/wbem/wscim/1/cim-schema/2/<class-name>/<method-name> */
 736           
 737                               if (0 != strncmp(e.data, "http://", 7))
 738                                   RETURN(-1);
 739           
 740                               wsheader->rqtServer = e.data + 7;
 741           
 742                               s = strchr(wsheader->rqtServer, '/');
 743 mike  1.1 
 744                               if (!s)
 745                                   RETURN(-1);
 746           
 747                               *s = 0;
 748                               s++;
 749           
 750                               if (0 != strncmp(s, "wbem/wscim/1/cim-schema/2/", 26))
 751                                   RETURN(-1);
 752           
 753                               s += 26;
 754           
 755                               wsheader->rqtClassname = s;
 756                               s = strchr(s, '/');
 757           
 758                               if (!s)
 759                                   RETURN(-1);
 760           
 761                               *s = 0;
 762                               s++;
 763                               wsheader->rqtMethod = s;
 764 mike  1.1                 }
 765           
 766                           if (XML_Expect(xml, &e, XML_END, "a:Action") != 0)
 767                               RETURN(-1);
 768                       }
 769                       break;
 770           
 771                       case WSMANTAG_SELECTOR_SET:
 772                       {
 773                           if (_GetSelectorSet(xml, wsheader) != 0)
 774                               RETURN(-1);
 775                       }
 776                       break;
 777           
 778                       case WSMANTAG_MESSAGE_ID:
 779                       {
 780                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
 781                               RETURN(-1);
 782           
 783                           wsheader->rqtMessageID = e.data;
 784           
 785 mike  1.1                 if (XML_Expect(xml, &e, XML_END, "a:MessageID") != 0)
 786                               RETURN(-1);
 787                       }
 788                       break;
 789           
 790                       case WSMANTAG_MAX_ENVELOPE_SIZE:
 791                       {
 792                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
 793                               RETURN(-1);
 794           
 795                           wsheader->maxEnvelopeSize = (MI_Uint32)Strtoull(e.data, NULL, 10);
 796                           PRINTF(("maxEnvelopeSize{%d}\n", wsheader->maxEnvelopeSize));
 797           
 798                           if (XML_Expect(xml, &e, XML_END, "w:MaxEnvelopeSize") != 0)
 799                               RETURN(-1);
 800                       }
 801                       break;
 802           
 803                       default:
 804                       {
 805                           if (_MustUnderstandCanBeIgnored(&e) != 0)
 806 mike  1.1                 {
 807                               wsheader->unknownMandatoryTag = e.data;
 808                               LOGW_CHAR(("wsman: unknown mandatory tag [%s]; aborted", 
 809                                   e.data ));
 810                               /* validate header will send correct repsonse to the client */
 811                           }
 812           
 813                           if (XML_Skip(xml) != 0)
 814                               RETURN(-1);
 815                       }
 816                       break;
 817           
 818                   }
 819               }
 820               return 0;
 821           }
 822           
 823           int WS_ParseSoapEnvelope(XML* xml)
 824           {
 825               XML_Elem e;
 826           
 827 mike  1.1     /* Ignore the processing instruction (if any) */
 828               {
 829                   if (XML_Next(xml, &e) != 0)
 830                   {
 831                       XML_Raise(xml, "missing root element");
 832                       RETURN(-1);
 833                   }
 834           
 835                   if (e.type != XML_INSTRUCTION)
 836                   {
 837                       if (XML_PutBack(xml, &e) != 0)
 838                           RETURN(-1);
 839                   }
 840               }
 841           
 842               /* Expect <s:Envelope> */
 843               if (XML_Expect(xml, &e, XML_START, "s:Envelope") != 0)
 844                   RETURN(-1);
 845           
 846               return 0;
 847           }
 848 mike  1.1 
 849           static const char* _ExpectCharsAndEnd(
 850               XML* xml,
 851               const char* name)
 852           {
 853               XML_Elem e;
 854               const char* chars;
 855           
 856               if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
 857                   return NULL;
 858           
 859               chars = e.data;
 860           
 861               if (XML_Expect(xml, &e, XML_END, name) != 0)
 862                   return NULL;
 863           
 864               return chars;
 865           }
 866           
 867           /*
 868           **==============================================================================
 869 mike  1.1 **
 870           ** _ParseAssociationFilterObject()
 871           **
 872           ** Example:
 873           **   <b:Object>
 874           **     <a:Address>
 875           **       http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
 876           **     </a:Address>
 877           **     <a:ReferenceParameters>
 878           **       <w:ResourceURI>
 879           **         http://schemas.microsoft.com/wbem/wscim/1/cim-schema/2/ABC_Widget
 880           **       </w:ResourceURI>
 881           **       <w:SelectorSet>
 882           **         <w:Selector Name="__cimnamespace">
 883           **           root/cimv2
 884           **         </w:Selector>
 885           **         <w:Selector Name="Key">
 886           **           1001
 887           **         </w:Selector>
 888           **       </w:SelectorSet>
 889           **     </a:ReferenceParameters>
 890 mike  1.1 **   </b:Object>
 891           *
 892           **==============================================================================
 893           */
 894           
 895           static int _ParseAssociationFilterObject(
 896               XML* xml, 
 897               Batch* batch,
 898               WSMAN_AssociationFilter* filter)
 899           {
 900               XML_Elem e;
 901           
 902               /* Parse child elements */
 903           
 904               for (;;)
 905               {
 906                   /* Get next element */
 907           
 908                   if (XML_Next(xml, &e) != 0)
 909                       RETURN(-1);
 910           
 911 mike  1.1         /* Put it back and break out if not a start tag */
 912           
 913                   if (e.type != XML_START)
 914                   {
 915                       if (XML_PutBack(xml, &e) != 0)
 916                           RETURN(-1);
 917           
 918                       break;
 919                   }
 920           
 921                   /* Handle "Object" tag */
 922           
 923                   if (strcmp(e.data, "a:ReferenceParameters") == 0)
 924                   {
 925                       if (_GetReferenceParameters(
 926                           xml, 
 927                           batch, 
 928                           &filter->referenceParameters) != 0)
 929                       {
 930                           RETURN(-1);
 931                       }
 932 mike  1.1         }
 933                   else if (strcmp(e.data, "a:Address") == 0)
 934                   {
 935                       filter->address = _ExpectCharsAndEnd(xml, "a:Address");
 936           
 937                       if (!filter->address)
 938                           RETURN(-1);
 939                   }
 940                   else
 941                   {
 942                       if (XML_Skip(xml) != 0)
 943                           RETURN(-1);
 944                   }
 945               }
 946           
 947               /* Expect </Object> */
 948           
 949               if (XML_Expect(xml, &e, XML_END, "b:Object") != 0)
 950                   RETURN(-1);
 951           
 952               return 0;
 953 mike  1.1 }
 954           
 955           /*
 956           **==============================================================================
 957           **
 958           ** _ParseAssociationFilter()
 959           **
 960           ** Example:
 961           **   <b:AssociatedInstances>
 962           **     <b:Object>
 963           **       <a:Address>
 964           **         http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
 965           **       </a:Address>
 966           **       <a:ReferenceParameters>
 967           **         <w:ResourceURI>
 968           **           http://schemas.microsoft.com/wbem/wscim/1/cim-schema/2/ABC_Widget
 969           **         </w:ResourceURI>
 970           **         <w:SelectorSet>
 971           **           <w:Selector Name="__cimnamespace">
 972           **             root/cimv2
 973           **           </w:Selector>
 974 mike  1.1 **           <w:Selector Name="Key">
 975           **             1001
 976           **           </w:Selector>
 977           **         </w:SelectorSet>
 978           **       </a:ReferenceParameters>
 979           **       </b:Object>
 980           **       <b:AssociationClassName>
 981           **           ABC_Connector
 982           **       </b:AssociationClassName>
 983           **       <b:Role>
 984           **           Component
 985           **       </b:Role>
 986           **     <b:ResultClassName>
 987           **       ABC_Gadget
 988           **     </b:ResultClassName>
 989           **     <b:ResultRole>
 990           **       Part
 991           **     </b:ResultRole>
 992           **   </b:AssociatedInstances>
 993           **
 994           **==============================================================================
 995 mike  1.1 */
 996           
 997           static int _ParseAssociationFilter(
 998               XML* xml, 
 999               Batch* batch,
1000               WSMAN_AssociationFilter* filter)
1001           {
1002               XML_Elem e;
1003           
1004               /* Expect <AssociatedInstances> */
1005           
1006               if (XML_Expect(xml, &e, XML_START, "b:AssociatedInstances") != 0)
1007                   RETURN(-1);
1008           
1009               /* Parse child elements */
1010           
1011               for (;;)
1012               {
1013                   /* Get next element */
1014           
1015                   if (XML_Next(xml, &e) != 0)
1016 mike  1.1             RETURN(-1);
1017           
1018                   /* Put it back and break out if not a start tag */
1019           
1020                   if (e.type != XML_START)
1021                   {
1022                       if (XML_PutBack(xml, &e) != 0)
1023                           RETURN(-1);
1024           
1025                       break;
1026                   }
1027           
1028                   /* Handle "Object" tag */
1029           
1030                   if (strcmp(e.data, "b:Object") == 0)
1031                   {
1032                       if (_ParseAssociationFilterObject(xml, batch, filter) != 0)
1033                           RETURN(-1);
1034                   }
1035                   else if (strcmp(e.data, "b:AssociationClassName") == 0)
1036                   {
1037 mike  1.1             filter->associationClassName = _ExpectCharsAndEnd(
1038                           xml, "b:AssociationClassName");
1039           
1040                       if (!filter->associationClassName)
1041                           RETURN(-1);
1042                   }
1043                   else if (strcmp(e.data, "b:Role") == 0)
1044                   {
1045                       filter->role = _ExpectCharsAndEnd(xml, "b:Role");
1046           
1047                       if (!filter->role)
1048                           RETURN(-1);
1049                   }
1050                   else if (strcmp(e.data, "b:ResultClassName") == 0)
1051                   {
1052                       filter->resultClassName = _ExpectCharsAndEnd(
1053                           xml, 
1054                           "b:ResultClassName");
1055           
1056                       if (!filter->resultClassName)
1057                           RETURN(-1);
1058 mike  1.1         }
1059                   else if (strcmp(e.data, "b:ResultRole") == 0)
1060                   {
1061                       filter->resultRole = _ExpectCharsAndEnd(
1062                           xml, 
1063                           "b:ResultRole");
1064           
1065                       if (!filter->resultRole)
1066                           RETURN(-1);
1067                   }
1068                   else
1069                   {
1070                       if (XML_Skip(xml) != 0)
1071                           RETURN(-1);
1072                   }
1073               }
1074           
1075           #if 0
1076               printf("AssociationFilter\n");
1077               printf("{\n");
1078               Instance_Print(filter->referenceParameters, stdout, 1, MI_TRUE);
1079 mike  1.1     printf("    nameSpace{%s}\n", filter->referenceParameters->nameSpace);
1080               printf("    address{%s}\n", filter->address);
1081               printf("    associationClassName{%s}\n", filter->associationClassName);
1082               printf("    resultClassName{%s}\n", filter->resultClassName);
1083               printf("    role{%s}\n", filter->role);
1084               printf("    resultRole{%s}\n", filter->resultRole);
1085               printf("}\n");
1086           #endif
1087           
1088               /* Expect </AssociatedInstances> */
1089           
1090               if (XML_Expect(xml, &e, XML_END, "b:AssociatedInstances") != 0)
1091                   RETURN(-1);
1092           
1093               return 0;
1094           }
1095           
1096           int WS_ParseEnumerateBody(
1097               XML* xml, 
1098               Batch** batch,
1099               WSMAN_WSEnumeratePullBody* wsenumbody)
1100 mike  1.1 {
1101               XML_Elem e;
1102           
1103               memset(wsenumbody, 0, sizeof(WSMAN_WSEnumeratePullBody));
1104           
1105               /* Allocate batch (owned by WSMAN_ConnectionData object */
1106           
1107               if (*batch == NULL)
1108               {
1109                   *batch = Batch_New(BATCH_MAX_PAGES);
1110           
1111                   if (!*batch)
1112                       RETURN(-1);
1113               }
1114           
1115               /* Expect <s:Body> */
1116               if (XML_Expect(xml, &e, XML_START, "s:Body") != 0)
1117                   RETURN(-1);
1118           
1119               /* Expect <n:Enumerate> */
1120               if (XML_Expect(xml, &e, XML_START, "n:Enumerate") != 0)
1121 mike  1.1         RETURN(-1);
1122           
1123               for (;;)
1124               {
1125                   if (XML_Next(xml, &e) != 0)
1126                       RETURN(-1);
1127           
1128                   if (e.type == XML_END)
1129                   {
1130                       int tag = HashStr(e.data, e.size);
1131           
1132                       if (WSMANTAG_ENUM_ENUMERATE != tag)
1133                       {
1134                           LOGW_CHAR(("wsman: unexpected close tag [%s] in incoming xml", e.data ));
1135                           RETURN(-1);
1136                       }
1137                       break;
1138                   }
1139           
1140                   /* skip possible comments */
1141                   if (e.type != XML_START)
1142 mike  1.1             continue;
1143           
1144                   switch (HashStr(e.data, e.size))
1145                   {
1146                   case WSMANTAG_ENUM_MAX_ELEMENTS:
1147                       {
1148                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
1149                               RETURN(-1);
1150           
1151                           wsenumbody->maxElements = (MI_Uint32)Strtoull(e.data, NULL, 10);
1152                           PRINTF(("maxElements{%d}\n", wsenumbody->maxElements));
1153           
1154                           if (XML_Expect(xml, &e, XML_END, "w:MaxElements") != 0)
1155                               RETURN(-1);
1156                       }
1157                       break;
1158           
1159                   case WSMANTAG_ENUM_OPTIMIZE_ENUMERATION:
1160                       {
1161                           wsenumbody->allowOptimization = MI_TRUE;
1162           
1163 mike  1.1                 if (XML_Skip(xml) != 0)
1164                               RETURN(-1);
1165                       }
1166                       break;
1167           
1168                   case WSMANTAG_ENUM_POLYMORPHISM_MODE:
1169                       {
1170                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
1171                               RETURN(-1);
1172           
1173                           wsenumbody->polymorphismMode = HashStr(e.data, e.size);
1174           
1175                           if (XML_Expect(xml, &e, XML_END, "b:PolymorphismMode") != 0)
1176                               RETURN(-1);
1177                       }
1178                       break;
1179           
1180                   case WSMANTAG_ENUM_MODE:
1181                       {
1182                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
1183                               RETURN(-1);
1184 mike  1.1 
1185                           wsenumbody->enumerationMode = HashStr(e.data, e.size);
1186           
1187                           if (XML_Expect(xml, &e, XML_END, "w:EnumerationMode") != 0)
1188                               RETURN(-1);
1189                       }
1190                       break;
1191           
1192                   /* 
1193                    * Examples:
1194                    *   <w:Filter Dialect="http://microsoft.com/wbem/wsman/1/WQL">
1195                    *     SELECT Weight FROM Widget WHERE Key = 1001
1196                    *   </w:Filter>
1197                    *
1198                    *   <w:Filter Dialect="http://microsoft.com/wbem/wsman/1/WQL">
1199                    *     <b:AssociatedInstances>
1200                    *       ...
1201                    *     </b:AssociatedInstances>
1202                    *   </w:Filter>
1203                    */
1204                   case WSMANTAG_ENUM_FILTER:
1205 mike  1.1             {
1206                           const char* dialect;
1207                           const char* p;
1208           
1209                           /* Get 'Dialect' attribute? */
1210                           dialect = XML_Elem_GetAttr(&e, "Dialect");
1211                           if (!dialect)
1212                           {
1213                               LOGW_CHAR(("wsman: Filter tag missing Dialect attribute"));
1214                               RETURN(-1);
1215                           }
1216           
1217           
1218                           /* Reduce long dialect name to final component of path */
1219                           p = strrchr(dialect, '/');
1220                           if (p)
1221                               wsenumbody->dialect = p + 1;
1222                           else
1223                               wsenumbody->dialect = dialect;
1224           
1225                           /* Parse the association filter */
1226 mike  1.1                 if (strcmp(dialect, URI_CIMBINDING "/associationFilter") == 0)
1227                           {
1228                               wsenumbody->foundAssociationFilter = MI_TRUE;
1229           
1230                               if (_ParseAssociationFilter(xml, *batch,
1231                                   &wsenumbody->associationFilter) != 0)
1232                               {
1233                                   RETURN(-1);
1234                               }
1235                           }
1236                           else
1237                           {
1238                               /* Get the filter text */
1239                               if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
1240                                   RETURN(-1);
1241           
1242                               wsenumbody->filter = e.data;
1243                           }
1244           
1245                           /* Check for closing </w:Filter> tag */
1246                           if (XML_Expect(xml, &e, XML_END, "w:Filter") != 0)
1247 mike  1.1                     RETURN(-1);
1248                       }
1249                       break;
1250           
1251                   default:
1252                       {
1253                           if (_MustUnderstandCanBeIgnored(&e) != 0)
1254                           {
1255                               LOGW_CHAR(("wsman: unknown mandatory tag [%s]; aborted", e.data ));
1256                               RETURN(-1);
1257                           }
1258           
1259                           if (XML_Skip(xml) != 0)
1260                               RETURN(-1);
1261                       }
1262                       break;
1263           
1264                   }
1265               }
1266           
1267               /* Expect <s:Body> */
1268 mike  1.1     if (XML_Expect(xml, &e, XML_END, "s:Body") != 0)
1269                   RETURN(-1);
1270           
1271               /* Expect </s:Envelope> */
1272               if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0)
1273                   RETURN(-1);
1274           
1275               return 0;
1276           }
1277           
1278           int WS_ParseInvokeBody(
1279               XML* xml, 
1280               Batch*  dynamicBatch,
1281               MI_Instance** dynamicInstanceParams)
1282           {
1283               XML_Elem e;
1284           
1285               *dynamicInstanceParams = 0;
1286           
1287               /* Expect <s:Body> */
1288               if (XML_Expect(xml, &e, XML_START, "s:Body") != 0)
1289 mike  1.1         RETURN(-1);
1290           
1291               /* Expect <?:?> parameter's tag */
1292               for (;;)
1293               {
1294                   if (XML_Next(xml, &e) != 0)
1295                       RETURN(-1);
1296           
1297                   /* empty body? can be valid for methods without parameters */
1298                   if (e.type == XML_END)
1299                       return 0;
1300           
1301                   if (e.type == XML_START)
1302                       break;
1303               }
1304           
1305               if (0 != _GetInstance(xml, &e, dynamicBatch, dynamicInstanceParams))
1306                   RETURN(-1);
1307           
1308           
1309               /* Expect <s:Body> */
1310 mike  1.1     if (XML_Expect(xml, &e, XML_END, "s:Body") != 0)
1311                   RETURN(-1);
1312           
1313               /* Expect </s:Envelope> */
1314               if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0)
1315                   RETURN(-1);
1316           
1317               return 0;
1318           }
1319           
1320           int WS_ParseCreateBody(
1321               XML* xml, 
1322               Batch*  dynamicBatch,
1323               MI_Instance** dynamicInstanceParams)
1324           {
1325               XML_Elem e;
1326           
1327               /* Expect <s:Body> */
1328               if (XML_Expect(xml, &e, XML_START, "s:Body") != 0)
1329                   RETURN(-1);
1330           
1331 mike  1.1     /* Expect <?:?> parameter's tag */
1332               if (XML_Next(xml, &e) != 0)
1333                   RETURN(-1);
1334           
1335               if (0 != _GetInstance(xml, &e, dynamicBatch, dynamicInstanceParams))
1336                   RETURN(-1);
1337           
1338               /* Expect <s:Body> */
1339               if (XML_Expect(xml, &e, XML_END, "s:Body") != 0)
1340                   RETURN(-1);
1341           
1342               /* Expect </s:Envelope> */
1343               if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0)
1344                   RETURN(-1);
1345           
1346               return 0;
1347           }
1348           
1349           int WS_ParsePullBody(
1350               XML* xml, 
1351               WSMAN_WSEnumeratePullBody* wsenumpullbody)
1352 mike  1.1 {
1353               XML_Elem e;
1354           
1355               memset(wsenumpullbody, 0, sizeof(WSMAN_WSEnumeratePullBody));
1356           
1357               /* Expect <s:Body> */
1358               if (XML_Expect(xml, &e, XML_START, "s:Body") != 0)
1359                   RETURN(-1);
1360           
1361               /* Expect <n:Enumerate> */
1362               if (XML_Expect(xml, &e, XML_START, "n:Pull") != 0)
1363                   RETURN(-1);
1364           
1365               for (;;)
1366               {
1367                   if (XML_Next(xml, &e) != 0)
1368                       RETURN(-1);
1369           
1370                   if (e.type == XML_END)
1371                   {
1372                       int tag = HashStr(e.data, e.size);
1373 mike  1.1 
1374                       if (WSMANTAG_ENUM_PULL != tag)
1375                       {
1376                           LOGW_CHAR(("wsman: unexpected close tag [%s] in incoming xml", e.data ));
1377                           RETURN(-1);
1378                       }
1379                       break;
1380                   }
1381           
1382                   /* skip possible comments */
1383                   if (e.type != XML_START)
1384                       continue;
1385           
1386                   switch (HashStr(e.data, e.size))
1387                   {
1388                   case WSMANTAG_PULL_MAX_ELEMENTS:
1389                       {
1390                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
1391                               RETURN(-1);
1392           
1393                           wsenumpullbody->maxElements = (MI_Uint32)Strtoull(e.data, NULL, 10);
1394 mike  1.1                 PRINTF(("maxElements{%d}\n", wsenumpullbody->maxElements));
1395           
1396                           if (XML_Expect(xml, &e, XML_END, "n:MaxElements") != 0)
1397                               RETURN(-1);
1398                       }
1399                       break;
1400           
1401                   case WSMANTAG_PULL_ENUMERATION_CONTEXT:
1402                       {
1403                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
1404                               RETURN(-1);
1405           
1406                           wsenumpullbody->enumerationContextID = (MI_Uint32)Strtoull(e.data, NULL, 10);
1407           
1408                           if (XML_Expect(xml, &e, XML_END, "n:EnumerationContext") != 0)
1409                               RETURN(-1);
1410                       }
1411                       break;
1412           
1413                   default:
1414                       {
1415 mike  1.1                 if (_MustUnderstandCanBeIgnored(&e) != 0)
1416                           {
1417                               LOGW_CHAR(("wsman: unknown mandatory tag [%s]; aborted", e.data ));
1418                               RETURN(-1);
1419                           }
1420           
1421                           if (XML_Skip(xml) != 0)
1422                               RETURN(-1);
1423                       }
1424                       break;
1425           
1426                   }
1427               }
1428           
1429               /* Expect <s:Body> */
1430               if (XML_Expect(xml, &e, XML_END, "s:Body") != 0)
1431                   RETURN(-1);
1432           
1433               /* Expect </s:Envelope> */
1434               if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0)
1435                   RETURN(-1);
1436 mike  1.1 
1437               return 0;
1438           }
1439           
1440           int WS_ParseReleaseBody(
1441               XML* xml, 
1442               WSMAN_WSEnumeratePullBody* wsenumpullbody)
1443           {
1444               XML_Elem e;
1445           
1446               memset(wsenumpullbody, 0, sizeof(WSMAN_WSEnumeratePullBody));
1447           
1448               /* Expect <s:Body> */
1449               if (XML_Expect(xml, &e, XML_START, "s:Body") != 0)
1450                   RETURN(-1);
1451           
1452               /* Expect <n:Release> */
1453               if (XML_Expect(xml, &e, XML_START, "n:Release") != 0)
1454                   RETURN(-1);
1455           
1456               for (;;)
1457 mike  1.1     {
1458                   if (XML_Next(xml, &e) != 0)
1459                       RETURN(-1);
1460           
1461                   if (e.type == XML_END)
1462                   {
1463                       int tag = HashStr(e.data, e.size);
1464           
1465                       if (WSMANTAG_ENUM_RELEASE != tag)
1466                       {
1467                           LOGW_CHAR(("wsman: unexpected close tag [%s] in incoming xml", e.data ));
1468                           RETURN(-1);
1469                       }
1470                       break;
1471                   }
1472           
1473                   /* skip possible comments */
1474                   if (e.type != XML_START)
1475                       continue;
1476           
1477                   switch (HashStr(e.data, e.size))
1478 mike  1.1         {
1479                   case WSMANTAG_PULL_ENUMERATION_CONTEXT:
1480                       {
1481                           if (XML_Expect(xml, &e, XML_CHARS, NULL) != 0)
1482                               RETURN(-1);
1483           
1484                           wsenumpullbody->enumerationContextID = (MI_Uint32)Strtoull(e.data, NULL, 10);
1485           
1486                           if (XML_Expect(xml, &e, XML_END, "n:EnumerationContext") != 0)
1487                               RETURN(-1);
1488                       }
1489                       break;
1490           
1491                   default:
1492                       {
1493                           if (_MustUnderstandCanBeIgnored(&e) != 0)
1494                           {
1495                               LOGW_CHAR(("wsman: unknown mandatory tag [%s]; aborted", e.data ));
1496                               RETURN(-1);
1497                           }
1498           
1499 mike  1.1                 if (XML_Skip(xml) != 0)
1500                               RETURN(-1);
1501                       }
1502                       break;
1503           
1504                   }
1505               }
1506           
1507               /* Expect <s:Body> */
1508               if (XML_Expect(xml, &e, XML_END, "s:Body") != 0)
1509                   RETURN(-1);
1510           
1511               /* Expect </s:Envelope> */
1512               if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0)
1513                   RETURN(-1);
1514           
1515               return 0;
1516           }
1517           
1518           int WS_ParseIdentifyBody(
1519               XML* xml)
1520 mike  1.1 {
1521               XML_Elem e;
1522           
1523               if (XML_Expect(xml, &e, XML_START, "s:Body") != 0)
1524                   RETURN(-1);
1525           
1526               if (XML_Expect(xml, &e, XML_START, "i:Identify") != 0)
1527                   RETURN(-1);
1528           
1529               if (XML_Expect(xml, &e, XML_END, "i:Identify") != 0)
1530                   RETURN(-1);
1531           
1532               if (XML_Expect(xml, &e, XML_END, "s:Body") != 0)
1533                   RETURN(-1);
1534           
1535               if (XML_Expect(xml, &e, XML_END, "s:Envelope") != 0)
1536                   RETURN(-1);
1537           
1538               return 0;
1539           }

ViewCVS 0.9.2