diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/format.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/format.c b/src/format.c index 9871ac6..9c25d4c 100644 --- a/src/format.c +++ b/src/format.c @@ -2900,6 +2900,112 @@ format_link(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, return ret; } +/* Eliminate duplicate values from the list. */ +static int +format_unique(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, + const char *group, const char *set, + const char *args, const char *disallowed, + char *outbuf, int outbuf_len, + struct format_choice **outbuf_choices, + char ***rel_attrs, + char ***ref_attrs, struct format_inref_attr ***inref_attrs, + struct format_ref_attr_list ***ref_attr_list, + struct format_ref_attr_list ***inref_attr_list) +{ + int ret, i, j, argc; + char **argv, **values; + const char *value_format, *default_value; + unsigned int *lengths; + struct berval **choices, bv; + + ret = format_parse_args(state, args, &argc, &argv); + if (ret != 0) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "unique: error parsing arguments\n"); + return -EINVAL; + } + if (argc < 1) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "unique: error parsing arguments\n"); + format_free_parsed_args(argv); + return -EINVAL; + } + if (argc < 2) { + value_format = argv[0]; + default_value = NULL; + } else { + value_format = argv[0]; + default_value = argv[1]; + } + ret = -ENOENT; + values = format_get_data_set(state, e, group, set, + value_format, disallowed, + rel_attrs, ref_attrs, inref_attrs, + ref_attr_list, inref_attr_list, + &lengths); + if (values == NULL) { + if (default_value == NULL) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "unique: no values for ->%s<-, " + "and no default value provided\n", + value_format); + ret = -ENOENT; + } else { + i = format_expand(state, pb, e, + group, set, + default_value, NULL, + outbuf, outbuf_len, + outbuf_choices, + rel_attrs, ref_attrs, inref_attrs, + ref_attr_list, inref_attr_list); + ret = i; + } + } else { + if (values != NULL) { + choices = NULL; + for (i = 0; values[i] != NULL; i++) { + /* XXX this is horribly slow */ + for (j = 0; j < i; j++) { + if ((lengths[i] == lengths[j]) && + (memcmp(values[i], values[j], lengths[i]) == 0)) { + break; + } + } + if (j == i) { + /* Add it to the list. */ + bv.bv_val = values[i]; + bv.bv_len = lengths[i]; + format_add_bv_list(&choices, &bv); + } + } + format_free_data_set(values, lengths); + if (choices != NULL) { + for (i = 0; choices[i] != NULL; i++) { + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "unique: returning \"%.*s\" as a " + "value for \"%s\"\n", + (int) choices[i]->bv_len, + choices[i]->bv_val, + slapi_entry_get_dn(e)); + continue; + } + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "unique: returning %d values for \"%s\"\n", i, + slapi_entry_get_dn(e)); + format_add_choice(outbuf_choices, outbuf, &choices); + ret = 0; + } else { + ret = -ENOENT; + } + } + } + format_free_parsed_args(argv); + return ret; +} + /* Choose a formatting function by name. */ static void * format_lookup_fn(const char *fnname) @@ -2936,6 +3042,8 @@ format_lookup_fn(const char *fnname) {"ifeq", format_ifeq}, {"collect", format_collect}, {"link", format_link}, + {"unique", format_unique}, + /* {"uuid", format_uuid}, */ }; for (i = 0; i < sizeof(fns) / sizeof(fns[0]); i++) { if ((fns[i].name != NULL) && |
