summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-09 15:17:21 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-09 15:17:21 -0400
commitce5b6f82c64d4a6e699bf59516947390f3776e98 (patch)
treea9aefde9e5d5a6316a92284c32fbb2f35aedfaf1 /src
parenta3837b5d6eea45ea50a1489485cb26f1333e3a4a (diff)
downloadslapi-nis-ce5b6f82c64d4a6e699bf59516947390f3776e98.tar.gz
slapi-nis-ce5b6f82c64d4a6e699bf59516947390f3776e98.tar.xz
slapi-nis-ce5b6f82c64d4a6e699bf59516947390f3776e98.zip
- implement substitution
Diffstat (limited to 'src')
-rw-r--r--src/format.c202
1 files changed, 172 insertions, 30 deletions
diff --git a/src/format.c b/src/format.c
index ff8be5f..6ee102e 100644
--- a/src/format.c
+++ b/src/format.c
@@ -1250,62 +1250,166 @@ xstrndupp(const char *start, const char *end)
/* Trim off prefixes or suffixes which match the given patterns, free the
* original, and return the result. */
static char *
-format_trim_value(char *tmp,
+format_trim_value(struct plugin_state *state, char *input,
const char *shortstart, const char *longstart,
- const char *shortend, const char *longend)
+ const char *shortend, const char *longend,
+ const char *replace, const char *replaceall,
+ const char *replaceval, const char *forbidden)
{
char *ret;
- int i, len;
- ret = strdup(tmp);
- len = strlen(tmp);
+ int i, j, k, len;
+ ret = strdup(input);
+ len = strlen(input);
if (ret != NULL) {
+ if (forbidden) {
+ /* Any forbidden character rejects this value. */
+ if (strcspn(ret, forbidden) != strlen(ret)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "trim: value \"%s\" contains "
+ "forbidden character '%c'\n",
+ ret,
+ ret + strcspn(ret, forbidden));
+ free(ret);
+ free(input);
+ return NULL;
+ }
+ }
if (shortstart) {
+ /* The shortest initial substring which matches gets
+ * skipped. */
for (i = 0; i < len; i++) {
- memcpy(ret, tmp, i);
+ memcpy(ret, input, i);
ret[i] = '\0';
if (fnmatch(shortstart, ret, 0) == 0) {
- strcpy(ret, tmp + i);
- free(tmp);
+ strcpy(ret, input + i);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "trim: ->%s<- => "
+ "->%s<-\n",
+ input, ret);
+ free(input);
return ret;
}
}
}
if (shortend) {
+ /* The shortest ending substring which matches gets
+ * snipped. */
for (i = 1; i <= len; i++) {
- strcpy(ret, tmp + len - i);
+ strcpy(ret, input + len - i);
if (fnmatch(shortend, ret, 0) == 0) {
- strcpy(ret, tmp);
+ strcpy(ret, input);
ret[len - i] = '\0';
- free(tmp);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "trim: ->%s<- => "
+ "->%s<-\n",
+ input, ret);
+ free(input);
return ret;
}
}
}
if (longstart) {
+ /* The longest initial substring which matches gets
+ * skipped. */
for (i = 1; i <= len; i++) {
- memcpy(ret, tmp, (len - i));
+ memcpy(ret, input, (len - i));
ret[len - i] = '\0';
if (fnmatch(longstart, ret, 0) == 0) {
- strcpy(ret, tmp + (len - i));
- free(tmp);
+ strcpy(ret, input + (len - i));
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "trim: ->%s<- => "
+ "->%s<-\n",
+ input, ret);
+ free(input);
return ret;
}
}
}
if (longend) {
+ /* The longest ending substring which matches gets
+ * snipped. */
for (i = 0; i < len; i++) {
- strcpy(ret, tmp + i);
+ strcpy(ret, input + i);
if (fnmatch(longend, ret, 0) == 0) {
- strcpy(ret, tmp);
+ strcpy(ret, input);
ret[i] = '\0';
- free(tmp);
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "trim: ->%s<- => "
+ "->%s<-\n",
+ input, ret);
+ free(input);
return ret;
}
}
}
+ if (replaceval == NULL) {
+ replaceval = "";
+ }
+ if (replace) {
+ /* Every occurrence of the substring which matches gets
+ * replaced, maybe. */
+ free(ret);
+ ret = malloc(len + strlen(replaceval) + 1);
+ if (ret == NULL) {
+ return input;
+ }
+ for (i = 0, j = 0;
+ (i < len) && (replaceval != NULL);
+ i++, j++) {
+ strcpy(ret + j, input + i);
+ for (k = strlen(ret + j); k > 0; k--) {
+ ret[j + k] = '\0';
+ if (fnmatch(ret + j, replaceall, 0)) {
+ strcpy(ret + j, replaceval);
+ j += (strlen(replaceval) - 1);
+ i += (k - 1);
+ replaceval = NULL;
+ break;
+ }
+ }
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "trim: ->%s<- => ->%s<-\n", input, ret);
+ free(input);
+ return ret;
+ }
+ if (replaceall) {
+ /* Every occurrence of the substring which matches gets
+ * replaced with the replaceval. */
+ free(ret);
+ ret = malloc(len * strlen(replaceval) + 1);
+ if (ret == NULL) {
+ return input;
+ }
+ for (i = 0, j = 0;
+ (i < len) && (replaceval != NULL);
+ i++, j++) {
+ strcpy(ret + j, input + i);
+ for (k = strlen(ret + j); k > 0; k--) {
+ ret[j + k] = '\0';
+ if (fnmatch(ret + j, replaceall, 0)) {
+ strcpy(ret + j, replaceval);
+ j += (strlen(replaceval) - 1);
+ i += (k - 1);
+ break;
+ }
+ }
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "trim: ->%s<- => ->%s<-\n", input, ret);
+ free(input);
+ return ret;
+ }
free(ret);
}
- return tmp;
+ return input;
}
/* Recursively expand the expression into the output buffer. adding any entries
@@ -1321,11 +1425,12 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
{
int i, j;
int exp_used, exp_size, level;
- const char *fmtstart, *fmtend, *match, *attribute, *p;
- char *tmp, *fnname, *spd_id;
+ const char *fmtstart, *fmtend, *match, *attribute;
+ char *tmp, *fnname, *spd_id, *p;
char *expr;
const char *default_value, *alternate_value, *paramstart, *paramend;
- const char *shortstart, *longstart, *shortend, *longend;
+ char *shortstart, *longstart, *shortend, *longend;
+ char *replace, *replaceall, *replaceval, *forbidden;
size_t spn;
int (*formatfn)(struct plugin_state *state,
Slapi_PBlock *pb, Slapi_Entry *e,
@@ -1559,9 +1664,13 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
longstart = NULL;
shortend = NULL;
longend = NULL;
+ replace = NULL;
+ replaceall = NULL;
+ replaceval = NULL;
+ forbidden = NULL;
/* It's a simple expression, so evaluate it. Check for
* substitutions. */
- spn = strcspn(expr, "#%");
+ spn = strcspn(expr, "#%/!");
if (spn != strlen(expr)) {
p = expr + spn;
if (strncmp(p, "##", 2)) {
@@ -1570,13 +1679,38 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
else if (strncmp(p, "%%", 2)) {
longend = p + 2;
}
+ else if (strncmp(p, "//", 2)) {
+ replaceall = p + 2;
+ }
else if (strncmp(p, "#", 1)) {
shortstart = p + 1;
}
else if (strncmp(p, "%", 1)) {
shortend = p + 1;
}
+ else if (strncmp(p, "/", 1)) {
+ replace = p + 1;
+ }
+ else if (strncmp(p, "!", 1)) {
+ forbidden = p + 1;
+ }
expr[spn] = '\0';
+ if ((replace != NULL) || (replaceall != NULL)) {
+ replaceval = NULL;
+ if (replace != NULL) {
+ spn = strcspn(replace, "/");
+ replaceval = replace + spn;
+ }
+ if (replaceall != NULL) {
+ spn = strcspn(replaceall, "/");
+ replaceval = replaceall + spn;
+ }
+ if ((replaceval != NULL) &&
+ (*replaceval != '\0')) {
+ *replaceval = '\0';
+ replaceval++;
+ }
+ }
attribute = expr;
alternate_value = NULL;
default_value = NULL;
@@ -1642,17 +1776,25 @@ format_expand(struct plugin_state *state, Slapi_PBlock *pb, Slapi_Entry *e,
return i;
} else {
/* Munge up the looked-up value. */
- tmp = format_trim_value(tmp,
+ tmp = format_trim_value(state, tmp,
shortstart, longstart,
- shortend, longend);
+ shortend, longend,
+ replace, replaceall,
+ replaceval, forbidden);
/* Supply the looked-up value. */
- i = strlen(tmp);
- if (i <= outbuf_len) {
- memcpy(outbuf, tmp, i);
+ if (tmp != NULL) {
+ i = strlen(tmp);
+ if (i <= outbuf_len) {
+ memcpy(outbuf, tmp, i);
+ }
+ free(tmp);
+ free(expr);
+ return i;
+ } else {
+ /* No useful value: FAIL. */
+ free(expr);
+ return -ENOENT;
}
- free(tmp);
- free(expr);
- return i;
}
}
}