/* ====================================================================
 * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * 4. The names "Apache Server" and "Apache Group" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
 * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Group and was originally based
 * on public domain software written at the National Center for
 * Supercomputing Applications, University of Illinois, Urbana-Champaign.
 * For more information on the Apache Group and the Apache HTTP server
 * project, please see <http://www.apache.org/>.
 *
 */

/*
 * This imagemap module started as a port of the original imagemap.c
 * written by Rob McCool (11/13/93 robm@ncsa.uiuc.edu).
 * This version includes the mapping algorithms found in version 1.3
 * of imagemap.c.
 *
 * Contributors to this code include:
 *
 * Kevin Hughes, kevinh@pulua.hcc.hawaii.edu
 *
 * Eric Haines, erich@eye.com
 * "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
 *
 * Randy Terbush, randy@zyzzyva.com
 * port to Apache module format, "base_uri" and support for relative URLs
 * 
 * James H. Cloos, Jr., cloos@jhcloos.com
 * Added point datatype, using code in NCSA's version 1.8 imagemap.c
 * program, as distributed with version 1.4.1 of their server.
 * The point code is originally added by Craig Milo Rogers, Rogers@ISI.Edu
 *
 * Nathan Kurz, nate@tripod.com
 * Rewrite/reorganization.  New handling of default, base and relative URLs.  
 * New Configuration directives:
 *    ImapMenu {none, formatted, semiformatted, unformatted}
 *    ImapDefault {error, nocontent, referer, menu, URL}
 *    ImapBase {map, referer, URL}
 * Support for creating non-graphical menu added.  (backwards compatible):
 *    Old:  directive URL [x,y ...]
 *    New:  directive URL "Menu text" [x,y ...]
 *     or:  directive URL x,y ... "Menu text"
 * Map format and menu concept courtesy Joshua Bell, jsbell@acs.ucalgary.ca.
 *
 * Mark Cox, mark@ukweb.com, Allow relative URLs even when no base specified
 */

#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_main.h"
#include "http_log.h"
#include "util_script.h"
#ifdef HAVE_STRING_H
#include <string.h>
#endif

#define IMAP_MAGIC_TYPE "application/x-httpd-imap"
#define MAXVERTS 100
#define X 0
#define Y 1

#define IMAP_MENU_DEFAULT "formatted"
#define IMAP_DEFAULT_DEFAULT "nocontent"
#define IMAP_BASE_DEFAULT "map"

#ifdef SUNOS4
double strtod();                /* SunOS needed this */
#endif

module MODULE_VAR_EXPORT imap_module;

typedef struct {
    char *imap_menu;
    char *imap_default;
    char *imap_base;
} imap_conf_rec;

static void *create_imap_dir_config(ap_context_t *p, char *dummy)
{
    imap_conf_rec *icr =
    (imap_conf_rec *) ap_palloc(p, sizeof(imap_conf_rec));

    icr->imap_menu = NULL;
    icr->imap_default = NULL;
    icr->imap_base = NULL;

    return icr;
}

static void *merge_imap_dir_configs(ap_context_t *p, void *basev, void *addv)
{
    imap_conf_rec *new = (imap_conf_rec *) ap_pcalloc(p, sizeof(imap_conf_rec));
    imap_conf_rec *base = (imap_conf_rec *) basev;
    imap_conf_rec *add = (imap_conf_rec *) addv;

    new->imap_menu = add->imap_menu ? add->imap_menu : base->imap_menu;
    new->imap_default = add->imap_default ? add->imap_default
                                          : base->imap_default;
    new->imap_base = add->imap_base ? add->imap_base : base->imap_base;

    return new;
}


static const command_rec imap_cmds[] =
{
    {"ImapMenu", ap_set_string_slot,
     (void *) XtOffsetOf(imap_conf_rec, imap_menu), OR_INDEXES, TAKE1,
 "the type of menu generated: none, formatted, semiformatted, unformatted"},
    {"ImapDefault", ap_set_string_slot,
     (void *) XtOffsetOf(imap_conf_rec, imap_default), OR_INDEXES, TAKE1,
     "the action taken if no match: error, nocontent, referer, menu, URL"},
    {"ImapBase", ap_set_string_slot,
     (void *) XtOffsetOf(imap_conf_rec, imap_base), OR_INDEXES, TAKE1,
     "the base for all URL's: map, referer, URL (or start of)"},
    {NULL}
};

static int pointinrect(const double point[2], double coords[MAXVERTS][2])
{
    double max[2], min[2];
    if (coords[0][X] > coords[1][X]) {
        max[0] = coords[0][X];
        min[0] = coords[1][X];
    }
    else {
        max[0] = coords[1][X];
        min[0] = coords[0][X];
    }

    if (coords[0][Y] > coords[1][Y]) {
        max[1] = coords[0][Y];
        min[1] = coords[1][Y];
    }
    else {
        max[1] = coords[1][Y];
        min[1] = coords[0][Y];
    }

    return ((point[X] >= min[0] && point[X] <= max[0]) &&
            (point[Y] >= min[1] && point[Y] <= max[1]));
}

static int pointincircle(const double point[2], double coords[MAXVERTS][2])
{
    double radius1, radius2;

    radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] - coords[1][Y]))
        + ((coords[0][X] - coords[1][X]) * (coords[0][X] - coords[1][X]));

    radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y]))
        + ((coords[0][X] - point[X]) * (coords[0][X] - point[X]));

    return (radius2 <= radius1);
}

#define fmin(a,b) (((a)>(b))?(b):(a))
#define fmax(a,b) (((a)>(b))?(a):(b))

static int pointinpoly(const double point[2], double pgon[MAXVERTS][2])
{
    int i, numverts, crossings = 0;
    double x = point[X], y = point[Y];

    for (numverts = 0; pgon[numverts][X] != -1 && numverts < MAXVERTS;
	numverts++) {
	/* just counting the vertexes */
    }

    for (i = 0; i < numverts; i++) {
        double x1=pgon[i][X];
        double y1=pgon[i][Y];
        double x2=pgon[(i + 1) % numverts][X];
        double y2=pgon[(i + 1) % numverts][Y];
        double d=(y - y1) * (x2 - x1) - (x - x1) * (y2 - y1);

        if ((y1 >= y) != (y2 >= y)) {
	    crossings +=y2 - y1 >= 0 ? d >= 0 : d <= 0;
	}
        if (!d && fmin(x1,x2) <= x && x <= fmax(x1,x2)
	    && fmin(y1,y2) <= y && y <= fmax(y1,y2)) {
	    return 1;
	}
    }
    return crossings & 0x01;
}


static int is_closer(const double point[2], double coords[MAXVERTS][2],
                     double *closest)
{
    double dist_squared = ((point[X] - coords[0][X])
                           * (point[X] - coords[0][X]))
                          + ((point[Y] - coords[0][Y])
                             * (point[Y] - coords[0][Y]));

    if (point[X] < 0 || point[Y] < 0) {
        return (0);          /* don't mess around with negative coordinates */
    }

    if (*closest < 0 || dist_squared < *closest) {
        *closest = dist_squared;
        return (1);          /* if this is the first point or is the closest yet
                                set 'closest' equal to this distance^2 */
    }

    return (0);              /* if it's not the first or closest */

}

static double get_x_coord(const char *args)
{
    char *endptr;               /* we want it non-null */
    double x_coord = -1;        /* -1 is returned if no coordinate is given */

    if (args == NULL) {
        return (-1);            /* in case we aren't passed anything */
    }

    while (*args && !ap_isdigit(*args) && *args != ',') {
        args++;                 /* jump to the first digit, but not past
                                   a comma or end */
    }

    x_coord = strtod(args, &endptr);

    if (endptr > args) {        /* if a conversion was made */
        return (x_coord);
    }

    return (-1);                /* else if no conversion was made,
                                   or if no args was given */
}

static double get_y_coord(const char *args)
{
    char *endptr;               /* we want it non-null */
    char *start_of_y = NULL;
    double y_coord = -1;        /* -1 is returned on error */

    if (args == NULL) {
        return (-1);            /* in case we aren't passed anything */
    }

    start_of_y = strchr(args, ',');     /* the comma */

    if (start_of_y) {

        start_of_y++;           /* start looking at the character after
                                   the comma */

        while (*start_of_y && !ap_isdigit(*start_of_y)) {
            start_of_y++;       /* jump to the first digit, but not
                                   past the end */
	}

        y_coord = strtod(start_of_y, &endptr);

        if (endptr > start_of_y) {
            return (y_coord);
	}
    }

    return (-1);                /* if no conversion was made, or
                                   no comma was found in args */
}


