• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
26 #define _WINSOCK_DEPRECATED_NO_WARNINGS
27 #endif
28 #include "private-lib-core.h"
29 
30 /*
31  * ie, if the plugins api needed at all
32  */
33 
34 #if defined(LWS_WITH_PLUGINS_API) && (UV_VERSION_MAJOR > 0)
35 
36 const lws_plugin_header_t *
lws_plat_dlopen(struct lws_plugin ** pplugin,const char * libpath,const char * sofilename,const char * _class,each_plugin_cb_t each,void * each_user)37 lws_plat_dlopen(struct lws_plugin **pplugin, const char *libpath,
38 		const char *sofilename, const char *_class,
39 		each_plugin_cb_t each, void *each_user)
40 {
41 	const lws_plugin_header_t *hdr;
42 	struct lws_plugin *pin;
43 	char sym[96], *dot;
44 	uv_lib_t lib;
45 	void *v;
46 	int m;
47 
48 	lib.errmsg = NULL;
49 	lib.handle = NULL;
50 
51 	if (uv_dlopen(libpath, &lib)) {
52 		uv_dlerror(&lib);
53 		lwsl_err("Error loading DSO: %s\n", lib.errmsg);
54 		uv_dlclose(&lib);
55 		return NULL;
56 	}
57 
58 	/* we could open it... can we get his export struct? */
59 	m = lws_snprintf(sym, sizeof(sym) - 1, "%s", sofilename);
60 	if (m < 4)
61 		goto bail;
62 	dot = strchr(sym, '.');
63 	if (dot)
64 		*dot = '\0'; /* snip the .so or .lib or what-have-you*/
65 
66 	if (uv_dlsym(&lib, sym, &v)) {
67 		uv_dlerror(&lib);
68 		lwsl_err("%s: Failed to get '%s' on %s: %s\n",
69 			 __func__, path, dent.name, lib.errmsg);
70 		goto bail;
71 	}
72 
73 	hdr = (const lws_plugin_header_t *)v;
74 	if (hdr->api_magic != LWS_PLUGIN_API_MAGIC) {
75 		lwsl_info("%s: plugin %s has outdated api %d (vs %d)\n",
76 			 __func__, libpath, hdr->api_magic,
77 			 LWS_PLUGIN_API_MAGIC);
78 		goto bail;
79 	}
80 
81 	if (strcmp(hdr->lws_build_hash, LWS_BUILD_HASH))
82 		goto bail;
83 
84 	if (strcmp(hdr->_class, _class))
85 		goto bail;
86 
87 	/*
88 	 * We don't already have one of these, right?
89 	 */
90 
91 	pin = *pplugin;
92 	while (pin) {
93 		if (!strcmp(pin->hdr->name, hdr->name))
94 			goto bail;
95 		pin = pin->list;
96 	}
97 
98 	/*
99 	 * OK let's bring it in
100 	 */
101 
102 	pin = lws_malloc(sizeof(*pin), __func__);
103 	if (!pin)
104 		goto bail;
105 
106 	pin->list = *pplugin;
107 	*pplugin = pin;
108 
109 	pin->u.lib = lib;
110 	pin->hdr = hdr;
111 
112 	if (each)
113 		each(pin, each_user);
114 
115 	return hdr;
116 
117 bail:
118 	uv_dlclose(&lib);
119 
120 	return NULL;
121 }
122 
123 int
lws_plat_destroy_dl(struct lws_plugin * p)124 lws_plat_destroy_dl(struct lws_plugin *p)
125 {
126 	return uv_dlclose(&p->u.lib);
127 }
128 
129 #endif
130 
131 /*
132  * Specifically for protocol plugins support
133  */
134 
135 #if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
136 
137 static int
protocol_plugin_cb(struct lws_plugin * pin,void * each_user)138 protocol_plugin_cb(struct lws_plugin *pin, void *each_user)
139 {
140 	struct lws_context *context = (struct lws_context *)each_user;
141 	const lws_plugin_protocol_t *plpr =
142 				(const lws_plugin_protocol_t *)pin->hdr;
143 
144 	context->plugin_protocol_count += plpr->count_protocols;
145 	context->plugin_extension_count += plpr->count_extensions;
146 
147 	return 0;
148 }
149 #endif
150 
151 int
lws_plat_plugins_init(struct lws_context * context,const char * const * d)152 lws_plat_plugins_init(struct lws_context *context, const char * const *d)
153 {
154 #if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
155 	if (info->plugin_dirs) {
156 		uv_loop_init(&context->uv.loop);
157 		lws_plugins_init(&context->plugin_list, info->plugin_dirs,
158 				 "lws_protocol_plugin", NULL,
159 				 protocol_plugin_cb, context);
160 	}
161 #endif
162 
163 	return 0;
164 }
165 
166 int
lws_plat_plugins_destroy(struct lws_context * context)167 lws_plat_plugins_destroy(struct lws_context * context)
168 {
169 #if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
170 	if (lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV) &&
171 	    context->plugin_list) {
172 		lws_plugins_destroy(&context->plugin_list, NULL, NULL);
173 		while (uv_loop_close(&context->uv.loop))
174 			;
175 	}
176 #endif
177 
178 	return 0;
179 }
180