mod_imap.c revision 89cbb0132036aa1bd2bac7dd962a8c43409de0b4
08cb74ca432a8c24e39f17dedce527e6a47b8001jerenkrantz/* ====================================================================
08cb74ca432a8c24e39f17dedce527e6a47b8001jerenkrantz * The Apache Software License, Version 1.1
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * reserved.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Redistribution and use in source and binary forms, with or without
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * modification, are permitted provided that the following conditions
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * are met:
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 1. Redistributions of source code must retain the above copyright
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * notice, this list of conditions and the following disclaimer.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd *
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 2. Redistributions in binary form must reproduce the above copyright
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * notice, this list of conditions and the following disclaimer in
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * the documentation and/or other materials provided with the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * distribution.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
785be1b6298010956622771c870ab3cd8ca57a2faaron * 3. The end-user documentation included with the redistribution,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * if any, must include the following acknowledgment:
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * "This product includes software developed by the
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * Apache Software Foundation (http://www.apache.org/)."
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * Alternately, this acknowledgment may appear in the software itself,
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * if and wherever such third-party acknowledgments normally appear.
1b21d7b3d97def358b2e923655edeb16613a1c31gstein *
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * 4. The names "Apache" and "Apache Software Foundation" must
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * not be used to endorse or promote products derived from this
1b21d7b3d97def358b2e923655edeb16613a1c31gstein * software without prior written permission. For written
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * permission, please contact apache@apache.org.
2d71630471d1c23f0137309e3c3957c633ecbfd6rbb *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * 5. Products derived from this software may not be called "Apache",
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * nor may "Apache" appear in their name, without prior written
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * permission of the Apache Software Foundation.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
51af95bb51b5084e883bad250b2afa2838e9ceebfielding * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
d4f1d9c1ff112a8ab9bee31f196973761329b236rbb * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7fae9cc4639013f3c04c085547256c68814aee8ftrawick * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
7fae9cc4639013f3c04c085547256c68814aee8ftrawick * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7fae9cc4639013f3c04c085547256c68814aee8ftrawick * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
7fae9cc4639013f3c04c085547256c68814aee8ftrawick * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * SUCH DAMAGE.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ====================================================================
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * This software consists of voluntary contributions made by many
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * individuals on behalf of the Apache Software Foundation. For more
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * information on the Apache Software Foundation, please see
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * <http://www.apache.org/>.
785be1b6298010956622771c870ab3cd8ca57a2faaron *
785be1b6298010956622771c870ab3cd8ca57a2faaron * Portions of this software are based upon public domain software
785be1b6298010956622771c870ab3cd8ca57a2faaron * originally written at the National Center for Supercomputing Applications,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * University of Illinois, Urbana-Champaign.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/*
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * This imagemap module started as a port of the original imagemap.c
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * written by Rob McCool (11/13/93 robm@ncsa.uiuc.edu).
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * This version includes the mapping algorithms found in version 1.3
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * of imagemap.c.
785be1b6298010956622771c870ab3cd8ca57a2faaron *
785be1b6298010956622771c870ab3cd8ca57a2faaron * Contributors to this code include:
785be1b6298010956622771c870ab3cd8ca57a2faaron *
785be1b6298010956622771c870ab3cd8ca57a2faaron * Kevin Hughes, kevinh@pulua.hcc.hawaii.edu
785be1b6298010956622771c870ab3cd8ca57a2faaron *
785be1b6298010956622771c870ab3cd8ca57a2faaron * Eric Haines, erich@eye.com
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
f4b96a996afbc46872f57ad1450e6ee1c8f13707jorton * Randy Terbush, randy@zyzzyva.com
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * port to Apache module format, "base_uri" and support for relative URLs
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * James H. Cloos, Jr., cloos@jhcloos.com
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Added point datatype, using code in NCSA's version 1.8 imagemap.c
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * program, as distributed with version 1.4.1 of their server.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * The point code is originally added by Craig Milo Rogers, Rogers@ISI.Edu
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Nathan Kurz, nate@tripod.com
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Rewrite/reorganization. New handling of default, base and relative URLs.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * New Configuration directives:
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ImapMenu {none, formatted, semiformatted, unformatted}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ImapDefault {error, nocontent, referer, menu, URL}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ImapBase {map, referer, URL}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Support for creating non-graphical menu added. (backwards compatible):
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Old: directive URL [x,y ...]
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * New: directive URL "Menu text" [x,y ...]
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * or: directive URL x,y ... "Menu text"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Map format and menu concept courtesy Joshua Bell, jsbell@acs.ucalgary.ca.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Mark Cox, mark@ukweb.com, Allow relative URLs even when no base specified
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "apr.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "apr_strings.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "apr_lib.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define APR_WANT_STDIO /* for sscanf() */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define APR_WANT_STRFUNC
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "apr_want.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "ap_config.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "httpd.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_config.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_request.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_core.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_protocol.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_main.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_log.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "util_script.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "mod_core.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define IMAP_MAGIC_TYPE "application/x-httpd-imap"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define MAXVERTS 100
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define X 0
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define Y 1
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define IMAP_MENU_DEFAULT "formatted"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define IMAP_DEFAULT_DEFAULT "nocontent"
45acd673a68181802b112e97e84fa3813ddd3ec1stoddard#define IMAP_BASE_DEFAULT "map"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#ifdef SUNOS4
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingdouble strtod(); /* SunOS needed this */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#endif
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingmodule AP_MODULE_DECLARE_DATA imap_module;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingtypedef struct {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *imap_menu;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *imap_default;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *imap_base;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding} imap_conf_rec;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void *create_imap_dir_config(apr_pool_t *p, char *dummy)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm imap_conf_rec *icr =
785be1b6298010956622771c870ab3cd8ca57a2faaron (imap_conf_rec *) apr_palloc(p, sizeof(imap_conf_rec));
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding icr->imap_menu = NULL;
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick icr->imap_default = NULL;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding icr->imap_base = NULL;
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick return icr;
58fd79b56eb624bf011772994e9761d3c2e228c1orlikowski}
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawickstatic void *merge_imap_dir_configs(apr_pool_t *p, void *basev, void *addv)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick imap_conf_rec *new = (imap_conf_rec *) apr_pcalloc(p, sizeof(imap_conf_rec));
785be1b6298010956622771c870ab3cd8ca57a2faaron imap_conf_rec *base = (imap_conf_rec *) basev;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding imap_conf_rec *add = (imap_conf_rec *) addv;
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick new->imap_menu = add->imap_menu ? add->imap_menu : base->imap_menu;
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames new->imap_default = add->imap_default ? add->imap_default
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames : base->imap_default;
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames new->imap_base = add->imap_base ? add->imap_base : base->imap_base;
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames return new;
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames}
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregamesstatic const command_rec imap_cmds[] =
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames{
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick AP_INIT_TAKE1("ImapMenu", ap_set_string_slot,
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick (void *) XtOffsetOf(imap_conf_rec, imap_menu), OR_INDEXES,
560f6ac786d611b858b2bad932713d9e971f0716trawick "the type of menu generated: none, formatted, semiformatted, "
560f6ac786d611b858b2bad932713d9e971f0716trawick "unformatted"),
560f6ac786d611b858b2bad932713d9e971f0716trawick AP_INIT_TAKE1("ImapDefault", ap_set_string_slot,
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick (void *) XtOffsetOf(imap_conf_rec, imap_default), OR_INDEXES,
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick "the action taken if no match: error, nocontent, referer, "
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick "menu, URL"),
7bf77d70b6830636bc36e6b76a228c301be23ff7brianp AP_INIT_TAKE1("ImapBase", ap_set_string_slot,
7bf77d70b6830636bc36e6b76a228c301be23ff7brianp (void *) XtOffsetOf(imap_conf_rec, imap_base), OR_INDEXES,
7bf77d70b6830636bc36e6b76a228c301be23ff7brianp "the base for all URL's: map, referer, URL (or start of)"),
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick {NULL}
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick};
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawickstatic int pointinrect(const double point[2], double coords[MAXVERTS][2])
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding double max[2], min[2];
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (coords[0][X] > coords[1][X]) {
eae32ab3fb398ca408bc2d45b22adf1b67a75471rbb max[0] = coords[0][X];
39b76a07959a0a332366c735a23894d9e8ed6872trawick min[0] = coords[1][X];
39b76a07959a0a332366c735a23894d9e8ed6872trawick }
785be1b6298010956622771c870ab3cd8ca57a2faaron else {
785be1b6298010956622771c870ab3cd8ca57a2faaron max[0] = coords[1][X];
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick min[0] = coords[0][X];
39b76a07959a0a332366c735a23894d9e8ed6872trawick }
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick
785be1b6298010956622771c870ab3cd8ca57a2faaron if (coords[0][Y] > coords[1][Y]) {
785be1b6298010956622771c870ab3cd8ca57a2faaron max[1] = coords[0][Y];
066877f1a045103acfdd376d48cdd473c33f409bdougm min[1] = coords[1][Y];
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick }
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick else {
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick max[1] = coords[1][Y];
74b39333600dee3260355ad3a06e36ef6c61c8f1dreid min[1] = coords[0][Y];
74b39333600dee3260355ad3a06e36ef6c61c8f1dreid }
74b39333600dee3260355ad3a06e36ef6c61c8f1dreid
74b39333600dee3260355ad3a06e36ef6c61c8f1dreid return ((point[X] >= min[0] && point[X] <= max[0]) &&
97c78987224dcd037076d393aad1867c26b2c8cftrawick (point[Y] >= min[1] && point[Y] <= max[1]));
97c78987224dcd037076d393aad1867c26b2c8cftrawick}
97c78987224dcd037076d393aad1867c26b2c8cftrawick
97c78987224dcd037076d393aad1867c26b2c8cftrawickstatic int pointincircle(const double point[2], double coords[MAXVERTS][2])
97c78987224dcd037076d393aad1867c26b2c8cftrawick{
97c78987224dcd037076d393aad1867c26b2c8cftrawick double radius1, radius2;
97c78987224dcd037076d393aad1867c26b2c8cftrawick
97c78987224dcd037076d393aad1867c26b2c8cftrawick radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] - coords[1][Y]))
97c78987224dcd037076d393aad1867c26b2c8cftrawick + ((coords[0][X] - coords[1][X]) * (coords[0][X] - coords[1][X]));
97c78987224dcd037076d393aad1867c26b2c8cftrawick
97c78987224dcd037076d393aad1867c26b2c8cftrawick radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y]))
97c78987224dcd037076d393aad1867c26b2c8cftrawick + ((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (radius2 <= radius1);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define fmin(a,b) (((a)>(b))?(b):(a))
785be1b6298010956622771c870ab3cd8ca57a2faaron#define fmax(a,b) (((a)>(b))?(a):(b))
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic int pointinpoly(const double point[2], double pgon[MAXVERTS][2])
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding int i, numverts, crossings = 0;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding double x = point[X], y = point[Y];
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding for (numverts = 0; pgon[numverts][X] != -1 && numverts < MAXVERTS;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding numverts++) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* just counting the vertexes */
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron for (i = 0; i < numverts; i++) {
785be1b6298010956622771c870ab3cd8ca57a2faaron double x1=pgon[i][X];
785be1b6298010956622771c870ab3cd8ca57a2faaron double y1=pgon[i][Y];
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding double x2=pgon[(i + 1) % numverts][X];
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding double y2=pgon[(i + 1) % numverts][Y];
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding double d=(y - y1) * (x2 - x1) - (x - x1) * (y2 - y1);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
785be1b6298010956622771c870ab3cd8ca57a2faaron if ((y1 >= y) != (y2 >= y)) {
785be1b6298010956622771c870ab3cd8ca57a2faaron crossings +=y2 - y1 >= 0 ? d >= 0 : d <= 0;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!d && fmin(x1,x2) <= x && x <= fmax(x1,x2)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding && fmin(y1,y2) <= y && y <= fmax(y1,y2)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return 1;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return crossings & 0x01;
785be1b6298010956622771c870ab3cd8ca57a2faaron}
785be1b6298010956622771c870ab3cd8ca57a2faaron
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic int is_closer(const double point[2], double coords[MAXVERTS][2],
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding double *closest)
785be1b6298010956622771c870ab3cd8ca57a2faaron{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding double dist_squared = ((point[X] - coords[0][X])
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * (point[X] - coords[0][X]))
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding + ((point[Y] - coords[0][Y])
f4b96a996afbc46872f57ad1450e6ee1c8f13707jorton * (point[Y] - coords[0][Y]));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (point[X] < 0 || point[Y] < 0) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (0); /* don't mess around with negative coordinates */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (*closest < 0 || dist_squared < *closest) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *closest = dist_squared;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (1); /* if this is the first point or is the closest yet
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding set 'closest' equal to this distance^2 */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (0); /* if it's not the first or closest */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic double get_x_coord(const char *args)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *endptr; /* we want it non-null */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding double x_coord = -1; /* -1 is returned if no coordinate is given */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
785be1b6298010956622771c870ab3cd8ca57a2faaron if (args == NULL) {
785be1b6298010956622771c870ab3cd8ca57a2faaron return (-1); /* in case we aren't passed anything */
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron while (*args && !apr_isdigit(*args) && *args != ',') {
785be1b6298010956622771c870ab3cd8ca57a2faaron args++; /* jump to the first digit, but not past
785be1b6298010956622771c870ab3cd8ca57a2faaron a comma or end */
785be1b6298010956622771c870ab3cd8ca57a2faaron }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding x_coord = strtod(args, &endptr);
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm
785be1b6298010956622771c870ab3cd8ca57a2faaron if (endptr > args) { /* if a conversion was made */
785be1b6298010956622771c870ab3cd8ca57a2faaron return (x_coord);
785be1b6298010956622771c870ab3cd8ca57a2faaron }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (-1); /* else if no conversion was made,
785be1b6298010956622771c870ab3cd8ca57a2faaron or if no args was given */
785be1b6298010956622771c870ab3cd8ca57a2faaron}
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic double get_y_coord(const char *args)
785be1b6298010956622771c870ab3cd8ca57a2faaron{
785be1b6298010956622771c870ab3cd8ca57a2faaron char *endptr; /* we want it non-null */
785be1b6298010956622771c870ab3cd8ca57a2faaron const char *start_of_y = NULL;
785be1b6298010956622771c870ab3cd8ca57a2faaron double y_coord = -1; /* -1 is returned on error */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm if (args == NULL) {
785be1b6298010956622771c870ab3cd8ca57a2faaron return (-1); /* in case we aren't passed anything */
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding start_of_y = ap_strchr_c(args, ','); /* the comma */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (start_of_y) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding start_of_y++; /* start looking at the character after
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding the comma */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding while (*start_of_y && !apr_isdigit(*start_of_y)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding start_of_y++; /* jump to the first digit, but not
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding past the end */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding y_coord = strtod(start_of_y, &endptr);
a7ed9c525f9460187f327cea953bf90ecf1bdc51gstein
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (endptr > start_of_y) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (y_coord);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
a7ed9c525f9460187f327cea953bf90ecf1bdc51gstein return (-1); /* if no conversion was made, or
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick no comma was found in args */
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick/* See if string has a "quoted part", and if so set *quoted_part to
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick * the first character of the quoted part, then hammer a \0 onto the
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick * trailing quote, and set *string to point at the first character
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick * past the second quote.
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick *
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick * Otherwise set *quoted_part to NULL, and leave *string alone.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmstatic void read_quoted(char **string, char **quoted_part)
785be1b6298010956622771c870ab3cd8ca57a2faaron{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *strp = *string;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* assume there's no quoted part */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm *quoted_part = NULL;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding while (apr_isspace(*strp)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding strp++; /* go along string until non-whitespace */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (*strp == '"') { /* if that character is a double quote */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding strp++; /* step over it */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *quoted_part = strp; /* note where the quoted part begins */
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron while (*strp && *strp != '"') {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ++strp; /* skip the quoted portion */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm *strp = '\0'; /* end the string with a NUL */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding strp++; /* step over the last double quote */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *string = strp;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/*
a7ed9c525f9460187f327cea953bf90ecf1bdc51gstein * returns the mapped URL or NULL.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic char *imap_url(request_rec *r, const char *base, const char *value)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* translates a value into a URL. */
f4b96a996afbc46872f57ad1450e6ee1c8f13707jorton int slen, clen;
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick char *string_pos = NULL;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding const char *string_pos_const = NULL;
785be1b6298010956622771c870ab3cd8ca57a2faaron char *directory = NULL;
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick const char *referer = NULL;
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick char *my_base;
39b76a07959a0a332366c735a23894d9e8ed6872trawick
8fd7c5046d164fb0959222497e5925dfc6a52ff3trawick if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) {
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick return ap_construct_url(r->pool, r->uri, r);
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick }
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return apr_pstrdup(r->pool, value); /* these are handled elsewhere,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding so just copy them */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
8f8ec0957334f50b7ac11359f90490ee467258eedreid
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(value, "referer")) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding referer = apr_table_get(r->headers_in, "Referer");
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (referer && *referer) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return apr_pstrdup(r->pool, referer);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* XXX: This used to do *value = '\0'; ... which is totally bogus
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * because it hammers the passed in value, which can be a string
785be1b6298010956622771c870ab3cd8ca57a2faaron * constant, or part of a config, or whatever. Total garbage.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * This works around that without changing the rest of this
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * code much
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding value = ""; /* if 'referer' but no referring page,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding null the value */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf string_pos_const = value;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding while (apr_isalpha(*string_pos_const)) {
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick string_pos_const++; /* go along the URL from the map
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding until a non-letter */
39b76a07959a0a332366c735a23894d9e8ed6872trawick }
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick if (*string_pos_const == ':') {
785be1b6298010956622771c870ab3cd8ca57a2faaron /* if letters and then a colon (like http:) */
785be1b6298010956622771c870ab3cd8ca57a2faaron /* it's an absolute URL, so use it! */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf return apr_pstrdup(r->pool, value);
39b76a07959a0a332366c735a23894d9e8ed6872trawick }
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!base || !*base) {
785be1b6298010956622771c870ab3cd8ca57a2faaron if (value && *value) {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf return apr_pstrdup(r->pool, value); /* no base: use what is given */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf }
785be1b6298010956622771c870ab3cd8ca57a2faaron /* no base, no value: pick a simple default */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf return ap_construct_url(r->pool, "/", r);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf }
785be1b6298010956622771c870ab3cd8ca57a2faaron
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf /* must be a relative URL to be combined with base */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf if (ap_strchr_c(base, '/') == NULL && (!strncmp(value, "../", 3)
785be1b6298010956622771c870ab3cd8ca57a2faaron || !strcmp(value, ".."))) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
785be1b6298010956622771c870ab3cd8ca57a2faaron "invalid base directive in map file: %s", r->uri);
785be1b6298010956622771c870ab3cd8ca57a2faaron return NULL;
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf }
066877f1a045103acfdd376d48cdd473c33f409bdougm my_base = apr_pstrdup(r->pool, base);
785be1b6298010956622771c870ab3cd8ca57a2faaron string_pos = my_base;
785be1b6298010956622771c870ab3cd8ca57a2faaron while (*string_pos) {
785be1b6298010956622771c870ab3cd8ca57a2faaron if (*string_pos == '/' && *(string_pos + 1) == '/') {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf string_pos += 2; /* if there are two slashes, jump over them */
785be1b6298010956622771c870ab3cd8ca57a2faaron continue;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (*string_pos == '/') { /* the first single slash */
785be1b6298010956622771c870ab3cd8ca57a2faaron if (value[0] == '/') {
785be1b6298010956622771c870ab3cd8ca57a2faaron *string_pos = '\0';
785be1b6298010956622771c870ab3cd8ca57a2faaron } /* if the URL from the map starts from root,
785be1b6298010956622771c870ab3cd8ca57a2faaron end the base URL string at the first single
785be1b6298010956622771c870ab3cd8ca57a2faaron slash */
785be1b6298010956622771c870ab3cd8ca57a2faaron else {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf directory = string_pos; /* save the start of
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf the directory portion */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf string_pos = strrchr(string_pos, '/'); /* now reuse
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf string_pos */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf string_pos++; /* step over that last slash */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf *string_pos = '\0';
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf } /* but if the map url is relative, leave the
066877f1a045103acfdd376d48cdd473c33f409bdougm slash on the base (if there is one) */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding break;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron string_pos++; /* until we get to the end of my_base without
785be1b6298010956622771c870ab3cd8ca57a2faaron finding a slash by itself */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
785be1b6298010956622771c870ab3cd8ca57a2faaron while (!strncmp(value, "../", 3) || !strcmp(value, "..")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron if (directory && (slen = strlen(directory))) {
785be1b6298010956622771c870ab3cd8ca57a2faaron
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf /* for each '..', knock a directory off the end
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf by ending the string right at the last slash.
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf But only consider the directory portion: don't eat
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf into the server name. And only try if a directory
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf portion was found */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf
785be1b6298010956622771c870ab3cd8ca57a2faaron clen = slen - 1;
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron while ((slen - clen) == 1) {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf if ((string_pos = strrchr(directory, '/'))) {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf *string_pos = '\0';
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf }
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf clen = strlen(directory);
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf if (clen == 0) {
785be1b6298010956622771c870ab3cd8ca57a2faaron break;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron value += 2; /* jump over the '..' that we found in the
785be1b6298010956622771c870ab3cd8ca57a2faaron value */
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick }
785be1b6298010956622771c870ab3cd8ca57a2faaron else if (directory) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
785be1b6298010956622771c870ab3cd8ca57a2faaron "invalid directory name in map file: %s", r->uri);
785be1b6298010956622771c870ab3cd8ca57a2faaron return NULL;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strncmp(value, "/../", 4) || !strcmp(value, "/..")) {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf value++; /* step over the '/' if there are more '..'
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf to do. This way, we leave the starting
785be1b6298010956622771c870ab3cd8ca57a2faaron '/' on value after the last '..', but get
785be1b6298010956622771c870ab3cd8ca57a2faaron rid of it otherwise */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf }
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf } /* by this point, value does not start
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf with '..' */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf if (value && *value) {
785be1b6298010956622771c870ab3cd8ca57a2faaron return apr_pstrcat(r->pool, my_base, value, NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron return my_base;
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick}
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic int imap_reply(request_rec *r, char *redirect)
785be1b6298010956622771c870ab3cd8ca57a2faaron{
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(redirect, "error")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron /* they actually requested an error! */
785be1b6298010956622771c870ab3cd8ca57a2faaron return HTTP_INTERNAL_SERVER_ERROR;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(redirect, "nocontent")) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* tell the client to keep the page it has */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return HTTP_NO_CONTENT;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
ebc18d48bea83ee5ed7a1b4e30007e5192539829wrowe if (redirect && *redirect) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* must be a URL, so redirect to it */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_table_setn(r->headers_out, "Location", redirect);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return HTTP_MOVED_TEMPORARILY;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return HTTP_INTERNAL_SERVER_ERROR;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void menu_header(request_rec *r, char *menu)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding r->content_type = "text/html";
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_rvputs(r, DOCTYPE_HTML_3_2, "<html><head>\n<title>Menu for ", r->uri,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding "</title>\n</head><body>\n", NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "formatted")) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_rvputs(r, "<h1>Menu for ", r->uri, "</h1>\n<hr />\n\n", NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return;
785be1b6298010956622771c870ab3cd8ca57a2faaron}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void menu_blank(request_rec *r, char *menu)
f4b96a996afbc46872f57ad1450e6ee1c8f13707jorton{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(menu, "formatted")) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_rputs("\n", r);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(menu, "semiformatted")) {
5f08a022a210f4e511561e89f500621a15e6177dtrawick ap_rputs("<br />\n", r);
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "unformatted")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rputs("\n", r);
5f08a022a210f4e511561e89f500621a15e6177dtrawick }
5f08a022a210f4e511561e89f500621a15e6177dtrawick return;
785be1b6298010956622771c870ab3cd8ca57a2faaron}
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic void menu_comment(request_rec *r, char *menu, char *comment)
785be1b6298010956622771c870ab3cd8ca57a2faaron{
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "formatted")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rputs("\n", r); /* print just a newline if 'formatted' */
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "semiformatted") && *comment) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rvputs(r, comment, "\n", NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "unformatted") && *comment) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rvputs(r, comment, "\n", NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron return; /* comments are ignored in the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding 'formatted' form */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
f4b96a996afbc46872f57ad1450e6ee1c8f13707jorton
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void menu_default(request_rec *r, char *menu, char *href, char *text)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return; /* don't print such lines, these aren't
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding really href's */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "formatted")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
785be1b6298010956622771c870ab3cd8ca57a2faaron "</a></pre>\n", NULL);
900127764fb985c340ee4979cac97146a330c694trawick }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "semiformatted")) {
900127764fb985c340ee4979cac97146a330c694trawick ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
900127764fb985c340ee4979cac97146a330c694trawick "</a></pre>\n", NULL);
900127764fb985c340ee4979cac97146a330c694trawick }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "unformatted")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaron }
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick return;
785be1b6298010956622771c870ab3cd8ca57a2faaron}
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic void menu_directive(request_rec *r, char *menu, char *href, char *text)
785be1b6298010956622771c870ab3cd8ca57a2faaron{
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron return; /* don't print such lines, as this isn't
785be1b6298010956622771c870ab3cd8ca57a2faaron really an href */
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "formatted")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rvputs(r, "<pre> <a href=\"", href, "\">", text,
785be1b6298010956622771c870ab3cd8ca57a2faaron "</a></pre>\n", NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "semiformatted")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rvputs(r, "<pre> <a href=\"", href, "\">", text,
785be1b6298010956622771c870ab3cd8ca57a2faaron "</a></pre>\n", NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(menu, "unformatted")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron return;
785be1b6298010956622771c870ab3cd8ca57a2faaron}
785be1b6298010956622771c870ab3cd8ca57a2faaron
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawickstatic void menu_footer(request_rec *r)
785be1b6298010956622771c870ab3cd8ca57a2faaron{
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rputs("\n\n</body>\n</html>\n", r); /* finish the menu */
785be1b6298010956622771c870ab3cd8ca57a2faaron}
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic int imap_handler(request_rec *r)
785be1b6298010956622771c870ab3cd8ca57a2faaron{
785be1b6298010956622771c870ab3cd8ca57a2faaron char input[MAX_STRING_LEN];
785be1b6298010956622771c870ab3cd8ca57a2faaron char *directive;
785be1b6298010956622771c870ab3cd8ca57a2faaron char *value;
785be1b6298010956622771c870ab3cd8ca57a2faaron char *href_text;
785be1b6298010956622771c870ab3cd8ca57a2faaron char *base;
785be1b6298010956622771c870ab3cd8ca57a2faaron char *redirect;
785be1b6298010956622771c870ab3cd8ca57a2faaron char *mapdflt;
785be1b6298010956622771c870ab3cd8ca57a2faaron char *closest = NULL;
785be1b6298010956622771c870ab3cd8ca57a2faaron double closest_yet = -1;
785be1b6298010956622771c870ab3cd8ca57a2faaron apr_status_t status;
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron double testpoint[2];
785be1b6298010956622771c870ab3cd8ca57a2faaron double pointarray[MAXVERTS + 1][2];
785be1b6298010956622771c870ab3cd8ca57a2faaron int vertex;
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron char *string_pos;
785be1b6298010956622771c870ab3cd8ca57a2faaron int showmenu = 0;
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron imap_conf_rec *icr;
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron char *imap_menu;
785be1b6298010956622771c870ab3cd8ca57a2faaron char *imap_default;
785be1b6298010956622771c870ab3cd8ca57a2faaron char *imap_base;
785be1b6298010956622771c870ab3cd8ca57a2faaron
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick ap_configfile_t *imap;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick if (r->method_number != M_GET || (strcmp(r->handler,IMAP_MAGIC_TYPE)
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick && strcmp(r->handler, "imap-file")))
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick return DECLINED;
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron icr = ap_get_module_config(r->per_dir_config, &imap_module);
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron imap_menu = icr->imap_menu ? icr->imap_menu : IMAP_MENU_DEFAULT;
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick imap_default = icr->imap_default
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick ? icr->imap_default : IMAP_DEFAULT_DEFAULT;
066877f1a045103acfdd376d48cdd473c33f409bdougm imap_base = icr->imap_base ? icr->imap_base : IMAP_BASE_DEFAULT;
785be1b6298010956622771c870ab3cd8ca57a2faaron
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick status = ap_pcfg_openfile(&imap, r->pool, r->filename);
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick if (status != APR_SUCCESS) {
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick return HTTP_NOT_FOUND;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron base = imap_url(r, NULL, imap_base); /* set base according
785be1b6298010956622771c870ab3cd8ca57a2faaron to default */
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!base) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return HTTP_INTERNAL_SERVER_ERROR;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding mapdflt = imap_url(r, NULL, imap_default); /* and default to
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding global default */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!mapdflt) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return HTTP_INTERNAL_SERVER_ERROR;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf testpoint[X] = get_x_coord(r->args);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding testpoint[Y] = get_y_coord(r->args);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if ((testpoint[X] == -1 || testpoint[Y] == -1) ||
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding (testpoint[X] == 0 && testpoint[Y] == 0)) {
bbbf8f0e622ad5a37ccf70f35660fc755575278arbb /* if either is -1 or if both are zero (new Lynx) */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm /* we don't have valid coordinates */
066877f1a045103acfdd376d48cdd473c33f409bdougm testpoint[X] = -1;
785be1b6298010956622771c870ab3cd8ca57a2faaron testpoint[Y] = -1;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (strncasecmp(imap_menu, "none", 2)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding showmenu = 1; /* show the menu _unless_ ImapMenu is
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding 'none' or 'no' */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (showmenu) { /* send start of imagemap menu if
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding we're going to */
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf menu_header(r, imap_menu);
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf }
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf while (!ap_cfg_getline(input, sizeof(input), imap)) {
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf if (!input[0]) {
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf if (showmenu) {
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf menu_blank(r, imap_menu);
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf }
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf continue;
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf }
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf
91583d2e9c0550f539ea6f4dedf051979ad1ad88fanf if (input[0] == '#') {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (showmenu) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding menu_comment(r, imap_menu, input + 1);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick continue;
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf } /* blank lines and comments are ignored
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick if we aren't printing a menu */
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf /* find the first two space delimited fields, recall that
9c518951a46c7a12e20876827bb2e84ef87d3c11jerenkrantz * ap_cfg_getline has removed leading/trailing whitespace.
9c518951a46c7a12e20876827bb2e84ef87d3c11jerenkrantz *
9c518951a46c7a12e20876827bb2e84ef87d3c11jerenkrantz * note that we're tokenizing as we go... if we were to use the
9c518951a46c7a12e20876827bb2e84ef87d3c11jerenkrantz * ap_getword() class of functions we would end up allocating extra
9c518951a46c7a12e20876827bb2e84ef87d3c11jerenkrantz * memory for every line of the map file
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick */
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick string_pos = input;
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick if (!*string_pos) { /* need at least two fields */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding goto need_2_fields;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
0db1b9810f06c0e3c537e0e0dfbc30160c308526trawick
0db1b9810f06c0e3c537e0e0dfbc30160c308526trawick directive = string_pos;
0db1b9810f06c0e3c537e0e0dfbc30160c308526trawick while (*string_pos && !apr_isspace(*string_pos)) { /* past directive */
0db1b9810f06c0e3c537e0e0dfbc30160c308526trawick ++string_pos;
0db1b9810f06c0e3c537e0e0dfbc30160c308526trawick }
d40fc22d54d5969fa330e4983cf07f450f7029cebrianp if (!*string_pos) { /* need at least two fields */
0db1b9810f06c0e3c537e0e0dfbc30160c308526trawick goto need_2_fields;
644be6f54749d2d9950d2c4d2ac448f7af016d26martin }
644be6f54749d2d9950d2c4d2ac448f7af016d26martin *string_pos++ = '\0';
644be6f54749d2d9950d2c4d2ac448f7af016d26martin
644be6f54749d2d9950d2c4d2ac448f7af016d26martin if (!*string_pos) { /* need at least two fields */
644be6f54749d2d9950d2c4d2ac448f7af016d26martin goto need_2_fields;
644be6f54749d2d9950d2c4d2ac448f7af016d26martin }
644be6f54749d2d9950d2c4d2ac448f7af016d26martin while(*string_pos && apr_isspace(*string_pos)) { /* past whitespace */
d40fc22d54d5969fa330e4983cf07f450f7029cebrianp ++string_pos;
644be6f54749d2d9950d2c4d2ac448f7af016d26martin }
0db1b9810f06c0e3c537e0e0dfbc30160c308526trawick
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick value = string_pos;
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick while (*string_pos && !apr_isspace(*string_pos)) { /* past value */
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick ++string_pos;
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick }
71715c646d5231de578431f8961e711764b899d3fanf if (apr_isspace(*string_pos)) {
3c8b3749225668f06abbb2b023a833a2cef46931brianp *string_pos++ = '\0';
3c8b3749225668f06abbb2b023a833a2cef46931brianp }
3c8b3749225668f06abbb2b023a833a2cef46931brianp else {
3c8b3749225668f06abbb2b023a833a2cef46931brianp /* end of input, don't advance past it */
ccad4fdc6c75a352157a413bd3bbaf4d0c8a6f72brianp *string_pos = '\0';
785be1b6298010956622771c870ab3cd8ca57a2faaron }
ccad4fdc6c75a352157a413bd3bbaf4d0c8a6f72brianp
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strncasecmp(directive, "base", 4)) { /* base, base_uri */
3c8b3749225668f06abbb2b023a833a2cef46931brianp base = imap_url(r, NULL, value);
3c8b3749225668f06abbb2b023a833a2cef46931brianp if (!base) {
3c8b3749225668f06abbb2b023a833a2cef46931brianp goto menu_bail;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron continue; /* base is never printed to a menu */
785be1b6298010956622771c870ab3cd8ca57a2faaron }
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick read_quoted(&string_pos, &href_text);
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick if (!strcasecmp(directive, "default")) { /* default */
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick mapdflt = imap_url(r, NULL, value);
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick if (!mapdflt) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding goto menu_bail;
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf }
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf if (showmenu) { /* print the default if there's a menu */
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf redirect = imap_url(r, base, mapdflt);
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf if (!redirect) {
2d399cd7535887fceaa9f8f116eb98ce68ddd602trawick goto menu_bail;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf menu_default(r, imap_menu, redirect,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding href_text ? href_text : mapdflt);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding continue;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding vertex = 0;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding while (vertex < MAXVERTS &&
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm sscanf(string_pos, "%lf%*[, ]%lf",
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding &pointarray[vertex][X], &pointarray[vertex][Y]) == 2) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* Now skip what we just read... we can't use ANSIism %n */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding while (apr_isspace(*string_pos)) { /* past whitespace */
785be1b6298010956622771c870ab3cd8ca57a2faaron string_pos++;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding while (apr_isdigit(*string_pos)) { /* and the 1st number */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding string_pos++;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding string_pos++; /* skip the ',' */
785be1b6298010956622771c870ab3cd8ca57a2faaron while (apr_isspace(*string_pos)) { /* past any more whitespace */
785be1b6298010956622771c870ab3cd8ca57a2faaron string_pos++;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron while (apr_isdigit(*string_pos)) { /* 2nd number */
785be1b6298010956622771c870ab3cd8ca57a2faaron string_pos++;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding vertex++;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding } /* so long as there are more vertices to
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding read, and we have room, read them in.
785be1b6298010956622771c870ab3cd8ca57a2faaron We start where we left off of the last
785be1b6298010956622771c870ab3cd8ca57a2faaron sscanf, not at the beginning. */
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron pointarray[vertex][X] = -1; /* signals the end of vertices */
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron if (showmenu) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!href_text) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding read_quoted(&string_pos, &href_text); /* href text could
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding be here instead */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding redirect = imap_url(r, base, value);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!redirect) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding goto menu_bail;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding menu_directive(r, imap_menu, redirect,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding href_text ? href_text : value);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding continue;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
3d96ee83babeec32482c9082c9426340cee8c44dwrowe /* note that we don't make it past here if we are making a menu */
785be1b6298010956622771c870ab3cd8ca57a2faaron
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (testpoint[X] == -1 || pointarray[0][X] == -1) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding continue; /* don't try the following tests if testpoints
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding are invalid, or if there are no
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding coordinates */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(directive, "poly")) { /* poly */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (pointinpoly(testpoint, pointarray)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_cfg_closefile(imap);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding redirect = imap_url(r, base, value);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!redirect) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return HTTP_INTERNAL_SERVER_ERROR;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (imap_reply(r, redirect));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding continue;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(directive, "circle")) { /* circle */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (pointincircle(testpoint, pointarray)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_cfg_closefile(imap);
785be1b6298010956622771c870ab3cd8ca57a2faaron redirect = imap_url(r, base, value);
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!redirect) {
785be1b6298010956622771c870ab3cd8ca57a2faaron return HTTP_INTERNAL_SERVER_ERROR;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (imap_reply(r, redirect));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding continue;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(directive, "rect")) { /* rect */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (pointinrect(testpoint, pointarray)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_cfg_closefile(imap);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding redirect = imap_url(r, base, value);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!redirect) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return HTTP_INTERNAL_SERVER_ERROR;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (imap_reply(r, redirect));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding continue;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(directive, "point")) { /* point */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (is_closer(testpoint, pointarray, &closest_yet)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding closest = apr_pstrdup(r->pool, value);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding continue;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding } /* move on to next line whether it's
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding closest or not */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
dad234382d8424e1c5a30af2838e172aec9d6d1bdreid } /* nothing matched, so we get another line! */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_cfg_closefile(imap); /* we are done with the map file; close it */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (showmenu) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding menu_footer(r); /* finish the menu and we are done */
e6cc28a5eb3371ba0c38e941855e71ff0054f50erbb return OK;
c1b808d160bfb5c849263be8d4acff600853a328trawick }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (closest) { /* if a 'point' directive has been seen */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding redirect = imap_url(r, base, closest);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!redirect) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return HTTP_INTERNAL_SERVER_ERROR;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (imap_reply(r, redirect));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (mapdflt) { /* a default should be defined, even if
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding only 'nocontent' */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding redirect = imap_url(r, base, mapdflt);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!redirect) {
785be1b6298010956622771c870ab3cd8ca57a2faaron return HTTP_INTERNAL_SERVER_ERROR;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron return (imap_reply(r, redirect));
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron
785be1b6298010956622771c870ab3cd8ca57a2faaron return HTTP_INTERNAL_SERVER_ERROR; /* If we make it this far,
785be1b6298010956622771c870ab3cd8ca57a2faaron we failed. They lose! */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingneed_2_fields:
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
785be1b6298010956622771c870ab3cd8ca57a2faaron "map file %s, line %d syntax error: requires at "
785be1b6298010956622771c870ab3cd8ca57a2faaron "least two fields", r->uri, imap->line_number);
785be1b6298010956622771c870ab3cd8ca57a2faaron /* fall through */
785be1b6298010956622771c870ab3cd8ca57a2faaronmenu_bail:
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_cfg_closefile(imap);
785be1b6298010956622771c870ab3cd8ca57a2faaron if (showmenu) {
785be1b6298010956622771c870ab3cd8ca57a2faaron /* There's not much else we can do ... we've already sent the headers
785be1b6298010956622771c870ab3cd8ca57a2faaron * to the client.
785be1b6298010956622771c870ab3cd8ca57a2faaron */
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rputs("\n\n[an internal server error occured]\n", r);
785be1b6298010956622771c870ab3cd8ca57a2faaron menu_footer(r);
785be1b6298010956622771c870ab3cd8ca57a2faaron return OK;
785be1b6298010956622771c870ab3cd8ca57a2faaron }
785be1b6298010956622771c870ab3cd8ca57a2faaron return HTTP_INTERNAL_SERVER_ERROR;
785be1b6298010956622771c870ab3cd8ca57a2faaron}
785be1b6298010956622771c870ab3cd8ca57a2faaron
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void register_hooks(apr_pool_t *p)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_hook_handler(imap_handler,NULL,NULL,APR_HOOK_MIDDLE);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
51af95bb51b5084e883bad250b2afa2838e9ceebfieldingmodule AP_MODULE_DECLARE_DATA imap_module =
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding STANDARD20_MODULE_STUFF,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding create_imap_dir_config, /* dir config creater */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding merge_imap_dir_configs, /* dir merger --- default is to override */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding NULL, /* server config */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding NULL, /* merge server config */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding imap_cmds, /* command apr_table_t */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding register_hooks /* register hooks */
dad234382d8424e1c5a30af2838e172aec9d6d1bdreid};
382fa07a63096c4a1aabfed36433ea5ac9c40ad0trawick