mod_imap.c revision 89cbb0132036aa1bd2bac7dd962a8c43409de0b4
08cb74ca432a8c24e39f17dedce527e6a47b8001jerenkrantz/* ====================================================================
08cb74ca432a8c24e39f17dedce527e6a47b8001jerenkrantz * The Apache Software License, Version 1.1
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * reserved.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Redistribution and use in source and binary forms, with or without
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * modification, are permitted provided that the following conditions
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * 1. Redistributions of source code must retain the above copyright
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * notice, this list of conditions and the following disclaimer.
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.
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 * 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.
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 * 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 * 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
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 * 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
785be1b6298010956622771c870ab3cd8ca57a2faaron * Contributors to this code include:
785be1b6298010956622771c870ab3cd8ca57a2faaron * Kevin Hughes, kevinh@pulua.hcc.hawaii.edu
785be1b6298010956622771c870ab3cd8ca57a2faaron * Eric Haines, erich@eye.com
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
f4b96a996afbc46872f57ad1450e6ee1c8f13707jorton * Randy Terbush, randy@zyzzyva.com
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * port to Apache module format, "base_uri" and support for relative URLs
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 * 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 * Mark Cox, mark@ukweb.com, Allow relative URLs even when no base specified
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingtypedef struct {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void *create_imap_dir_config(apr_pool_t *p, char *dummy)
785be1b6298010956622771c870ab3cd8ca57a2faaron (imap_conf_rec *) apr_palloc(p, sizeof(imap_conf_rec));
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawickstatic void *merge_imap_dir_configs(apr_pool_t *p, void *basev, void *addv)
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick imap_conf_rec *new = (imap_conf_rec *) apr_pcalloc(p, sizeof(imap_conf_rec));
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick new->imap_menu = add->imap_menu ? add->imap_menu : base->imap_menu;
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames new->imap_default = add->imap_default ? add->imap_default
e160b861b50a3a8dcc013b8cd3ef849fe777e52fgregames new->imap_base = add->imap_base ? add->imap_base : base->imap_base;
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick (void *) XtOffsetOf(imap_conf_rec, imap_menu), OR_INDEXES,
560f6ac786d611b858b2bad932713d9e971f0716trawick "the type of menu generated: none, formatted, semiformatted, "
560f6ac786d611b858b2bad932713d9e971f0716trawick "unformatted"),
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick (void *) XtOffsetOf(imap_conf_rec, imap_default), OR_INDEXES,
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick "the action taken if no match: error, nocontent, referer, "
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick "menu, URL"),
7bf77d70b6830636bc36e6b76a228c301be23ff7brianp (void *) XtOffsetOf(imap_conf_rec, imap_base), OR_INDEXES,
7bf77d70b6830636bc36e6b76a228c301be23ff7brianp "the base for all URL's: map, referer, URL (or start of)"),
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawickstatic int pointinrect(const double point[2], double coords[MAXVERTS][2])
97c78987224dcd037076d393aad1867c26b2c8cftrawickstatic int pointincircle(const double point[2], double coords[MAXVERTS][2])
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 radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y]))
97c78987224dcd037076d393aad1867c26b2c8cftrawick + ((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define fmin(a,b) (((a)>(b))?(b):(a))
785be1b6298010956622771c870ab3cd8ca57a2faaron#define fmax(a,b) (((a)>(b))?(a):(b))
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic int pointinpoly(const double point[2], double pgon[MAXVERTS][2])
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding for (numverts = 0; pgon[numverts][X] != -1 && numverts < MAXVERTS;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* just counting the vertexes */
785be1b6298010956622771c870ab3cd8ca57a2faaron for (i = 0; i < numverts; i++) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding double d=(y - y1) * (x2 - x1) - (x - x1) * (y2 - y1);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic int is_closer(const double point[2], double coords[MAXVERTS][2],
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (0); /* don't mess around with negative coordinates */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (1); /* if this is the first point or is the closest yet
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding set 'closest' equal to this distance^2 */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (0); /* if it's not the first or closest */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding double x_coord = -1; /* -1 is returned if no coordinate is given */
785be1b6298010956622771c870ab3cd8ca57a2faaron while (*args && !apr_isdigit(*args) && *args != ',') {
785be1b6298010956622771c870ab3cd8ca57a2faaron a comma or end */
785be1b6298010956622771c870ab3cd8ca57a2faaron or if no args was given */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding start_of_y = ap_strchr_c(args, ','); /* the comma */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding start_of_y++; /* start looking at the character after
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding the comma */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding past the end */
17f3ba69f65182426ad4e568bb2d6f192ccd2ed5trawick no comma was found in args */
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 * Otherwise set *quoted_part to NULL, and leave *string alone.
1ccd992d37d62c8cb2056126f2234f64ec189bfddougmstatic void read_quoted(char **string, char **quoted_part)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* assume there's no quoted part */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (*strp == '"') { /* if that character is a double quote */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *quoted_part = strp; /* note where the quoted part begins */
a7ed9c525f9460187f327cea953bf90ecf1bdc51gstein * returns the mapped URL or NULL.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic char *imap_url(request_rec *r, const char *base, const char *value)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* translates a value into a URL. */
8fd7c5046d164fb0959222497e5925dfc6a52ff3trawick if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) {
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 /* 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 null the value */
6b38fca3ec543a0f72efd5683e91a0b30fc752d1trawick string_pos_const++; /* go along the URL from the map
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding until a non-letter */
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); /* no base: use what is given */
785be1b6298010956622771c870ab3cd8ca57a2faaron /* no base, no value: pick a simple default */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf /* must be a relative URL to be combined with base */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf if (ap_strchr_c(base, '/') == NULL && (!strncmp(value, "../", 3)
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf string_pos += 2; /* if there are two slashes, jump over them */
785be1b6298010956622771c870ab3cd8ca57a2faaron if (*string_pos == '/') { /* the first single slash */
785be1b6298010956622771c870ab3cd8ca57a2faaron } /* if the URL from the map starts from root,
785be1b6298010956622771c870ab3cd8ca57a2faaron end the base URL string at the first single
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf the directory portion */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf string_pos */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf } /* but if the map url is relative, leave the
066877f1a045103acfdd376d48cdd473c33f409bdougm slash on the base (if there is one) */
785be1b6298010956622771c870ab3cd8ca57a2faaron string_pos++; /* until we get to the end of my_base without
785be1b6298010956622771c870ab3cd8ca57a2faaron finding a slash by itself */
785be1b6298010956622771c870ab3cd8ca57a2faaron while (!strncmp(value, "../", 3) || !strcmp(value, "..")) {
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 if (clen == 0) {
785be1b6298010956622771c870ab3cd8ca57a2faaron value += 2; /* jump over the '..' that we found in the
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strncmp(value, "/../", 4) || !strcmp(value, "/..")) {
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf to do. This way, we leave the starting
785be1b6298010956622771c870ab3cd8ca57a2faaron '/' on value after the last '..', but get
785be1b6298010956622771c870ab3cd8ca57a2faaron rid of it otherwise */
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf } /* by this point, value does not start
b88f887ed5554d9050d97f9a56a89ae62bdbd906fanf with '..' */
785be1b6298010956622771c870ab3cd8ca57a2faaron /* they actually requested an error! */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* tell the client to keep the page it has */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* must be a URL, so redirect to it */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_table_setn(r->headers_out, "Location", redirect);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_rvputs(r, DOCTYPE_HTML_3_2, "<html><head>\n<title>Menu for ", r->uri,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_rvputs(r, "<h1>Menu for ", r->uri, "</h1>\n<hr />\n\n", NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic void menu_comment(request_rec *r, char *menu, char *comment)
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rputs("\n", r); /* print just a newline if 'formatted' */
785be1b6298010956622771c870ab3cd8ca57a2faaron return; /* comments are ignored in the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding 'formatted' form */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void menu_default(request_rec *r, char *menu, char *href, char *text)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return; /* don't print such lines, these aren't
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding really href's */
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
900127764fb985c340ee4979cac97146a330c694trawick ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaronstatic void menu_directive(request_rec *r, char *menu, char *href, char *text)
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
785be1b6298010956622771c870ab3cd8ca57a2faaron return; /* don't print such lines, as this isn't
785be1b6298010956622771c870ab3cd8ca57a2faaron really an href */
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rputs("\n\n</body>\n</html>\n", r); /* finish the menu */
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick if (r->method_number != M_GET || (strcmp(r->handler,IMAP_MAGIC_TYPE)
785be1b6298010956622771c870ab3cd8ca57a2faaron icr = ap_get_module_config(r->per_dir_config, &imap_module);
785be1b6298010956622771c870ab3cd8ca57a2faaron imap_menu = icr->imap_menu ? icr->imap_menu : IMAP_MENU_DEFAULT;
066877f1a045103acfdd376d48cdd473c33f409bdougm imap_base = icr->imap_base ? icr->imap_base : IMAP_BASE_DEFAULT;
8a261a9f7d18d1e862d63f68e93f288d3e1f0d94trawick status = ap_pcfg_openfile(&imap, r->pool, r->filename);
785be1b6298010956622771c870ab3cd8ca57a2faaron base = imap_url(r, NULL, imap_base); /* set base according
785be1b6298010956622771c870ab3cd8ca57a2faaron to default */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding mapdflt = imap_url(r, NULL, imap_default); /* and default to
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding global default */
bbbf8f0e622ad5a37ccf70f35660fc755575278arbb /* if either is -1 or if both are zero (new Lynx) */
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm /* we don't have valid coordinates */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding showmenu = 1; /* show the menu _unless_ ImapMenu is
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding 'none' or 'no' */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding we're going to */
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf } /* blank lines and comments are ignored
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick if we aren't printing a menu */
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf /* find the first two space delimited fields, recall that
9c518951a46c7a12e20876827bb2e84ef87d3c11jerenkrantz * ap_cfg_getline has removed leading/trailing whitespace.
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
0db1b9810f06c0e3c537e0e0dfbc30160c308526trawick while (*string_pos && !apr_isspace(*string_pos)) { /* past directive */
644be6f54749d2d9950d2c4d2ac448f7af016d26martin while(*string_pos && apr_isspace(*string_pos)) { /* past whitespace */
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick while (*string_pos && !apr_isspace(*string_pos)) { /* past value */
3c8b3749225668f06abbb2b023a833a2cef46931brianp /* end of input, don't advance past it */
785be1b6298010956622771c870ab3cd8ca57a2faaron if (!strncasecmp(directive, "base", 4)) { /* base, base_uri */
785be1b6298010956622771c870ab3cd8ca57a2faaron continue; /* base is never printed to a menu */
3c48210f662a2ab8ed90708989e04c09aae33cb2trawick if (!strcasecmp(directive, "default")) { /* default */
3926b3b7716683a1241c1ff6f8dd2f9c5073665afanf if (showmenu) { /* print the default if there's a menu */
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 */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding while (apr_isdigit(*string_pos)) { /* and the 1st number */
785be1b6298010956622771c870ab3cd8ca57a2faaron while (apr_isspace(*string_pos)) { /* past any more whitespace */
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 pointarray[vertex][X] = -1; /* signals the end of vertices */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding read_quoted(&string_pos, &href_text); /* href text could
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding be here instead */
3d96ee83babeec32482c9082c9426340cee8c44dwrowe /* note that we don't make it past here if we are making a menu */
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 if (!strcasecmp(directive, "circle")) { /* circle */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (is_closer(testpoint, pointarray, &closest_yet)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding } /* move on to next line whether it's
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding closest or not */
dad234382d8424e1c5a30af2838e172aec9d6d1bdreid } /* nothing matched, so we get another line! */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_cfg_closefile(imap); /* we are done with the map file; close it */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding menu_footer(r); /* finish the menu and we are done */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (closest) { /* if a 'point' directive has been seen */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (mapdflt) { /* a default should be defined, even if
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding only 'nocontent' */
785be1b6298010956622771c870ab3cd8ca57a2faaron return HTTP_INTERNAL_SERVER_ERROR; /* If we make it this far,
785be1b6298010956622771c870ab3cd8ca57a2faaron we failed. They lose! */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
785be1b6298010956622771c870ab3cd8ca57a2faaron "map file %s, line %d syntax error: requires at "
785be1b6298010956622771c870ab3cd8ca57a2faaron /* fall through */
785be1b6298010956622771c870ab3cd8ca57a2faaron /* There's not much else we can do ... we've already sent the headers
785be1b6298010956622771c870ab3cd8ca57a2faaron * to the client.
785be1b6298010956622771c870ab3cd8ca57a2faaron ap_rputs("\n\n[an internal server error occured]\n", r);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_hook_handler(imap_handler,NULL,NULL,APR_HOOK_MIDDLE);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding merge_imap_dir_configs, /* dir merger --- default is to override */