summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/format.c84
1 files changed, 76 insertions, 8 deletions
diff --git a/src/format.c b/src/format.c
index 27f0364..7bb22ac 100644
--- a/src/format.c
+++ b/src/format.c
@@ -322,6 +322,58 @@ format_echo(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
return ret;
}
+/* Choose the first value of the attribute in the entry. */
+static int
+format_first(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *domain, const char *map,
+ const char *args, const char *disallowed,
+ char *outbuf, int outbuf_len,
+ char ***ref_attrs, struct format_inref_attr ***inref_attrs)
+{
+ int ret, i, len, slen, count, argc;
+ Slapi_ValueSet *values;
+ Slapi_Value *value;
+ char **argv, *actual_attr;
+ const char *cvalue;
+ int disposition, buffer_flags;
+ ret = format_parse_args(state, args, &argc, &argv);
+ if (argc != 1) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "first: error parsing arguments\n");
+ return -EINVAL;
+ }
+ ret = -ENOENT;
+ /* Get the list of values for this attribute. */
+ if (slapi_vattr_values_get(e, argv[0], &values, &disposition,
+ &actual_attr, 0,
+ &buffer_flags) == 0) {
+ i = slapi_valueset_first_value(values, &value);
+ if (i != -1) {
+ /* Get the length of the value. */
+ cvalue = slapi_value_get_string(value);
+ len = strlen(cvalue);
+ /* Check if we have space for the value. */
+ if (ret + len > outbuf_len) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "first: out of space\n");
+ ret = -ENOBUFS;
+ } else {
+ /* Copy in the value. */
+ memcpy(outbuf + ret, cvalue, len);
+ ret += len;
+ }
+ } else {
+ /* No such attribute. */
+ ret = -ENOENT;
+ }
+ /* Free the value set for this attribute. */
+ slapi_vattr_values_free(&values, &actual_attr, buffer_flags);
+ }
+ format_free_parsed_args(argv);
+ return ret;
+}
+
/* Create a list of the values of the attributes which are passed as arguments,
* joined by a separator given as the first argument. */
static int
@@ -824,7 +876,8 @@ format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
static int
format_case(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
const char *domain, const char *map,
- const char *args, char *outbuf, int outbuf_len,
+ const char *args, const char *disallowed,
+ char *outbuf, int outbuf_len,
char ***ref_attrs, struct format_inref_attr ***inref_attrs,
const char *fnname, int (*cb)(int))
{
@@ -843,8 +896,18 @@ format_case(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
return -EINVAL;
}
for (i = 0, ret = 0; i < argc; i++) {
- /* Get the length of this argument. */
- len = strlen(argv[i]);
+ /* Get the length of the expanded value of this argument. */
+ len = format_expand(state, pb, e, domain, map,
+ argv[i], disallowed,
+ outbuf + ret, outbuf_len - ret,
+ ref_attrs, inref_attrs, FALSE);
+ if (len < 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "%s: error expanding \"%s\'\n",
+ argv[i], fnname);
+ return -ENOBUFS;
+ }
/* Check that we've got space for this argument. */
if (ret + len > outbuf_len) {
slapi_log_error(SLAPI_LOG_PLUGIN,
@@ -854,7 +917,7 @@ format_case(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
}
/* Append the text of the argument. */
for (j = 0; j < len; j++) {
- outbuf[ret + j] = (*cb)(argv[i][j]);
+ outbuf[ret + j] = (*cb)(outbuf[ret + j]);
}
ret += len;
}
@@ -865,20 +928,24 @@ format_case(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
static int
format_up(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
const char *domain, const char *map,
- const char *args, char *outbuf, int outbuf_len,
+ const char *args, const char *disallowed,
+ char *outbuf, int outbuf_len,
char ***ref_attrs, struct format_inref_attr ***inref_attrs)
{
- return format_case(state, pb, e, domain, map, args, outbuf, outbuf_len,
+ return format_case(state, pb, e, domain, map, args, disallowed,
+ outbuf, outbuf_len,
ref_attrs, inref_attrs, "up", toupper);
}
static int
format_down(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
const char *domain, const char *map,
- const char *args, char *outbuf, int outbuf_len,
+ const char *args, const char *disallowed,
+ char *outbuf, int outbuf_len,
char ***ref_attrs, struct format_inref_attr ***inref_attrs)
{
- return format_case(state, pb, e, domain, map, args, outbuf, outbuf_len,
+ return format_case(state, pb, e, domain, map, args, disallowed,
+ outbuf, outbuf_len,
ref_attrs, inref_attrs, "down", tolower);
}
@@ -1222,6 +1289,7 @@ format_lookup_fn(const char *fnname)
{"echo", format_echo},
{"up", format_up},
{"down", format_down},
+ {"first", format_first},
{"list", format_list},
{"deref", format_deref},
{"referred", format_referred},