bump product version to 5.0.4.1
[LibreOffice.git] / extensions / source / plugin / unx / unxmgr.cxx
blob0433aea921fe366236b8937e7d340e387e416b4e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
30 #ifdef AIX
31 #define _LINUX_SOURCE_COMPAT
32 #include <sys/timer.h>
33 #undef _LINUX_SOURCE_COMPAT
34 #endif
36 #include <cstdarg>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <dirent.h>
40 #include <osl/thread.h>
41 #include <rtl/strbuf.hxx>
42 #include <tools/appendunixshellword.hxx>
44 #include <vcl/svapp.hxx>
45 #include <plugin/impl.hxx>
47 using namespace std;
48 using namespace com::sun::star::uno;
49 using namespace com::sun::star::plugin;
52 // Unix specific implementation
53 static bool CheckPlugin( const OString& rPath, list< PluginDescription* >& rDescriptions )
55 #if OSL_DEBUG_LEVEL > 1
56 fprintf( stderr, "Trying plugin %s ... ", rPath.getStr() );
57 #endif
59 sal_Int32 nPos = rPath.lastIndexOf('/');
60 if (nPos == -1)
62 #if OSL_DEBUG_LEVEL > 1
63 fprintf( stderr, "no absolute path to plugin\n" );
64 #endif
65 return false;
68 OString aBaseName = rPath.copy(nPos+1);
69 if (aBaseName == "libnullplugin.so")
71 #if OSL_DEBUG_LEVEL > 1
72 fprintf( stderr, "don't like %s\n", aBaseName.getStr() );
73 #endif
74 return false;
77 struct stat aStat;
78 if (stat(rPath.getStr(), &aStat) || !S_ISREG(aStat.st_mode))
80 #if OSL_DEBUG_LEVEL > 1
81 fprintf( stderr, "%s is not a regular file\n", rPath.getStr() );
82 #endif
83 return false;
86 rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
88 OString path;
89 if (!UnxPluginComm::getPluginappPath(&path))
91 #if OSL_DEBUG_LEVEL > 1
92 fprintf( stderr, "cannot construct path to pluginapp.bin\n" );
93 #endif
94 return false;
96 OStringBuffer cmd;
97 tools::appendUnixShellWord(&cmd, path);
98 cmd.append(' ');
99 tools::appendUnixShellWord(&cmd, rPath);
100 OString aCommand(cmd.makeStringAndClear());
102 FILE* pResult = popen( aCommand.getStr(), "r" );
103 int nDescriptions = 0;
104 if( pResult )
106 OStringBuffer aMIME;
107 char buf[256];
108 while( fgets( buf, sizeof( buf ), pResult ) )
110 for( size_t i = 0; i < sizeof(buf) && buf[i]; ++i )
112 if( buf[i] == '\n' )
113 buf[i] = ';';
115 aMIME.append( buf );
117 pclose( pResult );
119 if( !aMIME.isEmpty() )
121 OString aLine = aMIME.makeStringAndClear();
123 sal_Int32 nIndex = 0;
124 while( nIndex != -1 )
126 OString aType = aLine.getToken( 0, ';', nIndex );
128 sal_Int32 nTypeIndex = 0;
129 OString aMimetype = aType.getToken( 0, ':', nTypeIndex );
130 OString aExtLine = aType.getToken( 0, ':', nTypeIndex );
131 if( nTypeIndex < 0 ) // ensure at least three tokens
132 continue;
133 OString aDesc = aType.getToken( 0, ':', nTypeIndex );
135 // create extension list string
136 sal_Int32 nExtIndex = 0;
137 OStringBuffer aExtension;
138 while( nExtIndex != -1 )
140 OString aExt = aExtLine.getToken( 0, ',', nExtIndex);
141 if( aExt.indexOf( "*." ) != 0 )
142 aExtension.append( "*." );
143 aExtension.append( aExt );
144 if( nExtIndex != -1 )
145 aExtension.append( ';' );
148 PluginDescription* pNew = new PluginDescription;
149 // set plugin name (path to library)
150 pNew->PluginName = OStringToOUString( rPath, aEncoding );
151 // set mimetype
152 pNew->Mimetype = OStringToOUString( aMimetype, aEncoding );
153 // set extension line
154 pNew->Extension = OStringToOUString( aExtension.makeStringAndClear(), aEncoding );
155 // set description
156 pNew->Description= OStringToOUString( aDesc, aEncoding );
157 rDescriptions.push_back( pNew );
158 #if OSL_DEBUG_LEVEL > 1
159 fprintf( stderr, "Mimetype: %s\nExtension: %s\n"
160 "Description: %s\n",
161 OUStringToOString( pNew->Mimetype, aEncoding ).getStr(),
162 OUStringToOString( pNew->Extension, aEncoding ).getStr(),
163 OUStringToOString( pNew->Description, aEncoding ).getStr()
165 #endif
168 #if OSL_DEBUG_LEVEL > 1
169 else
170 fprintf( stderr, "result of \"%s\" contains no mimtype\n",
171 aCommand.getStr() );
172 #endif
174 #if OSL_DEBUG_LEVEL > 1
175 else
176 fprintf( stderr, "command \"%s\" failed\n", aCommand.getStr() );
177 #endif
178 return nDescriptions > 0;
181 union maxDirent
183 char aBuffer[ sizeof( struct dirent ) + PATH_MAX +1 ];
184 struct dirent asDirent;
187 static void CheckPluginRegistryFiles( const OString& rPath, list< PluginDescription* >& rDescriptions )
189 OStringBuffer aPath( 1024 );
190 aPath.append( rPath );
191 aPath.append( "/pluginreg.dat" );
192 FILE* fp = fopen( aPath.getStr(), "r" );
193 if( fp )
195 #if OSL_DEBUG_LEVEL > 1
196 fprintf( stderr, "parsing %s\n", aPath.getStr() );
197 #endif
198 char aLine[1024];
199 while( fgets( aLine, sizeof( aLine ), fp ) )
201 int nLineLen = strlen( aLine );
202 int nDotPos;
203 for( nDotPos = nLineLen-1; nDotPos > 0 && aLine[nDotPos] != ':'; nDotPos-- )
205 if( aLine[0] == '/' && aLine[nDotPos] == ':' && aLine[nDotPos+1] == '$' )
206 CheckPlugin( OString(aLine, nDotPos), rDescriptions );
208 fclose( fp );
211 // check subdirectories
212 DIR* pDIR = opendir( rPath.getStr() );
213 struct dirent* pDirEnt = NULL;
214 struct stat aStat;
215 maxDirent u;
216 while( pDIR && ! readdir_r( pDIR, &u.asDirent, &pDirEnt ) && pDirEnt )
218 char* pBaseName = u.asDirent.d_name;
219 if( rtl_str_compare( ".", pBaseName ) && rtl_str_compare( "..", pBaseName ) )
221 OStringBuffer aBuf( 1024 );
222 aBuf.append( rPath );
223 aBuf.append( '/' );
224 aBuf.append( pBaseName );
226 if( ! stat( aBuf.getStr(), &aStat ) )
228 if( S_ISDIR( aStat.st_mode ) )
229 CheckPluginRegistryFiles( aBuf.makeStringAndClear(), rDescriptions );
233 if( pDIR )
234 closedir( pDIR );
237 Sequence<PluginDescription> XPluginManager_Impl::impl_getPluginDescriptions() throw(css::uno::RuntimeException, std::exception)
239 static Sequence<PluginDescription> aDescriptions;
240 static bool bHavePlugins = false;
241 if( ! bHavePlugins )
243 rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
244 list<PluginDescription*> aPlugins;
245 int i;
247 // unix: search for plugins in /usr/lib/netscape/plugins,
248 // ~/.netscape/plugins und NPX_PLUGIN_PATH
249 // additionally: search in PluginsPath
250 static const char* pHome = getenv( "HOME" );
251 static const char* pNPXPluginPath = getenv( "NPX_PLUGIN_PATH" );
253 // netscape!, quick, beam me back to the 90's when Motif roamed the earth
254 OStringBuffer aSearchBuffer("/usr/lib/netscape/plugins");
255 if( pHome )
256 aSearchBuffer.append(':').append(pHome).append("/.netscape/plugins");
257 if( pNPXPluginPath )
258 aSearchBuffer.append(':').append(pNPXPluginPath);
260 const Sequence< OUString >& rPaths( PluginManager::getAdditionalSearchPaths() );
261 for( i = 0; i < rPaths.getLength(); i++ )
263 aSearchBuffer.append(':').append(OUStringToOString(
264 rPaths.getConstArray()[i], aEncoding));
267 OString aSearchPath = aSearchBuffer.makeStringAndClear();
269 sal_Int32 nIndex = 0;
270 maxDirent u;
273 OString aPath(aSearchPath.getToken(0, ':', nIndex));
274 if (!aPath.isEmpty())
276 DIR* pDIR = opendir(aPath.getStr());
277 struct dirent* pDirEnt = NULL;
278 while( pDIR && ! readdir_r( pDIR, &u.asDirent, &pDirEnt ) && pDirEnt )
280 char* pBaseName = u.asDirent.d_name;
281 if( pBaseName[0] != '.' ||
282 pBaseName[1] != '.' ||
283 pBaseName[2] != 0 )
285 OStringBuffer aFileName(aPath);
286 aFileName.append('/').append(pBaseName);
287 CheckPlugin( aFileName.makeStringAndClear(), aPlugins );
290 if( pDIR )
291 closedir( pDIR );
294 while ( nIndex >= 0 );
296 // try ~/.mozilla/pluginreg.dat
297 OStringBuffer aBuf(256);
298 aBuf.append( pHome );
299 aBuf.append( "/.mozilla" );
300 CheckPluginRegistryFiles( aBuf.makeStringAndClear(), aPlugins );
302 // create return value
303 aDescriptions = Sequence<PluginDescription>( aPlugins.size() );
304 #if OSL_DEBUG_LEVEL > 1
305 fprintf( stderr, "found %" SAL_PRI_SIZET "u plugins\n", aPlugins.size() );
306 #endif
307 list<PluginDescription*>::iterator iter;
308 for( iter = aPlugins.begin(), i=0; iter != aPlugins.end(); ++iter ,i++ )
310 aDescriptions.getArray()[ i ] = **iter;
311 delete *iter;
313 aPlugins.clear();
314 bHavePlugins = true;
316 return aDescriptions;
319 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */