1
1
#include <string.h>
2
2
#include <stdio.h>
3
+ #include <sys/types.h>
4
+ #include <dirent.h>
5
+ #include <errno.h>
6
+ #include <dlfcn.h>
3
7
4
8
#include "websocksy.h"
5
9
#include "plugin.h"
6
10
11
+ //cheap out because i dont want the overhead of allocating here
12
+ #define MAX_PLUGIN_PATH 4096
13
+
7
14
static size_t framing_functions = 0 ;
8
15
static ws_framing * framing_function = NULL ;
9
16
static char * * framing_function_name = NULL ;
10
17
18
+ static size_t attached_libraries = 0 ;
19
+ static void * * attached_library = NULL ;
20
+
21
+ static void * plugin_attach (char * path ){
22
+ void * module = dlopen (path , RTLD_LAZY );
23
+
24
+ if (!module ){
25
+ fprintf (stderr , "Failed to load module %s\n" , dlerror ());
26
+ return NULL ;
27
+ }
28
+
29
+ attached_library = realloc (attached_library , (attached_libraries + 1 ) * sizeof (void * ));
30
+ if (!attached_library ){
31
+ fprintf (stderr , "Failed to allocate memory\n" );
32
+ dlclose (module );
33
+ return NULL ;
34
+ }
35
+
36
+ attached_library [attached_libraries ] = module ;
37
+ attached_libraries ++ ;
38
+
39
+ return module ;
40
+ }
41
+
11
42
int plugin_framing_load (char * path ){
12
- //TODO load plugins
43
+ DIR * directory = opendir (path );
44
+ struct dirent * file = NULL ;
45
+ char plugin_path [MAX_PLUGIN_PATH ] = "" ;
46
+ size_t path_len ;
47
+
48
+ if (strlen (path ) >= sizeof (plugin_path ) - 20 ){
49
+ fprintf (stderr , "Plugin path length exceeds limit\n" );
50
+ return 1 ;
51
+ }
52
+
53
+ strncpy (plugin_path , path , sizeof (plugin_path ) - 2 );
54
+ if (path [strlen (path ) - 1 ] != '/' ){
55
+ plugin_path [strlen (path )] = '/' ;
56
+ plugin_path [strlen (path ) + 1 ] = 0 ;
57
+ }
58
+ path_len = strlen (plugin_path );
59
+
60
+ if (!directory ){
61
+ fprintf (stderr , "Failed to open directory %s: %s\n" , path , strerror (errno ));
62
+ return 0 ;
63
+ }
64
+
65
+ for (file = readdir (directory ); file ; file = readdir (directory )){
66
+ //skip backends
67
+ if (!strncmp (file -> d_name , "backend_" , 8 )){
68
+ continue ;
69
+ }
70
+ //skip file not ending in .so
71
+ if (strlen (file -> d_name ) < 4 || strcmp (file -> d_name + strlen (file -> d_name ) - 3 , ".so" )){
72
+ continue ;
73
+ }
74
+ strncpy (plugin_path + path_len , file -> d_name , sizeof (plugin_path ) - path_len - 2 );
75
+ if (!plugin_attach (plugin_path )){
76
+ return 1 ;
77
+ }
78
+ }
79
+
80
+ closedir (directory );
13
81
return 0 ;
14
82
}
15
83
16
- int plugin_backend_load (char * backend_requested , ws_backend * backend ){
17
- //TODO load backend
84
+ int plugin_backend_load (char * path , char * backend_requested , ws_backend * backend ){
85
+ char plugin_path [MAX_PLUGIN_PATH ] = "" ;
86
+ void * handle = NULL ;
87
+
88
+ if (strlen (path ) >= sizeof (plugin_path ) - 30 ){
89
+ fprintf (stderr , "Plugin path length exceeds limit\n" );
90
+ return 1 ;
91
+ }
92
+
93
+ snprintf (plugin_path , sizeof (plugin_path ), "%s%sbackend_%s.so" , path , (path [strlen (path ) - 1 ] == '/' ) ? "" : "/" , backend_requested );
94
+
95
+ handle = plugin_attach (plugin_path );
96
+ if (!handle ){
97
+ return 1 ;
98
+ }
99
+
100
+ //read backend functions into the structure
101
+ backend -> init = (ws_backend_init ) dlsym (handle , "init" );
102
+ backend -> config = (ws_backend_configure ) dlsym (handle , "configure" );
103
+ backend -> query = (ws_backend_query ) dlsym (handle , "query" );
104
+ backend -> cleanup = (ws_backend_cleanup ) dlsym (handle , "cleanup" );
105
+
106
+ if (!backend -> init || !backend -> query ){
107
+ fprintf (stderr , "Backend module %s is missing required symbols\n" , plugin_path );
108
+ return 1 ;
109
+ }
18
110
return 0 ;
19
111
}
20
112
@@ -63,8 +155,8 @@ ws_framing plugin_framing(char* name){
63
155
64
156
void plugin_cleanup (){
65
157
size_t u ;
66
- //TODO dlclose all plugins
67
-
158
+
159
+ //free allocated buffers
68
160
for (u = 0 ; u < framing_functions ; u ++ ){
69
161
free (framing_function_name [u ]);
70
162
}
@@ -74,4 +166,11 @@ void plugin_cleanup(){
74
166
framing_function_name = 0 ;
75
167
framing_function = NULL ;
76
168
framing_functions = 0 ;
169
+
170
+ //dlclose all plugins
171
+ for (u = 0 ; u < attached_libraries ; u ++ ){
172
+ dlclose (attached_library [u ]);
173
+ }
174
+ free (attached_library );
175
+ attached_libraries = 0 ;
77
176
}
0 commit comments