1 /*
2 * Copyright 1999-2006 University of Chicago
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "globus_service_engine.h"
18 #include "globus_service_registry.h"
19 #include "globus_wsrf_core_tools.h"
20 #include "globus_i_wsrf_core_tools.h"
21 #include "version.h"
22 #include "libxml/uri.h"
23 #include "globus_wsrf_resource.h"
24 #include "globus_error_string.h"
25 #include "wsbf_DescriptionType.h"
26 #include "globus_ws_addressing.h"
27 #include "globus_wsrf_core_tools.h"
28 #include "libxml/xmlschemastypes.h"
29 #include "wsa_EndpointReference.h"
30 #include "xpath_TargetedXPathQueryType.h"
31 #include "xpath_TargetedXPathQuery.h"
32
33
34 /**
35 * @mainpage Globus WSRF Core Tools
36 *
37 * The Globus WSRF Core Tools package consists of C libraries and programs for
38 * accessing and manipulating WSRF resources. The library consists of functions
39 * for manipulating EndpointReferences, performing conversions on some core
40 * wsrf and xml types, and for parsing some standard command-line options for
41 * WSRF client programs.
42 *
43 * This module uses standard Globus module activation and deactivation.
44 *
45 * Before any functions in this module can be called, the
46 * GLOBUS_WSRF_CORE_TOOLS_MODULE module descriptor must be activated.
47 *
48 * <code>
49 * globus_module_activate(GLOBUS_WSRF_CORE_TOOLS_MODULE);
50 * </code>
51 *
52 * This function returns GLOBUS_SUCCESS if the module was
53 * successfully initialized, and you are therefore allowed to call
54 * functions implemented in it. Otherwise, an error code is returned, and
55 * functions from this module should not be subsequently called. This function
56 * may be called multiple times.
57 *
58 * To deactivate this module, the following must be called:
59 *
60 * <code>
61 * globus_module_deactivate(GLOBUS_WSRF_CORE_TOOLS_MODULE);
62 * </code>
63 *
64 * This function should be called once for each time the module was activated.
65 */
66
67 /**
68 * @defgroup globus_wsrf_core_epr EndpointReferenceType Manipulation
69 * EndpointReferenceType constructors and manipulators.
70 */
71
72 /**
73 * @defgroup globus_wsrf_core_types WSRF Core Type Processing
74 * Functions to perform conversions on some core wsrf and xml types.
75 */
76
77 /**
78 * @defgroup globus_wsrf_core_resource WSRF Resource Access
79 * Functions to access WSRF resources
80 */
81 static
82 int
83 globus_l_wsrf_core_tools_activate(void);
84
85 static
86 int
87 globus_l_wsrf_core_tools_deactivate(void);
88
89 globus_module_descriptor_t globus_l_wsrf_core_tools_module =
90 {
91 "globus_wsrf_core_tools_module",
92 globus_l_wsrf_core_tools_activate,
93 globus_l_wsrf_core_tools_deactivate,
94 NULL,
95 NULL,
96 &local_version
97 };
98
99 0 GlobusDebugDefine(GLOBUS_WSRF_CORE_TOOLS);
100
101 static
102 int
103 globus_l_wsrf_core_tools_activate(void)
104 568 {
105 568 int rc = 0;
106 GlobusFuncName(globus_l_wsrf_core_tools_activate);
107
108 568 rc = globus_module_activate(GLOBUS_COMMON_MODULE);
109 568 if(rc != GLOBUS_SUCCESS)
110 {
111 0 goto error_exit;
112 }
113
114 568 GlobusDebugInit(GLOBUS_WSRF_CORE_TOOLS, DEBUG INFO TRACE WARN ERROR);
115 568 GlobusWSRFCoreToolsDebugEnter();
116
117 568 rc = globus_module_activate(GLOBUS_SOAP_MESSAGE_MODULE);
118 568 if(rc != GLOBUS_SUCCESS)
119 {
120 0 goto deactivate_common_exit;
121 }
122 568 rc = globus_module_activate(GLOBUS_SERVICE_ENGINE_MODULE);
123 568 if (rc != GLOBUS_SUCCESS)
124 {
125 0 goto deactivate_message_exit;
126 }
127
128 568 rc = globus_xsd_type_registry_insert(
129 GLOBUS_GLOBAL_TYPE_REGISTRY,
130 &xpath_TargetedXPathQueryType_info,
131 NULL);
132 568 if (rc != GLOBUS_SUCCESS)
133 {
134 0 goto deactivate_engine_exit;
135 }
136
137 568 rc = globus_xsd_type_registry_insert_element(
138 GLOBUS_GLOBAL_TYPE_REGISTRY,
139 &xpath_TargetedXPathQuery_qname,
140 xpath_TargetedXPathQueryType_info.type);
141
142 568 if (rc != GLOBUS_SUCCESS)
143 {
144 0 globus_xsd_type_registry_remove(
145 GLOBUS_GLOBAL_TYPE_REGISTRY,
146 xpath_TargetedXPathQueryType_info.type,
147 NULL);
148 0 deactivate_engine_exit:
149 0 globus_module_deactivate(GLOBUS_SERVICE_ENGINE_MODULE);
150 0 deactivate_message_exit:
151 0 globus_module_deactivate(GLOBUS_SOAP_MESSAGE_MODULE);
152 0 deactivate_common_exit:
153 0 globus_module_deactivate(GLOBUS_COMMON_MODULE);
154 0 error_exit:
155 0 GlobusWSRFCoreToolsDebugExit();
156 0 GlobusDebugDestroy(GLOBUS_WSRF_CORE_TOOLS);
157 0 return rc;
158 }
159
160 568 GlobusWSRFCoreToolsDebugExit();
161 568 return rc;
162 }
163 /* globus_l_wsrf_core_tools_activate() */
164
165 static
166 int
167 globus_l_wsrf_core_tools_deactivate(void)
168 294 {
169 294 int rc = 0;
170 GlobusFuncName(globus_l_wsrf_core_tools_deactivate);
171 294 GlobusWSRFCoreToolsDebugEnter();
172
173 294 globus_xsd_type_registry_remove_element(
174 GLOBUS_GLOBAL_TYPE_REGISTRY,
175 &xpath_TargetedXPathQuery_qname);
176
177 294 globus_xsd_type_registry_remove(
178 GLOBUS_GLOBAL_TYPE_REGISTRY,
179 xpath_TargetedXPathQueryType_info.type,
180 NULL);
181
182 294 globus_module_deactivate(GLOBUS_SOAP_MESSAGE_MODULE);
183 294 globus_module_activate(GLOBUS_SERVICE_ENGINE_MODULE);
184 294 GlobusWSRFCoreToolsDebugExit();
185 294 GlobusDebugDestroy(GLOBUS_WSRF_CORE_TOOLS);
186 294 globus_module_deactivate(GLOBUS_COMMON_MODULE);
187
188 294 return rc;
189 }
190 /* globus_l_wsrf_core_tools_deactivate() */
191
192 /**
193 * Construct an EndpointReference.
194 * @ingroup globus_wsrf_core_epr
195 *
196 * Construct an EndpointReference from a collection of information about the
197 * current processing context.
198 *
199 * @param engine
200 * An engine which is servicing this resource. The engine is used to determine the
201 * base part of the address used in the EPR.
202 * @param path
203 * The service's path which must be passed to the engine when operating on
204 * this service.
205 * @param resource_id
206 * The element containing the resource-specific ReferenceParameters. If this
207 * is non-null, then the any will be moved to the resulting EPR and its original
208 * values will be destroyed. If this is null, no ReferenceParameters will
209 * be associated with the EPR.
210 * @param endpoint_reference
211 * A new EndpointReference which will be populated
212 *
213 * @retval GLOBUS_SUCCESS
214 * The new endpoint reference was created successfully.
215 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_NULL_PARAMETER
216 * Could not create new endpoint reference because @a engine, @a path, or
217 * @a endpoint_reference was NULL.
218 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
219 * Could not create new endpoint reference because of a lack of available memory.
220 */
221 globus_result_t
222 globus_wsrf_core_create_endpoint_reference(
223 globus_service_engine_t engine,
224 const char * path,
225 xsd_any * * resource_id,
226 wsa_EndpointReferenceType * endpoint_reference)
227 307 {
228 307 globus_result_t result = GLOBUS_SUCCESS;
229 xsd_any * new_rp;
230 char * contact;
231 GlobusFuncName(globus_wsrf_core_create_endpoint_reference);
232 307 GlobusWSRFCoreToolsDebugEnter();
233
234 307 if (engine == NULL || path == NULL || endpoint_reference == NULL)
235 {
236 0 result = GlobusSoapMessageErrorNullParam;
237
238 0 goto out;
239 }
240 307 result = globus_service_engine_get_contact(engine, &contact);
241 307 if (result != GLOBUS_SUCCESS)
242 {
243 0 goto out;
244 }
245
246 307 result = wsa_EndpointReferenceType_init_contents(endpoint_reference);
247 307 if (result != GLOBUS_SUCCESS)
248 {
249 0 goto free_contact_out;
250 }
251
252 307 endpoint_reference->Address.base_value =
253 globus_common_create_string("%s%s",
254 contact,
255 path);
256
257 307 if (endpoint_reference->Address.base_value == NULL)
258 {
259 0 result = GlobusSoapMessageErrorOutOfMemory;
260 0 goto free_contact_out;
261 }
262
263 307 if (resource_id != NULL)
264 {
265 307 result = wsa_ReferenceParametersType_init(
266 &endpoint_reference->ReferenceParameters);
267 307 if (result != GLOBUS_SUCCESS)
268 {
269 0 goto destroy_epr_contents_out;
270 }
271
272 307 new_rp =
273 xsd_any_array_push(&endpoint_reference->ReferenceParameters->any);
274
275 307 if (new_rp == NULL)
276 {
277 0 result = GlobusSoapMessageErrorOutOfMemory;
278 0 goto destroy_epr_contents_out;
279 }
280
281 307 new_rp->value = (*resource_id)->value;
282 307 new_rp->element = (*resource_id)->element;
283 307 new_rp->any_info = (*resource_id)->any_info;
284
285 307 (*resource_id)->value = NULL;
286 307 (*resource_id)->element = NULL;
287 307 xsd_any_destroy(*resource_id);
288
289 307 *resource_id = NULL;
290 }
291
292 307 destroy_epr_contents_out:
293 307 if (result != GLOBUS_SUCCESS)
294 {
295 0 wsa_EndpointReferenceType_destroy_contents(endpoint_reference);
296 }
297 307 free_contact_out:
298 307 globus_free(contact);
299 307 out:
300 307 GlobusWSRFCoreToolsDebugExit();
301 307 return result;
302 }
303 /* globus_wsrf_core_create_endpoint_reference() */
304
305 /**
306 * Obtain a resource handle from a message handle and service descriptor.
307 * @ingroup globus_wsrf_core_resource
308 *
309 * Looks up the resource which is associated with the EndpointReference used in
310 * the addressing headers on the current message.
311 *
312 * @param message
313 * Message handle which the operation request arrived on.
314 * @param service
315 * Service handle for the service which is processing the operation.
316 * @param resource
317 * Pointer to a WSRF resource handle which will be set to the resource
318 * associated with the SOAP message EPR. This must be released by calling
319 * globus_resource_finish()
320 *
321 * @retval GLOBUS_SUCCESS
322 * Resource successfully located.
323 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
324 * Unable to locate the resource because of a lack of available memory.
325 * @retval GLOBUS_WSRF_CORE_TOOLS_ERROR_TYPE_GET_RESOURCE_FAILED
326 * Unable to locate the resource because the EPR could not be determined, or the
327 * resource ID does not map to a valid resource.
328 */
329 globus_result_t
330 globus_wsrf_core_get_resource(
331 globus_soap_message_handle_t message,
332 globus_service_descriptor_t * service,
333 globus_resource_t * resource)
334 10493 {
335 10493 globus_result_t result = GLOBUS_SUCCESS;
336 10493 char * id = NULL;
337 wsa_EndpointReferenceType * epr;
338 GlobusFuncName(globus_wsrf_core_get_resource_id);
339 10493 GlobusWSRFCoreToolsDebugEnter();
340
341 10493 if (message == NULL || service == NULL || resource == NULL)
342 {
343 0 result = GlobusSoapMessageErrorOutOfMemory;
344 0 goto exit;
345 }
346 10493 epr = globus_soap_message_handle_get_attr(
347 message,
348 WSADDR_EPR_KEY);
349 10493 if(!epr)
350 {
351 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
352 GLOBUS_SUCCESS,
353 "No EndpointReference found "
354 "in message properties");
355 0 goto exit;
356 }
357
358 10493 result = service->get_resource_id(&epr->ReferenceParameters->any, &id);
359 10493 if(result != GLOBUS_SUCCESS)
360 {
361 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
362 result, "Failed to get resource id from ReferenceParameters");
363 0 goto exit;
364 }
365
366 10493 result = globus_resource_find(id, resource);
367 10493 if(result != GLOBUS_SUCCESS)
368 {
369 3 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
370 result, "No resource found in resource registry");
371 3 goto exit;
372 }
373
374 10493 exit:
375
376 10493 if(id)
377 {
378 10493 free(id);
379 }
380
381 10493 GlobusWSRFCoreToolsDebugExit();
382 10493 return result;
383 }
384 /* globus_wsrf_core_get_resource() */
385
386 /**
387 * Obtain a resource handle from an EPR
388 * @ingroup globus_wsrf_core_resource
389 *
390 * Looks up the resource associated with an EPR.
391 *
392 * @param epr
393 * Endpoint reference to look up.
394 * @param resource
395 * Pointer to a WSRF resource handle which will be set to the resource
396 * associated with the EPR. This must be released by calling
397 * globus_resource_finish()
398 *
399 * @retval GLOBUS_SUCCESS
400 * Resource successfully located.
401 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
402 * Unable to locate the resource because of a lack of available memory.
403 * @retval GLOBUS_WSRF_CORE_TOOLS_ERROR_TYPE_GET_RESOURCE_FAILED
404 * Unable to locate the resource because the EPR could not be determined, or the
405 * resource ID does not map to a valid resource.
406 */
407 globus_result_t
408 globus_wsrf_core_get_resource_from_epr(
409 const wsa_EndpointReferenceType * epr,
410 globus_resource_t * resource)
411 441 {
412 441 xmlURIPtr uri = NULL;
413 441 char * base_path = NULL;
414 441 char * service_module_path = NULL;
415 globus_extension_handle_t ext;
416 441 globus_service_descriptor_t * service = NULL;
417 441 char * id = NULL;
418 441 globus_result_t result = GLOBUS_SUCCESS;
419 GlobusFuncName(globus_wsrf_core_get_resource_from_epr);
420 441 GlobusWSRFCoreToolsDebugEnter();
421
422 441 if (epr == NULL || resource == NULL)
423 {
424 0 result = GlobusSoapMessageErrorOutOfMemory;
425
426 0 goto exit;
427 }
428 441 *resource = NULL;
429
430 441 if (epr->Address.base_value == NULL)
431 {
432 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
433 GLOBUS_SUCCESS, "Invalid EPR");
434
435 0 goto exit;
436 }
437
438 441 uri = xmlParseURI(epr->Address.base_value);
439 441 if(!uri)
440 {
441 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
442 GLOBUS_SUCCESS, "Failed to parse EPR Address");
443 0 goto exit;
444 }
445
446 441 base_path = (char *) uri->path;
447 1368 while(*base_path == '/')
448 {
449 486 base_path++;
450 }
451
452 441 service_module_path = globus_common_create_string(
453 GLOBUS_SERVICE_ENGINE_MODULE_PATH_PREFIX "/%s",
454 base_path);
455 441 if (service_module_path == NULL)
456 {
457 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
458 GLOBUS_SUCCESS, "Failed to parse EPR Address");
459 0 goto exit;
460 }
461 441 GlobusWSRFCoreToolsDebugPrintf(GLOBUS_L_WSRF_CORE_TOOLS_DEBUG_DEBUG,
462 ("Path for service module is `%s'\n", service_module_path));
463
464 441 service = globus_extension_lookup(
465 &ext, GLOBUS_SERVICE_REGISTRY, service_module_path);
466 441 if(!service)
467 {
468 6 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
469 result, "Failed to get service descriptor from EPR Address");
470 6 goto exit;
471 }
472
473 435 result = service->get_resource_id(&epr->ReferenceParameters->any, &id);
474 435 if(result != GLOBUS_SUCCESS)
475 {
476 0 globus_extension_release(ext);
477 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
478 result, "Failed to get resource id from ReferenceParameters");
479 0 goto exit;
480 }
481
482 435 globus_extension_release(ext);
483
484 435 result = globus_resource_find(id, resource);
485 435 if(result != GLOBUS_SUCCESS)
486 {
487 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
488 result, "No resource found in resource registry");
489 0 goto exit;
490 }
491
492 441 exit:
493 441 if(service_module_path)
494 {
495 441 globus_libc_free(service_module_path);
496 }
497
498 441 if(uri)
499 {
500 441 xmlFreeURI(uri);
501 }
502
503 441 if(id)
504 {
505 435 free(id);
506 }
507
508 441 if (result != GLOBUS_SUCCESS)
509 {
510 6 GlobusWSRFCoreToolsDebugError(result);
511 }
512
513 441 GlobusWSRFCoreToolsDebugExit();
514 441 return result;
515 }
516 /* globus_wsrf_core_get_resource_from_epr() */
517
518 /**
519 * Convert an endpoint reference into a service-specific resource identifier
520 * @ingroup globus_wsrf_core_resource
521 * Uses the service descriptor for the service named by the EPR to convert
522 * the endpoint reference into a resource identifier string, suitable for use
523 * by globus_resource_find().
524 *
525 * @param epr
526 * Endpoint reference to convert.
527 * @param resource_id
528 * Pointer to a string. The pointer will be set to point to a newly
529 * allocated string containing the resource's ID. The caller must free this
530 * string.
531 *
532 * @retval GLOBUS_SUCCESS
533 * Resource ID created successfully.
534 * @retval GLOBUS_WSRF_CORE_TOOLS_ERROR_GET_RESOURCE_FAILED
535 * Unable to convert EPR.
536 */
537 globus_result_t
538 globus_wsrf_core_get_resource_id_from_epr(
539 const wsa_EndpointReferenceType * epr,
540 char ** resource_id)
541 862 {
542 862 xmlURIPtr uri = NULL;
543 862 char * base_path = NULL;
544 862 char * service_module_path = NULL;
545 globus_extension_handle_t ext;
546 862 globus_service_descriptor_t * service = NULL;
547 862 char * id = NULL;
548 862 globus_result_t result = GLOBUS_SUCCESS;
549 GlobusFuncName(globus_wsrf_core_get_resource_from_epr);
550 862 GlobusWSRFCoreToolsDebugEnter();
551
552 862 if (epr == NULL || epr->Address.base_value == NULL || resource_id == NULL)
553 {
554 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
555 GLOBUS_SUCCESS, "Null parameter");
556
557 0 goto exit;
558 }
559
560 862 uri = xmlParseURI(epr->Address.base_value);
561 862 if(!uri)
562 {
563 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
564 GLOBUS_SUCCESS, "Failed to parse EPR Address");
565 0 goto exit;
566 }
567
568 862 base_path = (char *) uri->path;
569 2631 while(*base_path == '/')
570 {
571 907 base_path++;
572 }
573
574 862 service_module_path = globus_common_create_string(
575 GLOBUS_SERVICE_ENGINE_MODULE_PATH_PREFIX "/%s",
576 base_path);
577
578 862 if (service_module_path == NULL)
579 {
580 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
581 GLOBUS_SUCCESS, "Failed to parse EPR Address");
582 0 goto exit;
583 }
584
585 862 service = globus_extension_lookup(
586 &ext, GLOBUS_SERVICE_REGISTRY, service_module_path);
587 862 if(!service)
588 {
589 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
590 result, "Failed to get service descriptor from EPR Address");
591 0 goto exit;
592 }
593
594 862 result = service->get_resource_id(&epr->ReferenceParameters->any, &id);
595 862 if(result != GLOBUS_SUCCESS)
596 {
597 0 globus_extension_release(ext);
598 0 result = GlobusWSRFCoreToolsErrorGetResourceFailed(
599 result, "Failed to get resource id from ReferenceParameters");
600 0 goto exit;
601 }
602
603 862 globus_extension_release(ext);
604
605 862 *resource_id = id;
606 862 id = NULL;
607
608 862 exit:
609 862 if(service_module_path)
610 {
611 862 globus_libc_free(service_module_path);
612 }
613
614 862 if(uri)
615 {
616 862 xmlFreeURI(uri);
617 }
618
619 862 if(id)
620 {
621 0 free(id);
622 }
623
624 862 GlobusWSRFCoreToolsDebugExit();
625 862 return result;
626 }
627 /* globus_wsrf_core_get_resource_id_from_epr() */
628
629 /**
630 * Convert an xsd_dateTime value into a string
631 * @ingroup globus_wsrf_core_types
632 * Allocates and returns a string containing the value of an xsd_dateTime.
633 * The caller is responsible for freeing this value.
634 *
635 * @param val
636 * The xsd_dateTime value to conver to a string.
637 */
638 char *
639 globus_wsrf_core_export_timestamp(
640 xsd_dateTime * val)
641 0 {
642 0 if (val == NULL)
643 {
644 0 return NULL;
645 }
646 0 return globus_common_create_string(
647 "%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ",
648 val->tm_year + 1900,
649 val->tm_mon + 1,
650 val->tm_mday,
651 val->tm_hour,
652 val->tm_min,
653 val->tm_sec);
654 }
655 /* globus_wsrf_core_export_timestamp() */
656
657 /**
658 * Convert a string into an xsd_dateTime value
659 * @ingroup globus_wsrf_core_types
660 * Allocates and returns a pointer to a xsd_dateTime structure containing the
661 * dateTime value in @a timesttamp_string. The caller must destroy the returned
662 * xsd_dateTime structure.
663 *
664 * @param timestamp_string
665 * The dateTime value string to convert.
666 */
667 xsd_dateTime *
668 globus_wsrf_core_import_timestamp(
669 const char * timestamp_string)
670 0 {
671 globus_result_t result;
672 0 xsd_dateTime * val = NULL;
673 0 xmlSchemaValPtr schema_val = NULL;
674 0 xmlChar * tmp_value = NULL;
675 0 int res = 0;
676
677 0 if (timestamp_string == NULL)
678 {
679 0 return NULL;
680 }
681 0 result = xsd_dateTime_init(&val);
682
683 0 if (result != GLOBUS_SUCCESS)
684 {
685 0 return NULL;
686 }
687
688 0 res = xmlSchemaValidatePredefinedType(
689 xmlSchemaGetBuiltInType(XML_SCHEMAS_DATETIME),
690 tmp_value,
691 &schema_val);
692 0 if(res != 0)
693 {
694 0 xsd_dateTime_destroy(val);
695 0 return NULL;
696 }
697
698 0 val->tm_year = schema_val->value.date.year - 1900;
699 0 val->tm_mon = schema_val->value.date.mon;
700 0 val->tm_mday = schema_val->value.date.day;
701 0 val->tm_hour = schema_val->value.date.hour;
702 0 val->tm_min = schema_val->value.date.min;
703 0 val->tm_sec = schema_val->value.date.sec;
704 0 if(schema_val->value.date.tz_flag)
705 {
706 0 val->tm_min += schema_val->value.date.tzo;
707 }
708
709 0 xmlSchemaFreeValue(schema_val);
710
711 0 return val;
712 }
713 /* globus_wsrf_core_import_timestamp() */
714
715 /**
716 * Convert a WSRF base fault into a globus_object_t error
717 * @ingroup globus_wsrf_core_types
718 * Converts the given fault to an error object which can be handled by
719 * the globus_object_t system and converted to a globus_result_t. The
720 * caller must free the resulting object by calling globus_object_free().
721 *
722 * @param fault
723 * Fault value to convert.
724 *
725 * @return
726 * Returns the new object. If an error occurs or there is no
727 * fault information, NULL will be returned.
728 */
729 globus_object_t *
730 globus_error_convert_wsrf_fault(
731 const wsbf_BaseFaultType * fault)
732 0 {
733 globus_object_t * cause;
734 0 char * description = NULL;
735 char ** array;
736
737 0 if (fault == NULL)
738 {
739 0 return NULL;
740 }
741 0 if(fault->FaultCause == NULL ||
742 fault->FaultCause->any.any_info == &globus_xml_buffer_info)
743 {
744 0 cause = NULL;
745 }
746 else
747 {
748 0 cause = globus_error_convert_wsrf_fault(fault->FaultCause->any.value);
749 }
750
751 0 array = (char **) globus_malloc(
752 sizeof(char *) * fault->Description.length * 2);
753 0 if(array)
754 {
755 int i;
756 0 int j = 0;
757
758 0 for(i = 0; i < fault->Description.length; i++)
759 {
760 0 if(i > 0)
761 {
762 0 array[j++] = "\n";
763 }
764 0 array[j++] = fault->Description.elements[i].base_value;
765 }
766
767 0 description = globus_libc_join((const char **)array, j);
768 0 globus_free(array);
769 }
770
771 0 return globus_error_construct_string(NULL, cause, "%s", description);
772 }
773 /* globus_error_convert_wsrf_fault() */
774
775 /**
776 * Write an EPR to a file
777 * @ingroup globus_wsrf_core_epr
778 * Serializes the given endpoint reference to a file.
779 *
780 * @param endpoint_reference
781 * Endpoint Reference to write to the file.
782 * @param filename
783 * File to create and write the endpoint reference value to. The file
784 * will be truncated to 0 before the EPR is written.
785 * @param element
786 * Optional name of the EPR element. If NULL, wsa:EndpointReference will
787 * be used.
788 *
789 * @retval GLOBUS_SUCCESS
790 * EPR written to file successfully.
791 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_NULL_PARAMETER
792 * One of @a endpoint_reference or @a filename is NULL.
793 * @retval GLOBUS_WSRF_CORE_TOOLS_ERROR_TYPE_EXPORT_FAILED
794 * Error serializing the EPR.
795 */
796 globus_result_t
797 globus_wsrf_core_export_endpoint_reference(
798 const wsa_EndpointReferenceType * endpoint_reference,
799 const char * filename,
800 xsd_QName * element)
801 36 {
802 36 globus_result_t result = GLOBUS_SUCCESS;
803 36 xsd_QName * elem = element;
804 GlobusFuncName(globus_wsrf_core_export_endpoint_reference);
805 36 GlobusWSRFCoreToolsDebugEnter();
806
807 36 if (endpoint_reference == NULL || filename == NULL)
808 {
809 0 result = GlobusSoapMessageErrorNullParam;
810
811 0 goto exit;
812 }
813 36 if(!elem)
814 {
815 0 elem = &wsa_EndpointReference_qname;
816 }
817
818 36 GlobusXSDTypeExport(filename,
819 wsa_EndpointReferenceType,
820 endpoint_reference,
821 elem,
822 result);
823
824 36 if(result != GLOBUS_SUCCESS)
825 {
826 0 result = GlobusWSRFCoreToolsErrorExportFailed(result, filename);
827 }
828
829 36 exit:
830 36 GlobusWSRFCoreToolsDebugExit();
831 36 return result;
832 }
833 /* globus_wsrf_core_export_endpoint_reference() */
834
835 /**
836 * Read an EPR from a file
837 * @ingroup globus_wsrf_core_epr
838 * Deserializes an endpoint reference from a file.
839 *
840 * @param filename
841 * File to read the endpoint reference value from.
842 * @param endpoint_reference
843 * Pointer to an area to be allocated and set to the EPR's value.
844 * @param element
845 * Optional name of the EPR element for verification purposes. If not
846 * present, the root element of the document located in @a filename
847 * will be used.
848 *
849 * @retval GLOBUS_SUCCESS
850 * EPR written to file successfully.
851 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_NULL_PARAMETER
852 * One of @a endpoint_reference or @a filename is NULL.
853 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_OUT_OF_MEMORY
854 * Insufficient memory to allocate the new EndpointReference
855 * @retval GLOBUS_WSRF_CORE_TOOLS_ERROR_TYPE_IMPORT_FAILED
856 * Error deserializing the EPR.
857 */
858 globus_result_t
859 globus_wsrf_core_import_endpoint_reference(
860 const char * filename,
861 wsa_EndpointReferenceType ** endpoint_reference,
862 xsd_QName * element)
863 60 {
864 60 globus_result_t result = GLOBUS_SUCCESS;
865 GlobusFuncName(globus_wsrf_core_import_endpoint_reference);
866 60 GlobusWSRFCoreToolsDebugEnter();
867
868 60 if (filename == NULL || endpoint_reference == NULL)
869 {
870 0 result = GlobusSoapMessageErrorNullParam;
871
872 0 goto exit;
873 }
874 60 result = wsa_EndpointReferenceType_init(endpoint_reference);
875 60 if (result != GLOBUS_SUCCESS)
876 {
877 0 goto exit;
878 }
879
880 60 GlobusXSDTypeImport(filename,
881 wsa_EndpointReferenceType,
882 (*endpoint_reference),
883 element,
884 result);
885 60 if(result != GLOBUS_SUCCESS)
886 {
887 0 result = GlobusWSRFCoreToolsErrorImportFailed(result, filename);
888 }
889
890 60 exit:
891 60 GlobusWSRFCoreToolsDebugExit();
892 60 return result;
893 }
894 /* globus_wsrf_core_import_endpoint_reference() */
895
896 /**
897 * Create a fault element
898 * @ingroup globus_wsrf_core_types
899 *
900 * Initializes the @a fault any and adds the fault element named by
901 * @a fault_element to it. The new fault is allocated and its @a Timestamp
902 * field is set.
903 *
904 * @param fault
905 * xsd_any value to hold the fault result.
906 * @param fault_element
907 * Name of the fault element.
908 *
909 * @retval GLOBUS_SUCCESS
910 * Success.
911 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_NULL_PARAM
912 * Invalid parameter.
913 * @retval GLOBUS_SOAP_MESSAGE_ERROR_TYPE_FAILED_REGISTRY_LOOKUP
914 * No fault type known for @a fault_element
915 */
916 globus_result_t
917 globus_wsrf_core_create_fault(
918 xsd_any * fault,
919 const xsd_QName * fault_element)
920 243 {
921 globus_result_t result;
922 243 time_t timestamp = time(NULL);
923 struct tm * tp;
924 243 globus_xsd_type_info_t info = NULL;
925
926 243 if (fault == NULL || fault_element == NULL)
927 {
928 0 result = GlobusSoapMessageErrorNullParam;
929
930 0 goto out;
931 }
932 243 result = xsd_any_init_contents(fault);
933 243 if (result != GLOBUS_SUCCESS)
934 {
935 0 goto out;
936 }
937 243 result = globus_xsd_type_registry_get_element(
938 GLOBUS_GLOBAL_TYPE_REGISTRY,
939 fault_element,
940 &info);
941 243 if (result != GLOBUS_SUCCESS)
942 {
943 0 goto out;
944 }
945 243 else if (info == NULL)
946 {
947 0 result = GlobusSoapMessageErrorFailedRegistryLookup(
948 result,
949 fault_element);
950 0 goto out;
951 }
952 243 result = xsd_QName_copy(&fault->element, fault_element);
953 243 if (result != GLOBUS_SUCCESS)
954 {
955 0 goto out;
956 }
957 243 fault->any_info = info;
958
959 243 result = info->initialize(&fault->value);
960 243 if (result != GLOBUS_SUCCESS)
961 {
962 0 goto free_element_out;
963 }
964
965 243 tp = globus_libc_gmtime_r(
966 &timestamp,
967 &((wsbf_BaseFaultType *)fault->value)->Timestamp);
968 243 globus_assert(tp != NULL);
969
970 243 free_element_out:
971 243 if (result != GLOBUS_SUCCESS)
972 {
973 0 xsd_QName_destroy(fault->element);
974 0 fault->element = NULL;
975 }
976 243 out:
977 243 return result;
978 }
979 /* globus_wsrf_core_create_fault() */
980
981 /**
982 * Append a new any to an xsd_any_array and return a pointer to the new any's value
983 * @ingroup globus_wsrf_core_types
984 *
985 * Adds a new xsd_any to the end of the array passed in the @a any parameter.
986 * The any_info and element_qname fields of the any are initialized with the
987 * respective parameters, and the value field is initialized wth the
988 * @a any_info initialize function pointer. The @a value field is returned in
989 * the @a new_value parameter.
990 *
991 * @param any
992 * Array of xsd:any values to append to.
993 * @param element
994 * QName to use for this element.
995 * @param type_info
996 * Type indicator for this element
997 * @param new_value
998 * Pointer to be set to the newly-allocated any's value.
999 */
1000 globus_result_t
1001 globus_wsrf_core_push_any(
1002 xsd_any_array * any,
1003 const xsd_QName * element,
1004 const globus_xsd_type_info_t type_info,
1005 void ** new_value)
1006 0 {
1007 globus_result_t result;
1008 xsd_any * tmp;
1009
1010 0 if (any == NULL || type_info == NULL)
1011 {
1012 0 result = GlobusSoapMessageErrorNullParam;
1013
1014 0 goto out;
1015 }
1016
1017 0 tmp = xsd_any_array_push(any);
1018 0 if (tmp == NULL)
1019 {
1020 0 result = GlobusSoapMessageErrorOutOfMemory;
1021
1022 0 goto out;
1023 }
1024
1025 0 if (element)
1026 {
1027 0 result = xsd_QName_copy(&tmp->element, element);
1028 0 if (result != GLOBUS_SUCCESS)
1029 {
1030 0 goto free_tmp;
1031 }
1032 }
1033
1034 0 tmp->any_info = type_info;
1035
1036 0 result = type_info->initialize(&tmp->value);
1037 0 if (result != GLOBUS_SUCCESS)
1038 {
1039 0 goto free_tmp;
1040 }
1041
1042 0 if (new_value)
1043 {
1044 0 *new_value = tmp->value;
1045 }
1046
1047 0 free_tmp:
1048 0 if (result != GLOBUS_SUCCESS)
1049 {
1050 0 xsd_any_destroy_contents(tmp);
1051 0 any->length--;
1052 }
1053 0 out:
1054 0 return result;
1055 }
1056 /* globus_wsrf_core_push_any() */
1057
1058 /**
1059 * Remove the named attribute from an xsd:any value
1060 * @ingroup globus_wsrf_core_types
1061 *
1062 * Removes the attribute named by @a attribute from the xml element
1063 * contained in @a any.
1064 *
1065 * @param any
1066 * Element to modify.
1067 * @param attribute
1068 * Attribute QName
1069 */
1070 globus_result_t
1071 globus_wsrf_core_remove_attribute(
1072 xsd_any * any,
1073 xsd_QName * attribute)
1074 10655 {
1075 globus_soap_message_handle_t dom_handle;
1076 xmlDocPtr dom;
1077 globus_result_t result;
1078 xmlNodePtr root;
1079 xmlNsPtr ns;
1080
1081 10655 result = globus_soap_message_handle_init_to_dom(&dom_handle, &dom);
1082 10655 if (result != GLOBUS_SUCCESS)
1083 {
1084 0 goto out;
1085 }
1086
1087 10655 result = xsd_any_serialize(
1088 any->element,
1089 any,
1090 dom_handle,
1091 0);
1092 10655 globus_soap_message_handle_destroy(dom_handle);
1093 10655 if (result != GLOBUS_SUCCESS)
1094 {
1095 0 goto destroy_dom;
1096 }
1097 10655 root = xmlDocGetRootElement(dom);
1098 10655 if (root == NULL)
1099 {
1100 0 goto destroy_dom;
1101 }
1102 10655 ns = xmlSearchNsByHref(dom, root, BAD_CAST attribute->Namespace);
1103 10655 if (ns)
1104 {
1105 10635 xmlUnsetNsProp(root, ns, BAD_CAST attribute->local);
1106
1107 10635 any->any_info->destroy_contents(any->value);
1108
1109 10635 result = globus_soap_message_handle_init_from_dom(&dom_handle, dom);
1110
1111 10635 result = xsd_any_deserialize(
1112 NULL,
1113 any,
1114 dom_handle,
1115 0);
1116 10635 globus_soap_message_handle_destroy(dom_handle);
1117 10635 dom = NULL;
1118 }
1119
1120 10655 destroy_dom:
1121 10655 if (dom != NULL)
1122 {
1123 20 xmlFreeDoc(dom);
1124 }
1125 10655 out:
1126 10655 return result;
1127 }