示例#1
0
文件: plugin.c 项目: NiChrome/krb5
/* Expand *list_inout to contain the mappings from modstrs, followed by the
 * existing built-in module mappings. */
static krb5_error_code
make_full_list(krb5_context context, char **modstrs,
               struct plugin_mapping ***list_inout)
{
    krb5_error_code ret = 0;
    size_t count, pos, i, j;
    struct plugin_mapping **list, **mp;
    char **mod;

    /* Allocate space for all of the modules plus a null terminator. */
    for (count = 0; modstrs[count] != NULL; count++);
    for (mp = *list_inout; mp != NULL && *mp != NULL; mp++, count++);
    list = calloc(count + 1, sizeof(*list));
    if (list == NULL)
        return ENOMEM;

    /* Parse each profile module entry and store it in the list. */
    for (mod = modstrs, pos = 0; *mod != NULL; mod++, pos++) {
        ret = parse_modstr(context, *mod, &list[pos]);
        if (ret != 0) {
            free_mapping_list(list);
            return ret;
        }
    }

    /* Cannibalize the old list of built-in modules. */
    for (mp = *list_inout; mp != NULL && *mp != NULL; mp++, pos++)
        list[pos] = *mp;
    assert(pos == count);

    /* Filter out duplicates, preferring earlier entries to later ones. */
    for (i = 0, pos = 0; i < count; i++) {
        for (j = 0; j < pos; j++) {
            if (strcmp(list[i]->modname, list[j]->modname) == 0) {
                free_plugin_mapping(list[i]);
                break;
            }
        }
        if (j == pos)
            list[pos++] = list[i];
    }
    list[pos] = NULL;

    free(*list_inout);
    *list_inout = list;
    return 0;
}
static int cmdlet_list(CmdLetData *cdata, int ac, char **av)
{
    glob_t globbuf;
    int ret, i = 0, fid = 0 /* fixed id */, tid = 0; /* template id */
    uint32_t modkind[2] = { 0, 0 };
    ModRequest fixed;

    if (ac != 2) {
        tc_log_error(EXE, "wrong number of arguments for `list' mode");
        return STATUS_BAD_PARAM;
    }
    /* we support only encoder|multiplexor, yet */
    modkind[0] = parse_modstr(av[0]);
    if (!(modkind[0] & TC_MODULE_ENCODER)) {
        tc_log_error(EXE, "unknown/unsupported module '%s'", av[0]);
        return STATUS_BAD_PARAM;
    }
    modkind[1] = parse_modstr(av[1]);
    if (!(modkind[1] & TC_MODULE_MUXER)) {
        tc_log_error(EXE, "unknown/unsupported module '%s'", av[1]);
        return STATUS_BAD_PARAM;
    }

    if ((modkind[0] & TC_MODULE_FIXED)
     && (modkind[1] & TC_MODULE_TEMPLATE)) {
        fid = 0;
        tid = 1;    
    } else if ((modkind[0] & TC_MODULE_TEMPLATE)
            && (modkind[1] & TC_MODULE_FIXED)) {
        fid = 1;
        tid = 0;
    } else {
        tc_log_error(EXE, "incorrect arguments,"
                          " maybe you want to use `check' mode?");
        return STATUS_BAD_PARAM;
    }

    modrequest_init(&fixed);
    ret = modrequest_load(cdata->factory, &fixed, av[fid]);
    if (ret != TC_OK) {
        return STATUS_MODULE_ERROR;
    }

    ret = modrequest_scan(cdata->modpath, av[tid], &globbuf);
    if (ret != 0) {
        return STATUS_GLOB_FAILED;
    }
    ret = modrequest_fill(cdata->factory, cdata->mods, MAX_MODS,
                          &cdata->modsnum, &globbuf);
    if (ret != TC_OK) {
        return STATUS_MODULE_ERROR;
    }

    for (i = 0; i < cdata->modsnum; i++) {
        const ModRequest *H = (tid == 0) ?(&cdata->mods[i]) :(&fixed);
        const ModRequest *T = (tid == 1) ?(&cdata->mods[i]) :(&fixed);
        check_module_pair(H, T, &(cdata->mods[i]),
                          (verbose == 0) ?TC_INFO :verbose);
    }

    CLEANUP(cdata);
    modrequest_free(&globbuf);
    ret = modrequest_unload(cdata->factory, &fixed);
    if (ret != TC_OK) {
        return STATUS_MODULE_ERROR;
    }
    return STATUS_OK;
}