Пример #1
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;
    
    // check arguments
    NCDValue *template_name_arg;
    NCDValue *args_arg;
    if (!NCDValue_ListRead(o->i->args, 2, &template_name_arg, &args_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail1;
    }
    if (NCDValue_Type(template_name_arg) != NCDVALUE_STRING || NCDValue_Type(args_arg) != NCDVALUE_LIST) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail1;
    }
    
    // signal up.
    // Do it before creating the process so that the process starts initializing before our own process continues.
    NCDModuleInst_Backend_Up(o->i);
    
    // copy arguments
    NCDValue args;
    if (!NCDValue_InitCopy(&args, args_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "NCDValue_InitCopy failed");
        goto fail1;
    }
    
    // create process
    if (!NCDModuleProcess_Init(&o->process, o->i, NCDValue_StringValue(template_name_arg), args, o, (NCDModuleProcess_handler_event)process_handler_event)) {
        ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed");
        NCDValue_Free(&args);
        goto fail1;
    }
    
    // set state working
    o->state = STATE_WORKING;
    return;
    
fail1:
    free(o);
fail0:
    NCDModuleInst_Backend_SetError(i);
    NCDModuleInst_Backend_Dead(i);
}
Пример #2
0
static void func_new_from_value (NCDModuleInst *i)
{
    // read arguments
    NCDValue *arg_value;
    if (!NCDValue_ListRead(i->args, 1, &arg_value)) {
        ModuleLog(i, BLOG_ERROR, "wrong arity");
        goto fail0;
    }
    if (NCDValue_Type(arg_value) != NCDVALUE_STRING) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    // parse value
    uintmax_t value;
    if (!parse_unsigned_integer(NCDValue_StringValue(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(i, value);
    return;
    
fail0:
    NCDModuleInst_Backend_SetError(i);
    NCDModuleInst_Backend_Dead(i);
}
Пример #3
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);
}
Пример #4
0
int build_cmdline (struct instance *o, CmdLine *c)
{
    // init cmdline
    if (!CmdLine_Init(c)) {
        goto fail0;
    }
    
    // append stdbuf part
    if (!build_stdbuf_cmdline(c, o->exec)) {
        goto fail1;
    }
    
    // append user arguments
    NCDValue *arg = NCDValue_ListFirst(o->args);
    while (arg) {
        if (NCDValue_Type(arg) != NCDVALUE_STRING) {
            ModuleLog(o->i, BLOG_ERROR, "wrong type");
            goto fail1;
        }
        
        // append argument
        if (!CmdLine_Append(c, NCDValue_StringValue(arg))) {
            goto fail1;
        }
        
        arg = NCDValue_ListNext(o->args, arg);
    }
    
    // append interface name
    if (!CmdLine_Append(c, "-i") || !CmdLine_Append(c, o->ifname)) {
        goto fail1;
    }
    
    // append config file
    if (!CmdLine_Append(c, "-c") || !CmdLine_Append(c, o->conf)) {
        goto fail1;
    }
    
    // terminate cmdline
    if (!CmdLine_Finish(c)) {
        goto fail1;
    }
    
    return 1;
    
fail1:
    CmdLine_Free(c);
fail0:
    return 0;
}
Пример #5
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;
    
    // check arguments
    NCDValue *template_name_arg;
    NCDValue *args_arg;
    if (!NCDValue_ListRead(o->i->args, 2, &template_name_arg, &args_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail1;
    }
    if (NCDValue_Type(template_name_arg) != NCDVALUE_STRING || NCDValue_Type(args_arg) != NCDVALUE_LIST) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail1;
    }
    char *template_name = NCDValue_StringValue(template_name_arg);
    
    // calling none?
    if (!strcmp(template_name, "<none>")) {
        // signal up
        NCDModuleInst_Backend_Up(o->i);
        
        // set state none
        o->state = STATE_NONE;
    } else {
        // copy arguments
        NCDValue args;
        if (!NCDValue_InitCopy(&args, args_arg)) {
            ModuleLog(o->i, BLOG_ERROR, "NCDValue_InitCopy failed");
            goto fail1;
        }
        
        // create process
        if (!NCDModuleProcess_Init(&o->process, o->i, template_name, args, o, (NCDModuleProcess_handler_event)process_handler_event)) {
            ModuleLog(o->i, BLOG_ERROR, "NCDModuleProcess_Init failed");
            NCDValue_Free(&args);
            goto fail1;
        }
        
        // set special functions
        NCDModuleProcess_SetSpecialFuncs(&o->process,
                                        (NCDModuleProcess_func_getspecialobj)process_func_getspecialobj);
        
        // set callrefhere
        o->crh = (o->i->method_user ? ((NCDModuleInst *)i->method_user)->inst_user : NULL);
        
        // add to callrefhere's calls list
        if (o->crh) {
            LinkedList0_Prepend(&o->crh->calls_list, &o->calls_list_node);
        }
        
        // set state working
        o->state = STATE_WORKING;
    }
    return;
    
fail1:
    free(o);
fail0:
    NCDModuleInst_Backend_SetError(i);
    NCDModuleInst_Backend_Dead(i);
}
Пример #6
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;
    
    // read arguments
    NCDValue *arg_choices;
    NCDValue *arg_default_result;
    if (!NCDValue_ListRead(i->args, 2, &arg_choices, &arg_default_result)) {
        ModuleLog(i, BLOG_ERROR, "wrong arity");
        goto fail1;
    }
    if (NCDValue_Type(arg_choices) != NCDVALUE_LIST) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail1;
    }
    
    // set no result
    o->result = NULL;
    
    // iterate choices
    for (NCDValue *c = NCDValue_ListFirst(arg_choices); c; c = NCDValue_ListNext(arg_choices, c)) {
        // check choice type
        if (NCDValue_Type(c) != NCDVALUE_LIST) {
            ModuleLog(i, BLOG_ERROR, "wrong choice type");
            goto fail1;
        }
        
        // read choice
        NCDValue *c_cond;
        NCDValue *c_result;
        if (!NCDValue_ListRead(c, 2, &c_cond, &c_result)) {
            ModuleLog(i, BLOG_ERROR, "wrong choice contents arity");
            goto fail1;
        }
        if (NCDValue_Type(c_cond) != NCDVALUE_STRING) {
            ModuleLog(i, BLOG_ERROR, "wrong choice condition type");
            goto fail1;
        }
        
        // update result
        if (!o->result && !strcmp(NCDValue_StringValue(c_cond), "true")) {
            o->result = c_result;
        }
    }
    
    // default?
    if (!o->result) {
        o->result = arg_default_result;
    }
    
    // signal up
    NCDModuleInst_Backend_Up(o->i);
    return;
    
