Exemplo n.º 1
0
static int set_servers (struct global *g)
{
    int ret = 0;
    
    // count servers
    size_t num_entries = count_entries(g);
    
    // allocate sort array
    struct dns_sort_entry *sort_entries = BAllocArray(num_entries, sizeof(sort_entries[0]));
    if (!sort_entries) {
        goto fail0;
    }
    
    // fill sort array
    num_entries = 0;
    for (LinkedList1Node *n = LinkedList1_GetFirst(&g->instances); n; n = LinkedList1Node_Next(n)) {
        struct instance *o = UPPER_OBJECT(n, struct instance, instances_node);
        for (LinkedList1Node *en = LinkedList1_GetFirst(&o->entries); en; en = LinkedList1Node_Next(en)) {
            struct dns_entry *e = UPPER_OBJECT(en, struct dns_entry, list_node);
            sort_entries[num_entries].line = e->line;
            sort_entries[num_entries].priority= e->priority;
            num_entries++;
        }
    }
    
    // sort by priority
    // use a custom insertion sort instead of qsort() because we want a stable sort
    struct dns_sort_entry temp;
    BInsertionSort(sort_entries, num_entries, sizeof(sort_entries[0]), dns_sort_comparator, &temp);
    
    ExpString estr;
    if (!ExpString_Init(&estr)) {
        goto fail1;
    }
    
    for (size_t i = 0; i < num_entries; i++) {
        if (!ExpString_Append(&estr, sort_entries[i].line)) {
            goto fail2;
        }
    }
    
    // set servers
    if (!NCDIfConfig_set_resolv_conf(ExpString_Get(&estr), ExpString_Length(&estr))) {
        goto fail2;
    }
    
    ret = 1;
    
fail2:
    ExpString_Free(&estr);
fail1:
    BFree(sort_entries);
fail0:
    return ret;
}
Exemplo n.º 2
0
static void func_new (NCDModuleInst *i)
{
    // allocate instance
    struct instance *o = malloc(sizeof(*o));
    if (!o) {
        ModuleLog(i, BLOG_ERROR, "failed to allocate instance");
        goto fail0;
    }
    NCDModuleInst_Backend_SetUser(i, o);
    
    // init arguments
    o->i = i;
    
    // init string
    ExpString s;
    if (!ExpString_Init(&s)) {
        ModuleLog(i, BLOG_ERROR, "ExpString_Init failed");
        goto fail1;
    }
    
    // append arguments
    NCDValue *arg = NCDValue_ListFirst(o->i->args);
    while (arg) {
        if (NCDValue_Type(arg) != NCDVALUE_STRING) {
            ModuleLog(i, BLOG_ERROR, "wrong type");
            goto fail2;
        }
        
        if (!ExpString_Append(&s, NCDValue_StringValue(arg))) {
            ModuleLog(i, BLOG_ERROR, "ExpString_Append failed");
            goto fail2;
        }
        
        arg = NCDValue_ListNext(o->i->args, arg);
    }
    
    // set string
    o->string = ExpString_Get(&s);
    
    // signal up
    NCDModuleInst_Backend_Up(o->i);
    
    return;
    
fail2:
    ExpString_Free(&s);
fail1:
    free(o);
fail0:
    NCDModuleInst_Backend_SetError(i);
    NCDModuleInst_Backend_Dead(i);
}
Exemplo n.º 3
0
static void print_value (NCDValue *v, unsigned int indent)
{
    ExpString estr;
    if (!ExpString_Init(&estr)) {
        DEBUG("ExpString_Init failed");
        exit(1);
    }
    
    if (!generate_val(v, &estr)) {
        DEBUG("generate_val failed");
        exit(1);
    }
    
    print_indent(indent);
    printf("%s\n", ExpString_Get(&estr));
    
    ExpString_Free(&estr);
}
Exemplo n.º 4
0
static void concat_eval (NCDCall call)
{
    ExpString estr;
    if (!ExpString_Init(&estr)) {
        FunctionLog(&call, BLOG_ERROR, "ExpString_Init failed");
        goto fail0;
    }
    size_t count = NCDCall_ArgCount(&call);
    for (size_t i = 0; i < count; i++) {
        NCDValRef arg = NCDCall_EvalArg(&call, i, NCDCall_ResMem(&call));
        if (NCDVal_IsInvalid(arg)) {
            goto fail1;
        }
        if (!concat_recurser(&estr, arg, &call)) {
            goto fail1;
        }
    }
    NCDCall_SetResult(&call, NCDVal_NewStringBinMr(NCDCall_ResMem(&call), ExpString_GetMr(&estr)));
fail1:
    ExpString_Free(&estr);
fail0:
    return;
}
Exemplo n.º 5
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);
}
Exemplo n.º 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);
}
Exemplo n.º 7
0
void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_output output, void *user)
{
    size_t line = 1;
    size_t line_char = 1;
    
    while (left > 0) {
        size_t l;
        int error = 0;
        int token;
        void *token_val = NULL;
        size_t token_len = 0;
        
        if (*str == '#') {
            l = 1;
            while (l < left && str[l] != '\n') {
                l++;
            }
            token = 0;
        }
        else if (l = data_begins_with(str, left, "{")) {
            token = NCD_TOKEN_CURLY_OPEN;
        }
        else if (l = data_begins_with(str, left, "}")) {
            token = NCD_TOKEN_CURLY_CLOSE;
        }
        else if (l = data_begins_with(str, left, "(")) {
            token = NCD_TOKEN_ROUND_OPEN;
        }
        else if (l = data_begins_with(str, left, ")")) {
            token = NCD_TOKEN_ROUND_CLOSE;
        }
        else if (l = data_begins_with(str, left, ";")) {
            token = NCD_TOKEN_SEMICOLON;
        }
        else if (l = data_begins_with(str, left, ".")) {
            token = NCD_TOKEN_DOT;
        }
        else if (l = data_begins_with(str, left, ",")) {
            token = NCD_TOKEN_COMMA;
        }
        else if (l = data_begins_with(str, left, ":")) {
            token = NCD_TOKEN_COLON;
        }
        else if (l = data_begins_with(str, left, "[")) {
            token = NCD_TOKEN_BRACKET_OPEN;
        }
        else if (l = data_begins_with(str, left, "]")) {
            token = NCD_TOKEN_BRACKET_CLOSE;
        }
        else if (l = data_begins_with(str, left, "->")) {
            token = NCD_TOKEN_ARROW;
        }
        else if (l = data_begins_with(str, left, "If")) {
            token = NCD_TOKEN_IF;
        }
        else if (l = data_begins_with(str, left, "Elif")) {
            token = NCD_TOKEN_ELIF;
        }
        else if (l = data_begins_with(str, left, "elif")) {
            token = NCD_TOKEN_ELIF;
        }
        else if (l = data_begins_with(str, left, "Else")) {
            token = NCD_TOKEN_ELSE;
        }
        else if (l = data_begins_with(str, left, "else")) {
            token = NCD_TOKEN_ELSE;
        }
        else if (l = data_begins_with(str, left, "Foreach")) {
            token = NCD_TOKEN_FOREACH;
        }
        else if (l = data_begins_with(str, left, "As")) {
            token = NCD_TOKEN_AS;
        }
        else if (l = data_begins_with(str, left, "include_guard")) {
            token = NCD_TOKEN_INCLUDE_GUARD;
        }
        else if (l = data_begins_with(str, left, "include")) {
            token = NCD_TOKEN_INCLUDE;
        }
        else if (is_name_first_char(*str)) {
            l = 1;
            while (l < left && is_name_char(str[l])) {
                l++;
            }
            
            // allocate buffer
            bsize_t bufsize = bsize_add(bsize_fromsize(l), bsize_fromint(1));
            char *buf;
            if (bufsize.is_overflow || !(buf = malloc(bufsize.value))) {
                BLog(BLOG_ERROR, "malloc failed");
                error = 1;
                goto out;
            }
            
            // copy and terminate
            memcpy(buf, str, l);
            buf[l] = '\0';
            
            if (!strcmp(buf, "process")) {
                token = NCD_TOKEN_PROCESS;
                free(buf);
            }
            else if (!strcmp(buf, "template")) {
                token = NCD_TOKEN_TEMPLATE;
                free(buf);
            }
            else {
                token = NCD_TOKEN_NAME;
                token_val = buf;
                token_len = l;
            }
        }
        else if (*str == '"') do {
            // init string
            ExpString estr;
            if (!ExpString_Init(&estr)) {
                BLog(BLOG_ERROR, "ExpString_Init failed");
                goto string_fail0;
            }
            
            // skip start quote
            l = 1;
            
            // decode string
            while (l < left) {
                uint8_t dec_ch;
                
                // get character
                if (str[l] == '\\') {
                    if (left - l < 2) {
                        BLog(BLOG_ERROR, "escape character found in string but nothing follows");
                        goto string_fail1;
                    }
                    
                    size_t extra = 0;
                    
                    switch (str[l + 1]) {
                        case '\'':
                        case '\"':
                        case '\\':
                        case '\?':
                            dec_ch = str[l + 1]; break;
                        
                        case 'a':
                            dec_ch = '\a'; break;
                        case 'b':
                            dec_ch = '\b'; break;
                        case 'f':
                            dec_ch = '\f'; break;
                        case 'n':
                            dec_ch = '\n'; break;
                        case 'r':
                            dec_ch = '\r'; break;
                        case 't':
                            dec_ch = '\t'; break;
                        case 'v':
                            dec_ch = '\v'; break;
                        
                        case '0':
                            dec_ch = 0; break;
                        
                        case 'x': {
                            if (left - l < 4) {
                                BLog(BLOG_ERROR, "hexadecimal escape found in string but too little characters follow");
                                goto string_fail1;
                            }
                            
                            uintmax_t hex_val;
                            if (!parse_unsigned_hex_integer_bin(&str[l + 2], 2, &hex_val)) {
                                BLog(BLOG_ERROR, "hexadecimal escape found in string but two hex characters don't follow");
                                goto string_fail1;
                            }
                            
                            dec_ch = hex_val;
                            extra = 2;
                        } break;
                        
                        default:
                            BLog(BLOG_ERROR, "bad escape sequence in string");
                            goto string_fail1;
                    }
                    
                    l += 2 + extra;
                }
                else if (str[l] == '"') {
                    break;
                }
                else {
                    dec_ch = str[l];
                    l++;
                }
                
                // append character to string
                if (!ExpString_AppendByte(&estr, dec_ch)) {
                    BLog(BLOG_ERROR, "ExpString_AppendChar failed");
                    goto string_fail1;
                }
            }
            
            // make sure ending quote was found
            if (l == left) {
                BLog(BLOG_ERROR, "missing ending quote for string");
                goto string_fail1;
            }
            
            // skip ending quote
            l++;
            
            token = NCD_TOKEN_STRING;
            token_val = ExpString_Get(&estr);
            token_len = ExpString_Length(&estr);
            break;
            
        string_fail1:
            ExpString_Free(&estr);
        string_fail0:
            error = 1;
        } while (0);
        else if (is_space_char(*str)) {
            token = 0;
            l = 1;
        }
        else {
            BLog(BLOG_ERROR, "unrecognized character");
            error = 1;
        }
        
    out:
        // report error
        if (error) {
            output(user, NCD_ERROR, NULL, 0, line, line_char);
            return;
        }
        
        // output token
        if (token) {
            if (!output(user, token, token_val, token_len, line, line_char)) {
                return;
            }
        }
        
        // update line/char counters
        for (size_t i = 0; i < l; i++) {
            if (str[i] == '\n') {
                line++;
                line_char = 1;
            } else {
                line_char++;
            }
        }
        
        str += l;
        left -= l;
    }
    
    output(user, NCD_EOF, NULL, 0, line, line_char);
}
Exemplo n.º 8
0
void NCDConfigTokenizer_Tokenize (char *str, size_t left, NCDConfigTokenizer_output output, void *user)
{
    size_t line = 1;
    size_t line_char = 1;
    
    while (left > 0) {
        size_t l;
        int error = 0;
        int token;
        void *token_val = NULL;
        
        if (*str == '#') {
            l = 1;
            while (l < left && str[l] != '\n') {
                l++;
            }
            token = 0;
        }
        else if (l = data_begins_with(str, left, "{")) {
            token = NCD_TOKEN_CURLY_OPEN;
        }
        else if (l = data_begins_with(str, left, "}")) {
            token = NCD_TOKEN_CURLY_CLOSE;
        }
        else if (l = data_begins_with(str, left, "(")) {
            token = NCD_TOKEN_ROUND_OPEN;
        }
        else if (l = data_begins_with(str, left, ")")) {
            token = NCD_TOKEN_ROUND_CLOSE;
        }
        else if (l = data_begins_with(str, left, ";")) {
            token = NCD_TOKEN_SEMICOLON;
        }
        else if (l = data_begins_with(str, left, ".")) {
            token = NCD_TOKEN_DOT;
        }
        else if (l = data_begins_with(str, left, ",")) {
            token = NCD_TOKEN_COMMA;
        }
        else if (l = data_begins_with(str, left, ":")) {
            token = NCD_TOKEN_COLON;
        }
        else if (l = data_begins_with(str, left, "[")) {
            token = NCD_TOKEN_BRACKET_OPEN;
        }
        else if (l = data_begins_with(str, left, "]")) {
            token = NCD_TOKEN_BRACKET_CLOSE;
        }
        else if (l = data_begins_with(str, left, "->")) {
            token = NCD_TOKEN_ARROW;
        }
        else if (is_name_first_char(*str)) {
            l = 1;
            while (l < left && is_name_char(str[l])) {
                l++;
            }
            
            // allocate buffer
            bsize_t bufsize = bsize_add(bsize_fromsize(l), bsize_fromint(1));
            char *buf;
            if (bufsize.is_overflow || !(buf = malloc(bufsize.value))) {
                BLog(BLOG_ERROR, "malloc failed");
                error = 1;
                goto out;
            }
            
            // copy and terminate
            memcpy(buf, str, l);
            buf[l] = '\0';
            
            if (!strcmp(buf, "process")) {
                token = NCD_TOKEN_PROCESS;
                free(buf);
            }
            else if (!strcmp(buf, "template")) {
                token = NCD_TOKEN_TEMPLATE;
                free(buf);
            }
            else {
                token = NCD_TOKEN_NAME;
                token_val = buf;
            }
        }
        else if (*str == '"') do {
            // init string
            ExpString estr;
            if (!ExpString_Init(&estr)) {
                BLog(BLOG_ERROR, "ExpString_Init failed");
                goto string_fail0;
            }
            
            // skip start quote
            l = 1;
            
            // decode string
            while (l < left) {
                char dec_ch;
                
                // get character
                if (str[l] == '\\') {
                    if (left - l < 2) {
                        BLog(BLOG_ERROR, "escape character found in string but nothing follows");
                        goto string_fail1;
                    }
                    
                    dec_ch = str[l + 1];
                    l += 2;
                }
                else if (str[l] == '"') {
                    break;
                }
                else {
                    dec_ch = str[l];
                    l++;
                }
                
                // string cannot contain zeros bytes
                if (dec_ch == '\0') {
                    BLog(BLOG_ERROR, "string contains zero byte");
                    goto string_fail1;
                }
                
                // append character to string
                if (!ExpString_AppendChar(&estr, dec_ch)) {
                    BLog(BLOG_ERROR, "ExpString_AppendChar failed");
                    goto string_fail1;
                }
            }
            
            // make sure ending quote was found
            if (l == left) {
                BLog(BLOG_ERROR, "missing ending quote for string");
                goto string_fail1;
            }
            
            // skip ending quote
            l++;
            
            token = NCD_TOKEN_STRING;
            token_val = ExpString_Get(&estr);
            break;
            
        string_fail1:
            ExpString_Free(&estr);
        string_fail0:
            error = 1;
        } while (0);
        else if (is_space_char(*str)) {
            token = 0;
            l = 1;
        }
        else {
            BLog(BLOG_ERROR, "unrecognized character");
            error = 1;
        }
        
    out:
        // report error
        if (error) {
            output(user, NCD_ERROR, NULL, line, line_char);
            return;
        }
        
        // output token
        if (token) {
            if (!output(user, token, token_val, line, line_char)) {
                return;
            }
        }
        
        // update line/char counters
        for (size_t i = 0; i < l; i++) {
            if (str[i] == '\n') {
                line++;
                line_char = 1;
            } else {
                line_char++;
            }
        }
        
        str += l;
        left -= l;
    }
    
    output(user, NCD_EOF, NULL, line, line_char);
}