Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
12 : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : * it under the terms of the GNU Lesser General Public License version 3
14 : * only, as published by the Free Software Foundation.
15 : *
16 : * OpenOffice.org is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU Lesser General Public License version 3 for more details
20 : * (a copy is included in the LICENSE file that accompanied this code).
21 : *
22 : * You should have received a copy of the GNU Lesser General Public License
23 : * version 3 along with OpenOffice.org. If not, see
24 : * <http://www.openoffice.org/license.html>
25 : * for a copy of the LGPLv3 License.
26 : *
27 : ************************************************************************/
28 :
29 :
30 : #ifdef UNIX
31 : #include <sys/types.h>
32 : #include <strings.h>
33 : #ifdef LINUX
34 : #include <dlfcn.h>
35 : #endif
36 : #include <stdarg.h>
37 : // For vsnprintf()
38 : #define NSP_vsnprintf vsnprintf
39 : #include "nsp_func.hxx"
40 : #endif // End UNIX
41 :
42 : #ifdef WNT
43 : #define _WINDOWS
44 :
45 : #ifdef _MSC_VER
46 : #pragma warning (push,1)
47 : #pragma warning (disable:4668)
48 : #pragma warning (disable:4917)
49 : #endif
50 :
51 : #include <windows.h>
52 : #include <direct.h>
53 : #include <stdlib.h>
54 : #include <shlobj.h>
55 : #include <objidl.h>
56 : // For vsnprintf()
57 : #define NSP_vsnprintf _vsnprintf
58 :
59 : #ifdef _MSC_VER
60 : #pragma warning (pop)
61 : #endif
62 : #endif // End WNT
63 :
64 : #include <sys/stat.h>
65 : #include <errno.h>
66 : #include "so_env.hxx"
67 : #include "ns_debug.hxx"
68 : #include <sal/config.h>
69 :
70 : #define PLUGIN_NAME "LibreOffice"
71 :
72 : // Tranform all strings like %20 in pPath to one char like space
73 : /*int retoreUTF8(char* pPath)
74 : {
75 : // Prepare buf
76 : int len = strlen(pPath) + 1;
77 : char* pBuf = (char*)malloc(len);
78 : memset(pBuf, 0, len);
79 :
80 : // Store the original pBuf and pPath
81 : char* pBufCur = pBuf;
82 : char* pPathCur = pPath;
83 : // ie, for %20, UTF8Numbers[0][0] = 2, UTF8Numbers[1][0] = 0
84 : char UTF8Numbers[2][2] = {{0, 0}, {0,0}};
85 : int temp;
86 :
87 : while (*pPathCur) {
88 : if (('%' == *pPathCur) && (0 != *(pPathCur + 1))
89 : && (0 != *(pPathCur + 2)))
90 : {
91 : UTF8Numbers[0][0] = *(pPathCur + 1);
92 : UTF8Numbers[1][0] = *(pPathCur + 2);
93 : temp = 0;
94 : temp = atoi(UTF8Numbers[0])*16 + atoi(UTF8Numbers[1]);
95 : *pBufCur = (char)temp;
96 : pBufCur++;
97 : pPathCur += 3;
98 : } else {
99 : *pBufCur++ = *pPathCur++;
100 : }
101 : }
102 :
103 : *pBufCur = 0;
104 : strcpy(pPath, pBuf);
105 : free(pBuf);
106 : return 0;
107 : }*/
108 :
109 : int
110 0 : restoreUTF8(char *pPath)
111 : {
112 : unsigned char *s, *d;
113 :
114 : #define XDIGIT(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10)
115 :
116 0 : s = d = (unsigned char *)pPath;
117 0 : do {
118 0 : if (*s == '%' && s[1] && s[2]) {
119 0 : *d++ = (XDIGIT (s[1]) << 4) + XDIGIT (s[2]);
120 0 : s += 2;
121 : } else
122 0 : *d++ = *s;
123 : } while (*s++);
124 0 : debug_fprintf(NSP_LOG_APPEND, "after restoreUTF8, pPath is %s\n", pPath);
125 0 : return 0;
126 : }
127 :
128 : #ifdef LINUX
129 : extern int nspluginOOoModuleHook (void** aResult);
130 0 : int nspluginOOoModuleHook (void** aResult)
131 : {
132 : void *dl_handle;
133 :
134 0 : dl_handle = dlopen(NULL, RTLD_NOW);
135 0 : if (!dl_handle)
136 : {
137 0 : fprintf (stderr, "Can't open myself '%s'\n", dlerror());
138 0 : return 1;
139 : }
140 :
141 0 : Dl_info dl_info = { 0,0,0,0 };
142 0 : if(!dladdr((void *)nspluginOOoModuleHook, &dl_info))
143 : {
144 0 : fprintf (stderr, "Can't find my own address '%s'\n", dlerror());
145 0 : return 1;
146 : }
147 :
148 0 : if (!dl_info.dli_fname)
149 : {
150 0 : fprintf (stderr, "Can't find my own file name\n");
151 0 : return 1;
152 : }
153 :
154 : char cwdstr[NPP_PATH_MAX];
155 0 : if (!getcwd (cwdstr, sizeof(cwdstr)))
156 : {
157 0 : fprintf (stderr, "Can't get cwd\n");
158 0 : return 1;
159 : }
160 :
161 : char libFileName[NPP_PATH_MAX];
162 :
163 0 : if (dl_info.dli_fname[0] != '/')
164 : {
165 0 : if ((strlen(cwdstr) + 1 + strlen(dl_info.dli_fname)) >= NPP_PATH_MAX)
166 : {
167 0 : fprintf (stderr, "Plugin path too long\n");
168 0 : return 1;
169 : }
170 0 : strcpy (libFileName, cwdstr);
171 0 : strcat (libFileName, "/");
172 0 : strcat (libFileName, dl_info.dli_fname);
173 : }
174 : else
175 : {
176 0 : if (strlen(dl_info.dli_fname) >= NPP_PATH_MAX)
177 : {
178 0 : fprintf (stderr, "Plugin path too long\n");
179 0 : return 1;
180 : }
181 0 : strcpy (libFileName, dl_info.dli_fname);
182 : }
183 :
184 : char *clobber;
185 : static char realFileName[NPP_PATH_MAX] = {0};
186 : # define SEARCH_SUFFIX "/program/libnpsoplug"
187 :
188 0 : if (!(clobber = strstr (libFileName, SEARCH_SUFFIX)))
189 : {
190 0 : ssize_t len = readlink(libFileName, realFileName, NPP_PATH_MAX-1);
191 0 : if (len == -1)
192 : {
193 0 : fprintf (stderr, "Couldn't read link '%s'\n", libFileName);
194 0 : return 1;
195 : }
196 0 : realFileName[len] = '\0';
197 0 : if (!(clobber = strstr (realFileName, SEARCH_SUFFIX)))
198 : {
199 0 : fprintf (stderr, "Couldn't find suffix in '%s'\n", realFileName);
200 0 : return 1;
201 : }
202 0 : *clobber = '\0';
203 : }
204 : else
205 : {
206 0 : *clobber = '\0';
207 0 : strcpy (realFileName, libFileName);
208 : }
209 :
210 : #if OSL_DEBUG_LEVEL > 0
211 : fprintf (stderr, "LibreOffice path before fixup is '%s'\n", realFileName);
212 : #endif
213 :
214 0 : if (realFileName[0] != '/') {
215 : /* a relative sym-link and we need to get an absolute path */
216 0 : char scratch[NPP_PATH_MAX] = {0};
217 0 : if (strlen (realFileName) + strlen (libFileName) + 2 >= NPP_PATH_MAX - 1)
218 : {
219 0 : fprintf (stderr, "Paths too long to fix up.\n");
220 0 : return 1;
221 : }
222 0 : strcpy (scratch, libFileName);
223 0 : if (strrchr (scratch, '/')) /* remove the last element */
224 0 : *(strrchr (scratch, '/') + 1) = '\0';
225 0 : strcat (scratch, realFileName);
226 0 : strcpy (realFileName, scratch);
227 : }
228 :
229 0 : *aResult = realFileName;
230 :
231 : #if OSL_DEBUG_LEVEL > 0
232 : fprintf (stderr, "LibreOffice path is '%s'\n", realFileName);
233 : #endif
234 :
235 0 : return 0;
236 : }
237 : #endif
238 :
239 : // *aResult points the static string holding "/opt/staroffice8"
240 0 : int findReadSversion(void** aResult, int /*bWnt*/, const char* /*tag*/, const char* /*entry*/)
241 : {
242 : #ifdef UNIX
243 : // The real space to hold "/opt/staroffice8"
244 : static char realFileName[NPP_PATH_MAX] = {0};
245 0 : memset(realFileName, 0, NPP_PATH_MAX);
246 0 : *aResult = realFileName;
247 :
248 : // Filename of lnk file, eg. "soffice"
249 0 : char lnkFileName[NPP_PATH_MAX] = {0};
250 0 : char* pTempZero = NULL;
251 :
252 : #ifdef LINUX
253 : /* try to fetch a 'self' pointer */
254 0 : if (!nspluginOOoModuleHook (aResult))
255 0 : return 0;
256 :
257 : /* .. now in $HOME */
258 : #endif // LINUX
259 0 : snprintf(lnkFileName, NPP_PATH_MAX - 1, "%s/.mozilla/plugins/libnpsoplugin%s", getenv("HOME"), SAL_DLLEXTENSION);
260 : #ifdef LINUX
261 0 : ssize_t len = readlink(lnkFileName, realFileName, NPP_PATH_MAX-1);
262 0 : if (-1 == len)
263 : {
264 0 : *realFileName = 0;
265 0 : return -1;
266 : }
267 0 : realFileName[len] = '\0';
268 :
269 0 : if (NULL == (pTempZero = strstr(realFileName, "/program/libnpsoplugin" SAL_DLLEXTENSION)))
270 : #else // LINUX
271 : if ((0 > readlink(lnkFileName, realFileName, NPP_PATH_MAX)) ||
272 : (NULL == (pTempZero = strstr(realFileName, "/program/libnpsoplugin" SAL_DLLEXTENSION))))
273 : #endif // LINUX
274 : {
275 0 : *realFileName = 0;
276 0 : return -1;
277 : }
278 0 : *pTempZero = 0;
279 0 : return 0;
280 : #elif defined WNT // UNIX
281 : static char realFileName[NPP_PATH_MAX] = {0};
282 : *aResult = realFileName;
283 : HKEY hKey;
284 : DWORD dwBufLen = NPP_PATH_MAX;
285 : LONG lRet;
286 :
287 : debug_fprintf(NSP_LOG_APPEND, "1 before before strstr realFileName is %s\n", realFileName);
288 : lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
289 : "SOFTWARE\\MozillaPlugins\\@sun.com/npsopluginmi;version=1.0",
290 : 0, KEY_QUERY_VALUE, &hKey );
291 : if (lRet == ERROR_FILE_NOT_FOUND) {
292 : lRet = RegOpenKeyEx(
293 : HKEY_CURRENT_USER,
294 : "SOFTWARE\\MozillaPlugins\\@sun.com/npsopluginmi;version=1.0", 0,
295 : KEY_QUERY_VALUE, &hKey);
296 : }
297 : debug_fprintf(NSP_LOG_APPEND, "2 before before strstr realFileName is %s\n", realFileName);
298 : if( lRet != ERROR_SUCCESS )
299 : return FALSE;
300 :
301 : lRet = RegQueryValueEx( hKey, "Path", NULL, NULL,
302 : (LPBYTE) realFileName, &dwBufLen);
303 : debug_fprintf(NSP_LOG_APPEND, "3 before before strstr realFileName is %s\n", realFileName);
304 : if( (lRet != ERROR_SUCCESS) || (dwBufLen > NPP_PATH_MAX) )
305 : return FALSE;
306 :
307 : RegCloseKey( hKey );
308 : char* pTempZero = NULL;
309 : debug_fprintf(NSP_LOG_APPEND, "before strstr realFileName is %s\n", realFileName);
310 : if (NULL == (pTempZero = strstr(realFileName, "\\program")))
311 : {
312 : *realFileName = 0;
313 : return -1;
314 : }
315 : *pTempZero = 0;
316 : debug_fprintf(NSP_LOG_APPEND, "realFileName is %s\n", realFileName);
317 : return 0;
318 : #endif // UNIX
319 : }
320 :
321 : // Return the install dir path of staroffice, return value like "/home/build/staroffice"
322 0 : const char* findInstallDir()
323 : {
324 : static char* pInstall = NULL;
325 0 : debug_fprintf(NSP_LOG_APPEND, "start of findInstallDir()\n");
326 0 : if (!pInstall)
327 : {
328 0 : findReadSversion((void**)&pInstall, 0, "[" SECTION_NAME "]", SOFFICE_VERSION "=");
329 0 : if (!pInstall)
330 0 : pInstall = const_cast< char* >( "" );
331 : }
332 0 : return pInstall;
333 : }
334 :
335 : // Return the program dir path of staroffice, return value like "/home/build/staroffice/program"
336 0 : const char* findProgramDir()
337 : {
338 : static char sProgram[NPP_BUFFER_SIZE] = {0};
339 0 : if (!sProgram[0])
340 : {
341 0 : sprintf(sProgram, "%s/program", findInstallDir());
342 : #ifdef WNT
343 : UnixToDosPath(sProgram);
344 : #endif
345 : }
346 0 : return sProgram;
347 : }
348 :
349 : #ifdef WNT
350 : // Return SO executable absolute path, like "/home/build/staroffice/program/soffice"
351 : const char* findSofficeExecutable()
352 : {
353 : static char pSofficeExeccutable[NPP_PATH_MAX] = {0};
354 : if (!pSofficeExeccutable[0])
355 : {
356 : sprintf(pSofficeExeccutable, "%s/%s", findProgramDir(), STAROFFICE_EXE_FILE_NAME);
357 : #ifdef WNT
358 : UnixToDosPath(pSofficeExeccutable);
359 : #endif
360 : }
361 :
362 : return pSofficeExeccutable;
363 : }
364 :
365 : // Change Dos path such as c:\program\soffice to c:/program/soffice
366 : int DosToUnixPath(char* sPath)
367 : {
368 : if (!sPath)
369 : return -1;
370 : char* p = sPath;
371 : while (*p)
372 : {
373 : if(*p == '\\')
374 : *p = '/';
375 : p++;
376 : }
377 : return 0;
378 :
379 : }
380 : #endif
381 : // Change Unix path such as program/soffice to program\soffice
382 0 : int UnixToDosPath(char* sPath)
383 : {
384 0 : if (!sPath)
385 0 : return -1;
386 0 : char* p = sPath;
387 0 : while (*p)
388 : {
389 0 : if(*p == '/')
390 0 : *p = '\\';
391 0 : p++;
392 : }
393 0 : return 0;
394 :
395 : }
396 :
397 : #ifdef UNIX
398 : char productName[128] = {0};
399 0 : char* NSP_getProductName()
400 : {
401 0 : if(productName[0])
402 0 : return productName;
403 0 : char fullBootstrapIniPath[1024] = {0};
404 0 : const char* pFullFilePath = findProgramDir();
405 0 : if(0 == *pFullFilePath)
406 : {
407 0 : strcpy(productName, PLUGIN_NAME);
408 0 : return productName;
409 : }
410 : sprintf(fullBootstrapIniPath, "%s/%s", pFullFilePath,
411 0 : "bootstraprc");
412 :
413 0 : FILE* fp = fopen(fullBootstrapIniPath, "r");
414 :
415 0 : if (NULL == fp)
416 : {
417 0 : strcpy(productName, PLUGIN_NAME);
418 0 : return productName;
419 : }
420 0 : char line[4096] = {0};
421 0 : char *pStart = 0;
422 0 : char *pEnd = 0;
423 0 : while(!feof(fp))
424 : {
425 0 : if (fgets( line, sizeof(line), fp ) == NULL)
426 0 : continue;
427 0 : if (NULL == (pStart = strstr( line, "ProductKey=" )))
428 0 : continue;
429 0 : pStart += strlen("ProductKey=");
430 0 : if (NULL == (pEnd = strchr( pStart, ' ' )) &&
431 : (NULL == (pEnd = strchr( pStart, '\r' ))))
432 0 : continue;
433 0 : *pEnd = 0;
434 0 : if (static_cast<size_t>(pEnd - pStart) <= sizeof(productName))
435 0 : strcpy(productName, pStart);
436 : }
437 0 : fclose(fp);
438 0 : if ((*productName == 0) ||
439 0 : (0 != STRNICMP(productName, "StarOffice", sizeof("StarOffice"))))
440 : {
441 0 : strcpy(productName, PLUGIN_NAME);
442 0 : return productName;
443 : }
444 0 : memset(productName, 0, sizeof(productName));
445 0 : strcat(productName, "StarOffice/StarSuite");
446 0 : return productName;
447 : }
448 :
449 : char PluginName[1024] = {0};
450 0 : char* NSP_getPluginName()
451 : {
452 0 : if(*PluginName)
453 0 : return PluginName;
454 0 : sprintf(PluginName, "%s Plug-in", NSP_getProductName());
455 0 : return PluginName;
456 : }
457 :
458 : char PluginDesc[1024] = {0};
459 0 : char* NSP_getPluginDesc()
460 : {
461 0 : if(*PluginDesc)
462 0 : return PluginDesc;
463 :
464 : sprintf(PluginDesc, "%s Plug-in handles all its documents",
465 0 : productName);
466 0 : return PluginDesc;
467 : }
468 : #endif //end of UNIX
469 :
470 0 : void NSP_WriteLog(int level, const char* pFormat, ...)
471 : {
472 : (void)level;
473 : #ifndef DEBUG
474 : (void)pFormat;
475 : #else
476 : va_list ap;
477 : char msgBuf[NPP_BUFFER_SIZE];
478 : static char logName[NPP_PATH_MAX] = {0};
479 : FILE * fp = NULL;
480 :
481 : va_start(ap,pFormat);
482 : NSP_vsnprintf(msgBuf, NPP_BUFFER_SIZE, pFormat, ap);
483 : va_end(ap);
484 :
485 : if (!logName[0])
486 : {
487 : #ifdef UNIX
488 : const char* homeDir = getenv("HOME");
489 : sprintf(logName,"%s/%s",homeDir,"nsplugin.log");
490 : #endif // End UNIX
491 : #ifdef WNT
492 : char szPath[MAX_PATH];
493 : if (!SHGetSpecialFolderPath(NULL, szPath, CSIDL_APPDATA, 0))
494 : {
495 : return;
496 : }
497 : char* homeDir = szPath;
498 : sprintf(logName,"%s\\%s", szPath, "nsplugin.log");
499 : #endif // End WNT
500 : }
501 : else
502 : fp = fopen(logName, "a+");
503 :
504 : if (!fp)
505 : return;
506 : fputs(msgBuf, fp);
507 : fclose(fp);
508 : #endif
509 0 : }
510 :
511 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|