fail1:
    free(o);
fail0:
    NCDModuleInst_Backend_SetError(i);
    NCDModuleInst_Backend_Dead(i);
}
Пример #7
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;
    
    // read arguments
    NCDValue *ifname_arg;
    NCDValue *user_arg;
    NCDValue *exec_arg;
    NCDValue *args_arg;
    if (!NCDValue_ListRead(o->i->args, 4, &ifname_arg, &user_arg, &exec_arg, &args_arg)) {
        ModuleLog(o->i, BLOG_ERROR, "wrong arity");
        goto fail1;
    }
    if (NCDValue_Type(ifname_arg) != NCDVALUE_STRING || NCDValue_Type(user_arg) != NCDVALUE_STRING ||
        NCDValue_Type(exec_arg) != NCDVALUE_STRING || NCDValue_Type(args_arg) != NCDVALUE_LIST) {
        ModuleLog(o->i, BLOG_ERROR, "wrong type");
        goto fail1;
    }
    o->ifname = NCDValue_StringValue(ifname_arg);
    o->user = NCDValue_StringValue(user_arg);
    o->exec = NCDValue_StringValue(exec_arg);
    o->args = args_arg;
    
    // check arguments
    NCDValue *arg = NCDValue_ListFirst(o->args);
    while (arg) {
        if (NCDValue_Type(arg) != NCDVALUE_STRING) {
            ModuleLog(o->i, BLOG_ERROR, "wrong type");
            goto fail1;
        }
        arg = NCDValue_ListNext(o->args, arg);
    }
    
    // create TAP device
    if (!NCDIfConfig_make_tuntap(o->ifname, o->user, 0)) {
        ModuleLog(o->i, BLOG_ERROR, "failed to create TAP device");
        goto fail1;
    }
    
    // set device up
    if (!NCDIfConfig_set_up(o->ifname)) {
        ModuleLog(o->i, BLOG_ERROR, "failed to set device up");
        goto fail2;
    }
    
    // set not dying
    o->dying = 0;
    
    // init timer
    BTimer_Init(&o->timer, RETRY_TIME, (BTimer_handler)timer_handler, o);
    
    // signal up
    NCDModuleInst_Backend_Up(o->i);
    
    // try starting process
    try_process(o);
    
    return;
    
