* returns the mapped URL or NULL. */
| 317 | * returns the mapped URL or NULL. |
| 318 | */ |
| 319 | static const char *imap_url(request_rec *r, const char *base, const char *value) |
| 320 | { |
| 321 | /* translates a value into a URL. */ |
| 322 | apr_size_t slen, clen; |
| 323 | char *string_pos = NULL; |
| 324 | const char *string_pos_const = NULL; |
| 325 | char *directory = NULL; |
| 326 | const char *referer = NULL; |
| 327 | char *my_base; |
| 328 | |
| 329 | if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) { |
| 330 | return ap_construct_url(r->pool, r->uri, r); |
| 331 | } |
| 332 | |
| 333 | if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) { |
| 334 | return apr_pstrdup(r->pool, value); /* these are handled elsewhere, |
| 335 | so just copy them */ |
| 336 | } |
| 337 | |
| 338 | if (!strcasecmp(value, "referer")) { |
| 339 | referer = apr_table_get(r->headers_in, "Referer"); |
| 340 | if (referer && *referer) { |
| 341 | return referer; |
| 342 | } |
| 343 | else { |
| 344 | /* XXX: This used to do *value = '\0'; ... which is totally bogus |
| 345 | * because it hammers the passed in value, which can be a string |
| 346 | * constant, or part of a config, or whatever. Total garbage. |
| 347 | * This works around that without changing the rest of this |
| 348 | * code much |
| 349 | */ |
| 350 | value = ""; /* if 'referer' but no referring page, |
| 351 | null the value */ |
| 352 | } |
| 353 | } |
| 354 | |
| 355 | string_pos_const = value; |
| 356 | while (apr_isalpha(*string_pos_const)) { |
| 357 | string_pos_const++; /* go along the URL from the map |
| 358 | until a non-letter */ |
| 359 | } |
| 360 | if (*string_pos_const == ':') { |
| 361 | /* if letters and then a colon (like http:) */ |
| 362 | /* it's an absolute URL, so use it! */ |
| 363 | return apr_pstrdup(r->pool, value); |
| 364 | } |
| 365 | |
| 366 | if (!base || !*base) { |
| 367 | if (value && *value) { |
| 368 | return apr_pstrdup(r->pool, value); /* no base: use what is given */ |
| 369 | } |
| 370 | /* no base, no value: pick a simple default */ |
| 371 | return ap_construct_url(r->pool, "/", r); |
| 372 | } |
| 373 | |
| 374 | /* must be a relative URL to be combined with base */ |
| 375 | if (ap_strchr_c(base, '/') == NULL && (!strncmp(value, "../", 3) |
| 376 | || !strcmp(value, ".."))) { |
no test coverage detected