merged tag ooo/OOO330_m14
[LibreOffice.git] / extensions / source / plugin / unx / unxmgr.cxx
blob1a3736e87e0b1a97dad3bea91c0351b609b5e049
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 #include <cstdarg>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <dirent.h>
34 #include <osl/thread.h>
35 #include <rtl/strbuf.hxx>
36 #include <tools/appendunixshellword.hxx>
38 #include <vcl/svapp.hxx>
39 #include <plugin/impl.hxx>
41 using namespace rtl;
42 using namespace std;
43 using namespace com::sun::star::uno;
44 using namespace com::sun::star::plugin;
46 // Unix specific implementation
47 static bool CheckPlugin( const ByteString& rPath, list< PluginDescription* >& rDescriptions )
49 #if OSL_DEBUG_LEVEL > 1
50 fprintf( stderr, "Trying plugin %s ... ", rPath.GetBuffer() );
51 #endif
53 xub_StrLen nPos = rPath.SearchBackward( '/' );
54 if( nPos == STRING_NOTFOUND )
56 #if OSL_DEBUG_LEVEL > 1
57 fprintf( stderr, "no absolute path to plugin\n" );
58 #endif
59 return false;
62 ByteString aBaseName = rPath.Copy( nPos+1 );
63 if( aBaseName.Equals( "libnullplugin.so" ) )
65 #if OSL_DEBUG_LEVEL > 1
66 fprintf( stderr, "don't like %s\n", aBaseName.GetBuffer() );
67 #endif
68 return false;
71 struct stat aStat;
72 if( stat( rPath.GetBuffer(), &aStat ) || ! S_ISREG( aStat.st_mode ) )
74 #if OSL_DEBUG_LEVEL > 1
75 fprintf( stderr, "%s is not a regular file\n", rPath.GetBuffer() );
76 #endif
77 return false;
81 rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
83 rtl::OString path;
84 if (!UnxPluginComm::getPluginappPath(&path)) {
85 #if OSL_DEBUG_LEVEL > 1
86 fprintf( stderr, "cannot construct path to pluginapp.bin\n" );
87 #endif
88 return false;
90 rtl::OStringBuffer cmd;
91 tools::appendUnixShellWord(&cmd, path);
92 cmd.append(' ');
93 tools::appendUnixShellWord(&cmd, rPath);
94 rtl::OString aCommand(cmd.makeStringAndClear());
96 FILE* pResult = popen( aCommand.getStr(), "r" );
97 int nDescriptions = 0;
98 if( pResult )
100 OStringBuffer aMIME;
101 char buf[256];
102 while( fgets( buf, sizeof( buf ), pResult ) )
104 for( size_t i = 0; i < sizeof(buf) && buf[i]; ++i )
106 if( buf[i] == '\n' )
107 buf[i] = ';';
109 aMIME.append( buf );
111 pclose( pResult );
113 if( aMIME.getLength() > 0 )
115 OString aLine = aMIME.makeStringAndClear();
117 sal_Int32 nIndex = 0;
118 while( nIndex != -1 )
120 OString aType = aLine.getToken( 0, ';', nIndex );
122 sal_Int32 nTypeIndex = 0;
123 OString aMimetype = aType.getToken( 0, ':', nTypeIndex );
124 OString aExtLine = aType.getToken( 0, ':', nTypeIndex );
125 if( nTypeIndex < 0 ) // ensure at least three tokens
126 continue;
127 OString aDesc = aType.getToken( 0, ':', nTypeIndex );
129 // create extension list string
130 sal_Int32 nExtIndex = 0;
131 OStringBuffer aExtension;
132 while( nExtIndex != -1 )
134 OString aExt = aExtLine.getToken( 0, ',', nExtIndex);
135 if( aExt.indexOf( "*." ) != 0 )
136 aExtension.append( "*." );
137 aExtension.append( aExt );
138 if( nExtIndex != -1 )
139 aExtension.append( ';' );
142 PluginDescription* pNew = new PluginDescription;
143 // set plugin name (path to library)
144 pNew->PluginName = OStringToOUString( rPath, aEncoding );
145 // set mimetype
146 pNew->Mimetype = OStringToOUString( aMimetype, aEncoding );
147 // set extension line
148 pNew->Extension = OStringToOUString( aExtension.makeStringAndClear(), aEncoding );
149 // set description
150 pNew->Description= OStringToOUString( aDesc, aEncoding );
151 rDescriptions.push_back( pNew );
152 #if OSL_DEBUG_LEVEL > 1
153 fprintf( stderr, "Mimetype: %s\nExtension: %s\n"
154 "Description: %s\n",
155 OUStringToOString( pNew->Mimetype, aEncoding ).getStr(),
156 OUStringToOString( pNew->Extension, aEncoding ).getStr(),
157 OUStringToOString( pNew->Description, aEncoding ).getStr()
159 #endif
162 #if OSL_DEBUG_LEVEL > 1
163 else
164 fprintf( stderr, "result of \"%s\" contains no mimtype\n",
165 aCommand.getStr() );
166 #endif
168 #if OSL_DEBUG_LEVEL > 1
169 else
170 fprintf( stderr, "command \"%s\" failed\n", aCommand.getStr() );
171 #endif
172 return nDescriptions > 0;
175 union maxDirent
177 char aBuffer[ sizeof( struct dirent ) + _PC_NAME_MAX +1 ];
178 struct dirent asDirent;
181 static void CheckPluginRegistryFiles( const rtl::OString& rPath, list< PluginDescription* >& rDescriptions )
183 rtl::OStringBuffer aPath( 1024 );
184 aPath.append( rPath );
185 aPath.append( "/pluginreg.dat" );
186 FILE* fp = fopen( aPath.getStr(), "r" );
187 if( fp )
189 #if OSL_DEBUG_LEVEL > 1
190 fprintf( stderr, "parsing %s\n", aPath.getStr() );
191 #endif
192 char aLine[1024];
193 while( fgets( aLine, sizeof( aLine ), fp ) )
195 int nLineLen = strlen( aLine );
196 int nDotPos;
197 for( nDotPos = nLineLen-1; nDotPos > 0 && aLine[nDotPos] != ':'; nDotPos-- )
199 if( aLine[0] == '/' && aLine[nDotPos] == ':' && aLine[nDotPos+1] == '$' )
200 CheckPlugin( ByteString( aLine, nDotPos ), rDescriptions );
202 fclose( fp );
205 // check subdirectories
206 DIR* pDIR = opendir( rPath.getStr() );
207 struct dirent* pDirEnt = NULL;
208 struct stat aStat;
209 maxDirent u;
210 while( pDIR && ! readdir_r( pDIR, &u.asDirent, &pDirEnt ) && pDirEnt )
212 char* pBaseName = u.asDirent.d_name;
213 if( rtl_str_compare( ".", pBaseName ) && rtl_str_compare( "..", pBaseName ) )
215 rtl::OStringBuffer aBuf( 1024 );
216 aBuf.append( rPath );
217 aBuf.append( '/' );
218 aBuf.append( pBaseName );
220 if( ! stat( aBuf.getStr(), &aStat ) )
222 if( S_ISDIR( aStat.st_mode ) )
223 CheckPluginRegistryFiles( aBuf.makeStringAndClear(), rDescriptions );
227 if( pDIR )
228 closedir( pDIR );
231 Sequence<PluginDescription> XPluginManager_Impl::impl_getPluginDescriptions() throw()
233 static Sequence<PluginDescription> aDescriptions;
234 static BOOL bHavePlugins = FALSE;
235 if( ! bHavePlugins )
237 rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
238 list<PluginDescription*> aPlugins;
239 int i;
241 // unix: search for plugins in /usr/lib/netscape/plugins,
242 // ~/.netscape/plugins und NPX_PLUGIN_PATH
243 // additionally: search in PluginsPath
244 static const char* pHome = getenv( "HOME" );
245 static const char* pNPXPluginPath = getenv( "NPX_PLUGIN_PATH" );
247 ByteString aSearchPath( "/usr/lib/netscape/plugins" );
248 if( pHome )
250 aSearchPath.Append( ':' );
251 aSearchPath.Append( pHome );
252 aSearchPath += "/.netscape/plugins";
254 if( pNPXPluginPath )
256 aSearchPath.Append( ':' );
257 aSearchPath += pNPXPluginPath;
260 const Sequence< ::rtl::OUString >& rPaths( PluginManager::getAdditionalSearchPaths() );
261 for( i = 0; i < rPaths.getLength(); i++ )
263 aSearchPath += ":";
264 aSearchPath += ByteString( String( rPaths.getConstArray()[i] ), aEncoding );
267 int nPaths = aSearchPath.GetTokenCount( ':' );
268 maxDirent u;
269 for( i = 0; i < nPaths; i++ )
271 ByteString aPath( aSearchPath.GetToken( i, ':' ) );
272 if( aPath.Len() )
274 DIR* pDIR = opendir( aPath.GetBuffer() );
275 struct dirent* pDirEnt = NULL;
276 while( pDIR && ! readdir_r( pDIR, &u.asDirent, &pDirEnt ) && pDirEnt )
278 char* pBaseName = u.asDirent.d_name;
279 if( pBaseName[0] != '.' ||
280 pBaseName[1] != '.' ||
281 pBaseName[2] != 0 )
283 ByteString aFileName( aPath );
284 aFileName += "/";
285 aFileName += pBaseName;
286 CheckPlugin( aFileName, aPlugins );
289 if( pDIR )
290 closedir( pDIR );
294 // try ~/.mozilla/pluginreg.dat
295 rtl::OStringBuffer aBuf(256);
296 aBuf.append( pHome );
297 aBuf.append( "/.mozilla" );
298 CheckPluginRegistryFiles( aBuf.makeStringAndClear(), aPlugins );
300 // create return value
301 aDescriptions = Sequence<PluginDescription>( aPlugins.size() );
302 #if OSL_DEBUG_LEVEL > 1
303 fprintf( stderr, "found %d plugins\n", aPlugins.size() );
304 #endif
305 list<PluginDescription*>::iterator iter;
306 for( iter = aPlugins.begin(), i=0; iter != aPlugins.end(); ++iter ,i++ )
308 aDescriptions.getArray()[ i ] = **iter;
309 delete *iter;
311 aPlugins.clear();
312 bHavePlugins = TRUE;
314 return aDescriptions;