1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef APR_HOOKS_H 18#define APR_HOOKS_H 19 20#include "apu.h" 21/* For apr_array_header_t */ 22#include "apr_tables.h" 23 24/** 25 * @file apr_hooks.h 26 * @brief Apache hook functions 27 */ 28 29#ifdef __cplusplus 30extern "C" { 31#endif 32/** 33 * @defgroup APR_Util_Hook Hook Functions 34 * @ingroup APR_Util 35 * @{ 36 */ 37/** macro to return the prototype of the hook function */ 38#define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \ 39link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void) 40 41/** macro to declare the hook correctly */ 42#define APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args) \ 43typedef ret ns##_HOOK_##name##_t args; \ 44link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf, \ 45 const char * const *aszPre, \ 46 const char * const *aszSucc, int nOrder); \ 47link##_DECLARE(ret) ns##_run_##name args; \ 48APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name); \ 49typedef struct ns##_LINK_##name##_t \ 50 { \ 51 ns##_HOOK_##name##_t *pFunc; \ 52 const char *szName; \ 53 const char * const *aszPredecessors; \ 54 const char * const *aszSuccessors; \ 55 int nOrder; \ 56 } ns##_LINK_##name##_t; 57 58/** macro to declare the hook structure */ 59#define APR_HOOK_STRUCT(members) \ 60static struct { members } _hooks; 61 62/** macro to link the hook structure */ 63#define APR_HOOK_LINK(name) \ 64 apr_array_header_t *link_##name; 65 66/** macro to implement the hook */ 67#define APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \ 68link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,const char * const *aszPre, \ 69 const char * const *aszSucc,int nOrder) \ 70 { \ 71 ns##_LINK_##name##_t *pHook; \ 72 if(!_hooks.link_##name) \ 73 { \ 74 _hooks.link_##name=apr_array_make(apr_hook_global_pool,1,sizeof(ns##_LINK_##name##_t)); \ 75 apr_hook_sort_register(#name,&_hooks.link_##name); \ 76 } \ 77 pHook=apr_array_push(_hooks.link_##name); \ 78 pHook->pFunc=pf; \ 79 pHook->aszPredecessors=aszPre; \ 80 pHook->aszSuccessors=aszSucc; \ 81 pHook->nOrder=nOrder; \ 82 pHook->szName=apr_hook_debug_current; \ 83 if(apr_hook_debug_enabled) \ 84 apr_hook_debug_show(#name,aszPre,aszSucc); \ 85 } \ 86 APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \ 87 { \ 88 return _hooks.link_##name; \ 89 } 90 91/** 92 * Implement a hook that has no return code, and therefore runs all of the 93 * registered functions 94 * @param ns The namespace prefix of the hook functions 95 * @param link The linkage declaration prefix of the hook 96 * @param name The name of the hook 97 * @param args_decl The declaration of the arguments for the hook 98 * @param args_use The names for the arguments for the hook 99 * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which 100 * provide export linkage from the module that IMPLEMENTs the hook, and 101 * import linkage from external modules that link to the hook's module. 102 */ 103#define APR_IMPLEMENT_EXTERNAL_HOOK_VOID(ns,link,name,args_decl,args_use) \ 104APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \ 105link##_DECLARE(void) ns##_run_##name args_decl \ 106 { \ 107 ns##_LINK_##name##_t *pHook; \ 108 int n; \ 109\ 110 if(!_hooks.link_##name) \ 111 return; \ 112\ 113 pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \ 114 for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \ 115 pHook[n].pFunc args_use; \ 116 } 117 118/* FIXME: note that this returns ok when nothing is run. I suspect it should 119 really return decline, but that breaks Apache currently - Ben 120*/ 121/** 122 * Implement a hook that runs until one of the functions returns something 123 * other than OK or DECLINE 124 * @param ns The namespace prefix of the hook functions 125 * @param link The linkage declaration prefix of the hook 126 * @param ret Type to return 127 * @param name The name of the hook 128 * @param args_decl The declaration of the arguments for the hook 129 * @param args_use The names for the arguments for the hook 130 * @param ok Success value 131 * @param decline Decline value 132 * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which 133 * provide export linkage from the module that IMPLEMENTs the hook, and 134 * import linkage from external modules that link to the hook's module. 135 */ 136#define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \ 137APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \ 138link##_DECLARE(ret) ns##_run_##name args_decl \ 139 { \ 140 ns##_LINK_##name##_t *pHook; \ 141 int n; \ 142 ret rv; \ 143\ 144 if(!_hooks.link_##name) \ 145 return ok; \ 146\ 147 pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \ 148 for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \ 149 { \ 150 rv=pHook[n].pFunc args_use; \ 151\ 152 if(rv != ok && rv != decline) \ 153 return rv; \ 154 } \ 155 return ok; \ 156 } 157 158 159/** 160 * Implement a hook that runs until the first function returns something 161 * other than the value of decline 162 * @param ns The namespace prefix of the hook functions 163 * @param link The linkage declaration prefix of the hook 164 * @param name The name of the hook 165 * @param ret Type to return 166 * @param args_decl The declaration of the arguments for the hook 167 * @param args_use The names for the arguments for the hook 168 * @param decline Decline value 169 * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which 170 * provide export linkage from the module that IMPLEMENTs the hook, and 171 * import linkage from external modules that link to the hook's module. 172 */ 173#define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ns,link,ret,name,args_decl,args_use,decline) \ 174APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \ 175link##_DECLARE(ret) ns##_run_##name args_decl \ 176 { \ 177 ns##_LINK_##name##_t *pHook; \ 178 int n; \ 179 ret rv; \ 180\ 181 if(!_hooks.link_##name) \ 182 return decline; \ 183\ 184 pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \ 185 for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \ 186 { \ 187 rv=pHook[n].pFunc args_use; \ 188\ 189 if(rv != decline) \ 190 return rv; \ 191 } \ 192 return decline; \ 193 } 194 195 /* Hook orderings */ 196/** run this hook first, before ANYTHING */ 197#define APR_HOOK_REALLY_FIRST (-10) 198/** run this hook first */ 199#define APR_HOOK_FIRST 0 200/** run this hook somewhere */ 201#define APR_HOOK_MIDDLE 10 202/** run this hook after every other hook which is defined*/ 203#define APR_HOOK_LAST 20 204/** run this hook last, after EVERYTHING */ 205#define APR_HOOK_REALLY_LAST 30 206 207/** 208 * The global pool used to allocate any memory needed by the hooks. 209 */ 210APU_DECLARE_DATA extern apr_pool_t *apr_hook_global_pool; 211 212/** 213 * A global variable to determine if debugging information about the 214 * hooks functions should be printed 215 */ 216APU_DECLARE_DATA extern int apr_hook_debug_enabled; 217 218/** 219 * The name of the module that is currently registering a function 220 */ 221APU_DECLARE_DATA extern const char *apr_hook_debug_current; 222 223/** 224 * Register a hook function to be sorted 225 * @param szHookName The name of the Hook the function is registered for 226 * @param aHooks The array which stores all of the functions for this hook 227 */ 228APU_DECLARE(void) apr_hook_sort_register(const char *szHookName, 229 apr_array_header_t **aHooks); 230/** 231 * Sort all of the registerd functions for a given hook 232 */ 233APU_DECLARE(void) apr_hook_sort_all(void); 234 235/** 236 * Print all of the information about the current hook. This is used for 237 * debugging purposes. 238 * @param szName The name of the hook 239 * @param aszPre All of the functions in the predecessor array 240 * @param aszSucc All of the functions in the successor array 241 */ 242APU_DECLARE(void) apr_hook_debug_show(const char *szName, 243 const char * const *aszPre, 244 const char * const *aszSucc); 245 246/** 247 * Remove all currently registered functions. 248 */ 249APU_DECLARE(void) apr_hook_deregister_all(void); 250 251/** @} */ 252#ifdef __cplusplus 253} 254#endif 255 256#endif /* APR_HOOKS_H */ 257