summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@dahyabhai.net>2008-05-14 00:26:57 -0400
committerNalin Dahyabhai <nalin@dahyabhai.net>2008-05-14 00:26:57 -0400
commitbed403e5b6614c0f7d9a50386aa98fb4f97a4a20 (patch)
tree6e6a9f4fe71ee70ade49c1970db2bc3880a68b26 /src
parent3864a728ddbc0ae8bea457b0c07e0bd6eae6c26a (diff)
- add the "merge" function
Diffstat (limited to 'src')
-rw-r--r--src/format.c206
1 files changed, 160 insertions, 46 deletions
diff --git a/src/format.c b/src/format.c
index b72c0a6..a38fe98 100644
--- a/src/format.c
+++ b/src/format.c
@@ -5,6 +5,12 @@
#include "format.h"
#include "plugin.h"
+static int format_expand(struct plugin_state *state,
+ Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *fmt,
+ char *outbuf, int outbuf_len,
+ char ***visited_ndns, PRBool literal);
+
void
format_free_data(char *data)
{
@@ -123,7 +129,7 @@ format_list(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
const char *args, char *outbuf, int outbuf_len,
char ***visited_ndns)
{
- int ret, i, j, len, count, argc;
+ int ret, i, j, len, slen, count, argc;
char **argv, **values;
ret = format_parse_args(state, args, &argc, &argv);
if (ret != 0) {
@@ -135,12 +141,27 @@ format_list(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
/* Get the list of values for this attribute. */
values = slapi_entry_attr_get_charray(e, argv[i]);
for (j = 0; (values != NULL) && (values[j] != NULL); j++) {
+ /* Get the length of the value. */
+ len = strlen(values[j]);
+ /* Check if we have space for the value. */
+ if (ret + len > outbuf_len) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "list: out of space\n");
+ slapi_ch_array_free(values);
+ format_free_parsed_args(argv);
+ return -1;
+ }
+ /* If the value is empty, skip it. */
+ if (len == 0) {
+ continue;
+ }
/* If we've already added values, add the separator. */
if (count > 0) {
/* Get the length of the separator. */
- len = strlen(argv[0]);
+ slen = strlen(argv[0]);
/* Check if we have space for the separator. */
- if (ret + len > outbuf_len) {
+ if (ret + len + slen > outbuf_len) {
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
"list: out of space\n");
@@ -149,19 +170,8 @@ format_list(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
return -1;
}
/* Copy in the separator. */
- memcpy(outbuf + ret, argv[0], len);
- ret += len;
- }
- /* Get the length of the value. */
- len = strlen(values[j]);
- /* Check if we have space for the value. */
- if (ret + len > outbuf_len) {
- slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc->spd_id,
- "list: out of space\n");
- slapi_ch_array_free(values);
- format_free_parsed_args(argv);
- return -1;
+ memcpy(outbuf + ret, argv[0], slen);
+ ret += slen;
}
/* Copy in the value. */
memcpy(outbuf + ret, values[j], len);
@@ -184,7 +194,7 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
const char *args, char *outbuf, int outbuf_len,
char ***visited_ndns)
{
- int i, j, len, ret, count, argc;
+ int i, j, len, slen, ret, count, argc;
Slapi_Entry *ref;
Slapi_DN *refdn;
char **argv, **values, **refs, *attrs[3];
@@ -203,12 +213,17 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
}
/* Get the names of the references. */
refs = slapi_entry_attr_get_charray(e, argv[0]);
+ if (refs == NULL) {
+ /* No references. */
+ format_free_parsed_args(argv);
+ return -1;
+ }
/* Retrieve these attributes from the referred-to entries. */
attrs[0] = argv[0];
attrs[1] = argv[1];
attrs[2] = NULL;
/* Iterate through the names of the referred-to entries. */
- for (i = 0, count = 0; (refs != NULL) && (refs[i] != NULL); i++) {
+ for (i = 0, count = 0; refs[i] != NULL; i++) {
/* Pull up the referred-to entry. */
refdn = slapi_sdn_new_dn_byval(refs[i]);
if (refdn == NULL) {
@@ -226,14 +241,30 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
for (j = 0;
(values != NULL) && (values[j] != NULL);
j++) {
- /* If we've already added one value, add the separator.
- */
+ /* Get the length of the value. */
+ len = strlen(values[j]);
+ /* Check if there's space for the value. */
+ if (ret + len > outbuf_len) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "deref: out of space\n");
+ slapi_ch_array_free(values);
+ slapi_entry_free(ref);
+ slapi_ch_array_free(refs);
+ format_free_parsed_args(argv);
+ return -1;
+ }
+ /* If the value is empty, skip it. */
+ if (len == 0) {
+ continue;
+ }
+ /* If we need to, add the separator. */
if (count > 0) {
/* Get the length of the separator. */
sep = (argc > 2) ? argv[2] : ",";
- len = strlen(sep);
+ slen = strlen(sep);
/* Check if there's space for the separator. */
- if (ret + len > outbuf_len) {
+ if (ret + len + slen > outbuf_len) {
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
"deref: out of space\n");
@@ -244,21 +275,8 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
return -1;
}
/* Append the separator. */
- memcpy(outbuf + ret, sep, len);
- ret += len;
- }
- /* Get the length of the value. */
- len = strlen(values[j]);
- /* Check if there's space for the value. */
- if (ret + len > outbuf_len) {
- slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc->spd_id,
- "deref: out of space\n");
- slapi_ch_array_free(values);
- slapi_entry_free(ref);
- slapi_ch_array_free(refs);
- format_free_parsed_args(argv);
- return -1;
+ memcpy(outbuf + ret, sep, slen);
+ ret += slen;
}
/* Append the value. */
memcpy(outbuf + ret, values[j], len);
@@ -273,6 +291,83 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
return ret;
}
+/* Evaluate each argument, after the first, in turn, and merge them, using the
+ * first argument as a separator. */
+static int
+format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *args, char *outbuf, int outbuf_len,
+ char ***visited_ndns)
+{
+ int ret, i, argc, len, slen, count;
+ char scratch[LINE_MAX];
+ char **argv;
+ ret = format_parse_args(state, args, &argc, &argv);
+ if (ret != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "merge: error parsing arguments\n");
+ return -1;
+ }
+ for (i = 1, ret = 0, count = 0; i < argc; i++) {
+ /* Expand this argument. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "merge: expanding ->%s<-\n",
+ argv[i]);
+ len = format_expand(state, pb, e, argv[i],
+ scratch, sizeof(scratch),
+ visited_ndns, TRUE);
+ /* Check that we've got space for this value. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "merge: expanding ->%s<-\n",
+ argv[i]);
+ if (len < 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "merge: failed to expand ->%s<-\n",
+ argv[i]);
+ continue;
+ }
+ if (ret + len > outbuf_len) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "merge: out of space\n");
+ format_free_parsed_args(argv);
+ return -1;
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "merge: expanded ->%s<- to ->%.*s<-\n",
+ argv[i], len, scratch);
+ /* If the value is empty, skip it. */
+ if (len == 0) {
+ continue;
+ }
+ /* Add the separator if we need to add it. */
+ if (count > 0) {
+ /* Check that we've got space for the separator. */
+ slen = strlen(argv[0]);
+ /* Check that we've got space for the separator. */
+ if (ret + len + slen > outbuf_len) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "merge: out of space\n");
+ format_free_parsed_args(argv);
+ return -1;
+ }
+ /* Append the separator. */
+ memcpy(outbuf + ret, argv[0], slen);
+ ret += slen;
+ }
+ /* Append the text of the argument. */
+ memcpy(outbuf + ret, scratch, len);
+ ret += len;
+ count++;
+ }
+ format_free_parsed_args(argv);
+ return ret;
+}
+
/* Choose a formatting function by name. */
static void *
format_lookup_fn(const char *fnname)
@@ -289,6 +384,7 @@ format_lookup_fn(const char *fnname)
{"echo", format_echo},
{"list", format_list},
{"deref", format_deref},
+ {"merge", format_merge},
};
for (i = 0; i < sizeof(fns) / sizeof(fns[0]); i++) {
if ((fns[i].name != NULL) &&
@@ -425,10 +521,19 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
visited_ndns,
FALSE);
free(tmp);
- if ((exp_len < 0) ||
- (exp_len + j >= (int) sizeof(exp))) {
- /* We'd be out of space,
- * FAIL. */
+ if (exp_len < 0) {
+ /* Miscellaneous failure, FAIL.
+ */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ spd_id,
+ "error "
+ "expanding "
+ "->%s<-\n",
+ tmp);
+ return -1;
+ }
+ if (exp_len + j >= (int) sizeof(exp)) {
+ /* Out of space, FAIL. */
slapi_log_error(SLAPI_LOG_PLUGIN,
spd_id,
"expansion "
@@ -516,12 +621,21 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
exp_len = (*formatfn)(state, pb, e, tmp,
exp + j, sizeof(exp) - j,
visited_ndns);
- free(fnname);
free(tmp);
- if ((exp_len < 0) ||
- (exp_len + j >= (int) sizeof(exp))) {
- /* We'd be out of space,
- * FAIL. */
+ if (exp_len < 0) {
+ /* Error in function, FAIL. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ spd_id,
+ "expansion "
+ "failed: function "
+ "'%s' failed\n",
+ fnname);
+ free(fnname);
+ return -1;
+ }
+ free(fnname);
+ if (exp_len + j >= (int) sizeof(exp)) {
+ /* We'd be out of space, FAIL. */
slapi_log_error(SLAPI_LOG_PLUGIN,
spd_id,
"expansion "