1 /*
2 * Portions of this file Copyright 1999-2005 University of Chicago
3 * Portions of this file Copyright 1999-2005 The University of Southern California.
4 *
5 * This file or a portion of this file is licensed under the
6 * terms of the Globus Toolkit Public License, found at
7 * http://www.globus.org/toolkit/download/license.html.
8 * If you redistribute this file, with or without
9 * modifications, you must include this notice in the file.
10 */
11
12 #include "globus_common.h"
13 #include "libxml/xmlreader.h"
14 #include <string.h>
15 #include <fcntl.h>
16 #include <sys/types.h>
17 #include <unistd.h>
18 #include <errno.h>
19
20 #define TEMPLATE_NODE "tmpl"
21 #define EVAL_NODE "eval"
22 #define SCRIPT_NODE "script"
23
24 #define BEGIN_PRINT "\nprint(\""
25 #define BEGIN_PRINT_LENGTH 8
26 #define END_PRINT "\");\n"
27 #define END_PRINT_LENGTH 4
28 #define PRINT_LENGTH 12
29
30 #define BEGIN_EPRINT "\nprint("
31 #define BEGIN_EPRINT_LENGTH 7
32 #define END_EPRINT ");\n"
33 #define END_EPRINT_LENGTH 3
34 #define EPRINT_LENGTH 10
35
36 #define DELIMITER_COUNT 2
37 static const char * DELIMITERS = "\n\"";
38 static const char * REPLACEMENTS[DELIMITER_COUNT] =
39 {"\\n", "\\\""};
40
41 /**
42 * Functions for parsing the template file
43 */
44
45 static
46 const char *
47 my_strpbrk(
48 const char * str,
49 size_t str_length,
50 int * locator_index,
51 const char * delims,
52 int * delim_index,
53 int escape);
54
55 static
56 int
57 globus_i_template_convert_chars(
58 const char * old_buffer,
59 size_t old_length,
60 char ** buffer,
61 size_t * length,
62 int delim_count,
63 const char * delim_set,
64 const char ** replace_set);
65
66 int
67 globus_wsdl_template_get_jsbuf(
68 const char * filename,
69 char ** buffer,
70 size_t * length,
71 char ** error_string,
72 char script_token,
73 char eval_token)
74 237 {
75 237 size_t read_length = 0;
76 char read_buffer[1000];
77 237 size_t new_length = 0;
78 237 char * new_buffer = NULL;
79 237 size_t tmp_length = 0;
80 237 char * tmp_buffer = NULL;
81 237 size_t script_length = 0;
82 237 size_t eval_length = 0;
83 237 size_t tmpl_length = 0;
84 const char * loc;
85 const char * prev;
86 char charset[3];
87 237 size_t template_length = 0;
88 237 char * template_buffer = NULL;
89 int infd, res;
90 237 int in_script = 0;
91 237 int in_eval = 0;
92 char token;
93 int loc_index, loc_length;
94 int delim_index;
95 237 int add_loc_index = 0;
96
97 237 *error_string = NULL;
98 237 charset[0] = script_token;
99 237 charset[1] = eval_token;
100 237 charset[2] = 0;
101
102 237 infd = open(filename, O_RDONLY, 0);
103 237 if(infd < 0)
104 {
105 /** XXX - this should be changed to use globus errno error calls */
106 char * error_message;
107 0 error_message = strerror(errno);
108 0 *error_string = globus_libc_strdup(error_message);
109 0 goto exit;
110 }
111
112 237 memset(read_buffer, 0, 1000);
113
114 4915 while((read_length = read(infd, read_buffer, 1000)) > 0)
115 {
116 4441 tmp_buffer = realloc(tmp_buffer, tmp_length + read_length);
117 4441 if(!tmp_buffer)
118 {
119 /** XXX - this should be fixed to use globus_error_errno calls */
120 char * error_message;
121 0 error_message = strerror(errno);
122 0 *error_string = globus_libc_strdup(error_message);
123 0 goto exit;
124 }
125
126 4441 memcpy(tmp_buffer + tmp_length, read_buffer, read_length);
127 4441 tmp_length += read_length;
128 }
129
130 237 tmp_buffer = realloc(tmp_buffer, tmp_length + 1);
131 237 tmp_buffer[tmp_length] = 0;
132
133 237 loc = tmp_buffer;
134 237 loc_length = tmp_length;
135 237 prev = tmp_buffer;
136
137 while(1)
138 {
139 59611 loc = my_strpbrk(loc, loc_length, &loc_index, charset, &delim_index, 1);
140 59611 if(!loc)
141 {
142 237 if(in_script)
143 {
144 0 *error_string = globus_libc_strdup(
145 "End of file reached inside a script chunk");
146 0 goto exit;
147 }
148
149 237 if(in_eval)
150 {
151 0 *error_string = globus_libc_strdup(
152 "End of file reached inside an evalu chunk");
153 0 goto exit;
154 }
155
156 237 tmpl_length = loc_length;
157 237 globus_i_template_convert_chars(
158 prev, tmpl_length,
159 &template_buffer, &template_length,
160 DELIMITER_COUNT,
161 DELIMITERS,
162 REPLACEMENTS);
163 237 new_buffer = realloc(
164 new_buffer,
165 new_length + template_length + PRINT_LENGTH);
166 237 memcpy(new_buffer + new_length,
167 BEGIN_PRINT, BEGIN_PRINT_LENGTH);
168 237 memcpy(new_buffer + new_length + BEGIN_PRINT_LENGTH,
169 template_buffer, template_length);
170 237 memcpy(new_buffer + new_length +
171 BEGIN_PRINT_LENGTH + template_length,
172 END_PRINT, END_PRINT_LENGTH);
173 237 new_length += PRINT_LENGTH + template_length;
174
175 237 free(template_buffer);
176 237 template_buffer = NULL;
177
178 237 break;
179 }
180
181 59374 if(add_loc_index > 0)
182 {
183 0 loc_index += add_loc_index + 1;
184 0 add_loc_index = 0;
185 }
186
187 59374 if(loc_index != 0 && (*(loc - 1) == '\\'))
188 {
189 0 add_loc_index = loc_index;
190 0 ++loc;
191 0 continue;
192 }
193
194 59374 loc_length -= (loc_index + 1);
195
196 59374 token = *loc;
197
198 59374 if(token == script_token)
199 {
200 10028 if(in_eval)
201 {
202 0 *error_string = malloc(500);
203 0 sprintf(*error_string,
204 "While parsing %s: Found a script token (%c), "
205 "expected an eval token (%c)",
206 filename, script_token, eval_token);
207 0 goto exit;
208 }
209
210 10028 if(in_script)
211 {
212 5014 in_script = 0;
213
214 5014 script_length = loc_index;
215 5014 new_buffer = realloc(new_buffer, new_length + script_length);
216 5014 memcpy(new_buffer + new_length, prev, script_length);
217 5014 new_length += script_length;
218 }
219 else
220 {
221 5014 in_script = 1;
222
223 5014 tmpl_length = loc_index;
224 5014 globus_i_template_convert_chars(
225 prev, tmpl_length,
226 &template_buffer, &template_length,
227 DELIMITER_COUNT,
228 DELIMITERS,
229 REPLACEMENTS);
230 5014 new_buffer = realloc(
231 new_buffer,
232 new_length + template_length + PRINT_LENGTH);
233 5014 memcpy(new_buffer + new_length,
234 BEGIN_PRINT, BEGIN_PRINT_LENGTH);
235 5014 memcpy(new_buffer + new_length + BEGIN_PRINT_LENGTH,
236 template_buffer, template_length);
237 5014 memcpy(new_buffer + new_length +
238 BEGIN_PRINT_LENGTH + template_length,
239 END_PRINT, END_PRINT_LENGTH);
240 5014 new_length += PRINT_LENGTH + template_length;
241
242 5014 free(template_buffer);
243 5014 template_buffer = NULL;
244 }
245 }
246 49346 else if(token == eval_token)
247 {
248 49346 if(in_script)
249 {
250 0 *error_string = malloc(500);
251 0 sprintf(
252 *error_string,
253 "While parsing %s: Found an eval token (%c), "
254 "expected a script token (%c)",
255 filename, eval_token, script_token);
256 0 goto exit;
257 }
258
259 49346 if(in_eval)
260 {
261 24673 in_eval = 0;
262
263 24673 eval_length = loc_index;
264 24673 new_buffer = realloc(new_buffer,
265 new_length + eval_length + EPRINT_LENGTH);
266 24673 memcpy(new_buffer + new_length, BEGIN_EPRINT,
267 BEGIN_EPRINT_LENGTH);
268 24673 memcpy(new_buffer + new_length + BEGIN_EPRINT_LENGTH,
269 prev, eval_length);
270 24673 memcpy(new_buffer + new_length +
271 BEGIN_EPRINT_LENGTH + eval_length,
272 END_EPRINT, END_EPRINT_LENGTH);
273 24673 new_length += EPRINT_LENGTH + eval_length;
274 }
275 else
276 {
277 24673 in_eval = 1;
278
279 24673 tmpl_length = loc_index;
280 24673 globus_i_template_convert_chars(
281 prev, tmpl_length,
282 &template_buffer, &template_length,
283 DELIMITER_COUNT,
284 DELIMITERS,
285 REPLACEMENTS);
286 24673 new_buffer = realloc(
287 new_buffer,
288 new_length + template_length + PRINT_LENGTH);
289 24673 memcpy(new_buffer + new_length,
290 BEGIN_PRINT, BEGIN_PRINT_LENGTH);
291 24673 memcpy(new_buffer + new_length + BEGIN_PRINT_LENGTH,
292 template_buffer, template_length);
293 24673 memcpy(new_buffer + new_length +
294 BEGIN_PRINT_LENGTH + template_length,
295 END_PRINT, END_PRINT_LENGTH);
296 24673 new_length += PRINT_LENGTH + template_length;
297
298 24673 free(template_buffer);
299 24673 template_buffer = NULL;
300 }
301 }
302
303 59374 if(loc_length >= 0)
304 {
305 59374 ++loc;
306 59374 prev = loc;
307 }
308 else
309 {
310 59374 break;
311 }
312 }
313
314 237 new_buffer = realloc(new_buffer, new_length + 2);
315 237 memcpy(new_buffer + new_length, "\r\n", 2);
316 237 new_length += 2;
317
318 237 *buffer = new_buffer;
319 237 *length = new_length;
320
321 237 exit:
322
323 237 if(infd > 0)
324 {
325 237 close(infd);
326 }
327
328 237 if(*error_string)
329 {
330 0 return -1;
331 }
332
333 237 return 0;
334 }
335
336
337 /* int */
338 /* globus_wsdl_xml_template_get_jsbuf( */
339 /* const char * filename, */
340 /* char ** buffer, */
341 /* size_t * length, */
342 /* char ** error_string) */
343 /* { */
344 /* size_t new_length = 0; */
345 /* xmlTextReaderPtr reader = NULL; */
346 /* char * new_buffer = NULL; */
347
348 /* reader = xmlNewTextReaderFilename(filename); */
349 /* if(!reader) */
350 /* { */
351 /* xmlErrorPtr error; */
352 /* char * error_message; */
353
354 /* error = xmlGetLastError(); */
355 /* if(!error) */
356 /* { */
357 /* return -1; */
358 /* } */
359
360 /* error_message = malloc(strlen(error->message) + 500); */
361 /* if(!error_message) */
362 /* { */
363 /* return -1; */
364 /* } */
365
366 /* sprintf(error_message, "Could not parse template: %s: %s", */
367 /* filename, error->message); */
368 /* *error_string = error_message; */
369 /* return -1; */
370 /* } */
371
372 /* while(xmlTextReaderRead(reader) > 0) */
373 /* { */
374 /* const xmlChar * local_name; */
375
376 /* local_name = xmlTextReaderConstLocalName(reader); */
377 /* if(xmlStrEqual(local_name, TEMPLATE_NODE)) */
378 /* { */
379 /* int bufflen; */
380 /* char * template_buffer; */
381 /* xmlNodePtr node; */
382
383 /* node = xmlTextReaderExpand(reader); */
384 /* if(node) */
385 /* { */
386 /* node = node->children; */
387 /* } */
388
389 /* while(node) */
390 /* { */
391 /* if(node->type == XML_TEXT_NODE) */
392 /* { */
393 /* if(node->content) */
394 /* { */
395 /* size_t template_length; */
396
397 /* globus_i_template_convert_chars( */
398 /* node->content, strlen(node->content), */
399 /* &template_buffer, &template_length, */
400 /* '\n', "\\n"); */
401 /* bufflen = template_length + 12; */
402 /* new_buffer = realloc(new_buffer, new_length + bufflen); */
403 /* memcpy(new_buffer + new_length, "\nprint(\"", 8); */
404 /* memcpy(new_buffer + new_length + 8, */
405 /* template_buffer, template_length); */
406 /* memcpy(new_buffer + new_length + 8 + template_length, */
407 /* "\");\n", 4); */
408 /* new_length += bufflen; */
409 /* } */
410 /* } */
411
412 /* node = node->next; */
413 /* } */
414 /* } */
415 /* else if(xmlStrEqual(local_name, EVAL_NODE)) */
416 /* { */
417 /* int bufflen; */
418 /* size_t eval_length; */
419 /* const xmlChar * eval_buffer; */
420 /* xmlNodePtr node; */
421
422 /* node = xmlTextReaderExpand(reader); */
423 /* if(node) */
424 /* { */
425 /* node = node->children; */
426 /* } */
427
428 /* while(node) */
429 /* { */
430 /* if(node->type == XML_TEXT_NODE) */
431 /* { */
432 /* eval_buffer = node->content; */
433 /* if(eval_buffer) */
434 /* { */
435 /* eval_length = strlen(eval_buffer); */
436 /* bufflen = eval_length + 10; */
437 /* new_buffer = realloc(new_buffer, new_length + bufflen); */
438 /* memcpy(new_buffer + new_length, "\nprint(", 7); */
439 /* memcpy(new_buffer + new_length + 7, */
440 /* eval_buffer, eval_length); */
441 /* memcpy(new_buffer + new_length + 7 + eval_length, */
442 /* ");\n", 3); */
443 /* new_length += bufflen; */
444 /* } */
445 /* } */
446
447 /* node = node->next; */
448 /* } */
449 /* } */
450 /* else if(xmlStrEqual(local_name, SCRIPT_NODE)) */
451 /* { */
452 /* size_t script_length; */
453 /* const xmlChar * script_buffer; */
454 /* xmlNodePtr node; */
455
456 /* node = xmlTextReaderExpand(reader); */
457 /* if(node) */
458 /* { */
459 /* node = node->children; */
460 /* } */
461
462 /* while(node) */
463 /* { */
464 /* if(node->type == XML_TEXT_NODE) */
465 /* { */
466 /* script_buffer = node->content; */
467 /* if(script_buffer) */
468 /* { */
469 /* script_length = strlen(script_buffer); */
470 /* new_buffer = realloc(new_buffer, */
471 /* new_length + script_length); */
472 /* memcpy(new_buffer + new_length, */
473 /* script_buffer, script_length); */
474 /* new_length += script_length; */
475 /* } */
476 /* } */
477
478 /* node = node->next; */
479 /* } */
480 /* } */
481 /* } */
482
483 /* new_buffer = realloc(new_buffer, new_length + 1); */
484 /* memcpy(new_buffer + new_length, "\0", 1); */
485 /* new_length += 1; */
486
487 /* *buffer = new_buffer; */
488 /* *length = new_length; */
489 /* return 0; */
490 /* } */
491
492 static
493 const char *
494 my_strpbrk(
495 const char * str,
496 size_t str_length,
497 int * locator_index,
498 const char * delims,
499 int * delim_index,
500 int escape)
501 179944 {
502 const char * locator;
503 int delim_count, ind, i;
504
505 179944 ind = 0;
506 179944 i = 0;
507 179944 delim_count = strlen(delims);
508 179944 locator = str;
509 6835197 while(*locator && ind < str_length)
510 {
511 19638997 for(i = 0; i < delim_count; ++i)
512 {
513 13163688 if(*locator == delims[i])
514 {
515 162692 if(escape &&
516 (ind != 0 && (*(locator - 1) == '\\')))
517 {
518 159354 continue;
519 }
520
521 159354 if(locator_index)
522 {
523 159354 *locator_index = ind;
524 }
525
526 159354 if(delim_index)
527 {
528 159354 *delim_index = i;
529 }
530 159354 return locator;
531 }
532 }
533
534 6475309 locator++;
535 6475309 ind++;
536 }
537
538 20590 if(locator_index)
539 {
540 20590 *locator_index = -1;
541 }
542 20590 return NULL;
543 }
544
545 static
546 int
547 globus_i_template_convert_chars(
548 const char * tmp_buffer,
549 size_t tmp_length,
550 char ** buffer,
551 size_t * length,
552 int delim_count,
553 const char * delim_set,
554 const char ** replace_set)
555 29924 {
556 const char * locator;
557 const char * prev;
558 29924 char * new_buffer = NULL;
559 29924 size_t new_length = 0;
560 int upto_length, locator_length;
561 int replace_length;
562 int found_index, delim_index;
563
564 29924 locator = tmp_buffer;
565 29924 locator_length = tmp_length;
566 29924 prev = tmp_buffer;
567 while(1)
568 {
569 129904 if(locator_length <= 0)
570 {
571 120333 break;
572 }
573
574 120333 locator = my_strpbrk(locator, locator_length, &found_index, delim_set, &delim_index, 0);
575 120333 if(!locator)
576 {
577 20353 upto_length = locator_length;
578 20353 new_buffer = realloc(new_buffer, new_length + upto_length);
579 20353 memcpy(new_buffer + new_length, prev, upto_length);
580 20353 new_length += upto_length;
581 20353 break;
582 }
583
584 99980 upto_length = found_index;
585 99980 locator_length -= (found_index + 1);
586
587 99980 replace_length = strlen(replace_set[delim_index]);
588 99980 new_buffer = realloc(new_buffer,
589 new_length + replace_length + upto_length);
590 99980 memcpy(new_buffer + new_length, prev, upto_length);
591 99980 memcpy(new_buffer + new_length + upto_length, replace_set[delim_index],
592 replace_length);
593 99980 new_length += upto_length + replace_length;
594
595 99980 locator++;
596 99980 prev = locator;
597
598 99980 }
599
600 29924 *buffer = new_buffer;
601 29924 *length = new_length;
602
603 29924 return 0;