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

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