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"
32 #include <sys/types.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>
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() );
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" );
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() );
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() );
81 rtl_TextEncoding aEncoding
= osl_getThreadTextEncoding();
84 if (!UnxPluginComm::getPluginappPath(&path
)) {
85 #if OSL_DEBUG_LEVEL > 1
86 fprintf( stderr
, "cannot construct path to pluginapp.bin\n" );
90 rtl::OStringBuffer cmd
;
91 tools::appendUnixShellWord(&cmd
, path
);
93 tools::appendUnixShellWord(&cmd
, rPath
);
94 rtl::OString
aCommand(cmd
.makeStringAndClear());
96 FILE* pResult
= popen( aCommand
.getStr(), "r" );
97 int nDescriptions
= 0;
102 while( fgets( buf
, sizeof( buf
), pResult
) )
104 for( size_t i
= 0; i
< sizeof(buf
) && buf
[i
]; ++i
)
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
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
);
146 pNew
->Mimetype
= OStringToOUString( aMimetype
, aEncoding
);
147 // set extension line
148 pNew
->Extension
= OStringToOUString( aExtension
.makeStringAndClear(), aEncoding
);
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"
155 OUStringToOString( pNew
->Mimetype
, aEncoding
).getStr(),
156 OUStringToOString( pNew
->Extension
, aEncoding
).getStr(),
157 OUStringToOString( pNew
->Description
, aEncoding
).getStr()
162 #if OSL_DEBUG_LEVEL > 1
164 fprintf( stderr
, "result of \"%s\" contains no mimtype\n",
168 #if OSL_DEBUG_LEVEL > 1
170 fprintf( stderr
, "command \"%s\" failed\n", aCommand
.getStr() );
172 return nDescriptions
> 0;
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" );
189 #if OSL_DEBUG_LEVEL > 1
190 fprintf( stderr
, "parsing %s\n", aPath
.getStr() );
193 while( fgets( aLine
, sizeof( aLine
), fp
) )
195 int nLineLen
= strlen( aLine
);
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
);
205 // check subdirectories
206 DIR* pDIR
= opendir( rPath
.getStr() );
207 struct dirent
* pDirEnt
= NULL
;
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
);
218 aBuf
.append( pBaseName
);
220 if( ! stat( aBuf
.getStr(), &aStat
) )
222 if( S_ISDIR( aStat
.st_mode
) )
223 CheckPluginRegistryFiles( aBuf
.makeStringAndClear(), rDescriptions
);
231 Sequence
<PluginDescription
> XPluginManager_Impl::impl_getPluginDescriptions() throw()
233 static Sequence
<PluginDescription
> aDescriptions
;
234 static BOOL bHavePlugins
= FALSE
;
237 rtl_TextEncoding aEncoding
= osl_getThreadTextEncoding();
238 list
<PluginDescription
*> aPlugins
;
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" );
250 aSearchPath
.Append( ':' );
251 aSearchPath
.Append( pHome
);
252 aSearchPath
+= "/.netscape/plugins";
256 aSearchPath
.Append( ':' );
257 aSearchPath
+= pNPXPluginPath
;
260 const Sequence
< ::rtl::OUString
>& rPaths( PluginManager::getAdditionalSearchPaths() );
261 for( i
= 0; i
< rPaths
.getLength(); i
++ )
264 aSearchPath
+= ByteString( String( rPaths
.getConstArray()[i
] ), aEncoding
);
267 int nPaths
= aSearchPath
.GetTokenCount( ':' );
269 for( i
= 0; i
< nPaths
; i
++ )
271 ByteString
aPath( aSearchPath
.GetToken( i
, ':' ) );
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] != '.' ||
283 ByteString
aFileName( aPath
);
285 aFileName
+= pBaseName
;
286 CheckPlugin( aFileName
, aPlugins
);
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() );
305 list
<PluginDescription
*>::iterator iter
;
306 for( iter
= aPlugins
.begin(), i
=0; iter
!= aPlugins
.end(); ++iter
,i
++ )
308 aDescriptions
.getArray()[ i
] = **iter
;
314 return aDescriptions
;