mod_imagemap.c revision fda1a61aacb6950953b7393b845b0639d8e87359
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd/* Licensed to the Apache Software Foundation (ASF) under one or more
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * contributor license agreements. See the NOTICE file distributed with
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * this work for additional information regarding copyright ownership.
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * The ASF licenses this file to You under the Apache License, Version 2.0
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * (the "License"); you may not use this file except in compliance with
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * the License. You may obtain a copy of the License at
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * http://www.apache.org/licenses/LICENSE-2.0
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *
96ad5d81ee4a2cc66a4ae19893efc8aa6d06fae7jailletc * Unless required by applicable law or agreed to in writing, software
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * distributed under the License is distributed on an "AS IS" BASIS,
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * See the License for the specific language governing permissions and
2e545ce2450a9953665f701bb05350f0d3f26275nd * limitations under the License.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd/*
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * This imagemap module started as a port of the original imagemap.c
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * written by Rob McCool (11/13/93 robm@ncsa.uiuc.edu).
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * This version includes the mapping algorithms found in version 1.3
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * of imagemap.c.
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * Contributors to this code include:
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * Kevin Hughes, kevinh@pulua.hcc.hawaii.edu
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * Eric Haines, erich@eye.com
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar *
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh * Randy Terbush, randy@zyzzyva.com
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * port to Apache module format, "base_uri" and support for relative URLs
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * James H. Cloos, Jr., cloos@jhcloos.com
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh * Added point datatype, using code in NCSA's version 1.8 imagemap.c
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * program, as distributed with version 1.4.1 of their server.
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * The point code is originally added by Craig Milo Rogers, Rogers@ISI.Edu
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * Nathan Kurz, nate@tripod.com
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * Rewrite/reorganization. New handling of default, base and relative URLs.
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh * New Configuration directives:
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * ImapMenu {none, formatted, semiformatted, unformatted}
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * ImapDefault {error, nocontent, referer, menu, URL}
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * ImapBase {map, referer, URL}
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * Support for creating non-graphical menu added. (backwards compatible):
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * Old: directive URL [x,y ...]
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * New: directive URL "Menu text" [x,y ...]
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * or: directive URL x,y ... "Menu text"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * Map format and menu concept courtesy Joshua Bell, jsbell@acs.ucalgary.ca.
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar *
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh * Mark Cox, mark@ukweb.com, Allow relative URLs even when no base specified
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar */
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh#include "apr.h"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#include "apr_strings.h"
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd#include "apr_lib.h"
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd#define APR_WANT_STDIO /* for sscanf() */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#define APR_WANT_STRFUNC
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#include "apr_want.h"
064f6f723bc9a4a1479444b6dc720c8307635c68humbedooh
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd#include "ap_config.h"
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd#include "httpd.h"
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen#include "http_config.h"
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd#include "http_request.h"
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd#include "http_core.h"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#include "http_protocol.h"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#include "http_main.h"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#include "http_log.h"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#include "util_script.h"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#include "mod_core.h"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd#define IMAP_MAGIC_TYPE "application/x-httpd-imap"
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#define MAXVERTS 100
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#define X 0
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar#define Y 1
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd#define IMAP_MENU_DEFAULT "formatted"
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd#define IMAP_DEFAULT_DEFAULT "nocontent"
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd#define IMAP_BASE_DEFAULT "map"
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coarmodule AP_MODULE_DECLARE_DATA imagemap_module;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coartypedef struct {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar char *imap_menu;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen char *imap_default;
4aa603e6448b99f9371397d439795c91a93637eand char *imap_base;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen} imap_conf_rec;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9ndstatic void *create_imap_dir_config(apr_pool_t *p, char *dummy)
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd{
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd imap_conf_rec *icr =
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen (imap_conf_rec *) apr_palloc(p, sizeof(imap_conf_rec));
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar icr->imap_menu = NULL;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen icr->imap_default = NULL;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen icr->imap_base = NULL;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen return icr;
4aa603e6448b99f9371397d439795c91a93637eand}
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowenstatic void *merge_imap_dir_configs(apr_pool_t *p, void *basev, void *addv)
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen{
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen imap_conf_rec *new = (imap_conf_rec *) apr_pcalloc(p, sizeof(imap_conf_rec));
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen imap_conf_rec *base = (imap_conf_rec *) basev;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen imap_conf_rec *add = (imap_conf_rec *) addv;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen new->imap_menu = add->imap_menu ? add->imap_menu : base->imap_menu;
4aa603e6448b99f9371397d439795c91a93637eand new->imap_default = add->imap_default ? add->imap_default
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen : base->imap_default;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd new->imap_base = add->imap_base ? add->imap_base : base->imap_base;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen return new;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar}
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
165cd068ea6f48c8992c82f5fe2fc1ff0a7d4c98humbedooh
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowenstatic const command_rec imap_cmds[] =
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd{
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh AP_INIT_TAKE1("ImapMenu", ap_set_string_slot,
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd (void *)APR_OFFSETOF(imap_conf_rec, imap_menu), OR_INDEXES,
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd "the type of menu generated: none, formatted, semiformatted, "
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen "unformatted"),
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar AP_INIT_TAKE1("ImapDefault", ap_set_string_slot,
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen (void *)APR_OFFSETOF(imap_conf_rec, imap_default), OR_INDEXES,
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen "the action taken if no match: error, nocontent, referer, "
4a56677aad9b66a36f3dc9fddbca8dc1230ad471rbowen "menu, URL"),
dc1328abb455410dfc5e4828f5e0e60dd859db49humbedooh AP_INIT_TAKE1("ImapBase", ap_set_string_slot,
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen (void *)APR_OFFSETOF(imap_conf_rec, imap_base), OR_INDEXES,
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar "the base for all URL's: map, referer, URL (or start of)"),
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd {NULL}
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd};
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coarstatic int pointinrect(const double point[2], double coords[MAXVERTS][2])
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar double max[2], min[2];
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (coords[0][X] > coords[1][X]) {
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh max[0] = coords[0][X];
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd min[0] = coords[1][X];
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd else {
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh max[0] = coords[1][X];
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd min[0] = coords[0][X];
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (coords[0][Y] > coords[1][Y]) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar max[1] = coords[0][Y];
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar min[1] = coords[1][Y];
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar else {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar max[1] = coords[1][Y];
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar min[1] = coords[0][Y];
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar return ((point[X] >= min[0] && point[X] <= max[0]) &&
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar (point[Y] >= min[1] && point[Y] <= max[1]));
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar}
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedoohstatic int pointincircle(const double point[2], double coords[MAXVERTS][2])
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar double radius1, radius2;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] - coords[1][Y]))
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar + ((coords[0][X] - coords[1][X]) * (coords[0][X] - coords[1][X]));
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y]))
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar + ((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh return (radius2 <= radius1);
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen}
4a56677aad9b66a36f3dc9fddbca8dc1230ad471rbowen
dc1328abb455410dfc5e4828f5e0e60dd859db49humbedooh#define fmin(a,b) (((a)>(b))?(b):(a))
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen#define fmax(a,b) (((a)>(b))?(a):(b))
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coarstatic int pointinpoly(const double point[2], double pgon[MAXVERTS][2])
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar int i, numverts, crossings = 0;
4a56677aad9b66a36f3dc9fddbca8dc1230ad471rbowen double x = point[X], y = point[Y];
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar for (numverts = 0; pgon[numverts][X] != -1 && numverts < MAXVERTS;
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh numverts++) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd /* just counting the vertexes */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd for (i = 0; i < numverts; i++) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar double x1=pgon[i][X];
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar double y1=pgon[i][Y];
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar double x2=pgon[(i + 1) % numverts][X];
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen double y2=pgon[(i + 1) % numverts][Y];
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd double d=(y - y1) * (x2 - x1) - (x - x1) * (y2 - y1);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if ((y1 >= y) != (y2 >= y)) {
4aa603e6448b99f9371397d439795c91a93637eand crossings +=y2 - y1 >= 0 ? d >= 0 : d <= 0;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (!d && fmin(x1,x2) <= x && x <= fmax(x1,x2)
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen && fmin(y1,y2) <= y && y <= fmax(y1,y2)) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return 1;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return crossings & 0x01;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen}
4aa603e6448b99f9371397d439795c91a93637eand
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9ndstatic int is_closer(const double point[2], double coords[MAXVERTS][2],
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd double *closest)
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar double dist_squared = ((point[X] - coords[0][X])
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * (point[X] - coords[0][X]))
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen + ((point[Y] - coords[0][Y])
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * (point[Y] - coords[0][Y]));
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (point[X] < 0 || point[Y] < 0) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar return (0); /* don't mess around with negative coordinates */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen if (*closest < 0 || dist_squared < *closest) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *closest = dist_squared;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return (1); /* if this is the first point or is the closest yet
4aa603e6448b99f9371397d439795c91a93637eand set 'closest' equal to this distance^2 */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return (0); /* if it's not the first or closest */
4aa603e6448b99f9371397d439795c91a93637eand
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen}
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9ndstatic double get_x_coord(const char *args)
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar char *endptr; /* we want it non-null */
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh double x_coord = -1; /* -1 is returned if no coordinate is given */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (args == NULL) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return (-1); /* in case we aren't passed anything */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh while (*args && !apr_isdigit(*args) && *args != ',') {
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen args++; /* jump to the first digit, but not past
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd a comma or end */
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh x_coord = strtod(args, &endptr);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
b58e08539de1f9a9167ed379efe2d5fdaf70200fhumbedooh if (endptr > args) { /* if a conversion was made */
b58e08539de1f9a9167ed379efe2d5fdaf70200fhumbedooh return (x_coord);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return (-1); /* else if no conversion was made,
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd or if no args was given */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd}
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9ndstatic double get_y_coord(const char *args)
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar char *endptr; /* we want it non-null */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar const char *start_of_y = NULL;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar double y_coord = -1; /* -1 is returned on error */
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (args == NULL) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar return (-1); /* in case we aren't passed anything */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen start_of_y = ap_strchr_c(args, ','); /* the comma */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (start_of_y) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd start_of_y++; /* start looking at the character after
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd the comma */
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd while (*start_of_y && !apr_isdigit(*start_of_y)) {
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen start_of_y++; /* jump to the first digit, but not
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen past the end */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd y_coord = strtod(start_of_y, &endptr);
4aa603e6448b99f9371397d439795c91a93637eand
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (endptr > start_of_y) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return (y_coord);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return (-1); /* if no conversion was made, or
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar no comma was found in args */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen}
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen/* See if string has a "quoted part", and if so set *quoted_part to
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * the first character of the quoted part, then hammer a \0 onto the
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * trailing quote, and set *string to point at the first character
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * past the second quote.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen *
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * Otherwise set *quoted_part to NULL, and leave *string alone.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen */
4aa603e6448b99f9371397d439795c91a93637eandstatic void read_quoted(char **string, char **quoted_part)
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen{
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd char *strp = *string;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen /* assume there's no quoted part */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar *quoted_part = NULL;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh while (apr_isspace(*strp)) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar strp++; /* go along string until non-whitespace */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (*strp == '"') { /* if that character is a double quote */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar strp++; /* step over it */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen *quoted_part = strp; /* note where the quoted part begins */
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar while (*strp && *strp != '"') {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar ++strp; /* skip the quoted portion */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh
fdfb488408aaf846476d8c42532952e088ea2258humbedooh *strp = '\0'; /* end the string with a NUL */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd strp++; /* step over the last double quote */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen *string = strp;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen}
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen/*
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * returns the mapped URL or NULL.
b58e08539de1f9a9167ed379efe2d5fdaf70200fhumbedooh */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowenstatic char *imap_url(request_rec *r, const char *base, const char *value)
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
b58e08539de1f9a9167ed379efe2d5fdaf70200fhumbedooh/* translates a value into a URL. */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd int slen, clen;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen char *string_pos = NULL;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar const char *string_pos_const = NULL;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar char *directory = NULL;
1784f96e3c9d47bf36a4d973d47e3857f260fc7dhumbedooh const char *referer = NULL;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd char *my_base;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return ap_construct_url(r->pool, r->uri, r);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return apr_pstrdup(r->pool, value); /* these are handled elsewhere,
4aa603e6448b99f9371397d439795c91a93637eand so just copy them */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!strcasecmp(value, "referer")) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd referer = apr_table_get(r->headers_in, "Referer");
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (referer && *referer) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return ap_escape_html(r->pool, referer);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen else {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen /* XXX: This used to do *value = '\0'; ... which is totally bogus
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * because it hammers the passed in value, which can be a string
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * constant, or part of a config, or whatever. Total garbage.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * This works around that without changing the rest of this
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * code much
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen value = ""; /* if 'referer' but no referring page,
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen null the value */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen string_pos_const = value;
4aa603e6448b99f9371397d439795c91a93637eand while (apr_isalpha(*string_pos_const)) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen string_pos_const++; /* go along the URL from the map
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd until a non-letter */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (*string_pos_const == ':') {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd /* if letters and then a colon (like http:) */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd /* it's an absolute URL, so use it! */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return apr_pstrdup(r->pool, value);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!base || !*base) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (value && *value) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar return apr_pstrdup(r->pool, value); /* no base: use what is given */
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh }
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen /* no base, no value: pick a simple default */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return ap_construct_url(r->pool, "/", r);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
4aa603e6448b99f9371397d439795c91a93637eand
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen /* must be a relative URL to be combined with base */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (ap_strchr_c(base, '/') == NULL && (!strncmp(value, "../", 3)
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen || !strcmp(value, ".."))) {
4aa603e6448b99f9371397d439795c91a93637eand ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen "invalid base directive in map file: %s", r->uri);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return NULL;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen my_base = apr_pstrdup(r->pool, base);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar string_pos = my_base;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar while (*string_pos) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (*string_pos == '/' && *(string_pos + 1) == '/') {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar string_pos += 2; /* if there are two slashes, jump over them */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar continue;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (*string_pos == '/') { /* the first single slash */
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh if (value[0] == '/') {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *string_pos = '\0';
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd } /* if the URL from the map starts from root,
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen end the base URL string at the first single
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd slash */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd else {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd directory = string_pos; /* save the start of
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh the directory portion */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen string_pos = strrchr(string_pos, '/'); /* now reuse
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd string_pos */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen string_pos++; /* step over that last slash */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *string_pos = '\0';
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd } /* but if the map url is relative, leave the
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd slash on the base (if there is one) */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd break;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd string_pos++; /* until we get to the end of my_base without
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd finding a slash by itself */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd while (!strncmp(value, "../", 3) || !strcmp(value, "..")) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (directory && (slen = strlen(directory))) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd /* for each '..', knock a directory off the end
fdfb488408aaf846476d8c42532952e088ea2258humbedooh by ending the string right at the last slash.
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd But only consider the directory portion: don't eat
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd into the server name. And only try if a directory
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar portion was found */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd clen = slen - 1;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen while ((slen - clen) == 1) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if ((string_pos = strrchr(directory, '/'))) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd *string_pos = '\0';
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd clen = strlen(directory);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (clen == 0) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd break;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd value += 2; /* jump over the '..' that we found in the
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen value */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd else if (directory) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd "invalid directory name in map file: %s", r->uri);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return NULL;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
fdfb488408aaf846476d8c42532952e088ea2258humbedooh
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (!strncmp(value, "/../", 4) || !strcmp(value, "/..")) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar value++; /* step over the '/' if there are more '..'
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd to do. This way, we leave the starting
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd '/' on value after the last '..', but get
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen rid of it otherwise */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd } /* by this point, value does not start
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd with '..' */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (value && *value) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return apr_pstrcat(r->pool, my_base, value, NULL);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return my_base;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd}
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coarstatic int imap_reply(request_rec *r, char *redirect)
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!strcasecmp(redirect, "error")) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar /* they actually requested an error! */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar return HTTP_INTERNAL_SERVER_ERROR;
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh }
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh if (!strcasecmp(redirect, "nocontent")) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd /* tell the client to keep the page it has */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return HTTP_NO_CONTENT;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (redirect && *redirect) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar /* must be a URL, so redirect to it */
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh apr_table_setn(r->headers_out, "Location", redirect);
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen return HTTP_MOVED_TEMPORARILY;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
f681bba51e40eac9bbb804c541100b0984df4026humbedooh return HTTP_INTERNAL_SERVER_ERROR;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd}
f681bba51e40eac9bbb804c541100b0984df4026humbedooh
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9ndstatic void menu_header(request_rec *r, char *menu)
f681bba51e40eac9bbb804c541100b0984df4026humbedooh{
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_set_content_type(r, "text/html; charset=ISO-8859-1");
f681bba51e40eac9bbb804c541100b0984df4026humbedooh
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh ap_rvputs(r, DOCTYPE_HTML_3_2, "<html><head>\n<title>Menu for ",
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_escape_html(r->pool, r->uri),
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen "</title>\n</head><body>\n", NULL);
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (!strcasecmp(menu, "formatted")) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_rvputs(r, "<h1>Menu for ",
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_escape_html(r->pool, r->uri),
4aa603e6448b99f9371397d439795c91a93637eand "</h1>\n<hr />\n\n", NULL);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
ea998f41c9019cf170d71291986db5d1a89d5128jailletc
ea998f41c9019cf170d71291986db5d1a89d5128jailletc return;
ea998f41c9019cf170d71291986db5d1a89d5128jailletc}
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowenstatic void menu_blank(request_rec *r, char *menu)
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!strcasecmp(menu, "formatted")) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen ap_rputs("\n", r);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!strcasecmp(menu, "semiformatted")) {
4aa603e6448b99f9371397d439795c91a93637eand ap_rputs("<br />\n", r);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (!strcasecmp(menu, "unformatted")) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_rputs("\n", r);
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar return;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar}
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coarstatic void menu_comment(request_rec *r, char *menu, char *comment)
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh{
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen if (!strcasecmp(menu, "formatted")) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_rputs("\n", r); /* print just a newline if 'formatted' */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
4aa603e6448b99f9371397d439795c91a93637eand if (!strcasecmp(menu, "semiformatted") && *comment) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen ap_rvputs(r, comment, "\n", NULL);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!strcasecmp(menu, "unformatted") && *comment) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen ap_rvputs(r, comment, "\n", NULL);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
4aa603e6448b99f9371397d439795c91a93637eand return; /* comments are ignored in the
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen 'formatted' form */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd}
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowenstatic void menu_default(request_rec *r, char *menu, char *href, char *text)
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar return; /* don't print such lines, these aren't
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh really href's */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (!strcasecmp(menu, "formatted")) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd "</a></pre>\n", NULL);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!strcasecmp(menu, "semiformatted")) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar "</a></pre>\n", NULL);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!strcasecmp(menu, "unformatted")) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar return;
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh}
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9ndstatic void menu_directive(request_rec *r, char *menu, char *href, char *text)
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen return; /* don't print such lines, as this isn't
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar really an href */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (!strcasecmp(menu, "formatted")) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_rvputs(r, "<pre> <a href=\"", href, "\">", text,
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen "</a></pre>\n", NULL);
156e9dfbbab272a462dadedda424385a706a8637humbedooh }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!strcasecmp(menu, "semiformatted")) {
156e9dfbbab272a462dadedda424385a706a8637humbedooh ap_rvputs(r, "<pre> <a href=\"", href, "\">", text,
156e9dfbbab272a462dadedda424385a706a8637humbedooh "</a></pre>\n", NULL);
156e9dfbbab272a462dadedda424385a706a8637humbedooh }
156e9dfbbab272a462dadedda424385a706a8637humbedooh if (!strcasecmp(menu, "unformatted")) {
156e9dfbbab272a462dadedda424385a706a8637humbedooh ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
4aa603e6448b99f9371397d439795c91a93637eand }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd}
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowenstatic void menu_footer(request_rec *r)
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh ap_rputs("\n\n</body>\n</html>\n", r); /* finish the menu */
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh}
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9ndstatic int imap_handler_internal(request_rec *r)
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd{
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd char input[MAX_STRING_LEN];
4aa603e6448b99f9371397d439795c91a93637eand char *directive;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen char *value;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd char *href_text;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen char *base;
4aa603e6448b99f9371397d439795c91a93637eand char *redirect;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd char *mapdflt;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd char *closest = NULL;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd double closest_yet = -1;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen apr_status_t status;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar double testpoint[2];
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh double pointarray[MAXVERTS + 1][2];
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd int vertex;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd char *string_pos;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd int showmenu = 0;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar imap_conf_rec *icr;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen char *imap_menu;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen char *imap_default;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen char *imap_base;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen ap_configfile_t *imap;
4aa603e6448b99f9371397d439795c91a93637eand
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen icr = ap_get_module_config(r->per_dir_config, &imagemap_module);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen imap_menu = icr->imap_menu ? icr->imap_menu : IMAP_MENU_DEFAULT;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen imap_default = icr->imap_default
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen ? icr->imap_default : IMAP_DEFAULT_DEFAULT;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen imap_base = icr->imap_base ? icr->imap_base : IMAP_BASE_DEFAULT;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen status = ap_pcfg_openfile(&imap, r->pool, r->filename);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (status != APR_SUCCESS) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return HTTP_NOT_FOUND;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen base = imap_url(r, NULL, imap_base); /* set base according
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen to default */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!base) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return HTTP_INTERNAL_SERVER_ERROR;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen mapdflt = imap_url(r, NULL, imap_default); /* and default to
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar global default */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!mapdflt) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return HTTP_INTERNAL_SERVER_ERROR;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen testpoint[X] = get_x_coord(r->args);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen testpoint[Y] = get_y_coord(r->args);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if ((testpoint[X] == -1 || testpoint[Y] == -1) ||
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen (testpoint[X] == 0 && testpoint[Y] == 0)) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen /* if either is -1 or if both are zero (new Lynx) */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen /* we don't have valid coordinates */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen testpoint[X] = -1;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar testpoint[Y] = -1;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (strncasecmp(imap_menu, "none", 2)) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar showmenu = 1; /* show the menu _unless_ ImapMenu is
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen 'none' or 'no' */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (showmenu) { /* send start of imagemap menu if
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar we're going to */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen menu_header(r, imap_menu);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar while (!ap_cfg_getline(input, sizeof(input), imap)) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!input[0]) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (showmenu) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen menu_blank(r, imap_menu);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar continue;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (input[0] == '#') {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (showmenu) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen menu_comment(r, imap_menu, input + 1);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen continue;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen } /* blank lines and comments are ignored
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if we aren't printing a menu */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen /* find the first two space delimited fields, recall that
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * ap_cfg_getline has removed leading/trailing whitespace.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen *
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * note that we're tokenizing as we go... if we were to use the
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * ap_getword() class of functions we would end up allocating extra
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * memory for every line of the map file
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar string_pos = input;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!*string_pos) { /* need at least two fields */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen goto need_2_fields;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen directive = string_pos;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen while (*string_pos && !apr_isspace(*string_pos)) { /* past directive */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen ++string_pos;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!*string_pos) { /* need at least two fields */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen goto need_2_fields;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen *string_pos++ = '\0';
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!*string_pos) { /* need at least two fields */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen goto need_2_fields;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen while(*string_pos && apr_isspace(*string_pos)) { /* past whitespace */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen ++string_pos;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen value = string_pos;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen while (*string_pos && !apr_isspace(*string_pos)) { /* past value */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar ++string_pos;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (apr_isspace(*string_pos)) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen *string_pos++ = '\0';
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen else {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen /* end of input, don't advance past it */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar *string_pos = '\0';
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!strncasecmp(directive, "base", 4)) { /* base, base_uri */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen base = imap_url(r, NULL, value);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!base) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar goto menu_bail;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen continue; /* base is never printed to a menu */
4aa603e6448b99f9371397d439795c91a93637eand }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd read_quoted(&string_pos, &href_text);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen if (!strcasecmp(directive, "default")) { /* default */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar mapdflt = imap_url(r, NULL, value);
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh if (!mapdflt) {
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen goto menu_bail;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (showmenu) { /* print the default if there's a menu */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd redirect = imap_url(r, base, mapdflt);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (!redirect) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd goto menu_bail;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar menu_default(r, imap_menu, redirect,
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar href_text ? href_text : mapdflt);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar continue;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd vertex = 0;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar while (vertex < MAXVERTS &&
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen sscanf(string_pos, "%lf%*[, ]%lf",
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen &pointarray[vertex][X], &pointarray[vertex][Y]) == 2) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar /* Now skip what we just read... we can't use ANSIism %n */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar while (apr_isspace(*string_pos)) { /* past whitespace */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar string_pos++;
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh }
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen while (apr_isdigit(*string_pos)) { /* and the 1st number */
4aa603e6448b99f9371397d439795c91a93637eand string_pos++;
4a56677aad9b66a36f3dc9fddbca8dc1230ad471rbowen }
4a56677aad9b66a36f3dc9fddbca8dc1230ad471rbowen string_pos++; /* skip the ',' */
dc1328abb455410dfc5e4828f5e0e60dd859db49humbedooh while (apr_isspace(*string_pos)) { /* past any more whitespace */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen string_pos++;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh while (apr_isdigit(*string_pos)) { /* 2nd number */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen string_pos++;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd vertex++;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen } /* so long as there are more vertices to
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd read, and we have room, read them in.
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd We start where we left off of the last
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd sscanf, not at the beginning. */
4aa603e6448b99f9371397d439795c91a93637eand
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen pointarray[vertex][X] = -1; /* signals the end of vertices */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (showmenu) {
4aa603e6448b99f9371397d439795c91a93637eand if (!href_text) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen read_quoted(&string_pos, &href_text); /* href text could
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd be here instead */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen redirect = imap_url(r, base, value);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar if (!redirect) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar goto menu_bail;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh menu_directive(r, imap_menu, redirect,
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen href_text ? href_text : value);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd continue;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
4aa603e6448b99f9371397d439795c91a93637eand /* note that we don't make it past here if we are making a menu */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (testpoint[X] == -1 || pointarray[0][X] == -1) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen continue; /* don't try the following tests if testpoints
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen are invalid, or if there are no
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen coordinates */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!strcasecmp(directive, "poly")) { /* poly */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (pointinpoly(testpoint, pointarray)) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen ap_cfg_closefile(imap);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen redirect = imap_url(r, base, value);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!redirect) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return HTTP_INTERNAL_SERVER_ERROR;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return (imap_reply(r, redirect));
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar continue;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!strcasecmp(directive, "circle")) { /* circle */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (pointincircle(testpoint, pointarray)) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen ap_cfg_closefile(imap);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen redirect = imap_url(r, base, value);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!redirect) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return HTTP_INTERNAL_SERVER_ERROR;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return (imap_reply(r, redirect));
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen continue;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!strcasecmp(directive, "rect")) { /* rect */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (pointinrect(testpoint, pointarray)) {
4aa603e6448b99f9371397d439795c91a93637eand ap_cfg_closefile(imap);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen redirect = imap_url(r, base, value);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (!redirect) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return HTTP_INTERNAL_SERVER_ERROR;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar return (imap_reply(r, redirect));
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh }
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen continue;
4a56677aad9b66a36f3dc9fddbca8dc1230ad471rbowen }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
4aa603e6448b99f9371397d439795c91a93637eand if (!strcasecmp(directive, "point")) { /* point */
dc1328abb455410dfc5e4828f5e0e60dd859db49humbedooh
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen if (is_closer(testpoint, pointarray, &closest_yet)) {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar closest = apr_pstrdup(r->pool, value);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd continue;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd } /* move on to next line whether it's
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh closest or not */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar } /* nothing matched, so we get another line! */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar ap_cfg_closefile(imap); /* we are done with the map file; close it */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh if (showmenu) {
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen menu_footer(r); /* finish the menu and we are done */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return OK;
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd }
4aa603e6448b99f9371397d439795c91a93637eand
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (closest) { /* if a 'point' directive has been seen */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd redirect = imap_url(r, base, closest);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen if (!redirect) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return HTTP_INTERNAL_SERVER_ERROR;
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen return (imap_reply(r, redirect));
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen }
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen
4aa603e6448b99f9371397d439795c91a93637eand if (mapdflt) { /* a default should be defined, even if
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen only 'nocontent' */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd redirect = imap_url(r, base, mapdflt);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd if (!redirect) {
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen return HTTP_INTERNAL_SERVER_ERROR;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh return (imap_reply(r, redirect));
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh return HTTP_INTERNAL_SERVER_ERROR; /* If we make it this far,
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen we failed. They lose! */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9ndneed_2_fields:
4aa603e6448b99f9371397d439795c91a93637eand ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd "map file %s, line %d syntax error: requires at "
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen "least two fields", r->uri, imap->line_number);
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen /* fall through */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowenmenu_bail:
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen ap_cfg_closefile(imap);
4aa603e6448b99f9371397d439795c91a93637eand if (showmenu) {
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen /* There's not much else we can do ... we've already sent the headers
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * to the client.
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd */
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_rputs("\n\n[an internal server error occured]\n", r);
58738603be16903384f67947bbe524be985ebae7nd menu_footer(r);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return OK;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen }
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return HTTP_INTERNAL_SERVER_ERROR;
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar}
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9ndstatic int imap_handler(request_rec *r)
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd /* Optimization: skip the allocation of large local variables on the
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * stack (in imap_handler_internal()) on requests that aren't using
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd * imagemaps
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar */
e7135fcbd2e1439ae327ecb63365c143d93d4b98humbedooh if (r->method_number != M_GET || (strcmp(r->handler,IMAP_MAGIC_TYPE)
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd && strcmp(r->handler, "imap-file"))) {
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd return DECLINED;
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar else {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar return imap_handler_internal(r);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar}
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9ndstatic void register_hooks(apr_pool_t *p)
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd{
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd ap_hook_handler(imap_handler,NULL,NULL,APR_HOOK_MIDDLE);
16055ce2030d5a9ab3b1797dfe4ba2c1177a6af9nd}
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coarmodule AP_MODULE_DECLARE_DATA imagemap_module =
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar STANDARD20_MODULE_STUFF,
fed0ff87936117a4db604de57c6bdfe449a4b7behumbedooh create_imap_dir_config, /* dir config creater */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar merge_imap_dir_configs, /* dir merger --- default is to override */
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar NULL, /* server config */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen NULL, /* merge server config */
35ac4e1a6ec5aa3cfa1a34d8f20fe8a841cc46b7rbowen imap_cmds, /* command apr_table_t */
4aa603e6448b99f9371397d439795c91a93637eand register_hooks /* register hooks */
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen};
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen