1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unoapploader.c,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
42 #include "cppuhelper/findsofficepath.h"
43 #include "rtl/string.h"
44 #include "sal/types.h"
46 char const* getPath();
47 char* createCommandName( char* argv0
);
49 const int SEPARATOR
= '/';
50 const char* PATHSEPARATOR
= ":";
54 * The main function implements a loader for applications which use UNO.
56 * <p>This code runs on the Unix/Linux platforms only.</p>
58 * <p>The main function detects a UNO installation on the system and adds the
59 * relevant directories of the installation to the LD_LIBRARY_PATH environment
60 * variable. After that, the application process is loaded and started, whereby
61 * the new process inherits the environment of the calling process, including
62 * the modified LD_LIBRARY_PATH environment variable. The application's
63 * executable name must be the same as the name of this executable, prefixed
65 * <p>On MACOSX DYLD_LIBRARY_PATH is used instead of LD_LIBRARY_PATH!<p>
67 * <p>A UNO installation can be specified by the user by setting the UNO_PATH
68 * environment variable to the program directory of the UNO installation.
69 * If no installation is specified by the user, the default installation on
70 * the system will be taken. The default installation is found from the
71 * PATH environment variable. This requires that the 'soffice' executable or
72 * a symbolic link is in one of the directories listed in the PATH environment
75 int main( int argc
, char *argv
[] )
80 (void) argc
; /* avoid warning about unused parameter */
82 /* get the path of the UNO installation */
88 static const char* ENVVARNAME
= "DYLD_LIBRARY_PATH";
90 static const char* ENVVARNAME
= "LD_LIBRARY_PATH";
99 size_t pathlen
= strlen(path
);
102 char * unoinfo
= malloc(
103 pathlen
+ RTL_CONSTASCII_LENGTH("/unoinfo") + 1);
105 if (unoinfo
== NULL
) {
106 fprintf(stderr
, "Error: out of memory!\n");
109 strcpy(unoinfo
, path
);
112 "/unoinfo" + (pathlen
== 0 || path
[pathlen
- 1] != '/' ? 0 : 1));
113 ret
= lstat(unoinfo
, &stat
);
118 2 * pathlen
+ RTL_CONSTASCII_LENGTH("/unoinfo c++") + 1);
126 fprintf(stderr
, "Error: out of memory!\n");
135 if (p
== path
|| p
[-1] != '/') {
138 strcpy(q
, "unoinfo c++");
143 fprintf(stderr
, "Error: calling unoinfo failed!\n");
149 libpath
= realloc(libpath
, n
);
150 if (libpath
== NULL
) {
153 "Error: out of memory reading unoinfo output!\n");
156 m
= fread(libpath
+ old
, 1, n
- old
- 1, f
);
157 if (m
!= n
- old
- 1) {
159 fprintf(stderr
, "Error: cannot read unoinfo output!\n");
162 libpath
[old
+ m
] = '\0';
165 if (n
>= SAL_MAX_SIZE
/ 2) {
168 "Error: out of memory reading unoinfo output!\n");
174 if (pclose(f
) != 0) {
175 fprintf(stderr
, "Error: executing unoinfo failed!\n");
182 /* Assume an old OOo 2.x installation without unoinfo: */
183 libpath
= (char *) path
;
187 value
= getenv( ENVVARNAME
);
189 size
= strlen( ENVVARNAME
) + strlen( "=" ) + strlen( libpath
) + 1;
191 size
+= strlen( PATHSEPARATOR
) + strlen( value
);
192 envstr
= (char*) malloc( size
);
193 strcpy( envstr
, ENVVARNAME
);
194 strcat( envstr
, "=" );
195 strcat( envstr
, libpath
);
196 if ( freeLibpath
!= 0 )
202 strcat( envstr
, PATHSEPARATOR
);
203 strcat( envstr
, value
);
209 fprintf( stderr
, "Warning: no UNO installation found!\n" );
213 /* set the executable name for the application process */
214 cmdname
= createCommandName( argv
[0] );
218 * create the application process;
219 * if successful, execvp doesn't return to the calling process
221 execvp( cmdname
, argv
);
222 fprintf( stderr
, "Error: execvp failed!\n" );
229 * Gets the path of a UNO installation.
231 * @return the installation path or NULL, if no installation was specified or
232 * found, or if an error occured
234 char const* getPath()
236 char const* path
= cppuhelper_detail_findSofficePath();
240 fprintf( stderr
, "Warning: getting path from PATH environment "
241 "variable failed!\n" );
249 * Creates the application's executable file name.
251 * <p>The application's executable file name is the name of this executable
252 * prefixed by '_'.</p>
254 * @param argv0 specifies the argv[0] parameter of the main function
256 * @return the application's executable file name or NULL, if an error occured
258 char* createCommandName( char* argv0
)
260 const char* CMDPREFIX
= "_";
261 const char* prgname
= NULL
;
263 char* cmdname
= NULL
;
268 /* get the executable file name from argv0 */
272 * if argv0 doesn't contain an absolute path name, try to get the absolute
273 * path name from dladdr; note that this only works for Solaris, not for
276 if ( argv0
!= NULL
&& *argv0
!= SEPARATOR
&&
277 dladdr( (void*) &createCommandName
, &dl_info
) &&
278 dl_info
.dli_fname
!= NULL
&& *dl_info
.dli_fname
== SEPARATOR
)
280 prgname
= dl_info
.dli_fname
;
283 /* prefix the executable file name by '_' */
284 if ( prgname
!= NULL
)
286 cmdname
= (char*) malloc( strlen( prgname
) + strlen( CMDPREFIX
) + 1 );
287 sep
= strrchr( prgname
, SEPARATOR
);
290 pos
= ++sep
- prgname
;
291 strncpy( cmdname
, prgname
, pos
);
292 cmdname
[ pos
] = '\0';
293 strcat( cmdname
, CMDPREFIX
);
294 strcat( cmdname
, sep
);
298 strcpy( cmdname
, CMDPREFIX
);
299 strcat( cmdname
, prgname
);