/[pdpsoft]/trunk/grid-mw-security/ees/src/eval_man/pdl.c
ViewVC logotype

Contents of /trunk/grid-mw-security/ees/src/eval_man/pdl.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1235 - (show annotations) (download) (as text)
Fri Dec 4 11:35:24 2009 UTC (12 years, 9 months ago) by aramv
File MIME type: text/x-chdr
File size: 28061 byte(s)
Moved around control logic of the parser to stop and report errors if they are encountered
1 #include "pdl.h"
2
3 /* Lex/Yacc stuff */
4 extern FILE * yyin;
5 extern unsigned int lineno;
6 extern int yyparse(void);
7 extern int yylex(void);
8
9 /* Lex/Yacc cleanup functions */
10 extern void delete_lex_buffer(void);
11 #if HAVE_YYLEX_DESTROY
12 extern int yylex_destroy(void);
13 #endif
14
15 /* internal data */
16 static const char* config_file_s;
17 FILE* config_file_fp;
18 static char* _pdl_path;
19
20 int recursion_was_created;
21 int unknown_variable_was_referenced;
22
23 var_t* variables_list;
24 var_t* variables_list_last;
25 var_t* current_variable;
26
27 rule_t* rules_list;
28 rule_t* rules_list_last;
29 rule_t* current_rule;
30
31 policy_t* policies_list;
32 policy_t* policies_list_last;
33 policy_t* current_policy;
34
35
36 /* This function does everything parser related. After running yacc through wrap_yacc(), the created list is reduced to those in the array of named policies, of number_of_policies is greater than 0. The policies are checked for unreachable rules. After the parser has created a list of policies containing lists of rules, these rules are transformed to a tree by the link_dead_end_rules_in_policies() function. Finally, when a list of policies containing rules trees was created, the plug-ins are linked to each rule in the node. */
37 EES_RC start_pdl_parser(char *config_file, int number_of_policies, char* names_of_policies[]){
38 recursion_was_created = 0;
39
40 eef_log(LOG_NOTICE, "Loading config file: %s\n", config_file);
41 if(wrap_yacc(config_file) == EES_SUCCESS){
42 /* after the config file was successfully parsed, the policies and path to plugins are accessible. We can try to set the global (EEF-wide) modules path if one was provided */
43 eef_log(LOG_NOTICE, "Loaded config file: %s\n", config_file);
44
45 /* set the EEF modules path to the path found by the evaluation manager */
46 set_modules_path(get_pdl_path());
47
48 /* retrieve policy list from the evaluation mananger */
49 parsed_policy_list = get_policies();
50
51 /* strip policies that are not explicitly passed in the names_of_policies array */
52 if(number_of_policies){
53 parsed_policy_list = reduce_policies(parsed_policy_list, number_of_policies, names_of_policies);
54 }
55
56 if(remove_unreachable_rules_in_policies(parsed_policy_list) == EES_SUCCESS){
57 if(parsed_policy_list){
58 link_dead_end_rules_in_policies(parsed_policy_list);
59 link_rules_to_plugins(parsed_policy_list);
60 }
61 eef_log(LOG_INFO, "Your configuration file seems sane.\n");
62 print_policies(parsed_policy_list);
63
64 /* this is a callout to the plugin manager, which dlopen()'s the plugin, dlsym()'s the plugin's functions and calls the plugin's initialize function */
65 if(initialize_plugins() == EES_SUCCESS){
66 return EES_SUCCESS;
67 } else {
68 eef_log(LOG_ERR, "Failed to initialize plug-ins from policy config file %s\n", config_file);
69 }
70 } else {
71 eef_log(LOG_ERR, "The loaded configuration file defines unreachable rules. Please check your configuration file.");
72 }
73 } else {
74 if(recursion_was_created){
75 eef_log(LOG_ERR, "The loaded configuration file defines recursive rules. Please check your configuration file.");
76 }
77 if(unknown_variable_was_referenced){
78 eef_log(LOG_ERR, "The loaded configuration file references undefined variables. Please check your configuration file.");
79 }
80 }
81 return EES_FAILURE;
82 }
83
84
85 /*! Initializes the parsing of the configuration file. When parsing has completed successfully, the policy_list is available. This can be transformed to a tree using the link_dead_end_rules_in_policies() function. */
86 EES_RC wrap_yacc(const char* config_file){
87 config_file_s = config_file;
88 if((config_file_fp = fopen(config_file_s,"r")) != NULL){
89 yyin = config_file_fp;
90 yyparse();
91 if(!recursion_was_created && !unknown_variable_was_referenced){
92 /* callout to the plugin manager */
93 if(add_plugin_structs() == EES_SUCCESS){
94 return EES_SUCCESS;
95 } else {
96 eef_log(LOG_ERR, "Failed to load plug-ins from policy config file %s\n", config_file_s);
97 }
98 }
99 } else {
100 eef_log(LOG_ERR, "Failed to open policy config file %s", config_file_s);
101 }
102 return EES_FAILURE;
103 }
104
105 policy_t* get_policies(){
106 return policies_list;
107 }
108
109 /*! sets the path to modules directory */
110 void set_pdl_path(record_t* path){
111 size_t path_size = 0;
112 size_t string_size = (sizeof(char) * (strlen(path->string)+2)); /* size of string + extra slash + null byte */
113 _pdl_path = "";
114
115 /*struct stat sb;*/
116 /*if stat(MODUL*/
117
118 if(string_size < FILENAME_MAX){
119 path_size = string_size;
120 } else {
121 path_size = FILENAME_MAX;
122 }
123
124 if((_pdl_path = calloc(1, path_size))){
125 strncpy(_pdl_path, path->string, path_size);
126 strncat(_pdl_path, "/", 1);
127 }
128
129 eef_log(LOG_DEBUG, "Found a new modules path: %s\n", _pdl_path);
130
131 free(path->string);
132 path->string = NULL;
133 free(path);
134 path = NULL;
135 }
136
137 /*! Handles a variable representing a plug-in; creates a structure containing its values and adds it to the list of var_t structs variables_list */
138 void add_variable(record_t* name, record_t* value){
139 eef_log(LOG_DEBUG, "Added variable name: %s\n", name->string);
140 eef_log(LOG_DEBUG, "Added variable value: %s\n", value->string);
141
142 /* allocate struct and populate fields */
143 if((current_variable = calloc(1,sizeof(var_t)))){
144 current_variable->name = strdup(name->string);
145 current_variable->value = strdup(value->string);
146 current_variable->lineno = name->lineno;
147 current_variable->next = NULL;
148 } else {
149 eef_log(LOG_ERR, "Out of memory!");
150 }
151
152 /* append to the end of the list */
153 if(variables_list){
154 variables_list_last->next = current_variable;
155 } else {
156 variables_list = current_variable;
157 }
158 variables_list_last = current_variable;
159
160 /* clean up */
161 free(name->string);
162 name->string = NULL;
163 free(name);
164 name = NULL;
165 free(value->string);
166 value->string = NULL;
167 free(value);
168 value = NULL;
169 }
170
171 /* TODO I think this function is a bit of a kludge and could probably be rewritten to be more efficient and more legible - I think it might do too much, so extracting some functions might help */
172 /*! Appends a rule to the global rules_list, which is to be added to a policy when add_policy is called
173 Will return NULL and log an error when:
174 - adding the rule to the list will create a recursion in the tree of rules
175 - an unknown variable is referenced
176 */
177 rule_t* add_rule(record_t* state, record_t* true_branch, record_t* false_branch){
178 rule_t *new_rule = NULL, *new_false_branch = NULL, *new_true_branch = NULL, *recursive_rule = NULL;
179 var_t *temp_var = NULL;
180 char *unknown_var_format_string = "Unknown variable %s at line %i in config file %s";
181
182 if((new_rule = get_left_hand_rule(rules_list, state->string))){
183 eef_log(LOG_WARNING, "State %s at line %i is already in use at line %i.\n", state->string, state->lineno, new_rule->lineno);
184 } else {
185 /*find variables for rule */
186 temp_var = get_variable_by_name(state->string);
187 if(temp_var == NULL){
188 /* Errorous state - variable referenced in rule not previously defined */
189 eef_log(LOG_ERR, unknown_var_format_string, state->string, state->lineno, config_file_s);
190 unknown_variable_was_referenced = 1;
191 new_rule = clean_rules_tree(new_rule);
192 goto cleanup;
193 }
194 if(temp_var != NULL){
195 if((new_rule = calloc(1, sizeof(rule_t)))){
196 /* populate fields of current state */
197 new_rule->state = strdup(state->string);
198 new_rule->lineno = state->lineno;
199
200 /* populate fields of branches */
201 if(false_branch){
202 temp_var = get_variable_by_name(false_branch->string);
203 if(temp_var == NULL){
204 /* Errorous state - variable referenced in rule not previously defined */
205 eef_log(LOG_ERR, unknown_var_format_string, false_branch->string, false_branch->lineno, config_file_s);
206 unknown_variable_was_referenced = 1;
207 new_rule = clean_rules_tree(new_rule);
208 goto cleanup;
209 } else {
210 if((new_false_branch = calloc(1, sizeof(rule_t)))){
211 new_false_branch->state = strdup(false_branch->string);
212 new_false_branch->lineno = false_branch->lineno;
213 new_rule->false_branch = new_false_branch;
214 }
215 }
216 }
217
218 if(true_branch){
219 temp_var = get_variable_by_name(true_branch->string);
220 if(temp_var == NULL){
221 /* Errorous state - variable referenced in rule not previously defined */
222 eef_log(LOG_ERR, unknown_var_format_string, true_branch->string, true_branch->lineno, config_file_s);
223 unknown_variable_was_referenced = 1;
224 new_rule = clean_rules_tree(new_rule);
225 goto cleanup;
226 } else {
227 if((new_true_branch = calloc(1, sizeof(rule_t)))){
228 new_true_branch->state = strdup(true_branch->string);
229 new_true_branch->lineno = true_branch->lineno;
230 new_rule->true_branch = new_true_branch;
231 }
232 }
233 }
234
235 /* check for recursion */
236 if((recursive_rule = check_for_recursion(rules_list, new_rule))){
237 eef_log(LOG_WARNING, "Rule %s at line %i leads to recursion into state %s", new_rule->state, new_rule->lineno, recursive_rule->state);
238 new_rule = clean_rules_tree(new_rule);
239 recursion_was_created = 1;
240 } else {
241 /* add new rule at the end of the rules list */
242 if(rules_list){
243 rules_list_last->next = new_rule;
244 } else {
245 rules_list = new_rule;
246 }
247 rules_list_last = new_rule;
248
249 eef_log(LOG_DEBUG, "Added a new rule: %s\n", new_rule->state);
250 }
251
252 } else {
253 eef_log(LOG_ERR, "Out of memory!");
254 }
255 }
256 }
257
258 cleanup:
259
260 /* clean up */
261 if(state != NULL){
262 free(state->string);
263 free(state);
264 }
265 if(true_branch != NULL){
266 free(true_branch->string);
267 free(true_branch);
268 }
269 if(false_branch != NULL){
270 free(false_branch->string);
271 free(false_branch);
272 }
273
274 return new_rule;
275 }
276
277 /* Tries to find a recursion in the list of rules by iterating through all the tree branches. When the same rule is encountered in the current list a recursion has been found */
278 rule_t* check_for_recursion(rule_t* rule_l, rule_t* rule_r){
279 rule_t* temp_rule = rule_l;
280
281 /* right hand rule leads to its own recursive state */
282 /* still need to find a way to reuse the code from the while loop to do this check */
283 if(rule_r){
284 if(rule_r->true_branch){
285 if(strcmp(rule_r->state, rule_r->true_branch->state) == 0){
286 return rule_r->true_branch;
287 }
288 }
289
290 if(rule_r->false_branch){
291 if(strcmp(rule_r->state, rule_r->false_branch->state) == 0){
292 return rule_r->false_branch;
293 }
294 }
295 }
296
297 /* iterate list of rules */
298 while(temp_rule){
299 if((temp_rule != NULL) && (rule_r != NULL)){
300 /* left hand and right hand state are equal */
301 if(strcmp(temp_rule->state, rule_r->state) == 0){
302 return rule_r;
303 }
304
305 /* start state and true branch of right hand rule are equal */
306 if(rule_r->true_branch){
307 if(strcmp(temp_rule->state, rule_r->true_branch->state) == 0){
308 return rule_r->true_branch;
309 }
310 }
311
312 /* start state and false branch of right hand side are equal */
313 if(rule_r->false_branch){
314 if(strcmp(temp_rule->state, rule_r->false_branch->state) == 0){
315 return rule_r->false_branch;
316 }
317 }
318 }
319
320 /* move to next rule */
321 temp_rule = temp_rule->next;
322 }
323 return NULL;
324 }
325
326 /* This function iterates the passed list of policies and removes unreachable rules from each policy */
327 EES_RC remove_unreachable_rules_in_policies(policy_t* policies){
328 policy_t *temp_policy = policies;
329 EES_RC retval = EES_SUCCESS;
330 while(temp_policy){
331 temp_policy->rules = remove_unreachable_rules(temp_policy->rules, &retval);
332 temp_policy = temp_policy->next;
333 }
334 return retval;
335 }
336
337 /* This function iterates the passed list of rules and removes those rules that, while they exist on the left-hand side, are never referenced on the right-hand side of a rule in the list */
338 rule_t* remove_unreachable_rules(rule_t* rules, EES_RC *retval){
339 rule_t *temp_rule = NULL, *next_rule = NULL, *previous_rule = rules;
340 if(rules){
341 temp_rule = rules->next;
342 while(temp_rule){
343 next_rule = temp_rule->next;
344
345 if(!(get_right_hand_rule(rules, temp_rule->state))){
346 eef_log(LOG_WARNING, "Removing unreachable rule %s at line %i\n", temp_rule->state, temp_rule->lineno);
347 clean_rules_tree(temp_rule);
348 previous_rule->next = next_rule;
349 temp_rule = previous_rule;
350 *retval = EES_FAILURE;
351 }
352 previous_rule = temp_rule;
353 temp_rule = next_rule;
354 }
355 }
356 return rules;
357 }
358
359 void link_dead_end_rules_in_policies(policy_t* policy){
360 policy_t* temp_policy = policy;
361 while(temp_policy){
362 link_dead_end_rules(temp_policy, temp_policy->rules);
363 temp_policy = temp_policy->next;
364 }
365 }
366
367 void link_dead_end_rules(policy_t* policy, rule_t* rule){
368 rule_t *temp_rule = rule, *true_rule, *false_rule;
369 while(temp_rule){
370 if(temp_rule->true_branch){
371 if((true_rule = get_left_hand_rule(policy->rules, temp_rule->true_branch->state))){
372 eef_log(LOG_DEBUG, "Overwriting rule %s with %s\n", temp_rule->true_branch->state, true_rule->state);
373 clean_rules_tree(temp_rule->true_branch);
374 temp_rule->true_branch = true_rule;
375 }
376 }
377 if(temp_rule->false_branch){
378 if((false_rule = get_left_hand_rule(policy->rules, temp_rule->false_branch->state))){
379 eef_log(LOG_DEBUG, "Overwriting rule %s with %s\n", temp_rule->false_branch->state, false_rule->state);
380 clean_rules_tree(temp_rule->false_branch);
381 temp_rule->false_branch = false_rule;
382 }
383 }
384 temp_rule = temp_rule->next;
385 }
386 policy->rules_list_transformed_to_tree = 1;
387 }
388
389 /*! Tries to find specified state in the rules_list */
390 rule_t* get_left_hand_rule(rule_t* temp_rule, const char* name){
391 if(!temp_rule || !name){
392 return NULL;
393 }
394
395 /* iterate while the rule isn't associated with the given state */
396 while(temp_rule){
397 if(!strcmp(name, temp_rule->state)){
398 return temp_rule;
399 }
400 temp_rule = temp_rule->next;
401 }
402 return NULL;
403 }
404
405 /*! Tries to find specified state in the rules_list */
406 rule_t* get_right_hand_rule(rule_t* temp_rule, const char* name){
407 if(!temp_rule || !name){
408 return NULL;
409 } else {
410 /* iterate while the rule isn't associated with the given state */
411 if(temp_rule->true_branch){
412 if(strcmp(name, temp_rule->true_branch->state) == 0){
413 return temp_rule->true_branch;
414 }
415 }
416 if(temp_rule->false_branch){
417 if(strcmp(name, temp_rule->false_branch->state) == 0){
418 return temp_rule->false_branch;
419 }
420 }
421 }
422 return NULL;
423 }
424
425 /*! Adds a new policy_t structure to the policies_list which will hold the current rules_list. rules_list is nulled after creating a policy so a new list can be created for the next policy */
426 void add_policy(record_t* policy, rule_t* top_rule){
427 policy_t* new_policy = NULL;
428 /*eef_log(LOG_DEBUG, "Found a new policy: %s\n", policy->string);*/
429
430 if((new_policy = calloc(1, sizeof(policy_t)))){
431 new_policy->name = strdup(policy->string);
432 new_policy->lineno = policy->lineno;
433 new_policy->rules = top_rule;
434 new_policy->rules_list_transformed_to_tree = 0;
435 new_policy->next = NULL;
436 }
437
438 /* append to the end of the list */
439 if(policies_list){
440 policies_list_last->next = new_policy;
441 } else {
442 policies_list = new_policy;
443 }
444 policies_list_last = new_policy;
445
446 /* start a new rules list */
447 rules_list = NULL;
448
449 free(policy->string);
450 policy->string = NULL;
451 free(policy);
452 policy = NULL;
453 }
454
455 /* prints the list of policies */
456 void print_policies(policy_t* policies){
457 policy_t* temp_policy = policies;
458 while(temp_policy){
459 eef_log(LOG_DEBUG, "Policy: %s\n", temp_policy->name);
460 print_rules(temp_policy, temp_policy->rules);
461 temp_policy = temp_policy->next;
462 }
463 return;
464 }
465
466
467 /* prints the list of rules */
468 void print_rules(policy_t* policy, rule_t* rule){
469 if(rule){
470 eef_log(LOG_DEBUG, " | Rule %s\n", rule->state);
471 eef_log(LOG_DEBUG, " -------------------------\n");
472 if(rule->true_branch){
473 print_rules(policy, get_left_hand_rule(policy->rules, rule->true_branch->state));
474 }
475 if(rule->false_branch){
476 print_rules(policy, get_left_hand_rule(policy->rules, rule->false_branch->state));
477 }
478 }
479 return;
480 }
481
482 /* tries to link all policy rules to a plugin in the plugin manager */
483 EES_RC link_rules_to_plugins(policy_t* policies){
484 policy_t *temp_policy = policies;
485
486 while(temp_policy){
487 link_rule_to_plugin(temp_policy, temp_policy->rules);
488 temp_policy = temp_policy->next;
489 }
490 return EES_SUCCESS;
491 }
492
493 void link_rule_to_plugin(policy_t *policy, rule_t *rule){
494 var_t *temp_var = NULL;
495 char** argv;
496 int argc;
497
498 eef_plugindl_t *temp_plugin = NULL;
499 if(rule){
500 if(!rule->plugin){
501 temp_var = get_variable_by_name(rule->state);
502 if(temp_var){
503 argv = _var_to_argv(temp_var->value, &argc);
504
505 temp_plugin = get_plugin(argv[0]);
506 if(temp_plugin){
507 rule->plugin = temp_plugin;
508 } else {
509 eef_log(LOG_WARNING, "Unknown plugin in variable %s\n", temp_var->value);
510 }
511 free_args(argc, argv);
512 }
513 } else {
514 eef_log(LOG_DEBUG, "Plugin already linked?\n");
515 }
516 link_rule_to_plugin(policy, rule->true_branch);
517 link_rule_to_plugin(policy, rule->false_branch);
518 }
519 return;
520 }
521
522 /* iterates the policies and removes those that are not explicitly named in the passed array of strings */
523 policy_t* reduce_policies(policy_t* policies, int number_of_policies, char* names_of_policies[]){
524 int i, policy_should_be_removed;
525 policy_t *temp_policy = policies, *next_policy = NULL;
526
527 while(temp_policy){
528 policy_should_be_removed = 1;
529 eef_log(LOG_DEBUG, "Checking policy: %s\n", (temp_policy)->name);
530 for(i = 0; i < number_of_policies; i++){
531 if(strcmp(temp_policy->name, names_of_policies[i]) == 0){
532 /* if the policy is in the named list, we can continue to the next plugin */
533 eef_log(LOG_DEBUG, "Allowed policy: %s\n", names_of_policies[i]);
534 policy_should_be_removed = 0;
535 break;
536 }
537 }
538
539 next_policy = temp_policy->next;
540
541 if(policy_should_be_removed){
542 eef_log(LOG_DEBUG, "Removing not-allowed policy: %s\n", temp_policy->name);
543 policies = remove_policy_by_name(policies, temp_policy->name);
544 }
545 temp_policy = next_policy;
546 }
547
548 return policies;
549 }
550
551 /*! concatenates two strings */
552 record_t* concat_strings(record_t* r1, record_t* r2){
553 record_t* new_record;
554 /*eef_log(LOG_DEBUG, "Concating: %s with %s\n", r1->string, r2->string);*/
555 if((new_record = malloc(sizeof(record_t)))){
556 if((new_record->string =
557 calloc(1, sizeof(char)*(strlen(r1->string) + strlen(r2->string)+1)))){
558 strncat(new_record->string, r1->string, strlen(r1->string));
559 strncat(new_record->string, r2->string, strlen(r2->string));
560 free(r1->string);
561 free(r1);
562 free(r2->string);
563 free(r2);
564 return new_record;
565 }
566 }
567 return NULL;
568 }
569
570 /*! concatenates two strings with a space in between */
571 record_t* concat_strings_with_space(record_t *r1, record_t* r2){
572 record_t *r;
573 /*eef_log(LOG_DEBUG, "Concating: %s with %s with spaces\n", r1->string, r2->string);*/
574 if((r = malloc(sizeof(record_t)))){
575 r->string = calloc(1,(sizeof(char)*(strlen(r1->string)+strlen(r2->string)+2)));
576 strncat(r->string, r1->string, strlen(r1->string));
577 strncat(r->string, " ", 1);
578 strncat(r->string, r2->string, strlen(r2->string));
579 free(r1->string);
580 free(r1);
581 free(r2->string);
582 free(r2);
583 return r;
584 }
585 return NULL;
586 }
587
588 /*! logs errors encountered during parsing */
589 int yyerror(char* string){
590 eef_log(LOG_ERR, "Parse error: %s at line %i in config file %s", string, lineno, config_file_s);
591 return 0;
592 }
593
594 /*! get variable from list */
595 var_t* get_variable_by_name(char* name){
596 for(current_variable = variables_list; current_variable != NULL; current_variable = current_variable->next){
597 if(!strncmp(name, current_variable->name, strlen(current_variable->name))){
598 return current_variable;
599 }
600 }
601 return NULL;
602 }
603
604 /*! Removes a policy from the list of policies */
605 void remove_policy(record_t* policy){
606 policy_t *temp_policy = policies_list, *next_policy = NULL;
607 eef_log(LOG_DEBUG, "Deleted policy: %s\n", policy->string);
608
609 while(temp_policy){
610 if(strcmp(temp_policy->name, policy->string) == 0){
611 /* target policy was found */
612 next_policy = temp_policy->next;
613
614 /* Clean policy fields */
615 if(temp_policy->rules_list_transformed_to_tree){
616 temp_policy->rules = clean_rules_tree(temp_policy->rules);
617 } else {
618 temp_policy->rules = clean_rules_list(temp_policy->rules);
619 }
620 free(temp_policy->name);
621 temp_policy->name = NULL;
622 free(temp_policy);
623 temp_policy = NULL;
624 }
625
626 /* Move to next policy */
627 temp_policy = next_policy;
628 }
629
630 free(policy->string);
631 free(policy);
632 return;
633 }
634
635 /*! Removes a policy from the list of policies */
636 policy_t* remove_policy_by_name(policy_t* policies, char* policy){
637 policy_t *temp_policy = NULL, *next_policy = NULL, *previous_policy = NULL;
638
639 for(temp_policy = policies; temp_policy != NULL; ){
640 next_policy = temp_policy->next;
641
642 if(strcmp(temp_policy->name, policy) == 0){
643 /* target policy was found */
644
645 /* Clean policy fields */
646 if(temp_policy->rules_list_transformed_to_tree){
647 clean_rules_tree(temp_policy->rules);
648 } else {
649 clean_rules_list(temp_policy->rules);
650 }
651
652 eef_log(LOG_DEBUG, "Deleted policy: %s\n", policy);
653 free(temp_policy->name);
654 free(temp_policy);
655
656 /* if the head node is deleted, overwrite it with the next node */
657 if(previous_policy){
658 previous_policy->next = next_policy;
659 } else {
660 policies = next_policy;
661 }
662 break;
663 }
664
665 previous_policy = temp_policy;
666
667 /* Move to next policy */
668 temp_policy = next_policy;
669 }
670
671 return policies;
672 }
673
674 /*! converts a string to an array of strings by splitting it at each \t delimiter
675 - overwrites the second argument with a pointer to the number of elements in the array */
676 char** _var_to_argv(char* value, int *argc){
677 char *start_of_arg = NULL, *copy_of_value = NULL, **argv = NULL;
678 char *delimiters = " \t";
679 size_t size_of_arg = 0, size_of_array, i = 0;
680 char *str_ptr;
681 copy_of_value = strdup(value);
682 size_of_array = (sizeof(char)*(strlen(copy_of_value)+1));
683 if((argv = calloc(1, size_of_array)) != NULL){
684 start_of_arg = strtok_r(copy_of_value, delimiters, &str_ptr);
685 while(start_of_arg != NULL){
686 size_of_arg = (sizeof(char)*(strlen(start_of_arg)+1));
687 if((argv[i] = calloc(1, size_of_arg))){
688 memcpy(argv[i], start_of_arg, size_of_arg);
689 start_of_arg = strtok_r(NULL, delimiters, &str_ptr);
690 i++;
691 }
692 }
693 }
694 free(copy_of_value);
695 copy_of_value = NULL;
696 if(i < ARG_MAX){
697 *argc = i;
698 } else {
699 *argc = ARG_MAX;
700 }
701 return argv;
702 }
703
704 /*! returns pdl path found in parsed config file */
705 const char* get_pdl_path(){
706 return _pdl_path;
707 }
708
709 /*! Iterates list of policies and the rules they contain and tries to let the plugin manager prepare plugin structs*/
710 EES_RC add_plugin_structs(){
711 char** argv;
712 int argc;
713 EES_RC plugin_struct_added_ok = EES_SUCCESS;
714 var_t *temp_var = variables_list;
715
716 while((temp_var != NULL) && (plugin_struct_added_ok == EES_SUCCESS)){
717 argv = _var_to_argv(temp_var->value, &argc);
718
719 /* this is a callout to the plug-in manager, which adds a struct describing a single plug-in to its list */
720 plugin_struct_added_ok = add_plugin_struct(argc, argv);
721
722 /* Move to next variable */
723 temp_var = temp_var->next;
724 }
725
726 return plugin_struct_added_ok;
727 }
728
729 /*! Iterates the list of var_t structures and tries to free them */
730 EES_RC clean_variables_list(){
731 current_variable = variables_list;
732 while(current_variable){
733 free(current_variable->name);
734 current_variable->name = NULL;
735 free(current_variable->value);
736 current_variable->value = NULL;
737
738 /* Move to next variable */
739 variables_list_last = current_variable;
740 current_variable = current_variable->next;
741
742 /* Clean last variable struct */
743 free(variables_list_last);
744 variables_list_last = NULL;
745 }
746 return EES_SUCCESS;
747 }
748
749 /*! Iterates the tree of rule_t structures starting with the passed rule and tries to free them and their true/false branches */
750 rule_t* clean_rules_tree(rule_t* top_rule){
751 rule_t* temp_rule = top_rule;
752 if(temp_rule){
753 clean_rules_tree(temp_rule->true_branch);
754
755 clean_rules_tree(temp_rule->false_branch);
756
757 free(temp_rule->state);
758 free(temp_rule);
759 temp_rule = NULL;
760 }
761 return NULL;
762 }
763
764 /*! Iterates the list of rule_t structures starting with the passed rule and tries to free them and their true/false branches */
765 rule_t* clean_rules_list(rule_t* top_rule){
766 rule_t *temp_rule = top_rule, *next_rule = NULL;
767 while(temp_rule){
768 next_rule = temp_rule->next;
769 clean_rules_tree(temp_rule);
770 temp_rule = next_rule;
771 }
772 return NULL;
773 }
774
775 void free_args(int argc, char** argv){
776 for(; argc > 0; argc--){
777 free(argv[argc-1]);
778 argv[argc-1] = NULL;
779 }
780 free(argv);
781 argv = NULL;
782 }
783
784 /*! Iterates the list of policy_t structures and tries to free them and their rules */
785 EES_RC clean_policies_list(policy_t* policies){
786 policy_t *temp_policy = policies, *last_policy = NULL;
787 while(temp_policy){
788 /* Clean policy fields */
789 if(temp_policy->rules_list_transformed_to_tree){
790 clean_rules_tree(temp_policy->rules);
791 } else {
792 clean_rules_list(temp_policy->rules);
793 }
794 free(temp_policy->name);
795 temp_policy->name = NULL;
796
797 /* Move to next policy */
798 last_policy = temp_policy;
799 temp_policy = temp_policy->next;
800 free(last_policy);
801 last_policy = NULL;
802 }
803 return EES_SUCCESS;
804 }
805
806 /*! Terminates the parser and tries to free all used memory */
807 EES_RC pdl_term(policy_t* policies){
808 clean_variables_list();
809 clean_policies_list(policies);
810 free(_pdl_path);
811 _pdl_path = NULL;
812
813 if(config_file_fp != NULL){
814 /* This is the preferred way of cleaning up various flex versions - See: http://flex.sourceforge.net/manual/Memory-leak-_002d-16386-bytes-allocated-by-malloc_002e.html#Memory-leak-_002d-16386-bytes-allocated-by-malloc_002e */
815 #if HAVE_YYLEX_DESTROY /* macro set by configure script */
816 yylex_destroy();
817 #else
818 /*eef_log(LOG_WARNING, "Lex function yylex_destroy() not available - possibly unable to free allocated memory for evaluation manager\n");*/
819 #if HAVE_FLEX
820 delete_lex_buffer(); /* this function is defined in pdl_lex.l */
821 /*eef_log(LOG_INFO, "Managed to free allocated memory for evaluation manager\n"); */
822 #else
823 eef_log(LOG_WARNING, "Lex functions yylex_destroy() and yy_delete_buffer() are both not available - unable to free allocated memory for evaluation manager\n");
824 #endif
825 #endif
826
827 if((fclose(config_file_fp)==0) ){
828 return EES_SUCCESS;
829 }
830 }
831 return EES_FAILURE;
832 }
833
834 /*! TODO */
835 EES_RC allow_rules(int val){
836 /*eef_log(LOG_DEBUG, "Allowed rule: %i\n", val);*/
837 return EES_SUCCESS;
838 }
839
840 /*! TODO */
841 EES_RC allowed_policy_rule(const char* label){
842 /*eef_log(LOG_DEBUG, "Allowed policy rule: %s\n", label);*/
843 return EES_SUCCESS;
844 }

grid.support@nikhef.nl
ViewVC Help
Powered by ViewVC 1.1.28