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