summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-06 16:54:31 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-06 16:54:31 -0400
commit2c85890eea236f53c1dc6e0a6b3bd1e45437288d (patch)
tree1582d190cfc76667c96fb792875a6cdb2f814508 /src
parentbe996fed5258d70a9f34ecbae1d7aea74f91cfa1 (diff)
downloadslapi-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')
-rw-r--r--src/format.c250
-rw-r--r--src/format.h17
2 files changed, 218 insertions, 49 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;
}
diff --git a/src/format.h b/src/format.h
index d59a3a8..ecc762f 100644
--- a/src/format.h
+++ b/src/format.h
@@ -24,10 +24,23 @@
struct slapi_pblock;
struct slapi_entry;
struct plugin_state;
+
+struct format_inref_attr {
+ char *domain, *map, *attribute;
+};
+
+void format_free_attr_list(char **attr_list);
+char **format_dup_attr_list(char **attr_list);
+
+void format_free_inref_attrs(struct format_inref_attr **);
+struct format_inref_attr **format_dup_inref_attrs(struct format_inref_attr **);
+
void format_free_data(char *data);
-void format_free_ndn_list(char **ndn_list);
char *format_get_data(struct plugin_state *state,
struct slapi_pblock *pb, struct slapi_entry *e,
const char *domain, const char *map,
- const char *fmt, char ***visited_ndn_list);
+ const char *fmt,
+ char ***ref_attrs,
+ struct format_inref_attr ***inref_attrs);
+
#endif