/* See if string has a "quoted part", and if so set *quoted_part to
 * the first character of the quoted part, then hammer a \0 onto the
 * trailing quote, and set *string to point at the first character
 * past the second quote.
 *
 * Otherwise set *quoted_part to NULL, and leave *string alone.
 */
static void read_quoted(char **string, char **quoted_part)
{
    char *strp = *string;

    /* assume there's no quoted part */
    *quoted_part = NULL;

    while (ap_isspace(*strp)) {
        strp++;               	/* go along string until non-whitespace */
    }

    if (*strp == '"') {       	/* if that character is a double quote */
        strp++;               	/* step over it */
	*quoted_part = strp;  	/* note where the quoted part begins */

        while (*strp && *strp != '"') {
	    ++strp;		/* skip the quoted portion */
        }

        *strp = '\0';    	/* end the string with a NUL */

        strp++;               	/* step over the last double quote */
	*string = strp;
    }
}

/*
 * returns the mapped URL or NULL.
 */
static char *imap_url(request_rec *r, const char *base, const char *value)
{
/* translates a value into a URL. */
    int slen, clen;
    char *string_pos = NULL;
    const char *string_pos_const = NULL;
    char *directory = NULL;
    const char *referer = NULL;
    char *my_base;

    if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) {
	return ap_construct_url(r->pool, r->uri, r);
    }

    if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) {
        return ap_pstrdup(r->pool, value);      /* these are handled elsewhere,
                                                so just copy them */
    }

    if (!strcasecmp(value, "referer")) {
        referer = ap_table_get(r->headers_in, "Referer");
        if (referer && *referer) {
	    return ap_pstrdup(r->pool, referer);
        }
        else {
	    /* XXX:  This used to do *value = '\0'; ... which is totally bogus
	     * because it hammers the passed in value, which can be a string
             * constant, or part of a config, or whatever.  Total garbage.
             * This works around that without changing the rest of this
             * code much
             */
            value = "";      /* if 'referer' but no referring page,
                                null the value */
        }
    }

    string_pos_const = value;
    while (ap_isalpha(*string_pos_const)) {
	string_pos_const++;           /* go along the URL from the map
                                         until a non-letter */
    }
    if (*string_pos_const == ':') {
	/* if letters and then a colon (like http:) */
	/* it's an absolute URL, so use it! */
	return ap_pstrdup(r->pool, value);
    }

    if (!base || !*base) {
        if (value && *value) {
	    return ap_pstrdup(r->pool, value); /* no base: use what is given */
        }
	/* no base, no value: pick a simple default */
	return ap_construct_url(r->pool, "/", r);
    }

    /* must be a relative URL to be combined with base */
    if (strchr(base, '/') == NULL && (!strncmp(value, "../", 3)
        || !strcmp(value, ".."))) {
        ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
                    "invalid base directive in map file: %s", r->uri);
        return NULL;
    }
    my_base = ap_pstrdup(r->pool, base);
    string_pos = my_base;
    while (*string_pos) {
        if (*string_pos == '/' && *(string_pos + 1) == '/') {
            string_pos += 2;    /* if there are two slashes, jump over them */
            continue;
        }
        if (*string_pos == '/') {       /* the first single slash */
            if (value[0] == '/') {
                *string_pos = '\0';
            }                   /* if the URL from the map starts from root,
                                   end the base URL string at the first single
                                   slash */
            else {
                directory = string_pos;         /* save the start of
                                                   the directory portion */

                string_pos = strrchr(string_pos, '/');  /* now reuse
                                                           string_pos */
                string_pos++;   /* step over that last slash */
                *string_pos = '\0';
            }                   /* but if the map url is relative, leave the
                                   slash on the base (if there is one) */
            break;
        }
        string_pos++;           /* until we get to the end of my_base without
                                   finding a slash by itself */
    }

    while (!strncmp(value, "../", 3) || !strcmp(value, "..")) {

        if (directory && (slen = strlen(directory))) {

            /* for each '..',  knock a directory off the end 
               by ending the string right at the last slash.
               But only consider the directory portion: don't eat
               into the server name.  And only try if a directory
               portion was found */

            clen = slen - 1;

            while ((slen - clen) == 1) {

                if ((string_pos = strrchr(directory, '/'))) {
                    *string_pos = '\0';
		}
                clen = strlen(directory);
                if (clen == 0) {
                    break;
		}
            }

            value += 2;         /* jump over the '..' that we found in the
                                   value */
        }
        else if (directory) {
            ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
                        "invalid directory name in map file: %s", r->uri);
            return NULL;
        }

        if (!strncmp(value, "/../", 4) || !strcmp(value, "/..")) {
            value++;            /* step over the '/' if there are more '..'
                                   to do.  This way, we leave the starting
                                   '/' on value after the last '..', but get
                                   rid of it otherwise */
	}

    }                           /* by this point, value does not start
                                   with '..' */

    if (value && *value) {
	return ap_pstrcat(r->pool, my_base, value, NULL);
    }
    return my_base;
}

