1 #include "config.h"
2 #include "alarm.h"
3 #include "userloader.h"
4 #include "configuration.h"
5 #ifdef USE_EMBEDDED_PERL
6 #include "perl.h"
7 #endif
8
9 static int handler_count = 0;
10 static struct dlfuncs handlers[1024] = { {0} };
11
register_shared(char * path,char * func,char type)12 int register_shared(char *path, char *func, char type) {
13 struct dlfuncs *handler;
14 char fullpath[MAXPATHLEN];
15 char fullsymbol[128];
16
17 #ifdef NEED_SYMBOL_PREFIX
18 snprintf(fullsymbol, sizeof(fullsymbol), "_%s", func);
19 #else
20 strncpy(fullsymbol, func, sizeof(fullsymbol));
21 #endif
22 snprintf(fullpath, MAXPATHLEN, "%s/%s", default_library_path, path);
23 if((type != DLFUNCS_TYPE_ON_UP) &&
24 (type != DLFUNCS_TYPE_ON_DOWN) &&
25 (type != DLFUNCS_TYPE_POST_UP) &&
26 (type != DLFUNCS_TYPE_POST_DOWN)) {
27 wack_alarm( PRINT, "register_shared called with unknown type: %d",
28 type );
29 return -1;
30 }
31 handler = &handlers[handler_count];
32 handler->handle = dlopen(fullpath, RTLD_NOW|RTLD_GLOBAL);
33 if(!handler->handle) {
34 strncat(fullpath, "."BUNDLEEXT, MAXPATHLEN);
35 handler->handle = dlopen(fullpath, RTLD_NOW|RTLD_GLOBAL);
36 }
37 if(!handler->handle) {
38 wack_alarm( PRINT, "register_shared open of %s failed: %s",
39 fullpath, dlerror() );
40 return -2;
41 }
42 if((handler->handler = dlsym(handler->handle, fullsymbol)) == NULL) {
43 wack_alarm( PRINT, "register_shared could not find symbol %s: %s",
44 fullsymbol, dlerror() );
45 dlclose(handler->handle);
46 return -3;
47 }
48 handler->genre = DLFUNCS_GENRE_DL;
49 handler->type = type;
50 handler_count++;
51 return type;
52 }
register_perl(char * func,char type)53 int register_perl(char *func, char type) {
54 struct dlfuncs *handler;
55
56 handler = &handlers[handler_count];
57 handler->genre = DLFUNCS_GENRE_PERL;
58 handler->func = func;
59 handler->type = type;
60 handler_count++;
61 return type;
62 }
deregister_all()63 int deregister_all() {
64 int i;
65 for(i=0;i<handler_count;i++) {
66 dlclose(handlers[i].handle);
67 }
68 handler_count = 0;
69 return i;
70 }
execute_all_user_simple(char type)71 int execute_all_user_simple(char type) {
72 int i, count = 0;
73 struct interface safe_pseudo;
74 struct interface safe_extras[MAX_DEP_IF];
75 struct interface safe_real;
76
77 memset(&safe_pseudo, 0, sizeof(struct interface));
78 memset(safe_extras, 0, sizeof(struct interface)*MAX_DEP_IF);
79 memset(&safe_real, 0, sizeof(struct interface));
80
81 for(i=0;i<handler_count;i++) {
82 if(handlers[i].type == type) {
83 switch(handlers[i].genre) {
84 case DLFUNCS_GENRE_DL:
85 handlers[i].handler(safe_pseudo, safe_extras, safe_real);
86 break;
87 #ifdef USE_EMBEDDED_PERL
88 case DLFUNCS_GENRE_PERL:
89 perl_handler(handlers[i].func,
90 &safe_pseudo, safe_extras, &safe_real);
91 break;
92 #endif
93 default:
94 wack_alarm(PRINT, "Unknown user function genre: %d",
95 handlers[i].genre);
96 }
97 count++;
98 }
99 }
100 return count;
101 }
execute_all_user(struct interface pseudo,struct interface * extras,struct interface real,char type)102 int execute_all_user(struct interface pseudo,
103 struct interface *extras,
104 struct interface real,
105 char type) {
106 int i, count = 0;
107 struct interface safe_pseudo;
108 struct interface safe_extras[MAX_DEP_IF];
109 struct interface safe_real;
110
111 /* Let's copy this so people can't f them up */
112 memcpy(&safe_pseudo, &pseudo, sizeof(struct interface));
113 memcpy(safe_extras, extras, sizeof(struct interface)*MAX_DEP_IF);
114 memcpy(&safe_real, &real, sizeof(struct interface));
115 for(i=0;i<handler_count;i++) {
116 if(handlers[i].type == type) {
117 switch(handlers[i].genre) {
118 case DLFUNCS_GENRE_DL:
119 handlers[i].handler(safe_pseudo, safe_extras, safe_real);
120 break;
121 #ifdef USE_EMBEDDED_PERL
122 case DLFUNCS_GENRE_PERL:
123 perl_handler(handlers[i].func,
124 &safe_pseudo, safe_extras, &safe_real);
125 break;
126 #endif
127 default:
128 wack_alarm(PRINT, "Unknown user function genre: %d",
129 handlers[i].genre);
130 }
131 count++;
132 }
133 }
134 return count;
135 }
136