diff options
| author | Nalin Dahyabhai <nalin@dahyabhai.net> | 2008-05-14 00:26:57 -0400 |
|---|---|---|
| committer | Nalin Dahyabhai <nalin@dahyabhai.net> | 2008-05-14 00:26:57 -0400 |
| commit | bed403e5b6614c0f7d9a50386aa98fb4f97a4a20 (patch) | |
| tree | 6e6a9f4fe71ee70ade49c1970db2bc3880a68b26 /src | |
| parent | 3864a728ddbc0ae8bea457b0c07e0bd6eae6c26a (diff) | |
- add the "merge" function
Diffstat (limited to 'src')
| -rw-r--r-- | src/format.c | 206 |
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 " |
