nss: upgrade to release 3.73
[LibreOffice.git] / include / LibreOfficeKit / LibreOfficeKitInit.h
blob8a48bd8392bed158238c7be31939243440bf5f85
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #ifndef INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITINIT_H
11 #define INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITINIT_H
13 #include <LibreOfficeKit/LibreOfficeKit.h>
15 #ifdef __cplusplus
16 extern "C"
18 #endif
20 #if defined __GNUC__ || defined __clang__
21 # define LOK_TOLERATE_UNUSED __attribute__((used))
22 #else
23 # define LOK_TOLERATE_UNUSED
24 #endif
26 #if defined(__linux__) || defined (__FreeBSD__) || defined(_AIX) ||\
27 defined(_WIN32) || defined(__APPLE__) || defined (__NetBSD__) ||\
28 defined (__sun) || defined(__OpenBSD__)
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/stat.h>
35 #ifndef _WIN32
37 #include <dlfcn.h>
39 #ifdef _AIX
40 # include <sys/ldr.h>
41 #endif
42 #ifdef __APPLE__
43 #define TARGET_LIB "lib" "sofficeapp" ".dylib"
44 #define TARGET_MERGED_LIB "lib" "mergedlo" ".dylib"
45 #else
46 #define TARGET_LIB "lib" "sofficeapp" ".so"
47 #define TARGET_MERGED_LIB "lib" "mergedlo" ".so"
48 #endif
49 #define SEPARATOR '/'
51 #if !defined(IOS)
52 static void *lok_loadlib(const char *pFN)
54 return dlopen(pFN, RTLD_LAZY
55 #if defined LOK_LOADLIB_GLOBAL
56 | RTLD_GLOBAL
57 #endif
61 static char *lok_dlerror(void)
63 return dlerror();
66 // This function must be called to release memory allocated by lok_dlerror()
67 static void lok_dlerror_free(char *pErrMessage)
69 (void)pErrMessage;
70 // Do nothing for return of dlerror()
73 static void extendUnoPath(const char *pPath)
75 (void)pPath;
78 static void *lok_dlsym(void *Hnd, const char *pName)
80 return dlsym(Hnd, pName);
83 static int lok_dlclose(void *Hnd)
85 return dlclose(Hnd);
87 #endif // IOS
90 #else
91 #if !defined WIN32_LEAN_AND_MEAN
92 #define WIN32_LEAN_AND_MEAN
93 #endif
94 #include <windows.h>
95 #define TARGET_LIB "sofficeapp" ".dll"
96 #define TARGET_MERGED_LIB "mergedlo" ".dll"
97 #define SEPARATOR '\\'
98 #define UNOPATH "\\..\\URE\\bin"
100 static void *lok_loadlib(const char *pFN)
102 return (void *) LoadLibraryA(pFN);
105 static char *lok_dlerror(void)
107 LPSTR buf = NULL;
108 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
109 NULL, GetLastError(), 0, reinterpret_cast<LPSTR>(&buf), 0, NULL);
110 return buf;
113 // This function must be called to release memory allocated by lok_dlerror()
114 static void lok_dlerror_free(char *pErrMessage)
116 HeapFree(GetProcessHeap(), 0, pErrMessage);
119 static void *lok_dlsym(void *Hnd, const char *pName)
121 return reinterpret_cast<void *>(GetProcAddress((HINSTANCE) Hnd, pName));
124 static int lok_dlclose(void *Hnd)
126 return FreeLibrary((HINSTANCE) Hnd);
129 static void extendUnoPath(const char *pPath)
131 char *sNewPath = NULL, *sEnvPath = NULL;
132 size_t size_sEnvPath = 0, buffer_size = 0;
133 DWORD cChars;
135 if (!pPath)
136 return;
138 cChars = GetEnvironmentVariableA("PATH", sEnvPath, 0);
139 if (cChars > 0)
141 sEnvPath = (char *) malloc(cChars);
142 cChars = GetEnvironmentVariableA("PATH", sEnvPath, cChars);
143 //If PATH is not set then it is no error
144 if (cChars == 0 && GetLastError() != ERROR_ENVVAR_NOT_FOUND)
146 free(sEnvPath);
147 return;
150 //prepare the new PATH. Add the Ure/bin directory at the front.
151 //note also adding ';'
152 if(sEnvPath)
153 size_sEnvPath = strlen(sEnvPath);
154 buffer_size = size_sEnvPath + 2*strlen(pPath) + strlen(UNOPATH) + 4;
155 sNewPath = (char *) malloc(buffer_size);
156 sNewPath[0] = L'\0';
157 strcat_s(sNewPath, buffer_size, pPath); // program to PATH
158 strcat_s(sNewPath, buffer_size, ";");
159 strcat_s(sNewPath, buffer_size, UNOPATH); // UNO to PATH
160 if (size_sEnvPath > 0)
162 strcat_s(sNewPath, buffer_size, ";");
163 strcat_s(sNewPath, buffer_size, sEnvPath);
166 SetEnvironmentVariableA("PATH", sNewPath);
168 free(sNewPath);
169 free(sEnvPath);
171 #endif
173 #if !defined(IOS)
174 static void *lok_dlopen( const char *install_path, char ** _imp_lib )
176 char *imp_lib;
177 void *dlhandle;
179 size_t partial_length, imp_lib_size;
180 struct stat dir_st;
182 *_imp_lib = NULL;
184 if (!install_path)
185 return NULL;
187 if (stat(install_path, &dir_st) != 0)
189 fprintf(stderr, "installation path \"%s\" does not exist\n", install_path);
190 return NULL;
193 // allocate large enough buffer
194 partial_length = strlen(install_path);
195 imp_lib_size = partial_length + sizeof(TARGET_LIB) + sizeof(TARGET_MERGED_LIB) + 2;
196 imp_lib = (char *) malloc(imp_lib_size);
197 if (!imp_lib)
199 fprintf( stderr, "failed to open library : not enough memory\n");
200 return NULL;
203 memcpy(imp_lib, install_path, partial_length);
205 extendUnoPath(install_path);
207 imp_lib[partial_length++] = SEPARATOR;
208 strncpy(imp_lib + partial_length, TARGET_LIB, imp_lib_size - partial_length);
210 dlhandle = lok_loadlib(imp_lib);
211 if (!dlhandle)
213 // If TARGET_LIB exists, and likely is a real library (not a
214 // small one-line text stub as in the --enable-mergedlib
215 // case), but dlopen failed for some reason, don't try
216 // TARGET_MERGED_LIB.
217 struct stat st;
218 if (stat(imp_lib, &st) == 0 && st.st_size > 100)
220 char *pErrMessage = lok_dlerror();
221 fprintf(stderr, "failed to open library '%s': %s\n",
222 imp_lib, pErrMessage);
223 lok_dlerror_free(pErrMessage);
224 free(imp_lib);
225 return NULL;
228 strncpy(imp_lib + partial_length, TARGET_MERGED_LIB, imp_lib_size - partial_length);
230 dlhandle = lok_loadlib(imp_lib);
231 if (!dlhandle)
233 char *pErrMessage = lok_dlerror();
234 fprintf(stderr, "failed to open library '%s': %s\n",
235 imp_lib, pErrMessage);
236 lok_dlerror_free(pErrMessage);
237 free(imp_lib);
238 return NULL;
241 *_imp_lib = imp_lib;
242 return dlhandle;
244 #endif
246 typedef LibreOfficeKit *(LokHookFunction)( const char *install_path);
248 typedef LibreOfficeKit *(LokHookFunction2)( const char *install_path, const char *user_profile_url );
250 typedef int (LokHookPreInit) ( const char *install_path, const char *user_profile_url );
252 #if defined(IOS) || defined(ANDROID)
253 LibreOfficeKit *libreofficekit_hook_2(const char* install_path, const char* user_profile_path);
254 #endif
256 static LibreOfficeKit *lok_init_2( const char *install_path, const char *user_profile_url )
258 #if !defined(IOS) && !defined(ANDROID)
259 void *dlhandle;
260 char *imp_lib;
261 LokHookFunction *pSym;
262 LokHookFunction2 *pSym2;
264 dlhandle = lok_dlopen(install_path, &imp_lib);
265 if (!dlhandle)
266 return NULL;
268 pSym2 = (LokHookFunction2 *) lok_dlsym(dlhandle, "libreofficekit_hook_2");
269 if (!pSym2)
271 if (user_profile_url != NULL)
273 fprintf( stderr, "the LibreOffice version in '%s' does not support passing a user profile to the hook function\n",
274 imp_lib );
275 lok_dlclose( dlhandle );
276 free( imp_lib );
277 return NULL;
279 pSym = (LokHookFunction *) lok_dlsym( dlhandle, "libreofficekit_hook" );
280 if (!pSym)
282 fprintf( stderr, "failed to find hook in library '%s'\n", imp_lib );
283 lok_dlclose( dlhandle );
284 free( imp_lib );
285 return NULL;
287 free( imp_lib );
288 // dlhandle is "leaked"
289 // coverity[leaked_storage] - on purpose
290 return pSym( install_path );
293 if (user_profile_url != NULL && user_profile_url[0] == '/')
295 // It should be either a file: URL or a vnd.sun.star.pathname: URL.
296 fprintf( stderr, "second parameter to lok_init_2 '%s' should be a URL, not a pathname\n", user_profile_url );
297 lok_dlclose( dlhandle );
298 free( imp_lib );
299 return NULL;
302 free( imp_lib );
303 // dlhandle is "leaked"
304 // coverity[leaked_storage] - on purpose
305 return pSym2( install_path, user_profile_url );
306 #else
307 return libreofficekit_hook_2( install_path, user_profile_url );
308 #endif
311 static LOK_TOLERATE_UNUSED
312 LibreOfficeKit *lok_init( const char *install_path )
314 return lok_init_2( install_path, NULL );
317 #if !defined(IOS)
318 static LOK_TOLERATE_UNUSED
319 int lok_preinit( const char *install_path, const char *user_profile_url )
321 void *dlhandle;
322 char *imp_lib;
323 LokHookPreInit *pSym;
325 dlhandle = lok_dlopen(install_path, &imp_lib);
326 if (!dlhandle)
327 return -1;
329 pSym = (LokHookPreInit *) lok_dlsym(dlhandle, "lok_preinit");
330 if (!pSym)
332 fprintf( stderr, "failed to find pre-init hook in library '%s'\n", imp_lib );
333 lok_dlclose( dlhandle );
334 free( imp_lib );
335 return -1;
338 free( imp_lib );
340 // dlhandle is "leaked"
341 // coverity[leaked_storage] - on purpose
342 return pSym( install_path, user_profile_url );
344 #endif
346 #undef SEPARATOR // It is used at least in enum class MenuItemType
348 #endif // defined(__linux__) || defined (__FreeBSD__) || defined(_AIX) || defined(_WIN32) || defined(__APPLE__)
350 #ifdef __cplusplus
352 #endif
354 #endif // INCLUDED_LIBREOFFICEKIT_LIBREOFFICEKITINIT_H
356 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */