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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_comphelper.hxx"
26 
27 #include <stdio.h>
28 #include <osl/file.hxx>
29 #include <osl/security.hxx>
30 #include <osl/thread.h>
31 #include <vos/process.hxx>
32 #include <rtl/textenc.h>
33 #include <rtl/uri.h>
34 #include <rtl/uri.hxx>
35 
36 using namespace vos;
37 using namespace osl;
38 using namespace rtl;
39 
40 #define PATH_DELEMITTER	'/'
41 
42 #define USER_REGISTRY_NAME_ENV 		"STAR_USER_REGISTRY"
43 #define SYSTEM_REGISTRY_NAME_ENV 	"STAR_REGISTRY"
44 #define REGISTRY_SYSTEM_NAME	"services.rdb"
45 
46 #define REGISTRY_LOCAL_NAME		"user60.rdb"
47 
48 #ifdef SAL_UNX
49 #define CONFIG_PATH_PREFIX		"."
50 #else
51 #define CONFIG_PATH_PREFIX		""
52 #endif
53 
54 namespace comphelper
55 {
56 
57 /**
58    @return sal_True, if the office is started in a portal
59                      environment.
60 		   sal_False, if the common office is started
61  */
retrievePortalUserDir(OUString * pDirectory)62 static sal_Bool retrievePortalUserDir( OUString *pDirectory )
63 {
64 	OStartupInfo startInfo;
65 	sal_uInt32 nArgs = startInfo.getCommandArgCount();
66 	sal_Bool bIsPortalUser = sal_False;
67 	OUString sArg;
68 	while( nArgs > 0 )
69   	{
70 		if ( !startInfo.getCommandArg(--nArgs, sArg) )
71 	  	{
72 	    	if ( sArg.indexOf(OUString::createFromAscii("-userid")) == 0 )
73 	    	{
74 
75 	      		bIsPortalUser = sal_True;
76 				sal_Int32 nStart = sArg.lastIndexOf( '[' );
77 				sal_Int32 nEnd   = sArg.lastIndexOf( ']' );
78 				if( -1 == nStart || -1 == nEnd || nEnd < nStart)
79 				{
80 					*pDirectory = OUString();
81 				}
82 				else
83 				{
84 					OUString aEncHome = sArg.copy( nStart + 1 , nEnd - nStart -1 );
85 					*pDirectory = rtl::Uri::decode(aEncHome,
86 												   rtl_UriDecodeWithCharset,
87 												   RTL_TEXTENCODING_UTF8);
88 				}
89 	      		break;
90 	    	}
91 	  	}
92  	}
93 	return bIsPortalUser;
94 }
95 
96 
getDefaultLocalRegistry()97 static OUString getDefaultLocalRegistry()
98 {
99 	OUString uBuffer, userRegistryName;
100 	OUString portalUserDir;
101 
102 	sal_Bool bIsPortalUser = retrievePortalUserDir( &portalUserDir );
103 
104 	if ( bIsPortalUser )
105    	{
106 		if( !portalUserDir.isEmpty() )
107 		{
108 			FileBase::getFileURLFromSystemPath( portalUserDir , portalUserDir );
109 			userRegistryName = portalUserDir;
110 			userRegistryName += OUString( RTL_CONSTASCII_USTRINGPARAM(
111 				"/user/" REGISTRY_LOCAL_NAME ) );
112 
113 			// Directory creation is probably necessary for bootstrapping a new
114 			// user in the portal environment (the ucb uses this function).
115 			// This should be solved differently, as
116 			// no one expects this function to create anything ...
117 			OUString sSeparator(RTL_CONSTASCII_USTRINGPARAM("/"));
118 			OUString sPath(RTL_CONSTASCII_USTRINGPARAM("file://"));
119 			FileBase::RC retRC = FileBase::E_None;
120 
121 			sal_Int32 nIndex = 3;
122 			sPath += userRegistryName.getToken(2, '/', nIndex);
123 			while( nIndex != -1 )
124 			{
125 				sPath += sSeparator;
126 				sPath += userRegistryName.getToken(0, '/', nIndex);
127 				if( nIndex == -1 )
128 					break;
129 				Directory aDir( sPath );
130 				if( aDir.open() == FileBase::E_NOENT )
131 				{
132 					retRC = Directory::create(sPath);
133 					if ( retRC != FileBase::E_None && retRC != FileBase::E_EXIST)
134 					{
135 						return OUString();
136 					}
137 				}
138 			}
139 		}
140 	}
141 	else /* bIsPortalUser */
142 	{
143 		::osl::Security aUserSecurity;
144 		aUserSecurity.getConfigDir( userRegistryName );
145 		userRegistryName += OUString( RTL_CONSTASCII_USTRINGPARAM(
146 			"/" CONFIG_PATH_PREFIX REGISTRY_LOCAL_NAME ) );
147 	}
148 
149 	return userRegistryName;
150 }
151 
152 
getPathToUserRegistry()153 OUString getPathToUserRegistry()
154 {
155 	OUString  	userRegistryName;
156 	FILE  		*f=NULL;
157 
158 	// search the environment STAR_USER_REGISTRY
159 	OString sBuffer( getenv(USER_REGISTRY_NAME_ENV) );
160 	if ( !sBuffer.isEmpty() )
161 	{
162 		f = fopen( sBuffer.getStr(), "r" );
163 
164 		if (f != NULL)
165 		{
166 			fclose(f);
167 			userRegistryName = OStringToOUString( sBuffer, osl_getThreadTextEncoding() );
168 		}
169 	}
170 
171 	if ( userRegistryName.isEmpty() )
172 	{
173 		userRegistryName = getDefaultLocalRegistry();
174 	}
175 
176 	return userRegistryName;
177 }
178 
getPathToSystemRegistry()179 OUString getPathToSystemRegistry()
180 {
181 	OUString uBuffer;
182 	OUString registryBaseName( RTL_CONSTASCII_USTRINGPARAM(REGISTRY_SYSTEM_NAME) );
183 	OUString systemRegistryName;
184 	FILE  	 *f=NULL;
185 
186 	// search in the directory of the executable
187     OStartupInfo info;
188 	if( OStartupInfo::E_None == info.getExecutableFile(uBuffer) )
189 	{
190 		sal_uInt32 	lastIndex = uBuffer.lastIndexOf(PATH_DELEMITTER);
191 		if (lastIndex > 0)
192 		{
193 			uBuffer = uBuffer.copy(0, lastIndex + 1);
194 		}
195 
196 		uBuffer += registryBaseName;
197 
198 		if (!FileBase::getSystemPathFromFileURL(uBuffer, systemRegistryName))
199 		{
200 			OString tmpStr( OUStringToOString(systemRegistryName, osl_getThreadTextEncoding()) );
201 			f = fopen( tmpStr.getStr(), "r" );
202 		}
203 	}
204 
205 	if (f == NULL)
206 	{
207 		// search the environment STAR_REGISTRY
208 		OString tmpStr( getenv(SYSTEM_REGISTRY_NAME_ENV) );
209 		if ( !tmpStr.isEmpty() )
210 		{
211 			f = fopen(tmpStr.getStr(), "r");
212 
213 			if (f != NULL)
214 			{
215 				fclose(f);
216 				systemRegistryName = OStringToOUString( tmpStr, osl_getThreadTextEncoding() );
217 			} else
218 			{
219 				systemRegistryName = OUString();
220 			}
221 		}
222 	} else
223 	{
224 		fclose(f);
225 	}
226 
227 	return systemRegistryName;
228 }
229 
230 }
231 
232