Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-utils / load_plugin.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * Plugin Loading Utils
4  *
5  * Copyright 2011 Vic Lee
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <freerdp/utils/file.h>
24 #include <freerdp/utils/print.h>
25 #include <freerdp/utils/memory.h>
26 #include <freerdp/utils/load_plugin.h>
27
28 #ifdef _WIN32
29
30 #include <windows.h>
31 #define DLOPEN(f) LoadLibraryA(f)
32 #define DLSYM(f, n) GetProcAddress(f, n)
33 #define DLCLOSE(f) FreeLibrary(f)
34 #define DLERROR() ""
35
36 #else
37
38 #include <dlfcn.h>
39 #include <unistd.h>
40 #define DLOPEN(f) dlopen(f, RTLD_LOCAL | RTLD_LAZY)
41 #define DLSYM(f, n) dlsym(f, n)
42 #define DLCLOSE(f) dlclose(f)
43 #define DLERROR() dlerror()
44
45 #endif
46
47 void* freerdp_open_library(const char* file)
48 {
49         void* library;
50
51         library = DLOPEN(file);
52
53         if (library == NULL)
54         {
55                 printf("freerdp_load_library: failed to open %s: %s\n", file, DLERROR());
56                 return NULL;
57         }
58
59         return library;
60 }
61
62 void* freerdp_get_library_symbol(void* library, const char* name)
63 {
64         void* symbol;
65
66         symbol = DLSYM(library, name);
67
68         if (symbol == NULL)
69         {
70                 printf("freerdp_get_library_symbol: failed to load %s: %s\n", name, DLERROR());
71                 return NULL;
72         }
73
74         return symbol;
75 }
76
77 boolean freerdp_close_library(void* library)
78 {
79         int status;
80
81         status = DLCLOSE(library);
82
83 #ifdef _WIN32
84         if (status != 0)
85 #else
86         if (status == 0)
87 #endif
88         {
89                 printf("freerdp_free_library: failed to close: %s\n", DLERROR());
90                 return false;
91         }
92
93         return true;
94 }
95
96 void* freerdp_load_library_symbol(const char* file, const char* name)
97 {
98         void* library;
99         void* symbol;
100
101         library = DLOPEN(file);
102
103         if (library == NULL)
104         {
105                 printf("freerdp_load_library_symbol: failed to open %s: %s\n", file, DLERROR());
106                 return NULL;
107         }
108
109         symbol = DLSYM(library, name);
110
111         if (symbol == NULL)
112         {
113                 printf("freerdp_load_library_symbol: failed to load %s: %s\n", file, DLERROR());
114                 return NULL;
115         }
116
117         return symbol;
118 }
119
120 void* freerdp_load_plugin(const char* name, const char* entry_name)
121 {
122         char* path;
123         void* entry;
124         char* suffixed_name;
125
126         suffixed_name = freerdp_append_shared_library_suffix((char*) name);
127
128         if (!freerdp_path_contains_separator(suffixed_name))
129         {
130                 /* no explicit path given, use default path */
131                 path = freerdp_construct_path(PLUGIN_PATH, suffixed_name);
132         }
133         else
134         {
135                 /* explicit path given, use it instead of default path */
136                 path = xstrdup(suffixed_name);
137         }
138
139         entry = freerdp_load_library_symbol(path, entry_name);
140
141         xfree(suffixed_name);
142         xfree(path);
143
144         if (entry == NULL)
145         {
146                 printf("freerdp_load_plugin: failed to load %s/%s\n", name, entry_name);
147                 return NULL;
148         }
149
150         return entry;
151 }
152
153 void* freerdp_load_channel_plugin(rdpSettings* settings, const char* name, const char* entry_name)
154 {
155         char* path;
156         void* entry;
157         char* suffixed_name;
158
159         suffixed_name = freerdp_append_shared_library_suffix((char*) name);
160
161         if (!freerdp_path_contains_separator(suffixed_name))
162         {
163                 /* no explicit path given, use default path */
164
165                 if (!settings->development_mode)
166                 {
167                         path = freerdp_construct_path(PLUGIN_PATH, suffixed_name);
168                 }
169                 else
170                 {
171                         char* dot;
172                         char* plugin_name;
173                         char* channels_path;
174                         char* channel_subpath;
175
176                         dot = strrchr(suffixed_name, '.');
177                         plugin_name = xmalloc((dot - suffixed_name) + 1);
178                         strncpy(plugin_name, suffixed_name, (dot - suffixed_name));
179                         plugin_name[(dot - suffixed_name)] = '\0';
180
181                         channels_path = freerdp_construct_path(settings->development_path, "channels");
182                         channel_subpath = freerdp_construct_path(channels_path, plugin_name);
183
184                         path = freerdp_construct_path(channel_subpath, suffixed_name);
185
186                         xfree(plugin_name);
187                         xfree(channels_path);
188                         xfree(channel_subpath);
189                 }
190         }
191         else
192         {
193                 /* explicit path given, use it instead of default path */
194                 path = xstrdup(suffixed_name);
195         }
196
197         entry = freerdp_load_library_symbol(path, entry_name);
198
199         xfree(suffixed_name);
200         xfree(path);
201
202         if (entry == NULL)
203         {
204                 printf("freerdp_load_channel_plugin: failed to load %s/%s\n", name, entry_name);
205                 return NULL;
206         }
207
208         return entry;
209 }