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

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