Пример #1
0
static int rules_parse(JsonNode *root) {
	int have_error = 0, match = 0, x = 0;
	unsigned int i = 0;
	struct JsonNode *jrules = NULL;
	char *rule = NULL;
	double active = 1.0;

	if(root->tag == JSON_OBJECT) {
		jrules = json_first_child(root);
		while(jrules) {
			i++;
			if(jrules->tag == JSON_OBJECT) {
				if(json_find_string(jrules, "rule", &rule) != 0) {
					logprintf(LOG_ERR, "config rule #%d \"%s\", missing \"rule\"", i, jrules->key);
					have_error = 1;
					break;
				} else {
					active = 1.0;
					json_find_number(jrules, "active", &active);

					struct rules_t *tmp = rules;
					match = 0;
					while(tmp) {
						if(strcmp(tmp->name, jrules->key) == 0) {
							match = 1;
							break;
						}
						tmp = tmp->next;
					}
					if(match == 1) {
						logprintf(LOG_ERR, "config rule #%d \"%s\" already exists", i, jrules->key);
						have_error = 1;
						break;
					}
					for(x=0;x<strlen(jrules->key);x++) {
						if(!isalnum(jrules->key[x]) && jrules->key[x] != '-' && jrules->key[x] != '_') {
							logprintf(LOG_ERR, "config rule #%d \"%s\", not alphanumeric", i, jrules->key);
							have_error = 1;
							break;
						}
					}

					struct rules_t *node = MALLOC(sizeof(struct rules_t));
					if(node == NULL) {
						fprintf(stderr, "out of memory\n");
						exit(EXIT_FAILURE);
					}
					node->next = NULL;
					node->values = NULL;
					node->nrdevices = 0;
					node->status = 0;
					node->devices = NULL;
					node->actions = NULL;
					node->nr = i;
					if((node->name = MALLOC(strlen(jrules->key)+1)) == NULL) {
						fprintf(stderr, "out of memory\n");
						exit(EXIT_FAILURE);
					}
					strcpy(node->name, jrules->key);
					clock_gettime(CLOCK_MONOTONIC, &node->timestamp.first);
					if(event_parse_rule(rule, node, 0, 1) == -1) {
						have_error = 1;
					}
					clock_gettime(CLOCK_MONOTONIC, &node->timestamp.second);
					logprintf(LOG_INFO, "rule #%d %s was parsed in %.6f seconds", node->nr, node->name,
						((double)node->timestamp.second.tv_sec + 1.0e-9*node->timestamp.second.tv_nsec) -
						((double)node->timestamp.first.tv_sec + 1.0e-9*node->timestamp.first.tv_nsec));

					node->status = 0;
					if((node->rule = MALLOC(strlen(rule)+1)) == NULL) {
						fprintf(stderr, "out of memory\n");
						exit(EXIT_FAILURE);
					}
					strcpy(node->rule, rule);
					node->active = (unsigned short)active;

					tmp = rules;
					if(tmp) {
						while(tmp->next != NULL) {
							tmp = tmp->next;
						}
						tmp->next = node;
					} else {
						node->next = rules;
						rules = node;
					}
					/*
					 * In case of an error, we do want to
					 * save a pointer to our faulty rule
					 * so it can be properly garbage collected.
					 */
					if(have_error == 1) {
						break;
					}
				}
			}
			jrules = jrules->next;
		}
	} else {
		logprintf(LOG_ERR, "config rules should be placed in an object");
		have_error = 1;
	}

	return have_error;
}
Пример #2
0
static int rules_parse(JsonNode *root) {
	int have_error = 0, match = 0;
	unsigned int i = 0;
	struct JsonNode *jrules = NULL;
	char *rule = NULL;
	double active = 1.0;

	if(root->tag == JSON_OBJECT) {
		jrules = json_first_child(root);
		while(jrules) {
			i++;
			if(jrules->tag == JSON_OBJECT) {
				if(json_find_string(jrules, "rule", &rule) != 0) {
					logprintf(LOG_ERR, "config rules #%d \"%s\", missing \"rule\"", i, jrules->key);
					have_error = 1;
					break;
				} else {
					active = 1.0;
					json_find_number(jrules, "active", &active);

					struct rules_t *tmp = rules;
					match = 0;
					while(tmp) {
						if(strcmp(tmp->name, jrules->key) == 0) {
							match = 1;
							break;
						}
						tmp = tmp->next;
					}
					if(match == 1) {
						logprintf(LOG_ERR, "config rules #%d \"%s\" already exists", i, jrules->key);
						have_error = 1;
						break;
					}
					struct rules_t *node = MALLOC(sizeof(struct rules_t));
					if(node == NULL) {
						logprintf(LOG_ERR, "out of memory");
						exit(EXIT_FAILURE);
					}
					node->next = NULL;
					node->values = NULL;
					node->nrdevices = 0;
					node->status = 0;
					node->devices = NULL;
					node->action = NULL;
					node->arguments = NULL;
					if(event_parse_rule(rule, node, 0, i, 1) == -1) {
						for(i=0;i<node->nrdevices;i++) {
							FREE(node->devices[i]);
						}
						if(node->devices != NULL) {
							FREE(node->devices);
						}
						FREE(node);
						have_error = 1;
						break;
					}
					node->status = 0;
					node->rule = MALLOC(strlen(rule)+1);
					if(node->rule == NULL) {
						logprintf(LOG_ERR, "out of memory");
						exit(EXIT_FAILURE);
					}
					strcpy(node->rule, rule);
					node->name = MALLOC(strlen(jrules->key)+1);
					if(node->name == NULL) {
						logprintf(LOG_ERR, "out of memory");
						exit(EXIT_FAILURE);
					}
					strcpy(node->name, jrules->key);
					node->active = (unsigned short)active;

					tmp = rules;
					if(tmp) {
						while(tmp->next != NULL) {
							tmp = tmp->next;
						}
						tmp->next = node;
					} else {
						node->next = rules;
						rules = node;
					}
				}
			}
			jrules = jrules->next;
		}
	} else {
		logprintf(LOG_ERR, "config rules should be placed in an object");
		have_error = 1;
	}

	return have_error;
}
Пример #3
0
void *events_loop(void *param) {
	logprintf(LOG_STACK, "%s(...)", __FUNCTION__);

	pthread_mutexattr_init(&events_attr);
	pthread_mutexattr_settype(&events_attr, PTHREAD_MUTEX_RECURSIVE);
	pthread_mutex_init(&events_lock, &events_attr);
	pthread_cond_init(&events_signal, NULL);

	struct JsonNode *jdevices = NULL, *jchilds = NULL;
	struct rules_t *tmp_rules = NULL;
	char *str = NULL;
	unsigned short match = 0;
	unsigned int i = 0;

	pthread_mutex_lock(&events_lock);
	while(loop) {
		if(eventsqueue_number > 0) {
			pthread_mutex_lock(&events_lock);

			logprintf(LOG_STACK, "%s::unlocked", __FUNCTION__);

			running = 1;

			jdevices = json_find_member(eventsqueue->jconfig, "devices");
			tmp_rules = rules_get();
			while(tmp_rules) {
				if(tmp_rules->active == 1) {
					match = 0;
					if((str = MALLOC(strlen(tmp_rules->rule)+1)) == NULL) {
						logprintf(LOG_ERR, "out of memory");
						exit(EXIT_FAILURE);
					}
					strcpy(str, tmp_rules->rule);
					/* Only run those events that affect the updates devices */
					if(jdevices != NULL) {
						jchilds = json_first_child(jdevices);
						while(jchilds) {
							for(i=0;i<tmp_rules->nrdevices;i++) {
								if(jchilds->tag == JSON_STRING &&
								   strcmp(jchilds->string_, tmp_rules->devices[i]) == 0) {
									match = 1;
									break;
								}
							}
							if(match == 1) {
								break;
							}
							jchilds = jchilds->next;
						}
					}
					if(match == 1 && tmp_rules->status == 0) {
						if(event_parse_rule(str, tmp_rules, 0, 1, 0) == 0) {
							if(tmp_rules->status) {
								logprintf(LOG_INFO, "executed rule: %s", tmp_rules->name);
							}
						}
						tmp_rules->status = 0;
					}
					FREE(str);
				}
				tmp_rules = tmp_rules->next;
			}
			struct eventsqueue_t *tmp = eventsqueue;
			json_delete(tmp->jconfig);
			eventsqueue = eventsqueue->next;
			FREE(tmp);
			eventsqueue_number--;
			running = 0;
			pthread_mutex_unlock(&events_lock);
		} else {
			pthread_cond_wait(&events_signal, &events_lock);
		}
	}
	return (void *)NULL;
}