int main (int argc, char **argv) { s_rules rr; if (argv[argc]) err(1, "bad argument list"); if (argc != 3) usage(argv[0]); if (strcmp(argv[1], "-c")) usage(argv[0]); openlog(argv[0], LOG_PID, LOG_AUTH); log_args("NEW", argc, (const char **)argv); init_package(); { const char *env_auth_id = getenv(ENV_AUTH_ID); t_sym id = sympackage_intern(&g_sympkg, env_auth_id ? env_auth_id : ""); s_symtable cmd; cmd_init(&cmd, id, argv[2]); rules_init(&rr); rules_read(&rr, "/etc/git-auth.conf"); { int auth_ok = auth(&rr, &cmd); rules_free(&rr); log_rule(auth_ok ? "ALLOW" : "DENY", &cmd); if (auth_ok) { exec_cmd(&cmd); // never reached } } log_rule("DENY", &cmd); } cleanup(); return 1; }
static void attend_cntrl_msg(int sfd, short ev, void *arg) { // int s, // *nsfd; // pthread_t t1; // if((nsfd = malloc(sizeof(int))) == NULL){ // dbg_e("Error on malloc() the control socket file descriptor", NULL); // return; // } // *nsfd = sfd; // s = pthread_create(&t1, NULL, attend_cntrl_msg_thread, (void *) nsfd); // if(s != 0) // dbg("Unable to create the thread to receive control messages", strerror(s)); int psfd; // int sfd = *((int *) arg); // free((int *) arg); struct r_msg response; struct r_msg *msg; void *data; response.hd.mtype = ACK; response.hd.size = 0; response.msg = NULL; psfd = accept(sfd, NULL, NULL); if((msg = receive_cntrl_msg(psfd)) == NULL) { err("Error in the communication with 'reactorctl'"); goto end; } switch(msg->hd.mtype) { case EVENT: reactor_event_handler(&reactor, msg->msg); send_cntrl_msg(psfd, &response); free(msg->msg); break; case ADD_RULE: /* TODO Change uid to the user who sent the rule */ data = (void *) r_rule_parse(msg->msg); response.hd.mtype = reactor_add_rule_handler(&reactor, (struct r_rule *) data); rules_free((struct r_rule *) data); send_cntrl_msg(psfd, &response); free(msg->msg); break; case RM_TRANS: response.hd.mtype = reactor_rm_trans_handler(&reactor, msg->msg); send_cntrl_msg(psfd, &response); free(msg->msg); default: break; } end: close(psfd); free(msg); }
END_TEST START_TEST(test_tokenizer_comments){ struct r_rule *rule; struct rr_expr rexpr; char *line; line = "A | B # This is a very simple rule"; rexpr.exprnum = 0; rexpr.tokensep = '|'; rexpr.end = '\0'; rexpr.trim = true; rexpr.next = NULL; rexpr.subexpr = NULL; rule = tokenize_rule(line, &rexpr); fail_unless(rule->objs != NULL); fail_unless(rule->errors == NULL); fail_unless(strcmp(rule->objs->data, "A") == 0); fail_unless(rule->objs->next != NULL); fail_unless(rule->objs->down == NULL); fail_unless(strcmp(rule->objs->next->data, "B") == 0); fail_unless(rule->objs->next->next == NULL); fail_unless(rule->objs->next->down == NULL); rules_free(rule); line = "# This is comment line"; rule = tokenize_rule(line, &rexpr); fail_unless(rule->objs == NULL); fail_unless(rule->errors == NULL); rules_free(rule); }
void analyzer_free(Analyzer * analyzer) { MA_DEBUG("[MANALYZER] Finishing MAnalyzer.\n"); lemmas_rules_free(analyzer -> l_rules); endings_rules_free(analyzer -> e_rules); forms_free(analyzer -> forms); rules_free(analyzer -> rules); normal_forms_free(analyzer -> n_forms); delete analyzer; MA_DEBUG("[MANALYZER] Succesfully finished MAnalyzer.\n"); }
void destroy(void) { struct monitor *mon; for (mon = mons; mon; mon = mon->next) { while (mon->cstack) remove_client(mon->cstack, false); } while (mons) mons = monitor_free(mons); bars_free(); cursors_free(); rules_free(); x11_destroy(); }
/* TODO Main admin rules file */ static void init_rules() { struct r_user *users; struct r_rule *rules; char filename[PATH_MAX]; unsigned int fnln; for(users = load_users(R_GRP); users != NULL; users = users->next) { strcpy(filename, users->pw->pw_dir); fnln = strlen(users->pw->pw_dir); strcpy(&filename[fnln], "/."); fnln += strlen("/."); strcpy(&filename[fnln], RULES_FILE); for(rules = parse_rules_file(filename, r_rule_parse); rules != NULL; rules = rules->next) { reactor_add_rule_handler(&reactor, rules); } rules_free(rules); } }
END_TEST START_TEST(test_tokenizer_reactor_rule_long){ struct r_rule *rrule; struct rr_expr rexpr; struct rr_expr evexpr; struct rr_expr actexpr; char *line; char *expectedmsg; expectedmsg = "'%s' token content was expected instead of '%s'"; line = "A B e1 &e2 & e3&e4& e5 CMD echo \"A->B\" >> /tmp/test"; rexpr.exprnum = 0; rexpr.tokensep = ' '; rexpr.end = '\0'; rexpr.trim = true; rexpr.next = NULL; rexpr.subexpr = &evexpr; evexpr.exprnum = 2; evexpr.tokensep = '&'; evexpr.end = ' '; evexpr.trim = true; evexpr.next = &actexpr; evexpr.subexpr = NULL; actexpr.exprnum = 4; actexpr.tokensep = '\0'; actexpr.end = '\0'; actexpr.trim = true; actexpr.next = NULL; actexpr.subexpr = NULL; rrule = tokenize_rule(line, &rexpr); fail_unless(rrule->errors == NULL); fail_unless(rrule->objs != NULL); fail_unless(strcmp(rrule->objs->data, "A") == 0, expectedmsg, "A", rrule->objs->data ); fail_unless(rrule->objs->down == NULL); fail_unless(rrule->objs->next != NULL); fail_unless(strcmp(rrule->objs->next->data, "B") == 0, expectedmsg, "B", rrule->objs->next->data ); fail_unless(rrule->objs->next->down == NULL); fail_unless(rrule->objs->next->next != NULL); fail_unless(rrule->objs->next->next->data == NULL); fail_unless(rrule->objs->next->next->down != NULL); fail_unless(rrule->objs->next->next->next != NULL); fail_unless(strcmp(rrule->objs->next->next->down->data, "e1") == 0, expectedmsg, "e1", rrule ); fail_unless(rrule->objs->next->next->down->down == NULL); fail_unless(rrule->objs->next->next->down->next != NULL); fail_unless(strcmp(rrule->objs->next->next->down->next->data, "e2") == 0, expectedmsg, "e2", rrule ); fail_unless(rrule->objs->next->next->down->next->down == NULL); fail_unless(rrule->objs->next->next->down->next->next != NULL); fail_unless(strcmp(rrule->objs->next->next->down->next->next->data, "e3") == 0, expectedmsg, "e3", rrule ); fail_unless(rrule->objs->next->next->down->next->next->down == NULL); fail_unless(rrule->objs->next->next->down->next->next->next != NULL); fail_unless(strcmp(rrule->objs->next->next->down->next->next->next->data, "e4") == 0, expectedmsg, "e4", rrule ); fail_unless(rrule->objs->next->next->down->next->next->next->down == NULL); fail_unless(rrule->objs->next->next->down->next->next->next->next != NULL); fail_unless(strcmp(rrule->objs->next->next->down->next->next->next->next->data, "e5") == 0, expectedmsg, "e5", rrule ); fail_unless(rrule->objs->next->next->down->next->next->next->next->down == NULL); fail_unless(rrule->objs->next->next->down->next->next->next->next->next == NULL); fail_unless(strcmp(rrule->objs->next->next->next->data, "CMD") == 0, expectedmsg, "CMD", rrule->objs->next->next->next->data ); fail_unless(rrule->objs->next->next->next->down == NULL); fail_unless(rrule->objs->next->next->next->next != NULL); fail_unless(rrule->objs->next->next->next->next->data == NULL); fail_unless(rrule->objs->next->next->next->next->down != NULL); fail_unless(rrule->objs->next->next->next->next->next == NULL); fail_unless(strcmp(rrule->objs->next->next->next->next->down->data, "echo \"A->B\" >> /tmp/test") == 0, expectedmsg, "echo \"A->B\" >> /tmp/test", rrule->objs->next->next->next->data ); fail_unless(rrule->objs->next->next->next->next->down->down == NULL); fail_unless(rrule->objs->next->next->next->next->down->next == NULL); rules_free(rrule); }
END_TEST START_TEST(test_tokenizer_reactor_rule_short){ struct r_rule *rrule; struct rr_expr rexpr; struct rr_expr evexpr; struct rr_expr actexpr; char *expectedmsg; char *line; expectedmsg = "'%s' token content was expected instead of '%s'"; line = "A B e1 PROP localhost"; rexpr.exprnum = 0; rexpr.tokensep = ' '; rexpr.end = '\0'; rexpr.trim = true; rexpr.next = NULL; rexpr.subexpr = &evexpr; evexpr.exprnum = 2; evexpr.tokensep = '&'; evexpr.end = ' '; evexpr.trim = true; evexpr.next = &actexpr; evexpr.subexpr = NULL; actexpr.exprnum = 4; actexpr.tokensep = '\0'; actexpr.end = '\0'; actexpr.trim = true; actexpr.next = NULL; actexpr.subexpr = NULL; rrule = tokenize_rule(line, &rexpr); fail_unless(rrule->errors == NULL); fail_unless(rrule->objs != NULL); fail_unless(strcmp(rrule->objs->data, "A") == 0, expectedmsg, "A", rrule->objs->data ); fail_unless(rrule->objs->down == NULL); fail_unless(rrule->objs->next != NULL); fail_unless(strcmp(rrule->objs->next->data, "B") == 0, expectedmsg, "B", rrule->objs->next->data ); fail_unless(rrule->objs->next->down == NULL); fail_unless(rrule->objs->next->next != NULL); fail_unless(rrule->objs->next->next->data == NULL); fail_unless(rrule->objs->next->next->down != NULL); fail_unless(rrule->objs->next->next->next != NULL); fail_unless(strcmp(rrule->objs->next->next->down->data, "e1") == 0, expectedmsg, "e1", rrule ); fail_unless(rrule->objs->next->next->down->down == NULL); fail_unless(rrule->objs->next->next->down->next == NULL); fail_unless(strcmp(rrule->objs->next->next->next->data, "PROP") == 0, expectedmsg, "PROP", rrule->objs->next->next->next->data ); fail_unless(rrule->objs->next->next->next->down == NULL); fail_unless(rrule->objs->next->next->next->next != NULL); fail_unless(rrule->objs->next->next->next->next->data == NULL); fail_unless(rrule->objs->next->next->next->next->down != NULL); fail_unless(rrule->objs->next->next->next->next->next == NULL); fail_unless(strcmp(rrule->objs->next->next->next->next->down->data, "localhost") == 0, expectedmsg, "localhost", rrule->objs->next->next->next->data ); fail_unless(rrule->objs->next->next->next->next->down->down == NULL); fail_unless(rrule->objs->next->next->next->next->down->next == NULL); rules_free(rrule); }
END_TEST START_TEST(test_tokenizer_notrim){ struct r_rule *rule; struct rr_expr rexpr; struct rr_expr iexpr; char *line; line = "A |B| C|z y x| D"; rexpr.exprnum = 0; rexpr.tokensep = '|'; rexpr.end = '\0'; rexpr.trim = false; rexpr.next = NULL; rexpr.subexpr = &iexpr; iexpr.exprnum = 3; iexpr.tokensep = ' '; iexpr.end = '|'; iexpr.trim = false; iexpr.next = NULL; iexpr.subexpr = NULL; rule = tokenize_rule(line, &rexpr); fail_unless(rule->objs != NULL); fail_unless(rule->errors == NULL); fail_unless(strcmp(rule->objs->data, "A ") == 0); fail_unless(rule->objs->next != NULL); fail_unless(rule->objs->down == NULL); fail_unless(strcmp(rule->objs->next->data, "B") == 0); fail_unless(rule->objs->next->next != NULL); fail_unless(rule->objs->next->down == NULL); fail_unless(strcmp(rule->objs->next->next->data, " C") == 0); fail_unless(rule->objs->next->next->next != NULL); fail_unless(rule->objs->next->next->down == NULL); fail_unless(rule->objs->next->next->next->data == NULL); fail_unless(rule->objs->next->next->next->next != NULL); fail_unless(rule->objs->next->next->next->down != NULL); fail_unless(strcmp(rule->objs->next->next->next->down->data, "z") == 0); fail_unless(rule->objs->next->next->next->down->next != NULL); fail_unless(rule->objs->next->next->next->down->down == NULL); fail_unless(strcmp(rule->objs->next->next->next->down->next->data, "y") == 0); fail_unless(rule->objs->next->next->next->down->next->next != NULL); fail_unless(rule->objs->next->next->next->down->next->down == NULL); fail_unless(strcmp(rule->objs->next->next->next->down->next->data, "x") == 0); fail_unless(rule->objs->next->next->next->down->next->next == NULL); fail_unless(rule->objs->next->next->next->down->next->down == NULL); fail_unless(strcmp(rule->objs->next->next->next->next->data, " D") == 0); fail_unless(rule->objs->next->next->next->next->next == NULL); fail_unless(rule->objs->next->next->next->next->down == NULL); rules_free(rule); }
END_TEST START_TEST(test_tokenizer_tokens_lack){ struct r_rule *rule; struct rr_expr rexpr; struct rr_expr subrexpr; struct rr_expr subrexpr2; char *line; rexpr.exprnum = 0; rexpr.tokensep = '|'; rexpr.end = '\0'; rexpr.trim = true; rexpr.next = NULL; rexpr.subexpr = &subrexpr; subrexpr.exprnum = 2; subrexpr.tokensep = '&'; subrexpr.end = '|'; subrexpr.trim = true; subrexpr.next = &subrexpr; subrexpr.subexpr = NULL; subrexpr2.exprnum = 3; subrexpr2.tokensep = '\0'; subrexpr2.end = '\0'; subrexpr2.trim = true; subrexpr2.next = NULL; subrexpr2.subexpr = NULL; line = "A | B"; rule = tokenize_rule(line, &rexpr); fail_unless(rule->errors == NULL); fail_unless(rule->objs != NULL); fail_unless(strcmp(rule->objs->data, "A") == 0); fail_unless(rule->objs->down == NULL); fail_unless(rule->objs->next != NULL); fail_unless(strcmp(rule->objs->next->data, "B") == 0); fail_unless(rule->objs->next->down == NULL); fail_unless(rule->objs->next->next == NULL); rules_free(rule); line = "A | B | C"; rule = tokenize_rule(line, &rexpr); fail_unless(rule->errors == NULL); fail_unless(rule->objs != NULL); fail_unless(strcmp(rule->objs->data, "A") == 0); fail_unless(rule->objs->down == NULL); fail_unless(rule->objs->next != NULL); fail_unless(strcmp(rule->objs->next->data, "B") == 0); fail_unless(rule->objs->next->down == NULL); fail_unless(rule->objs->next->next != NULL); fail_unless(rule->objs->next->next->data == NULL); fail_unless(rule->objs->next->next->next == NULL); fail_unless(rule->objs->next->next->down != NULL); fail_unless(strcmp(rule->objs->next->next->down->data, "C") == 0); fail_unless(rule->objs->next->next->down->next == NULL); fail_unless(rule->objs->next->next->down->down == NULL); rules_free(rule); }
END_TEST START_TEST(test_parser_cmd_rule){ struct r_rule *rule; struct rr_obj *fromobj, *toobj, *eventsobj, *actionobj; struct r_action *action; struct cmd_action *cmdaction; char *line; line = "STATE_A STATE_B event1& event2 &event3& event4 CMD echo \"test\" >> /tmp/test"; rule = r_rule_parse(line); fail_unless(rule != NULL); fail_unless(rule->errors == NULL); fail_unless((fromobj = get_rule_obj(rule->objs, RULE_FROM)) != NULL); fail_unless(strcmp((char *)fromobj->data, "STATE_A") == 0); fail_unless((toobj = get_rule_obj(rule->objs, RULE_TO)) != NULL); fail_unless(strcmp((char *)toobj->data, "STATE_B") == 0); fail_unless((eventsobj = get_rule_obj(rule->objs, RULE_EVENTS)) != NULL); fail_unless(eventsobj->down != NULL); fail_unless(get_rule_obj(eventsobj->down, 0) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 0))->data, "event1") == 0); fail_unless(get_rule_obj(eventsobj->down, 1) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 1))->data, "event2") == 0); fail_unless(get_rule_obj(eventsobj->down, 2) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 2))->data, "event3") == 0); fail_unless(get_rule_obj(eventsobj->down, 3) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 3))->data, "event4") == 0); fail_unless((actionobj = get_rule_obj(rule->objs, RULE_RACTION)) != NULL); fail_unless((action = (struct r_action *) actionobj->data) != NULL); fail_unless(actionobj->next == NULL); fail_unless(actionobj->down == NULL); fail_unless(action->atype == CMD); cmdaction = (struct cmd_action *)action->action; fail_unless(strcmp(cmdaction->cmd, "echo \"test\" >> /tmp/test") == 0); action_free(actionobj->data); actionobj->data = NULL; rule_objs_free(actionobj); actionobj = NULL; eventsobj->next = NULL; rules_free(rule); line = "STATE_A STATE_B event1& event2 &event3& event4 CMD"; rule = r_rule_parse(line); fail_unless(rule != NULL); fail_unless(rule->errors != NULL); fail_unless(rule->objs == NULL); }
END_TEST START_TEST(test_parser_none_rule){ struct r_rule *rule; struct rr_obj *fromobj, *toobj, *eventsobj, *actionobj; struct r_action *action; char *line = "STATE_A STATE_B event1"; rule = r_rule_parse(line); fail_unless(rule != NULL); fail_unless(rule->errors == NULL); fail_unless((fromobj = get_rule_obj(rule->objs, RULE_FROM)) != NULL); fail_unless(strcmp((char *)fromobj->data, "STATE_A") == 0); fail_unless((toobj = get_rule_obj(rule->objs, RULE_TO)) != NULL); fail_unless(strcmp((char *)toobj->data, "STATE_B") == 0); fail_unless((eventsobj = get_rule_obj(rule->objs, RULE_EVENTS)) != NULL); fail_unless(eventsobj->down != NULL); fail_unless(get_rule_obj(eventsobj->down, 0) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 0))->data, "event1") == 0); fail_unless((get_rule_obj(eventsobj->down, 0))->next == NULL); fail_unless((get_rule_obj(eventsobj->down, 0))->down == NULL); fail_unless((actionobj = get_rule_obj(rule->objs, RULE_RACTION)) != NULL); fail_unless((action = (struct r_action *) actionobj->data) != NULL); fail_unless(actionobj->next == NULL); fail_unless(actionobj->down == NULL); fail_unless(action->atype == NONE); action_free(actionobj->data); actionobj->data = NULL; rule_objs_free(actionobj); actionobj = NULL; eventsobj->next = NULL; rules_free(rule); line = "STATE_A STATE_B event1 NONE"; rule = r_rule_parse(line); fail_unless(rule != NULL); fail_unless(rule->errors == NULL); fail_unless((fromobj = get_rule_obj(rule->objs, RULE_FROM)) != NULL); fail_unless(strcmp((char *)fromobj->data, "STATE_A") == 0); fail_unless((toobj = get_rule_obj(rule->objs, RULE_TO)) != NULL); fail_unless(strcmp((char *)toobj->data, "STATE_B") == 0); fail_unless((eventsobj = get_rule_obj(rule->objs, RULE_EVENTS)) != NULL); fail_unless(eventsobj->down != NULL); fail_unless(get_rule_obj(eventsobj->down, 0) != NULL); fail_unless(strcmp((char *)(get_rule_obj(eventsobj->down, 0))->data, "event1") == 0); fail_unless((get_rule_obj(eventsobj->down, 0))->next == NULL); fail_unless((get_rule_obj(eventsobj->down, 0))->down == NULL); fail_unless((actionobj = get_rule_obj(rule->objs, RULE_RACTION)) != NULL); fail_unless((action = (struct r_action *) actionobj->data) != NULL); fail_unless(actionobj->next == NULL); fail_unless(actionobj->down == NULL); fail_unless(action->atype == NONE); action_free(actionobj->data); actionobj->data = NULL; rule_objs_free(actionobj); actionobj = NULL; eventsobj->next = NULL; rules_free(rule); line = "STATE_A STATE_B event1 NONE this shouldn't be here"; rule = r_rule_parse(line); fail_unless(rule != NULL); fail_unless(rule->errors != NULL); fail_unless(rule->objs == NULL); rules_free(rule); }
static STANDARDIZER * CreateStd(char *lextab, char *gaztab, char *rultab) { STANDARDIZER *std; LEXICON *lex; LEXICON *gaz; RULES *rules; int err; int SPIcode; DBG("Enter: CreateStd"); SPIcode = SPI_connect(); if (SPIcode != SPI_OK_CONNECT) { elog(ERROR, "CreateStd: couldn't open a connection to SPI"); } std = std_init(); if (!std) elog(ERROR, "CreateStd: could not allocate memory (std)"); lex = lex_init(std->err_p); if (!lex) { std_free(std); SPI_finish(); elog(ERROR, "CreateStd: could not allocate memory (lex)"); } err = load_lex(lex, lextab); if (err == -1) { lex_free(lex); std_free(std); SPI_finish(); elog(ERROR, "CreateStd: failed to load '%s' for lexicon", lextab); } gaz = lex_init(std->err_p); if (!gaz) { lex_free(lex); std_free(std); SPI_finish(); elog(ERROR, "CreateStd: could not allocate memory (gaz)"); } err = load_lex(gaz, gaztab); if (err == -1) { lex_free(gaz); lex_free(lex); std_free(std); SPI_finish(); elog(ERROR, "CreateStd: failed to load '%s' for gazeteer", gaztab); } rules = rules_init(std->err_p); if (!rules) { lex_free(gaz); lex_free(lex); std_free(std); SPI_finish(); elog(ERROR, "CreateStd: could not allocate memory (rules)"); } err = load_rules(rules, rultab); if (err == -1) { rules_free(rules); lex_free(gaz); lex_free(lex); std_free(std); SPI_finish(); elog(ERROR, "CreateStd: failed to load '%s' for rules", rultab); } std_use_lex(std, lex); std_use_gaz(std, gaz); std_use_rules(std, rules); std_ready_standardizer(std); SPI_finish(); return std; }
/** * Parses an entire file of rules. * * @1 The whole file in memory or mmap'd * * Returns: A newly allocated ruleset. */ struct rules_t *rules_from_config(char *input, struct rules_t *return_rules) { #define last_rule return_rules->rules[return_rules->rules_c - 1] int nested; int status; int terminate; char *buf; /* * TODO: cleanup * * BIIIG cleanup... Use callbacks for actions and for internal actions. */ int i, j; struct key_rec_t conditions[] = { /*NOTE: We never have parameters for conditions. */ {"is", 0, COND_MATCH_IS}, {"==", 0, COND_MATCH_CMP}, {"!=", 0, COND_NMATCH_CMP}, {"~~", 0, COND_MATCH_RE}, {"!~", 0, COND_NMATCH_RE}, {NULL, 0, -1} }; struct key_rec_t actions[] = { /*one line / one command*/ {"run", 1, ACT_RUN_SHELL}, {"exec", -1, ACT_RUN_NOSHELL}, {"break", 0, ACT_STOP_PROCESSING}, {"break_if_failed", 0, ACT_STOP_IF_FAILED}, {"next", 0, ACT_NEXT_EVENT}, {"next_if_failed", 0, ACT_NEXT_IF_FAILED}, {"chown", 2, ACT_CHOWN}, {"chmod", 2, ACT_CHMOD}, {"chgrp", 2, ACT_CHGRP}, {"setenv", 2, ACT_SETENV}, {"remove", 1, ACT_REMOVE}, {"nothrottle", 0, ACT_FLAG_NOTHROTTLE}, {"printdebug", 0, ACT_DEBUG}, /*symlink*/ {"symlink", 2, ACT_SYMLINK}, {"softlink", 2, ACT_SYMLINK}, /*makedev*/ {"mknod", 2, ACT_MAKE_DEVICE}, {"makedev", 2, ACT_MAKE_DEVICE}, {NULL, 0, -1} }; /* * A little trick for inclusion. */ if (return_rules == NULL) { return_rules = xmalloc(sizeof(struct rules_t)); return_rules->rules_c = 1; return_rules->rules = xmalloc(sizeof(struct rule_t) * return_rules->rules_c); nested = 0; } else { nested = 1; } status = STATUS_KEY; last_rule.actions = NULL; last_rule.actions_c = 0; last_rule.conditions = NULL; last_rule.conditions_c = 0; terminate = 0; do { buf = rules_get_value(input, &input); if (buf == NULL) { ERROR("rules_get_value", "Malformed rule - unable to read!"); terminate = 1; break; } if (buf[0] == '#') { /* Skip to next line */ while (*input != '\0' && *input != '\n') input++; free(buf); continue; } else if (buf[0] == '$') { buf++; /* * Warning, hack ahead... */ if (!strcmp("include", buf)) { buf = rules_get_value(input, &input); if (rules_include(buf, &return_rules)) { ERROR("rules_include", "Unable to include ruleset '%s'!", buf); } } free(buf); continue; } switch (status) { case STATUS_KEY: last_rule.conditions_c++; last_rule.conditions = xrealloc(last_rule.conditions, sizeof(struct condition_t) * last_rule.conditions_c); last_rule.conditions[last_rule.conditions_c-1].key = strdup(buf); status = STATUS_CONDTYPE; break; case STATUS_CONDTYPE: last_rule.conditions[last_rule.conditions_c-1].type = -1; for (i = 0; conditions[i].key != NULL; i++) { if (!strcmp(conditions[i].key, buf)) { last_rule.conditions[last_rule.conditions_c-1].type = conditions[i].type; break; } } if (last_rule.conditions[last_rule.conditions_c-1].type == -1) { ERROR("rules_get_value / status / condtype", "Malformed rule - unknown condition type."); terminate = 1; } status = STATUS_VALUE; break; case STATUS_VALUE: last_rule.conditions[last_rule.conditions_c-1].value = strdup(buf); status = STATUS_INITIATOR; break; case STATUS_INITIATOR: if (!strcmp(buf, ",") || !strcmp(buf, ";")) { status = STATUS_KEY; } else if (!strcmp(buf, "{")) { status = STATUS_ACTION; } else { ERROR("rules_get_value / status / initiator", "Malformed rule - unknown initiator."); terminate = 1; } break; case STATUS_ACTION: if (!strcmp(buf, "}")) { status = STATUS_KEY; return_rules->rules_c++; return_rules->rules = xrealloc(return_rules->rules, sizeof(struct rule_t) * return_rules->rules_c); last_rule.actions = NULL; last_rule.actions_c = 0; last_rule.conditions = NULL; last_rule.conditions_c = 0; break; } last_rule.actions_c++; last_rule.actions = xrealloc(last_rule.actions, sizeof(struct action_t) * last_rule.actions_c); last_rule.actions[last_rule.actions_c-1].parameter = NULL; last_rule.actions[last_rule.actions_c-1].type = -1; for (i = 0; actions[i].key != NULL; i++) { if (!strcmp(actions[i].key, buf)) { last_rule.actions[last_rule.actions_c-1].type = actions[i].type; break; } } if (last_rule.actions[last_rule.actions_c-1].type == -1) { ERROR("rules_get_value / status / action", "Malformed rule - unknown action: %s.", buf); terminate = 1; } if (actions[i].param > 0) { last_rule.actions[last_rule.actions_c-1].parameter = xmalloc(sizeof(char*) * (actions[i].param + 1)); last_rule.actions[last_rule.actions_c-1].parameter[actions[i].param] = NULL; for (j = 0; j < actions[i].param; j++) { last_rule.actions[last_rule.actions_c-1].parameter[j] = rules_get_value(input, &input); if (!strcmp(last_rule.actions[last_rule.actions_c-1].parameter[j], "}")) { ERROR("rules_get_value / status / action", "Malformed rule - not enough parameters passed."); status = STATUS_KEY; break; } last_rule.actions[last_rule.actions_c-1].parameter[j] = replace_str(last_rule.actions[last_rule.actions_c-1].parameter[j], "\\}", "}"); } } else if (actions[i].param == -1) { j = 0; last_rule.actions[last_rule.actions_c-1].parameter = xmalloc(sizeof(char*) * (j + 1)); last_rule.actions[last_rule.actions_c-1].parameter[j] = rules_get_value(input, &input); while (last_rule.actions[last_rule.actions_c-1].parameter[j] != NULL) { if (!strcmp(last_rule.actions[last_rule.actions_c-1].parameter[j], ";")) { break; } if (!strcmp(last_rule.actions[last_rule.actions_c-1].parameter[j], "}")) { ERROR("rules_get_value / status / action", "Malformed rule - missing parameter terminator ';'."); status = STATUS_KEY; break; } if (last_rule.actions[last_rule.actions_c-1].parameter[j][0] == '\0') { ERROR("rules_get_value / status / action", "Malformed rule - missing parameter terminator ';'."); status = STATUS_KEY; break; } last_rule.actions[last_rule.actions_c-1].parameter[j] = replace_str(last_rule.actions[last_rule.actions_c-1].parameter[j], "\\}", "}"); last_rule.actions[last_rule.actions_c-1].parameter[j] = replace_str(last_rule.actions[last_rule.actions_c-1].parameter[j], "\\;", ";"); j++; last_rule.actions[last_rule.actions_c-1].parameter = xrealloc(last_rule.actions[last_rule.actions_c-1].parameter, sizeof(char*) * (j + 1)); last_rule.actions[last_rule.actions_c-1].parameter[j] = rules_get_value(input, &input); } free(last_rule.actions[last_rule.actions_c-1].parameter[j]); last_rule.actions[last_rule.actions_c-1].parameter[j] = NULL; } if (status == STATUS_KEY) { return_rules->rules_c++; return_rules->rules = xrealloc(return_rules->rules, sizeof(struct rule_t) * return_rules->rules_c); last_rule.actions = NULL; last_rule.actions_c = 0; last_rule.conditions = NULL; last_rule.conditions_c = 0; } break; } free(buf); } while (*input != '\0' && !terminate); if (!terminate) { /* A little bit hacky cleanup */ if (!nested) return_rules->rules_c--; return return_rules; } else { /* * We don't want to cleanup if we're nested. */ if (!nested) { rules_free(return_rules); free(return_rules); } return NULL; } }