os-cmpi-xen

view src/cmpiutil.c @ 121:4868ace2726b

Add initial consistence checks in test suite for Xen_MemoryPool, Xen_ProcessorPool and Xen_VirtualSystemManagementService.

Signed-off-by: Luke Szymanski <Lukasz.Szymanski@Unisys.com>
author Jim Fehlig <jfehlig@novell.com>
date Fri Jun 08 10:22:05 2007 -0600 (2007-06-08)
parents 92a3b51298ab
children
line source
1 // Copyright (C) 2006 IBM Corporation
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 // ============================================================================
17 // Author: Dr. Gareth S. Bestor <bestor@us.ibm.com>
18 // Contributors:
19 // Summary: Some useful utility functions
20 // Description:
21 // TODO
22 // For more information about the SBLIM Project see:
23 // http://sblim.sourceforge.net/
24 // ============================================================================
26 #include <stdlib.h>
27 #include <string.h>
29 /* Include the required CMPI data types, function headers, and macros. */
30 #include "cmpidt.h"
31 #include "cmpift.h"
32 #include "cmpimacs.h"
34 /* ------------------------------------------------------------------------- */
36 /* CMNewInstance() substitute that does the prerequisite CMNewObjectPath() for you. */
37 CMPIInstance * _CMNewInstance(const CMPIBroker *mb, char *ns, char *cn, CMPIStatus *rc)
38 {
39 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */
41 /* First attempt to create a CMPIObjectPath for the new instance. */
42 CMPIObjectPath * objectpath = CMNewObjectPath(mb, ns, cn, &status);
43 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(objectpath)) return NULL;
45 /* Next attempt to create the CMPIInstance. */
46 CMPIInstance * instance = CMNewInstance(mb, objectpath, rc);
47 if (((rc != NULL) && (rc->rc != CMPI_RC_OK)) || CMIsNullObject(instance)) return NULL;
49 /* Everything worked OK. */
50 return instance;
51 }
53 /* ------------------------------------------------------------------------- */
55 /* Compare two CIM types to see if they are identical. */
56 int _CMSameType( CMPIData value1, CMPIData value2 )
57 {
58 return (value1.type == value2.type);
59 }
61 /* ------------------------------------------------------------------------- */
63 /* Compare two CIM data values to see if they are identical. */
64 int _CMSameValue( CMPIData value1, CMPIData value2 )
65 {
66 /* Check if the type of the two CIM values is the same. */
67 if (!_CMSameType(value1, value2)) return 0;
69 /* Check if the value of the two CIM values is the same. */
70 switch (value1.type) {
71 case CMPI_string: {
72 if (CMIsNullObject(value1.value.string) || CMIsNullObject(value2.value.string)) return 0;
74 /* Compare the C strings for equality. */
75 return (strcmp(CMGetCharPtr(value1.value.string), CMGetCharPtr(value2.value.string)) == 0);
76 }
78 case CMPI_dateTime: {
79 CMPIUint64 dateTime1, dateTime2; /* Binary representation of the dateTimes. */
80 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */
82 if (CMIsNullObject(value1.value.dateTime) || CMIsNullObject(value2.value.dateTime)) return 0;
83 dateTime1 = CMGetBinaryFormat(value1.value.dateTime, &status);
84 if (status.rc != CMPI_RC_OK) return 0;
85 dateTime2 = CMGetBinaryFormat(value2.value.dateTime, &status);
86 if (status.rc != CMPI_RC_OK) return 0;
88 /* Compare the binary dateTimes for equality. */
89 return (dateTime1 == dateTime2);
90 }
92 /* Compare the simple types for equality. */
93 case CMPI_boolean: return (value1.value.boolean == value2.value.boolean);
94 case CMPI_char16: return (value1.value.char16 == value2.value.char16);
95 case CMPI_uint8: return (value1.value.uint8 == value2.value.uint8);
96 case CMPI_sint8: return (value1.value.sint8 == value2.value.sint8);
97 case CMPI_uint16: return (value1.value.uint16 == value2.value.uint16);
98 case CMPI_sint16: return (value1.value.sint16 == value2.value.sint16);
99 case CMPI_uint32: return (value1.value.uint32 == value2.value.uint32);
100 case CMPI_sint32: return (value1.value.sint32 == value2.value.sint32);
101 case CMPI_uint64: return (value1.value.uint64 == value2.value.uint64);
102 case CMPI_sint64: return (value1.value.sint64 == value2.value.sint64);
103 case CMPI_real32: return (value1.value.real32 == value2.value.real32);
104 case CMPI_real64: return (value1.value.real64 == value2.value.real64);
105 }
106 return 0;
107 }
109 /* ------------------------------------------------------------------------- */
111 /* Compare two CIM object paths to see if they are identical. */
112 int _CMSameObject( CMPIObjectPath * object1, CMPIObjectPath * object2 )
113 {
114 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */
115 int i;
117 /* Check if the two object paths have the same namespace. */
118 CMPIString * namespace1 = CMGetNameSpace(object1, &status);
119 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(namespace1)) return 0;
120 CMPIString * namespace2 = CMGetNameSpace(object2, &status);
121 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(namespace2)) return 0;
122 if (strcmp(CMGetCharPtr(namespace1), CMGetCharPtr(namespace2)) != 0) return 0;
124 /* Check if the two object paths have the same class. */
125 CMPIString * classname1 = CMGetClassName(object1, &status);
126 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(classname1)) return 0;
127 CMPIString * classname2 = CMGetClassName(object2, &status);
128 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(classname2)) return 0;
129 if (strcmp(CMGetCharPtr(classname1), CMGetCharPtr(classname2)) != 0) return 0;
131 /* Check if the two object paths have the same number of keys. */
132 int numkeys1 = CMGetKeyCount(object1, &status);
133 if (status.rc != CMPI_RC_OK) return 0;
134 int numkeys2 = CMGetKeyCount(object2, &status);
135 if (status.rc != CMPI_RC_OK) return 0;
136 if (numkeys1 != numkeys2) return 0;
138 /* Go through the keys for the 1st object path and compare to the 2nd object path. */
139 for (i=0; i<numkeys1; i++) {
140 CMPIString * keyname = NULL;
142 /* Retrieve the same key from both object paths. */
143 CMPIData key1 = CMGetKeyAt(object1, i, &keyname, &status);
144 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(keyname)) return 0;
145 CMPIData key2 = CMGetKey(object2, CMGetCharPtr(keyname), &status);
146 if (status.rc != CMPI_RC_OK) return 0;
148 /* Check if both keys are not nullValue and have the same value. '^' = XOR. */
149 if ((CMIsNullValue(key1) ^ CMIsNullValue(key2)) || !_CMSameValue(key1,key2)) return 0;
150 }
152 /* If got here then everything matched! */
153 return 1;
154 }
156 /* ------------------------------------------------------------------------- */
158 /* Compare two CIM instances to see if they are identical. */
159 int _CMSameInstance( CMPIInstance * instance1, CMPIInstance * instance2 )
160 {
161 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations */
162 int i;
164 /* Check that the two instances have the same object path. */
165 CMPIObjectPath * objectpath1 = CMGetObjectPath(instance1, &status);
166 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(objectpath1)) return 0;
167 CMPIObjectPath * objectpath2 = CMGetObjectPath(instance2, &status);
168 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(objectpath2)) return 0;
169 if (!_CMSameObject(objectpath1, objectpath2)) return 0;
171 /* Check if the two instances have the same number of properties. */
172 int numproperties1 = CMGetPropertyCount(instance1, &status);
173 if (status.rc != CMPI_RC_OK) return 0;
174 int numproperties2 = CMGetPropertyCount(instance2, &status);
175 if (status.rc != CMPI_RC_OK) return 0;
176 if (numproperties1 != numproperties2) return 0;
178 /* Go through the properties for the 1st instance and compare to the 2nd instance. */
179 for (i=0; i<numproperties1; i++) {
180 CMPIString * propertyname = NULL;
182 /* Retrieve the same property from both instances */
183 CMPIData property1 = CMGetPropertyAt(instance1, i, &propertyname, &status);
184 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(propertyname)) return 0;
185 CMPIData property2 = CMGetProperty(instance2, CMGetCharPtr(propertyname), &status);
186 if (status.rc != CMPI_RC_OK) return 0;
188 /* Check if both properties are not nullValue and have the same value. '^' = XOR */
189 if ((CMIsNullValue(property1) ^ CMIsNullValue(property2)) || !_CMSameValue(property1,property2)) return 0;
190 }
192 /* If got here then everything matched! */
193 return 1;
194 }
196 /* ------------------------------------------------------------------------- */
198 /* Get the string name of a CMPIStatus return code. */
199 const char * _CMPIrcName ( CMPIrc rc )
200 {
201 switch (rc) {
202 case CMPI_RC_OK: return "CMPI_RC_OK";
203 case CMPI_RC_ERR_FAILED: return "CMPI_RC_ERR_FAILED";
204 case CMPI_RC_ERR_ACCESS_DENIED: return "CMPI_RC_ERR_ACCESS_DENIED";
205 case CMPI_RC_ERR_INVALID_NAMESPACE: return "CMPI_RC_ERR_INVALID_NAMESPACE";
206 case CMPI_RC_ERR_INVALID_PARAMETER: return "CMPI_RC_ERR_INVALID_PARAMETER";
207 case CMPI_RC_ERR_INVALID_CLASS: return "CMPI_RC_ERR_INVALID_CLASS";
208 case CMPI_RC_ERR_NOT_FOUND: return "CMPI_RC_ERR_NOT_FOUND";
209 case CMPI_RC_ERR_NOT_SUPPORTED: return "CMPI_RC_ERR_NOT_SUPPORTED";
210 case CMPI_RC_ERR_CLASS_HAS_CHILDREN: return "CMPI_RC_ERR_CLASS_HAS_CHILDREN";
211 case CMPI_RC_ERR_CLASS_HAS_INSTANCES: return "CMPI_RC_ERR_CLASS_HAS_INSTANCES";
212 case CMPI_RC_ERR_INVALID_SUPERCLASS: return "CMPI_RC_ERR_INVALID_SUPERCLASS";
213 case CMPI_RC_ERR_ALREADY_EXISTS: return "CMPI_RC_ERR_ALREADY_EXISTS";
214 case CMPI_RC_ERR_NO_SUCH_PROPERTY: return "CMPI_RC_ERR_NO_SUCH_PROPERTY";
215 case CMPI_RC_ERR_TYPE_MISMATCH: return "CMPI_RC_ERR_TYPE_MISMATCH";
216 case CMPI_RC_ERR_QUERY_LANGUAGE_NOT_SUPPORTED: return "CMPI_RC_ERR_QUERY_LANGUAGE_NOT_SUPPORTED";
217 case CMPI_RC_ERR_INVALID_QUERY: return "CMPI_RC_ERR_INVALID_QUERY";
218 case CMPI_RC_ERR_METHOD_NOT_AVAILABLE: return "CMPI_RC_ERR_METHOD_NOT_AVAILABLE";
219 case CMPI_RC_ERR_METHOD_NOT_FOUND: return "CMPI_RC_ERR_METHOD_NOT_FOUND";
220 // case CMPI_RC_DO_NOT_UNLOAD: return "CMPI_RC_DO_NOT_UNLOAD";
221 // case CMPI_RC_NEVER_UNLOAD: return "CMPI_RC_NEVER_UNLOAD";
222 // case CMPI_RC_ERR_INVALID_HANDLE: return "CMPI_RC_ERR_INVALID_HANDLE";
223 // case CMPI_RC_ERR_INVALID_DATA_TYPE: return "CMPI_RC_ERR_INVALID_DATA_TYPE";
224 case CMPI_RC_ERROR_SYSTEM: return "CMPI_RC_ERROR_SYSTEM";
225 case CMPI_RC_ERROR: return "CMPI_RC_ERROR";
227 default: return "UNKNOWN";
228 }
229 }
231 /* ------------------------------------------------------------------------- */
233 /* Get the string name of a CMPIType identifier. */
234 const char * _CMPITypeName ( CMPIType type )
235 {
236 switch(type) {
237 case CMPI_null: return "CMPI_null";
238 case CMPI_boolean: return "CMPI_boolean";
239 case CMPI_char16: return "CMPI_char16";
240 case CMPI_real32: return "CMPI_real32";
241 case CMPI_real64: return "CMPI_real64";
242 case CMPI_uint8: return "CMPI_uint8";
243 case CMPI_uint16: return "CMPI_uint16";
244 case CMPI_uint32: return "CMPI_uint32";
245 case CMPI_uint64: return "CMPI_uint64";
246 case CMPI_sint8: return "CMPI_sint8";
247 case CMPI_sint16: return "CMPI_sint16";
248 case CMPI_sint32: return "CMPI_sint32";
249 case CMPI_sint64: return "CMPI_sint64";
250 case CMPI_instance: return "CMPI_instance";
251 case CMPI_ref: return "CMPI_ref";
252 case CMPI_args: return "CMPI_args";
253 case CMPI_class: return "CMPI_class";
254 case CMPI_filter: return "CMPI_filter";
255 case CMPI_enumeration: return "CMPI_enumeration";
256 case CMPI_string: return "CMPI_string";
257 case CMPI_chars: return "CMPI_chars";
258 case CMPI_dateTime: return "CMPI_dateTime";
259 case CMPI_ptr: return "CMPI_ptr";
260 case CMPI_charsptr: return "CMPI_charsptr";
261 case CMPI_ARRAY: return "CMPI_ARRAY";
263 default: return "UNKNOWN";
264 }
265 }
267 /* ------------------------------------------------------------------------- */
269 /* Get a string representation of a CMPIData value. */
270 /* Note - the caller *MUST* free this string when they done with it. */
271 char * _CMPIValueToString ( CMPIData data )
272 {
273 char * valuestring = NULL;
274 int len;
276 /* First make sure there is a value. */
277 if (CMIsNullValue(data)) return NULL;
279 /* Format the value string as appropriate for the value type. */
280 switch(data.type) {
281 case CMPI_char16: {
282 len = 2 * sizeof(char);
283 valuestring = (char *)malloc(len);
284 if (valuestring == NULL) return NULL;
285 snprintf(valuestring, len, "%c", data.value.char16);
286 return valuestring;
287 }
288 case CMPI_sint8: {
289 len = 5 * sizeof(char);
290 valuestring = (char *)malloc(len);
291 if (valuestring == NULL) return NULL;
292 snprintf(valuestring, len, "%d", data.value.sint8);
293 return valuestring;
294 }
295 case CMPI_uint8: {
296 len = 4 * sizeof(char);
297 valuestring = (char *)malloc(len);
298 if (valuestring == NULL) return NULL;
299 snprintf(valuestring, len, "%u", data.value.uint8);
300 return valuestring;
301 }
302 case CMPI_sint16: {
303 len = 7 * sizeof(char);
304 valuestring = (char *)malloc(len);
305 if (valuestring == NULL) return NULL;
306 snprintf(valuestring, len, "%d", data.value.sint16);
307 return valuestring;
308 }
309 case CMPI_uint16: {
310 len = 6 * sizeof(char);
311 valuestring = (char *)malloc(len);
312 if (valuestring == NULL) return NULL;
313 snprintf(valuestring, len, "%u", data.value.uint16);
314 return valuestring;
315 }
316 case CMPI_sint32: {
317 len = 12 * sizeof(char);
318 valuestring = (char *)malloc(len);
319 if (valuestring == NULL) return NULL;
320 snprintf(valuestring, len, "%d", data.value.sint32);
321 return valuestring;
322 }
323 case CMPI_uint32: {
324 len = 11 * sizeof(char);
325 valuestring = (char *)malloc(len);
326 if (valuestring == NULL) return NULL;
327 snprintf(valuestring, len, "%u", data.value.uint32);
328 return valuestring;
329 }
330 case CMPI_sint64: {
331 len = 21 * sizeof(char);
332 valuestring = (char *)malloc(len);
333 if (valuestring == NULL) return NULL;
334 snprintf(valuestring, len, "%d", data.value.sint64);
335 return valuestring;
336 }
337 case CMPI_uint64: {
338 len = 20 * sizeof(char);
339 valuestring = (char *)malloc(len);
340 if (valuestring == NULL) return NULL;
341 snprintf(valuestring, len, "%u", data.value.uint64);
342 return valuestring;
343 }
344 case CMPI_string: {
345 if (CMIsNullObject(data.value.string)) return NULL;
346 char * str = CMGetCharPtr(data.value.string);
347 if (str == NULL) return NULL;
348 valuestring = (char *)strdup(str);
349 return valuestring;
350 }
351 case CMPI_boolean: {
352 len = 6 * sizeof(char);
353 valuestring = (char *)malloc(len);
354 if (valuestring == NULL) return NULL;
355 snprintf(valuestring, len, "%s", (data.value.boolean)? "TRUE":"FALSE");
356 return valuestring;
357 }
358 case CMPI_real32: {
359 len = 20 * sizeof(char);
360 valuestring = (char *)malloc(len);
361 if (valuestring == NULL) return NULL;
362 snprintf(valuestring, len, "%.16e", data.value.real32);
363 return valuestring;
364 }
365 case CMPI_real64: {
366 len = 36 * sizeof(char);
367 valuestring = (char *)malloc(len);
368 if (valuestring == NULL) return NULL;
369 snprintf(valuestring, len, "%.32e", data.value.real64);
370 return valuestring;
371 }
372 case CMPI_dateTime: {
373 CMPIStatus status = {CMPI_RC_OK, NULL};
374 if (CMIsNullObject(data.value.dateTime)) return NULL;
376 /* Get the string representation of CMPI_dateTime value. */
377 CMPIString * datetimestr = CMGetStringFormat(data.value.dateTime, &status);
378 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(datetimestr)) return NULL;
379 valuestring = (char *)strdup(CMGetCharPtr(datetimestr));
380 return valuestring;
381 }
383 default:
384 return NULL;
385 }
386 }
389 /*
390 * Return the 'system' component of InstanceID property values.
391 * The system name will be returned in buffer buf of buf_len.
392 * Syntax of id parameter
393 * Xen:<domain name>[:<device name>]
394 */
395 char * _CMPIStrncpySystemNameFromID(char *buf, const char *id, size_t buf_len)
396 {
397 char *begin;
398 char *end;
399 char *tmp = strdup(id);
401 if (tmp == NULL)
402 return NULL;
404 if ((begin = strchr(tmp, ':')) == NULL) {
405 free(tmp);
406 return NULL;
407 }
408 begin++;
410 if ((end = strrchr(begin, ':')))
411 *end = '\0';
413 if (strlen(begin) >= buf_len) {
414 free(tmp);
415 return NULL;
416 }
418 strncpy(buf, begin, buf_len);
419 free(tmp);
420 return buf;
421 }
424 /*
425 * Return the 'device name' component of InstanceID property values.
426 * The device name be returned in buffer buf of buf_len.
427 * Syntax of id parameter
428 * Xen:<domain name>[:<device name>]
429 */
430 char * _CMPIStrncpyDeviceNameFromID(char *buf, const char *id, size_t buf_len)
431 {
432 char *dev_name;
434 if (id == NULL)
435 return NULL;
437 if ((dev_name = strrchr(id, ':')) == NULL)
438 return NULL;
440 /* Ensure we don't have an InstanceId of form "Xen:<domain name>" */
441 char *p = strchr(id, ':');
442 if (p == dev_name)
443 return NULL;
445 dev_name++;
447 if (strlen(dev_name) >= buf_len)
448 return NULL;
450 strncpy(buf, dev_name, buf_len);
451 return buf;
452 }