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_common.h"
18 #include "libxml/xmlreader.h"
19 #include <string.h>
20 #include <fcntl.h>
21 #include <sys/types.h>
22 #include <unistd.h>
23 #include <errno.h>
24
25 #define TEMPLATE_NODE "tmpl"
26 #define EVAL_NODE "eval"
27 #define SCRIPT_NODE "script"
28
29 #define BEGIN_PRINT "\nprint(\""
30 #define BEGIN_PRINT_LENGTH 8
31 #define END_PRINT "\");\n"
32 #define END_PRINT_LENGTH 4
33 #define PRINT_LENGTH 12
34
35 #define BEGIN_EPRINT "\nprint("
36 #define BEGIN_EPRINT_LENGTH 7
37 #define END_EPRINT ");\n"
38 #define END_EPRINT_LENGTH 3
39 #define EPRINT_LENGTH 10
40
41 #define DELIMITER_COUNT 2
42 static const char * DELIMITERS = "\n\"";
43 static const char * REPLACEMENTS[DELIMITER_COUNT] =
44 {"\\n", "\\\""};
45
46 /**
47 * Functions for parsing the template file
48 */
49
50 static
51 const char *
52 my_strpbrk(
53 const char * str,
54 size_t str_length,
55 int * locator_index,
56 const char * delims,
57 int * delim_index,
58 int escape);
59
60 static
61 int
62 globus_i_template_convert_chars(
63 const char * old_buffer,
64 size_t old_length,
65 char ** buffer,
66 size_t * length,
67 int delim_count,
68 const char * delim_set,
69 const char ** replace_set);
70
71 int
72 globus_wsdl_template_get_jsbuf(
73 const char * filename,
74 char ** buffer,
75 size_t * length,
76 char ** error_string,
77 char script_token,
78 char eval_token)
79 518 {
80 518 size_t read_length = 0;
81 char read_buffer[1000];
82 518 size_t new_length = 0;
83 518 char * new_buffer = NULL;
84 518 size_t tmp_length = 0;
85 518 char * tmp_buffer = NULL;
86 518 size_t script_length = 0;
87 518 size_t eval_length = 0;
88 518 size_t tmpl_length = 0;
89 const char * loc;
90 const char * prev;
91 char charset[3];
92 518 size_t template_length = 0;
93 518 char * template_buffer = NULL;
94 int infd;
95 518 int in_script = 0;
96 518 int in_eval = 0;
97 char token;
98 int loc_index, loc_length;
99 int delim_index;
100 518 int add_loc_index = 0;
101
102 518 *error_string = NULL;
103 518 charset[0] = script_token;
104 518 charset[1] = eval_token;
105 518 charset[2] = 0;
106
107 518 infd = open(filename, O_RDONLY, 0);
108 518 if(infd < 0)
109 {
110 /** XXX - this should be changed to use globus errno error calls */
111 char * error_message;
112 0 error_message = strerror(errno);
113 0 *error_string = globus_libc_strdup(error_message);
114 0 goto exit;
115 }
116
117 518 memset(read_buffer, 0, 1000);
118
119 10077 while((read_length = read(infd, read_buffer, 1000)) > 0)
120 {
121 9041 tmp_buffer = realloc(tmp_buffer, tmp_length + read_length);
122 9041 if(!tmp_buffer)
123 {
124 /** XXX - this should be fixed to use globus_error_errno calls */
125 char * error_message;
126 0 error_message = strerror(errno);
127 0 *error_string = globus_libc_strdup(error_message);
128 0 goto exit;
129 }
130
131 9041 memcpy(tmp_buffer + tmp_length, read_buffer, read_length);
132 9041 tmp_length += read_length;
133 }
134
135 518 tmp_buffer = realloc(tmp_buffer, tmp_length + 1);
136 518 tmp_buffer[tmp_length] = 0;
137
138 518 loc = tmp_buffer;
139 518 loc_length = tmp_length;
140 518 prev = tmp_buffer;
141
142 while(1)
143 {
144 114172 loc = my_strpbrk(loc, loc_length, &loc_index, charset, &delim_index, 1);
145 114172 if(!loc)
146 {
147 518 if(in_script)
148 {
149 0 *error_string = globus_libc_strdup(
150 "End of file reached inside a script chunk");
151 0 goto exit;
152 }
153
154 518 if(in_eval)
155 {
156 0 *error_string = globus_libc_strdup(
157 "End of file reached inside an evalu chunk");
158 0 goto exit;
159 }
160
161 518 tmpl_length = loc_length;
162 518 globus_i_template_convert_chars(
163 prev, tmpl_length,
164 &template_buffer, &template_length,
165 DELIMITER_COUNT,
166 DELIMITERS,
167 REPLACEMENTS);
168 518 new_buffer = realloc(
169 new_buffer,
170 new_length + template_length + PRINT_LENGTH);
171 518 memcpy(new_buffer + new_length,
172 BEGIN_PRINT, BEGIN_PRINT_LENGTH);
173 518 memcpy(new_buffer + new_length + BEGIN_PRINT_LENGTH,
174 template_buffer, template_length);
175 518 memcpy(new_buffer + new_length +
176 BEGIN_PRINT_LENGTH + template_length,
177 END_PRINT, END_PRINT_LENGTH);
178 518 new_length += PRINT_LENGTH + template_length;
179
180 518 free(template_buffer);
181 518 template_buffer = NULL;
182
183 518 break;
184 }
185
186 113654 if(add_loc_index > 0)
187 {
188 0 loc_index += add_loc_index + 1;
189 0 add_loc_index = 0;
190 }
191
192 113654 if(loc_index != 0 && (*(loc - 1) == '\\'))
193 {
194 0 add_loc_index = loc_index;
195 0 ++loc;
196 0 continue;
197 }
198
199 113654 loc_length -= (loc_index + 1);
200
201 113654 token = *loc;
202
203 113654 if(token == script_token)
204 {
205 21096 if(in_eval)
206 {
207 0 *error_string = malloc(500);
208 0 sprintf(*error_string,
209 "While parsing %s: Found a script token (%c), "
210 "expected an eval token (%c)",
211 filename, script_token, eval_token);
212 0 goto exit;
213 }
214
215 21096 if(in_script)
216 {
217 10548 in_script = 0;
218
219 10548 script_length = loc_index;
220 10548 new_buffer = realloc(new_buffer, new_length + script_length);
221 10548 memcpy(new_buffer + new_length, prev, script_length);
222 10548 new_length += script_length;
223 }
224 else
225 {
226 10548 in_script = 1;
227
228 10548 tmpl_length = loc_index;
229 10548 globus_i_template_convert_chars(
230 prev, tmpl_length,
231 &template_buffer, &template_length,
232 DELIMITER_COUNT,
233 DELIMITERS,
234 REPLACEMENTS);
235 10548 new_buffer = realloc(
236 new_buffer,
237 new_length + template_length + PRINT_LENGTH);
238 10548 memcpy(new_buffer + new_length,
239 BEGIN_PRINT, BEGIN_PRINT_LENGTH);
240 10548 memcpy(new_buffer + new_length + BEGIN_PRINT_LENGTH,
241 template_buffer, template_length);
242 10548 memcpy(new_buffer + new_length +
243 BEGIN_PRINT_LENGTH + template_length,
244 END_PRINT, END_PRINT_LENGTH);
245 10548 new_length += PRINT_LENGTH + template_length;
246
247 10548 free(template_buffer);
248 10548 template_buffer = NULL;
249 }
250 }
251 92558 else if(token == eval_token)
252 {
253 92558 if(in_script)
254 {
255 0 *error_string = malloc(500);
256 0 sprintf(
257 *error_string,
258 "While parsing %s: Found an eval token (%c), "
259 "expected a script token (%c)",
260 filename, eval_token, script_token);
261 0 goto exit;
262 }
263
264 92558 if(in_eval)
265 {
266 46279 in_eval = 0;
267
268 46279 eval_length = loc_index;
269 46279 new_buffer = realloc(new_buffer,
270 new_length + eval_length + EPRINT_LENGTH);
271 46279 memcpy(new_buffer + new_length, BEGIN_EPRINT,
272 BEGIN_EPRINT_LENGTH);
273 46279 memcpy(new_buffer + new_length + BEGIN_EPRINT_LENGTH,
274 prev, eval_length);
275 46279 memcpy(new_buffer + new_length +
276 BEGIN_EPRINT_LENGTH + eval_length,
277 END_EPRINT, END_EPRINT_LENGTH);
278 46279 new_length += EPRINT_LENGTH + eval_length;
279 }
280 else
281 {
282 46279 in_eval = 1;
283
284 46279 tmpl_length = loc_index;
285 46279 globus_i_template_convert_chars(
286 prev, tmpl_length,
287 &template_buffer, &template_length,
288 DELIMITER_COUNT,
289 DELIMITERS,
290 REPLACEMENTS);
291 46279 new_buffer = realloc(
292 new_buffer,
293 new_length + template_length + PRINT_LENGTH);
294 46279 memcpy(new_buffer + new_length,
295 BEGIN_PRINT, BEGIN_PRINT_LENGTH);
296 46279 memcpy(new_buffer + new_length + BEGIN_PRINT_LENGTH,
297 template_buffer, template_length);
298 46279 memcpy(new_buffer + new_length +
299 BEGIN_PRINT_LENGTH + template_length,
300 END_PRINT, END_PRINT_LENGTH);
301 46279 new_length += PRINT_LENGTH + template_length;
302
303 46279 free(template_buffer);
304 46279 template_buffer = NULL;
305 }
306 }
307
308 113654 if(loc_length >= 0)
309 {
310 113654 ++loc;
311 113654 prev = loc;
312 }
313 else
314 {
315 0 break;
316 }
317 113654 }
318
319 518 new_buffer = realloc(new_buffer, new_length + 2);
320 518 memcpy(new_buffer + new_length, "\r\n", 2);
321 518 new_length += 2;
322
323 518 *buffer = new_buffer;
324 518 *length = new_length;
325
326 518 exit:
327
328 518 if(infd > 0)
329 {
330 518 close(infd);
331 }
332
333 518 if(*error_string)
334 {
335 0 return -1;
336 }
337
338 518 return 0;
339 }
340
341
342 static
343 const char *
344 my_strpbrk(
345 const char * str,
346 size_t str_length,
347 int * locator_index,
348 const char * delims,
349 int * delim_index,
350 int escape)
351 334186 {
352 const char * locator;
353 int delim_count, ind, i;
354
355 334186 ind = 0;
356 334186 i = 0;
357 334186 delim_count = strlen(delims);
358 334186 locator = str;
359 13347230 while(*locator && ind < str_length)
360 {
361 38433097 for(i = 0; i < delim_count; ++i)
362 {
363 25754239 if(*locator == delims[i])
364 {
365 302186 if(escape &&
366 (ind != 0 && (*(locator - 1) == '\\')))
367 {
368 8039 continue;
369 }
370
371 294147 if(locator_index)
372 {
373 294147 *locator_index = ind;
374 }
375
376 294147 if(delim_index)
377 {
378 294147 *delim_index = i;
379 }
380 294147 return locator;
381 }
382 }
383
384 12678858 locator++;
385 12678858 ind++;
386 }
387
388 40039 if(locator_index)
389 {
390 40039 *locator_index = -1;
391 }
392 40039 return NULL;
393 }
394
395 static
396 int
397 globus_i_template_convert_chars(
398 const char * tmp_buffer,
399 size_t tmp_length,
400 char ** buffer,
401 size_t * length,
402 int delim_count,
403 const char * delim_set,
404 const char ** replace_set)
405 57345 {
406 const char * locator;
407 const char * prev;
408 57345 char * new_buffer = NULL;
409 57345 size_t new_length = 0;
410 int upto_length, locator_length;
411 int replace_length;
412 int found_index, delim_index;
413
414 57345 locator = tmp_buffer;
415 57345 locator_length = tmp_length;
416 57345 prev = tmp_buffer;
417 while(1)
418 {
419 237838 if(locator_length <= 0)
420 {
421 17824 break;
422 }
423
424 220014 locator = my_strpbrk(locator, locator_length, &found_index, delim_set, &delim_index, 0);
425 220014 if(!locator)
426 {
427 39521 upto_length = locator_length;
428 39521 new_buffer = realloc(new_buffer, new_length + upto_length);
429 39521 memcpy(new_buffer + new_length, prev, upto_length);
430 39521 new_length += upto_length;
431 39521 break;
432 }
433
434 180493 upto_length = found_index;
435 180493 locator_length -= (found_index + 1);
436
437 180493 replace_length = strlen(replace_set[delim_index]);
438 180493 new_buffer = realloc(new_buffer,
439 new_length + replace_length + upto_length);
440 180493 memcpy(new_buffer + new_length, prev, upto_length);
441 180493 memcpy(new_buffer + new_length + upto_length, replace_set[delim_index],
442 replace_length);
443 180493 new_length += upto_length + replace_length;
444
445 180493 locator++;
446 180493 prev = locator;
447
448 180493 }
449
450 57345 *buffer = new_buffer;
451 57345 *length = new_length;
452
453 57345 return 0;