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