github.com/krum110487/go-htaccess@v0.0.0-20240316004156-60641c8e7598/tests/data/apache_2_2_34/include/apr_hooks.h (about) 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 30 extern "C" { 31 #endif 32 /** 33 * @defgroup APR_Util_Hook Hook Functions 34 * @ingroup APR_Util 35 * @{ 36 */ 37 38 /** 39 * @defgroup apr_hook_probes Hook probe capability 40 * APR hooks provide a trace probe capability for capturing 41 * the flow of control and return values with hooks. 42 * 43 * In order to use this facility, the application must define 44 * the symbol APR_HOOK_PROBES_ENABLED and the four APR_HOOK_PROBE_ 45 * macros described below before including apr_hooks.h in files 46 * that use the APR_IMPLEMENT_EXTERNAL_HOOK_* macros. 47 * 48 * This probe facility is not provided for APR optional hooks. 49 * @{ 50 */ 51 52 #ifdef APR_HOOK_PROBES_ENABLED 53 #define APR_HOOK_INT_DCL_UD void *ud = NULL 54 #else 55 /** internal implementation detail to avoid the ud declaration when 56 * hook probes are not used 57 */ 58 #define APR_HOOK_INT_DCL_UD 59 /** 60 * User-defined hook probe macro that is invoked when the hook 61 * is run, before calling any hook functions. 62 * @param ud A void * user data field that should be filled in by 63 * this macro, and will be provided to the other hook probe macros. 64 * @param ns The namespace prefix of the hook functions 65 * @param name The name of the hook 66 * @param args The argument list to the hook functions, with enclosing 67 * parens. 68 */ 69 #define APR_HOOK_PROBE_ENTRY(ud,ns,name,args) 70 /** 71 * User-defined hook probe macro that is invoked after the hook 72 * has run. 73 * @param ud A void * user data field that was filled in by the user- 74 * provided APR_HOOK_PROBE_ENTRY(). 75 * @param ns The namespace prefix of the hook functions 76 * @param name The name of the hook 77 * @param rv The return value of the hook, or 0 if the hook is void. 78 * @param args The argument list to the hook functions, with enclosing 79 * parens. 80 */ 81 #define APR_HOOK_PROBE_RETURN(ud,ns,name,rv,args) 82 /** 83 * User-defined hook probe macro that is invoked before calling a 84 * hook function. 85 * @param ud A void * user data field that was filled in by the user- 86 * provided APR_HOOK_PROBE_ENTRY(). 87 * @param ns The namespace prefix of the hook functions 88 * @param name The name of the hook 89 * @param src The value of apr_hook_debug_current at the time the function 90 * was hooked (usually the source file implementing the hook function). 91 * @param args The argument list to the hook functions, with enclosing 92 * parens. 93 */ 94 #define APR_HOOK_PROBE_INVOKE(ud,ns,name,src,args) 95 /** 96 * User-defined hook probe macro that is invoked after calling a 97 * hook function. 98 * @param ud A void * user data field that was filled in by the user- 99 * provided APR_HOOK_PROBE_ENTRY(). 100 * @param ns The namespace prefix of the hook functions 101 * @param name The name of the hook 102 * @param src The value of apr_hook_debug_current at the time the function 103 * was hooked (usually the source file implementing the hook function). 104 * @param rv The return value of the hook function, or 0 if the hook is void. 105 * @param args The argument list to the hook functions, with enclosing 106 * parens. 107 */ 108 #define APR_HOOK_PROBE_COMPLETE(ud,ns,name,src,rv,args) 109 #endif 110 111 /** @} */ 112 113 /** macro to return the prototype of the hook function */ 114 #define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \ 115 link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void) 116 117 /** macro to declare the hook correctly */ 118 #define APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args) \ 119 typedef ret ns##_HOOK_##name##_t args; \ 120 link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf, \ 121 const char * const *aszPre, \ 122 const char * const *aszSucc, int nOrder); \ 123 link##_DECLARE(ret) ns##_run_##name args; \ 124 APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name); \ 125 typedef struct ns##_LINK_##name##_t \ 126 { \ 127 ns##_HOOK_##name##_t *pFunc; \ 128 const char *szName; \ 129 const char * const *aszPredecessors; \ 130 const char * const *aszSuccessors; \ 131 int nOrder; \ 132 } ns##_LINK_##name##_t; 133 134 /** macro to declare the hook structure */ 135 #define APR_HOOK_STRUCT(members) \ 136 static struct { members } _hooks; 137 138 /** macro to link the hook structure */ 139 #define APR_HOOK_LINK(name) \ 140 apr_array_header_t *link_##name; 141 142 /** macro to implement the hook */ 143 #define APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \ 144 link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,const char * const *aszPre, \ 145 const char * const *aszSucc,int nOrder) \ 146 { \ 147 ns##_LINK_##name##_t *pHook; \ 148 if(!_hooks.link_##name) \ 149 { \ 150 _hooks.link_##name=apr_array_make(apr_hook_global_pool,1,sizeof(ns##_LINK_##name##_t)); \ 151 apr_hook_sort_register(#name,&_hooks.link_##name); \ 152 } \ 153 pHook=apr_array_push(_hooks.link_##name); \ 154 pHook->pFunc=pf; \ 155 pHook->aszPredecessors=aszPre; \ 156 pHook->aszSuccessors=aszSucc; \ 157 pHook->nOrder=nOrder; \ 158 pHook->szName=apr_hook_debug_current; \ 159 if(apr_hook_debug_enabled) \ 160 apr_hook_debug_show(#name,aszPre,aszSucc); \ 161 } \ 162 APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \ 163 { \ 164 return _hooks.link_##name; \ 165 } 166 167 /** 168 * Implement a hook that has no return code, and therefore runs all of the 169 * registered functions 170 * @param ns The namespace prefix of the hook functions 171 * @param link The linkage declaration prefix of the hook 172 * @param name The name of the hook 173 * @param args_decl The declaration of the arguments for the hook 174 * @param args_use The names for the arguments for the hook 175 * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which 176 * provide export linkage from the module that IMPLEMENTs the hook, and 177 * import linkage from external modules that link to the hook's module. 178 */ 179 #define APR_IMPLEMENT_EXTERNAL_HOOK_VOID(ns,link,name,args_decl,args_use) \ 180 APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \ 181 link##_DECLARE(void) ns##_run_##name args_decl \ 182 { \ 183 ns##_LINK_##name##_t *pHook; \ 184 int n; \ 185 APR_HOOK_INT_DCL_UD; \ 186 \ 187 APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \ 188 \ 189 if(_hooks.link_##name) \ 190 { \ 191 pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \ 192 for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \ 193 { \ 194 APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \ 195 pHook[n].pFunc args_use; \ 196 APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, 0, args_use); \ 197 } \ 198 } \ 199 \ 200 APR_HOOK_PROBE_RETURN(ud, ns, name, 0, args_use); \ 201 \ 202 } 203 204 /* FIXME: note that this returns ok when nothing is run. I suspect it should 205 really return decline, but that breaks Apache currently - Ben 206 */ 207 /** 208 * Implement a hook that runs until one of the functions returns something 209 * other than OK or DECLINE 210 * @param ns The namespace prefix of the hook functions 211 * @param link The linkage declaration prefix of the hook 212 * @param ret Type to return 213 * @param name The name of the hook 214 * @param args_decl The declaration of the arguments for the hook 215 * @param args_use The names for the arguments for the hook 216 * @param ok Success value 217 * @param decline Decline value 218 * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which 219 * provide export linkage from the module that IMPLEMENTs the hook, and 220 * import linkage from external modules that link to the hook's module. 221 */ 222 #define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_ALL(ns,link,ret,name,args_decl,args_use,ok,decline) \ 223 APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \ 224 link##_DECLARE(ret) ns##_run_##name args_decl \ 225 { \ 226 ns##_LINK_##name##_t *pHook; \ 227 int n; \ 228 ret rv = ok; \ 229 APR_HOOK_INT_DCL_UD; \ 230 \ 231 APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \ 232 \ 233 if(_hooks.link_##name) \ 234 { \ 235 pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \ 236 for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \ 237 { \ 238 APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \ 239 rv=pHook[n].pFunc args_use; \ 240 APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, rv, args_use); \ 241 if(rv != ok && rv != decline) \ 242 break; \ 243 rv = ok; \ 244 } \ 245 } \ 246 \ 247 APR_HOOK_PROBE_RETURN(ud, ns, name, rv, args_use); \ 248 \ 249 return rv; \ 250 } 251 252 253 /** 254 * Implement a hook that runs until the first function returns something 255 * other than the value of decline 256 * @param ns The namespace prefix of the hook functions 257 * @param link The linkage declaration prefix of the hook 258 * @param name The name of the hook 259 * @param ret Type to return 260 * @param args_decl The declaration of the arguments for the hook 261 * @param args_use The names for the arguments for the hook 262 * @param decline Decline value 263 * @note The link prefix FOO corresponds to FOO_DECLARE() macros, which 264 * provide export linkage from the module that IMPLEMENTs the hook, and 265 * import linkage from external modules that link to the hook's module. 266 */ 267 #define APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(ns,link,ret,name,args_decl,args_use,decline) \ 268 APR_IMPLEMENT_EXTERNAL_HOOK_BASE(ns,link,name) \ 269 link##_DECLARE(ret) ns##_run_##name args_decl \ 270 { \ 271 ns##_LINK_##name##_t *pHook; \ 272 int n; \ 273 ret rv = decline; \ 274 APR_HOOK_INT_DCL_UD; \ 275 \ 276 APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \ 277 \ 278 if(_hooks.link_##name) \ 279 { \ 280 pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \ 281 for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \ 282 { \ 283 APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \ 284 rv=pHook[n].pFunc args_use; \ 285 APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, rv, args_use); \ 286 \ 287 if(rv != decline) \ 288 break; \ 289 } \ 290 } \ 291 \ 292 APR_HOOK_PROBE_RETURN(ud, ns, name, rv, args_use); \ 293 \ 294 return rv; \ 295 } 296 297 /* Hook orderings */ 298 /** run this hook first, before ANYTHING */ 299 #define APR_HOOK_REALLY_FIRST (-10) 300 /** run this hook first */ 301 #define APR_HOOK_FIRST 0 302 /** run this hook somewhere */ 303 #define APR_HOOK_MIDDLE 10 304 /** run this hook after every other hook which is defined*/ 305 #define APR_HOOK_LAST 20 306 /** run this hook last, after EVERYTHING */ 307 #define APR_HOOK_REALLY_LAST 30 308 309 /** 310 * The global pool used to allocate any memory needed by the hooks. 311 */ 312 APU_DECLARE_DATA extern apr_pool_t *apr_hook_global_pool; 313 314 /** 315 * A global variable to determine if debugging information about the 316 * hooks functions should be printed. 317 */ 318 APU_DECLARE_DATA extern int apr_hook_debug_enabled; 319 320 /** 321 * The name of the module that is currently registering a function. 322 */ 323 APU_DECLARE_DATA extern const char *apr_hook_debug_current; 324 325 /** 326 * Register a hook function to be sorted. 327 * @param szHookName The name of the Hook the function is registered for 328 * @param aHooks The array which stores all of the functions for this hook 329 */ 330 APU_DECLARE(void) apr_hook_sort_register(const char *szHookName, 331 apr_array_header_t **aHooks); 332 /** 333 * Sort all of the registered functions for a given hook. 334 */ 335 APU_DECLARE(void) apr_hook_sort_all(void); 336 337 /** 338 * Print all of the information about the current hook. This is used for 339 * debugging purposes. 340 * @param szName The name of the hook 341 * @param aszPre All of the functions in the predecessor array 342 * @param aszSucc All of the functions in the successor array 343 */ 344 APU_DECLARE(void) apr_hook_debug_show(const char *szName, 345 const char * const *aszPre, 346 const char * const *aszSucc); 347 348 /** 349 * Remove all currently registered functions. 350 */ 351 APU_DECLARE(void) apr_hook_deregister_all(void); 352 353 /** @} */ 354 #ifdef __cplusplus 355 } 356 #endif 357 358 #endif /* APR_HOOKS_H */