static void new_number_templ (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params, number_compute_func cfunc) { struct number_instance *o = vo; o->i = i; NCDValRef n1_arg; NCDValRef n2_arg; if (!NCDVal_ListRead(params->args, 2, &n1_arg, &n2_arg)) { ModuleLog(i, BLOG_ERROR, "wrong arity"); goto fail0; } uintmax_t n1; if (!ncd_read_uintmax(n1_arg, &n1)) { ModuleLog(o->i, BLOG_ERROR, "wrong first argument"); goto fail0; } uintmax_t n2; if (!ncd_read_uintmax(n2_arg, &n2)) { ModuleLog(o->i, BLOG_ERROR, "wrong second argument"); goto fail0; } o->error = cfunc(i, n1, n2, &o->value); NCDModuleInst_Backend_Up(i); return; fail0: NCDModuleInst_Backend_DeadError(i); }
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { struct instance *o = vo; o->i = i; // check arguments NCDValRef ms_start_arg; NCDValRef ms_stop_arg = NCDVal_NewInvalid(); if (!NCDVal_ListRead(params->args, 1, &ms_start_arg) && !NCDVal_ListRead(params->args, 2, &ms_start_arg, &ms_stop_arg)) { ModuleLog(o->i, BLOG_ERROR, "wrong arity"); goto fail0; } uintmax_t ms; btime_t ms_start; if (NCDVal_IsString(ms_start_arg) && NCDVal_StringEqualsId(ms_start_arg, NCD_STRING_EMPTY)) { ms_start = -1; } else { if (!ncd_read_uintmax(ms_start_arg, &ms) || ms > INT64_MAX) { ModuleLog(o->i, BLOG_ERROR, "wrong start time"); goto fail0; } ms_start = ms; } if (NCDVal_IsInvalid(ms_stop_arg) || (NCDVal_IsString(ms_stop_arg) && NCDVal_StringEqualsId(ms_stop_arg, NCD_STRING_EMPTY))) { o->ms_stop = -1; } else { if (!ncd_read_uintmax(ms_stop_arg, &ms) || ms > INT64_MAX) { ModuleLog(o->i, BLOG_ERROR, "wrong stop time"); goto fail0; } o->ms_stop = ms; } // init timer BTimer_Init(&o->timer, 0, timer_handler, o); // set not dying o->dying = 0; if (ms_start < 0) { // go up NCDModuleInst_Backend_Up(i); } else { // set timer BReactor_SetTimerAfter(o->i->params->iparams->reactor, &o->timer, ms_start); } return; fail0: NCDModuleInst_Backend_DeadError(i); }
static void func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { // check arguments NCDValRef exit_code_arg; if (!NCDVal_ListRead(params->args, 1, &exit_code_arg)) { ModuleLog(i, BLOG_ERROR, "wrong arity"); goto fail0; } if (!NCDVal_IsString(exit_code_arg)) { ModuleLog(i, BLOG_ERROR, "wrong type"); goto fail0; } // parse exit code uintmax_t exit_code; if (!ncd_read_uintmax(exit_code_arg, &exit_code) || exit_code >= INT_MAX) { ModuleLog(i, BLOG_ERROR, "wrong exit code value"); goto fail0; } // signal up NCDModuleInst_Backend_Up(i); // initiate exit (before up!) NCDModuleInst_Backend_InterpExit(i, exit_code); return; fail0: NCDModuleInst_Backend_DeadError(i); }
static void func_new_from_value (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { // read arguments NCDValRef arg_value; if (!NCDVal_ListRead(params->args, 1, &arg_value)) { ModuleLog(i, BLOG_ERROR, "wrong arity"); goto fail0; } if (!NCDVal_IsString(arg_value)) { ModuleLog(i, BLOG_ERROR, "wrong type"); goto fail0; } // parse value uintmax_t value; if (!ncd_read_uintmax(arg_value, &value)) { ModuleLog(i, BLOG_ERROR, "wrong value"); goto fail0; } // check overflow if (value > SIZE_MAX) { ModuleLog(i, BLOG_ERROR, "value too large"); goto fail0; } func_new_templ(vo, i, value); return; fail0: NCDModuleInst_Backend_DeadError(i); }
static int parse_options (NCDModuleInst *i, NCDValRef options, size_t *out_read_size) { ASSERT(out_read_size) *out_read_size = DEFAULT_READ_BUF_SIZE; if (!NCDVal_IsInvalid(options)) { if (!NCDVal_IsMap(options)) { ModuleLog(i, BLOG_ERROR, "options argument is not a map"); return 0; } int num_recognized = 0; NCDValRef value; if (!NCDVal_IsInvalid(value = NCDVal_MapGetValue(options, "read_size"))) { uintmax_t read_size; if (!ncd_read_uintmax(value, &read_size) || read_size > SIZE_MAX || read_size == 0) { ModuleLog(i, BLOG_ERROR, "wrong read_size"); return 0; } num_recognized++; *out_read_size = read_size; } if (NCDVal_MapCount(options) > num_recognized) { ModuleLog(i, BLOG_ERROR, "unrecognized options present"); return 0; } } return 1; }
static void integer_compare_eval (NCDCall call, integer_compare_func func) { if (NCDCall_ArgCount(&call) != 2) { return FunctionLog(&call, BLOG_ERROR, "integer_compare: need two arguments"); } uintmax_t ints[2]; for (int i = 0; i < 2; i++) { NCDValRef arg = NCDCall_EvalArg(&call, i, NCDCall_ResMem(&call)); if (NCDVal_IsInvalid(arg)) { return; } if (!ncd_read_uintmax(arg, &ints[i])) { return FunctionLog(&call, BLOG_ERROR, "integer_compare: wrong value"); } } int res = func(ints[0], ints[1]); NCDCall_SetResult(&call, ncd_make_boolean(NCDCall_ResMem(&call), res)); }
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { struct instance *o = vo; o->i = i; // read arguments NCDValRef delimiter_arg; NCDValRef input_arg; NCDValRef limit_arg = NCDVal_NewInvalid(); if (!NCDVal_ListRead(params->args, 2, &delimiter_arg, &input_arg) && !NCDVal_ListRead(params->args, 3, &delimiter_arg, &input_arg, &limit_arg)) { ModuleLog(i, BLOG_ERROR, "wrong arity"); goto fail0; } if (!NCDVal_IsString(delimiter_arg) || !NCDVal_IsString(input_arg) || (!NCDVal_IsInvalid(limit_arg) && !NCDVal_IsString(limit_arg))) { ModuleLog(i, BLOG_ERROR, "wrong type"); goto fail0; } size_t limit = SIZE_MAX; if (!NCDVal_IsInvalid(limit_arg)) { uintmax_t n; if (!ncd_read_uintmax(limit_arg, &n) || n == 0) { ModuleLog(i, BLOG_ERROR, "bad limit argument"); goto fail0; } n--; limit = (n <= SIZE_MAX ? n : SIZE_MAX); } const char *del_data = NCDVal_StringData(delimiter_arg); size_t del_len = NCDVal_StringLength(delimiter_arg); if (del_len == 0) { ModuleLog(i, BLOG_ERROR, "delimiter must be nonempty"); goto fail0; } size_t *table = BAllocArray(del_len, sizeof(table[0])); if (!table) { ModuleLog(i, BLOG_ERROR, "ExpArray_init failed"); goto fail0; } build_substring_backtrack_table(del_data, del_len, table); if (!ExpArray_init(&o->arr, sizeof(struct substring), 8)) { ModuleLog(i, BLOG_ERROR, "ExpArray_init failed"); goto fail1; } o->num = 0; const char *data = NCDVal_StringData(input_arg); size_t len = NCDVal_StringLength(input_arg); while (1) { size_t start; int is_end = 0; if (limit == 0 || !find_substring(data, len, del_data, del_len, table, &start)) { start = len; is_end = 1; } if (!ExpArray_resize(&o->arr, o->num + 1)) { ModuleLog(i, BLOG_ERROR, "ExpArray_init failed"); goto fail2; } struct substring *elem = &((struct substring *)o->arr.v)[o->num]; if (!(elem->data = BAlloc(start))) { ModuleLog(i, BLOG_ERROR, "BAlloc failed"); goto fail2; } memcpy(elem->data, data, start); elem->len = start; o->num++; if (is_end) { break; } data += start + del_len; len -= start + del_len; limit--; } BFree(table); // signal up NCDModuleInst_Backend_Up(i); return; fail2: while (o->num-- > 0) { BFree(((struct substring *)o->arr.v)[o->num].data); } free(o->arr.v); fail1: BFree(table); fail0: NCDModuleInst_Backend_DeadError(i); }
static void func_new_substr (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { NCDValRef str_arg; NCDValRef start_arg; NCDValRef max_arg = NCDVal_NewInvalid(); if (!NCDVal_ListRead(params->args, 2, &str_arg, &start_arg) && !NCDVal_ListRead(params->args, 3, &str_arg, &start_arg, &max_arg) ) { ModuleLog(i, BLOG_ERROR, "wrong arity"); goto fail0; } if (!NCDVal_IsString(str_arg) || !NCDVal_IsString(start_arg) || (!NCDVal_IsInvalid(max_arg) && !NCDVal_IsString(max_arg)) ) { ModuleLog(i, BLOG_ERROR, "wrong type"); goto fail0; } uintmax_t start; if (!ncd_read_uintmax(start_arg, &start) || start > SIZE_MAX) { ModuleLog(i, BLOG_ERROR, "wrong size"); goto fail0; } uintmax_t max = SIZE_MAX; if (!NCDVal_IsInvalid(max_arg)) { if (!ncd_read_uintmax(max_arg, &max) || max > SIZE_MAX) { ModuleLog(i, BLOG_ERROR, "wrong max"); goto fail0; } } const char *str_data = NCDVal_StringData(str_arg); size_t str_length = NCDVal_StringLength(str_arg); if (start > str_length) { ModuleLog(i, BLOG_ERROR, "start is beyond the end of the string"); goto fail0; } const char *sub_data = str_data + start; size_t sub_length = str_length - start; if (sub_length > max) { sub_length = max; } int is_external = 0; BRefTarget *external_ref_target = NULL; if (NCDVal_IsExternalString(str_arg)) { is_external = 1; external_ref_target = NCDVal_ExternalStringTarget(str_arg); } else if (NCDVal_IsIdString(str_arg)) { is_external = 1; } substr_func_new_common(vo, i, sub_data, sub_length, is_external, external_ref_target); return; fail0: NCDModuleInst_Backend_DeadError(i); }
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { struct instance *o = vo; o->i = i; // read arguments NCDValRef dest_arg; NCDValRef dest_prefix_arg = NCDVal_NewInvalid(); NCDValRef gateway_arg; NCDValRef metric_arg; NCDValRef ifname_arg; if (!NCDVal_ListRead(params->args, 4, &dest_arg, &gateway_arg, &metric_arg, &ifname_arg) && !NCDVal_ListRead(params->args, 5, &dest_arg, &dest_prefix_arg, &gateway_arg, &metric_arg, &ifname_arg) ) { ModuleLog(o->i, BLOG_ERROR, "wrong arity"); goto fail0; } if (!NCDVal_IsString(dest_arg) || !NCDVal_IsString(gateway_arg) || !NCDVal_IsStringNoNulls(ifname_arg) || (!NCDVal_IsInvalid(dest_prefix_arg) && !NCDVal_IsString(dest_prefix_arg)) ) { ModuleLog(o->i, BLOG_ERROR, "wrong type"); goto fail0; } // read dest if (NCDVal_IsInvalid(dest_prefix_arg)) { if (!ipaddr6_parse_ipv6_ifaddr_bin(NCDVal_StringData(dest_arg), NCDVal_StringLength(dest_arg), &o->dest)) { ModuleLog(o->i, BLOG_ERROR, "wrong CIDR notation dest"); goto fail0; } } else { if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(dest_arg), NCDVal_StringLength(dest_arg), &o->dest.addr)) { ModuleLog(o->i, BLOG_ERROR, "wrong dest addr"); goto fail0; } if (!ipaddr6_parse_ipv6_prefix_bin(NCDVal_StringData(dest_prefix_arg), NCDVal_StringLength(dest_prefix_arg), &o->dest.prefix)) { ModuleLog(o->i, BLOG_ERROR, "wrong dest prefix"); goto fail0; } } // read gateway and choose type if (NCDVal_StringEquals(gateway_arg, "none")) { o->type = TYPE_IFONLY; } else if (NCDVal_StringEquals(gateway_arg, "blackhole")) { o->type = TYPE_BLACKHOLE; } else { if (!ipaddr6_parse_ipv6_addr_bin(NCDVal_StringData(gateway_arg), NCDVal_StringLength(gateway_arg), &o->gateway)) { ModuleLog(o->i, BLOG_ERROR, "wrong gateway"); goto fail0; } o->type = TYPE_NORMAL; } // read metric uintmax_t metric; if (!ncd_read_uintmax(metric_arg, &metric) || metric > INT_MAX) { ModuleLog(i, BLOG_ERROR, "bad metric"); goto fail0; } o->metric = metric; // null terminate ifname if (!NCDVal_StringNullTerminate(ifname_arg, &o->ifname_nts)) { ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); goto fail0; } // add route int res = 0; // to remove warning switch (o->type) { case TYPE_NORMAL: res = NCDIfConfig_add_ipv6_route(o->dest, &o->gateway, o->metric, o->ifname_nts.data); break; case TYPE_IFONLY: res = NCDIfConfig_add_ipv6_route(o->dest, NULL, o->metric, o->ifname_nts.data); break; case TYPE_BLACKHOLE: res = NCDIfConfig_add_ipv6_blackhole_route(o->dest, o->metric); break; default: ASSERT(0); } if (!res) { ModuleLog(o->i, BLOG_ERROR, "failed to add route"); goto fail1; } // signal up NCDModuleInst_Backend_Up(o->i); return; fail1: NCDValNullTermString_Free(&o->ifname_nts); fail0: NCDModuleInst_Backend_DeadError(i); }
static void func_new_resolvconf (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { struct global *g = ModuleGlobal(i); struct instance *o = vo; o->i = i; // init servers list LinkedList1_Init(&o->entries); // get arguments NCDValRef lines_arg; NCDValRef priority_arg; if (!NCDVal_ListRead(params->args, 2, &lines_arg, &priority_arg)) { ModuleLog(o->i, BLOG_ERROR, "wrong arity"); goto fail1; } if (!NCDVal_IsList(lines_arg) || !NCDVal_IsString(priority_arg)) { ModuleLog(o->i, BLOG_ERROR, "wrong type"); goto fail1; } uintmax_t priority; if (!ncd_read_uintmax(priority_arg, &priority) || priority > INT_MAX) { ModuleLog(o->i, BLOG_ERROR, "wrong priority"); goto fail1; } // read lines size_t count = NCDVal_ListCount(lines_arg); for (size_t j = 0; j < count; j++) { int loop_failed = 1; NCDValRef line = NCDVal_ListGet(lines_arg, j); if (!NCDVal_IsList(line) || NCDVal_ListCount(line) != 2) { ModuleLog(o->i, BLOG_ERROR, "lines element is not a list with two elements"); goto loop_fail0; } NCDValRef type = NCDVal_ListGet(line, 0); NCDValRef value = NCDVal_ListGet(line, 1); if (!NCDVal_IsStringNoNulls(type) || !NCDVal_IsStringNoNulls(value)) { ModuleLog(o->i, BLOG_ERROR, "wrong type of type or value"); goto loop_fail0; } NCDValNullTermString type_nts; if (!NCDVal_StringNullTerminate(type, &type_nts)) { ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); goto loop_fail0; } NCDValNullTermString value_nts; if (!NCDVal_StringNullTerminate(value, &value_nts)) { ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed"); goto loop_fail1; } if (!add_dns_entry(o, type_nts.data, value_nts.data, priority)) { ModuleLog(o->i, BLOG_ERROR, "failed to add dns entry"); goto loop_fail2; } loop_failed = 0; loop_fail2: NCDValNullTermString_Free(&value_nts); loop_fail1: NCDValNullTermString_Free(&type_nts); loop_fail0: if (loop_failed) { goto fail1; } } // add to instances LinkedList1_Append(&g->instances, &o->instances_node); // set servers if (!set_servers(g)) { ModuleLog(o->i, BLOG_ERROR, "failed to set DNS servers"); goto fail2; } // signal up NCDModuleInst_Backend_Up(o->i); return; fail2: LinkedList1_Remove(&g->instances, &o->instances_node); fail1: remove_entries(o); NCDModuleInst_Backend_DeadError(i); }
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params) { struct global *g = ModuleGlobal(i); struct instance *o = vo; o->i = i; // init servers list LinkedList1_Init(&o->entries); // get arguments NCDValRef servers_arg; NCDValRef priority_arg; if (!NCDVal_ListRead(params->args, 2, &servers_arg, &priority_arg)) { ModuleLog(o->i, BLOG_ERROR, "wrong arity"); goto fail1; } if (!NCDVal_IsList(servers_arg) || !NCDVal_IsString(priority_arg)) { ModuleLog(o->i, BLOG_ERROR, "wrong type"); goto fail1; } uintmax_t priority; if (!ncd_read_uintmax(priority_arg, &priority) || priority > INT_MAX) { ModuleLog(o->i, BLOG_ERROR, "wrong priority"); goto fail1; } // read servers size_t count = NCDVal_ListCount(servers_arg); for (size_t j = 0; j < count; j++) { NCDValRef server_arg = NCDVal_ListGet(servers_arg, j); if (!NCDVal_IsString(server_arg)) { ModuleLog(o->i, BLOG_ERROR, "wrong type"); goto fail1; } uint32_t addr; if (!ipaddr_parse_ipv4_addr_bin((char *)NCDVal_StringData(server_arg), NCDVal_StringLength(server_arg), &addr)) { ModuleLog(o->i, BLOG_ERROR, "wrong addr"); goto fail1; } char addr_str[IPADDR_PRINT_MAX]; ipaddr_print_addr(addr, addr_str); if (!add_dns_entry(o, "nameserver", addr_str, priority)) { ModuleLog(o->i, BLOG_ERROR, "failed to add dns entry"); goto fail1; } } // add to instances LinkedList1_Append(&g->instances, &o->instances_node); // set servers if (!set_servers(g)) { ModuleLog(o->i, BLOG_ERROR, "failed to set DNS servers"); goto fail2; } // signal up NCDModuleInst_Backend_Up(o->i); return; fail2: LinkedList1_Remove(&g->instances, &o->instances_node); fail1: remove_entries(o); NCDModuleInst_Backend_DeadError(i); }