static int imap_reply(request_rec *r, char *redirect)
{
    if (!strcasecmp(redirect, "error")) {
        return SERVER_ERROR;    /* they actually requested an error! */
    }
    if (!strcasecmp(redirect, "nocontent")) {
        return HTTP_NO_CONTENT; /* tell the client to keep the page it has */
    }
    if (redirect && *redirect) {
        ap_table_setn(r->headers_out, "Location", redirect);
        return REDIRECT;        /* must be a URL, so redirect to it */
    }
    return SERVER_ERROR;
}

static void menu_header(request_rec *r, char *menu)
{
    r->content_type = "text/html";
    ap_send_http_header(r);


    ap_rvputs(r, DOCTYPE_HTML_3_2, "<html><head>\n<title>Menu for ", r->uri,
           "</title>\n</head><body>\n", NULL);

    if (!strcasecmp(menu, "formatted")) {
        ap_rvputs(r, "<h1>Menu for ", r->uri, "</h1>\n<hr>\n\n", NULL);
    }

    return;
}

static void menu_blank(request_rec *r, char *menu)
{
    if (!strcasecmp(menu, "formatted")) {
        ap_rputs("\n", r);
    }
    if (!strcasecmp(menu, "semiformatted")) {
        ap_rputs("<br>\n", r);
    }
    if (!strcasecmp(menu, "unformatted")) {
        ap_rputs("\n", r);
    }
    return;
}

static void menu_comment(request_rec *r, char *menu, char *comment)
{
    if (!strcasecmp(menu, "formatted")) {
        ap_rputs("\n", r);         /* print just a newline if 'formatted' */
    }
    if (!strcasecmp(menu, "semiformatted") && *comment) {
        ap_rvputs(r, comment, "\n", NULL);
    }
    if (!strcasecmp(menu, "unformatted") && *comment) {
        ap_rvputs(r, comment, "\n", NULL);
    }
    return;                     /* comments are ignored in the
                                   'formatted' form */
}

static void menu_default(request_rec *r, char *menu, char *href, char *text)
{
    if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
        return;                 /* don't print such lines, these aren't
                                   really href's */
    }
    if (!strcasecmp(menu, "formatted")) {
        ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
               "</a></pre>\n", NULL);
    }
    if (!strcasecmp(menu, "semiformatted")) {
        ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
               "</a></pre>\n", NULL);
    }
    if (!strcasecmp(menu, "unformatted")) {
        ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
    }
    return;
}

static void menu_directive(request_rec *r, char *menu, char *href, char *text)
{
    if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
        return;                 /* don't print such lines, as this isn't
                                   really an href */
    }
    if (!strcasecmp(menu, "formatted")) {
        ap_rvputs(r, "<pre>          <a href=\"", href, "\">", text,
               "</a></pre>\n", NULL);
    }
    if (!strcasecmp(menu, "semiformatted")) {
        ap_rvputs(r, "<pre>          <a href=\"", href, "\">", text,
               "</a></pre>\n", NULL);
    }
    if (!strcasecmp(menu, "unformatted")) {
        ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
    }
    return;
}

static void menu_footer(request_rec *r)
{
    ap_rputs("\n\n</body>\n</html>\n", r);         /* finish the menu */
}

static int imap_handler(request_rec *r)
{
    char input[MAX_STRING_LEN];
    char *directive;
    char *value;
    char *href_text;
    char *base;
    char *redirect;
    char *mapdflt;
    char *closest = NULL;
    double closest_yet = -1;
    ap_status_t status;

    double testpoint[2];
    double pointarray[MAXVERTS + 1][2];
    int vertex;

    char *string_pos;
    int showmenu = 0;

    imap_conf_rec *icr = ap_get_module_config(r->per_dir_config, &imap_module);

    char *imap_menu = icr->imap_menu ? icr->imap_menu : IMAP_MENU_DEFAULT;
    char *imap_default = icr->imap_default
			    ?  icr->imap_default : IMAP_DEFAULT_DEFAULT;
    char *imap_base = icr->imap_base ? icr->imap_base : IMAP_BASE_DEFAULT;

    configfile_t *imap; 

    if (r->method_number != M_GET) {
	return DECLINED;
    }

    status = ap_pcfg_openfile(&imap, r->pool, r->filename);

    if (status != APR_SUCCESS) {
        return NOT_FOUND;
    }

    base = imap_url(r, NULL, imap_base);         /* set base according
                                                    to default */
    if (!base) {
	return HTTP_INTERNAL_SERVER_ERROR;
    }
    mapdflt = imap_url(r, NULL, imap_default);   /* and default to
                                                    global default */
    if (!mapdflt) {
	return HTTP_INTERNAL_SERVER_ERROR;
    }

    testpoint[X] = get_x_coord(r->args);
    testpoint[Y] = get_y_coord(r->args);

    if ((testpoint[X] == -1 || testpoint[Y] == -1) ||
        (testpoint[X] == 0 && testpoint[Y] == 0)) {
        /* if either is -1 or if both are zero (new Lynx) */
        /* we don't have valid coordinates */
        testpoint[X] = -1;
        testpoint[Y] = -1;
        if (strncasecmp(imap_menu, "none", 2)) {
            showmenu = 1;       /* show the menu _unless_ ImapMenu is
                                   'none' or 'no' */
	}
    }

    if (showmenu) {             /* send start of imagemap menu if
                                   we're going to */
        menu_header(r, imap_menu);
    }

    while (!ap_cfg_getline(input, sizeof(input), imap)) {
        if (!input[0]) {
            if (showmenu) {
                menu_blank(r, imap_menu);
            }
            continue;
        }

        if (input[0] == '#') {
            if (showmenu) {
                menu_comment(r, imap_menu, input + 1);
            }
            continue;
        }                       /* blank lines and comments are ignored
                                   if we aren't printing a menu */

	/* find the first two space delimited fields, recall that
	 * ap_cfg_getline has removed leading/trailing whitespace.
	 *
	 * note that we're tokenizing as we go... if we were to use the
	 * ap_getword() class of functions we would end up allocating extra
	 * memory for every line of the map file
	 */
        string_pos = input;
	if (!*string_pos) {		/* need at least two fields */
	    goto need_2_fields;
	}

	directive = string_pos;
	while (*string_pos && !ap_isspace(*string_pos)) {	/* past directive */
	    ++string_pos;
	}
	if (!*string_pos) {		/* need at least two fields */
	    goto need_2_fields;
	}
	*string_pos++ = '\0';

	if (!*string_pos) {		/* need at least two fields */
	    goto need_2_fields;
	}
	while(*string_pos && ap_isspace(*string_pos)) { /* past whitespace */
	    ++string_pos;
	}

	value = string_pos;
	while (*string_pos && !ap_isspace(*string_pos)) {	/* past value */
	    ++string_pos;
	}
	if (ap_isspace(*string_pos)) {
	    *string_pos++ = '\0';
	}
	else {
	    /* end of input, don't advance past it */
	    *string_pos = '\0';
	}

        if (!strncasecmp(directive, "base", 4)) {       /* base, base_uri */
            base = imap_url(r, NULL, value);
	    if (!base) {
		goto menu_bail;
	    }
            continue;           /* base is never printed to a menu */
        }

        read_quoted(&string_pos, &href_text);

        if (!strcasecmp(directive, "default")) {        /* default */
            mapdflt = imap_url(r, NULL, value);
	    if (!mapdflt) {
		goto menu_bail;
	    }
            if (showmenu) {     /* print the default if there's a menu */
                redirect = imap_url(r, base, mapdflt);
		if (!redirect) {
		    goto menu_bail;
		}
                menu_default(r, imap_menu, redirect,
                             href_text ? href_text : mapdflt);
            }
            continue;
        }

        vertex = 0;
        while (vertex < MAXVERTS &&
               sscanf(string_pos, "%lf%*[, ]%lf",
                      &pointarray[vertex][X], &pointarray[vertex][Y]) == 2) {
            /* Now skip what we just read... we can't use ANSIism %n */
            while (ap_isspace(*string_pos)) {      /* past whitespace */
                string_pos++;
	    }
            while (ap_isdigit(*string_pos)) {      /* and the 1st number */
                string_pos++;
	    }
            string_pos++;       /* skip the ',' */
            while (ap_isspace(*string_pos)) {      /* past any more whitespace */
                string_pos++;
	    }
            while (ap_isdigit(*string_pos)) {      /* 2nd number */
                string_pos++;
	    }
            vertex++;
        }                       /* so long as there are more vertices to
                                   read, and we have room, read them in.
                                   We start where we left off of the last
                                   sscanf, not at the beginning. */

        pointarray[vertex][X] = -1;     /* signals the end of vertices */

        if (showmenu) {
	    if (!href_text) {
		read_quoted(&string_pos, &href_text);     /* href text could
                                                             be here instead */
	    }
            redirect = imap_url(r, base, value);
	    if (!redirect) {
		goto menu_bail;
	    }
            menu_directive(r, imap_menu, redirect,
                           href_text ? href_text : value);
            continue;
        }
        /* note that we don't make it past here if we are making a menu */

        if (testpoint[X] == -1 || pointarray[0][X] == -1) {
            continue;           /* don't try the following tests if testpoints
                                   are invalid, or if there are no
                                   coordinates */
	}

        if (!strcasecmp(directive, "poly")) {   /* poly */

            if (pointinpoly(testpoint, pointarray)) {
		ap_cfg_closefile(imap);
                redirect = imap_url(r, base, value);
		if (!redirect) {
		    return HTTP_INTERNAL_SERVER_ERROR;
		}
                return (imap_reply(r, redirect));
            }
            continue;
        }

        if (!strcasecmp(directive, "circle")) {         /* circle */

            if (pointincircle(testpoint, pointarray)) {
		ap_cfg_closefile(imap);
                redirect = imap_url(r, base, value);
		if (!redirect) {
		    return HTTP_INTERNAL_SERVER_ERROR;
		}
                return (imap_reply(r, redirect));
            }
            continue;
        }

        if (!strcasecmp(directive, "rect")) {   /* rect */

            if (pointinrect(testpoint, pointarray)) {
		ap_cfg_closefile(imap);
                redirect = imap_url(r, base, value);
		if (!redirect) {
		    return HTTP_INTERNAL_SERVER_ERROR;
		}
                return (imap_reply(r, redirect));
            }
            continue;
        }

        if (!strcasecmp(directive, "point")) {  /* point */

            if (is_closer(testpoint, pointarray, &closest_yet)) {
		closest = ap_pstrdup(r->pool, value);
            }

            continue;
        }                       /* move on to next line whether it's
                                   closest or not */

    }                           /* nothing matched, so we get another line! */

    ap_cfg_closefile(imap);        /* we are done with the map file; close it */

    if (showmenu) {
        menu_footer(r);         /* finish the menu and we are done */
        return OK;
    }

    if (closest) {             /* if a 'point' directive has been seen */
        redirect = imap_url(r, base, closest);
	if (!redirect) {
	    return HTTP_INTERNAL_SERVER_ERROR;
	}
        return (imap_reply(r, redirect));
    }

    if (mapdflt) {             /* a default should be defined, even if
                                  only 'nocontent' */
        redirect = imap_url(r, base, mapdflt);
	if (!redirect) {
	    return HTTP_INTERNAL_SERVER_ERROR;
	}
        return (imap_reply(r, redirect));
    }

    return HTTP_INTERNAL_SERVER_ERROR;        /* If we make it this far,
                                                 we failed. They lose! */

need_2_fields:
    ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
		"map file %s, line %d syntax error: requires at "
                "least two fields", r->uri, imap->line_number);
    /* fall through */
menu_bail:
    ap_cfg_closefile(imap);
    if (showmenu) {
	/* There's not much else we can do ... we've already sent the headers
	 * to the client.
	 */
	ap_rputs("\n\n[an internal server error occured]\n", r);
	menu_footer(r);
	return OK;
    }
    return HTTP_INTERNAL_SERVER_ERROR;
}


static const handler_rec imap_handlers[] =
{
    {IMAP_MAGIC_TYPE, imap_handler},
    {"imap-file", imap_handler},
    {NULL}
};

module MODULE_VAR_EXPORT imap_module =
{
    STANDARD20_MODULE_STUFF,
    create_imap_dir_config,     /* dir config creater */
    merge_imap_dir_configs,     /* dir merger --- default is to override */
    NULL,                       /* server config */
    NULL,                       /* merge server config */
    imap_cmds,                  /* command ap_table_t */
    imap_handlers,              /* handlers */
    NULL                        /* register hooks */
};
