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

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