1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "precompiled_cppuhelper.hxx"
25 #include "sal/config.h"
26 
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #if defined WNT
31 
32 #define WIN32_LEAN_AND_MEAN
33 #include <windows.h>
34 
35 /*
36  * Gets the installation path from the Windows Registry for the specified
37  * registry key.
38  *
39  * @param hroot       open handle to predefined root registry key
40  * @param subKeyName  name of the subkey to open
41  *
42  * @return the installation path or NULL, if no installation was found or
43  *         if an error occured
44  */
45 static char* getPathFromRegistryKey( HKEY hroot, const char* subKeyName )
46 {
47     HKEY hkey;
48     DWORD type;
49     char* data = NULL;
50     DWORD size;
51 
52     /* open the specified registry key */
53     if ( RegOpenKeyEx( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )
54     {
55         return NULL;
56     }
57 
58     /* find the type and size of the default value */
59     if ( RegQueryValueEx( hkey, NULL, NULL, &type, NULL, &size) != ERROR_SUCCESS )
60     {
61         RegCloseKey( hkey );
62         return NULL;
63     }
64 
65     /* get memory to hold the default value */
66     data = (char*) malloc( size );
67 
68     /* read the default value */
69     if ( RegQueryValueEx( hkey, NULL, NULL, &type, (LPBYTE) data, &size ) != ERROR_SUCCESS )
70     {
71         RegCloseKey( hkey );
72         return NULL;
73     }
74 
75     /* release registry key handle */
76     RegCloseKey( hkey );
77 
78     return data;
79 }
80 
81 /*
82  * Gets the installation path from the Windows Registry.
83  *
84  * @return the installation path or NULL, if no installation was found or
85  *         if an error occured
86  */
87 static char* platformSpecific()
88 {
89     const char* SUBKEYNAME = "Software\\OpenOffice.org\\UNO\\InstallPath";
90 
91     char* path = NULL;
92 
93     /* read the key's default value from HKEY_CURRENT_USER */
94     path = getPathFromRegistryKey( HKEY_CURRENT_USER, SUBKEYNAME );
95 
96     if ( path == NULL )
97     {
98         /* read the key's default value from HKEY_LOCAL_MACHINE */
99         path = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, SUBKEYNAME );
100     }
101 
102     return path;
103 }
104 
105 #else
106 
107 #include <unistd.h>
108 #include <limits.h>
109 
110 /*
111  * Gets the installation path from the PATH environment variable.
112  *
113  * <p>An installation is found, if the executable 'soffice' or a symbolic link
114  * is in one of the directories listed in the PATH environment variable.</p>
115  *
116  * @return the installation path or NULL, if no installation was found or
117  *         if an error occured
118  */
119 static char* platformSpecific()
120 {
121     const int SEPARATOR = '/';
122     const char* PATHSEPARATOR = ":";
123     const char* PATHVARNAME = "PATH";
124     const char* APPENDIX = "/soffice";
125 
126     char* path = NULL;
127     char* env = NULL;
128     char* str = NULL;
129     char* dir = NULL;
130     char* file = NULL;
131     char* resolved = NULL;
132 	char* sep = NULL;
133 
134     char buffer[PATH_MAX];
135     int pos;
136 
137     /* get the value of the PATH environment variable */
138     env = getenv( PATHVARNAME );
139 	str = (char*) malloc( strlen( env ) + 1 );
140 	strcpy( str, env );
141 
142     /* get the tokens separated by ':' */
143     dir = strtok( str, PATHSEPARATOR );
144 
145 	while ( dir )
146 	{
147         /* construct soffice file path */
148         file = (char*) malloc( strlen( dir ) + strlen( APPENDIX ) + 1 );
149 		strcpy( file, dir );
150 		strcat( file, APPENDIX );
151 
152 		/* check existence of soffice file */
153 		if ( !access( file, F_OK ) )
154 		{
155             /* resolve symbolic link */
156 			resolved = realpath( file, buffer );
157 
158             if ( resolved != NULL )
159 			{
160                 /* get path to program directory */
161 				sep = strrchr( resolved, SEPARATOR );
162 
163 				if ( sep != NULL )
164 				{
165                     pos = sep - resolved;
166                     path = (char*) malloc( pos + 1 );
167                     strncpy( path, resolved, pos );
168                     path[ pos ] = '\0';
169                     free( file );
170                     break;
171 				}
172 			}
173 		}
174 
175 		dir = strtok( NULL, PATHSEPARATOR );
176         free( file );
177 	}
178 
179 	free( str );
180 
181     return path;
182 }
183 
184 #endif
185 
186 char const* cppuhelper_detail_findSofficePath()
187 {
188     const char* UNOPATHVARNAME = "UNO_PATH";
189 
190     char* path = NULL;
191 
192     /* get the installation path from the UNO_PATH environment variable */
193     path = getenv( UNOPATHVARNAME );
194 
195     if ( path == NULL || strlen( path ) == 0 )
196     {
197 		path = platformSpecific();
198     }
199 
200     return path;
201 }
202