📄 ap_hook.c
字号:
#if 0=pod#endif/* ==================================================================== * Copyright (c) 1998-2000 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 * ITS 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/>. * *//*** Implementation of a Generic Hook Interface for Apache** Written by Ralf S. Engelschall <rse@engelschall.com> **** See POD document at end of ap_hook.h for description.** View it with the command ``pod2man ap_hook.h | nroff -man | more''**** Attention: This source file is a little bit tricky.** It's a combination of a C source and an embedded Perl script** (which updates the C source). The purpose of this is to have** both things together at one place. So you can both pass** this file to the C compiler and the Perl interpreter.*/ /* * Premature optimization is * the root of all evil. * -- D. E. Knuth */#ifdef EAPI#include "httpd.h"#include "http_log.h"#include "ap_config.h"#include "ap_hook.h"/* * the internal hook pool */static ap_hook_entry **ap_hook_pool = NULL;/* * forward prototypes for internal functions */static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf);static ap_hook_entry *ap_hook_create(char *hook);static ap_hook_entry *ap_hook_find(char *hook);static void ap_hook_destroy(ap_hook_entry *he);/* * Initialize the hook mechanism */API_EXPORT(void) ap_hook_init(void){ int i; if (ap_hook_pool != NULL) return; ap_hook_pool = (ap_hook_entry **)malloc(sizeof(ap_hook_entry *) *(AP_HOOK_MAX_ENTRIES+1)); for (i = 0; i < AP_HOOK_MAX_ENTRIES; i++) ap_hook_pool[i] = NULL; return;}/* * Kill the hook mechanism */API_EXPORT(void) ap_hook_kill(void){ int i; if (ap_hook_pool == NULL) return; for (i = 0; ap_hook_pool[i] != NULL; i++) ap_hook_destroy(ap_hook_pool[i]); free(ap_hook_pool); ap_hook_pool = NULL; return;} /* * Smart creation of a hook (when it exist this is the same as * ap_hook_find, when it doesn't exists it is created) */static ap_hook_entry *ap_hook_create(char *hook){ int i; ap_hook_entry *he; for (i = 0; ap_hook_pool[i] != NULL; i++) if (strcmp(ap_hook_pool[i]->he_hook, hook) == 0) return ap_hook_pool[i]; if (i >= AP_HOOK_MAX_ENTRIES) return NULL; if ((he = (ap_hook_entry *)malloc(sizeof(ap_hook_entry))) == NULL) return NULL; ap_hook_pool[i] = he; he->he_hook = strdup(hook); he->he_sig = AP_HOOK_SIG_UNKNOWN; he->he_modeid = AP_HOOK_MODE_UNKNOWN; he->he_modeval.v_int = 0; he->he_func = (ap_hook_func **)malloc(sizeof(ap_hook_func *) *(AP_HOOK_MAX_FUNCS+1)); if (he->he_func == NULL) return FALSE; for (i = 0; i < AP_HOOK_MAX_FUNCS; i++) he->he_func[i] = NULL; return he;}/* * Find a particular hook */static ap_hook_entry *ap_hook_find(char *hook){ int i; for (i = 0; ap_hook_pool[i] != NULL; i++) if (strcmp(ap_hook_pool[i]->he_hook, hook) == 0) return ap_hook_pool[i]; return NULL;}/* * Destroy a particular hook */static void ap_hook_destroy(ap_hook_entry *he){ int i; if (he == NULL) return; free(he->he_hook); for (i = 0; he->he_func[i] != NULL; i++) free(he->he_func[i]); free(he->he_func); free(he); return;}/* * Configure a particular hook, * i.e. remember its signature and return value mode */API_EXPORT(int) ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...){ ap_hook_entry *he; va_list ap; int rc; va_start(ap, modeid); if ((he = ap_hook_create(hook)) == NULL) rc = FALSE; else { he->he_sig = sig; he->he_modeid = modeid; if (modeid == AP_HOOK_MODE_DECLINE || modeid == AP_HOOK_MODE_DECLTMP) { if (AP_HOOK_SIG_HAS(sig, RC, char)) he->he_modeval.v_char = va_arg(ap, va_type(char)); else if (AP_HOOK_SIG_HAS(sig, RC, int)) he->he_modeval.v_int = va_arg(ap, va_type(int)); else if (AP_HOOK_SIG_HAS(sig, RC, long)) he->he_modeval.v_long = va_arg(ap, va_type(long)); else if (AP_HOOK_SIG_HAS(sig, RC, float)) he->he_modeval.v_float = va_arg(ap, va_type(float)); else if (AP_HOOK_SIG_HAS(sig, RC, double)) he->he_modeval.v_double = va_arg(ap, va_type(double)); else if (AP_HOOK_SIG_HAS(sig, RC, ptr)) he->he_modeval.v_ptr = va_arg(ap, va_type(ptr)); } rc = TRUE; } va_end(ap); return rc;}/* * Register a function to call for a hook */API_EXPORT(int) ap_hook_register_I(char *hook, void *func, void *ctx){ int i, j; ap_hook_entry *he; ap_hook_func *hf; if ((he = ap_hook_create(hook)) == NULL) return FALSE; for (i = 0; he->he_func[i] != NULL; i++) if (he->he_func[i]->hf_ptr == func) return FALSE; if (i == AP_HOOK_MAX_FUNCS) return FALSE; if ((hf = (ap_hook_func *)malloc(sizeof(ap_hook_func))) == NULL) return FALSE; for (j = i; j >= 0; j--) he->he_func[j+1] = he->he_func[j]; he->he_func[0] = hf; hf->hf_ptr = func; hf->hf_ctx = ctx; return TRUE;}/* * Unregister a function to call for a hook */API_EXPORT(int) ap_hook_unregister_I(char *hook, void *func){ int i, j; ap_hook_entry *he; if ((he = ap_hook_find(hook)) == NULL) return FALSE; for (i = 0; he->he_func[i] != NULL; i++) { if (he->he_func[i]->hf_ptr == func) { free(he->he_func[i]); for (j = i; he->he_func[j] != NULL; j++) he->he_func[j] = he->he_func[j+1]; return TRUE; } } return FALSE;}/* * Retrieve the status of a particular hook */API_EXPORT(ap_hook_state) ap_hook_status(char *hook){ ap_hook_entry *he; if ((he = ap_hook_find(hook)) == NULL) return AP_HOOK_STATE_NOTEXISTANT; if ( he->he_func[0] != NULL && he->he_sig != AP_HOOK_SIG_UNKNOWN && he->he_modeid != AP_HOOK_MODE_UNKNOWN) return AP_HOOK_STATE_REGISTERED; if ( he->he_sig != AP_HOOK_SIG_UNKNOWN && he->he_modeid != AP_HOOK_MODE_UNKNOWN) return AP_HOOK_STATE_CONFIGURED; return AP_HOOK_STATE_ESTABLISHED;}/* * Use a hook, i.e. optional on-the-fly configure it before calling it */API_EXPORT(int) ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...){ int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -