mod_imap.c revision fc9b2e8809c305f340d86a789566f8abb1ca8a19
842ae4bd224140319ae7feec1872b93dfd491143fielding/* ====================================================================
842ae4bd224140319ae7feec1872b93dfd491143fielding * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
842ae4bd224140319ae7feec1872b93dfd491143fielding * Redistribution and use in source and binary forms, with or without
842ae4bd224140319ae7feec1872b93dfd491143fielding * modification, are permitted provided that the following conditions
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * 1. Redistributions of source code must retain the above copyright
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * notice, this list of conditions and the following disclaimer.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * 2. Redistributions in binary form must reproduce the above copyright
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * notice, this list of conditions and the following disclaimer in
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * the documentation and/or other materials provided with the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * distribution.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * 3. All advertising materials mentioning features or use of this
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * software must display the following acknowledgment:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * "This product includes software developed by the Apache Group
e8f95a682820a599fe41b22977010636be5c2717jim * for use in the Apache HTTP server project (http://www.apache.org/)."
e8f95a682820a599fe41b22977010636be5c2717jim * 4. The names "Apache Server" and "Apache Group" must not be used to
1747d30b98aa1bdbc43994c02cd46ab4cb9319e4fielding * endorse or promote products derived from this software without
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * prior written permission. For written permission, please contact
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * apache@apache.org.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * 5. Products derived from this software may not be called "Apache"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * nor may "Apache" appear in their names without prior written
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * permission of the Apache Group.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * 6. Redistributions of any form whatsoever must retain the following
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * acknowledgment:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * "This product includes software developed by the Apache Group
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * for use in the Apache HTTP server project (http://www.apache.org/)."
5c0419d51818eb02045cf923a9fe456127a44c60wrowe * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
d266c3777146d36a4c23c17aad6f153aebea1bf4jorton * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * OF THE POSSIBILITY OF SUCH DAMAGE.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * ====================================================================
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * This software consists of voluntary contributions made by many
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * individuals on behalf of the Apache Group and was originally based
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * on public domain software written at the National Center for
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * Supercomputing Applications, University of Illinois, Urbana-Champaign.
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * For more information on the Apache Group and the Apache HTTP server
22f8da8087791fcb95b836c8a81937c5a9bba202bnicholes * project, please see <http://www.apache.org/>.
0568280364eb026393be492ebc732795c4934643jorton * This imagemap module started as a port of the original imagemap.c
0568280364eb026393be492ebc732795c4934643jorton * written by Rob McCool (11/13/93 robm@ncsa.uiuc.edu).
0568280364eb026393be492ebc732795c4934643jorton * This version includes the mapping algorithms found in version 1.3
0568280364eb026393be492ebc732795c4934643jorton * Contributors to this code include:
0568280364eb026393be492ebc732795c4934643jorton * Kevin Hughes, kevinh@pulua.hcc.hawaii.edu
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Eric Haines, erich@eye.com
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener * "macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Randy Terbush, randy@zyzzyva.com
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * port to Apache module format, "base_uri" and support for relative URLs
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * James H. Cloos, Jr., cloos@jhcloos.com
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Added point datatype, using code in NCSA's version 1.8 imagemap.c
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * program, as distributed with version 1.4.1 of their server.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * The point code is originally added by Craig Milo Rogers, Rogers@ISI.Edu
796e4a7141265d8ed7036e4628161c6eafb2a789jorton * Nathan Kurz, nate@tripod.com
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Rewrite/reorganization. New handling of default, base and relative URLs.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * New Configuration directives:
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * ImapMenu {none, formatted, semiformatted, unformatted}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * ImapDefault {error, nocontent, referer, menu, URL}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * ImapBase {map, referer, URL}
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Support for creating non-graphical menu added. (backwards compatible):
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Old: directive URL [x,y ...]
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * New: directive URL "Menu text" [x,y ...]
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * or: directive URL x,y ... "Menu text"
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Map format and menu concept courtesy Joshua Bell, jsbell@acs.ucalgary.ca.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * Mark Cox, mark@ukweb.com, Allow relative URLs even when no base specified
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholestypedef struct {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void *create_imap_dir_config(ap_context_t *p, char *dummy)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (imap_conf_rec *) ap_palloc(p, sizeof(imap_conf_rec));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void *merge_imap_dir_configs(ap_context_t *p, void *basev, void *addv)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes imap_conf_rec *new = (imap_conf_rec *) ap_pcalloc(p, sizeof(imap_conf_rec));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes new->imap_menu = add->imap_menu ? add->imap_menu : base->imap_menu;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes new->imap_default = add->imap_default ? add->imap_default
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes new->imap_base = add->imap_base ? add->imap_base : base->imap_base;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener (void *) XtOffsetOf(imap_conf_rec, imap_menu), OR_INDEXES, TAKE1,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes "the type of menu generated: none, formatted, semiformatted, unformatted"},
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (void *) XtOffsetOf(imap_conf_rec, imap_default), OR_INDEXES, TAKE1,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes "the action taken if no match: error, nocontent, referer, menu, URL"},
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes (void *) XtOffsetOf(imap_conf_rec, imap_base), OR_INDEXES, TAKE1,
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener "the base for all URL's: map, referer, URL (or start of)"},
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic int pointinrect(const double point[2], double coords[MAXVERTS][2])
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return ((point[X] >= min[0] && point[X] <= max[0]) &&
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic int pointincircle(const double point[2], double coords[MAXVERTS][2])
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes radius1 = ((coords[0][Y] - coords[1][Y]) * (coords[0][Y] - coords[1][Y]))
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes + ((coords[0][X] - coords[1][X]) * (coords[0][X] - coords[1][X]));
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes radius2 = ((coords[0][Y] - point[Y]) * (coords[0][Y] - point[Y]))
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes + ((coords[0][X] - point[X]) * (coords[0][X] - point[X]));
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes#define fmin(a,b) (((a)>(b))?(b):(a))
e8f95a682820a599fe41b22977010636be5c2717jim#define fmax(a,b) (((a)>(b))?(a):(b))
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovenerstatic int pointinpoly(const double point[2], double pgon[MAXVERTS][2])
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener for (numverts = 0; pgon[numverts][X] != -1 && numverts < MAXVERTS;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener /* just counting the vertexes */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener for (i = 0; i < numverts; i++) {
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener double d=(y - y1) * (x2 - x1) - (x - x1) * (y2 - y1);
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovenerstatic int is_closer(const double point[2], double coords[MAXVERTS][2],
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener return (0); /* don't mess around with negative coordinates */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener return (1); /* if this is the first point or is the closest yet
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener set 'closest' equal to this distance^2 */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener return (0); /* if it's not the first or closest */
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener double x_coord = -1; /* -1 is returned if no coordinate is given */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return (-1); /* in case we aren't passed anything */
b08925593f214f621161742925dcf074a8047e0acovener a comma or end */
3dfeb02cfb853d8717ca0cc259b59fea610173f5bnicholes if (endptr > args) { /* if a conversion was made */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes or if no args was given */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes double y_coord = -1; /* -1 is returned on error */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return (-1); /* in case we aren't passed anything */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes start_of_y++; /* start looking at the character after
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes the comma */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes past the end */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes no comma was found in args */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes/* See if string has a "quoted part", and if so set *quoted_part to
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * the first character of the quoted part, then hammer a \0 onto the
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * trailing quote, and set *string to point at the first character
54d22ed1c429b903b029bbd62621f11a9e286137minfrin * past the second quote.
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * Otherwise set *quoted_part to NULL, and leave *string alone.
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholesstatic void read_quoted(char **string, char **quoted_part)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* assume there's no quoted part */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes strp++; /* go along string until non-whitespace */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (*strp == '"') { /* if that character is a double quote */
7add8f7fb048534390571801b7794f71cd9e127abnicholes *quoted_part = strp; /* note where the quoted part begins */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * returns the mapped URL or NULL.
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholesstatic char *imap_url(request_rec *r, const char *base, const char *value)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes/* translates a value into a URL. */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) {
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) {
ebe5305f8b22507374358f32b74d12fb50c05a25covener return ap_pstrdup(r->pool, value); /* these are handled elsewhere,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes so just copy them */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* XXX: This used to do *value = '\0'; ... which is totally bogus
e8f95a682820a599fe41b22977010636be5c2717jim * because it hammers the passed in value, which can be a string
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * constant, or part of a config, or whatever. Total garbage.
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes * This works around that without changing the rest of this
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes value = ""; /* if 'referer' but no referring page,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes null the value */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes string_pos_const++; /* go along the URL from the map
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes until a non-letter */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* if letters and then a colon (like http:) */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* it's an absolute URL, so use it! */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes return ap_pstrdup(r->pool, value); /* no base: use what is given */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* no base, no value: pick a simple default */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes /* must be a relative URL to be combined with base */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes if (strchr(base, '/') == NULL && (!strncmp(value, "../", 3)
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes "invalid base directive in map file: %s", r->uri);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (*string_pos == '/' && *(string_pos + 1) == '/') {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes string_pos += 2; /* if there are two slashes, jump over them */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (*string_pos == '/') { /* the first single slash */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes } /* if the URL from the map starts from root,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes end the base URL string at the first single
54d22ed1c429b903b029bbd62621f11a9e286137minfrin the directory portion */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes string_pos = strrchr(string_pos, '/'); /* now reuse
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes string_pos */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes } /* but if the map url is relative, leave the
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes slash on the base (if there is one) */
d330a801b1e5d63a4b8b4fd431542ad0903fd71bbnicholes string_pos++; /* until we get to the end of my_base without
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes finding a slash by itself */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (!strncmp(value, "../", 3) || !strcmp(value, "..")) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* for each '..', knock a directory off the end
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes by ending the string right at the last slash.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes But only consider the directory portion: don't eat
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes into the server name. And only try if a directory
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes portion was found */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (clen == 0) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin value += 2; /* jump over the '..' that we found in the
54d22ed1c429b903b029bbd62621f11a9e286137minfrin ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
54d22ed1c429b903b029bbd62621f11a9e286137minfrin if (!strncmp(value, "/../", 4) || !strcmp(value, "/..")) {
54d22ed1c429b903b029bbd62621f11a9e286137minfrin value++; /* step over the '/' if there are more '..'
54d22ed1c429b903b029bbd62621f11a9e286137minfrin to do. This way, we leave the starting
54d22ed1c429b903b029bbd62621f11a9e286137minfrin '/' on value after the last '..', but get
54d22ed1c429b903b029bbd62621f11a9e286137minfrin rid of it otherwise */
54d22ed1c429b903b029bbd62621f11a9e286137minfrin } /* by this point, value does not start
edc346c3223efd41e6a2057c37cea69744b73dccwrowe with '..' */
54d22ed1c429b903b029bbd62621f11a9e286137minfrinstatic int imap_reply(request_rec *r, char *redirect)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return SERVER_ERROR; /* they actually requested an error! */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return HTTP_NO_CONTENT; /* tell the client to keep the page it has */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_rvputs(r, DOCTYPE_HTML_3_2, "<html><head>\n<title>Menu for ", r->uri,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_rvputs(r, "<h1>Menu for ", r->uri, "</h1>\n<hr>\n\n", NULL);
e8f95a682820a599fe41b22977010636be5c2717jimstatic void menu_comment(request_rec *r, char *menu, char *comment)
e8f95a682820a599fe41b22977010636be5c2717jim ap_rputs("\n", r); /* print just a newline if 'formatted' */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!strcasecmp(menu, "unformatted") && *comment) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return; /* comments are ignored in the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes 'formatted' form */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void menu_default(request_rec *r, char *menu, char *href, char *text)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return; /* don't print such lines, these aren't
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes really href's */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_rvputs(r, "<pre>(Default) <a href=\"", href, "\">", text,
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholesstatic void menu_directive(request_rec *r, char *menu, char *href, char *text)
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!strcasecmp(href, "error") || !strcasecmp(href, "nocontent")) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return; /* don't print such lines, as this isn't
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes really an href */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_rvputs(r, "<pre> <a href=\"", href, "\">", text,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_rvputs(r, "<pre> <a href=\"", href, "\">", text,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_rvputs(r, "<a href=\"", href, "\">", text, "</a>", NULL);
ebe5305f8b22507374358f32b74d12fb50c05a25covener ap_rputs("\n\n</body>\n</html>\n", r); /* finish the menu */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes imap_conf_rec *icr = ap_get_module_config(r->per_dir_config, &imap_module);
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *imap_menu = icr->imap_menu ? icr->imap_menu : IMAP_MENU_DEFAULT;
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes char *imap_base = icr->imap_base ? icr->imap_base : IMAP_BASE_DEFAULT;
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener base = imap_url(r, NULL, imap_base); /* set base according
4e9c24785b525d2956e6e381015c0f2bd0a72f4bcovener to default */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes mapdflt = imap_url(r, NULL, imap_default); /* and default to
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes global default */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* if either is -1 or if both are zero (new Lynx) */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* we don't have valid coordinates */
e8f95a682820a599fe41b22977010636be5c2717jim 'none' or 'no' */
e8f95a682820a599fe41b22977010636be5c2717jim we're going to */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (!ap_cfg_getline(input, sizeof(input), imap)) {
e8f95a682820a599fe41b22977010636be5c2717jim if (!input[0]) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes } /* blank lines and comments are ignored
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if we aren't printing a menu */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* find the first two space delimited fields, recall that
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * ap_cfg_getline has removed leading/trailing whitespace.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * note that we're tokenizing as we go... if we were to use the
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * ap_getword() class of functions we would end up allocating extra
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * memory for every line of the map file
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!*string_pos) { /* need at least two fields */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (*string_pos && !ap_isspace(*string_pos)) { /* past directive */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!*string_pos) { /* need at least two fields */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!*string_pos) { /* need at least two fields */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while(*string_pos && ap_isspace(*string_pos)) { /* past whitespace */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (*string_pos && !ap_isspace(*string_pos)) { /* past value */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* end of input, don't advance past it */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!strncasecmp(directive, "base", 4)) { /* base, base_uri */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes continue; /* base is never printed to a menu */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!strcasecmp(directive, "default")) { /* default */
e8f95a682820a599fe41b22977010636be5c2717jim if (showmenu) { /* print the default if there's a menu */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes &pointarray[vertex][X], &pointarray[vertex][Y]) == 2) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes /* Now skip what we just read... we can't use ANSIism %n */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (ap_isspace(*string_pos)) { /* past whitespace */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (ap_isdigit(*string_pos)) { /* and the 1st number */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (ap_isspace(*string_pos)) { /* past any more whitespace */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes while (ap_isdigit(*string_pos)) { /* 2nd number */
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe } /* so long as there are more vertices to
e8f95a682820a599fe41b22977010636be5c2717jim read, and we have room, read them in.
e8f95a682820a599fe41b22977010636be5c2717jim We start where we left off of the last
482f676c6c19b1c5bb5cca04dad11509c1da3a4cwrowe sscanf, not at the beginning. */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes pointarray[vertex][X] = -1; /* signals the end of vertices */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes read_quoted(&string_pos, &href_text); /* href text could
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes be here instead */
8445dae5cc606ba8ba04efc341cc1e081d95920drpluem /* note that we don't make it past here if we are making a menu */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (testpoint[X] == -1 || pointarray[0][X] == -1) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes continue; /* don't try the following tests if testpoints
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe are invalid, or if there are no
8113dac419143273351446c3ad653f3fe5ba5cfdwrowe coordinates */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!strcasecmp(directive, "circle")) { /* circle */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (!strcasecmp(directive, "point")) { /* point */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (is_closer(testpoint, pointarray, &closest_yet)) {
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes } /* move on to next line whether it's
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes closest or not */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes } /* nothing matched, so we get another line! */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_cfg_closefile(imap); /* we are done with the map file; close it */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes menu_footer(r); /* finish the menu and we are done */
3f5585f7f4a7d74f2f94ec729ea8c1879d419e35rederpj if (closest) { /* if a 'point' directive has been seen */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes if (mapdflt) { /* a default should be defined, even if
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes only 'nocontent' */
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes return HTTP_INTERNAL_SERVER_ERROR; /* If we make it this far,
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes we failed. They lose! */
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin "map file %s, line %d syntax error: requires at "
bb07ee33bce1a448bcc60ca43720b1ab1c413f87minfrin /* fall through */
f43b67c5a9d29b572eac916f8335cedc80c908bebnicholes /* There's not much else we can do ... we've already sent the headers
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes * to the client.
d5b12fe8ae917e654a33247fd4e59dc9e75170aebnicholes ap_rputs("\n\n[an internal server error occured]\n", r);
e8f95a682820a599fe41b22977010636be5c2717jim merge_imap_dir_configs, /* dir merger --- default is to override */