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 ************************************************************************/
31 #define _LINUX_SOURCE_COMPAT
32 #include <sys/timer.h>
33 #undef _LINUX_SOURCE_COMPAT
38 #include <sys/types.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>
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() );
59 sal_Int32 nPos
= rPath
.lastIndexOf('/');
62 #if OSL_DEBUG_LEVEL > 1
63 fprintf( stderr
, "no absolute path to plugin\n" );
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() );
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() );
86 rtl_TextEncoding aEncoding
= osl_getThreadTextEncoding();
89 if (!UnxPluginComm::getPluginappPath(&path
))
91 #if OSL_DEBUG_LEVEL > 1
92 fprintf( stderr
, "cannot construct path to pluginapp.bin\n" );
97 tools::appendUnixShellWord(&cmd
, path
);
99 tools::appendUnixShellWord(&cmd
, rPath
);
100 OString
aCommand(cmd
.makeStringAndClear());
102 FILE* pResult
= popen( aCommand
.getStr(), "r" );
103 int nDescriptions
= 0;
108 while( fgets( buf
, sizeof( buf
), pResult
) )
110 for( size_t i
= 0; i
< sizeof(buf
) && buf
[i
]; ++i
)
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
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
);
152 pNew
->Mimetype
= OStringToOUString( aMimetype
, aEncoding
);
153 // set extension line
154 pNew
->Extension
= OStringToOUString( aExtension
.makeStringAndClear(), aEncoding
);
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"
161 OUStringToOString( pNew
->Mimetype
, aEncoding
).getStr(),
162 OUStringToOString( pNew
->Extension
, aEncoding
).getStr(),
163 OUStringToOString( pNew
->Description
, aEncoding
).getStr()
168 #if OSL_DEBUG_LEVEL > 1
170 fprintf( stderr
, "result of \"%s\" contains no mimtype\n",
174 #if OSL_DEBUG_LEVEL > 1
176 fprintf( stderr
, "command \"%s\" failed\n", aCommand
.getStr() );
178 return nDescriptions
> 0;
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" );
195 #if OSL_DEBUG_LEVEL > 1
196 fprintf( stderr
, "parsing %s\n", aPath
.getStr() );
199 while( fgets( aLine
, sizeof( aLine
), fp
) )
201 int nLineLen
= strlen( aLine
);
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
);
211 // check subdirectories
212 DIR* pDIR
= opendir( rPath
.getStr() );
213 struct dirent
* pDirEnt
= NULL
;
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
);
224 aBuf
.append( pBaseName
);
226 if( ! stat( aBuf
.getStr(), &aStat
) )
228 if( S_ISDIR( aStat
.st_mode
) )
229 CheckPluginRegistryFiles( aBuf
.makeStringAndClear(), rDescriptions
);
237 Sequence
<PluginDescription
> XPluginManager_Impl::impl_getPluginDescriptions() throw(css::uno::RuntimeException
, std::exception
)
239 static Sequence
<PluginDescription
> aDescriptions
;
240 static bool bHavePlugins
= false;
243 rtl_TextEncoding aEncoding
= osl_getThreadTextEncoding();
244 list
<PluginDescription
*> aPlugins
;
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");
256 aSearchBuffer
.append(':').append(pHome
).append("/.netscape/plugins");
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;
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] != '.' ||
285 OStringBuffer
aFileName(aPath
);
286 aFileName
.append('/').append(pBaseName
);
287 CheckPlugin( aFileName
.makeStringAndClear(), aPlugins
);
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() );
307 list
<PluginDescription
*>::iterator iter
;
308 for( iter
= aPlugins
.begin(), i
=0; iter
!= aPlugins
.end(); ++iter
,i
++ )
310 aDescriptions
.getArray()[ i
] = **iter
;
316 return aDescriptions
;
319 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */