diff options
author | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-06-09 15:17:21 -0400 |
---|---|---|
committer | Nalin Dahyabhai <nalin.dahyabhai@pobox.com> | 2008-06-09 15:17:21 -0400 |
commit | ce5b6f82c64d4a6e699bf59516947390f3776e98 (patch) | |
tree | a9aefde9e5d5a6316a92284c32fbb2f35aedfaf1 /src | |
parent | a3837b5d6eea45ea50a1489485cb26f1333e3a4a (diff) | |
download | slapi-nis-ce5b6f82c64d4a6e699bf59516947390f3776e98.tar.gz slapi-nis-ce5b6f82c64d4a6e699bf59516947390f3776e98.tar.xz slapi-nis-ce5b6f82c64d4a6e699bf59516947390f3776e98.zip |
- implement substitution
Diffstat (limited to 'src')
-rw-r--r-- | src/format.c | 202 |
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; } } } |