config.c 18 KB

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