1 /*
2 * esx_vi_types.c: client for the VMware VI API 2.5 to manage ESX hosts
3 *
4 * Copyright (C) 2010, 2014 Red Hat, Inc.
5 * Copyright (C) 2009-2011 Matthias Bolte <matthias.bolte@googlemail.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library. If not, see
19 * <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #include <config.h>
24
25 #include <libxml/parser.h>
26 #include <libxml/xpathInternals.h>
27
28 #include "virbuffer.h"
29 #include "datatypes.h"
30 #include "viralloc.h"
31 #include "virlog.h"
32 #include "esx_vi.h"
33 #include "esx_vi_types.h"
34 #include "virstring.h"
35 #include "virxml.h"
36
37 #define VIR_FROM_THIS VIR_FROM_ESX
38
39 VIR_LOG_INIT("esx.esx_vi_types");
40
41 #define ESX_VI__TEMPLATE__ALLOC(__type) \
42 int \
43 esxVI_##__type##_Alloc(esxVI_##__type **ptrptr) \
44 { \
45 ESX_VI_CHECK_ARG_LIST(ptrptr); \
46 \
47 *ptrptr = g_new0(esxVI_##__type, 1); \
48 \
49 (*ptrptr)->_type = esxVI_Type_##__type; \
50 \
51 return 0; \
52 }
53
54
55
56 #define ESX_VI__TEMPLATE__FREE(_type, _body) \
57 void \
58 esxVI_##_type##_Free(esxVI_##_type **ptrptr) \
59 { \
60 esxVI_##_type *item G_GNUC_UNUSED; \
61 \
62 if (!ptrptr || !(*ptrptr)) { \
63 return; \
64 } \
65 \
66 item = *ptrptr; \
67 \
68 _body \
69 \
70 g_clear_pointer(ptrptr, g_free); \
71 }
72
73
74
75 #define ESX_VI__TEMPLATE__VALIDATE(__type, _require) \
76 int \
77 esxVI_##__type##_Validate(esxVI_##__type *item) \
78 { \
79 const char *typeName = esxVI_Type_ToString(esxVI_Type_##__type); \
80 \
81 if (item->_type <= esxVI_Type_Undefined || \
82 item->_type >= esxVI_Type_Other) { \
83 virReportError(VIR_ERR_INTERNAL_ERROR, \
84 _("%s object has invalid dynamic type"), typeName);\
85 return -1; \
86 } \
87 \
88 _require \
89 \
90 return 0; \
91 }
92
93
94
95 #define ESX_VI__TEMPLATE__DEEP_COPY(_type, _deep_copy) \
96 int \
97 esxVI_##_type##_DeepCopy(esxVI_##_type **dest, esxVI_##_type *src) \
98 { \
99 ESX_VI_CHECK_ARG_LIST(dest); \
100 \
101 if (!src) { \
102 return 0; \
103 } \
104 \
105 if (esxVI_##_type##_Alloc(dest) < 0) { \
106 goto failure; \
107 } \
108 \
109 _deep_copy \
110 \
111 return 0; \
112 \
113 failure: \
114 esxVI_##_type##_Free(dest); \
115 \
116 return -1; \
117 }
118
119
120
121 #define ESX_VI__TEMPLATE__LIST__APPEND(_type) \
122 int \
123 esxVI_##_type##_AppendToList(esxVI_##_type **list, esxVI_##_type *item) \
124 { \
125 return esxVI_List_Append((esxVI_List **)list, (esxVI_List *)item); \
126 }
127
128
129
130 #define ESX_VI__TEMPLATE__LIST__DEEP_COPY(_type) \
131 int \
132 esxVI_##_type##_DeepCopyList(esxVI_##_type **destList, \
133 esxVI_##_type *srcList) \
134 { \
135 return esxVI_List_DeepCopy \
136 ((esxVI_List **)destList, (esxVI_List *)srcList, \
137 (esxVI_List_DeepCopyFunc)esxVI_##_type##_DeepCopy, \
138 (esxVI_List_FreeFunc)esxVI_##_type##_Free); \
139 }
140
141
142
143 #define ESX_VI__TEMPLATE__LIST__CAST_FROM_ANY_TYPE(_type) \
144 int \
145 esxVI_##_type##_CastListFromAnyType(esxVI_AnyType *anyType, \
146 esxVI_##_type **list) \
147 { \
148 return esxVI_List_CastFromAnyType \
149 (anyType, (esxVI_List **)list, \
150 (esxVI_List_CastFromAnyTypeFunc) \
151 esxVI_##_type##_CastFromAnyType, \
152 (esxVI_List_FreeFunc)esxVI_##_type##_Free); \
153 }
154
155
156
157 #define ESX_VI__TEMPLATE__LIST__SERIALIZE(_type) \
158 int \
159 esxVI_##_type##_SerializeList(esxVI_##_type *list, const char *element, \
160 virBuffer *output) \
161 { \
162 return esxVI_List_Serialize((esxVI_List *)list, element, output, \
163 (esxVI_List_SerializeFunc) \
164 esxVI_##_type##_Serialize); \
165 }
166
167
168
169 #define ESX_VI__TEMPLATE__LIST__DESERIALIZE(_type) \
170 int \
171 esxVI_##_type##_DeserializeList(xmlNodePtr node, esxVI_##_type **list) \
172 { \
173 return esxVI_List_Deserialize \
174 (node, (esxVI_List **)list, \
175 (esxVI_List_DeserializeFunc)esxVI_##_type##_Deserialize, \
176 (esxVI_List_FreeFunc)esxVI_##_type##_Free); \
177 }
178
179
180
181 #define ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE_EXTRA(_type, _dest_type, _extra, \
182 _dest_extra) \
183 int \
184 esxVI_##_type##_Cast##_dest_extra##FromAnyType(esxVI_AnyType *anyType, \
185 _dest_type **ptrptr) \
186 { \
187 _dest_type *item G_GNUC_UNUSED; \
188 \
189 if (!anyType || !ptrptr || *ptrptr) { \
190 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", \
191 _("Invalid argument")); \
192 return -1; \
193 } \
194 \
195 item = *ptrptr; \
196 \
197 _extra \
198 \
199 return esxVI_##_type##_Deserialize##_dest_extra(anyType->node, \
200 ptrptr); \
201 }
202
203
204
205 #define ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE(_type) \
206 ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE_EXTRA(_type, esxVI_##_type, \
207 { \
208 if (anyType->type != esxVI_Type_##_type) { \
209 virReportError(VIR_ERR_INTERNAL_ERROR, \
210 _("Call to %s for unexpected type '%s', " \
211 "expected '%s'"), \
212 __FUNCTION__, anyType->other, \
213 esxVI_Type_ToString(esxVI_Type_##_type)); \
214 return -1; \
215 } \
216 }, /* nothing */)
217
218
219
220 #define ESX_VI__TEMPLATE__CAST_VALUE_FROM_ANY_TYPE(_type, _value_type) \
221 ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE_EXTRA(_type, _value_type, \
222 { \
223 if (anyType->type != esxVI_Type_##_type) { \
224 virReportError(VIR_ERR_INTERNAL_ERROR, \
225 _("Call to %s for unexpected type '%s', " \
226 "expected '%s'"), \
227 __FUNCTION__, anyType->other, \
228 esxVI_Type_ToString(esxVI_Type_##_type)); \
229 return -1; \
230 } \
231 }, Value)
232
233
234
235 #define ESX_VI__TEMPLATE__SERIALIZE_EXTRA(_type, _extra, _serialize) \
236 int \
237 esxVI_##_type##_Serialize(esxVI_##_type *item, \
238 const char *element, virBuffer *output) \
239 { \
240 if (!element || !output) { \
241 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", \
242 _("Invalid argument")); \
243 return -1; \
244 } \
245 \
246 if (!item) { \
247 return 0; \
248 } \
249 \
250 _extra \
251 \
252 if (esxVI_##_type##_Validate(item) < 0) { \
253 return -1; \
254 } \
255 \
256 ESV_VI__XML_TAG__OPEN(output, element, \
257 esxVI_Type_ToString(esxVI_Type_##_type)); \
258 \
259 _serialize \
260 \
261 ESV_VI__XML_TAG__CLOSE(output, element); \
262 \
263 return 0; \
264 }
265
266
267
268 #define ESX_VI__TEMPLATE__SERIALIZE(_type, _serialize) \
269 ESX_VI__TEMPLATE__SERIALIZE_EXTRA(_type, /* nothing */, _serialize)
270
271
272
273 #define ESX_VI__TEMPLATE__DESERIALIZE_EXTRA(_type, _extra1, _extra2, \
274 _deserialize) \
275 int \
276 esxVI_##_type##_Deserialize(xmlNodePtr node, esxVI_##_type **ptrptr) \
277 { \
278 xmlNodePtr childNode = NULL; \
279 \
280 _extra1 \
281 \
282 if (!ptrptr || *ptrptr) { \
283 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", \
284 _("Invalid argument")); \
285 return -1; \
286 } \
287 \
288 if (esxVI_##_type##_Alloc(ptrptr) < 0) { \
289 return -1; \
290 } \
291 \
292 _extra2 \
293 \
294 for (childNode = node->children; childNode; \
295 childNode = childNode->next) { \
296 if (childNode->type != XML_ELEMENT_NODE) { \
297 virReportError(VIR_ERR_INTERNAL_ERROR, \
298 _("Wrong XML element type %d"), \
299 childNode->type); \
300 goto failure; \
301 } \
302 \
303 _deserialize \
304 \
305 VIR_WARN("Unexpected '%s' property", childNode->name); \
306 } \
307 \
308 if (esxVI_##_type##_Validate(*ptrptr) < 0) { \
309 goto failure; \
310 } \
311 \
312 return 0; \
313 \
314 failure: \
315 esxVI_##_type##_Free(ptrptr); \
316 \
317 return -1; \
318 }
319
320
321
322 #define ESX_VI__TEMPLATE__DESERIALIZE(_type, _deserialize) \
323 ESX_VI__TEMPLATE__DESERIALIZE_EXTRA(_type, /* nothing */, /* nothing */, \
324 _deserialize)
325
326
327
328 #define ESX_VI__TEMPLATE__DESERIALIZE_NUMBER(_type, _xsdType, _min, _max) \
329 int \
330 esxVI_##_type##_Deserialize(xmlNodePtr node, esxVI_##_type **number) \
331 { \
332 int result = -1; \
333 g_autofree char *string = NULL; \
334 long long value; \
335 \
336 if (!number || *number) { \
337 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", \
338 _("Invalid argument")); \
339 return -1; \
340 } \
341 \
342 if (esxVI_##_type##_Alloc(number) < 0) { \
343 return -1; \
344 } \
345 \
346 string = (char *)xmlNodeListGetString(node->doc, node->children, 1); \
347 \
348 if (!string) { \
349 virReportError(VIR_ERR_INTERNAL_ERROR, \
350 _("XML node doesn't contain text, expecting an %s "\
351 "value"), _xsdType); \
352 goto cleanup; \
353 } \
354 \
355 if (virStrToLong_ll(string, NULL, 10, &value) < 0) { \
356 virReportError(VIR_ERR_INTERNAL_ERROR, \
357 _("Unknown value '%s' for %s"), string, _xsdType); \
358 goto cleanup; \
359 } \
360 \
361 if (((_min) != INT64_MIN && value < (_min)) \
362 || ((_max) != INT64_MAX && value > (_max))) { \
363 virReportError(VIR_ERR_INTERNAL_ERROR, \
364 _("Value '%s' is not representable as %s"), \
365 string, _xsdType); \
366 goto cleanup; \
367 } \
368 \
369 (*number)->value = value; \
370 \
371 result = 0; \
372 \
373 cleanup: \
374 if (result < 0) { \
375 esxVI_##_type##_Free(number); \
376 } \
377 \
378 return result; \
379 }
380
381
382
383 /*
384 * Macros for property handling to be used as part of other macros
385 */
386
387 #define ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY(_type, _name) \
388 if (esxVI_##_type##_DeepCopy(&(*dest)->_name, src->_name) < 0) { \
389 goto failure; \
390 }
391
392
393
394 #define ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_LIST(_type, _name) \
395 if (esxVI_##_type##_DeepCopyList(&(*dest)->_name, src->_name) < 0) { \
396 goto failure; \
397 }
398
399
400
401 #define ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_VALUE(_type, _name) \
402 if (esxVI_##_type##_DeepCopyValue(&(*dest)->_name, src->_name) < 0) { \
403 goto failure; \
404 }
405
406
407
408 #define ESX_VI__TEMPLATE__PROPERTY__SERIALIZE(_type, _name) \
409 if (esxVI_##_type##_Serialize(item->_name, #_name, output) < 0) { \
410 return -1; \
411 }
412
413
414
415 #define ESX_VI__TEMPLATE__PROPERTY__SERIALIZE_VALUE(_type, _name) \
416 if (esxVI_##_type##_SerializeValue(item->_name, #_name, output) < 0) { \
417 return -1; \
418 }
419
420
421
422 #define ESX_VI__TEMPLATE__PROPERTY__SERIALIZE_LIST(_type, _name) \
423 if (esxVI_##_type##_SerializeList(item->_name, #_name, output) < 0) { \
424 return -1; \
425 }
426
427
428
429 #define ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(_type, _name) \
430 if (virXMLNodeNameEqual(childNode, #_name)) { \
431 if (esxVI_##_type##_Deserialize(childNode, &(*ptrptr)->_name) < 0) { \
432 goto failure; \
433 } \
434 \
435 continue; \
436 }
437
438
439
440 #define ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_IGNORE(_name) \
441 if (virXMLNodeNameEqual(childNode, #_name)) { \
442 continue; \
443 }
444
445
446
447 #define ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(_type, _name) \
448 if (virXMLNodeNameEqual(childNode, #_name)) { \
449 if (esxVI_##_type##_DeserializeValue(childNode, \
450 &(*ptrptr)->_name) < 0) { \
451 goto failure; \
452 } \
453 \
454 continue; \
455 }
456
457
458
459 #define ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_LIST(_type, _name) \
460 if (virXMLNodeNameEqual(childNode, #_name)) { \
461 esxVI_##_type *_name##Item = NULL; \
462 \
463 if (esxVI_##_type##_Deserialize(childNode, &_name##Item) < 0) { \
464 goto failure; \
465 } \
466 \
467 if (esxVI_##_type##_AppendToList(&(*ptrptr)->_name, \
468 _name##Item) < 0) { \
469 esxVI_##_type##_Free(&_name##Item); \
470 goto failure; \
471 } \
472 \
473 continue; \
474 }
475
476
477
478 /*
479 * A required property must be != 0 (NULL for pointers, "undefined" == 0 for
480 * enumeration values).
481 *
482 * To be used as part of ESX_VI__TEMPLATE__VALIDATE.
483 */
484 #define ESX_VI__TEMPLATE__PROPERTY__REQUIRE(_name) \
485 if (item->_name == 0) { \
486 virReportError(VIR_ERR_INTERNAL_ERROR, \
487 _("%s object is missing the required '%s' property"), \
488 typeName, #_name); \
489 return -1; \
490 }
491
492
493
494 /*
495 * Macros to implement enumerations
496 */
497
498 #define ESX_VI__TEMPLATE__ENUMERATION__CAST_FROM_ANY_TYPE(_type) \
499 int \
500 esxVI_##_type##_CastFromAnyType(esxVI_AnyType *anyType, \
501 esxVI_##_type *value) \
502 { \
503 return esxVI_Enumeration_CastFromAnyType \
504 (&_esxVI_##_type##_Enumeration, anyType, (int *)value); \
505 }
506
507
508
509 #define ESX_VI__TEMPLATE__ENUMERATION__SERIALIZE(_type) \
510 int \
511 esxVI_##_type##_Serialize(esxVI_##_type value, const char *element, \
512 virBuffer *output) \
513 { \
514 return esxVI_Enumeration_Serialize(&_esxVI_##_type##_Enumeration, \
515 value, element, output); \
516 }
517
518
519
520 #define ESX_VI__TEMPLATE__ENUMERATION__DESERIALIZE(_type) \
521 int \
522 esxVI_##_type##_Deserialize(xmlNodePtr node, esxVI_##_type *value) \
523 { \
524 return esxVI_Enumeration_Deserialize(&_esxVI_##_type##_Enumeration, \
525 node, (int *)value); \
526 }
527
528
529
530 /*
531 * Macros to implement dynamic dispatched functions
532 */
533
534 #define ESX_VI__TEMPLATE__DISPATCH(_actual_type, _actual_type_name, __type, \
535 _dispatch, _error_return) \
536 switch ((int)_actual_type) { \
537 _dispatch \
538 \
539 case esxVI_Type_##__type: \
540 break; \
541 \
542 default: \
543 virReportError(VIR_ERR_INTERNAL_ERROR, \
544 _("Call to %s for unexpected type '%s'"), \
545 __FUNCTION__, _actual_type_name); \
546 return _error_return; \
547 }
548
549
550
551 #define ESX_VI__TEMPLATE__DISPATCH__FREE(_type) \
552 case esxVI_Type_##_type: \
553 esxVI_##_type##_Free((esxVI_##_type **)ptrptr); \
554 return;
555
556
557
558 #define ESX_VI__TEMPLATE__DISPATCH__DEEP_COPY(_type) \
559 case esxVI_Type_##_type: \
560 return esxVI_##_type##_DeepCopy((esxVI_##_type **)dest, \
561 (esxVI_##_type *)src);
562
563
564
565 #define ESX_VI__TEMPLATE__DISPATCH__CAST_FROM_ANY_TYPE(_type) \
566 case esxVI_Type_##_type: \
567 return esxVI_##_type##_Deserialize(anyType->node, \
568 (esxVI_##_type **)ptrptr);
569
570
571
572 #define ESX_VI__TEMPLATE__DISPATCH__SERIALIZE(_type) \
573 case esxVI_Type_##_type: \
574 return esxVI_##_type##_Serialize((esxVI_##_type *)item, element, \
575 output);
576
577
578
579 #define ESX_VI__TEMPLATE__DISPATCH__DESERIALIZE(_type) \
580 case esxVI_Type_##_type: \
581 return esxVI_##_type##_Deserialize(node, (esxVI_##_type **)ptrptr);
582
583
584
585 #define ESX_VI__TEMPLATE__DYNAMIC_FREE(__type, _dispatch, _body) \
586 ESX_VI__TEMPLATE__FREE(__type, \
587 ESX_VI__TEMPLATE__DISPATCH(item->_type, \
588 esxVI_Type_ToString(item->_type), \
589 __type, _dispatch, \
590 /* nothing */) \
591 _body)
592
593
594
595 #define ESX_VI__TEMPLATE__DYNAMIC_CAST__ACCEPT(__type) \
596 if (((esxVI_Object *)item)->_type == esxVI_Type_##__type) { \
597 return item; \
598 }
599
600
601
602 #define ESX_VI__TEMPLATE__DYNAMIC_CAST(__type, _accept) \
603 esxVI_##__type * \
604 esxVI_##__type##_DynamicCast(void *item) \
605 { \
606 if (!item) { \
607 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", \
608 _("Invalid argument")); \
609 return NULL; \
610 } \
611 \
612 ESX_VI__TEMPLATE__DYNAMIC_CAST__ACCEPT(__type) \
613 \
614 _accept \
615 \
616 return NULL; \
617 }
618
619
620
621 #define ESX_VI__TEMPLATE__DYNAMIC_DEEP_COPY(__type, _dispatch, _deep_copy) \
622 int \
623 esxVI_##__type##_DeepCopy(esxVI_##__type **dest, esxVI_##__type *src) \
624 { \
625 if (!dest || *dest) { \
626 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", \
627 _("Invalid argument")); \
628 return -1; \
629 } \
630 \
631 if (!src) { \
632 return 0; \
633 } \
634 \
635 ESX_VI__TEMPLATE__DISPATCH(src->_type, \
636 esxVI_Type_ToString(src->_type), \
637 __type, _dispatch, -1) \
638 \
639 if (esxVI_##__type##_Alloc(dest) < 0) { \
640 goto failure; \
641 } \
642 \
643 _deep_copy \
644 \
645 return 0; \
646 \
647 failure: \
648 esxVI_##__type##_Free(dest); \
649 \
650 return -1; \
651 }
652
653
654
655 #define ESX_VI__TEMPLATE__DYNAMIC_CAST_FROM_ANY_TYPE(__type, _dispatch) \
656 ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE_EXTRA(__type, esxVI_##__type, \
657 ESX_VI__TEMPLATE__DISPATCH(anyType->type, \
658 esxVI_AnyType_TypeToString(anyType), \
659 __type, _dispatch, -1), \
660 /* nothing */)
661
662
663
664 #define ESX_VI__TEMPLATE__DYNAMIC_SERIALIZE(__type, _dispatch, _serialize) \
665 ESX_VI__TEMPLATE__SERIALIZE_EXTRA(__type, \
666 ESX_VI__TEMPLATE__DISPATCH(item->_type, \
667 esxVI_Type_ToString(item->_type), \
668 __type, _dispatch, -1), \
669 _serialize)
670
671
672
673 #define ESX_VI__TEMPLATE__DYNAMIC_DESERIALIZE(__type, _dispatch, \
674 _deserialize) \
675 ESX_VI__TEMPLATE__DESERIALIZE_EXTRA(__type, \
676 esxVI_Type type = esxVI_Type_Undefined; \
677 \
678 if (esxVI_GetActualObjectType(node, esxVI_Type_##__type, &type) < 0) { \
679 return -1; \
680 } \
681 \
682 switch ((int)type) { \
683 _dispatch \
684 \
685 case esxVI_Type_##__type: \
686 break; \
687 \
688 default: \
689 virReportError(VIR_ERR_INTERNAL_ERROR, \
690 _("Call to %s for unexpected type '%s'"), \
691 __FUNCTION__, esxVI_Type_ToString(type)); \
692 return -1; \
693 }, \
694 /* nothing */, \
695 _deserialize)
696
697
698
699 static int
esxVI_GetActualObjectType(xmlNodePtr node,esxVI_Type baseType,esxVI_Type * actualType)700 esxVI_GetActualObjectType(xmlNodePtr node, esxVI_Type baseType,
701 esxVI_Type *actualType)
702 {
703 g_autofree char *type = NULL;
704
705 if (!actualType || *actualType != esxVI_Type_Undefined) {
706 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
707 return -1;
708 }
709
710 type = (char *)xmlGetNsProp
711 (node, BAD_CAST "type",
712 BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
713
714 if (!type) {
715 /* no actual type specified, use base type instead */
716 *actualType = baseType;
717 return 0;
718 }
719
720 *actualType = esxVI_Type_FromString(type);
721
722 if (*actualType == esxVI_Type_Undefined || *actualType == esxVI_Type_Other) {
723 virReportError(VIR_ERR_INTERNAL_ERROR,
724 _("Unknown value '%s' for %s 'type' property"),
725 type, esxVI_Type_ToString(baseType));
726 return -1;
727 }
728
729 return 0;
730 }
731
732
733
734 /*
735 * Macros to implement managed objects
736 */
737
738 #define ESX_VI__TEMPLATE__PROPERTY__MANAGED_REQUIRE(_name) \
739 /* FIXME: This results in O(n^2) runtime in case of missing required, but \
740 * unselected properties. */ \
741 if (item->_name == 0 && \
742 esxVI_String_ListContainsValue(selectedPropertyNameList, #_name)) { \
743 virReportError(VIR_ERR_INTERNAL_ERROR, \
744 _("%s object is missing the required '%s' property"), \
745 typeName, #_name); \
746 return -1; \
747 }
748
749
750
751 #define ESX_VI__TEMPLATE__MANAGED_VALIDATE(__type, _require) \
752 int \
753 esxVI_##__type##_Validate(esxVI_##__type *item, \
754 esxVI_String *selectedPropertyNameList) \
755 { \
756 const char *typeName = esxVI_Type_ToString(esxVI_Type_##__type); \
757 \
758 if (item->_type <= esxVI_Type_Undefined || \
759 item->_type >= esxVI_Type_Other) { \
760 virReportError(VIR_ERR_INTERNAL_ERROR, \
761 _("%s object has invalid dynamic type"), typeName);\
762 return -1; \
763 } \
764 \
765 _require \
766 \
767 return 0; \
768 }
769
770
771
772 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
773 * XSI: Type
774 */
775
776 const char *
esxVI_Type_ToString(esxVI_Type type)777 esxVI_Type_ToString(esxVI_Type type)
778 {
779 switch (type) {
780 default:
781 case esxVI_Type_Undefined:
782 return "<undefined>";
783
784 case esxVI_Type_Boolean:
785 return "xsd:boolean";
786
787 case esxVI_Type_AnyType:
788 return "xsd:anyType";
789
790 case esxVI_Type_String:
791 return "xsd:string";
792
793 case esxVI_Type_Byte:
794 return "xsd:byte";
795
796 case esxVI_Type_Short:
797 return "xsd:short";
798
799 case esxVI_Type_Int:
800 return "xsd:int";
801
802 case esxVI_Type_Long:
803 return "xsd:long";
804
805 case esxVI_Type_DateTime:
806 return "xsd:dateTime";
807
808 case esxVI_Type_Fault:
809 return "Fault";
810
811 case esxVI_Type_MethodFault:
812 return "MethodFault";
813
814 case esxVI_Type_ManagedObjectReference:
815 return "ManagedObjectReference";
816
817 case esxVI_Type_Event:
818 return "Event";
819
820 #include "esx_vi_types.generated.typetostring"
821
822 case esxVI_Type_Other:
823 return "<other>";
824 }
825 }
826
827 esxVI_Type
esxVI_Type_FromString(const char * type)828 esxVI_Type_FromString(const char *type)
829 {
830 if (!type || STREQ(type, "<undefined>")) {
831 return esxVI_Type_Undefined;
832 } else if (STREQ(type, "xsd:boolean")) {
833 return esxVI_Type_Boolean;
834 } else if (STREQ(type, "xsd:anyType")) {
835 return esxVI_Type_AnyType;
836 } else if (STREQ(type, "xsd:string")) {
837 return esxVI_Type_String;
838 } else if (STREQ(type, "xsd:byte")) {
839 return esxVI_Type_Byte;
840 } else if (STREQ(type, "xsd:short")) {
841 return esxVI_Type_Short;
842 } else if (STREQ(type, "xsd:int")) {
843 return esxVI_Type_Int;
844 } else if (STREQ(type, "xsd:long")) {
845 return esxVI_Type_Long;
846 } else if (STREQ(type, "xsd:dateTime")) {
847 return esxVI_Type_DateTime;
848 } else if (STREQ(type, "Fault")) {
849 return esxVI_Type_Fault;
850 } else if (STREQ(type, "MethodFault")) {
851 return esxVI_Type_MethodFault;
852 } else if (STREQ(type, "ManagedObjectReference")) {
853 return esxVI_Type_ManagedObjectReference;
854 } else if (STREQ(type, "Event")) {
855 return esxVI_Type_Event;
856 }
857
858 #include "esx_vi_types.generated.typefromstring"
859
860 return esxVI_Type_Other;
861 }
862
863
864 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
865 * XSD: Boolean
866 */
867
868 static const esxVI_Enumeration _esxVI_Boolean_Enumeration = {
869 esxVI_Type_Boolean, {
870 { "true", esxVI_Boolean_True },
871 { "false", esxVI_Boolean_False },
872 { NULL, -1 },
873 },
874 };
875
876 /* esxVI_Boolean_Serialize */
877 ESX_VI__TEMPLATE__ENUMERATION__SERIALIZE(Boolean)
878
879 /* esxVI_Boolean_Deserialize */
ESX_VI__TEMPLATE__ENUMERATION__DESERIALIZE(Boolean)880 ESX_VI__TEMPLATE__ENUMERATION__DESERIALIZE(Boolean)
881
882
883
884 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
885 * XSD: AnyType
886 */
887
888 /* esxVI_AnyType_Alloc */
889 ESX_VI__TEMPLATE__ALLOC(AnyType)
890
891 /* esxVI_AnyType_Free */
892 ESX_VI__TEMPLATE__FREE(AnyType,
893 {
894 xmlFreeNode(item->node);
895 g_free(item->other);
896 g_free(item->value);
897 })
898
899 const char *
900 esxVI_AnyType_TypeToString(esxVI_AnyType *anyType)
901 {
902 if (anyType->type == esxVI_Type_Other) {
903 return anyType->other;
904 } else {
905 return esxVI_Type_ToString(anyType->type);
906 }
907 }
908
909 int
esxVI_AnyType_ExpectType(esxVI_AnyType * anyType,esxVI_Type type)910 esxVI_AnyType_ExpectType(esxVI_AnyType *anyType, esxVI_Type type)
911 {
912 if (anyType->type != type) {
913 virReportError(VIR_ERR_INTERNAL_ERROR,
914 _("Expecting type '%s' but found '%s'"),
915 esxVI_Type_ToString(type),
916 esxVI_AnyType_TypeToString(anyType));
917 return -1;
918 }
919
920 return 0;
921 }
922
923 int
esxVI_AnyType_DeepCopy(esxVI_AnyType ** dest,esxVI_AnyType * src)924 esxVI_AnyType_DeepCopy(esxVI_AnyType **dest, esxVI_AnyType *src)
925 {
926 ESX_VI_CHECK_ARG_LIST(dest);
927
928 if (!src)
929 return 0;
930
931 if (esxVI_AnyType_Alloc(dest) < 0)
932 goto failure;
933
934 (*dest)->_type = src->_type;
935 (*dest)->node = xmlCopyNode(src->node, 1);
936
937 if (!(*dest)->node) {
938 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
939 _("Could not copy an XML node"));
940 goto failure;
941 }
942
943 (*dest)->type = src->type;
944
945 (*dest)->other = g_strdup(src->other);
946 (*dest)->value = g_strdup(src->value);
947
948 switch ((int)src->type) {
949 case esxVI_Type_Boolean:
950 (*dest)->boolean = src->boolean;
951 break;
952
953 case esxVI_Type_String:
954 (*dest)->string = (*dest)->value;
955 break;
956
957 case esxVI_Type_Byte:
958 (*dest)->int8 = src->int8;
959 break;
960
961 case esxVI_Type_Short:
962 (*dest)->int16 = src->int16;
963 break;
964
965 case esxVI_Type_Int:
966 (*dest)->int32 = src->int32;
967 break;
968
969 case esxVI_Type_Long:
970 (*dest)->int64 = src->int64;
971 break;
972
973 default:
974 break;
975 }
976
977 return 0;
978
979 failure:
980 esxVI_AnyType_Free(dest);
981
982 return -1;
983 }
984
985 int
esxVI_AnyType_Deserialize(xmlNodePtr node,esxVI_AnyType ** anyType)986 esxVI_AnyType_Deserialize(xmlNodePtr node, esxVI_AnyType **anyType)
987 {
988 long long int number;
989
990 ESX_VI_CHECK_ARG_LIST(anyType);
991
992 if (esxVI_AnyType_Alloc(anyType) < 0)
993 return -1;
994
995 (*anyType)->node = xmlCopyNode(node, 1);
996
997 if (!(*anyType)->node) {
998 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
999 _("Could not copy an XML node"));
1000 goto failure;
1001 }
1002
1003 (*anyType)->other =
1004 (char *)xmlGetNsProp
1005 (node, BAD_CAST "type",
1006 BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
1007
1008 if (!(*anyType)->other) {
1009 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1010 _("AnyType is missing 'type' property"));
1011 goto failure;
1012 }
1013
1014 (*anyType)->type = esxVI_Type_FromString((*anyType)->other);
1015
1016 if ((*anyType)->type == esxVI_Type_Undefined) {
1017 virReportError(VIR_ERR_INTERNAL_ERROR,
1018 _("Unknown value '%s' for AnyType 'type' property"),
1019 (*anyType)->other);
1020 goto failure;
1021 }
1022
1023 (*anyType)->value =
1024 (char *)xmlNodeListGetString(node->doc, node->children, 1);
1025
1026 if (!(*anyType)->value)
1027 (*anyType)->value = g_strdup("");
1028
1029 #define _DESERIALIZE_NUMBER(_type, _xsdType, _name, _min, _max) \
1030 do { \
1031 if (virStrToLong_ll((*anyType)->value, NULL, 10, &number) < 0) { \
1032 virReportError(VIR_ERR_INTERNAL_ERROR, \
1033 _("Unknown value '%s' for %s"), \
1034 (*anyType)->value, _xsdType); \
1035 goto failure; \
1036 } \
1037 \
1038 if (((_min) != INT64_MIN && number < (_min)) \
1039 || ((_max) != INT64_MAX && number > (_max))) { \
1040 virReportError(VIR_ERR_INTERNAL_ERROR, \
1041 _("Value '%s' is out of %s range"), \
1042 (*anyType)->value, _xsdType); \
1043 goto failure; \
1044 } \
1045 \
1046 (*anyType)->_name = number; \
1047 } while (0)
1048
1049 switch ((int)(*anyType)->type) {
1050 case esxVI_Type_Boolean:
1051 if (STREQ((*anyType)->value, "true")) {
1052 (*anyType)->boolean = esxVI_Boolean_True;
1053 } else if (STREQ((*anyType)->value, "false")) {
1054 (*anyType)->boolean = esxVI_Boolean_False;
1055 } else {
1056 virReportError(VIR_ERR_INTERNAL_ERROR,
1057 _("Unknown value '%s' for xsd:boolean"),
1058 (*anyType)->value);
1059 goto failure;
1060 }
1061
1062 break;
1063
1064 case esxVI_Type_String:
1065 (*anyType)->string = (*anyType)->value;
1066 break;
1067
1068 case esxVI_Type_Byte:
1069 _DESERIALIZE_NUMBER(Byte, "xsd:byte", int8, INT8_MIN, INT8_MAX);
1070 break;
1071
1072 case esxVI_Type_Short:
1073 _DESERIALIZE_NUMBER(Short, "xsd:short", int16, INT16_MIN, INT16_MAX);
1074 break;
1075
1076 case esxVI_Type_Int:
1077 _DESERIALIZE_NUMBER(Int, "xsd:int", int32, INT32_MIN, INT32_MAX);
1078 break;
1079
1080 case esxVI_Type_Long:
1081 _DESERIALIZE_NUMBER(Long, "xsd:long", int64, INT64_MIN, INT64_MAX);
1082 break;
1083
1084 default:
1085 break;
1086 }
1087
1088 #undef _DESERIALIZE_NUMBER
1089
1090 return 0;
1091
1092 failure:
1093 esxVI_AnyType_Free(anyType);
1094
1095 return -1;
1096 }
1097
1098
1099
1100 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1101 * XSD: String
1102 */
1103
1104 /* esxVI_String_Alloc */
1105 ESX_VI__TEMPLATE__ALLOC(String)
1106
1107 /* esxVI_String_Free */
1108 ESX_VI__TEMPLATE__FREE(String,
1109 {
1110 esxVI_String_Free(&item->_next);
1111
1112 g_free(item->value);
1113 })
1114
1115 /* esxVI_String_Validate */
1116 ESX_VI__TEMPLATE__VALIDATE(String,
1117 {
1118 ESX_VI__TEMPLATE__PROPERTY__REQUIRE(value)
1119 })
1120
1121 bool
esxVI_String_ListContainsValue(esxVI_String * stringList,const char * value)1122 esxVI_String_ListContainsValue(esxVI_String *stringList, const char *value)
1123 {
1124 esxVI_String *string;
1125
1126 for (string = stringList; string; string = string->_next) {
1127 if (STREQ(string->value, value))
1128 return true;
1129 }
1130
1131 return false;
1132 }
1133
1134 /* esxVI_String_AppendToList */
ESX_VI__TEMPLATE__LIST__APPEND(String)1135 ESX_VI__TEMPLATE__LIST__APPEND(String)
1136
1137 int
1138 esxVI_String_AppendValueToList(esxVI_String **stringList, const char *value)
1139 {
1140 esxVI_String *string = NULL;
1141
1142 if (esxVI_String_Alloc(&string) < 0)
1143 return -1;
1144
1145 string->value = g_strdup(value);
1146
1147 if (esxVI_String_AppendToList(stringList, string) < 0)
1148 goto failure;
1149
1150 return 0;
1151
1152 failure:
1153 esxVI_String_Free(&string);
1154
1155 return -1;
1156 }
1157
1158 int
esxVI_String_AppendValueListToList(esxVI_String ** stringList,const char * valueList)1159 esxVI_String_AppendValueListToList(esxVI_String **stringList,
1160 const char *valueList)
1161 {
1162 esxVI_String *stringListToAppend = NULL;
1163 const char *value = valueList;
1164
1165 while (value && *value != '\0') {
1166 if (esxVI_String_AppendValueToList(&stringListToAppend, value) < 0)
1167 goto failure;
1168
1169 value += strlen(value) + 1;
1170 }
1171
1172 if (esxVI_String_AppendToList(stringList, stringListToAppend) < 0)
1173 goto failure;
1174
1175 return 0;
1176
1177 failure:
1178 esxVI_String_Free(&stringListToAppend);
1179
1180 return -1;
1181 }
1182
1183 /* esxVI_String_DeepCopy */
1184 ESX_VI__TEMPLATE__DEEP_COPY(String,
1185 {
1186 ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_VALUE(String, value)
1187 })
1188
1189 /* esxVI_String_DeepCopyList */
ESX_VI__TEMPLATE__LIST__DEEP_COPY(String)1190 ESX_VI__TEMPLATE__LIST__DEEP_COPY(String)
1191
1192 int
1193 esxVI_String_DeepCopyValue(char **dest, const char *src)
1194 {
1195 ESX_VI_CHECK_ARG_LIST(dest);
1196
1197 *dest = g_strdup(src);
1198 return 0;
1199 }
1200
1201 /* esxVI_String_CastFromAnyType */
1202 ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE(String)
1203
1204 /* esxVI_String_CastValueFromAnyType */
ESX_VI__TEMPLATE__CAST_VALUE_FROM_ANY_TYPE(String,char)1205 ESX_VI__TEMPLATE__CAST_VALUE_FROM_ANY_TYPE(String, char)
1206
1207 int
1208 esxVI_String_Serialize(esxVI_String *string, const char *element,
1209 virBuffer *output)
1210 {
1211 return esxVI_String_SerializeValue(string ? string->value : NULL,
1212 element, output);
1213 }
1214
1215 /* esxVI_String_SerializeList */
ESX_VI__TEMPLATE__LIST__SERIALIZE(String)1216 ESX_VI__TEMPLATE__LIST__SERIALIZE(String)
1217
1218 int
1219 esxVI_String_SerializeValue(const char *value, const char *element,
1220 virBuffer *output)
1221 {
1222 if (!element || !output) {
1223 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
1224 return -1;
1225 }
1226
1227 if (!value)
1228 return 0;
1229
1230 ESV_VI__XML_TAG__OPEN(output, element, "xsd:string");
1231
1232 virBufferAdd(output, value, -1);
1233
1234 ESV_VI__XML_TAG__CLOSE(output, element);
1235
1236 return 0;
1237 }
1238
1239 int
esxVI_String_Deserialize(xmlNodePtr node,esxVI_String ** string)1240 esxVI_String_Deserialize(xmlNodePtr node, esxVI_String **string)
1241 {
1242 ESX_VI_CHECK_ARG_LIST(string);
1243
1244 if (esxVI_String_Alloc(string) < 0 ||
1245 esxVI_String_DeserializeValue(node, &(*string)->value) < 0) {
1246 goto failure;
1247 }
1248
1249 return 0;
1250
1251 failure:
1252 esxVI_String_Free(string);
1253
1254 return -1;
1255 }
1256
1257 /* esxVI_String_DeserializeList */
ESX_VI__TEMPLATE__LIST__DESERIALIZE(String)1258 ESX_VI__TEMPLATE__LIST__DESERIALIZE(String)
1259
1260 int
1261 esxVI_String_DeserializeValue(xmlNodePtr node, char **value)
1262 {
1263 ESX_VI_CHECK_ARG_LIST(value);
1264
1265 *value = (char *)xmlNodeListGetString(node->doc, node->children, 1);
1266 if (!*value)
1267 *value = g_strdup("");
1268
1269 return 0;
1270 }
1271
1272
1273
1274 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1275 * XSD: Byte
1276 */
1277
1278 /* esxVI_Byte_Alloc */
1279 ESX_VI__TEMPLATE__ALLOC(Byte)
1280
1281 /* esxVI_Byte_Free */
1282 ESX_VI__TEMPLATE__FREE(Byte,
1283 {
1284 esxVI_Byte_Free(&item->_next);
1285 })
1286
1287 /* esxVI_Byte_Validate */
1288 ESX_VI__TEMPLATE__VALIDATE(Byte,
1289 {
1290 })
1291
1292 /* esxVI_Byte_AppendToList */
1293 ESX_VI__TEMPLATE__LIST__APPEND(Byte)
1294
1295 /* esxVI_Byte_DeepCopy */
1296 ESX_VI__TEMPLATE__DEEP_COPY(Byte,
1297 {
1298 (*dest)->value = src->value;
1299 })
1300
1301 /* esxVI_Byte_DeepCopyList */
1302 ESX_VI__TEMPLATE__LIST__DEEP_COPY(Byte)
1303
1304 /* esxVI_Byte_Serialize */
1305 ESX_VI__TEMPLATE__SERIALIZE(Byte,
1306 {
1307 virBufferAsprintf(output, "%d", (int)item->value);
1308 })
1309
1310 /* esxVI_Byte_SerializeList */
1311 ESX_VI__TEMPLATE__LIST__SERIALIZE(Byte)
1312
1313 /* esxVI_Byte_Deserialize */
1314 ESX_VI__TEMPLATE__DESERIALIZE_NUMBER(Byte, "xsd:byte", INT8_MIN, INT8_MAX);
1315
1316
1317
1318 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1319 * XSD: Int
1320 */
1321
1322 /* esxVI_Int_Alloc */
1323 ESX_VI__TEMPLATE__ALLOC(Int)
1324
1325 /* esxVI_Int_Free */
1326 ESX_VI__TEMPLATE__FREE(Int,
1327 {
1328 esxVI_Int_Free(&item->_next);
1329 })
1330
1331 /* esxVI_Int_Validate */
1332 ESX_VI__TEMPLATE__VALIDATE(Int,
1333 {
1334 })
1335
1336 /* esxVI_Int_AppendToList */
ESX_VI__TEMPLATE__LIST__APPEND(Int)1337 ESX_VI__TEMPLATE__LIST__APPEND(Int)
1338
1339 /* esxVI_Int_DeepCopy */
1340 ESX_VI__TEMPLATE__DEEP_COPY(Int,
1341 {
1342 (*dest)->value = src->value;
1343 })
1344
1345 /* esxVI_Int_CastFromAnyType */
1346 ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE(Int)
1347
1348 /* esxVI_Int_Serialize */
1349 ESX_VI__TEMPLATE__SERIALIZE(Int,
1350 {
1351 virBufferAsprintf(output, "%d", (int)item->value);
1352 })
1353
1354 /* esxVI_Int_SerializeList */
1355 ESX_VI__TEMPLATE__LIST__SERIALIZE(Int)
1356
1357 /* esxVI_Int_Deserialize */
1358 ESX_VI__TEMPLATE__DESERIALIZE_NUMBER(Int, "xsd:int", INT32_MIN, INT32_MAX)
1359
1360
1361
1362 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1363 * XSD: Long
1364 */
1365
1366 /* esxVI_Long_Alloc */
1367 ESX_VI__TEMPLATE__ALLOC(Long)
1368
1369 /* esxVI_Long_Free */
1370 ESX_VI__TEMPLATE__FREE(Long,
1371 {
1372 esxVI_Long_Free(&item->_next);
1373 })
1374
1375 /* esxVI_Long_Validate */
1376 ESX_VI__TEMPLATE__VALIDATE(Long,
1377 {
1378 })
1379
1380 /* esxVI_Long_AppendToList */
1381 ESX_VI__TEMPLATE__LIST__APPEND(Long)
1382
1383 /* esxVI_Long_DeepCopy */
1384 ESX_VI__TEMPLATE__DEEP_COPY(Long,
1385 {
1386 (*dest)->value = src->value;
1387 })
1388
1389 /* esxVI_Long_CastFromAnyType */
1390 ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE(Long)
1391
1392 /* esxVI_Long_Serialize */
1393 ESX_VI__TEMPLATE__SERIALIZE(Long,
1394 {
1395 virBufferAsprintf(output, "%lld", (long long int)item->value);
1396 })
1397
1398 /* esxVI_Long_SerializeList */
1399 ESX_VI__TEMPLATE__LIST__SERIALIZE(Long)
1400
1401 /* esxVI_Long_Deserialize */
1402 ESX_VI__TEMPLATE__DESERIALIZE_NUMBER(Long, "xsd:long", INT64_MIN, INT64_MAX)
1403
1404
1405
1406 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1407 * XSD: DateTime
1408 */
1409
1410 /* esxVI_DateTime_Alloc */
1411 ESX_VI__TEMPLATE__ALLOC(DateTime)
1412
1413 /* esxVI_DateTime_Free */
1414 ESX_VI__TEMPLATE__FREE(DateTime,
1415 {
1416 g_free(item->value);
1417 })
1418
1419 /* esxVI_DateTime_Validate */
1420 ESX_VI__TEMPLATE__VALIDATE(DateTime,
1421 {
1422 ESX_VI__TEMPLATE__PROPERTY__REQUIRE(value);
1423 })
1424
1425 /* esxVI_DateTime_DeepCopy */
1426 ESX_VI__TEMPLATE__DEEP_COPY(DateTime,
1427 {
1428 ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_VALUE(String, value)
1429 })
1430
1431 /* esxVI_DateTime_Serialize */
1432 ESX_VI__TEMPLATE__SERIALIZE(DateTime,
1433 {
1434 virBufferAdd(output, item->value, -1);
1435 })
1436
1437 int
1438 esxVI_DateTime_Deserialize(xmlNodePtr node, esxVI_DateTime **dateTime)
1439 {
1440 ESX_VI_CHECK_ARG_LIST(dateTime);
1441
1442 if (esxVI_DateTime_Alloc(dateTime) < 0)
1443 return -1;
1444
1445 (*dateTime)->value =
1446 (char *)xmlNodeListGetString(node->doc, node->children, 1);
1447
1448 if (!(*dateTime)->value) {
1449 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1450 _("XML node doesn't contain text, expecting an "
1451 "xsd:dateTime value"));
1452 goto failure;
1453 }
1454
1455 return 0;
1456
1457 failure:
1458 esxVI_DateTime_Free(dateTime);
1459
1460 return -1;
1461 }
1462
1463 int
esxVI_DateTime_ConvertToCalendarTime(esxVI_DateTime * dateTime,long long * secondsSinceEpoch)1464 esxVI_DateTime_ConvertToCalendarTime(esxVI_DateTime *dateTime,
1465 long long *secondsSinceEpoch)
1466 {
1467 char *tmp;
1468 g_autoptr(GDateTime) then = NULL;
1469 g_autoptr(GTimeZone) tz = NULL;
1470 int year, mon, mday, hour, min, sec, milliseconds;
1471
1472 if (!dateTime || !secondsSinceEpoch) {
1473 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
1474 return -1;
1475 }
1476
1477 /*
1478 * expected format: [-]CCYY-MM-DDTHH:MM:SS[.ssssss][((+|-)HH:MM|Z)]
1479 * typical example: 2010-04-05T12:13:55.316789+02:00
1480 *
1481 * see http://www.w3.org/TR/xmlschema-2/#dateTime
1482 *
1483 * map negative years to 0, since the base for time_t is the year 1970.
1484 */
1485 if (dateTime->value[0] == '-') {
1486 *secondsSinceEpoch = 0;
1487 return 0;
1488 }
1489
1490 if (/* year */
1491 virStrToLong_i(dateTime->value, &tmp, 10, &year) < 0 || *tmp != '-' ||
1492 /* month */
1493 virStrToLong_i(tmp+1, &tmp, 10, &mon) < 0 || *tmp != '-' ||
1494 /* day */
1495 virStrToLong_i(tmp+1, &tmp, 10, &mday) < 0 || *tmp != 'T' ||
1496 /* hour */
1497 virStrToLong_i(tmp+1, &tmp, 10, &hour) < 0 || *tmp != ':' ||
1498 /* minute */
1499 virStrToLong_i(tmp+1, &tmp, 10, &min) < 0 || *tmp != ':' ||
1500 /* second */
1501 virStrToLong_i(tmp+1, &tmp, 10, &sec) < 0) {
1502 virReportError(VIR_ERR_INTERNAL_ERROR,
1503 _("xsd:dateTime value '%s' has unexpected format"),
1504 dateTime->value);
1505 return -1;
1506 }
1507
1508 if (*tmp != '\0') {
1509 /* skip .ssssss part if present */
1510 if (*tmp == '.' &&
1511 virStrToLong_i(tmp + 1, &tmp, 10, &milliseconds) < 0) {
1512 virReportError(VIR_ERR_INTERNAL_ERROR,
1513 _("xsd:dateTime value '%s' has unexpected format"),
1514 dateTime->value);
1515 return -1;
1516 }
1517
1518 /* parse timezone offset if present. if missing assume UTC */
1519 if (*tmp == '+' || *tmp == '-') {
1520 tz = g_time_zone_new(tmp);
1521 } else if (STREQ(tmp, "Z")) {
1522 tz = g_time_zone_new_utc();
1523 } else {
1524 virReportError(VIR_ERR_INTERNAL_ERROR,
1525 _("xsd:dateTime value '%s' has unexpected format"),
1526 dateTime->value);
1527 return -1;
1528 }
1529 } else {
1530 tz = g_time_zone_new_utc();
1531 }
1532
1533 /*
1534 * xsd:dateTime represents local time relative to the optional timezone
1535 * given as offset. pretend the local time is in UTC and use timegm in
1536 * order to avoid interference with the timezone to this computer.
1537 * apply timezone correction afterwards, because it's simpler than
1538 * handling all the possible over- and underflows when trying to apply
1539 * it to the tm struct.
1540 */
1541 then = g_date_time_new(tz, year, mon, mday, hour, min, sec);
1542 *secondsSinceEpoch = (long long)g_date_time_to_unix(then);
1543
1544 return 0;
1545 }
1546
1547
1548
1549 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1550 * SOAP: Fault
1551 */
1552
1553 /* esxVI_Fault_Alloc */
1554 ESX_VI__TEMPLATE__ALLOC(Fault);
1555
1556 /* esxVI_Fault_Free */
1557 ESX_VI__TEMPLATE__FREE(Fault,
1558 {
1559 g_free(item->faultcode);
1560 g_free(item->faultstring);
1561 })
1562
1563 /* esxVI_Fault_Validate */
1564 ESX_VI__TEMPLATE__VALIDATE(Fault,
1565 {
1566 ESX_VI__TEMPLATE__PROPERTY__REQUIRE(faultcode);
1567 ESX_VI__TEMPLATE__PROPERTY__REQUIRE(faultstring);
1568 })
1569
1570 /* esxVI_Fault_Deserialize */
1571 ESX_VI__TEMPLATE__DESERIALIZE(Fault,
1572 {
1573 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, faultcode);
1574 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, faultstring);
1575 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_IGNORE(detail); /* FIXME */
1576 })
1577
1578
1579
1580 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1581 * VI Object: MethodFault
1582 */
1583
1584 /* esxVI_MethodFault_Alloc */
1585 ESX_VI__TEMPLATE__ALLOC(MethodFault);
1586
1587 /* esxVI_MethodFault_Free */
1588 ESX_VI__TEMPLATE__FREE(MethodFault,
1589 {
1590 g_free(item->_actualType);
1591 })
1592
1593 int
esxVI_MethodFault_Deserialize(xmlNodePtr node,esxVI_MethodFault ** methodFault)1594 esxVI_MethodFault_Deserialize(xmlNodePtr node, esxVI_MethodFault **methodFault)
1595 {
1596 ESX_VI_CHECK_ARG_LIST(methodFault);
1597
1598 if (esxVI_MethodFault_Alloc(methodFault) < 0)
1599 return -1;
1600
1601 (*methodFault)->_actualType =
1602 (char *)xmlGetNsProp(node, BAD_CAST "type",
1603 BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
1604
1605 if (!(*methodFault)->_actualType) {
1606 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1607 _("MethodFault is missing 'type' property"));
1608 goto failure;
1609 }
1610
1611 return 0;
1612
1613 failure:
1614 esxVI_MethodFault_Free(methodFault);
1615
1616 return -1;
1617 }
1618
1619
1620
1621 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1622 * VI Object: ManagedObjectReference
1623 */
1624
1625 /* esxVI_ManagedObjectReference_Alloc */
1626 ESX_VI__TEMPLATE__ALLOC(ManagedObjectReference)
1627
1628 /* esxVI_ManagedObjectReference_Free */
1629 ESX_VI__TEMPLATE__FREE(ManagedObjectReference,
1630 {
1631 esxVI_ManagedObjectReference_Free(&item->_next);
1632
1633 g_free(item->type);
1634 g_free(item->value);
1635 })
1636
1637 /* esxVI_ManagedObjectReference_DeepCopy */
1638 ESX_VI__TEMPLATE__DEEP_COPY(ManagedObjectReference,
1639 {
1640 ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_VALUE(String, type)
1641 ESX_VI__TEMPLATE__PROPERTY__DEEP_COPY_VALUE(String, value)
1642 })
1643
1644 /* esxVI_ManagedObjectReference_AppendToList */
ESX_VI__TEMPLATE__LIST__APPEND(ManagedObjectReference)1645 ESX_VI__TEMPLATE__LIST__APPEND(ManagedObjectReference)
1646
1647 /* esxVI_ManagedObjectReference_CastFromAnyType */
1648 ESX_VI__TEMPLATE__CAST_FROM_ANY_TYPE(ManagedObjectReference)
1649
1650 /* esxVI_ManagedObjectReference_CastListFromAnyType */
1651 ESX_VI__TEMPLATE__LIST__CAST_FROM_ANY_TYPE(ManagedObjectReference)
1652
1653 int
1654 esxVI_ManagedObjectReference_Serialize
1655 (esxVI_ManagedObjectReference *managedObjectReference,
1656 const char *element, virBuffer *output)
1657 {
1658 if (!element || !output) {
1659 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
1660 return -1;
1661 }
1662
1663 if (!managedObjectReference)
1664 return 0;
1665
1666 virBufferAddLit(output, "<");
1667 virBufferAdd(output, element, -1);
1668 virBufferAsprintf(output,
1669 " xmlns=\"urn:vim25\" "
1670 "xsi:type=\"ManagedObjectReference\" type=\"%s\">",
1671 managedObjectReference->type);
1672
1673 virBufferAdd(output, managedObjectReference->value, -1);
1674
1675 ESV_VI__XML_TAG__CLOSE(output, element);
1676
1677 return 0;
1678 }
1679
1680 /* esxVI_ManagedObjectReference_SerializeList */
ESX_VI__TEMPLATE__LIST__SERIALIZE(ManagedObjectReference)1681 ESX_VI__TEMPLATE__LIST__SERIALIZE(ManagedObjectReference)
1682
1683 int
1684 esxVI_ManagedObjectReference_Deserialize
1685 (xmlNodePtr node, esxVI_ManagedObjectReference **managedObjectReference)
1686 {
1687 ESX_VI_CHECK_ARG_LIST(managedObjectReference);
1688
1689 if (esxVI_ManagedObjectReference_Alloc(managedObjectReference) < 0)
1690 return -1;
1691
1692 (*managedObjectReference)->type =
1693 (char *)xmlGetNoNsProp(node, BAD_CAST "type");
1694
1695 if (!(*managedObjectReference)->type) {
1696 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
1697 _("ManagedObjectReference is missing 'type' property"));
1698 goto failure;
1699 }
1700
1701 if (esxVI_String_DeserializeValue(node,
1702 &(*managedObjectReference)->value) < 0) {
1703 goto failure;
1704 }
1705
1706 return 0;
1707
1708 failure:
1709 esxVI_ManagedObjectReference_Free(managedObjectReference);
1710
1711 return -1;
1712 }
1713
1714
1715
1716 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1717 * VI Type: Event
1718 */
1719
1720 /* esxVI_Event_Alloc */
1721 ESX_VI__TEMPLATE__ALLOC(Event)
1722
1723 /* esxVI_Event_Free */
1724 ESX_VI__TEMPLATE__FREE(Event,
1725 {
1726 esxVI_Event_Free(&item->_next);
1727 g_free(item->_actualType);
1728
1729 esxVI_Int_Free(&item->key);
1730 esxVI_Int_Free(&item->chainId);
1731 esxVI_DateTime_Free(&item->createdTime);
1732 g_free(item->userName);
1733 /* FIXME: datacenter is currently ignored */
1734 /* FIXME: computeResource is currently ignored */
1735 /* FIXME: host is currently ignored */
1736 esxVI_VmEventArgument_Free(&item->vm);
1737 g_free(item->fullFormattedMessage);
1738 })
1739
1740 /* esxVI_Event_Validate */
1741 ESX_VI__TEMPLATE__VALIDATE(Event,
1742 {
1743 ESX_VI__TEMPLATE__PROPERTY__REQUIRE(key)
1744 ESX_VI__TEMPLATE__PROPERTY__REQUIRE(chainId)
1745 ESX_VI__TEMPLATE__PROPERTY__REQUIRE(createdTime)
1746 ESX_VI__TEMPLATE__PROPERTY__REQUIRE(userName)
1747 /* FIXME: datacenter is currently ignored */
1748 /* FIXME: computeResource is currently ignored */
1749 /* FIXME: host is currently ignored */
1750 })
1751
1752 /* esxVI_Event_AppendToList */
ESX_VI__TEMPLATE__LIST__APPEND(Event)1753 ESX_VI__TEMPLATE__LIST__APPEND(Event)
1754
1755 /* esxVI_Event_CastFromAnyType */
1756 ESX_VI__TEMPLATE__DYNAMIC_CAST_FROM_ANY_TYPE(Event,
1757 {
1758 case esxVI_Type_Other:
1759 /* Just accept everything here */
1760 break;
1761 })
1762
1763 /* esxVI_Event_CastListFromAnyType */
1764 ESX_VI__TEMPLATE__LIST__CAST_FROM_ANY_TYPE(Event)
1765
1766 /* esxVI_Event_Deserialize */
1767 ESX_VI__TEMPLATE__DESERIALIZE_EXTRA(Event, /* nothing */,
1768 {
1769 (*ptrptr)->_actualType =
1770 (char *)xmlGetNsProp(node, BAD_CAST "type",
1771 BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
1772
1773 if (!(*ptrptr)->_actualType) {
1774 virReportError(VIR_ERR_INTERNAL_ERROR,
1775 _("%s is missing 'type' property"),
1776 esxVI_Type_ToString((*ptrptr)->_type));
1777 goto failure;
1778 }
1779 },
1780 {
1781 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Int, key)
1782 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(Int, chainId)
1783 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(DateTime, createdTime)
1784 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, userName)
1785 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_IGNORE(datacenter) /* FIXME */
1786 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_IGNORE(computeResource) /* FIXME */
1787 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_IGNORE(host) /* FIXME */
1788 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE(VmEventArgument, vm)
1789 ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, fullFormattedMessage)
1790
1791 /* Don't warn about unexpected properties */
1792 continue;
1793 })
1794
1795 /* esxVI_Event_DeserializeList */
1796 ESX_VI__TEMPLATE__LIST__DESERIALIZE(Event)
1797
1798
1799
1800 #include "esx_vi_types.generated.c"
1801
1802
1803
1804 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1805 * VI Enum: VirtualMachinePowerState (Additions)
1806 */
1807
1808 int
1809 esxVI_VirtualMachinePowerState_ConvertToLibvirt
1810 (esxVI_VirtualMachinePowerState powerState)
1811 {
1812 switch (powerState) {
1813 case esxVI_VirtualMachinePowerState_PoweredOff:
1814 return VIR_DOMAIN_SHUTOFF;
1815
1816 case esxVI_VirtualMachinePowerState_PoweredOn:
1817 return VIR_DOMAIN_RUNNING;
1818
1819 case esxVI_VirtualMachinePowerState_Suspended:
1820 return VIR_DOMAIN_PAUSED;
1821
1822 case esxVI_VirtualMachinePowerState_Undefined:
1823 default:
1824 return VIR_DOMAIN_NOSTATE;
1825 }
1826 }
1827