gdi32: IntersectClipRect should update actual clipping region for a EMF DC.
[wine] / libs / wine / config.c
1 /*
2  * Configuration parameters shared between Wine server and clients
3  *
4  * Copyright 2002 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <sys/stat.h>
30 #ifdef HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif
33 #ifdef HAVE_PWD_H
34 #include <pwd.h>
35 #endif
36 #include "wine/library.h"
37
38 static const char server_config_dir[] = "/.wine";        /* config dir relative to $HOME */
39 static const char server_root_prefix[] = "/tmp/.wine-";  /* prefix for server root dir */
40 static const char server_dir_prefix[] = "/server-";      /* prefix for server dir */
41
42 static char *bindir;
43 static char *dlldir;
44 static char *datadir;
45 static char *config_dir;
46 static char *server_dir;
47 static char *build_dir;
48 static char *user_name;
49 static char *argv0_name;
50
51 #ifdef __GNUC__
52 static void fatal_error( const char *err, ... )  __attribute__((noreturn,format(printf,1,2)));
53 static void fatal_perror( const char *err, ... )  __attribute__((noreturn,format(printf,1,2)));
54 #endif
55
56 #if defined(__linux__) || defined(__FreeBSD_kernel__ )
57 #define EXE_LINK "/proc/self/exe"
58 #elif defined (__FreeBSD__) || defined(__DragonFly__)
59 #define EXE_LINK "/proc/curproc/file"
60 #endif
61
62 /* die on a fatal error */
63 static void fatal_error( const char *err, ... )
64 {
65     va_list args;
66
67     va_start( args, err );
68     fprintf( stderr, "wine: " );
69     vfprintf( stderr, err, args );
70     va_end( args );
71     exit(1);
72 }
73
74 /* die on a fatal error */
75 static void fatal_perror( const char *err, ... )
76 {
77     va_list args;
78
79     va_start( args, err );
80     fprintf( stderr, "wine: " );
81     vfprintf( stderr, err, args );
82     perror( " " );
83     va_end( args );
84     exit(1);
85 }
86
87 /* malloc wrapper */
88 static void *xmalloc( size_t size )
89 {
90     void *res;
91
92     if (!size) size = 1;
93     if (!(res = malloc( size ))) fatal_error( "virtual memory exhausted\n");
94     return res;
95 }
96
97 /* strdup wrapper */
98 static char *xstrdup( const char *str )
99 {
100     size_t len = strlen(str) + 1;
101     char *res = xmalloc( len );
102     memcpy( res, str, len );
103     return res;
104 }
105
106 /* check if a string ends in a given substring */
107 static inline int strendswith( const char* str, const char* end )
108 {
109     size_t len = strlen( str );
110     size_t tail = strlen( end );
111     return len >= tail && !strcmp( str + len - tail, end );
112 }
113
114 /* remove all trailing slashes from a path name */
115 static inline void remove_trailing_slashes( char *path )
116 {
117     int len = strlen( path );
118     while (len > 1 && path[len-1] == '/') path[--len] = 0;
119 }
120
121 /* build a path from the specified dir and name */
122 static char *build_path( const char *dir, const char *name )
123 {
124     size_t len = strlen(dir);
125     char *ret = xmalloc( len + strlen(name) + 2 );
126
127     memcpy( ret, dir, len );
128     if (len && ret[len-1] != '/') ret[len++] = '/';
129     strcpy( ret + len, name );
130     return ret;
131 }
132
133 /* return the directory that contains the library at run-time */
134 static char *get_runtime_libdir(void)
135 {
136 #ifdef HAVE_DLADDR
137     Dl_info info;
138     char *libdir;
139
140     if (dladdr( get_runtime_libdir, &info ) && info.dli_fname[0] == '/')
141     {
142         const char *p = strrchr( info.dli_fname, '/' );
143         unsigned int len = p - info.dli_fname;
144         if (!len) len++;  /* include initial slash */
145         libdir = xmalloc( len + 1 );
146         memcpy( libdir, info.dli_fname, len );
147         libdir[len] = 0;
148         return libdir;
149     }
150 #endif /* HAVE_DLADDR */
151     return NULL;
152 }
153
154 /* return the directory that contains the main exe at run-time */
155 static char *get_runtime_bindir( const char *argv0 )
156 {
157     char *p, *bindir, *cwd;
158     int len, size;
159
160 #ifdef EXE_LINK
161     for (size = 256; ; size *= 2)
162     {
163         int ret;
164         if (!(bindir = malloc( size ))) break;
165         if ((ret = readlink( EXE_LINK, bindir, size )) == -1) break;
166         if (ret != size)
167         {
168             bindir[ret] = 0;
169             if (!(p = strrchr( bindir, '/' ))) break;
170             if (p == bindir) p++;
171             *p = 0;
172             return bindir;
173         }
174         free( bindir );
175     }
176     free( bindir );
177 #endif
178
179     if (!(p = strrchr( argv0, '/' ))) return NULL;
180
181     len = p - argv0;
182     if (!len) len++;  /* include leading slash */
183
184     if (argv0[0] == '/')  /* absolute path */
185     {
186         bindir = xmalloc( len + 1 );
187         memcpy( bindir, argv0, len );
188         bindir[len] = 0;
189     }
190     else
191     {
192         /* relative path, make it absolute */
193         for (size = 256 + len; ; size *= 2)
194         {
195             if (!(cwd = malloc( size ))) return NULL;
196             if (getcwd( cwd, size - len ))
197             {
198                 bindir = cwd;
199                 cwd += strlen(cwd);
200                 *cwd++ = '/';
201                 memcpy( cwd, argv0, len );
202                 cwd[len] = 0;
203                 break;
204             }
205             free( cwd );
206             if (errno != ERANGE) return NULL;
207         }
208     }
209     return bindir;
210 }
211
212 /* initialize the server directory value */
213 static void init_server_dir( dev_t dev, ino_t ino )
214 {
215     char *p;
216 #ifdef HAVE_GETUID
217     const unsigned int uid = getuid();
218 #else
219     const unsigned int uid = 0;
220 #endif
221
222     server_dir = xmalloc( sizeof(server_root_prefix) + 32 + sizeof(server_dir_prefix) +
223                           2*sizeof(dev) + 2*sizeof(ino) );
224     sprintf( server_dir, "%s%u%s", server_root_prefix, uid, server_dir_prefix );
225     p = server_dir + strlen(server_dir);
226
227     if (dev != (unsigned long)dev)
228         p += sprintf( p, "%lx%08lx-", (unsigned long)((unsigned long long)dev >> 32), (unsigned long)dev );
229     else
230         p += sprintf( p, "%lx-", (unsigned long)dev );
231
232     if (ino != (unsigned long)ino)
233         sprintf( p, "%lx%08lx", (unsigned long)((unsigned long long)ino >> 32), (unsigned long)ino );
234     else
235         sprintf( p, "%lx", (unsigned long)ino );
236 }
237
238 /* retrieve the default dll dir */
239 const char *get_dlldir( const char **default_dlldir )
240 {
241     *default_dlldir = DLLDIR;
242     return dlldir;
243 }
244
245 /* initialize all the paths values */
246 static void init_paths(void)
247 {
248     struct stat st;
249
250     const char *home = getenv( "HOME" );
251     const char *user = NULL;
252     const char *prefix = getenv( "WINEPREFIX" );
253
254 #ifdef HAVE_GETPWUID
255     char uid_str[32];
256     struct passwd *pwd = getpwuid( getuid() );
257
258     if (pwd)
259     {
260         user = pwd->pw_name;
261         if (!home) home = pwd->pw_dir;
262     }
263     if (!user)
264     {
265         sprintf( uid_str, "%lu", (unsigned long)getuid() );
266         user = uid_str;
267     }
268 #else  /* HAVE_GETPWUID */
269     if (!(user = getenv( "USER" )))
270         fatal_error( "cannot determine your user name, set the USER environment variable\n" );
271 #endif  /* HAVE_GETPWUID */
272     user_name = xstrdup( user );
273
274     /* build config_dir */
275
276     if (prefix)
277     {
278         config_dir = xstrdup( prefix );
279         remove_trailing_slashes( config_dir );
280         if (config_dir[0] != '/')
281             fatal_error( "invalid directory %s in WINEPREFIX: not an absolute path\n", prefix );
282         if (stat( config_dir, &st ) == -1)
283         {
284             if (errno == ENOENT) return;  /* will be created later on */
285             fatal_perror( "cannot open %s as specified in WINEPREFIX", config_dir );
286         }
287     }
288     else
289     {
290         if (!home) fatal_error( "could not determine your home directory\n" );
291         if (home[0] != '/') fatal_error( "your home directory %s is not an absolute path\n", home );
292         config_dir = xmalloc( strlen(home) + sizeof(server_config_dir) );
293         strcpy( config_dir, home );
294         remove_trailing_slashes( config_dir );
295         strcat( config_dir, server_config_dir );
296         if (stat( config_dir, &st ) == -1)
297         {
298             if (errno == ENOENT) return;  /* will be created later on */
299             fatal_perror( "cannot open %s", config_dir );
300         }
301     }
302     if (!S_ISDIR(st.st_mode)) fatal_error( "%s is not a directory\n", config_dir );
303 #ifdef HAVE_GETUID
304     if (st.st_uid != getuid()) fatal_error( "%s is not owned by you\n", config_dir );
305 #endif
306
307     init_server_dir( st.st_dev, st.st_ino );
308 }
309
310 /* check if bindir is valid by checking for wineserver */
311 static int is_valid_bindir( const char *bindir )
312 {
313     struct stat st;
314     char *path = build_path( bindir, "wineserver" );
315     int ret = (stat( path, &st ) != -1);
316     free( path );
317     return ret;
318 }
319
320 /* check if basedir is a valid build dir by checking for wineserver and ntdll */
321 /* helper for running_from_build_dir */
322 static inline int is_valid_build_dir( char *basedir, int baselen )
323 {
324     struct stat st;
325
326     strcpy( basedir + baselen, "/server/wineserver" );
327     if (stat( basedir, &st ) == -1) return 0;  /* no wineserver found */
328     /* check for ntdll too to make sure */
329     strcpy( basedir + baselen, "/dlls/ntdll/ntdll.dll.so" );
330     if (stat( basedir, &st ) == -1) return 0;  /* no ntdll found */
331
332     basedir[baselen] = 0;
333     return 1;
334 }
335
336 /* check if we are running from the build directory */
337 static char *running_from_build_dir( const char *basedir )
338 {
339     const char *p;
340     char *path;
341
342     /* remove last component from basedir */
343     p = basedir + strlen(basedir) - 1;
344     while (p > basedir && *p == '/') p--;
345     while (p > basedir && *p != '/') p--;
346     if (p == basedir) return NULL;
347     path = xmalloc( p - basedir + sizeof("/dlls/ntdll/ntdll.dll.so") );
348     memcpy( path, basedir, p - basedir );
349
350     if (!is_valid_build_dir( path, p - basedir ))
351     {
352         /* remove another component */
353         while (p > basedir && *p == '/') p--;
354         while (p > basedir && *p != '/') p--;
355         if (p == basedir || !is_valid_build_dir( path, p - basedir ))
356         {
357             free( path );
358             return NULL;
359         }
360     }
361     return path;
362 }
363
364 /* initialize the argv0 path */
365 void wine_init_argv0_path( const char *argv0 )
366 {
367     const char *basename;
368     char *libdir;
369
370     if (!(basename = strrchr( argv0, '/' ))) basename = argv0;
371     else basename++;
372
373     bindir = get_runtime_bindir( argv0 );
374     libdir = get_runtime_libdir();
375
376     if (bindir && !is_valid_bindir( bindir ))
377     {
378         build_dir = running_from_build_dir( bindir );
379         free( bindir );
380         bindir = NULL;
381     }
382     if (libdir && !bindir && !build_dir)
383     {
384         build_dir = running_from_build_dir( libdir );
385         if (!build_dir) bindir = build_path( libdir, LIB_TO_BINDIR );
386     }
387
388     if (build_dir)
389     {
390         argv0_name = build_path( "loader/", basename );
391     }
392     else
393     {
394         if (libdir) dlldir = build_path( libdir, LIB_TO_DLLDIR );
395         else if (bindir) dlldir = build_path( bindir, BIN_TO_DLLDIR );
396
397         if (bindir) datadir = build_path( bindir, BIN_TO_DATADIR );
398         argv0_name = xstrdup( basename );
399     }
400     free( libdir );
401 }
402
403 /* return the configuration directory ($WINEPREFIX or $HOME/.wine) */
404 const char *wine_get_config_dir(void)
405 {
406     if (!config_dir) init_paths();
407     return config_dir;
408 }
409
410 /* retrieve the wine data dir */
411 const char *wine_get_data_dir(void)
412 {
413     return datadir;
414 }
415
416 /* retrieve the wine build dir (if we are running from there) */
417 const char *wine_get_build_dir(void)
418 {
419     return build_dir;
420 }
421
422 /* return the full name of the server directory (the one containing the socket) */
423 const char *wine_get_server_dir(void)
424 {
425     if (!server_dir)
426     {
427         if (!config_dir) init_paths();
428         else
429         {
430             struct stat st;
431
432             if (stat( config_dir, &st ) == -1)
433             {
434                 if (errno != ENOENT) fatal_error( "cannot stat %s\n", config_dir );
435                 return NULL;  /* will have to try again once config_dir has been created */
436             }
437             init_server_dir( st.st_dev, st.st_ino );
438         }
439     }
440     return server_dir;
441 }
442
443 /* return the current user name */
444 const char *wine_get_user_name(void)
445 {
446     if (!user_name) init_paths();
447     return user_name;
448 }
449
450 /* return the standard version string */
451 const char *wine_get_version(void)
452 {
453     return PACKAGE_VERSION;
454 }
455
456 /* return the build id string */
457 const char *wine_get_build_id(void)
458 {
459     extern const char wine_build[];
460     return wine_build;
461 }
462
463 /* exec a binary using the preloader if requested; helper for wine_exec_wine_binary */
464 static void preloader_exec( char **argv, int use_preloader )
465 {
466     if (use_preloader)
467     {
468         static const char preloader[] = "wine-preloader";
469         static const char preloader64[] = "wine64-preloader";
470         char *p, *full_name;
471         char **last_arg = argv, **new_argv;
472
473         if (!(p = strrchr( argv[0], '/' ))) p = argv[0];
474         else p++;
475
476         full_name = xmalloc( p - argv[0] + sizeof(preloader64) );
477         memcpy( full_name, argv[0], p - argv[0] );
478         if (strendswith( p, "64" ))
479             memcpy( full_name + (p - argv[0]), preloader64, sizeof(preloader64) );
480         else
481             memcpy( full_name + (p - argv[0]), preloader, sizeof(preloader) );
482
483         /* make a copy of argv */
484         while (*last_arg) last_arg++;
485         new_argv = xmalloc( (last_arg - argv + 2) * sizeof(*argv) );
486         memcpy( new_argv + 1, argv, (last_arg - argv + 1) * sizeof(*argv) );
487         new_argv[0] = full_name;
488         execv( full_name, new_argv );
489         free( new_argv );
490         free( full_name );
491     }
492     execv( argv[0], argv );
493 }
494
495 /* exec a wine internal binary (either the wine loader or the wine server) */
496 void wine_exec_wine_binary( const char *name, char **argv, const char *env_var )
497 {
498     const char *path, *pos, *ptr;
499     int use_preloader;
500
501     if (!name) name = argv0_name;  /* no name means default loader */
502
503 #ifdef linux
504     use_preloader = !strendswith( name, "wineserver" );
505 #else
506     use_preloader = 0;
507 #endif
508
509     if ((ptr = strrchr( name, '/' )))
510     {
511         /* if we are in build dir and name contains a path, try that */
512         if (build_dir)
513         {
514             argv[0] = build_path( build_dir, name );
515             preloader_exec( argv, use_preloader );
516             free( argv[0] );
517         }
518         name = ptr + 1;  /* get rid of path */
519     }
520
521     /* first, bin directory from the current libdir or argv0 */
522     if (bindir)
523     {
524         argv[0] = build_path( bindir, name );
525         preloader_exec( argv, use_preloader );
526         free( argv[0] );
527     }
528
529     /* then specified environment variable */
530     if (env_var)
531     {
532         argv[0] = (char *)env_var;
533         preloader_exec( argv, use_preloader );
534     }
535
536     /* now search in the Unix path */
537     if ((path = getenv( "PATH" )))
538     {
539         argv[0] = xmalloc( strlen(path) + strlen(name) + 2 );
540         pos = path;
541         for (;;)
542         {
543             while (*pos == ':') pos++;
544             if (!*pos) break;
545             if (!(ptr = strchr( pos, ':' ))) ptr = pos + strlen(pos);
546             memcpy( argv[0], pos, ptr - pos );
547             strcpy( argv[0] + (ptr - pos), "/" );
548             strcat( argv[0] + (ptr - pos), name );
549             preloader_exec( argv, use_preloader );
550             pos = ptr;
551         }
552         free( argv[0] );
553     }
554
555     /* and finally try BINDIR */
556     argv[0] = build_path( BINDIR, name );
557     preloader_exec( argv, use_preloader );
558     free( argv[0] );
559 }