Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <cstring>
31 : : #include <sys/stat.h>
32 : : #include <unistd.h>
33 : : #include <limits.h>
34 : :
35 : : #include "vcl/helper.hxx"
36 : : #include "vcl/ppdparser.hxx"
37 : : #include "tools/string.hxx"
38 : : #include "tools/urlobj.hxx"
39 : : #include "osl/file.hxx"
40 : : #include "osl/process.h"
41 : : #include "rtl/bootstrap.hxx"
42 : :
43 : : using ::rtl::Bootstrap;
44 : : using ::rtl::OUString;
45 : : using ::rtl::OUStringBuffer;
46 : : using ::rtl::OString;
47 : : using ::rtl::OStringToOUString;
48 : : using ::rtl::OUStringToOString;
49 : :
50 : : namespace psp {
51 : :
52 : 2088 : OUString getOfficePath( enum whichOfficePath ePath )
53 : : {
54 [ + + ][ + - ]: 2088 : static OUString aInstallationRootPath;
55 [ + + ][ + - ]: 2088 : static OUString aUserPath;
56 [ + + ][ + - ]: 2088 : static OUString aConfigPath;
57 [ + + ][ + - ]: 2088 : static OUString aEmpty;
58 : : static bool bOnce = false;
59 : :
60 [ + + ]: 2088 : if( ! bOnce )
61 : : {
62 : 277 : bOnce = true;
63 : 277 : OUString aIni;
64 [ + - ]: 277 : Bootstrap::get( OUString( RTL_CONSTASCII_USTRINGPARAM( "BRAND_BASE_DIR" ) ), aInstallationRootPath );
65 [ + - ]: 277 : aIni = aInstallationRootPath + OUString( RTL_CONSTASCII_USTRINGPARAM( "/program/" SAL_CONFIGFILE( "bootstrap" ) ) );
66 : 277 : Bootstrap aBootstrap( aIni );
67 [ + - ]: 277 : aBootstrap.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "CustomDataUrl" ) ), aConfigPath );
68 [ + - ]: 277 : aBootstrap.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "UserInstallation" ) ), aUserPath );
69 : 277 : OUString aUPath = aUserPath;
70 : :
71 [ - + ]: 277 : if( ! aConfigPath.compareToAscii( "file://", 7 ) )
72 : : {
73 : 0 : OUString aSysPath;
74 [ # # ][ # # ]: 0 : if( osl_getSystemPathFromFileURL( aConfigPath.pData, &aSysPath.pData ) == osl_File_E_None )
75 : 0 : aConfigPath = aSysPath;
76 : : }
77 [ + + ]: 277 : if( ! aInstallationRootPath.compareToAscii( "file://", 7 ) )
78 : : {
79 : 158 : OUString aSysPath;
80 [ + - ][ + - ]: 158 : if( osl_getSystemPathFromFileURL( aInstallationRootPath.pData, &aSysPath.pData ) == osl_File_E_None )
81 : 158 : aInstallationRootPath = aSysPath;
82 : : }
83 [ + + ]: 277 : if( ! aUserPath.compareToAscii( "file://", 7 ) )
84 : : {
85 : 272 : OUString aSysPath;
86 [ + - ][ + - ]: 272 : if( osl_getSystemPathFromFileURL( aUserPath.pData, &aSysPath.pData ) == osl_File_E_None )
87 : 272 : aUserPath = aSysPath;
88 : : }
89 : : // ensure user path exists
90 [ + - ]: 277 : aUPath += OUString( RTL_CONSTASCII_USTRINGPARAM( "/user/psprint" ) );
91 : : #if OSL_DEBUG_LEVEL > 1
92 : : oslFileError eErr =
93 : : #endif
94 [ + - ]: 277 : osl_createDirectoryPath( aUPath.pData, NULL, NULL );
95 : : #if OSL_DEBUG_LEVEL > 1
96 : : fprintf( stderr, "try to create \"%s\" = %d\n", OUStringToOString( aUPath, RTL_TEXTENCODING_UTF8 ).getStr(), eErr );
97 : : #endif
98 : : }
99 : :
100 [ + + + - ]: 2088 : switch( ePath )
101 : : {
102 : 272 : case ConfigPath: return aConfigPath;
103 : 772 : case InstallationRootPath: return aInstallationRootPath;
104 : 1044 : case UserPath: return aUserPath;
105 : : }
106 : 2088 : return aEmpty;
107 : : }
108 : :
109 : 500 : static OString getEnvironmentPath( const char* pKey )
110 : : {
111 : 500 : OString aPath;
112 : :
113 : 500 : const char* pValue = getenv( pKey );
114 [ # # ][ - + ]: 500 : if( pValue && *pValue )
115 : : {
116 : 500 : aPath = OString( pValue );
117 : : }
118 : 500 : return aPath;
119 : : }
120 : :
121 : : } // namespace psp
122 : :
123 : 500 : void psp::getPrinterPathList( std::list< OUString >& rPathList, const char* pSubDir )
124 : : {
125 : 500 : rPathList.clear();
126 [ + - ]: 500 : rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
127 : :
128 : 500 : OUStringBuffer aPathBuffer( 256 );
129 : :
130 : : // append net path
131 [ + - ][ + - ]: 500 : aPathBuffer.append( getOfficePath( psp::InstallationRootPath ) );
132 [ + + ]: 500 : if( aPathBuffer.getLength() )
133 : : {
134 [ + - ]: 290 : aPathBuffer.appendAscii( "/share/psprint" );
135 [ + + ]: 290 : if( pSubDir )
136 : : {
137 [ + - ]: 218 : aPathBuffer.append( sal_Unicode('/') );
138 [ + - ]: 218 : aPathBuffer.appendAscii( pSubDir );
139 : : }
140 [ + - ][ + - ]: 290 : rPathList.push_back( aPathBuffer.makeStringAndClear() );
141 : : }
142 : : // append user path
143 [ + - ][ + - ]: 500 : aPathBuffer.append( getOfficePath( psp::UserPath ) );
144 [ + + ]: 500 : if( aPathBuffer.getLength() )
145 : : {
146 [ + - ]: 495 : aPathBuffer.appendAscii( "/user/psprint" );
147 [ + + ]: 495 : if( pSubDir )
148 : : {
149 [ + - ]: 423 : aPathBuffer.append( sal_Unicode('/') );
150 [ + - ]: 423 : aPathBuffer.appendAscii( pSubDir );
151 : : }
152 [ + - ][ + - ]: 495 : rPathList.push_back( aPathBuffer.makeStringAndClear() );
153 : : }
154 : :
155 [ + - ]: 500 : OString aPath( getEnvironmentPath("SAL_PSPRINT") );
156 : 500 : sal_Int32 nIndex = 0;
157 [ - + ]: 500 : do
158 : : {
159 : 500 : OString aDir( aPath.getToken( 0, ':', nIndex ) );
160 [ + - ]: 500 : if( aDir.isEmpty() )
161 : 500 : continue;
162 : :
163 [ # # ]: 0 : if( pSubDir )
164 : : {
165 : 0 : aDir += "/";
166 : 0 : aDir += pSubDir;
167 : : }
168 : : struct stat aStat;
169 [ # # ][ # # ]: 0 : if( stat( aDir.getStr(), &aStat ) || ! S_ISDIR( aStat.st_mode ) )
[ # # ]
170 : 0 : continue;
171 : :
172 [ # # ][ # # ]: 500 : rPathList.push_back( OStringToOUString( aDir, aEncoding ) );
[ - + ]
173 : : } while( nIndex != -1 );
174 : :
175 : : #ifdef SYSTEM_PPD_DIR
176 : : if( pSubDir && rtl_str_compare( pSubDir, PRINTER_PPDDIR ) == 0 )
177 : : {
178 : : rPathList.push_back( rtl::OStringToOUString( rtl::OString( SYSTEM_PPD_DIR ), RTL_TEXTENCODING_UTF8 ) );
179 : : }
180 : : #endif
181 : :
182 [ + + ]: 500 : if( rPathList.empty() )
183 : : {
184 : : // last resort: next to program file (mainly for setup)
185 : 5 : OUString aExe;
186 [ + - ][ + - ]: 5 : if( osl_getExecutableFile( &aExe.pData ) == osl_Process_E_None )
187 : : {
188 [ + - ]: 5 : INetURLObject aDir( aExe );
189 [ + - ]: 5 : aDir.removeSegment();
190 [ + - ]: 5 : aExe = aDir.GetMainURL( INetURLObject::NO_DECODE );
191 : 5 : OUString aSysPath;
192 [ + - ][ + - ]: 5 : if( osl_getSystemPathFromFileURL( aExe.pData, &aSysPath.pData ) == osl_File_E_None )
193 : : {
194 [ + - ]: 5 : rPathList.push_back( aSysPath );
195 [ + - ]: 5 : }
196 : 5 : }
197 : 500 : }
198 : 500 : }
199 : :
200 : 272 : OUString psp::getFontPath()
201 : : {
202 [ + - ][ + - ]: 272 : static OUString aPath;
203 : :
204 [ + - ]: 272 : if (aPath.isEmpty())
205 : : {
206 : 272 : OUStringBuffer aPathBuffer( 512 );
207 : :
208 [ + - ]: 272 : OUString aConfigPath( getOfficePath( psp::ConfigPath ) );
209 [ + - ]: 272 : OUString aInstallationRootPath( getOfficePath( psp::InstallationRootPath ) );
210 [ + - ]: 272 : OUString aUserPath( getOfficePath( psp::UserPath ) );
211 [ - + ]: 272 : if( !aConfigPath.isEmpty() )
212 : : {
213 : : // #i53530# Path from CustomDataUrl will completely
214 : : // replace net and user paths if the path exists
215 [ # # ]: 0 : aPathBuffer.append(aConfigPath);
216 [ # # ]: 0 : aPathBuffer.appendAscii("/share/fonts");
217 : : // check existance of config path
218 : : struct stat aStat;
219 [ # # ][ # # ]: 0 : if( 0 != stat( OUStringToOString( aPathBuffer.makeStringAndClear(), osl_getThreadTextEncoding() ).getStr(), &aStat )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # #
# # # # ]
220 : 0 : || ! S_ISDIR( aStat.st_mode ) )
221 : 0 : aConfigPath = OUString();
222 : : else
223 : : {
224 [ # # ]: 0 : aPathBuffer.append(aConfigPath);
225 [ # # ]: 0 : aPathBuffer.appendAscii("/share/fonts");
226 : : }
227 : : }
228 [ + - ]: 272 : if( aConfigPath.isEmpty() )
229 : : {
230 [ + + ]: 272 : if( !aInstallationRootPath.isEmpty() )
231 : : {
232 [ + - ]: 158 : aPathBuffer.append( aInstallationRootPath );
233 [ + - ]: 158 : aPathBuffer.appendAscii( "/share/fonts/truetype;");
234 [ + - ]: 158 : aPathBuffer.append( aInstallationRootPath );
235 [ + - ]: 158 : aPathBuffer.appendAscii( "/share/fonts/type1;" );
236 : : }
237 [ + + ]: 272 : if( !aUserPath.isEmpty() )
238 : : {
239 [ + - ]: 267 : aPathBuffer.append( aUserPath );
240 [ + - ]: 267 : aPathBuffer.appendAscii( "/user/fonts" );
241 : : }
242 : : }
243 : :
244 [ + - ]: 272 : aPath = aPathBuffer.makeStringAndClear();
245 : : #if OSL_DEBUG_LEVEL > 1
246 : : fprintf( stderr, "initializing font path to \"%s\"\n", OUStringToOString( aPath, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
247 : : #endif
248 : : }
249 : 272 : return aPath;
250 : : }
251 : :
252 : 0 : bool psp::convertPfbToPfa( ::osl::File& rInFile, ::osl::File& rOutFile )
253 : : {
254 : : static unsigned char hexDigits[] =
255 : : {
256 : : '0', '1', '2', '3', '4', '5', '6', '7',
257 : : '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
258 : : };
259 : :
260 : 0 : bool bSuccess = true;
261 : 0 : bool bEof = false;
262 : : unsigned char buffer[256];
263 : : sal_uInt64 nRead;
264 : 0 : sal_uInt64 nOrgPos = 0;
265 [ # # ]: 0 : rInFile.getPos( nOrgPos );
266 : :
267 [ # # ][ # # ]: 0 : while( bSuccess && ! bEof )
[ # # ]
268 : : {
269 : : // read leading bytes
270 [ # # ][ # # ]: 0 : bEof = ! rInFile.read( buffer, 6, nRead ) && nRead == 6 ? false : true;
[ # # ]
271 : 0 : unsigned int nType = buffer[ 1 ];
272 : 0 : unsigned int nBytesToRead = buffer[2] | buffer[3] << 8 | buffer[4] << 16 | buffer[5] << 24;
273 [ # # ]: 0 : if( buffer[0] != 0x80 ) // test for pfb m_agic number
274 : : {
275 : : // this migt be a pfa font already
276 [ # # ][ # # ]: 0 : if( ! rInFile.read( buffer+6, 9, nRead ) && nRead == 9 &&
[ # # ][ # # ]
[ # # ][ # # ]
277 : 0 : ( ! std::strncmp( (char*)buffer, "%!FontType1-", 12 ) ||
278 : 0 : ! std::strncmp( (char*)buffer, "%!PS-AdobeFont-", 15 ) ) )
279 : : {
280 : 0 : sal_uInt64 nWrite = 0;
281 [ # # ][ # # ]: 0 : if( rOutFile.write( buffer, 15, nWrite ) || nWrite != 15 )
[ # # ][ # # ]
282 : 0 : bSuccess = false;
283 [ # # ][ # # ]: 0 : while( bSuccess &&
[ # # ][ # # ]
284 [ # # ]: 0 : ! rInFile.read( buffer, sizeof( buffer ), nRead ) &&
285 : : nRead != 0 )
286 : : {
287 [ # # ][ # # ]: 0 : if( rOutFile.write( buffer, nRead, nWrite ) ||
[ # # ][ # # ]
288 : : nWrite != nRead )
289 : 0 : bSuccess = false;
290 : : }
291 : 0 : bEof = true;
292 : : }
293 : : else
294 : 0 : bSuccess = false;
295 : : }
296 [ # # ][ # # ]: 0 : else if( nType == 1 || nType == 2 )
297 : : {
298 [ # # ]: 0 : unsigned char* pBuffer = new unsigned char[ nBytesToRead+1 ];
299 : :
300 [ # # ][ # # ]: 0 : if( ! rInFile.read( pBuffer, nBytesToRead, nRead ) && nRead == nBytesToRead )
[ # # ][ # # ]
301 : : {
302 [ # # ]: 0 : if( nType == 1 )
303 : : {
304 : : // ascii data, convert dos lineends( \r\n ) and
305 : : // m_ac lineends( \r ) to \n
306 [ # # ]: 0 : unsigned char * pWriteBuffer = new unsigned char[ nBytesToRead ];
307 : 0 : unsigned int nBytesToWrite = 0;
308 [ # # ]: 0 : for( unsigned int i = 0; i < nBytesToRead; i++ )
309 : : {
310 [ # # ]: 0 : if( pBuffer[i] != '\r' )
311 : 0 : pWriteBuffer[ nBytesToWrite++ ] = pBuffer[i];
312 [ # # ]: 0 : else if( pBuffer[ i+1 ] == '\n' )
313 : : {
314 : 0 : i++;
315 : 0 : pWriteBuffer[ nBytesToWrite++ ] = '\n';
316 : : }
317 : : else
318 : 0 : pWriteBuffer[ nBytesToWrite++ ] = '\n';
319 : : }
320 [ # # ][ # # ]: 0 : if( rOutFile.write( pWriteBuffer, nBytesToWrite, nRead ) || nRead != nBytesToWrite )
[ # # ][ # # ]
321 : 0 : bSuccess = false;
322 : :
323 [ # # ]: 0 : delete [] pWriteBuffer;
324 : : }
325 : : else
326 : : {
327 : : // binary data
328 : 0 : unsigned int nBuffer = 0;
329 [ # # ][ # # ]: 0 : for( unsigned int i = 0; i < nBytesToRead && bSuccess; i++ )
[ # # ]
330 : : {
331 : 0 : buffer[ nBuffer++ ] = hexDigits[ pBuffer[ i ] >> 4 ];
332 : 0 : buffer[ nBuffer++ ] = hexDigits[ pBuffer[ i ] & 15 ];
333 [ # # ]: 0 : if( nBuffer >= 80 )
334 : : {
335 : 0 : buffer[ nBuffer++ ] = '\n';
336 [ # # ][ # # ]: 0 : if( rOutFile.write( buffer, nBuffer, nRead ) || nRead != nBuffer )
[ # # ][ # # ]
337 : 0 : bSuccess = false;
338 : 0 : nBuffer = 0;
339 : : }
340 : : }
341 [ # # ][ # # ]: 0 : if( nBuffer > 0 && bSuccess )
342 : : {
343 : 0 : buffer[ nBuffer++ ] = '\n';
344 [ # # ][ # # ]: 0 : if( rOutFile.write( buffer, nBuffer, nRead ) || nRead != nBuffer )
[ # # ][ # # ]
345 : 0 : bSuccess = false;
346 : : }
347 : : }
348 : : }
349 : : else
350 : 0 : bSuccess = false;
351 : :
352 [ # # ]: 0 : delete [] pBuffer;
353 : : }
354 [ # # ]: 0 : else if( nType == 3 )
355 : 0 : bEof = true;
356 : : else
357 : 0 : bSuccess = false;
358 : : }
359 : :
360 : 0 : return bSuccess;
361 : : }
362 : :
363 : 51669 : void psp::normPath( OString& rPath )
364 : : {
365 : : char buf[PATH_MAX];
366 : :
367 : : // double slashes and slash at end are probably
368 : : // removed by realpath anyway, but since this runs
369 : : // on many different platforms let's play it safe
370 : 51669 : rtl::OString aPath = rPath.replaceAll("//", "/");
371 : :
372 [ - + ][ - + ]: 51669 : if( !aPath.isEmpty() && aPath[aPath.getLength()-1] == '/' )
[ + - ]
373 : 0 : aPath = aPath.copy(0, aPath.getLength()-1);
374 : :
375 [ + + - + : 103338 : if( ( aPath.indexOfL(RTL_CONSTASCII_STRINGPARAM("./")) != -1 ||
+ + ][ + + ]
376 : 51353 : aPath.indexOf( '~' ) != -1 )
377 : 316 : && realpath( aPath.getStr(), buf ) )
378 : : {
379 : 158 : rPath = buf;
380 : : }
381 : : else
382 : : {
383 : 51511 : rPath = aPath;
384 : 51669 : }
385 : 51669 : }
386 : :
387 : 51086 : void psp::splitPath( OString& rPath, OString& rDir, OString& rBase )
388 : : {
389 : 51086 : normPath( rPath );
390 : 51086 : sal_Int32 nIndex = rPath.lastIndexOf( '/' );
391 [ + - ]: 51086 : if( nIndex > 0 )
392 : 51086 : rDir = rPath.copy( 0, nIndex );
393 [ # # ]: 0 : else if( nIndex == 0 ) // root dir
394 : 0 : rDir = rPath.copy( 0, 1 );
395 [ + - ]: 51086 : if( rPath.getLength() > nIndex+1 )
396 : 51086 : rBase = rPath.copy( nIndex+1 );
397 : 51086 : }
398 : :
399 : :
400 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|