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; }
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; }
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; }
/* 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; }