⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_imap.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * 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 "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"#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 SUNOS4double strtod();                /* SunOS needed this */#endifmodule 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(pool *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(pool *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_escape_html(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, 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, 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 '..' */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -