/[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 1123 - (show annotations) (download) (as text)
Fri Nov 13 16:00:45 2009 UTC (12 years, 2 months ago) by aramv
File MIME type: text/x-chdr
File size: 13973 byte(s)
Added functionality to create policies, pretty printer for debug purposes
1 #include "pdl.h"
2
3 /* Lex/Yacc stuff */
4 extern FILE * yyin;
5 extern int yylex_destroy(void);
6 extern int yyparse(void);
7 extern int yylex(void);
8 extern unsigned int lineno;
9 extern void delete_lex_buffer(void);
10
11 /* internal data */
12 static const char* config_file_s;
13 FILE* config_file_fp;
14 EES_RC config_file_ok;
15 static char* _pdl_path;
16
17 var_t* variables_list;
18 var_t* variables_list_last;
19 var_t* current_variable;
20
21 rule_t* rules_list;
22 rule_t* rules_list_last;
23 rule_t* current_rule;
24
25 policy_t* policies_list;
26 policy_t* policies_list_last;
27 policy_t* current_policy;
28
29 /*! initializes the parsing of the configuration file */
30 EES_RC pdl_init(const char* config_file_name){
31 config_file_s = config_file_name;
32 if((config_file_fp = fopen(config_file_s,"r")) != NULL){
33 yyin = config_file_fp;
34 yyparse();
35 print_policies();
36 if(initialize_plugins() == EES_SUCCESS){
37 return EES_SUCCESS;
38 }
39 } else {
40 eef_log(LOG_ERR, "Failed to open policy file %s", config_file_s);
41 }
42 return EES_FAILURE;
43 }
44
45 /*! sets the path to modules directory */
46 void set_modules_path(record_t* path){
47 size_t path_size = 0;
48 size_t string_size = (sizeof(char) * (strlen(path->string)+2)); /* size of string + extra slash + null byte */
49 _pdl_path = "";
50
51 /*struct stat sb;*/
52 /*if stat(MODUL*/
53
54 if(string_size < FILENAME_MAX){
55 path_size = string_size;
56 } else {
57 path_size = FILENAME_MAX;
58 }
59
60 if((_pdl_path = calloc(1, path_size))){
61 strncpy(_pdl_path, path->string, path_size);
62 strncat(_pdl_path, "/", 1);
63 }
64
65 eef_log(LOG_DEBUG, "Found a new modules path: %s\n", _pdl_path);
66
67 free(path->string);
68 free(path);
69 }
70
71 /*! 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 */
72 void add_variable(record_t* name, record_t* value){
73 /*eef_log(LOG_DEBUG, "Added variable name: %s\n", name->string);*/
74 /*eef_log(LOG_DEBUG, "Added variable value: %s\n", value->string);*/
75
76 /* allocate struct and populate fields */
77 if((current_variable = calloc(1,sizeof(var_t)))){
78 current_variable->name = strdup(name->string);
79 current_variable->value = strdup(value->string);
80 current_variable->lineno = name->lineno;
81 current_variable->next = NULL;
82 } else {
83 eef_log(LOG_ERR, "Out of memory!");
84 }
85
86 /* append to the end of the list */
87 if(variables_list){
88 variables_list_last->next = current_variable;
89 } else {
90 variables_list = current_variable;
91 }
92 variables_list_last = current_variable;
93
94 /* clean up */
95 free(name->string);
96 free(name);
97 free(value->string);
98 free(value);
99 }
100
101 /*! Adds a rule */
102 /*TODO describe function better*/
103 rule_t* add_rule(record_t* state, record_t* true_branch, record_t* false_branch){
104 rule_t *new_rule = NULL, *new_false_branch = NULL, *new_true_branch = NULL, *recursive_rule = NULL, *recurse_target = NULL;
105 var_t* temp_var = NULL;
106
107 if((new_rule = find_state(rules_list, state->string))){
108 eef_log(LOG_WARNING, "State %s at line %i is already in use at line %i.\n", state->string, state->lineno, new_rule->lineno);
109 } else {
110 /*find variables for rule */
111 if((temp_var = get_variable_by_name(state->string)) != NULL){
112 if((new_rule = calloc(1, sizeof(rule_t)))){
113 /* populate fields of current state */
114 new_rule->state = strdup(state->string);
115 new_rule->lineno = state->lineno;
116
117 /* populate fields of branches */
118 if(false_branch){
119 if((new_false_branch = calloc(1, sizeof(rule_t)))){
120 new_false_branch->state = strdup(false_branch->string);
121 new_false_branch->lineno = false_branch->lineno;
122 new_rule->false_branch = new_false_branch;
123 }
124 }
125 if(true_branch){
126 if((new_true_branch = calloc(1, sizeof(rule_t)))){
127 new_true_branch->state = strdup(true_branch->string);
128 new_true_branch->lineno = true_branch->lineno;
129 new_rule->true_branch = new_true_branch;
130 }
131 }
132
133 /* check for recursion */
134 if((recursive_rule = check_for_recursion(rules_list, new_rule))){
135 eef_log(LOG_WARNING, "Rule %s at line %i leads to recursion into state %s", new_rule->state, new_rule->lineno, recursive_rule->state);
136 } else {
137 /* add new rule at the end of the rules list */
138 if(rules_list){
139 rules_list_last->next = new_rule;
140 } else {
141 rules_list = new_rule;
142 }
143 rules_list_last = new_rule;
144 /*eef_log(LOG_DEBUG, "Added a new rule: %s\n", new_rule->state);*/
145 }
146
147 } else {
148 eef_log(LOG_ERR, "Out of memory!");
149 }
150
151 } else {
152 /* Errorous state - variable referenced in rule not previously defined */
153 eef_log(LOG_ERR, "Unknown variable %s at line %i in config file %s", state->string, state->lineno, config_file_s);
154 }
155 }
156
157 /* clean up */
158 if(state != NULL){
159 free(state->string);
160 free(state);
161 }
162 if(true_branch != NULL){
163 free(true_branch->string);
164 free(true_branch);
165 }
166 if(false_branch != NULL){
167 free(false_branch->string);
168 free(false_branch);
169 }
170
171 return new_rule;
172 }
173
174 rule_t* check_for_recursion(rule_t* rule_l, rule_t* rule_r){
175 rule_t* temp_rule = rule_l;
176
177 /* right hand rule leads to its own recursive state */
178 /* still need a way to reuse the code from the wile loop to do this check */
179 if(rule_r){
180 if(rule_r->true_branch){
181 if(strcmp(rule_r->state, rule_r->true_branch->state) == 0){
182 return rule_r->true_branch;
183 }
184 }
185
186 if(rule_r->false_branch){
187 if(strcmp(rule_r->state, rule_r->false_branch->state) == 0){
188 return rule_r->false_branch;
189 }
190 }
191 }
192
193 while(temp_rule){
194 if((temp_rule != NULL) && (rule_r != NULL)){
195 /* left hand and right hand state are equal */
196 if(strcmp(temp_rule->state, rule_r->state) == 0){
197 return rule_r;
198 }
199
200 /* start state and true branch of right hand rule are equal */
201 if(rule_r->true_branch){
202 if(strcmp(temp_rule->state, rule_r->true_branch->state) == 0){
203 return rule_r->true_branch;
204 }
205 } else {
206 return NULL;
207 }
208
209 /* start state and false branch of right hand side are equal */
210 if(rule_r->false_branch){
211 if(strcmp(temp_rule->state, rule_r->false_branch->state) == 0){
212 return rule_r->false_branch;
213 }
214 }
215 } else {
216 return NULL;
217 }
218 /* move to next rule */
219 temp_rule = temp_rule->next;
220 }
221 return NULL;
222 }
223
224 /* Tries to find specified state in the list */
225 rule_t* find_state(rule_t* rule, const char* state){
226 if(!rule || !state){
227 return NULL;
228 }
229
230 /* iterate while the rule isn't associated with the given state */
231 while(rule && strcmp(state, rule->state)){
232 rule = rule->next;
233 }
234 return rule;
235 }
236
237 /* TODO */
238 void add_policy(record_t* policy, rule_t* rule){
239 policy_t* new_policy = NULL;
240 /*eef_log(LOG_DEBUG, "Found a new policy: %s\n", policy->string);*/
241
242 if(new_policy = calloc(1, sizeof(policy_t))){
243 new_policy->name = strdup(policy->string);
244 new_policy->lineno = policy->lineno;
245 new_policy->rules = rule;
246 }
247
248 /* append to the end of the list */
249 if(policies_list){
250 policies_list_last->next = new_policy;
251 } else {
252 policies_list = new_policy;
253 }
254 policies_list_last = new_policy;
255
256 rules_list = NULL;
257
258 free(policy->string);
259 free(policy);
260 }
261
262 void print_policies(){
263 rule_t* temp_rule = NULL;
264 policy_t* temp_policy = policies_list;
265
266 while(temp_policy){
267 temp_rule = temp_policy->rules;
268 eef_log(LOG_DEBUG, "Policy: %s\n", temp_policy->name);
269 while(temp_rule){
270 eef_log(LOG_DEBUG, " | Rule %s\n", temp_rule->state);
271 eef_log(LOG_DEBUG, " -------------------------\n");
272 if(temp_rule->true_branch){
273 eef_log(LOG_DEBUG, " True branch: %s\n", temp_rule->true_branch->state);
274 }
275 /*if(temp_rule->true_branch && temp_rule->false_branch){*/
276 /*}*/
277 if(temp_rule->false_branch){
278 eef_log(LOG_DEBUG, " False branch: %s\n", temp_rule->false_branch->state);
279 }
280 eef_log(LOG_DEBUG, "\n");
281 temp_rule = temp_rule->next;
282 }
283 temp_policy = temp_policy->next;
284 }
285 }
286
287 /*! concatenates two strings */
288 record_t* concat_strings(record_t* r1, record_t* r2){
289 record_t* new_record;
290 /*eef_log(LOG_DEBUG, "Concating: %s with %s\n", r1->string, r2->string);*/
291 if((new_record = malloc(sizeof(record_t)))){
292 if((new_record->string =
293 calloc(1, sizeof(char)*(strlen(r1->string) + strlen(r2->string)+1)))){
294 strncat(new_record->string, r1->string, strlen(r1->string));
295 strncat(new_record->string, r2->string, strlen(r2->string));
296 free(r1->string);
297 free(r1);
298 free(r2->string);
299 free(r2);
300 return new_record;
301 }
302 }
303 return NULL;
304 }
305
306 /*! concatenates two strings with a space in between */
307 record_t* concat_strings_with_space(record_t *r1, record_t* r2){
308 record_t *r;
309 /*eef_log(LOG_DEBUG, "Concating: %s with %s with spaces\n", r1->string, r2->string);*/
310 if((r = malloc(sizeof(record_t)))){
311 r->string = calloc(1,(sizeof(char)*(strlen(r1->string)+strlen(r2->string)+2)));
312 strncat(r->string, r1->string, strlen(r1->string));
313 strncat(r->string, " ", 1);
314 strncat(r->string, r2->string, strlen(r2->string));
315 free(r1->string);
316 free(r1);
317 free(r2->string);
318 free(r2);
319 return r;
320 }
321 return NULL;
322 }
323
324 /*! logs errors encountered during parsing */
325 int yyerror(char* string){
326 eef_log(LOG_ERR, "Parse error: %s at line %i in config file %s", string, lineno, config_file_s);
327 return 0;
328 }
329
330 /*! get variable from list */
331 var_t* get_variable_by_name(char* name){
332 for(current_variable = variables_list; current_variable != NULL; current_variable = current_variable->next){
333 if(!strncmp(name, current_variable->name, strlen(current_variable->name))){
334 return current_variable;
335 }
336 }
337 return NULL;
338 }
339
340 /*TODO*/
341 /*! Removes a policy from the list of policies */
342 void remove_policy(record_t* policy){
343 eef_log(LOG_DEBUG, "Deleted policy: %s\n", policy->string);
344 free(policy->string);
345 free(policy);
346 }
347
348 /*! converts a string to an array of strings by splitting it at each \t delimiter
349 - overwrites the second argument with a pointer to the number of elements in the array */
350 char** _var_to_argv(char* value, int *argc){
351 char *start_of_arg = NULL, *copy_of_value = NULL, **argv = NULL;
352 char *delimiters = " \t";
353 size_t size_of_arg = 0, size_of_array, i = 0;
354 char *str_ptr;
355 copy_of_value = strdup(value);
356 size_of_array = (sizeof(char)*(strlen(copy_of_value)+1));
357 if((argv = calloc(1, size_of_array)) != NULL){
358 start_of_arg = strtok_r(copy_of_value, delimiters, &str_ptr);
359 while(start_of_arg != NULL){
360 size_of_arg = (sizeof(char)*(strlen(start_of_arg)+1));
361 if((argv[i] = calloc(1, size_of_arg))){
362 memcpy(argv[i], start_of_arg, size_of_arg);
363 start_of_arg = strtok_r(NULL, delimiters, &str_ptr);
364 i++;
365 }
366 }
367 }
368 free(copy_of_value);
369 if(i < ARG_MAX){
370 *argc = i;
371 } else {
372 *argc = ARG_MAX;
373 }
374 return argv;
375 }
376
377 const char* get_pdl_path(){
378 if(_pdl_path == NULL){
379 return "";
380 }
381 return _pdl_path;
382 }
383
384 /*! Iterates the list of plug-in structures and tries to initialize the specified plug-ins */
385 EES_RC initialize_plugins(){
386 char** argv;
387 int argc;
388 current_variable = variables_list;
389 while(current_variable && config_file_ok){
390 /* prepare arguments and add to plug-in manager */
391 argv = _var_to_argv(current_variable->value, &argc);
392 /* TODO rename addPlugin to something more uniform */
393 config_file_ok = addPlugin(argc, argv);
394 variables_list_last = current_variable;
395 current_variable = current_variable->next;
396 }
397 /*return EES_SUCCESS;*/
398 return config_file_ok;
399 }
400
401 /*! Iterates the list of plug-in structures and tries to free them */
402 EES_RC clean_variables_list(){
403 current_variable = variables_list;
404 while(current_variable){
405 free(current_variable->name);
406 free(current_variable->value);
407
408 variables_list_last = current_variable;
409 current_variable = current_variable->next;
410
411 free(variables_list_last);
412 }
413 return EES_SUCCESS;
414 }
415
416 /*! Iterates the list of plug-in structures and tries to free them */
417 EES_RC clean_rules_list(){
418 current_rule = rules_list;
419 while(current_rule){
420 free(current_rule->state);
421 free(current_rule->true_branch);
422 free(current_rule->false_branch);
423
424 rules_list_last = current_rule;
425 current_rule = current_rule->next;
426
427 free(rules_list_last);
428 }
429 return EES_SUCCESS;
430 }
431
432 /*! Terminates the parser and tries to free all used memory */
433 EES_RC pdl_term(){
434 clean_rules_list();
435 clean_variables_list();
436 free(_pdl_path);
437
438 if(config_file_fp != NULL){
439 /* 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 */
440 #if HAVE_YYLEX_DESTROY
441 yylex_destroy();
442 #else
443 eef_log(LOG_WARNING, "Lex function yylex_destroy() not available - possibly unable to free allocated memory for evaluation manager\n");
444 #if HAVE_FLEX
445 delete_lex_buffer();
446 eef_log(LOG_INFO, "Managed to free allocated memory for evaluation manager\n");
447 #endif
448 #endif
449 if((fclose(config_file_fp)==0) ){
450 return EES_SUCCESS;
451 }
452 }
453 return EES_FAILURE;
454 }
455
456 /*! TODO */
457 EES_RC allow_rules(int val){
458 return EES_SUCCESS;
459 }
460
461 /*! TODO */
462 EES_RC allowed_policy_rule(const char* label){
463 return EES_SUCCESS;
464 }

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