summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@redhat.com>2012-01-24 12:29:09 -0500
committerNalin Dahyabhai <nalin@redhat.com>2012-01-24 12:29:09 -0500
commit516eb50a45ac8debd53e14fb28dc38ecef1be2ee (patch)
tree1d58c5ec52bec8e9a0aec8ef7dba716b9d974858
parentc83ccc440299a2d063fc7f5289d1ed459d26231d (diff)
downloadslapi-nis-516eb50a45ac8debd53e14fb28dc38ecef1be2ee.tar.gz
slapi-nis-516eb50a45ac8debd53e14fb28dc38ecef1be2ee.tar.xz
slapi-nis-516eb50a45ac8debd53e14fb28dc38ecef1be2ee.zip
- add multiple-result capable versions of match/regmatch/regsub
-rw-r--r--doc/format-specifiers.txt35
-rw-r--r--src/format.c132
-rwxr-xr-xtests/test37-nis-multi/before.sh8
-rw-r--r--tests/test37-nis-multi/before.txt49
-rw-r--r--tests/test37-nis-multi/description.txt1
-rw-r--r--tests/test37-nis-multi/dse.ldif20
-rw-r--r--tests/test37-nis-multi/userRoot.ldif18
7 files changed, 260 insertions, 3 deletions
diff --git a/doc/format-specifiers.txt b/doc/format-specifiers.txt
index b9a0490..91c7b9c 100644
--- a/doc/format-specifiers.txt
+++ b/doc/format-specifiers.txt
@@ -92,6 +92,13 @@ And here's how it evaluates out:
%match("%{member}","e*","jim") -> jim
%match("%{member}","*","%{cn}") -> group
+=== mmatch ===
+
+ mmatch(''EXPRESSION'',''PATTERN''])
+
+Similar to match, except that any number of matching values may be found
+and returned.
+
=== regmatch ===
regmatch(''EXPRESSION'',''PATTERN''[,''DEFAULT''])
@@ -123,6 +130,20 @@ And here's how it evaluates out:
Exactly the same as regmatch, except that pattern matching is performed in a
case-insensitive manner.
+=== mregmatch ===
+
+ mregmatch(''EXPRESSION'',''PATTERN''])
+
+Similar to regmatch, except that any number of matching values may be found
+and returned.
+
+=== mregmatchi ===
+
+ mregmatchi(''EXPRESSION'',''PATTERN''])
+
+Exactly the same as mregmatch, except that pattern matching is performed in
+a case-insensitive manner.
+
=== regsub ===
regsub(''EXPRESSION'',''PATTERN'',''TEMPLATE''[,''DEFAULT''])
@@ -160,6 +181,20 @@ And here's how it evaluates out:
Exactly the same as regsub, except that pattern matching is performed in a
case-insensitive manner.
+=== mregsub ===
+
+ mregsub(''EXPRESSION'',''PATTERN'',''TEMPLATE'')
+
+Similar to regsub, except that any number of matching values may be found,
+processed, and returned.
+
+=== regsubi ===
+
+ mregsubi(''EXPRESSION'',''PATTERN'',''TEMPLATE'')
+
+Exactly the same as regsubi, except that pattern matching is performed in a
+case-insensitive manner.
+
=== deref ===
deref(''THISATTRIBUTE'',''THATATTRIBUTE'')
diff --git a/src/format.c b/src/format.c
index 60c3bf6..70d0f19 100644
--- a/src/format.c
+++ b/src/format.c
@@ -2066,7 +2066,7 @@ format_merge(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
/* Look up the entry's values for the attribute named by the first argument,
* and use the callback to check if they match the second argument. If we find
* exactly one match, store it in the output buffer, otherwise store the text
- * of the default_arg'th argument if given, or return an error if no
+ * of the default_arg'th argument if given, or return everything if no
* default_arg'th argument was given. */
static int
format_match_generic(struct plugin_state *state,
@@ -2156,7 +2156,8 @@ format_match_generic(struct plugin_state *state,
break;
case 0:
default:
- /* Either no matches, or too many matches to store. */
+ /* Either no matches, or multiple matches, which may be too
+ * many matches to store. */
default_value = NULL;
if ((default_arg >= 0) && (argv[default_arg] != NULL)) {
default_value = format_get_data(state, pb, e,
@@ -2170,7 +2171,11 @@ format_match_generic(struct plugin_state *state,
inref_attr_list,
&default_length);
}
- if (default_value != NULL) {
+ if (default_arg < 0) {
+ /* Return all of the matches as a list. */
+ format_add_choice_str(outbuf_choices, outbuf, matches);
+ len = 0;
+ } else if ((default_arg >= 0) && (default_value != NULL)) {
if (count == 0) {
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id,
"%s: no matching value "
@@ -2282,6 +2287,25 @@ format_match(struct plugin_state *state,
ref_attr_list, inref_attr_list,
"format_match", format_match_cb);
}
+static int
+format_mmatch(struct plugin_state *state,
+ Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *group, const char *set,
+ const char *args, const char *disallowed,
+ char *outbuf, int outbuf_len,
+ struct format_choice **outbuf_choices,
+ char ***rel_attrs, char ***ref_attrs,
+ struct format_inref_attr ***inref_attrs,
+ struct format_ref_attr_list ***ref_attr_list,
+ struct format_ref_attr_list ***inref_attr_list)
+{
+ return format_match_generic(state, pb, e, group, set, args, 2, -1,
+ disallowed,
+ outbuf, outbuf_len, outbuf_choices,
+ rel_attrs, ref_attrs, inref_attrs,
+ ref_attr_list, inref_attr_list,
+ "format_mmatch", format_match_cb);
+}
/* Check for a regex match. */
static char *
@@ -2323,6 +2347,25 @@ format_regmatch(struct plugin_state *state,
ref_attr_list, inref_attr_list,
"format_regmatch", format_regmatch_cb);
}
+static int
+format_mregmatch(struct plugin_state *state,
+ Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *group, const char *set,
+ const char *args, const char *disallowed,
+ char *outbuf, int outbuf_len,
+ struct format_choice **outbuf_choices,
+ char ***rel_attrs, char ***ref_attrs,
+ struct format_inref_attr ***inref_attrs,
+ struct format_ref_attr_list ***ref_attr_list,
+ struct format_ref_attr_list ***inref_attr_list)
+{
+ return format_match_generic(state, pb, e, group, set, args, 2, -1,
+ disallowed,
+ outbuf, outbuf_len, outbuf_choices,
+ rel_attrs, ref_attrs, inref_attrs,
+ ref_attr_list, inref_attr_list,
+ "format_mregmatch", format_regmatch_cb);
+}
static char *
format_regmatchi_cb(const char *pattern, const char *value, char **argv)
{
@@ -2347,6 +2390,25 @@ format_regmatchi(struct plugin_state *state,
ref_attr_list, inref_attr_list,
"format_regmatchi", format_regmatchi_cb);
}
+static int
+format_mregmatchi(struct plugin_state *state,
+ Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *group, const char *set,
+ const char *args, const char *disallowed,
+ char *outbuf, int outbuf_len,
+ struct format_choice **outbuf_choices,
+ char ***rel_attrs, char ***ref_attrs,
+ struct format_inref_attr ***inref_attrs,
+ struct format_ref_attr_list ***ref_attr_list,
+ struct format_ref_attr_list ***inref_attr_list)
+{
+ return format_match_generic(state, pb, e, group, set, args, 2, -1,
+ disallowed,
+ outbuf, outbuf_len, outbuf_choices,
+ rel_attrs, ref_attrs, inref_attrs,
+ ref_attr_list, inref_attr_list,
+ "format_mregmatchi", format_regmatchi_cb);
+}
/* Check for a regex match and build a custom result from the matching value. */
static char *
@@ -2481,6 +2543,25 @@ format_regsub(struct plugin_state *state,
ref_attr_list, inref_attr_list,
"format_regsub", format_regsub_cb);
}
+static int
+format_mregsub(struct plugin_state *state,
+ Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *group, const char *set,
+ const char *args, const char *disallowed,
+ char *outbuf, int outbuf_len,
+ struct format_choice **outbuf_choices,
+ char ***rel_attrs, char ***ref_attrs,
+ struct format_inref_attr ***inref_attrs,
+ struct format_ref_attr_list ***ref_attr_list,
+ struct format_ref_attr_list ***inref_attr_list)
+{
+ return format_match_generic(state, pb, e, group, set, args, 3, -1,
+ disallowed,
+ outbuf, outbuf_len, outbuf_choices,
+ rel_attrs, ref_attrs, inref_attrs,
+ ref_attr_list, inref_attr_list,
+ "format_mregsub", format_regsub_cb);
+}
static char *
format_regsubi_cb(const char *pattern, const char *value, char **argv)
{
@@ -2505,6 +2586,25 @@ format_regsubi(struct plugin_state *state,
ref_attr_list, inref_attr_list,
"format_regsubi", format_regsubi_cb);
}
+static int
+format_mregsubi(struct plugin_state *state,
+ Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *group, const char *set,
+ const char *args, const char *disallowed,
+ char *outbuf, int outbuf_len,
+ struct format_choice **outbuf_choices,
+ char ***rel_attrs, char ***ref_attrs,
+ struct format_inref_attr ***inref_attrs,
+ struct format_ref_attr_list ***ref_attr_list,
+ struct format_ref_attr_list ***inref_attr_list)
+{
+ return format_match_generic(state, pb, e, group, set, args, 3, -1,
+ disallowed,
+ outbuf, outbuf_len, outbuf_choices,
+ rel_attrs, ref_attrs, inref_attrs,
+ ref_attr_list, inref_attr_list,
+ "format_mregsubi", format_regsubi_cb);
+}
/* If the attribute given by the first argument is equal to the value given in
* the second, return the third, else return the fourth. We used to allow an
@@ -2633,6 +2733,13 @@ format_collect(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
format_free_parsed_args(argv);
return -EINVAL;
}
+ if (outbuf_choices == NULL) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "collect: returns a list, but a list "
+ "would not be appropriate\n");
+ format_free_parsed_args(argv);
+ return -EINVAL;
+ }
/* Walk the list of the arguments. */
choices = NULL;
@@ -2733,6 +2840,13 @@ format_link(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
format_free_parsed_args(argv);
return -EINVAL;
}
+ if (outbuf_choices == NULL) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "link: returns a list, but a list "
+ "would not be appropriate\n");
+ format_free_parsed_args(argv);
+ return -EINVAL;
+ }
/* Allocate space to store the information. */
values = malloc(sizeof(char **) * ((argc + 1) / 3));
@@ -2926,6 +3040,13 @@ format_unique(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
value_format = argv[0];
default_value = argv[1];
}
+ if (outbuf_choices == NULL) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "unique: returns a list, but a list "
+ "would not be appropriate\n");
+ format_free_parsed_args(argv);
+ return -EINVAL;
+ }
ret = -ENOENT;
values = format_get_data_set(state, pb, e, group, set,
value_format, disallowed,
@@ -3075,6 +3196,11 @@ format_lookup_fn(const char *fnname)
{"regmatchi", format_regmatchi},
{"regsub", format_regsub},
{"regsubi", format_regsubi},
+ {"mmatch", format_mmatch},
+ {"mregmatch", format_mregmatch},
+ {"mregmatchi", format_mregmatchi},
+ {"mregsub", format_mregsub},
+ {"mregsubi", format_mregsubi},
{"ifeq", format_ifeq},
{"collect", format_collect},
{"link", format_link},
diff --git a/tests/test37-nis-multi/before.sh b/tests/test37-nis-multi/before.sh
new file mode 100755
index 0000000..a49cf3e
--- /dev/null
+++ b/tests/test37-nis-multi/before.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+echo map list:
+$YP maplist example.com
+$YP -c maplist example.com
+for map in name2mac mac2name ; do
+ echo all contents of example.com:"$map":
+ $YP -c all example.com $map | LANG=C sort
+done
diff --git a/tests/test37-nis-multi/before.txt b/tests/test37-nis-multi/before.txt
new file mode 100644
index 0000000..32c84a2
--- /dev/null
+++ b/tests/test37-nis-multi/before.txt
@@ -0,0 +1,49 @@
+map list:
+mac2name
+name2mac
+mac2name
+name2mac
+all contents of example.com:name2mac:
+testbox1 01:02:03:04:05:06 testbox1
+testbox1 01:02:03:04:05:07 testbox1
+testbox1 01:02:03:04:05:08 testbox1
+testbox1 01:02:03:04:05:09 testbox1
+testbox1 01:02:03:04:05:0a testbox1
+testbox1 01:02:03:04:05:0b testbox1
+testbox1 01:02:03:04:05:0c testbox1
+testbox2 01:02:03:04:05:06 testbox2
+testbox2 01:02:03:04:05:07 testbox2
+testbox2 01:02:03:04:05:08 testbox2
+testbox2 01:02:03:04:05:09 testbox2
+testbox2 01:02:03:04:05:0a testbox2
+testbox2 01:02:03:04:05:0b testbox2
+testbox2 01:02:03:04:05:0c testbox2
+testbox3 01:02:03:04:05:06 testbox3
+testbox3 01:02:03:04:05:07 testbox3
+testbox3 01:02:03:04:05:08 testbox3
+testbox3 01:02:03:04:05:09 testbox3
+testbox3 01:02:03:04:05:0a testbox3
+testbox3 01:02:03:04:05:0b testbox3
+testbox3 01:02:03:04:05:0c testbox3
+all contents of example.com:mac2name:
+01:02:03:04:05:06 01:02:03:04:05:06 testbox1
+01:02:03:04:05:06 01:02:03:04:05:06 testbox2
+01:02:03:04:05:06 01:02:03:04:05:06 testbox3
+01:02:03:04:05:07 01:02:03:04:05:07 testbox1
+01:02:03:04:05:07 01:02:03:04:05:07 testbox2
+01:02:03:04:05:07 01:02:03:04:05:07 testbox3
+01:02:03:04:05:08 01:02:03:04:05:08 testbox1
+01:02:03:04:05:08 01:02:03:04:05:08 testbox2
+01:02:03:04:05:08 01:02:03:04:05:08 testbox3
+01:02:03:04:05:09 01:02:03:04:05:09 testbox1
+01:02:03:04:05:09 01:02:03:04:05:09 testbox2
+01:02:03:04:05:09 01:02:03:04:05:09 testbox3
+01:02:03:04:05:0a 01:02:03:04:05:0a testbox1
+01:02:03:04:05:0a 01:02:03:04:05:0a testbox2
+01:02:03:04:05:0a 01:02:03:04:05:0a testbox3
+01:02:03:04:05:0b 01:02:03:04:05:0b testbox1
+01:02:03:04:05:0b 01:02:03:04:05:0b testbox2
+01:02:03:04:05:0b 01:02:03:04:05:0b testbox3
+01:02:03:04:05:0c 01:02:03:04:05:0c testbox1
+01:02:03:04:05:0c 01:02:03:04:05:0c testbox2
+01:02:03:04:05:0c 01:02:03:04:05:0c testbox3
diff --git a/tests/test37-nis-multi/description.txt b/tests/test37-nis-multi/description.txt
new file mode 100644
index 0000000..2f296c8
--- /dev/null
+++ b/tests/test37-nis-multi/description.txt
@@ -0,0 +1 @@
+multiple regsub (mregsub)
diff --git a/tests/test37-nis-multi/dse.ldif b/tests/test37-nis-multi/dse.ldif
new file mode 100644
index 0000000..6c32914
--- /dev/null
+++ b/tests/test37-nis-multi/dse.ldif
@@ -0,0 +1,20 @@
+dn: nis-domain=example.com+nis-map=name2mac,cn=NIS Server,cn=plugins,cn=config
+objectClass: top
+objectClass: extensibleObject
+nis-domain: example.com
+nis-map: name2mac
+nis-base: cn=computers, cn=Accounts, dc=example, dc=com
+nis-filter: objectclass=ieee802device
+nis-keys-format: %mregsub("%{macaddress} %{cn}","(..:..:..:..:..:..) (.*)","%2")
+nis-values-format: %{macaddress} %{cn}
+
+dn: nis-domain=example.com+nis-map=mac2name,cn=NIS Server,cn=plugins,cn=config
+objectClass: top
+objectClass: extensibleObject
+nis-domain: example.com
+nis-map: mac2name
+nis-base: cn=computers, cn=Accounts, dc=example, dc=com
+nis-filter: objectclass=ieee802device
+nis-keys-format: %mregsub("%{macaddress} %{cn}","(..:..:..:..:..:..) (.*)","%1")
+nis-values-format: %{macaddress} %{cn}
+
diff --git a/tests/test37-nis-multi/userRoot.ldif b/tests/test37-nis-multi/userRoot.ldif
new file mode 100644
index 0000000..98727a6
--- /dev/null
+++ b/tests/test37-nis-multi/userRoot.ldif
@@ -0,0 +1,18 @@
+dn: cn=computers, cn=Accounts, dc=example, dc=com
+objectClass: nsContainer
+cn: computers
+
+dn: cn=testbox1, cn=computers, cn=Accounts, dc=example, dc=com
+objectClass: ieee802device
+objectClass: device
+cn: testbox1
+cn: testbox2
+cn: testbox3
+macAddress: 01:02:03:04:05:06
+macAddress: 01:02:03:04:05:07
+macAddress: 01:02:03:04:05:08
+macAddress: 01:02:03:04:05:09
+macAddress: 01:02:03:04:05:0a
+macAddress: 01:02:03:04:05:0b
+macAddress: 01:02:03:04:05:0c
+