fail2:
    if (!NCDIfConfig_remove_tuntap(o->ifname, 0)) {
        ModuleLog(o->i, BLOG_ERROR, "failed to remove TAP device");
    }
fail1:
    free(o);
fail0:
    NCDModuleInst_Backend_SetError(i);
    NCDModuleInst_Backend_Dead(i);
}
Пример #8
0
static int generate_val (NCDValue *value, ExpString *out_str)
{
    switch (NCDValue_Type(value)) {
        case NCDVALUE_STRING: {
            const char *str = NCDValue_StringValue(value);
            size_t len = NCDValue_StringLength(value);
            
            if (!ExpString_AppendChar(out_str, '"')) {
                goto fail;
            }
            
            for (size_t i = 0; i < len; i++) {
                if (str[i] == '\0') {
                    char buf[5];
                    snprintf(buf, sizeof(buf), "\\x%02"PRIx8, (uint8_t)str[i]);
                    
                    if (!ExpString_Append(out_str, buf)) {
                        goto fail;
                    }
                    
                    continue;
                }
                
                if (str[i] == '"' || str[i] == '\\') {
                    if (!ExpString_AppendChar(out_str, '\\')) {
                        goto fail;
                    }
                }
                
                if (!ExpString_AppendChar(out_str, str[i])) {
                    goto fail;
                }
            }
            
            if (!ExpString_AppendChar(out_str, '"')) {
                goto fail;
            }
        } break;
        
        case NCDVALUE_LIST: {
            if (!ExpString_AppendChar(out_str, '{')) {
                goto fail;
            }
            
            int is_first = 1;
            
            for (NCDValue *e = NCDValue_ListFirst(value); e; e = NCDValue_ListNext(value, e)) {
                if (!is_first) {
                    if (!ExpString_Append(out_str, ", ")) {
                        goto fail;
                    }
                }
                
                if (!generate_val(e, out_str)) {
                    goto fail;
                }
                
                is_first = 0;
            }
            
            if (!ExpString_AppendChar(out_str, '}')) {
                goto fail;
            }
        } break;
        
        case NCDVALUE_MAP: {
            if (!ExpString_AppendChar(out_str, '[')) {
                goto fail;
            }
            
            int is_first = 1;
            
            for (NCDValue *ekey = NCDValue_MapFirstKey(value); ekey; ekey = NCDValue_MapNextKey(value, ekey)) {
                NCDValue *eval = NCDValue_MapKeyValue(value, ekey);
                
                if (!is_first) {
                    if (!ExpString_Append(out_str, ", ")) {
                        goto fail;
                    }
                }
                
                if (!generate_val(ekey, out_str)) {
                    goto fail;
                }
                
                if (!ExpString_AppendChar(out_str, ':')) {
                    goto fail;
                }
                
                if (!generate_val(eval, out_str)) {
                    goto fail;
                }
                
                is_first = 0;
            }
            
            if (!ExpString_AppendChar(out_str, ']')) {
                goto fail;
            }
        } break;
        
        case NCDVALUE_VAR: {
            if (!ExpString_Append(out_str, NCDValue_VarName(value))) {
                goto fail;
            }
        } break;
        
        case NCDVALUE_INVOC: {
            if (!generate_val(NCDValue_InvocFunc(value), out_str)) {
                goto fail;
            }
            
            if (!ExpString_AppendChar(out_str, '(')) {
                goto fail;
            }
            
            if (!generate_val(NCDValue_InvocArg(value), out_str)) {
                goto fail;
            }
            
            if (!ExpString_AppendChar(out_str, ')')) {
                goto fail;
            }
        } break;
        
        default: ASSERT(0);
    }
    
    return 1;
    
fail:
    return 0;
}
Пример #9
0
static int build_cmdline (NCDModuleInst *i, NCDValue *cmd_arg, char **exec, CmdLine *cl)
{
    if (NCDValue_Type(cmd_arg) != NCDVALUE_LIST) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    
    // read exec
    NCDValue *exec_arg = NCDValue_ListFirst(cmd_arg);
    if (!exec_arg) {
        ModuleLog(i, BLOG_ERROR, "missing executable name");
        goto fail0;
    }
    if (NCDValue_Type(exec_arg) != NCDVALUE_STRING) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail0;
    }
    if (!(*exec = strdup(NCDValue_StringValue(exec_arg)))) {
        ModuleLog(i, BLOG_ERROR, "strdup failed");
        goto fail0;
    }
    
    // start cmdline
    if (!CmdLine_Init(cl)) {
        ModuleLog(i, BLOG_ERROR, "CmdLine_Init failed");
        goto fail1;
    }
    
    // add header
    if (!CmdLine_Append(cl, *exec)) {
        ModuleLog(i, BLOG_ERROR, "CmdLine_Append failed");
        goto fail2;
    }
    
    // add additional arguments
    NCDValue *arg = exec_arg;
    while (arg = NCDValue_ListNext(cmd_arg, arg)) {
        if (NCDValue_Type(arg) != NCDVALUE_STRING) {
            ModuleLog(i, BLOG_ERROR, "wrong type");
            goto fail2;
        }
        
        if (!CmdLine_Append(cl, NCDValue_StringValue(arg))) {
            ModuleLog(i, BLOG_ERROR, "CmdLine_Append failed");
            goto fail2;
        }
    }
    
    // finish
    if (!CmdLine_Finish(cl)) {
        ModuleLog(i, BLOG_ERROR, "CmdLine_Finish failed");
        goto fail2;
    }
    
    return 1;
    
