1 /* ====================================================================
2  * Copyright (c) 1998-2000 The Apache Group.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in
13  *    the documentation and/or other materials provided with the
14  *    distribution.
15  *
16  * 3. All advertising materials mentioning features or use of this
17  *    software must display the following acknowledgment:
18  *    "This product includes software developed by the Apache Group
19  *    for use in the Apache HTTP server project (http://www.apache.org/)."
20  *
21  * 4. The names "Apache Server" and "Apache Group" must not be used to
22  *    endorse or promote products derived from this software without
23  *    prior written permission. For written permission, please contact
24  *    apache@apache.org.
25  *
26  * 5. Products derived from this software may not be called "Apache"
27  *    nor may "Apache" appear in their names without prior written
28  *    permission of the Apache Group.
29  *
30  * 6. Redistributions of any form whatsoever must retain the following
31  *    acknowledgment:
32  *    "This product includes software developed by the Apache Group
33  *    for use in the Apache HTTP server project (http://www.apache.org/)."
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
36  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46  * OF THE POSSIBILITY OF SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Group and was originally based
51  * on public domain software written at the National Center for
52  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
53  * For more information on the Apache Group and the Apache HTTP server
54  * project, please see <http://www.apache.org/>.
55  *
56  */
57 
58 /*
59 **  Implementation of a Generic Hook Interface for Apache
60 **  Written by Ralf S. Engelschall <rse@engelschall.com>
61 **
62 **  See POD document at end of ap_hook.h for description.
63 **  View it with the command ``pod2man ap_hook.h | nroff -man | more''
64 **
65 */
66 
67                                       /*
68                                        * Premature optimization is
69                                        * the root of all evil.
70                                        *       -- D. E. Knuth
71                                        */
72 
73 #include "httpd.h"
74 #include "http_log.h"
75 #include "ap_config.h"
76 #include "ap_hook.h"
77 
78 /*
79  * the internal hook pool
80  */
81 static ap_hook_entry **ap_hook_pool = NULL;
82 
83 /*
84  * forward prototypes for internal functions
85  */
86 static int            ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf);
87 static ap_hook_entry *ap_hook_create(char *hook);
88 static ap_hook_entry *ap_hook_find(char *hook);
89 static void           ap_hook_destroy(ap_hook_entry *he);
90 
91 /*
92  * Initialize the hook mechanism
93  */
ap_hook_init(void)94 API_EXPORT(void) ap_hook_init(void)
95 {
96 	int i;
97 
98 	if (ap_hook_pool != NULL)
99 		return;
100 	ap_hook_pool = (ap_hook_entry **)malloc(sizeof(ap_hook_entry *)
101 	    *(AP_HOOK_MAX_ENTRIES+1));
102 	for (i = 0; i < AP_HOOK_MAX_ENTRIES; i++)
103 		ap_hook_pool[i] = NULL;
104 	return;
105 }
106 
107 /*
108  * Kill the hook mechanism
109  */
ap_hook_kill(void)110 API_EXPORT(void) ap_hook_kill(void)
111 {
112 	int i;
113 
114 	if (ap_hook_pool == NULL)
115 		return;
116 	for (i = 0; ap_hook_pool[i] != NULL; i++)
117 		ap_hook_destroy(ap_hook_pool[i]);
118 	free(ap_hook_pool);
119 	ap_hook_pool = NULL;
120 	return;
121 }
122 
123 /*
124  * Smart creation of a hook (when it exist this is the same as
125  * ap_hook_find, when it doesn't exists it is created)
126  */
ap_hook_create(char * hook)127 static ap_hook_entry *ap_hook_create(char *hook)
128 {
129 	int i;
130 	ap_hook_entry *he;
131 
132 	for (i = 0; ap_hook_pool[i] != NULL; i++)
133 		if (strcmp(ap_hook_pool[i]->he_hook, hook) == 0)
134 			return ap_hook_pool[i];
135 
136 	if (i >= AP_HOOK_MAX_ENTRIES)
137 		return NULL;
138 
139 	if ((he = (ap_hook_entry *)malloc(sizeof(ap_hook_entry))) == NULL)
140 		return NULL;
141 	ap_hook_pool[i] = he;
142 
143 	he->he_hook          = strdup(hook);
144 	he->he_sig           = AP_HOOK_SIG_UNKNOWN;
145 	he->he_modeid        = AP_HOOK_MODE_UNKNOWN;
146 	he->he_modeval.v_int = 0;
147 
148 	he->he_func = (ap_hook_func **)malloc(sizeof(ap_hook_func *)
149 	    *(AP_HOOK_MAX_FUNCS+1));
150 	if (he->he_func == NULL)
151 		return FALSE;
152 
153 	for (i = 0; i < AP_HOOK_MAX_FUNCS; i++)
154 		he->he_func[i] = NULL;
155 	return he;
156 }
157 
158 /*
159  * Find a particular hook
160  */
ap_hook_find(char * hook)161 static ap_hook_entry *ap_hook_find(char *hook)
162 {
163 	int i;
164 
165 	for (i = 0; ap_hook_pool[i] != NULL; i++)
166 		if (strcmp(ap_hook_pool[i]->he_hook, hook) == 0)
167 			return ap_hook_pool[i];
168 	return NULL;
169 }
170 
171 /*
172  * Destroy a particular hook
173  */
ap_hook_destroy(ap_hook_entry * he)174 static void ap_hook_destroy(ap_hook_entry *he)
175 {
176 	int i;
177 
178 	if (he == NULL)
179 		return;
180 	free(he->he_hook);
181 	for (i = 0; he->he_func[i] != NULL; i++)
182 		free(he->he_func[i]);
183 	free(he->he_func);
184 	free(he);
185 	return;
186 }
187 
188 /*
189  * Configure a particular hook,
190  * i.e. remember its signature and return value mode
191  */
ap_hook_configure(char * hook,ap_hook_sig sig,ap_hook_mode modeid,...)192 API_EXPORT(int) ap_hook_configure(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...)
193 {
194 	ap_hook_entry *he;
195 	va_list ap;
196 	int rc;
197 
198 	va_start(ap, modeid);
199 	if ((he = ap_hook_create(hook)) == NULL)
200 	rc = FALSE;
201 	else {
202 		he->he_sig = sig;
203 		he->he_modeid = modeid;
204 		if (modeid == AP_HOOK_MODE_DECLINE || modeid == AP_HOOK_MODE_DECLTMP) {
205 			if (AP_HOOK_SIG_HAS(sig, RC, char))
206 				he->he_modeval.v_char = va_arg(ap, va_type(char));
207 			else if (AP_HOOK_SIG_HAS(sig, RC, int))
208 				he->he_modeval.v_int = va_arg(ap, va_type(int));
209 			else if (AP_HOOK_SIG_HAS(sig, RC, long))
210 				he->he_modeval.v_long = va_arg(ap, va_type(long));
211 			else if (AP_HOOK_SIG_HAS(sig, RC, float))
212 				he->he_modeval.v_float = va_arg(ap, va_type(float));
213 			else if (AP_HOOK_SIG_HAS(sig, RC, double))
214 				he->he_modeval.v_double = va_arg(ap, va_type(double));
215 			else if (AP_HOOK_SIG_HAS(sig, RC, ptr))
216 				he->he_modeval.v_ptr = va_arg(ap, va_type(ptr));
217 		}
218 		rc = TRUE;
219 	}
220 	va_end(ap);
221 	return rc;
222 }
223 
224 /*
225  * Register a function to call for a hook
226  */
ap_hook_register_I(char * hook,void * func,void * ctx)227 API_EXPORT(int) ap_hook_register_I(char *hook, void *func, void *ctx)
228 {
229 	int i, j;
230 	ap_hook_entry *he;
231 	ap_hook_func *hf;
232 
233 	if ((he = ap_hook_create(hook)) == NULL)
234 		return FALSE;
235 
236 	for (i = 0; he->he_func[i] != NULL; i++)
237 		if (he->he_func[i]->hf_ptr == func)
238 			return FALSE;
239 
240 	if (i == AP_HOOK_MAX_FUNCS)
241 		return FALSE;
242 
243 	if ((hf = (ap_hook_func *)malloc(sizeof(ap_hook_func))) == NULL)
244 		return FALSE;
245 
246 	for (j = i; j >= 0; j--)
247 		he->he_func[j+1] = he->he_func[j];
248 	he->he_func[0] = hf;
249 
250 	hf->hf_ptr = func;
251 	hf->hf_ctx = ctx;
252 
253 	return TRUE;
254 }
255 
256 /*
257  * Unregister a function to call for a hook
258  */
ap_hook_unregister_I(char * hook,void * func)259 API_EXPORT(int) ap_hook_unregister_I(char *hook, void *func)
260 {
261 	int i, j;
262 	ap_hook_entry *he;
263 
264 	if ((he = ap_hook_find(hook)) == NULL)
265 		return FALSE;
266 	for (i = 0; he->he_func[i] != NULL; i++) {
267 		if (he->he_func[i]->hf_ptr == func) {
268 			free(he->he_func[i]);
269 			for (j = i; he->he_func[j] != NULL; j++)
270 				he->he_func[j] = he->he_func[j+1];
271 			return TRUE;
272 			}
273 	}
274 	return FALSE;
275 }
276 
277 /*
278  * Retrieve the status of a particular hook
279  */
ap_hook_status(char * hook)280 API_EXPORT(ap_hook_state) ap_hook_status(char *hook)
281 {
282 	ap_hook_entry *he;
283 
284 	if ((he = ap_hook_find(hook)) == NULL)
285 		return AP_HOOK_STATE_NOTEXISTANT;
286 	if (   he->he_func[0] != NULL
287 	    && he->he_sig != AP_HOOK_SIG_UNKNOWN
288 	    && he->he_modeid != AP_HOOK_MODE_UNKNOWN)
289 		return AP_HOOK_STATE_REGISTERED;
290 	if (   he->he_sig != AP_HOOK_SIG_UNKNOWN
291 	    && he->he_modeid != AP_HOOK_MODE_UNKNOWN)
292 		return AP_HOOK_STATE_CONFIGURED;
293 	return AP_HOOK_STATE_ESTABLISHED;
294 }
295 
296 /*
297  * Use a hook, i.e. optional on-the-fly configure it before calling it
298  */
ap_hook_use(char * hook,ap_hook_sig sig,ap_hook_mode modeid,...)299 API_EXPORT(int) ap_hook_use(char *hook, ap_hook_sig sig, ap_hook_mode modeid, ...)
300 {
301 	int i;
302 	ap_hook_value modeval;
303 	ap_hook_entry *he;
304 	va_list ap;
305 	int rc;
306 
307 	va_start(ap, modeid);
308 
309 	if (modeid == AP_HOOK_MODE_DECLINE || modeid == AP_HOOK_MODE_DECLTMP) {
310 		if (AP_HOOK_SIG_HAS(sig, RC, char))
311 			modeval.v_char = va_arg(ap, va_type(char));
312 		else if (AP_HOOK_SIG_HAS(sig, RC, int))
313 			modeval.v_int = va_arg(ap, va_type(int));
314 		else if (AP_HOOK_SIG_HAS(sig, RC, long))
315 			modeval.v_long = va_arg(ap, va_type(long));
316 		else if (AP_HOOK_SIG_HAS(sig, RC, float))
317 			modeval.v_float = va_arg(ap, va_type(float));
318 		else if (AP_HOOK_SIG_HAS(sig, RC, double))
319 			modeval.v_double = va_arg(ap, va_type(double));
320 		else if (AP_HOOK_SIG_HAS(sig, RC, ptr))
321 			modeval.v_ptr = va_arg(ap, va_type(ptr));
322 	}
323 
324 	if ((he = ap_hook_create(hook)) == NULL)
325 		return FALSE;
326 
327 	if (he->he_sig == AP_HOOK_SIG_UNKNOWN)
328 		he->he_sig = sig;
329 	if (he->he_modeid == AP_HOOK_MODE_UNKNOWN) {
330 		he->he_modeid  = modeid;
331 		he->he_modeval = modeval;
332 	}
333 
334 	for (i = 0; he->he_func[i] != NULL; i++)
335 		if (ap_hook_call_func(ap, he, he->he_func[i]))
336 			break;
337 
338 	if (i > 0 && he->he_modeid == AP_HOOK_MODE_ALL)
339 		rc = TRUE;
340 	else if (i == AP_HOOK_MAX_FUNCS || he->he_func[i] == NULL)
341 		rc = FALSE;
342 	else
343 		rc = TRUE;
344 
345 	va_end(ap);
346 	return rc;
347 }
348 
349 /*
350  * Call a hook
351  */
ap_hook_call(char * hook,...)352 API_EXPORT(int) ap_hook_call(char *hook, ...)
353 {
354 	int i;
355 	ap_hook_entry *he;
356 	va_list ap;
357 	int rc;
358 
359 	va_start(ap, hook);
360 
361 	if ((he = ap_hook_find(hook)) == NULL) {
362 		va_end(ap);
363 		return FALSE;
364 	}
365 	if (   he->he_sig == AP_HOOK_SIG_UNKNOWN
366 	    || he->he_modeid == AP_HOOK_MODE_UNKNOWN) {
367 		va_end(ap);
368 		return FALSE;
369 	}
370 
371 	for (i = 0; he->he_func[i] != NULL; i++)
372 		if (ap_hook_call_func(ap, he, he->he_func[i]))
373 			break;
374 
375 	if (i > 0 && he->he_modeid == AP_HOOK_MODE_ALL)
376 		rc = TRUE;
377 	else if (i == AP_HOOK_MAX_FUNCS || he->he_func[i] == NULL)
378 		rc = FALSE;
379 	else
380 		rc = TRUE;
381 
382 	va_end(ap);
383 	return rc;
384 }
385 
ap_hook_call_func(va_list ap,ap_hook_entry * he,ap_hook_func * hf)386 static int ap_hook_call_func(va_list ap, ap_hook_entry *he, ap_hook_func *hf)
387 {
388 	void *v_rc;
389 	ap_hook_value v_tmp;
390 	int rc;
391 
392 	/*
393 	* Now we dispatch the various function calls. We support function
394 	* signatures with up to 9 types (1 return type, 8 argument types) where
395 	* each argument can have 7 different types (ctx, char, int, long, float,
396 	* double, ptr), so theoretically there are 9^7 (=4782969) combinations
397 	* possible.  But because we don't need all of them, of course, we
398 	* implement only the following well chosen subset (duplicates are ok):
399 	*
400 	* 1. `The basic hook'.
401 	*
402 	*    void func()
403 	*
404 	* 2. The standard set of signatures which form all combinations of
405 	*    int&ptr based signatures for up to 3 arguments. We provide
406 	*    them per default for module authors.
407 	*
408 	*    int func()
409 	*    ptr func()
410 	*    int func(int)
411 	*    int func(ptr)
412 	*    ptr func(int)
413 	*    ptr func(ptr)
414 	*    int func(int,int)
415 	*    int func(int,ptr)
416 	*    int func(ptr,int)
417 	*    int func(ptr,ptr)
418 	*    ptr func(int,int)
419 	*    ptr func(int,ptr)
420 	*    ptr func(ptr,int)
421 	*    ptr func(ptr,ptr)
422 	*    int func(int,int,int)
423 	*    int func(int,int,ptr)
424 	*    int func(int,ptr,int)
425 	*    int func(int,ptr,ptr)
426 	*    int func(ptr,int,int)
427 	*    int func(ptr,int,ptr)
428 	*    int func(ptr,ptr,int)
429 	*    int func(ptr,ptr,ptr)
430 	*    ptr func(int,int,int)
431 	*    ptr func(int,int,ptr)
432 	*    ptr func(int,ptr,int)
433 	*    ptr func(int,ptr,ptr)
434 	*    ptr func(ptr,int,int)
435 	*    ptr func(ptr,int,ptr)
436 	*    ptr func(ptr,ptr,int)
437 	*    ptr func(ptr,ptr,ptr)
438 	*
439 	* 3. Actually currently used hooks.
440 	*
441 	*    int   func(ptr)                          [2x]
442 	*    int   func(ptr,ptr)                      [2x]
443 	*    int   func(ptr,ptr,int)                  [5x]
444 	*    int   func(ptr,ptr,ptr,int)              [1x]
445 	*    int   func(ptr,ptr,ptr,int,ptr)          [1x]
446 	*    int   func(ptr,ptr,ptr,ptr,int)          [1x]
447 	*    int   func(ptr,ptr,ptr,ptr,int,ptr)      [1x]
448 	*    ptr   func(ptr,ptr)                      [3x]
449 	*    ptr   func(ptr,ptr,ptr,ptr,ptr)          [1x]
450 	*    void  func(ptr)                          [2x]
451 	*    void  func(ptr,int,int)                  [1x]
452 	*    void  func(ptr,ptr)                      [5x]
453 	*    void  func(ptr,ptr,ptr)                  [3x]
454 	*    void  func(ptr,ptr,ptr,ptr)              [2x]
455 	*
456 	* To simplify the programming task we generate the actual dispatch code
457 	* for these calls via the embedded Perl script at the end of this source
458 	* file. This script parses the above lines and generates the section
459 	* below.  So, when you need more signature variants just add them to the
460 	* above list and run
461 	*
462 	*     $ perl ap_hook.c
463 	*
464 	* This automatically updates the above code.
465 	*/
466 
467 	rc = TRUE;
468 	v_rc = NULL;
469 	if (!AP_HOOK_SIG_HAS(he->he_sig, RC, void)) {
470 		if (he->he_modeid == AP_HOOK_MODE_DECLTMP) {
471 			/* the return variable is a temporary one */
472 			if (AP_HOOK_SIG_HAS(he->he_sig, RC, char))
473 				v_rc = &v_tmp.v_char;
474 			else if (AP_HOOK_SIG_HAS(he->he_sig, RC, int))
475 				v_rc = &v_tmp.v_int;
476 			else if (AP_HOOK_SIG_HAS(he->he_sig, RC, long))
477 				v_rc = &v_tmp.v_long;
478 			else if (AP_HOOK_SIG_HAS(he->he_sig, RC, float))
479 				v_rc = &v_tmp.v_float;
480 			else if (AP_HOOK_SIG_HAS(he->he_sig, RC, double))
481 				v_rc = &v_tmp.v_double;
482 			else if (AP_HOOK_SIG_HAS(he->he_sig, RC, ptr))
483 				v_rc = &v_tmp.v_ptr;
484 		}
485 		else {
486 			/* the return variable is provided by caller */
487 			v_rc = va_arg(ap, void *);
488 		}
489 	}
490 
491 	/* ----BEGIN GENERATED SECTION-------- */
492 	if (he->he_sig == AP_HOOK_SIG1(void)) {
493 		/* Call: void func() */
494 		((void(*)())(hf->hf_ptr))();
495 	}
496 	else if (he->he_sig == AP_HOOK_SIG1(int)) {
497 		/* Call: int func() */
498 		*((int *)v_rc) = ((int(*)())(hf->hf_ptr))();
499 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
500 	}
501 	else if (he->he_sig == AP_HOOK_SIG1(ptr)) {
502 		/* Call: ptr func() */
503 		*((void * *)v_rc) = ((void *(*)())(hf->hf_ptr))();
504 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
505 	}
506 	else if (he->he_sig == AP_HOOK_SIG2(int, int)) {
507 		/* Call: int func(int) */
508 		int   v1 = va_arg(ap, va_type(int));
509 		*((int *)v_rc) = ((int(*)(int))(hf->hf_ptr))(v1);
510 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
511 	}
512 	else if (he->he_sig == AP_HOOK_SIG2(int, ptr)) {
513 		/* Call: int func(ptr) */
514 		void *v1 = va_arg(ap, va_type(ptr));
515 		*((int *)v_rc) = ((int(*)(void *))(hf->hf_ptr))(v1);
516 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
517 	}
518 	else if (he->he_sig == AP_HOOK_SIG2(ptr, int)) {
519 		/* Call: ptr func(int) */
520 		int   v1 = va_arg(ap, va_type(int));
521 		*((void * *)v_rc) = ((void *(*)(int))(hf->hf_ptr))(v1);
522 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
523 	}
524 	else if (he->he_sig == AP_HOOK_SIG2(ptr, ptr)) {
525 		/* Call: ptr func(ptr) */
526 		void *v1 = va_arg(ap, va_type(ptr));
527 		*((void * *)v_rc) = ((void *(*)(void *))(hf->hf_ptr))(v1);
528 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
529 	}
530 	else if (he->he_sig == AP_HOOK_SIG3(int, int, int)) {
531 		/* Call: int func(int,int) */
532 		int   v1 = va_arg(ap, va_type(int));
533 		int   v2 = va_arg(ap, va_type(int));
534 		*((int *)v_rc) = ((int(*)(int, int))(hf->hf_ptr))(v1, v2);
535 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
536 	}
537 	else if (he->he_sig == AP_HOOK_SIG3(int, int, ptr)) {
538 		/* Call: int func(int,ptr) */
539 		int   v1 = va_arg(ap, va_type(int));
540 		void *v2 = va_arg(ap, va_type(ptr));
541 		*((int *)v_rc) = ((int(*)(int, void *))(hf->hf_ptr))(v1, v2);
542 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
543 	}
544 	else if (he->he_sig == AP_HOOK_SIG3(int, ptr, int)) {
545 		/* Call: int func(ptr,int) */
546 		void *v1 = va_arg(ap, va_type(ptr));
547 		int   v2 = va_arg(ap, va_type(int));
548 		*((int *)v_rc) = ((int(*)(void *, int))(hf->hf_ptr))(v1, v2);
549 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
550 	}
551 	else if (he->he_sig == AP_HOOK_SIG3(int, ptr, ptr)) {
552 		/* Call: int func(ptr,ptr) */
553 		void *v1 = va_arg(ap, va_type(ptr));
554 		void *v2 = va_arg(ap, va_type(ptr));
555 		*((int *)v_rc) = ((int(*)(void *, void *))(hf->hf_ptr))(v1, v2);
556 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
557 	}
558 	else if (he->he_sig == AP_HOOK_SIG3(ptr, int, int)) {
559 		/* Call: ptr func(int,int) */
560 		int   v1 = va_arg(ap, va_type(int));
561 		int   v2 = va_arg(ap, va_type(int));
562 		*((void * *)v_rc) = ((void *(*)(int, int))(hf->hf_ptr))(v1, v2);
563 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
564 	}
565 	else if (he->he_sig == AP_HOOK_SIG3(ptr, int, ptr)) {
566 		/* Call: ptr func(int,ptr) */
567 		int   v1 = va_arg(ap, va_type(int));
568 		void *v2 = va_arg(ap, va_type(ptr));
569 		*((void * *)v_rc) = ((void *(*)(int, void *))(hf->hf_ptr))(v1, v2);
570 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
571 	}
572 	else if (he->he_sig == AP_HOOK_SIG3(ptr, ptr, int)) {
573 		/* Call: ptr func(ptr,int) */
574 		void *v1 = va_arg(ap, va_type(ptr));
575 		int   v2 = va_arg(ap, va_type(int));
576 		*((void * *)v_rc) = ((void *(*)(void *, int))(hf->hf_ptr))(v1, v2);
577 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
578 	}
579 	else if (he->he_sig == AP_HOOK_SIG3(ptr, ptr, ptr)) {
580 		/* Call: ptr func(ptr,ptr) */
581 		void *v1 = va_arg(ap, va_type(ptr));
582 		void *v2 = va_arg(ap, va_type(ptr));
583 		*((void * *)v_rc) = ((void *(*)(void *, void *))(hf->hf_ptr))(v1, v2);
584 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
585 	}
586 	else if (he->he_sig == AP_HOOK_SIG4(int, int, int, int)) {
587 		/* Call: int func(int,int,int) */
588 		int   v1 = va_arg(ap, va_type(int));
589 		int   v2 = va_arg(ap, va_type(int));
590 		int   v3 = va_arg(ap, va_type(int));
591 		*((int *)v_rc) = ((int(*)(int, int, int))(hf->hf_ptr))(v1, v2, v3);
592 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
593 	}
594 	else if (he->he_sig == AP_HOOK_SIG4(int, int, int, ptr)) {
595 		/* Call: int func(int,int,ptr) */
596 		int   v1 = va_arg(ap, va_type(int));
597 		int   v2 = va_arg(ap, va_type(int));
598 		void *v3 = va_arg(ap, va_type(ptr));
599 		*((int *)v_rc) = ((int(*)(int, int, void *))(hf->hf_ptr))(v1, v2, v3);
600 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
601 	}
602 	else if (he->he_sig == AP_HOOK_SIG4(int, int, ptr, int)) {
603 		/* Call: int func(int,ptr,int) */
604 		int   v1 = va_arg(ap, va_type(int));
605 		void *v2 = va_arg(ap, va_type(ptr));
606 		int   v3 = va_arg(ap, va_type(int));
607 		*((int *)v_rc) = ((int(*)(int, void *, int))(hf->hf_ptr))(v1, v2, v3);
608 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
609 	}
610 	else if (he->he_sig == AP_HOOK_SIG4(int, int, ptr, ptr)) {
611 		/* Call: int func(int,ptr,ptr) */
612 		int   v1 = va_arg(ap, va_type(int));
613 		void *v2 = va_arg(ap, va_type(ptr));
614 		void *v3 = va_arg(ap, va_type(ptr));
615 		*((int *)v_rc) = ((int(*)(int, void *, void *))(hf->hf_ptr))(v1, v2, v3);
616 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
617 	}
618 	else if (he->he_sig == AP_HOOK_SIG4(int, ptr, int, int)) {
619 		/* Call: int func(ptr,int,int) */
620 		void *v1 = va_arg(ap, va_type(ptr));
621 		int   v2 = va_arg(ap, va_type(int));
622 		int   v3 = va_arg(ap, va_type(int));
623 		*((int *)v_rc) = ((int(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
624 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
625 	}
626 	else if (he->he_sig == AP_HOOK_SIG4(int, ptr, int, ptr)) {
627 		/* Call: int func(ptr,int,ptr) */
628 		void *v1 = va_arg(ap, va_type(ptr));
629 		int   v2 = va_arg(ap, va_type(int));
630 		void *v3 = va_arg(ap, va_type(ptr));
631 		*((int *)v_rc) = ((int(*)(void *, int, void *))(hf->hf_ptr))(v1, v2, v3);
632 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
633 	}
634 	else if (he->he_sig == AP_HOOK_SIG4(int, ptr, ptr, int)) {
635 		/* Call: int func(ptr,ptr,int) */
636 		void *v1 = va_arg(ap, va_type(ptr));
637 		void *v2 = va_arg(ap, va_type(ptr));
638 		int   v3 = va_arg(ap, va_type(int));
639 		*((int *)v_rc) = ((int(*)(void *, void *, int))(hf->hf_ptr))(v1, v2, v3);
640 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
641 	}
642 	else if (he->he_sig == AP_HOOK_SIG4(int, ptr, ptr, ptr)) {
643 		/* Call: int func(ptr,ptr,ptr) */
644 		void *v1 = va_arg(ap, va_type(ptr));
645 		void *v2 = va_arg(ap, va_type(ptr));
646 		void *v3 = va_arg(ap, va_type(ptr));
647 		*((int *)v_rc) = ((int(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
648 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
649 	}
650 	else if (he->he_sig == AP_HOOK_SIG4(ptr, int, int, int)) {
651 		/* Call: ptr func(int,int,int) */
652 		int   v1 = va_arg(ap, va_type(int));
653 		int   v2 = va_arg(ap, va_type(int));
654 		int   v3 = va_arg(ap, va_type(int));
655 		*((void * *)v_rc) = ((void *(*)(int, int, int))(hf->hf_ptr))(v1, v2, v3);
656 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
657 	}
658 	else if (he->he_sig == AP_HOOK_SIG4(ptr, int, int, ptr)) {
659 		/* Call: ptr func(int,int,ptr) */
660 		int   v1 = va_arg(ap, va_type(int));
661 		int   v2 = va_arg(ap, va_type(int));
662 		void *v3 = va_arg(ap, va_type(ptr));
663 		*((void * *)v_rc) = ((void *(*)(int, int, void *))(hf->hf_ptr))(v1, v2, v3);
664 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
665 	}
666 	else if (he->he_sig == AP_HOOK_SIG4(ptr, int, ptr, int)) {
667 		/* Call: ptr func(int,ptr,int) */
668 		int   v1 = va_arg(ap, va_type(int));
669 		void *v2 = va_arg(ap, va_type(ptr));
670 		int   v3 = va_arg(ap, va_type(int));
671 		*((void * *)v_rc) = ((void *(*)(int, void *, int))(hf->hf_ptr))(v1, v2, v3);
672 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
673 	}
674 	else if (he->he_sig == AP_HOOK_SIG4(ptr, int, ptr, ptr)) {
675 		/* Call: ptr func(int,ptr,ptr) */
676 		int   v1 = va_arg(ap, va_type(int));
677 		void *v2 = va_arg(ap, va_type(ptr));
678 		void *v3 = va_arg(ap, va_type(ptr));
679 		*((void * *)v_rc) = ((void *(*)(int, void *, void *))(hf->hf_ptr))(v1, v2, v3);
680 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
681 	}
682 	else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, int, int)) {
683 		/* Call: ptr func(ptr,int,int) */
684 		void *v1 = va_arg(ap, va_type(ptr));
685 		int   v2 = va_arg(ap, va_type(int));
686 		int   v3 = va_arg(ap, va_type(int));
687 		*((void * *)v_rc) = ((void *(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
688 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
689 	}
690 	else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, int, ptr)) {
691 		/* Call: ptr func(ptr,int,ptr) */
692 		void *v1 = va_arg(ap, va_type(ptr));
693 		int   v2 = va_arg(ap, va_type(int));
694 		void *v3 = va_arg(ap, va_type(ptr));
695 		*((void * *)v_rc) = ((void *(*)(void *, int, void *))(hf->hf_ptr))(v1, v2, v3);
696 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
697 	}
698 	else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, ptr, int)) {
699 		/* Call: ptr func(ptr,ptr,int) */
700 		void *v1 = va_arg(ap, va_type(ptr));
701 		void *v2 = va_arg(ap, va_type(ptr));
702 		int   v3 = va_arg(ap, va_type(int));
703 		*((void * *)v_rc) = ((void *(*)(void *, void *, int))(hf->hf_ptr))(v1, v2, v3);
704 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
705 	}
706 	else if (he->he_sig == AP_HOOK_SIG4(ptr, ptr, ptr, ptr)) {
707 		/* Call: ptr func(ptr,ptr,ptr) */
708 		void *v1 = va_arg(ap, va_type(ptr));
709 		void *v2 = va_arg(ap, va_type(ptr));
710 		void *v3 = va_arg(ap, va_type(ptr));
711 		*((void * *)v_rc) = ((void *(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
712 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
713 	}
714 	else if (he->he_sig == AP_HOOK_SIG5(int, ptr, ptr, ptr, int)) {
715 		/* Call: int func(ptr,ptr,ptr,int) */
716 		void *v1 = va_arg(ap, va_type(ptr));
717 		void *v2 = va_arg(ap, va_type(ptr));
718 		void *v3 = va_arg(ap, va_type(ptr));
719 		int   v4 = va_arg(ap, va_type(int));
720 		*((int *)v_rc) = ((int(*)(void *, void *, void *, int))(hf->hf_ptr))(v1, v2, v3, v4);
721 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
722 	}
723 	else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, int, ptr)) {
724 		/* Call: int func(ptr,ptr,ptr,int,ptr) */
725 		void *v1 = va_arg(ap, va_type(ptr));
726 		void *v2 = va_arg(ap, va_type(ptr));
727 		void *v3 = va_arg(ap, va_type(ptr));
728 		int   v4 = va_arg(ap, va_type(int));
729 		void *v5 = va_arg(ap, va_type(ptr));
730 		*((int *)v_rc) = ((int(*)(void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5);
731 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
732 	}
733 	else if (he->he_sig == AP_HOOK_SIG6(int, ptr, ptr, ptr, ptr, int)) {
734 		/* Call: int func(ptr,ptr,ptr,ptr,int) */
735 		void *v1 = va_arg(ap, va_type(ptr));
736 		void *v2 = va_arg(ap, va_type(ptr));
737 		void *v3 = va_arg(ap, va_type(ptr));
738 		void *v4 = va_arg(ap, va_type(ptr));
739 		int   v5 = va_arg(ap, va_type(int));
740 		*((int *)v_rc) = ((int(*)(void *, void *, void *, void *, int))(hf->hf_ptr))(v1, v2, v3, v4, v5);
741 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
742 	}
743 	else if (he->he_sig == AP_HOOK_SIG7(int, ptr, ptr, ptr, ptr, int, ptr)) {
744 		/* Call: int func(ptr,ptr,ptr,ptr,int,ptr) */
745 		void *v1 = va_arg(ap, va_type(ptr));
746 		void *v2 = va_arg(ap, va_type(ptr));
747 		void *v3 = va_arg(ap, va_type(ptr));
748 		void *v4 = va_arg(ap, va_type(ptr));
749 		int   v5 = va_arg(ap, va_type(int));
750 		void *v6 = va_arg(ap, va_type(ptr));
751 		*((int *)v_rc) = ((int(*)(void *, void *, void *, void *, int, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5, v6);
752 		rc = (*((int *)v_rc) != he->he_modeval.v_int);
753 	}
754 	else if (he->he_sig == AP_HOOK_SIG6(ptr, ptr, ptr, ptr, ptr, ptr)) {
755 		/* Call: ptr func(ptr,ptr,ptr,ptr,ptr) */
756 		void *v1 = va_arg(ap, va_type(ptr));
757 		void *v2 = va_arg(ap, va_type(ptr));
758 		void *v3 = va_arg(ap, va_type(ptr));
759 		void *v4 = va_arg(ap, va_type(ptr));
760 		void *v5 = va_arg(ap, va_type(ptr));
761 		*((void * *)v_rc) = ((void *(*)(void *, void *, void *, void *, void *))(hf->hf_ptr))(v1, v2, v3, v4, v5);
762 		rc = (*((void * *)v_rc) != he->he_modeval.v_ptr);
763 	}
764 	else if (he->he_sig == AP_HOOK_SIG2(void, ptr)) {
765 		/* Call: void func(ptr) */
766 		void *v1 = va_arg(ap, va_type(ptr));
767 		((void(*)(void *))(hf->hf_ptr))(v1);
768 	}
769 	else if (he->he_sig == AP_HOOK_SIG4(void, ptr, int, int)) {
770 		/* Call: void func(ptr,int,int) */
771 		void *v1 = va_arg(ap, va_type(ptr));
772 		int   v2 = va_arg(ap, va_type(int));
773 		int   v3 = va_arg(ap, va_type(int));
774 		((void(*)(void *, int, int))(hf->hf_ptr))(v1, v2, v3);
775 	}
776 	else if (he->he_sig == AP_HOOK_SIG3(void, ptr, ptr)) {
777 		/* Call: void func(ptr,ptr) */
778 		void *v1 = va_arg(ap, va_type(ptr));
779 		void *v2 = va_arg(ap, va_type(ptr));
780 		((void(*)(void *, void *))(hf->hf_ptr))(v1, v2);
781 	}
782 	else if (he->he_sig == AP_HOOK_SIG4(void, ptr, ptr, ptr)) {
783 		/* Call: void func(ptr,ptr,ptr) */
784 		void *v1 = va_arg(ap, va_type(ptr));
785 		void *v2 = va_arg(ap, va_type(ptr));
786 		void *v3 = va_arg(ap, va_type(ptr));
787 		((void(*)(void *, void *, void *))(hf->hf_ptr))(v1, v2, v3);
788 	}
789 	else if (he->he_sig == AP_HOOK_SIG5(void, ptr, ptr, ptr, ptr)) {
790 		/* Call: void func(ptr,ptr,ptr,ptr) */
791 		void *v1 = va_arg(ap, va_type(ptr));
792 		void *v2 = va_arg(ap, va_type(ptr));
793 		void *v3 = va_arg(ap, va_type(ptr));
794 		void *v4 = va_arg(ap, va_type(ptr));
795 		((void(*)(void *, void *, void *, void *))(hf->hf_ptr))(v1, v2, v3, v4);
796 	}
797 	/* ----END GENERATED SECTION---------- */
798 	else
799 		ap_log_assert("hook signature not implemented", __FILE__, 0);
800 
801 	if (he->he_modeid == AP_HOOK_MODE_ALL)
802 		rc = FALSE;
803 	else if (he->he_modeid == AP_HOOK_MODE_TOPMOST)
804 		rc = TRUE;
805 
806 	return rc;
807 }
808