diff options
Diffstat (limited to 'src/libtipidee')
-rw-r--r-- | src/libtipidee/tipidee_conf_get_redirection.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/src/libtipidee/tipidee_conf_get_redirection.c b/src/libtipidee/tipidee_conf_get_redirection.c index 62ada34..9d40de2 100644 --- a/src/libtipidee/tipidee_conf_get_redirection.c +++ b/src/libtipidee/tipidee_conf_get_redirection.c @@ -3,33 +3,52 @@ #include <errno.h> #include <string.h> +#include <skalibs/lolstdio.h> + #include <tipidee/conf.h> #include <skalibs/posixishard.h> -int tipidee_conf_get_redirection (tipidee_conf const *conf, char const *res, size_t docrootlen, tipidee_redirection *r) +static int get_redir (tipidee_conf const *conf, size_t minl, char *key, size_t l, char const *path, tipidee_redirection *r) { - size_t reslen = strlen(res) ; - size_t l = 2 + reslen ; - char const *v = 0 ; - char key[3 + reslen] ; - key[0] = 'R' ; key[1] = ':' ; - memcpy(key + 2, res, reslen) ; - key[2 + reslen] = '/' ; - errno = ENOENT ; - while (!v) + char const *v ; + key[0] = 'R' ; + key[l] = '/' ; + for (;;) { - if (errno != ENOENT) return -1 ; - while (l > 2 + docrootlen && key[l] != '/') l-- ; - if (l <= 2 + docrootlen) break ; + while (l > minl && key[l] != '/') l-- ; + if (l <= minl) return 0 ; key[l--] = 0 ; - key[0] = 'r' ; v = tipidee_conf_get_string(conf, key) ; + if (v) break ; + if (errno != ENOENT) return -1 ; + key[0] = 'r' ; } - if (!v) return 0 ; if (v[0] < '@' || v[0] > 'C') return (errno = EPROTO, -1) ; r->type = v[0] & ~'@' ; r->location = v+1 ; - r->sub = res + l - 2 ; + r->sub = path + (l - minl + 1) ; + LOLDEBUG("get_redir: found redirection of type %c to %s with sub %s", v[0], r->location, r->sub) ; return 1 ; } + +int tipidee_conf_get_redirection (tipidee_conf const *conf, char const *docroot, size_t docrootlen, char const *path, tipidee_redirection *r) +{ + size_t pathlen = strlen(path) ; + char key[docrootlen + pathlen + 3] ; + key[1] = ':' ; + memcpy(key + 2, docroot, docrootlen) ; + memcpy(key + 2 + docrootlen, path, pathlen + 1) ; + { + int e = get_redir(conf, 2 + docrootlen, key, 2 + docrootlen + pathlen, path, r) ; + if (e) return e ; + } + { + char *p = memchr(docroot, ':', docrootlen) ; + if (!p) return 0 ; + docrootlen = p - docroot ; + } + memcpy(key + 2, docroot, docrootlen) ; + memcpy(key + 2 + docrootlen, path, pathlen + 1) ; + return get_redir(conf, 2 + docrootlen, key, 2 + docrootlen + pathlen, path, r) ; +} |