summaryrefslogtreecommitdiffstats
path: root/src/format.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format.c')
-rw-r--r--src/format.c121
1 files changed, 99 insertions, 22 deletions
diff --git a/src/format.c b/src/format.c
index c2e78ef..b6cc37d 100644
--- a/src/format.c
+++ b/src/format.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include "defaults.h"
#include "format.h"
+#include "plugin.h"
void
format_free_data(char *data)
@@ -20,6 +21,8 @@ format_free_ndn_list(char **ndn_list)
}
}
+/* Retrieve a single value for an attribute. If there are no values, or more
+ * than one, fail. */
static char *
format_single(Slapi_PBlock *pb, Slapi_Entry *e, const char *attr,
char ***visited_ndns)
@@ -39,6 +42,7 @@ format_single(Slapi_PBlock *pb, Slapi_Entry *e, const char *attr,
return ret;
}
+/* Find the matching closing marker. */
static const char *
format_find_closer(const char *pair, const char *pattern)
{
@@ -62,7 +66,7 @@ format_find_closer(const char *pair, const char *pattern)
* 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. */
static int
-format_expand(Slapi_PBlock *pb, Slapi_Entry *e,
+format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
const char *fmt,
char *outbuf, int outbuf_len,
char ***visited_ndns,
@@ -71,24 +75,25 @@ format_expand(Slapi_PBlock *pb, Slapi_Entry *e,
int i, j;
int exp_len, level;
const char *fmtstart, *fmtend, *match, *attribute;
- char *tmp;
+ char *tmp, *fnname, *spd_id;
char exp[outbuf_len * 2];
- const char *default_value, *alternate_value;
+ const char *default_value, *alternate_value, *paramstart, *paramend;
size_t spn;
- slapi_log_error(SLAPI_LOG_PLUGIN, "nis-plugin",
+ spd_id = state->plugin_desc->spd_id;
+ slapi_log_error(SLAPI_LOG_PLUGIN, spd_id,
"expanding %s\"%s\"%s\n",
- literal ? "" : "%{", fmt, literal ? "" : "%{");
+ literal ? "" : "%{", fmt, literal ? "" : "}");
- /* First, expand any subexpressions. */
+ /* First, expand any subexpressions and call any "functions". */
level = 0;
i = 0;
j = 0;
while (fmt[i] != '\0') {
switch (fmt[i]) {
case '%':
- /* This might be a subexpression, or an escaped
- * character. */
+ /* This might be a subexpression, a "function" call, or
+ * an escaped character. */
switch (fmt[i + 1]) {
case '%':
/* It's just an escaped "%". */
@@ -102,8 +107,10 @@ format_expand(Slapi_PBlock *pb, Slapi_Entry *e,
/* Find the end of the subexpression. */
match = format_find_closer("{}", fmtstart + 1);
if (match == NULL) {
- slapi_log_error(SLAPI_LOG_PLUGIN, "nis-plugin",
- "expansion failed: no closing brace (2)\n");
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ spd_id,
+ "expansion failed: "
+ "no closing brace\n");
return -1;
} else {
/* Mark the first character after the
@@ -112,8 +119,11 @@ format_expand(Slapi_PBlock *pb, Slapi_Entry *e,
/* Make a copy of the subexpression. */
tmp = malloc(fmtend - fmtstart);
if (tmp == NULL) {
- slapi_log_error(SLAPI_LOG_PLUGIN, "nis-plugin",
- "expansion out of memory\n");
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ spd_id,
+ "expansion "
+ "failed: out "
+ "of memory\n");
return -1;
}
memcpy(tmp, fmtstart + 2,
@@ -121,7 +131,7 @@ format_expand(Slapi_PBlock *pb, Slapi_Entry *e,
tmp[fmtend - fmtstart - 3] = '\0';
/* Recursively expand the
* subexpression. */
- exp_len = format_expand(pb, e,
+ exp_len = format_expand(state, pb, e,
tmp,
exp + j,
sizeof(exp) - j,
@@ -130,9 +140,14 @@ format_expand(Slapi_PBlock *pb, Slapi_Entry *e,
free(tmp);
if ((exp_len < 0) ||
(exp_len + j >= (int) sizeof(exp))) {
- /* We'd be out of space, FAIL. */
- slapi_log_error(SLAPI_LOG_PLUGIN, "nis-plugin",
- "expansion too big\n");
+ /* We'd be out of space,
+ * FAIL. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ spd_id,
+ "expansion "
+ "failed: result"
+ " would be too "
+ "big\n");
return -1;
} else {
/* It fit, so keep going. */
@@ -142,6 +157,63 @@ format_expand(Slapi_PBlock *pb, Slapi_Entry *e,
}
continue;
break;
+ default:
+ /* Assume it's a "function" call. Pick out the
+ * name of the function. */
+ paramstart = strchr(fmt + i, '{');
+ if (paramstart == NULL) {
+ /* No start? Bad format. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ spd_id,
+ "expansion failed: "
+ "bad function "
+ "invocation\n");
+ return -1;
+ }
+ paramend = strchr(paramstart + 1, '}');
+ if (paramend == NULL) {
+ /* No matching end? Bad format. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ spd_id,
+ "expansion failed: "
+ "bad function "
+ "invocation\n");
+ return -1;
+ }
+ fnname = malloc(paramstart - (fmt + i));
+ if (fnname == NULL) {
+ /* Out of memory, FAIL. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ spd_id,
+ "expansion failed: "
+ "out of memory\n");
+ return -1;
+ }
+ memcpy(fnname, fmt + i + 1,
+ paramstart - (fmt + i + 1));
+ fnname[paramstart - (fmt + i + 1)] = '\0';
+ /* Isolate the parameter string. */
+ tmp = malloc(paramend - paramstart);
+ if (tmp == NULL) {
+ /* Out of memory, FAIL. */
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ spd_id,
+ "expansion failed: "
+ "out of memory\n");
+ free(fnname);
+ return -1;
+ }
+ memcpy(tmp, paramstart + 1,
+ paramend - (paramstart + 1));
+ tmp[paramend - paramstart] = '\0';
+ slapi_log_error(SLAPI_LOG_PLUGIN, spd_id,
+ "calling \"%s\"(\"%s\")\n",
+ fnname, tmp);
+ free(fnname);
+ free(tmp);
+ i = (paramend - fmt) + 1;
+ continue;
+ break;
}
break;
default:
@@ -261,15 +333,16 @@ format_expand(Slapi_PBlock *pb, Slapi_Entry *e,
}
static char *
-format_format(Slapi_PBlock *pb, Slapi_Entry *e, const char *fmt,
- char ***visited_ndns)
+format_format(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *fmt, char ***visited_ndns)
{
char buf[YPMAXRECORD], *tmp;
const char *match, *fmtstart, *fmtend;
unsigned int i, j;
int exp_len;
- i = format_expand(pb, e, fmt, buf, sizeof(buf), visited_ndns, TRUE);
+ i = format_expand(state, pb, e, fmt, buf, sizeof(buf),
+ visited_ndns, TRUE);
if (i < sizeof(buf)) {
buf[i] = '\0';
return strdup(buf);
@@ -279,12 +352,13 @@ format_format(Slapi_PBlock *pb, Slapi_Entry *e, const char *fmt,
}
char *
-format_get_data(Slapi_PBlock *pb, Slapi_Entry *e, const char *fmt,
- char ***visited_ndns)
+format_get_data(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
+ const char *fmt, char ***visited_ndns)
{
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 {
@@ -292,6 +366,7 @@ format_get_data(Slapi_PBlock *pb, Slapi_Entry *e, const char *fmt,
local_ndn_list = NULL;
}
+ /* Supply a PBlock if the caller didn't. */
if (pb == NULL) {
local_pb = slapi_pblock_new();
pb = local_pb;
@@ -299,11 +374,13 @@ format_get_data(Slapi_PBlock *pb, Slapi_Entry *e, const char *fmt,
local_pb = NULL;
}
- ret = format_format(pb, e, fmt, ndn_list);
+ ret = format_format(state, pb, e, fmt, ndn_list);
+ /* 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);
}