Update ooo320-m1
[ooovba.git] / extensions / source / plugin / unx / unxmgr.cxx
blob473f288163eb81680d61d760d5342c7451d184cf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unxmgr.cxx,v $
10 * $Revision: 1.14.90.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
33 #include <cstdarg>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <dirent.h>
37 #include <osl/thread.h>
38 #include <rtl/strbuf.hxx>
39 #include <tools/appendunixshellword.hxx>
41 #include <vcl/svapp.hxx>
42 #include <plugin/impl.hxx>
44 using namespace rtl;
45 using namespace std;
46 using namespace com::sun::star::uno;
47 using namespace com::sun::star::plugin;
49 // Unix specific implementation
50 static bool CheckPlugin( const ByteString& rPath, list< PluginDescription* >& rDescriptions )
52 #if OSL_DEBUG_LEVEL > 1
53 fprintf( stderr, "Trying plugin %s ... ", rPath.GetBuffer() );
54 #endif
56 xub_StrLen nPos = rPath.SearchBackward( '/' );
57 if( nPos == STRING_NOTFOUND )
59 #if OSL_DEBUG_LEVEL > 1
60 fprintf( stderr, "no absolute path to plugin\n" );
61 #endif
62 return false;
65 ByteString aBaseName = rPath.Copy( nPos+1 );
66 if( aBaseName.Equals( "libnullplugin.so" ) )
68 #if OSL_DEBUG_LEVEL > 1
69 fprintf( stderr, "don't like %s\n", aBaseName.GetBuffer() );
70 #endif
71 return false;
74 struct stat aStat;
75 if( stat( rPath.GetBuffer(), &aStat ) || ! S_ISREG( aStat.st_mode ) )
77 #if OSL_DEBUG_LEVEL > 1
78 fprintf( stderr, "%s is not a regular file\n", rPath.GetBuffer() );
79 #endif
80 return false;
84 rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
86 rtl::OString path;
87 if (!UnxPluginComm::getPluginappPath(&path)) {
88 #if OSL_DEBUG_LEVEL > 1
89 fprintf( stderr, "cannot construct path to pluginapp.bin\n" );
90 #endif
91 return false;
93 rtl::OStringBuffer cmd;
94 tools::appendUnixShellWord(&cmd, path);
95 cmd.append(' ');
96 tools::appendUnixShellWord(&cmd, rPath);
97 rtl::OString aCommand(cmd.makeStringAndClear());
99 FILE* pResult = popen( aCommand.getStr(), "r" );
100 int nDescriptions = 0;
101 if( pResult )
103 OStringBuffer aMIME;
104 char buf[256];
105 while( fgets( buf, sizeof( buf ), pResult ) )
107 for( size_t i = 0; i < sizeof(buf) && buf[i]; ++i )
109 if( buf[i] == '\n' )
110 buf[i] = ';';
112 aMIME.append( buf );
114 pclose( pResult );
116 if( aMIME.getLength() > 0 )
118 OString aLine = aMIME.makeStringAndClear();
120 sal_Int32 nIndex = 0;
121 while( nIndex != -1 )
123 OString aType = aLine.getToken( 0, ';', nIndex );
125 sal_Int32 nTypeIndex = 0;
126 OString aMimetype = aType.getToken( 0, ':', nTypeIndex );
127 OString aExtLine = aType.getToken( 0, ':', nTypeIndex );
128 if( nTypeIndex < 0 ) // ensure at least three tokens
129 continue;
130 OString aDesc = aType.getToken( 0, ':', nTypeIndex );
132 // create extension list string
133 sal_Int32 nExtIndex = 0;
134 OStringBuffer aExtension;
135 while( nExtIndex != -1 )
137 OString aExt = aExtLine.getToken( 0, ',', nExtIndex);
138 if( aExt.indexOf( "*." ) != 0 )
139 aExtension.append( "*." );
140 aExtension.append( aExt );
141 if( nExtIndex != -1 )
142 aExtension.append( ';' );
145 PluginDescription* pNew = new PluginDescription;
146 // set plugin name (path to library)
147 pNew->PluginName = OStringToOUString( rPath, aEncoding );
148 // set mimetype
149 pNew->Mimetype = OStringToOUString( aMimetype, aEncoding );
150 // set extension line
151 pNew->Extension = OStringToOUString( aExtension.makeStringAndClear(), aEncoding );
152 // set description
153 pNew->Description= OStringToOUString( aDesc, aEncoding );
154 rDescriptions.push_back( pNew );
155 #if OSL_DEBUG_LEVEL > 1
156 fprintf( stderr, "Mimetype: %s\nExtension: %s\n"
157 "Description: %s\n",
158 OUStringToOString( pNew->Mimetype, aEncoding ).getStr(),
159 OUStringToOString( pNew->Extension, aEncoding ).getStr(),
160 OUStringToOString( pNew->Description, aEncoding ).getStr()
162 #endif
165 #if OSL_DEBUG_LEVEL > 1
166 else
167 fprintf( stderr, "result of \"%s\" contains no mimtype\n",
168 aCommand.getStr() );
169 #endif
171 #if OSL_DEBUG_LEVEL > 1
172 else
173 fprintf( stderr, "command \"%s\" failed\n", aCommand.getStr() );
174 #endif
175 return nDescriptions > 0;
178 static void CheckPluginRegistryFiles( const rtl::OString& rPath, list< PluginDescription* >& rDescriptions )
180 rtl::OStringBuffer aPath( 1024 );
181 aPath.append( rPath );
182 aPath.append( "/pluginreg.dat" );
183 FILE* fp = fopen( aPath.getStr(), "r" );
184 if( fp )
186 #if OSL_DEBUG_LEVEL > 1
187 fprintf( stderr, "parsing %s\n", aPath.getStr() );
188 #endif
189 char aLine[1024];
190 while( fgets( aLine, sizeof( aLine ), fp ) )
192 int nLineLen = strlen( aLine );
193 int nDotPos;
194 for( nDotPos = nLineLen-1; nDotPos > 0 && aLine[nDotPos] != ':'; nDotPos-- )
196 if( aLine[0] == '/' && aLine[nDotPos] == ':' && aLine[nDotPos+1] == '$' )
197 CheckPlugin( ByteString( aLine, nDotPos ), rDescriptions );
199 fclose( fp );
202 // check subdirectories
203 long aBuffer[ sizeof( struct dirent ) + _PC_NAME_MAX +1 ];
205 DIR* pDIR = opendir( rPath.getStr() );
206 struct dirent* pDirEnt = NULL;
207 struct stat aStat;
208 while( pDIR && ! readdir_r( pDIR, (struct dirent*)aBuffer, &pDirEnt ) && pDirEnt )
210 char* pBaseName = ((struct dirent*)aBuffer)->d_name;
211 if( rtl_str_compare( ".", pBaseName ) && rtl_str_compare( "..", pBaseName ) )
213 rtl::OStringBuffer aBuf( 1024 );
214 aBuf.append( rPath );
215 aBuf.append( '/' );
216 aBuf.append( pBaseName );
218 if( ! stat( aBuf.getStr(), &aStat ) )
220 if( S_ISDIR( aStat.st_mode ) )
221 CheckPluginRegistryFiles( aBuf.makeStringAndClear(), rDescriptions );
225 if( pDIR )
226 closedir( pDIR );
229 Sequence<PluginDescription> XPluginManager_Impl::impl_getPluginDescriptions() throw()
231 static Sequence<PluginDescription> aDescriptions;
232 static BOOL bHavePlugins = FALSE;
233 if( ! bHavePlugins )
235 rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
236 list<PluginDescription*> aPlugins;
237 int i;
239 // unix: search for plugins in /usr/lib/netscape/plugins,
240 // ~/.netscape/plugins und NPX_PLUGIN_PATH
241 // additionally: search in PluginsPath
242 static const char* pHome = getenv( "HOME" );
243 static const char* pNPXPluginPath = getenv( "NPX_PLUGIN_PATH" );
245 ByteString aSearchPath( "/usr/lib/netscape/plugins" );
246 if( pHome )
248 aSearchPath.Append( ':' );
249 aSearchPath.Append( pHome );
250 aSearchPath += "/.netscape/plugins";
252 if( pNPXPluginPath )
254 aSearchPath.Append( ':' );
255 aSearchPath += pNPXPluginPath;
258 const Sequence< ::rtl::OUString >& rPaths( PluginManager::getAdditionalSearchPaths() );
259 for( i = 0; i < rPaths.getLength(); i++ )
261 aSearchPath += ":";
262 aSearchPath += ByteString( String( rPaths.getConstArray()[i] ), aEncoding );
266 long aBuffer[ sizeof( struct dirent ) + _PC_NAME_MAX +1 ];
267 int nPaths = aSearchPath.GetTokenCount( ':' );
268 for( i = 0; i < nPaths; i++ )
270 ByteString aPath( aSearchPath.GetToken( i, ':' ) );
271 if( aPath.Len() )
273 DIR* pDIR = opendir( aPath.GetBuffer() );
274 struct dirent* pDirEnt = NULL;
275 while( pDIR && ! readdir_r( pDIR, (struct dirent*)aBuffer, &pDirEnt ) && pDirEnt )
277 char* pBaseName = ((struct dirent*)aBuffer)->d_name;
278 if( pBaseName[0] != '.' ||
279 pBaseName[1] != '.' ||
280 pBaseName[2] != 0 )
282 ByteString aFileName( aPath );
283 aFileName += "/";
284 aFileName += pBaseName;
285 CheckPlugin( aFileName, aPlugins );
288 if( pDIR )
289 closedir( pDIR );
293 // try ~/.mozilla/pluginreg.dat
294 rtl::OStringBuffer aBuf(256);
295 aBuf.append( pHome );
296 aBuf.append( "/.mozilla" );
297 CheckPluginRegistryFiles( aBuf.makeStringAndClear(), aPlugins );
299 // create return value
300 aDescriptions = Sequence<PluginDescription>( aPlugins.size() );
301 #if OSL_DEBUG_LEVEL > 1
302 fprintf( stderr, "found %d plugins\n", aPlugins.size() );
303 #endif
304 list<PluginDescription*>::iterator iter;
305 for( iter = aPlugins.begin(), i=0; iter != aPlugins.end(); ++iter ,i++ )
307 aDescriptions.getArray()[ i ] = **iter;
308 delete *iter;
310 aPlugins.clear();
311 bHavePlugins = TRUE;
313 return aDescriptions;