fail2:
    CmdLine_Free(cl);
fail1:
    free(*exec);
fail0:
    return 0;
}
Пример #10
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;
    o->term_on_deinit = 0;
    
    // read arguments
    NCDValue *cmd_arg;
    NCDValue *opts_arg = NULL;
    if (!NCDValue_ListRead(i->args, 1, &cmd_arg) && !NCDValue_ListRead(i->args, 2, &cmd_arg, &opts_arg)) {
        ModuleLog(i, BLOG_ERROR, "wrong arity");
        goto fail1;
    }
    if (opts_arg && NCDValue_Type(opts_arg) != NCDVALUE_LIST) {
        ModuleLog(i, BLOG_ERROR, "wrong type");
        goto fail1;
    }
    
    int keep_stdout = 0;
    int keep_stderr = 0;
    int do_setsid = 0;
    
    // read options
    for (NCDValue *opt = (opts_arg ? NCDValue_ListFirst(opts_arg) : NULL); opt; opt = NCDValue_ListNext(opts_arg, opt)) {
        // read name
        if (NCDValue_Type(opt) != NCDVALUE_STRING) {
            ModuleLog(o->i, BLOG_ERROR, "wrong option name type");
            goto fail1;
        }
        char *optname = NCDValue_StringValue(opt);
        
        if (!strcmp(optname, "term_on_deinit")) {
            o->term_on_deinit = 1;
        }
        else if (!strcmp(optname, "keep_stdout")) {
            keep_stdout = 1;
        }
        else if (!strcmp(optname, "keep_stderr")) {
            keep_stderr = 1;
        }
        else if (!strcmp(optname, "do_setsid")) {
            do_setsid = 1;
        }
        else {
            ModuleLog(o->i, BLOG_ERROR, "unknown option name");
            goto fail1;
        }
    }
    
    // build cmdline
    char *exec;
    CmdLine cl;
    if (!build_cmdline(o->i, cmd_arg, &exec, &cl)) {
        goto fail1;
    }
    
    // build fd mapping
    int fds[3];
    int fds_map[2];
    int nfds = 0;
    if (keep_stdout) {
        fds[nfds] = 1;
        fds_map[nfds++] = 1;
    }
    if (keep_stderr) {
        fds[nfds] = 2;
        fds_map[nfds++] = 2;
    }
    fds[nfds] = -1;
    
    // build params
    struct BProcess_params params;
    params.username = NULL;
    params.fds = fds;
    params.fds_map = fds_map;
    params.do_setsid = do_setsid;
    
    // start process
    if (!BProcess_Init2(&o->process, o->i->params->manager, (BProcess_handler)process_handler, o, exec, CmdLine_Get(&cl), params)) {
        ModuleLog(i, BLOG_ERROR, "BProcess_Init failed");
        CmdLine_Free(&cl);
        free(exec);
        goto fail1;
    }
    
    CmdLine_Free(&cl);
    free(exec);
    
    // set state
    o->state = STATE_RUNNING;
    
    return;
    
fail1:
    free(o);
fail0:
    NCDModuleInst_Backend_SetError(i);
    NCDModuleInst_Backend_Dead(i);
}