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