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