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
18 #include "globus_common.h"
19 #include "version.h"
20 #include "globus_i_wsdl_config.h"
21
22 #define MAX_LINE_SIZE 1000
23
24 #ifdef WIN32
25 #define FILE_SEPARATOR "\\"
26 #else
27 #define FILE_SEPARATOR "/"
28 #endif
29
30 static int globus_l_wsdl_config_activate();
31 static int globus_l_wsdl_config_deactivate();
32
33 globus_module_descriptor_t globus_i_wsdl_config_module =
34 {
35 "globus_wsdl_config",
36 globus_l_wsdl_config_activate,
37 globus_l_wsdl_config_deactivate,
38 GLOBUS_NULL,
39 GLOBUS_NULL,
40 &local_version
41 };
42
43 0 GlobusDebugDefine(GLOBUS_WSDL_CONFIG);
44
45 static int
46 globus_l_wsdl_config_activate()
47 0 {
48 0 int res = (int) GLOBUS_SUCCESS;
49
50 0 res = (int) globus_module_activate(GLOBUS_COMMON_MODULE);
51 0 GlobusDebugInit(GLOBUS_WSDL_CONFIG, ERROR TRACE INFO);
52 0 return res;
53 }
54
55 static int
56 globus_l_wsdl_config_deactivate()
57 0 {
58 0 globus_result_t result = GLOBUS_SUCCESS;
59 0 globus_module_deactivate(GLOBUS_COMMON_MODULE);
60 0 GlobusDebugDestroy(GLOBUS_WSDL_CONFIG);
61 0 return (int) result;
62 }
63
64 void
65 globus_i_wsdl_config_delete_entry(
66 void * hash_entry)
67 1293 {
68 char ** entry;
69
70 1293 entry = (char **) hash_entry;
71
72 1293 if(entry[0])
73 {
74 1293 free(entry[0]);
75 }
76
77 1293 if(entry[1])
78 {
79 1293 free(entry[1]);
80 }
81
82 1293 free(entry);
83 1293 }
84
85 static
86 const char *
87 my_strpbrk(
88 const char * str,
89 size_t str_length,
90 int * locator_index,
91 const char * delims,
92 int * delim_index);
93
94 char *
95 globus_wsdl_config_get_property(
96 globus_hashtable_t props,
97 const char * key)
98 34404 {
99 char ** entry;
100
101 34404 entry = globus_hashtable_lookup(&props, (void *)key);
102 34404 if(!entry)
103 {
104 176 return NULL;
105 }
106
107 34228 return (char *) entry[1];
108 }
109
110 globus_result_t
111 globus_wsdl_config_set_property(
112 globus_hashtable_t * props,
113 const char * prop_string)
114 511 {
115 511 globus_result_t result = GLOBUS_SUCCESS;
116 511 int res = 0;
117 char * key;
118 char * value;
119 511 char * prop = NULL;
120 char * pos;
121 char * qpos;
122 char * qpos_end;
123 char * delim;
124 int line_length;
125 int index;
126 int delim_index;
127 char ** hash_entry;
128 GlobusFuncName(globus_wsdl_config_set_property);
129 GlobusWSDLConfigDebugEnter();
130
131 511 prop = globus_libc_strdup(prop_string);
132 511 pos = prop;
133 511 line_length = strlen(prop);
134 511 pos = (char *)my_strpbrk(pos, line_length, &index, "=", NULL);
135 511 if(!pos)
136 {
137 0 result = GlobusWSDLConfigErrorNoEqualsProp(prop);
138 0 goto exit;
139 }
140
141 511 *pos = '\0';
142
143 511 key = prop;
144 511 pos++;
145 511 line_length -= (pos - prop);
146 511 qpos = (char *) my_strpbrk(pos, line_length, &index, "\"'", &delim_index);
147 511 if(!qpos)
148 {
149 511 value = pos;
150 }
151 else
152 {
153 0 line_length -= (qpos - pos);
154 0 qpos++;
155 0 if(delim_index == 0)
156 {
157 0 delim = "\"";
158 }
159 else
160 {
161 0 delim = "'";
162 }
163
164 0 qpos_end = (char *) my_strpbrk(qpos, line_length, &index, delim, NULL);
165 0 if(!qpos_end)
166 {
167 0 result = GlobusWSDLConfigErrorNoEndQuoteProp(
168 prop, delim);
169 0 goto exit;
170 }
171 else
172 {
173 0 *qpos_end = '\0';
174 0 value = qpos;
175 }
176 }
177
178 511 hash_entry = globus_malloc(2 * sizeof(char *));
179 511 if(!hash_entry)
180 {
181 0 result = GlobusWSDLConfigErrorOutOfMemory;
182 0 goto exit;
183 }
184
185 511 hash_entry[0] = globus_libc_strdup(key);
186 511 hash_entry[1] = globus_libc_strdup(value);
187
188 511 res = globus_hashtable_insert(
189 props, (void *) hash_entry[0], (void *) hash_entry);
190 511 if(res != GLOBUS_SUCCESS)
191 {
192 0 result = GlobusWSDLConfigErrorHashInsertFailed();
193 0 goto exit;
194 }
195
196 511 exit:
197
198 511 if(prop)
199 {
200 511 free(prop);
201 }
202
203 GlobusWSDLConfigDebugExit();
204 511 return result;
205 }
206
207 void
208 globus_wsdl_config_properties_destroy(
209 globus_hashtable_t props)
210 68 {
211 68 globus_hashtable_destroy_all(&props, globus_i_wsdl_config_delete_entry);
212 68 }
213
214 globus_result_t
215 globus_wsdl_config_properties_init(
216 globus_hashtable_t * props)
217 68 {
218 GlobusFuncName(globus_wsdl_config_properties_init);
219 GlobusWSDLConfigDebugEnter();
220
221 68 globus_hashtable_init(props, 10,
222 globus_hashtable_string_hash,
223 globus_hashtable_string_keyeq);
224 68 globus_assert(props);
225
226 GlobusWSDLConfigDebugExit();
227 68 return GLOBUS_SUCCESS;
228 }
229
230
231 globus_result_t
232 globus_wsdl_config_load_properties(
233 const char * filename,
234 globus_hashtable_t * properties)
235
236 34 {
237 34 globus_result_t result = GLOBUS_SUCCESS;
238 char line[MAX_LINE_SIZE];
239 34 FILE * propstream = NULL;
240 34 int linenum = 0;
241 34 char * key = NULL;
242 34 char * value = NULL;
243 34 char * new_value = NULL;
244 34 size_t new_value_length = 0;
245 34 char ** hash_entry = NULL;
246 GlobusFuncName(globus_wsdl_config_load_properties);
247 GlobusWSDLConfigDebugEnter();
248
249 34 globus_assert_string(properties,
250 "NULL properties parameter passed to function");
251 34 globus_assert_string(filename,
252 "NULL filename passed to function");
253
254 34 propstream = fopen(filename, "r");
255 34 if(!propstream)
256 {
257 0 result = GlobusWSDLConfigErrorFileOpen(filename);
258 0 goto exit;
259 }
260
261 34 memset(line, 0, MAX_LINE_SIZE);
262 850 while(fgets(line, MAX_LINE_SIZE, propstream) != NULL)
263 {
264 size_t line_length;
265 782 char * pos = NULL;
266 782 char * kpos = NULL;
267 782 char * qpos = NULL;
268 782 char * qpos_end = NULL;
269 782 int index = 0;
270 782 int delim_index = 0;
271 782 char * delim = NULL;
272 782 int res = 0;
273
274 782 linenum++;
275 782 line_length = strlen(line);
276
277 782 pos = line;
278
279 1564 while(pos && (*pos == ' '))
280 {
281 0 ++pos;
282 }
283
284 782 if(pos && ((*pos == '#') || (*pos == '\n')))
285 {
286 continue;
287 }
288
289 782 if(line[line_length-1] == '\n')
290 {
291 782 line[line_length-1] = '\0';
292 }
293
294 782 kpos = pos;
295 782 pos = (char *)my_strpbrk(pos, line_length, &index, "=", NULL);
296 782 if(!pos)
297 {
298 0 result = GlobusWSDLConfigErrorNoEquals(filename, linenum);
299 0 goto exit;
300 }
301
302 782 *pos = '\0';
303
304 782 key = globus_libc_strdup(kpos);
305 782 pos++;
306 782 line_length -= (pos - line);
307 782 qpos = (char *) my_strpbrk(pos, line_length, &index, "\"'", &delim_index);
308 782 if(!qpos)
309 {
310 782 value = globus_libc_strdup(pos);
311 }
312 else
313 {
314 0 line_length -= (qpos - pos);
315 0 qpos++;
316 0 if(delim_index == 0)
317 {
318 0 delim = "\"";
319 }
320 else
321 {
322 0 delim = "'";
323 }
324
325 0 qpos_end = (char *) my_strpbrk(qpos, line_length, &index, delim, NULL);
326 0 if(!qpos_end)
327 {
328 0 result = GlobusWSDLConfigErrorNoEndQuote(
329 filename, linenum, delim);
330 0 goto exit;
331 }
332 else
333 {
334 0 *qpos_end = '\0';
335 0 value = globus_libc_strdup(qpos);
336 }
337 }
338
339 782 hash_entry = globus_malloc(2 * sizeof(char *));
340 782 if(!hash_entry)
341 {
342 0 result = GlobusWSDLConfigErrorOutOfMemory;
343 0 goto exit;
344 }
345
346 782 hash_entry[0] = globus_libc_strdup(key);
347 782 hash_entry[1] = globus_libc_strdup(value);
348 782 res = globus_hashtable_insert(
349 properties, (void *) key, (void *) hash_entry);
350 782 if(res != GLOBUS_SUCCESS)
351 {
352 0 result = GlobusWSDLConfigErrorHashInsertFailed();
353 0 goto exit;
354 }
355
356 782 hash_entry = NULL;
357 782 key = NULL;
358 782 value = NULL;
359
360 782 memset(line, 0, MAX_LINE_SIZE);
361 }
362
363 34 hash_entry = (char **)globus_hashtable_first(properties);
364 850 while(hash_entry)
365 {
366 782 result = globus_wsdl_config_expand_refs(
367 *properties, hash_entry[1], strlen(hash_entry[1]) + 1,
368 &new_value, &new_value_length);
369 782 if(result != GLOBUS_SUCCESS)
370 {
371 0 result = GlobusWSDLConfigErrorExpandingRefs(result, filename, linenum);
372 0 goto exit;
373 }
374
375 782 if(hash_entry[1] != new_value)
376 {
377 0 free(hash_entry[1]);
378 0 hash_entry[1] = globus_libc_strdup(new_value);
379 }
380
381 782 new_value = NULL;
382
383 782 hash_entry = (char **)globus_hashtable_next(properties);
384 }
385
386 34 exit:
387
388 34 if(propstream)
389 {
390 34 fclose(propstream);
391 }
392
393 34 if(key)
394 {
395 0 free(key);
396 }
397
398 34 if(value)
399 {
400 0 free(value);
401 }
402
403 34 if(new_value)
404 {
405 0 free(new_value);
406 }
407
408 34 if(hash_entry)
409 {
410 0 globus_free(hash_entry);
411 }
412
413 GlobusWSDLConfigDebugExit();
414 34 return result;
415 }
416
417 globus_result_t
418 globus_wsdl_config_expand_refs(
419 globus_hashtable_t hash,
420 char * value,
421 size_t value_length,
422 char ** new_value,
423 size_t * new_length)
424 782 {
425 782 char * nvalue = NULL;
426 782 size_t nvalue_length = 0;
427 782 char * rp = NULL;
428 782 char * prev_rp = NULL;
429 782 size_t rp_length = 0;
430 782 int rp_index = 0;
431 782 int newrp_index = 0;
432 782 char * rp_env = NULL;
433 782 char * tmp_rp = NULL;
434 782 int tmp_rp_index = 0;
435 782 char * envstring = NULL;
436 782 globus_result_t result = GLOBUS_SUCCESS;
437 782 char ** hash_entry = NULL;
438
439 GlobusFuncName(globus_wsdl_config_expand_refs);
440 GlobusWSDLConfigDebugEnter();
441
442 782 rp = (char *)value;
443 782 prev_rp = rp;
444 782 rp_length = value_length;
445 782 rp = (char *)my_strpbrk(rp, rp_length, &rp_index, "$", NULL);
446
447 782 if(!rp)
448 {
449 782 nvalue = value;
450 782 nvalue_length = value_length;
451 }
452
453 1564 while(rp)
454 {
455 0 rp_length -= rp_index;
456
457 0 if(rp_index != 0)
458 {
459 0 if(rp[-1] == '\\')
460 {
461 0 rp++;
462 0 rp_length--;
463 0 rp = (char *)my_strpbrk(rp, rp_length, &newrp_index,
464 "$", NULL);
465 0 rp_length -= newrp_index;
466 0 rp_index += newrp_index + 1;
467 }
468 }
469
470
471 0 nvalue = realloc(nvalue, nvalue_length + rp_index);
472 0 memcpy(nvalue + (nvalue_length - 1), prev_rp, rp_index);
473 0 nvalue_length += rp_index;
474
475 0 if(rp_length && (*(rp + 1) == '{'))
476 {
477 0 rp_env = rp + 2;
478 0 rp_length -= 2;
479
480 0 tmp_rp = (char *)my_strpbrk(rp_env, rp_length, &tmp_rp_index, "}", NULL);
481 0 if(!tmp_rp)
482 {
483 0 result = GlobusWSDLConfigErrorNoCurly();
484 0 goto error_exit;
485 }
486
487 0 envstring = malloc(tmp_rp_index + 1);
488 0 memcpy(envstring, rp_env, tmp_rp_index);
489 0 envstring[tmp_rp_index] = '\0';
490 0 rp = tmp_rp + 1;
491 0 rp_length -= tmp_rp_index - 1;
492 }
493 else
494 {
495 0 rp_env = rp + 1;
496 0 tmp_rp = (char *)my_strpbrk(rp_env, rp_length, &tmp_rp_index,
497 FILE_SEPARATOR" ", NULL);
498 0 if(tmp_rp)
499 {
500 0 rp = tmp_rp;
501 0 rp_length -= tmp_rp_index;
502 0 envstring = malloc(tmp_rp_index + 1);
503 0 memcpy(envstring, rp_env, tmp_rp_index);
504 0 envstring[tmp_rp_index] = '\0';
505 }
506 else
507 {
508 0 rp = tmp_rp;
509 0 envstring = malloc(rp_length + 1);
510 0 memcpy(envstring, rp_env, rp_length);
511 0 envstring[rp_length] = '\0';
512 0 rp_length = 0;
513 }
514 }
515
516 0 hash_entry = globus_hashtable_lookup(&hash, (void *) envstring);
517 0 if(hash_entry)
518 {
519 0 size_t tmp_length = strlen(hash_entry[1]);
520 0 nvalue = realloc(nvalue, nvalue_length + tmp_length);
521 0 memcpy(nvalue + (nvalue_length - 1), hash_entry[1], tmp_length);
522 0 nvalue_length += tmp_length;
523 }
524 else
525 {
526 char * env_value;
527 size_t tmp_length;
528 0 env_value = getenv(envstring);
529 0 if(!env_value)
530 {
531 0 result = GlobusWSDLConfigErrorNoEnv(envstring);
532 0 goto error_exit;
533 }
534
535 0 tmp_length += strlen(env_value);
536 0 nvalue = realloc(nvalue, nvalue_length + tmp_length);
537 0 memcpy(nvalue + (nvalue_length - 1), env_value, tmp_length);
538 0 nvalue_length += tmp_length;
539 }
540
541 0 if(envstring)
542 {
543 0 free(envstring);
544 0 envstring = NULL;
545 }
546
547 0 if(rp)
548 {
549 0 prev_rp = rp;
550 0 rp = (char *)my_strpbrk(rp, rp_length, &rp_index, "$", NULL);
551 }
552 }
553
554 782 if(rp && rp_length)
555 {
556 0 nvalue = realloc(nvalue, nvalue_length + rp_length);
557 0 memcpy(nvalue + (nvalue_length - 1), rp, rp_length);
558 0 nvalue_length += rp_length;
559 }
560
561 782 nvalue[nvalue_length - 1] = '\0';
562
563 782 *new_value = nvalue;
564 782 *new_length = nvalue_length;
565
566 782 goto exit;
567
568 0 error_exit:
569
570 0 if(nvalue)
571 {
572 0 free(nvalue);
573 }
574
575 782 exit:
576
577 782 if(envstring)
578 {
579 0 free(envstring);
580 }
581
582 GlobusWSDLConfigDebugExit();
583 782 return result;
584 }
585
586 static
587 const char *
588 my_strpbrk(
589 const char * str,
590 size_t str_length,
591 int * locator_index,
592 const char * delims,
593 int * delim_index)
594 3368 {
595 const char * locator;
596 int delim_count, ind, i;
597
598 3368 ind = 0;
599 3368 i = 0;
600 3368 delim_count = strlen(delims);
601 3368 locator = str;
602 65521 while(*locator && ind < str_length)
603 {
604 135087 for(i = 0; i < delim_count; ++i)
605 {
606 76302 if(*locator == delims[i])
607 {
608 1293 if(locator_index)
609 {
610 1293 *locator_index = ind;
611 }
612
613 1293 if(delim_index)
614 {
615 0 *delim_index = i;
616 }
617 1293 return locator;
618 }
619 }
620
621 58785 locator++;
622 58785 ind++;
623 }
624
625 2075 if(locator_index)
626 {
627 2075 *locator_index = -1;
628 }
629 2075 return NULL;