diff options
author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-06-06 16:54:31 -0400 |
---|---|---|
committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-06-06 16:54:31 -0400 |
commit | 2c85890eea236f53c1dc6e0a6b3bd1e45437288d (patch) | |
tree | 1582d190cfc76667c96fb792875a6cdb2f814508 /src/format.c | |
parent | be996fed5258d70a9f34ecbae1d7aea74f91cfa1 (diff) | |
download | slapi-nis-2c85890eea236f53c1dc6e0a6b3bd1e45437288d.tar.gz slapi-nis-2c85890eea236f53c1dc6e0a6b3bd1e45437288d.tar.xz slapi-nis-2c85890eea236f53c1dc6e0a6b3bd1e45437288d.zip |
- forget about tracking visited DNs, just track attributes used for refs
(outgoing) and inref info (incoming)
Diffstat (limited to 'src/format.c')
-rw-r--r-- | src/format.c | 250 |
1 files changed, 203 insertions, 47 deletions
diff --git a/src/format.c b/src/format.c index 9eb8978..d584b74 100644 --- a/src/format.c +++ b/src/format.c @@ -28,6 +28,7 @@ #include <fnmatch.h> #include <regex.h> #include <stdlib.h> +#include <string.h> #ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H #include <nspr.h> @@ -50,7 +51,9 @@ static int format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *fmt, char *outbuf, int outbuf_len, - char ***visited_ndns, bool_t contains_literals); + char ***ref_attrs, + struct format_inref_attr ***inref_attrs, + bool_t is_expression); void format_free_data(char *data) @@ -60,11 +63,157 @@ format_free_data(char *data) } } +char ** +format_dup_attr_list(char **attr_list) +{ + int i, elements, length; + char **ret, *p; + length = 0; + elements = 0; + if (*attr_list != NULL) { + for (i = 0; attr_list[i] != NULL; i++) { + length += (strlen(attr_list[i] + 1)); + } + elements = i; + } + ret = malloc(((elements + 1) * sizeof(char *)) + length); + if (ret != NULL) { + p = (char *) ret; + p += (elements + 1) * sizeof(char *); + for (i = 0; i < elements; i++) { + ret[i] = p; + strcpy(p, attr_list[i]); + p += (strlen(attr_list[i]) + 1); + } + ret[i] = NULL; + } + return ret; +} + void -format_free_ndn_list(char **ndn_list) +format_add_attr_list(char ***attr_list, const char *value) { - if (ndn_list != NULL) { - free(ndn_list); + int i, elements, length; + char **ret, *p; + + length = strlen(value) + 1; + elements = 0; + if (*attr_list != NULL) { + for (i = 0; (*attr_list)[i] != NULL; i++) { + if (strcmp(value, (*attr_list)[i]) == 0) { + return; + } + length += (strlen((*attr_list)[i] + 1)); + elements++; + } + } + + ret = malloc(((elements + 2) * sizeof(char *)) + length); + if (ret != NULL) { + p = (char *) ret; + p += (elements + 2) * sizeof(char *); + for (i = 0; i < elements; i++) { + ret[i] = p; + strcpy(p, (*attr_list)[i]); + p += (strlen((*attr_list)[i]) + 1); + } + ret[i++] = p; + strcpy(p, value); + p += (strlen(value) + 1); + ret[i] = NULL; + format_free_attr_list(*attr_list); + } + *attr_list = ret; +} + +void +format_free_attr_list(char **attr_list) +{ + if (attr_list != NULL) { + free(attr_list); + } +} + +struct format_inref_attr ** +format_dup_inref_attrs(struct format_inref_attr **attrs) +{ + int i, j, elements; + struct format_inref_attr **ret; + + elements = 0; + ret = NULL; + if (attrs != NULL) { + for (i = 0; attrs[i] != NULL; i++) { + continue; + } + elements = i; + ret = malloc(sizeof(*ret) * (elements + 1)); + if (ret != NULL) { + for (i = 0, j = 0; i < elements; i++) { + ret[j] = malloc(sizeof(**attrs)); + if (ret[j] != NULL) { + ret[j]->domain = + strdup(attrs[i]->domain); + ret[j]->map = strdup(attrs[i]->map); + ret[j]->attribute = + strdup(attrs[i]->attribute); + if ((ret[j]->map != NULL) && + (ret[j]->attribute != NULL)) { + j++; + } + } + } + ret[j] = NULL; + } + } + return ret; +} +void +format_add_inref_attrs(struct format_inref_attr ***attrs, + const char *domain, const char *map, + const char *attribute) +{ + struct format_inref_attr **ret; + int i, elements; + elements = 0; + ret = NULL; + if (*attrs != NULL) { + for (i = 0; (*attrs)[i] != NULL; i++) { + if ((strcmp((*attrs)[i]->domain, domain) == 0) && + (strcmp((*attrs)[i]->map, map) == 0) && + (strcmp((*attrs)[i]->attribute, attribute) == 0)) { + return; + } + } + elements = i; + } + ret = malloc(sizeof(*ret) * (elements + 2)); + if (ret != NULL) { + memcpy(ret, *attrs, elements * sizeof(**attrs)); + ret[elements] = malloc(sizeof(**ret)); + if (ret[elements] != NULL) { + ret[elements]->domain = strdup(domain); + ret[elements]->map = strdup(map); + ret[elements]->attribute = strdup(attribute); + ret[elements + 1] = NULL; + } + free(*attrs); + *attrs = ret; + } +} + +void +format_free_inref_attrs(struct format_inref_attr **attrs) +{ + int i; + if (attrs != NULL) { + for (i = 0; attrs[i] != NULL; i++) { + free(attrs[i]->domain); + free(attrs[i]->map); + free(attrs[i]->attribute); + free(attrs[i]); + } + free(attrs); } } @@ -136,7 +285,7 @@ static int format_echo(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, - char ***visited_ndns) + char ***ref_attrs, struct format_inref_attr ***inref_attrs) { int ret, i, argc, len; char **argv; @@ -176,7 +325,7 @@ static int format_list(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, - char ***visited_ndns) + char ***ref_attrs, struct format_inref_attr ***inref_attrs) { int ret, i, j, len, slen, count, argc; Slapi_ValueSet *values; @@ -255,7 +404,7 @@ static int format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, - char ***visited_ndns) + char ***ref_attrs, struct format_inref_attr ***inref_attrs) { int i, j, len, slen, ret, count, argc; Slapi_Entry *ref; @@ -277,6 +426,10 @@ format_deref(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, format_free_parsed_args(argv); return -EINVAL; } + /* Note that the attribute in this entry refers to other entries. */ + if (ref_attrs != NULL) { + format_add_attr_list(ref_attrs, argv[1]); + } /* Get the names of the reference attribute. */ if (slapi_vattr_values_get(e, argv[1], &ref_values, &ref_disposition, &actual_ref_attr, @@ -476,7 +629,7 @@ static int format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, - char ***visited_ndns) + char ***ref_attrs, struct format_inref_attr ***inref_attrs) { int i, j, len, slen, ret, count, argc; Slapi_Entry *ref; @@ -537,6 +690,11 @@ format_referred(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, domain, argv[1]); } + /* Note that the attribute in this map refers to this entry. */ + if (inref_attrs != NULL) { + format_add_inref_attrs(inref_attrs, domain, argv[1], argv[2]); + } + /* Now just search through the entries used for the map. */ for (i = 0; (map_bases != NULL) && (map_bases[i] != NULL); i++) { /* Build the search filter. */ @@ -587,7 +745,7 @@ static int format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, - char ***visited_ndns) + char ***ref_attrs, struct format_inref_attr ***inref_attrs) { int ret, i, argc, len, slen, count; char **argv; @@ -611,7 +769,7 @@ format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, len = format_expand(state, pb, e, domain, map, argv[i], outbuf + ret + (count ? slen : 0), outbuf_len - (ret + (count ? slen : 0)), - visited_ndns, TRUE); + ref_attrs, inref_attrs, FALSE); if (len < 0) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, @@ -653,7 +811,8 @@ format_match_generic(struct plugin_state *state, const char *domain, const char *map, const char *args, int min_args, int default_arg, char *outbuf, int outbuf_len, - char ***visited_ndns, + char ***ref_attrs, + struct format_inref_attr ***inref_attrs, const char *fnname, char * (*match_fn)(const char *pattern, const char *value, char **argv)) @@ -802,10 +961,10 @@ format_match(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, - char ***visited_ndns) + char ***ref_attrs, struct format_inref_attr ***inref_attrs) { return format_match_generic(state, pb, e, domain, map, args, 2, 2, - outbuf, outbuf_len, visited_ndns, + outbuf, outbuf_len, ref_attrs, inref_attrs, "format_match", format_match_cb); } @@ -829,10 +988,10 @@ format_regmatch(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, - char ***visited_ndns) + char ***ref_attrs, struct format_inref_attr ***inref_attrs) { return format_match_generic(state, pb, e, domain, map, args, 2, 2, - outbuf, outbuf_len, visited_ndns, + outbuf, outbuf_len, ref_attrs, inref_attrs, "format_regmatch", format_regmatch_cb); } @@ -949,10 +1108,10 @@ format_regsub(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, - char ***visited_ndns) + char ***ref_attrs, struct format_inref_attr ***inref_attrs) { return format_match_generic(state, pb, e, domain, map, args, 3, 3, - outbuf, outbuf_len, visited_ndns, + outbuf, outbuf_len, ref_attrs, inref_attrs, "format_regsub", format_regsub_cb); } @@ -968,7 +1127,8 @@ format_lookup_fn(const char *fnname) const char *domain, const char *map, const char *args, char *outbuf, int outbuf_len, - char ***visited_ndns); + char ***ref_attrs, + struct format_inref_attr ***inref_attrs); } fns[] = { {"echo", format_echo}, {"list", format_list}, @@ -992,7 +1152,7 @@ format_lookup_fn(const char *fnname) * than one, fail. */ static char * format_single(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, - const char *attr, char ***visited_ndns) + const char *attr) { Slapi_ValueSet *value_set; Slapi_Value *value; @@ -1076,15 +1236,16 @@ xstrndupp(const char *start, const char *end) return ret; } -/* Recursively expand the expression into the output buffer, adding any entries - * we visit (other than e) to the list of visited NDNs. Unless it's a literal, - * treat the entire input format specifier as an expression. */ +/* Recursively expand the expression into the output buffer. adding any entries + * we visit (other than e) to the list of visited NDNs. If the result will + * also be an expression, treat the entire result as an attribute specifier and + * evaluate it, otherwise return it. */ static int format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *fmt, char *outbuf, int outbuf_len, - char ***visited_ndns, - bool_t contains_literals) + char ***ref_attrs, struct format_inref_attr ***inref_attrs, + bool_t is_expression) { int i, j; int exp_used, exp_size, level; @@ -1096,7 +1257,9 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, int (*formatfn)(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, const char *args, - char *outbuf, int outbuf_len, char ***visited_ndns); + char *outbuf, int outbuf_len, + char ***ref_attrs, + struct format_inref_attr ***inref_attrs); spd_id = state->plugin_desc->spd_id; exp_size = outbuf_len * 2; @@ -1158,8 +1321,9 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, tmp, expr + j, exp_size - j, - visited_ndns, - FALSE); + ref_attrs, + inref_attrs, + TRUE); if (exp_used < 0) { /* Miscellaneous failure, FAIL. */ @@ -1265,7 +1429,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, exp_used = (*formatfn)(state, pb, e, domain, map, tmp, expr + j, exp_size - j, - visited_ndns); + ref_attrs, inref_attrs); free(tmp); if (exp_used < 0) { /* Error in function, FAIL. */ @@ -1306,8 +1470,8 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, } expr[j] = '\0'; - if (contains_literals) { - /* It's a full format specifier, so we're actually done. */ + if (!is_expression) { + /* The result is literal text, so we're done. */ i = strlen(expr); if (i <= outbuf_len) { memcpy(outbuf, expr, i); @@ -1347,7 +1511,7 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, } } /* Retrieve the value. */ - tmp = format_single(state, pb, e, attribute, visited_ndns); + tmp = format_single(state, pb, e, attribute); if (tmp == NULL) { /* The attribute is undefined, or we're treating it as * if it is. */ @@ -1393,7 +1557,8 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, static char * format_format(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, - const char *fmt, char ***visited_ndns) + const char *fmt, + char ***ref_attrs, struct format_inref_attr ***inref_attrs) { char *buf, *tmp, *ret, *spd_id; const char *match, *fmtstart, *fmtend; @@ -1414,7 +1579,7 @@ format_format(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, } i = format_expand(state, pb, e, domain, map, fmt, buf, buflen, - visited_ndns, TRUE); + ref_attrs, inref_attrs, FALSE); if ((i >= 0) && (i < buflen)) { buf[i] = '\0'; ret = strdup(buf); @@ -1460,19 +1625,13 @@ format_format(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, char * format_get_data(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, const char *domain, const char *map, - const char *fmt, char ***visited_ndns) + const char *fmt, + char ***ref_attrs, + struct format_inref_attr ***inref_attrs) { Slapi_PBlock *local_pb; char ***ndn_list, **local_ndn_list, *ret; - /* Supply an NDN list if the caller didn't. */ - if (visited_ndns != NULL) { - ndn_list = visited_ndns; - } else { - ndn_list = &local_ndn_list; - local_ndn_list = NULL; - } - /* Supply a PBlock if the caller didn't. */ if (pb == NULL) { local_pb = slapi_pblock_new(); @@ -1481,16 +1640,13 @@ format_get_data(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e, local_pb = NULL; } - ret = format_format(state, pb, e, domain, map, fmt, ndn_list); + ret = format_format(state, pb, e, domain, map, fmt, + ref_attrs, inref_attrs); /* If we supplied a PBlock, clean it up. */ if (pb == local_pb) { slapi_pblock_destroy(local_pb); } - /* If we supplied an NDN list, clean it up. */ - if (ndn_list == &local_ndn_list) { - format_free_ndn_list(local_ndn_list); - } return ret; } |