00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00034 #include <stdarg.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038
00039 #include "lcmaps_log.h"
00040 #include "pdl.h"
00041 #include "pdl_variable.h"
00042 #include "pdl_policy.h"
00043 #include "pdl_rule.h"
00044
00045 static const char* script_name = NULL;
00046 static const char* d_path = "/usr/lib";
00047 static const char* path = 0;
00048 static int path_lineno = 0;
00049 static plugin_t* top_plugin = NULL;
00050 static BOOL default_path = TRUE;
00051 static BOOL parse_error = FALSE;
00052 static char* level_str[PDL_SAME];
00053
00054 unsigned int lineno = 1;
00055
00056 void _set_path(const record_t* _path);
00057 record_t* _concat_strings(const record_t* s1, const record_t* s2, const char* extra);
00058 void reduce_policies(void);
00059 void init_name_args(plugin_t** plugin, const rule_t* rule, rule_type_t type);
00060 BOOL plugin_exists(const char* string);
00061 int find_first_space(const char* string);
00062
00063
00073 int pdl_init(const char* name)
00074 {
00075 if (name) {
00076 FILE* file;
00077
00078 script_name = strdup(name);
00079
00080 file = fopen(name, "r");
00081 if (file)
00082 yyin = file;
00083 else {
00084 warning(PDL_ERROR, "Could not open file '%s'.", name);
00085 return -1;
00086 }
00087 }
00088
00089
00090 path = d_path;
00091 default_path = TRUE;
00092
00093
00094
00095
00096
00097 while (top_plugin) {
00098 free(top_plugin->name);
00099 free(top_plugin->args);
00100 top_plugin = top_plugin->next;
00101 }
00102
00103
00104 level_str[PDL_INFO] = "info";
00105 level_str[PDL_WARNING] = "warning";
00106 level_str[PDL_ERROR] = "error";
00107 level_str[PDL_UNKNOWN] = "<unknown>";
00108
00109 parse_error = FALSE;
00110
00111 return 0;
00112 }
00113
00114
00121 int yyparse_errors(void)
00122 {
00123 return parse_error ? -1 : 0;
00124 }
00125
00126
00133 const plugin_t* get_plugins(void)
00134 {
00135 plugin_t* plugin;
00136 policy_t* policy;
00137
00138
00139
00140
00141
00142
00143 if (!policies_have_been_reduced()) {
00144 lcmaps_log(1, "The policies have not been reduced. Probably the startElevaluationManager has failed or has not been called yet.\n");
00145 return 0;
00146 }
00147
00148
00149
00150
00151
00152 if (top_plugin)
00153 return top_plugin;
00154
00155 policy = get_policies();
00156
00157 while (policy) {
00158 rule_t* rule = policy->rule;
00159
00160 lcmaps_log_debug(1, "processing policy: %s\n", policy->name);
00161 while (rule) {
00162 lcmaps_log_debug(1, " processing rule: %s -> %s | %s\n", rule->state, rule->true_branch, rule->false_branch);
00163
00164 lcmaps_log_debug(1, " get_plugins: initializing...\n");
00165 init_name_args(&plugin, rule, STATE);
00166 init_name_args(&plugin, rule, TRUE_BRANCH);
00167 init_name_args(&plugin, rule, FALSE_BRANCH);
00168 lcmaps_log_debug(1, " get_plugins: initializing done.\n");
00169
00170 rule = rule->next;
00171 }
00172 policy = policy->next;
00173 }
00174
00175 return top_plugin;
00176 }
00177
00178
00186 BOOL plugin_exists(const char* string)
00187 {
00188 int space, remainder;
00189 plugin_t *plugin;
00190
00191 space = find_first_space(string);
00192 remainder = strlen(string) - space - 1;
00193 plugin = top_plugin;
00194
00195 while (plugin) {
00196 if (plugin->name && strncmp(plugin->name, string, space)==0) {
00197 if (plugin->args)
00198 if (strncmp(plugin->args, string+space+1, remainder)!=0) {
00199 plugin = plugin->next;
00200 continue;
00201 }
00202 return TRUE;
00203 }
00204 plugin = plugin->next;
00205 }
00206
00207 return FALSE;
00208 }
00209
00210
00214 void init_name_args(plugin_t** plugin, const rule_t* rule, rule_type_t type)
00215 {
00216 int space, remainder;
00217 const char* string;
00218
00219 switch (type) {
00220 case STATE:
00221 string = rule->state;
00222 break;
00223 case TRUE_BRANCH:
00224 string = rule->true_branch;
00225 break;
00226 case FALSE_BRANCH:
00227 string = rule->false_branch;
00228 break;
00229 default:
00230 warning(PDL_ERROR, "init_name_args: unknown type!");
00231 return;
00232 }
00233
00234 lcmaps_log_debug(1, " init_name_args: processing: %s\n", string);
00235
00236 if (!string || plugin_exists(string)) {
00237 lcmaps_log_debug(1, " init_name_args: Either the plugin exists or string == 0.\n");
00238 return;
00239 }
00240
00241 lcmaps_log_debug(1, " init_name_args: plugin does not exists.\n");
00242
00243 if (!top_plugin) {
00244 top_plugin = (plugin_t*)malloc(sizeof(plugin_t));
00245 *plugin = top_plugin;
00246 }
00247 else {
00248 (*plugin)->next = (plugin_t*)malloc(sizeof(plugin_t));
00249 *plugin = (*plugin)->next;
00250 }
00251
00252 (*plugin)->name = (*plugin)->args = 0;
00253 (*plugin)->next = 0;
00254
00255 space = find_first_space(string);
00256
00257 lcmaps_log_debug(1, " init_name_args: space found a pos: %d strlen = %d.\n", space, strlen(string));
00258
00259 (*plugin)->name = (char *)malloc(space+1);
00260 strncpy((*plugin)->name, string, space);
00261 *((*plugin)->name+space) = '\0';
00262
00263 remainder = strlen(string)-space-1;
00264 if (remainder > 0) {
00265 (*plugin)->args = (char *)malloc(remainder+1);
00266 strncpy((*plugin)->args, string+space+1, remainder);
00267 *((*plugin)->args+remainder) = '\0';
00268 } else
00269 (*plugin)->args = 0;
00270
00271 (*plugin)->lineno = rule->lineno;
00272 (*plugin)->next = 0;
00273
00274 lcmaps_log_debug(1, " init_name_args: plugin->name = %s\n", (*plugin)->name);
00275 lcmaps_log_debug(1, " init_name_args: plugin->args = %s\n", (*plugin)->args);
00276 }
00277
00278
00288 int find_first_space(const char* string)
00289 {
00290 int space, max_length;
00291 space = 0;
00292 max_length = strlen(string);
00293
00294 for (; *string++ != ' ' && space < max_length; ++space);
00295
00296 return space;
00297 }
00298
00299
00305 const char *pdl_path(void)
00306 {
00307 return path;
00308 };
00309
00310
00318 int yyerror(const char* s)
00319 {
00320
00321
00322 warning(PDL_ERROR, s);
00323
00324 return 0;
00325 }
00326
00327
00335 void set_path(record_t* path)
00336 {
00337 _set_path(path);
00338
00339 free(path->string);
00340 free(path);
00341 }
00342
00343
00352 void _set_path(const record_t* _path)
00353 {
00354
00355
00356 if (!default_path) {
00357 warning(PDL_ERROR, "path already defined in: %d; ignoring this instance.", path_lineno);
00358 return;
00359 }
00360
00361 default_path = FALSE;
00362 path_lineno = _path->lineno;
00363 path = strdup(_path->string);
00364 }
00365
00366
00367
00371 void free_path(void)
00372 {
00373 if (!default_path && path) {
00374 free((char*)path);
00375 default_path = TRUE;
00376 path = 0;
00377 }
00378 }
00379
00380
00381
00392 record_t* concat_strings(record_t* s1, record_t* s2)
00393 {
00394 record_t* r = _concat_strings(s1, s2, 0);
00395
00396 free(s1->string);
00397 free(s2->string);
00398 free(s1);
00399 free(s2);
00400
00401 return r;
00402 }
00403
00404
00413 record_t* _concat_strings(const record_t* s1, const record_t* s2,
00414 const char* extra)
00415 {
00416 int len = strlen(s1->string);
00417 int len_extra = extra ? strlen(extra) : 0;
00418
00419 record_t* record = (record_t *)malloc(sizeof(record_t));
00420
00421 if (!(record->string = (char *)malloc(len + len_extra + strlen(s2->string)+1))) {
00422 warning(PDL_ERROR, "out of memory");
00423 return 0;
00424 }
00425
00426 strcpy(record->string, s1->string);
00427 if (extra)
00428 strcpy(record->string+len, extra);
00429 strcpy(record->string+len+len_extra, s2->string);
00430
00431
00432
00433 return record;
00434 }
00435
00436
00447 record_t* concat_strings_with_space(record_t* s1, record_t* s2)
00448 {
00449 record_t* r;
00450
00451
00452 if (strlen(s2->string)!=0) {
00453
00454
00455
00456
00457 if ((s1->string[strlen(s1->string)-1]=='"') &&
00458 (s2->string[strlen(s2->string)-1]=='"'))
00459 r = _concat_strings(s1, s2, 0);
00460 else
00461 r = _concat_strings(s1, s2, " ");
00462
00463 free(s1->string);
00464 free(s2->string);
00465 free(s1);
00466 free(s2);
00467 } else {
00468
00469
00470
00471
00472 r = (record_t*)malloc(sizeof(r));
00473 memcpy(r, s1, sizeof(r));
00474 }
00475
00476 return r;
00477 }
00478
00479
00497 const char* pdl_next_plugin(plugin_status_t status)
00498 {
00499 const static policy_t* current_policy = 0;
00500 const static rule_t* current_rule = 0;
00501 char* string = 0;
00502 const char* state = 0;
00503
00504 switch (status) {
00505 case EVALUATION_START:
00506
00507 if (!(current_policy = get_policies()))
00508 return 0;
00509 if (!(current_rule = current_policy->rule))
00510 return 0;
00511
00512 state = current_rule->state;
00513 break;
00514
00515 case EVALUATION_SUCCESS:
00516 if (current_rule)
00517 state = current_rule->true_branch;
00518
00519 if (current_policy && state)
00520 current_rule = find_state(current_policy->rule, state);
00521 else
00522 current_rule = 0;
00523 break;
00524
00525 case EVALUATION_FAILURE:
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540 if (current_rule)
00541 state = current_rule->false_branch;
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 if (!(current_rule && state)) {
00552 if (current_policy && (current_policy = current_policy->next)) {
00553 if ((current_rule = current_policy->rule))
00554 state = current_rule->state;
00555 }
00556 } else {
00557
00558 if (current_policy)
00559 current_rule = find_state(current_policy->rule, state);
00560 }
00561
00562 break;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571 if (state) {
00572 const char* tmp;
00573 int state_length, path_length;
00574
00575 tmp = state;
00576 state_length = path_length = 0;
00577
00578 while (*tmp!=' ' && *tmp++!='\0') {
00579 ++state_length;
00580 }
00581 path_length = strlen(pdl_path());
00582
00583
00584 string = (char*)malloc(state_length + path_length + 2);
00585 strcpy(string, pdl_path());
00586
00587
00588 if (string[path_length-1] != '/')
00589 string[path_length++] = '/';
00590 strncpy(string + path_length, state, state_length);
00591 string[path_length + state_length] = '\0';
00592 }
00593
00594 return string;
00595 }
00596
00597
00602 void free_resources(void)
00603 {
00604 if (script_name) {
00605 free((char*)script_name);
00606 script_name = 0;
00607 }
00608
00609 free_path();
00610
00611 free_variables();
00612 free_policies();
00613
00614
00615
00616
00617
00618
00619 if (yyin!=stdin && yyin!=stderr) {
00620 fclose(yyin);
00621 yyin=stdin;
00622 }
00623
00624 #ifdef HAVE_FLEX
00625 delete_lex_buffer();
00626 #endif
00627 }
00628
00629
00638 void warning(pdl_error_t error, const char* s, ...)
00639 {
00640 static char* level = 0;
00641 char buf[2048];
00642 int res;
00643
00644 va_list args;
00645
00646 if (error == PDL_ERROR)
00647 parse_error = TRUE;
00648
00649 if (!level)
00650 level = level_str[PDL_UNKNOWN];
00651
00652 if (error != PDL_SAME)
00653 level = level_str[error];
00654
00655
00656
00657
00658
00659 res = sprintf(buf, "%s:%d: [%s] ", script_name, lineno, level);
00660
00661
00662 va_start(args, s);
00663 res += vsnprintf(buf+res, sizeof(buf)-res-2, s, args);
00664 va_end(args);
00665
00666
00667
00668
00669
00670
00671 buf[res<sizeof(buf)-1 ? res++ : sizeof(buf)-2] = '\n';
00672 buf[res<sizeof(buf) ? res : sizeof(buf)-1] = '\0';
00673
00674 lcmaps_log(0, buf);
00675 }
00676