Beispiel #1
0
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct instance *o = vo;
    o->i = i;
    
    // read arguments
    NCDValRef arg_choices;
    NCDValRef arg_default_result;
    if (!NCDVal_ListRead(params->args, 2, &arg_choices, &arg_default_result)) {
        ModuleLog(i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsList(arg_choices)) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    // iterate choices
    int have_result = 0;
    size_t count = NCDVal_ListCount(arg_choices);
    for (size_t j = 0; j < count; j++) {
        NCDValRef c = NCDVal_ListGet(arg_choices, j);
        
        // check choice type
        if (!NCDVal_IsList(c)) {
            ModuleLog(i, BLOG_ERROR, "wrong choice type");
            goto fail0;
        }
        
        // read choice
        NCDValRef c_cond;
        NCDValRef c_result;
        if (!NCDVal_ListRead(c, 2, &c_cond, &c_result)) {
            ModuleLog(i, BLOG_ERROR, "wrong choice contents arity");
            goto fail0;
        }
        if (!NCDVal_IsString(c_cond)) {
            ModuleLog(i, BLOG_ERROR, "wrong choice condition type");
            goto fail0;
        }
        
        // update result
        if (!have_result && ncd_read_boolean(c_cond)) {
            o->result = c_result;
            have_result = 1;
        }
    }
    
    // default?
    if (!have_result) {
        o->result = arg_default_result;
    }
    
    // signal up
    NCDModuleInst_Backend_Up(o->i);
    return;
    
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Beispiel #2
0
static int concat_recurser (ExpString *estr, NCDValRef arg, NCDCall const *call)
{
    if (NCDVal_IsString(arg)) {
        if (!ExpString_AppendBinaryMr(estr, NCDVal_StringMemRef(arg))) {
            FunctionLog(call, BLOG_ERROR, "ExpString_AppendBinaryMr failed");
            return 0;
        }
    } else if (NCDVal_IsList(arg)) {
        size_t count = NCDVal_ListCount(arg);
        for (size_t i = 0; i < count; i++) {
            if (!concat_recurser(estr, NCDVal_ListGet(arg, i), call)) {
                return 0;
            }
        }
    } else {
        FunctionLog(call, BLOG_ERROR, "concat: value is not a string or list");
        return 0;
    }
    return 1;
}
Beispiel #3
0
static void concatlist_eval (NCDCall call)
{
    NCDValRef args_list;
    if (!ncd_eval_func_args(&call, NCDCall_ResMem(&call), &args_list)) {
        return;
    }
    size_t arg_count = NCDVal_ListCount(args_list);
    bsize_t elem_count = bsize_fromsize(0);
    for (size_t i = 0; i < arg_count; i++) {
        NCDValRef arg = NCDVal_ListGet(args_list, i);
        if (!NCDVal_IsList(arg)) {
            return FunctionLog(&call, BLOG_ERROR, "concatlist: argument is not a list");
        }
        elem_count = bsize_add(elem_count, bsize_fromsize(NCDVal_ListCount(arg)));
    }
    if (elem_count.is_overflow) {
        return FunctionLog(&call, BLOG_ERROR, "concatlist: count overflow");
    }
    NCDValRef res = NCDVal_NewList(NCDCall_ResMem(&call), elem_count.value);
    if (NCDVal_IsInvalid(res)) {
        return;
    }
    for (size_t i = 0; i < arg_count; i++) {
        NCDValRef arg = NCDVal_ListGet(args_list, i);
        size_t arg_list_count = NCDVal_ListCount(arg);
        for (size_t j = 0; j < arg_list_count; j++) {
            NCDValRef copy = NCDVal_NewCopy(NCDCall_ResMem(&call), NCDVal_ListGet(arg, j));
            if (NCDVal_IsInvalid(copy)) {
                return;
            }
            if (!NCDVal_ListAppend(res, copy)) {
                return;
            }
        }
    }
    NCDCall_SetResult(&call, res);
}
Beispiel #4
0
static void replace_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct replace_instance *o = vo;
    o->i = i;
    
    // read arguments
    NCDValRef input_arg;
    NCDValRef regex_arg;
    NCDValRef replace_arg;
    if (!NCDVal_ListRead(params->args, 3, &input_arg, &regex_arg, &replace_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong arity");
        goto fail1;
    }
    if (!NCDVal_IsString(input_arg) || !NCDVal_IsList(regex_arg) || !NCDVal_IsList(replace_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail1;
    }
    
    // check number of regex/replace
    if (NCDVal_ListCount(regex_arg) != NCDVal_ListCount(replace_arg)) {
        ModuleLog(i, BLOG_ERROR, "number of regex's is not the same as number of replacements");
        goto fail1;
    }
    size_t num_regex = NCDVal_ListCount(regex_arg);
    
    // allocate array for compiled regex's
    regex_t *regs = BAllocArray(num_regex, sizeof(regs[0]));
    if (!regs) {
        ModuleLog(i, BLOG_ERROR, "BAllocArray failed");
        goto fail1;
    }
    size_t num_done_regex = 0;
    
    // compile regex's, check arguments
    while (num_done_regex < num_regex) {
        NCDValRef regex = NCDVal_ListGet(regex_arg, num_done_regex);
        NCDValRef replace = NCDVal_ListGet(replace_arg, num_done_regex);
        
        if (!NCDVal_IsStringNoNulls(regex) || !NCDVal_IsString(replace)) {
            ModuleLog(i, BLOG_ERROR, "wrong regex/replace type for pair %zu", num_done_regex);
            goto fail2;
        }
        
        // null terminate regex
        NCDValNullTermString regex_nts;
        if (!NCDVal_StringNullTerminate(regex, &regex_nts)) {
            ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
            goto fail2;
        }
        
        int res = regcomp(&regs[num_done_regex], regex_nts.data, REG_EXTENDED);
        NCDValNullTermString_Free(&regex_nts);
        if (res != 0) {
            ModuleLog(i, BLOG_ERROR, "regcomp failed for pair %zu (error=%d)", num_done_regex, res);
            goto fail2;
        }
        
        num_done_regex++;
    }
    
    // init output string
    ExpString out;
    if (!ExpString_Init(&out)) {
        ModuleLog(i, BLOG_ERROR, "ExpString_Init failed");
        goto fail2;
    }
    
    // input state
    MemRef in = NCDVal_StringMemRef(input_arg);
    size_t in_pos = 0;
    
    // process input
    while (in_pos < in.len) {
        // find first match
        int have_match = 0;
        size_t match_regex = 0; // to remove warning
        regmatch_t match = {0, 0}; // to remove warning
        for (size_t j = 0; j < num_regex; j++) {
            regmatch_t this_match;
            this_match.rm_so = 0;
            this_match.rm_eo = in.len - in_pos;
            if (regexec(&regs[j], in.ptr + in_pos, 1, &this_match, REG_STARTEND) == 0 && (!have_match || this_match.rm_so < match.rm_so)) {
                have_match = 1;
                match_regex = j;
                match = this_match;
            }
        }
        
        // if no match, append remaining data and finish
        if (!have_match) {
            if (!ExpString_AppendBinaryMr(&out, MemRef_SubFrom(in, in_pos))) {
                ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinaryMr failed");
                goto fail3;
            }
            break;
        }
        
        // append data before match
        if (!ExpString_AppendBinaryMr(&out, MemRef_Sub(in, in_pos, match.rm_so))) {
            ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinaryMr failed");
            goto fail3;
        }
        
        // append replacement data
        NCDValRef replace = NCDVal_ListGet(replace_arg, match_regex);
        if (!ExpString_AppendBinaryMr(&out, NCDVal_StringMemRef(replace))) {
            ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinaryMr failed");
            goto fail3;
        }
        
        in_pos += match.rm_eo;
    }
    
    // set output
    o->output = ExpString_GetMr(&out);
    
    // free compiled regex's
    while (num_done_regex-- > 0) {
        regfree(&regs[num_done_regex]);
    }
    
    // free array
    BFree(regs);
    
    // signal up
    NCDModuleInst_Backend_Up(i);
    return;
    
fail3:
    ExpString_Free(&out);
fail2:
    while (num_done_regex-- > 0) {
        regfree(&regs[num_done_regex]);
    }
    BFree(regs);
fail1:
    NCDModuleInst_Backend_DeadError(i);
}
Beispiel #5
0
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct instance *o = vo;
    o->i = i;
    
    // check arguments
    NCDValRef ifname_arg;
    NCDValRef opts_arg = NCDVal_NewInvalid();
    if (!NCDVal_ListRead(params->args, 1, &ifname_arg) && !NCDVal_ListRead(params->args, 2, &ifname_arg, &opts_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsStringNoNulls(ifname_arg) || (!NCDVal_IsInvalid(opts_arg) && !NCDVal_IsList(opts_arg))) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    NCDValNullTermString hostname_nts = NCDValNullTermString_NewDummy();
    NCDValNullTermString vendorclassid_nts = NCDValNullTermString_NewDummy();
    
    struct BDHCPClient_opts opts = {};
    
    // read options
    size_t count = NCDVal_IsInvalid(opts_arg) ? 0 : NCDVal_ListCount(opts_arg);
    for (size_t j = 0; j < count; j++) {
        NCDValRef opt = NCDVal_ListGet(opts_arg, j);
        
        // read name
        if (!NCDVal_IsString(opt)) {
            ModuleLog(o->i, BLOG_ERROR, "wrong option name type");
            goto fail1;
        }
        
        if (NCDVal_StringEquals(opt, "hostname") || NCDVal_StringEquals(opt, "vendorclassid")) {
            int is_hostname = NCDVal_StringEquals(opt, "hostname");
            
            // read value
            if (j == count) {
                ModuleLog(o->i, BLOG_ERROR, "option value missing");
                goto fail1;
            }
            NCDValRef val = NCDVal_ListGet(opts_arg, j + 1);
            if (!NCDVal_IsStringNoNulls(val)) {
                ModuleLog(o->i, BLOG_ERROR, "wrong option value type");
                goto fail1;
            }
            
            // null terminate
            NCDValNullTermString nts;
            if (!NCDVal_StringNullTerminate(val, &nts)) {
                ModuleLog(o->i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
                goto fail1;
            }
            NCDValNullTermString *nts_ptr = (is_hostname ? &hostname_nts : &vendorclassid_nts);
            NCDValNullTermString_Free(nts_ptr);
            *nts_ptr = nts;
            
            if (is_hostname) {
                opts.hostname = nts.data;
            } else {
                opts.vendorclassid = nts.data;
            }
            
            j++;
        }
        else if (NCDVal_StringEquals(opt, "auto_clientid")) {
            opts.auto_clientid = 1;
        }
        else {
            ModuleLog(o->i, BLOG_ERROR, "unknown option name");
            goto fail1;
        }
    }
    
    // null terminate ifname
    NCDValNullTermString ifname_nts;
    if (!NCDVal_StringNullTerminate(ifname_arg, &ifname_nts)) {
        ModuleLog(i, BLOG_ERROR, "NCDVal_StringNullTerminate failed");
        goto fail1;
    }
    
    // init DHCP
    int res = BDHCPClient_Init(&o->dhcp, ifname_nts.data, opts, o->i->params->iparams->reactor, o->i->params->iparams->random2, (BDHCPClient_handler)dhcp_handler, o);
    NCDValNullTermString_Free(&ifname_nts);
    if (!res) {
        ModuleLog(o->i, BLOG_ERROR, "BDHCPClient_Init failed");
        goto fail1;
    }
    
    // set not up
    o->up = 0;
    
    // free options nts's
    NCDValNullTermString_Free(&hostname_nts);
    NCDValNullTermString_Free(&vendorclassid_nts);
    return;
    
fail1:
    NCDValNullTermString_Free(&hostname_nts);
    NCDValNullTermString_Free(&vendorclassid_nts);
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Beispiel #6
0
static void func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
    struct instance *o = vo;
    o->i = i;
    
    // read arguments
    NCDValRef glue_arg;
    NCDValRef pieces_arg;
    if (!NCDVal_ListRead(params->args, 2, &glue_arg, &pieces_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (!NCDVal_IsString(glue_arg) || !NCDVal_IsList(pieces_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    // init result string
    ExpString str;
    if (!ExpString_Init(&str)) {
        ModuleLog(i, BLOG_ERROR, "ExpString_Init failed");
        goto fail0;
    }
    
    size_t count = NCDVal_ListCount(pieces_arg);
    for (size_t j = 0; j < count; j++) {
        NCDValRef piece = NCDVal_ListGet(pieces_arg, j);
        
        // check piece type
        if (!NCDVal_IsString(piece)) {
            ModuleLog(i, BLOG_ERROR, "wrong piece type");
            goto fail1;
        }
        
        // append glue
        if (j > 0) {
            if (!ExpString_AppendBinary(&str, (const uint8_t *)NCDVal_StringData(glue_arg), NCDVal_StringLength(glue_arg))) {
                ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinary failed");
                goto fail1;
            }
        }
        
        // append piece
        if (!ExpString_AppendBinary(&str, (const uint8_t *)NCDVal_StringData(piece), NCDVal_StringLength(piece))) {
            ModuleLog(i, BLOG_ERROR, "ExpString_AppendBinary failed");
            goto fail1;
        }
    }
    
    // store result
    o->result = ExpString_Get(&str);
    o->result_len = ExpString_Length(&str);
    
    // signal up
    NCDModuleInst_Backend_Up(i);
    return;
    
fail1:
    ExpString_Free(&str);
fail0:
    NCDModuleInst_Backend_DeadError(i);
}
Beispiel #7
0
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);
}
Beispiel #8
0
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);
}