Example #1
0
static int dbops_fixup_func(void** param, int init_act) {
	struct dbops_action **p, *a;
	char *c;
	int res;

	/* check if is it a declare_no that references to declare_xxxx */
	c = *param;
	eat_spaces(c);
	*param = c;
	eat_alphanum(c);
	if (*c == 0) {
		a = find_action_by_name(*param, -1);
		if (!a) {
			ERR(MODULE_NAME": fixup_func: query (%s) not declared\n", (char*) *param);
			return -1;
		}
		*param = (void*) a;
		return 0;
	}

	for (p = &dbops_actions; *p; p=&(*p)->next);	/* add at the end of list */
	res = parse_ops(*param, p, init_act == 0 /* declare query has name */);
	if (res < 0) return res;
	/* pkg_free(*param); do not free it!*/
	*param = (void*) *p;
	if (init_act)
		return init_action(*p);   /* fixup is acquired after init_mod() therefore initialize new action */
	else
		return 0;
}
Example #2
0
int krip_init(dictionary *conf)
{
	char *svrname;
	char *vip, *ip, *port, *if_name;
	char *p;
	char *c;
	char file[1024], buf[512];
	FILE *fp;
	struct sockaddr_in sin;
	int listen;

	/* Parse the configuration file. ("HOSTNAME_krip" in the current working directory) */
	svrname = iniparser_getstring(conf, "KENS:server_name", "KENS");

	sprintf(file, "%s_krip", svrname);
	fp = fopen(file, "r");
	if (fp == NULL) {
		_enabled = 0;
		return 0;
	}

	/* Initialize system parameters. */
	_update_time = krip_get_mtime();

	c = iniparser_getstring(conf,"KENS:krip_update_interval","3000");
	_update_interval = atoi(c);

	c = iniparser_getstring(conf,"KENS:krip_timeout","7000");
	_timeout = atoi(c);

	_rip_info_list = list_open();
	_neighbor_info_list = list_open();

	/* Create a UDP socket for RIP communication. */
	if ((_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("krip");
		return -1;
	}

	_enabled = 1;

	/* configuration example:
	 * listen 127.0.0.1:9501
	 * 10.1.0.1 seth0 127.0.0.1:9502
	 * 10.1.1.1 seth1 127.0.0.1:9503
	 */

	while (fgets(buf, 512, fp)) {
		p = strchr(buf, '#');
		if (p != NULL) *p = '\0';
		if (buf[strlen(buf) - 1] == '\n') buf[strlen(buf) - 1] = '\0';
		
		p = buf;
		p = eat_ws(p);
		if (p == NULL) continue;

		if (strncmp(buf, "listen", 6) == 0) {
			listen = 1;

			p += 6;
			p = eat_ws(p);
		}
		else {
			listen = 0;
			
			vip = p;
			p = eat_ipaddr(vip);
			*p++ = '\0';
			p = eat_ws(p);

			if_name = p;
			p = eat_alphanum(if_name);
			*p++ = '\0';
			p = eat_ws(p);
		}

		ip = p;
		p = eat_ipaddr(ip);
		*p++ = '\0';
		port = p;
		p = eat_digit(port);

		if (listen)
		{
			/* Setup the RIP listening socket. */
			L_ROUTE("krip_init(): bind to %s:%s", ip, port);
			sin.sin_family = AF_INET;
			inet_aton(ip, &sin.sin_addr);
			sin.sin_port = htons((in_port_t)atoi(port));
			if (bind(_sock, (struct sockaddr *)&sin, sizeof(sin))) {
				perror("krip");
				return -1;
			}
		}
		else
		{
			/* Setup the neighbor information for RIP clients. */
			L_ROUTE("krip_init(): register neighbor %s(%s:%s)", vip, ip, port);
			neighbor_info *ni = (neighbor_info *)malloc(sizeof(neighbor_info));
			inet_aton(vip, &ni->virtual_addr);
			ni->krip_addr.sin_family = AF_INET;
			inet_aton(ip, &ni->krip_addr.sin_addr);
			ni->krip_addr.sin_port = htons((in_port_t)atoi(port));
			ni->ifp = ifunit(if_name);
			if (!ni->ifp) {
				L_ROUTE("krip_init(): invalid interface name: %s", if_name);
				free(ni);
				continue;
			}

			list_add_tail(_neighbor_info_list, ni);
		}
	}

	fclose(fp);

	/* Fetch the routing table entries. */
	list rte_list = rt_query();
	list_position pos;
	uint32_t now = krip_get_mtime();
	for (pos = list_get_head_position(rte_list);
			pos; pos = list_get_next_position(pos)) {
		rtentry *rte = list_get_at(pos);
		for (; rte; rte = (rtentry *)((radix_node *)rte)->rn_dupedkey) {
			if (((radix_node *)rte)->rn_mask == NULL)
				continue;
			if (rte->dst.s_addr == 0x00000000) {
				L_ROUTE("krip_init(): default gw %s", inet_ntoa(rte->gw));
			}
			else if (rte->dst.s_addr == inet_addr("127.0.0.1")) {
			}
			else {
				L_ROUTE("krip_init(): dst %s", inet_ntoa(rte->dst));
				L_ROUTE("krip_init(): mask %s", inet_ntoa(rte->mask));
				L_ROUTE("krip_init(): gw %s", inet_ntoa(rte->gw));

				rip_info *ri = (rip_info *)malloc(sizeof(rip_info));
				ri->assoc_rte = rte;
				ri->metric = 1;
				ri->change_flag = 1;
				ri->timeout = 0;		/* The initial entries will not be expired. */
				ri->from = NULL;
				list_add_tail(_rip_info_list, ri);
			}
		}
	}

	/* Send the initial request packets */
	pos = list_get_head_position(_neighbor_info_list);
	for (; pos; pos = list_get_next_position(pos)) {
		neighbor_info *ni = list_get_at(pos);
		krip_send_request(ni);
	}

	return 0;
}
Example #3
0
static int parse_ops(char* act_s, struct dbops_action** action, int has_name) {
	int res = 0, i;
	char *c, *s, *part;
	static int query_no = 0;

	s = act_s;
	*action = pkg_malloc(sizeof(**action));
	if (!*action) return E_OUT_OF_MEM;
	memset(*action, 0, sizeof(**action));
	(*action)->query_no = query_no++;

	eat_spaces(s);
	c = s;
	eat_alphanum(c);
	if (has_name) {
		char *c2;
		c2 = c;
		eat_spaces(c2);
		if (c != s && *c2 == '=') {
			*c = '\0';
			if (find_action_by_name(s, -1) != NULL) {
				ERR(MODULE_NAME": parse_ops: duplicate query name: %s\n", s);
				return E_CFG;
			}		
			(*action)->query_name = s;
			s = c2+1;
			eat_spaces(s);
			c = s;
			eat_alphanum(c);
		}
		else {
			ERR(MODULE_NAME": parse_ops: query_no: %d, valid query name not found in '%s'\n%s\n%s\n", (*action)->query_no, s, c, c2);
			return E_CFG;
		}
	}

	if (c[0] == ':' && c[1] == '/' && c[2] == '/') { /* database part is optional */
		for (c=s; *c!=':'; c++) {
			*c = tolower(*c);                       /* _type_://user:host/database_name/ */
		}
		(*action)->db_url = s;
		s = c+1;
		while (*s == '/') s++;
		res = get_next_part(&s, &part, PART_DELIM, 1);  /* type://_user:host_/database_name/ */
		if (res < 0) return res;


		res = get_next_part(&s, &part, PART_DELIM, 0);  /* type://user:host/_database_name_/ */
		if (res < 0) return res;
	}
	res = get_next_part(&s, &part, PART_DELIM, 0);
	if (res < 0) return res;

	for (c = part; *c && *c != PART_DELIM; c++) {
		if (*c == ' ') {
			(*action)->is_raw_query = 1;
			*c = '\0';
			break;
		}
	}
	if (strcasecmp(part, "select") == 0)
		(*action)->operation = OPEN_QUERY_OPS;
	else if (strcasecmp(part, "insert") == 0)
		(*action)->operation = INSERT_OPS;
	else if (strcasecmp(part, "update") == 0)
		(*action)->operation = UPDATE_OPS;
	else if (strcasecmp(part, "replace") == 0)
		(*action)->operation = REPLACE_OPS;
	else if (strcasecmp(part, "delete") == 0)
		(*action)->operation = DELETE_OPS;
	else {
		if ((*action)->is_raw_query) *c = ' ';
		ERR(MODULE_NAME": parse_ops: query: %s(%d), unknown type of query '%s'\n", (*action)->query_name, (*action)->query_no, part);
		return E_CFG;
	}
	if ((*action)->is_raw_query) {
		*c = ' ';
		(*action)->raw.s = part;
		(*action)->table.s = part;
	}

	res = get_next_part(&s, &part, PART_DELIM, 0);
	if (res < 0) return res;
	if (!(*action)->is_raw_query) {

		if (!*part) {
			ERR(MODULE_NAME": parse_ops: query: %s(%d), table not specified near '%s' in '%s'\n", (*action)->query_name, (*action)->query_no, s, act_s);
			return E_CFG;
		}
		trim_apostr(&part);
		(*action)->table.s = part;

		res = get_next_part(&s, &part, PART_DELIM, 0);
		if (res < 0) return res;
		switch ((*action)->operation) {
			case OPEN_QUERY_OPS:
			case UPDATE_OPS:
			case REPLACE_OPS:
			case INSERT_OPS:
				res = split_fields(part, &(*action)->field_count, &(*action)->fields);
				if (res < 0) return res;
				if ((*action)->field_count == 0) {
					ERR(MODULE_NAME": parse_ops: query: %s(%d), no field specified near '%s' ?n '%s'\n", (*action)->query_name, (*action)->query_no, part, act_s);
					return E_CFG;
				}
				break;
			case DELETE_OPS:
				res = split_fields(part, &(*action)->where_count, &(*action)->wheres);
				if (res < 0) return res;
				res = get_next_part(&s, &part, PART_DELIM, 0);
				if (res < 0) return res;
				res = split_fields(part, &(*action)->op_count, &(*action)->ops);
				if (res < 0) return res;
				break;
			default:;
		}

		res = get_next_part(&s, &part, PART_DELIM, 0);
		if (res < 0) return res;
		switch ((*action)->operation) {
			case OPEN_QUERY_OPS:
			case UPDATE_OPS:
				res = split_fields(part, &(*action)->where_count, &(*action)->wheres);
				if (res < 0) return res;
				res = get_next_part(&s, &part, PART_DELIM, 0);
				if (res < 0) return res;
				res = split_fields(part, &(*action)->op_count, &(*action)->ops);
				if (res < 0) return res;
				res = get_next_part(&s, &part, PART_DELIM, 0);
				if (res < 0) return res;
				switch ((*action)->operation) {
					case OPEN_QUERY_OPS:
						if (*part) {
							(*action)->order.s = part;
						}
						res = get_next_part(&s, &part, PART_DELIM, 0);
						if (res < 0) return res;
						break;
					default:;
				}
				break;
			default:
				;
		}
	}

	/* values */
	res = split_fields(part, &(*action)->value_count, &(*action)->values);
	if (res < 0) return res;

	if ((*action)->value_count) {
		(*action)->value_types = (int*)pkg_malloc(sizeof(int) * (*action)->value_count);
		if ((*action)->value_types == NULL) {
			ERR(MODULE_NAME": No memory left\n");
			return -1;
		}

		for (i=0; i<(*action)->value_count; i++) {
			(*action)->value_types[i] = DB_CSTR; // DB_NONE; /* let decide db driver itself, FIXME: until jjanak changes then default type is string */
			res = get_type(&(*action)->values[i].s, &(*action)->value_types[i]);
			if (res < 0) return res;
		}
	}

	/* extra options */
	res = get_next_part(&s, &part, PART_DELIM, 0);
	if (res < 0) return res;

	(*action)->extra_ops_count = 0;
	c = part;
	while (*c) {
		char *fld;
		res = get_next_part(&c, &fld, FLD_DELIM, 1);
		if (res < 0) return res;
		(*action)->extra_ops_count++;
	}
	if ((*action)->extra_ops_count > 0) {
		(*action)->extra_ops = pkg_malloc( (*action)->extra_ops_count*sizeof(*(*action)->extra_ops));
		if (!(*action)->extra_ops) {
			ERR(MODULE_NAME": parse_ops: not enough pkg memory\n");
			return E_OUT_OF_MEM;
		}
		memset((*action)->extra_ops, 0, (*action)->extra_ops_count*sizeof(*(*action)->extra_ops));

		i = 0;
		c = part;
		while (*c) {
			char *fld;
			res = get_next_part(&c, &fld, FLD_DELIM, 0);
			if (res < 0) return res;
			/* name=[i|s]:value */
			(*action)->extra_ops[i].name = fld;
			eat_alphanum(fld);
			if (*fld != '=') {
				ERR(MODULE_NAME": parse_ops: query: %s(%d), bad extra parameter format in '%s'\n", (*action)->query_name, (*action)->query_no, (*action)->extra_ops[i].name);
				return E_CFG;
			}
			*fld = '\0';
			fld++;
			while (*fld==' ' || *fld=='\t') fld++;
			(*action)->extra_ops[i].type = DB_NONE;
			res = get_type(&fld, &(*action)->extra_ops[i].type);
			if (res < 0) return res;
			trim_apostr(&fld);
			(*action)->extra_ops[i].value = fld;
			DEBUG(MODULE_NAME": extra_ops #%d, name='%s', type=%d, val='%s'\n", i, (*action)->extra_ops[i].name, (*action)->extra_ops[i].type, (*action)->extra_ops[i].value);
			i++;
		}
	}

	if (*s) {
		ERR(MODULE_NAME": parse_ops: query: %s(%d), too many parameters/parts, remaining '%s' in '%s'\n", (*action)->query_name, (*action)->query_no, s, act_s);
		return E_CFG;
	}
	if ((*action)->is_raw_query) {
		DEBUG(MODULE_NAME": query: %s(%d) oper:%d database:'%s' query:'%s' value#:%d extra_ops#:%d\n", (*action)->query_name, (*action)->query_no, (*action)->operation, (*action)->db_url, (*action)->raw.s, (*action)->value_count, (*action)->extra_ops_count);
	}
	else {
		/* check num of fields */
		if ((((*action)->operation==OPEN_QUERY_OPS)?0:(*action)->field_count)+(*action)->where_count != (*action)->value_count) {
			ERR(MODULE_NAME": parse_ops: query: %s(%d), number of values does not correspond to number of fields (%d+%d!=%d) in '%s'\n", (*action)->query_name, (*action)->query_no, ((*action)->operation==OPEN_QUERY_OPS)?0:(*action)->field_count,  (*action)->where_count, (*action)->value_count, act_s);
			return E_CFG;
		}
		DEBUG(MODULE_NAME": query_no:%d oper:%d database:'%s' table:'%s' 'field#:'%d' where#:'%d' order:'%s' value#:%d extra_ops#:%d\n", (*action)->query_no, (*action)->operation, (*action)->db_url, (*action)->table.s, (*action)->field_count,  (*action)->where_count, (*action)->order.s, (*action)->value_count, (*action)->extra_ops_count);
	}
	return 0;
}
Example #4
0
/* timer_id=route_no,interval_ms[,"slow"|"fast"[,"enable"]] */
static int declare_timer(modparam_t type, char* param) {
	int n;
	unsigned int route_no, interval, enabled, flags;
	struct timer_action *pa;
	char *p, *save_p, c, *timer_name;
	str s;

	timer_name = 0;
	save_p = p = param;
	eat_alphanum(p);
	if (*p != '=' || p == save_p) goto err;
	*p = '\0';
	timer_name = save_p;
	p++;
	if (find_action_by_name(pkg_timer_actions, timer_name, -1) != NULL) {
		ERR(MODULE_NAME": declare_timer: timer '%s' already exists\n", timer_name);
		return E_CFG;
	}

	save_p = p;
	if (!get_next_part(&p, &s, ',')) goto err;

	c = s.s[s.len];
	s.s[s.len] = '\0';
	n = route_get(&main_rt, s.s);
	s.s[s.len] = c;
	if (n == -1) goto err;
	route_no = n;

	save_p = p;
	if (!get_next_part(&p, &s, ',')) goto err;
	if (str2int(&s, &interval) < 0) goto err;

	save_p = p;
	flags = 0;
	if (get_next_part(&p, &s, ',')) {
		if (s.len == 4 && strncasecmp(s.s, "FAST", 4)==0)
			flags = F_TIMER_FAST;
		else if (s.len == 4 && strncasecmp(s.s, "SLOW", 4)==0)
			;
		else goto err;
	}

	save_p = p;
	enabled = 0;
	if (get_next_part(&p, &s, ',')) {
		if (s.len == 6 && strncasecmp(s.s, "ENABLE", 6)==0)
			enabled = 1;
		else goto err;
	}

	
	pa = pkg_malloc(sizeof(*pa));   /* cannot use shmmem here! */
	if (!pa) {
		ERR(MODULE_NAME": cannot allocate timer data\n");
		return E_OUT_OF_MEM;
	}
	memset(pa, 0, sizeof(*pa));
	pa->timer_name = timer_name;
	pa->route_no = route_no;
	pa->interval = interval;
	pa->enable_on_start = enabled;
	pa->flags = flags;
	pa->next = pkg_timer_actions;
	pkg_timer_actions = pa;

	return 0;
err:
	ERR(MODULE_NAME": declare_timer: timer_name: '%s', error near '%s'\n", timer_name, save_p);
	return E_CFG;
}