Apache HTTPD
apr_hooks.c
Go to the documentation of this file.
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#include <assert.h>
18#include <stdio.h>
19#include <stdlib.h>
20
21#include "apr_pools.h"
22#include "apr_tables.h"
23#include "apr.h"
24#include "apr_hooks.h"
25#include "apr_hash.h"
26#include "apr_optional_hooks.h"
27#include "apr_optional.h"
28#define APR_WANT_MEMFUNC
29#define APR_WANT_STRFUNC
30#include "apr_want.h"
31
32#if 0
33#define apr_palloc(pool,size) malloc(size)
34#endif
35
39
42
45
48
49/* NB: This must echo the LINK_##name structure */
50typedef struct
51{
52 void (*dummy)(void *);
53 const char *szName;
54 const char * const *aszPredecessors;
55 const char * const *aszSuccessors;
56 int nOrder;
57} TSortData;
58
59typedef struct tsort_
60{
61 void *pData;
64 struct tsort_ *pNext;
66
67#ifdef NETWARE
68#include "apr_private.h"
69#define get_apd APP_DATA* apd = (APP_DATA*)get_app_data(gLibId);
70#define s_aHooksToSort ((apr_array_header_t *)(apd->gs_aHooksToSort))
71#define s_phOptionalHooks ((apr_hash_t *)(apd->gs_phOptionalHooks))
72#define s_phOptionalFunctions ((apr_hash_t *)(apd->gs_phOptionalFunctions))
73#endif
74
75static int crude_order(const void *a_,const void *b_)
76{
77 const TSortData *a=a_;
78 const TSortData *b=b_;
79
80 return a->nOrder-b->nOrder;
81}
82
84{
86 int n;
87
89 for(n=0 ; n < nItems ; ++n) {
90 pData[n].nPredecessors=0;
91 pData[n].ppPredecessors=apr_pcalloc(p,nItems*sizeof *pData[n].ppPredecessors);
92 pData[n].pNext=NULL;
93 pData[n].pData=&pItems[n];
94 }
95
96 for(n=0 ; n < nItems ; ++n) {
97 int i,k;
98
99 for(i=0 ; pItems[n].aszPredecessors && pItems[n].aszPredecessors[i] ; ++i)
100 for(k=0 ; k < nItems ; ++k)
101 if(!strcmp(pItems[k].szName,pItems[n].aszPredecessors[i])) {
102 int l;
103
104 for(l=0 ; l < pData[n].nPredecessors ; ++l)
105 if(pData[n].ppPredecessors[l] == &pData[k])
106 goto got_it;
107 pData[n].ppPredecessors[pData[n].nPredecessors]=&pData[k];
108 ++pData[n].nPredecessors;
109 got_it:
110 break;
111 }
112 for(i=0 ; pItems[n].aszSuccessors && pItems[n].aszSuccessors[i] ; ++i)
113 for(k=0 ; k < nItems ; ++k)
114 if(!strcmp(pItems[k].szName,pItems[n].aszSuccessors[i])) {
115 int l;
116
117 for(l=0 ; l < pData[k].nPredecessors ; ++l)
118 if(pData[k].ppPredecessors[l] == &pData[n])
119 goto got_it2;
120 pData[k].ppPredecessors[pData[k].nPredecessors]=&pData[n];
121 ++pData[k].nPredecessors;
122 got_it2:
123 break;
124 }
125 }
126
127 return pData;
128}
129
130/* Topologically sort, dragging out-of-order items to the front. Note that
131 this tends to preserve things that want to be near the front better, and
132 changing that behaviour might compromise some of Apache's behaviour (in
133 particular, mod_log_forensic might otherwise get pushed to the end, and
134 core.c's log open function used to end up at the end when pushing items
135 to the back was the methedology). Also note that the algorithm could
136 go back to its original simplicity by sorting from the back instead of
137 the front.
138*/
140{
141 int nTotal;
142 TSort *pHead=NULL;
143 TSort *pTail=NULL;
144
145 for(nTotal=0 ; nTotal < nItems ; ++nTotal) {
146 int n,i,k;
147
148 for(n=0 ; ; ++n) {
149 if(n == nItems)
150 assert(0); /* we have a loop... */
151 if(!pData[n].pNext) {
152 if(pData[n].nPredecessors) {
153 for(k=0 ; ; ++k) {
154 assert(k < nItems);
155 if(pData[n].ppPredecessors[k])
156 break;
157 }
158 for(i=0 ; ; ++i) {
159 assert(i < nItems);
160 if(&pData[i] == pData[n].ppPredecessors[k]) {
161 n=i-1;
162 break;
163 }
164 }
165 } else
166 break;
167 }
168 }
169 if(pTail)
170 pTail->pNext=&pData[n];
171 else
172 pHead=&pData[n];
173 pTail=&pData[n];
174 pTail->pNext=pTail; /* fudge it so it looks linked */
175 for(i=0 ; i < nItems ; ++i)
176 for(k=0 ; k < nItems ; ++k)
177 if(pData[i].ppPredecessors[k] == &pData[n]) {
179 pData[i].ppPredecessors[k]=NULL;
180 break;
181 }
182 }
183 if(pTail)
184 pTail->pNext=NULL; /* unfudge the tail */
185 return pHead;
186}
187
189 const char *szName)
190{
191 apr_pool_t *p;
192 TSort *pSort;
194 int n;
195
197 pSort=prepare(p,(TSortData *)pHooks->elts,pHooks->nelts);
198 pSort=tsort(pSort,pHooks->nelts);
201 printf("Sorting %s:",szName);
202 for(n=0 ; pSort ; pSort=pSort->pNext,++n) {
206 memcpy(pHook,pSort->pData,sizeof *pHook);
208 printf(" %s",pHook->szName);
209 }
211 fputc('\n',stdout);
212
213 /* destroy the pool - the sorted hooks were already copied */
215
216 return pNew;
217}
218
219#ifndef NETWARE
221#endif
222
223typedef struct
224{
225 const char *szHookName;
228
229APU_DECLARE(void) apr_hook_sort_register(const char *szHookName,
230 apr_array_header_t **paHooks)
231{
232#ifdef NETWARE
233 get_apd
234#endif
236
237 if(!s_aHooksToSort)
240 pEntry->szHookName=szHookName;
241 pEntry->paHooks=paHooks;
242}
243
245{
246#ifdef NETWARE
247 get_apd
248#endif
249 int n;
250
251 if (!s_aHooksToSort) {
253 }
254
255 for(n=0 ; n < s_aHooksToSort->nelts ; ++n) {
257 *pEntry->paHooks=sort_hook(*pEntry->paHooks,pEntry->szHookName);
258 }
259}
260
261#ifndef NETWARE
264#endif
265
267{
268#ifdef NETWARE
269 get_apd
270#endif
271 int n;
272
273 if (!s_aHooksToSort) {
274 return;
275 }
276
277 for(n=0 ; n < s_aHooksToSort->nelts ; ++n) {
280 }
284}
285
286APU_DECLARE(void) apr_hook_debug_show(const char *szName,
287 const char * const *aszPre,
288 const char * const *aszSucc)
289{
290 int nFirst;
291
292 printf(" Hooked %s",szName);
293 if(aszPre) {
294 fputs(" pre(",stdout);
295 nFirst=1;
296 while(*aszPre) {
297 if(!nFirst)
298 fputc(',',stdout);
299 nFirst=0;
301 ++aszPre;
302 }
303 fputc(')',stdout);
304 }
305 if(aszSucc) {
306 fputs(" succ(",stdout);
307 nFirst=1;
308 while(*aszSucc) {
309 if(!nFirst)
310 fputc(',',stdout);
311 nFirst=0;
313 ++aszSucc;
314 }
315 fputc(')',stdout);
316 }
317 fputc('\n',stdout);
318}
319
320/* Optional hook support */
321
323
325{
326#ifdef NETWARE
327 get_apd
328#endif
330
332 return NULL;
333 ppArray=apr_hash_get(s_phOptionalHooks,szName,strlen(szName));
334 if(!ppArray)
335 return NULL;
336 return *ppArray;
337}
338
339APU_DECLARE(void) apr_optional_hook_add(const char *szName,void (*pfn)(void),
340 const char * const *aszPre,
341 const char * const *aszSucc,int nOrder)
342{
343#ifdef NETWARE
344 get_apd
345#endif
348
349 if(!pArray) {
351
353 sizeof(apr_LINK__optional_t));
358 apr_hash_set(s_phOptionalHooks,szName,strlen(szName),ppArray);
360 }
362 pHook->pFunc=pfn;
363 pHook->aszPredecessors=aszPre;
364 pHook->aszSuccessors=aszSucc;
365 pHook->nOrder=nOrder;
369}
370
371/* optional function support */
372
374{
375#ifdef NETWARE
376 get_apd
377#endif
379 return NULL;
380 return (void(*)(void))apr_hash_get(s_phOptionalFunctions,szName,strlen(szName));
381}
382
383/* Deprecated */
386{
387#ifdef NETWARE
388 get_apd
389#endif
392 apr_hash_set(s_phOptionalFunctions,szName,strlen(szName),(void *)pfn);
393}
394
395#if 0
396void main()
397{
398 const char *aszAPre[]={"b","c",NULL};
399 const char *aszBPost[]={"a",NULL};
400 const char *aszCPost[]={"b",NULL};
401 TSortData t1[]=
402 {
403 { "a",aszAPre,NULL },
404 { "b",NULL,aszBPost },
405 { "c",NULL,aszCPost }
406 };
407 TSort *pResult;
408
409 pResult=prepare(t1,3);
411
412 for( ; pResult ; pResult=pResult->pNext)
413 printf("%s\n",pResult->pData->szName);
414}
415#endif
int n
Definition ap_regex.h:278
APR Hash Tables.
APU_DECLARE(void)
Computes SipHash-2-4, producing a 64bit (APR_SIPHASH_DSIZE) hash from a message and a 128bit (APR_SIP...
Definition apr_hooks.c:229
static TSort * tsort(TSort *pData, int nItems)
Definition apr_hooks.c:139
static apr_hash_t * s_phOptionalHooks
Definition apr_hooks.c:262
static apr_array_header_t * s_aHooksToSort
Definition apr_hooks.c:220
struct tsort_ TSort
static apr_array_header_t * sort_hook(apr_array_header_t *pHooks, const char *szName)
Definition apr_hooks.c:188
static apr_hash_t * s_phOptionalFunctions
Definition apr_hooks.c:263
apr_LINK__optional_t
Definition apr_hooks.c:322
static int crude_order(const void *a_, const void *b_)
Definition apr_hooks.c:75
APU_DECLARE_DATA int apr_debug_module_hooks
Definition apr_hooks.c:44
static TSort * prepare(apr_pool_t *p, TSortData *pItems, int nItems)
Definition apr_hooks.c:83
APU_DECLARE_DATA apr_pool_t * apr_global_hook_pool
Definition apr_hooks.c:41
APU_DECLARE_DATA const char * apr_current_hooking_module
Definition apr_hooks.c:47
Apache hook functions.
APR-UTIL registration of functions exported by modules.
Apache optional hook functions.
APR memory allocation.
APR Table library.
APR Standard Headers Support.
void * dummy
Definition http_vhost.h:62
APU_DECLARE_NONSTD(void)
Definition apr_hooks.c:384
apr_bucket apr_bucket_brigade * a
APU_DECLARE_DATA const char * apr_hook_debug_current
Definition apr_hooks.c:38
APU_DECLARE_DATA int apr_hook_debug_enabled
Definition apr_hooks.c:37
const char *const const char *const * aszSucc
Definition apr_hooks.h:346
#define APR_DECLARE_EXTERNAL_HOOK(ns, link, ret, name, args)
Definition apr_hooks.h:118
const char *const * aszPre
Definition apr_hooks.h:345
APU_DECLARE_DATA apr_pool_t * apr_hook_global_pool
Definition apr_hooks.c:36
void(*) const char *const const char *const in nOrder)
void() apr_opt_fn_t(void)
apr_size_t size
apr_pool_t * b
Definition apr_pools.h:529
#define apr_pool_create(newpool, parent)
Definition apr_pools.h:322
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
int nelts
Definition apr_tables.h:122
apr_pool_t * p
Definition md_event.c:32
static apr_OFN_TestOptionalFn_t * pfn
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
int main(void)
Definition occhild.c:9
const char * szHookName
Definition apr_hooks.c:225
apr_array_header_t ** paHooks
Definition apr_hooks.c:226
int nOrder
Definition apr_hooks.c:56
const char * szName
Definition apr_hooks.c:53
const char *const * aszSuccessors
Definition apr_hooks.c:55
const char *const * aszPredecessors
Definition apr_hooks.c:54
struct tsort_ ** ppPredecessors
Definition apr_hooks.c:63
int nPredecessors
Definition apr_hooks.c:62
void * pData
Definition apr_hooks.c:61
struct tsort_ * pNext
Definition apr_hooks.c:64
static apr_table_t * t1
Definition testtable.c:34