config.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  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 "wine/asm.h"
  23. #ifdef __ASM_OBSOLETE
  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. #ifdef __APPLE__
  37. #include <crt_externs.h>
  38. #include <spawn.h>
  39. #ifndef _POSIX_SPAWN_DISABLE_ASLR
  40. #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
  41. #endif
  42. #endif
  43. static char *bindir;
  44. static char *dlldir;
  45. static char *datadir;
  46. const char *build_dir;
  47. static char *argv0_name;
  48. static char *wineserver64;
  49. #ifdef __GNUC__
  50. static void fatal_error( const char *err, ... ) __attribute__((noreturn,format(printf,1,2)));
  51. #endif
  52. #if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
  53. static const char exe_link[] = "/proc/self/exe";
  54. #elif defined (__FreeBSD__) || defined(__DragonFly__)
  55. static const char exe_link[] = "/proc/curproc/file";
  56. #else
  57. static const char exe_link[] = "";
  58. #endif
  59. /* die on a fatal error */
  60. static void fatal_error( const char *err, ... )
  61. {
  62. va_list args;
  63. va_start( args, err );
  64. fprintf( stderr, "wine: " );
  65. vfprintf( stderr, err, args );
  66. va_end( args );
  67. exit(1);
  68. }
  69. /* malloc wrapper */
  70. static void *xmalloc( size_t size )
  71. {
  72. void *res;
  73. if (!size) size = 1;
  74. if (!(res = malloc( size ))) fatal_error( "virtual memory exhausted\n");
  75. return res;
  76. }
  77. /* strdup wrapper */
  78. static char *xstrdup( const char *str )
  79. {
  80. size_t len = strlen(str) + 1;
  81. char *res = xmalloc( len );
  82. memcpy( res, str, len );
  83. return res;
  84. }
  85. /* build a path from the specified dir and name */
  86. static char *build_path( const char *dir, const char *name )
  87. {
  88. size_t len = strlen(dir);
  89. char *ret = xmalloc( len + strlen(name) + 2 );
  90. memcpy( ret, dir, len );
  91. if (len && ret[len-1] != '/') ret[len++] = '/';
  92. strcpy( ret + len, name );
  93. return ret;
  94. }
  95. /* return the directory that contains the library at run-time */
  96. static char *get_runtime_libdir(void)
  97. {
  98. #ifdef HAVE_DLADDR
  99. Dl_info info;
  100. char *libdir;
  101. if (dladdr( get_runtime_libdir, &info ) && info.dli_fname[0] == '/')
  102. {
  103. const char *p = strrchr( info.dli_fname, '/' );
  104. unsigned int len = p - info.dli_fname;
  105. if (!len) len++; /* include initial slash */
  106. libdir = xmalloc( len + 1 );
  107. memcpy( libdir, info.dli_fname, len );
  108. libdir[len] = 0;
  109. return libdir;
  110. }
  111. #endif /* HAVE_DLADDR */
  112. return NULL;
  113. }
  114. /* read a symlink and return its directory */
  115. static char *symlink_dirname( const char *name )
  116. {
  117. char *p, *fullpath = realpath( name, NULL );
  118. if (fullpath)
  119. {
  120. p = strrchr( fullpath, '/' );
  121. if (p == fullpath) p++;
  122. if (p) *p = 0;
  123. }
  124. return fullpath;
  125. }
  126. /* return the directory that contains the main exe at run-time */
  127. static char *get_runtime_exedir(void)
  128. {
  129. if (exe_link[0]) return symlink_dirname( exe_link );
  130. return NULL;
  131. }
  132. /* return the base directory from argv0 */
  133. static char *get_runtime_argvdir( const char *argv0 )
  134. {
  135. char *p, *bindir, *cwd;
  136. int len, size;
  137. if (!(p = strrchr( argv0, '/' ))) return NULL;
  138. len = p - argv0;
  139. if (!len) len++; /* include leading slash */
  140. if (argv0[0] == '/') /* absolute path */
  141. {
  142. bindir = xmalloc( len + 1 );
  143. memcpy( bindir, argv0, len );
  144. bindir[len] = 0;
  145. }
  146. else
  147. {
  148. /* relative path, make it absolute */
  149. for (size = 256 + len; ; size *= 2)
  150. {
  151. if (!(cwd = malloc( size ))) return NULL;
  152. if (getcwd( cwd, size - len ))
  153. {
  154. bindir = cwd;
  155. cwd += strlen(cwd);
  156. *cwd++ = '/';
  157. memcpy( cwd, argv0, len );
  158. cwd[len] = 0;
  159. break;
  160. }
  161. free( cwd );
  162. if (errno != ERANGE) return NULL;
  163. }
  164. }
  165. return bindir;
  166. }
  167. /* retrieve the default dll dir */
  168. const char *get_dlldir( const char **default_dlldir )
  169. {
  170. *default_dlldir = DLLDIR;
  171. return dlldir;
  172. }
  173. /* check if bindir is valid by checking for wineserver */
  174. static int is_valid_bindir( const char *bindir )
  175. {
  176. struct stat st;
  177. char *path = build_path( bindir, "wineserver" );
  178. int ret = (stat( path, &st ) != -1);
  179. free( path );
  180. return ret;
  181. }
  182. /* check if dlldir is valid by checking for ntdll */
  183. static int is_valid_dlldir( const char *dlldir )
  184. {
  185. struct stat st;
  186. char *path = build_path( dlldir, "ntdll.dll.so" );
  187. int ret = (stat( path, &st ) != -1);
  188. free( path );
  189. return ret;
  190. }
  191. /* check if basedir is a valid build dir by checking for wineserver and ntdll */
  192. /* helper for running_from_build_dir */
  193. static inline int is_valid_build_dir( char *basedir, int baselen )
  194. {
  195. struct stat st;
  196. strcpy( basedir + baselen, "/server/wineserver" );
  197. if (stat( basedir, &st ) == -1) return 0; /* no wineserver found */
  198. /* check for ntdll too to make sure */
  199. strcpy( basedir + baselen, "/dlls/ntdll/ntdll.dll.so" );
  200. if (stat( basedir, &st ) == -1) return 0; /* no ntdll found */
  201. basedir[baselen] = 0;
  202. return 1;
  203. }
  204. /* check if we are running from the build directory */
  205. static char *running_from_build_dir( const char *basedir )
  206. {
  207. const char *p;
  208. char *path;
  209. /* remove last component from basedir */
  210. p = basedir + strlen(basedir) - 1;
  211. while (p > basedir && *p == '/') p--;
  212. while (p > basedir && *p != '/') p--;
  213. if (p == basedir) return NULL;
  214. path = xmalloc( p - basedir + sizeof("/dlls/ntdll/ntdll.dll.so") );
  215. memcpy( path, basedir, p - basedir );
  216. if (!is_valid_build_dir( path, p - basedir ))
  217. {
  218. /* remove another component */
  219. while (p > basedir && *p == '/') p--;
  220. while (p > basedir && *p != '/') p--;
  221. if (p == basedir || !is_valid_build_dir( path, p - basedir ))
  222. {
  223. free( path );
  224. return NULL;
  225. }
  226. }
  227. return path;
  228. }
  229. /* try to set the specified directory as bindir, or set build_dir if it's inside the build directory */
  230. static int set_bindir( char *dir )
  231. {
  232. if (!dir) return 0;
  233. if (is_valid_bindir( dir ))
  234. {
  235. bindir = dir;
  236. dlldir = build_path( bindir, BIN_TO_DLLDIR );
  237. }
  238. else
  239. {
  240. build_dir = running_from_build_dir( dir );
  241. free( dir );
  242. }
  243. return bindir || build_dir;
  244. }
  245. /* try to set the specified directory as dlldir, or set build_dir if it's inside the build directory */
  246. static int set_dlldir( char *libdir )
  247. {
  248. char *path;
  249. if (!libdir) return 0;
  250. path = build_path( libdir, LIB_TO_DLLDIR );
  251. if (is_valid_dlldir( path ))
  252. {
  253. dlldir = path;
  254. bindir = build_path( libdir, LIB_TO_BINDIR );
  255. }
  256. else
  257. {
  258. build_dir = running_from_build_dir( libdir );
  259. free( path );
  260. }
  261. free( libdir );
  262. return dlldir || build_dir;
  263. }
  264. /* initialize the argv0 path */
  265. void wine_init_argv0_path_obsolete( const char *argv0 )
  266. {
  267. const char *basename, *wineloader;
  268. if (!(basename = strrchr( argv0, '/' ))) basename = argv0;
  269. else basename++;
  270. if (set_bindir( get_runtime_exedir() )) goto done;
  271. if (set_dlldir( get_runtime_libdir() )) goto done;
  272. if (set_bindir( get_runtime_argvdir( argv0 ))) goto done;
  273. if ((wineloader = getenv( "WINELOADER" ))) set_bindir( get_runtime_argvdir( wineloader ));
  274. done:
  275. if (build_dir)
  276. {
  277. argv0_name = build_path( "loader/", basename );
  278. if (sizeof(int) == sizeof(void *))
  279. {
  280. char *loader, *linkname = build_path( build_dir, "loader/wine64" );
  281. if ((loader = symlink_dirname( linkname )))
  282. {
  283. wineserver64 = build_path( loader, "../server/wineserver" );
  284. free( loader );
  285. }
  286. free( linkname );
  287. }
  288. }
  289. else
  290. {
  291. if (bindir) datadir = build_path( bindir, BIN_TO_DATADIR );
  292. argv0_name = xstrdup( basename );
  293. }
  294. }
  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_init_argv0_path);
  550. __ASM_OBSOLETE(wine_get_build_dir);
  551. __ASM_OBSOLETE(wine_get_build_id);
  552. __ASM_OBSOLETE(wine_get_config_dir);
  553. __ASM_OBSOLETE(wine_get_data_dir);
  554. __ASM_OBSOLETE(wine_get_server_dir);
  555. __ASM_OBSOLETE(wine_get_user_name);
  556. __ASM_OBSOLETE(wine_get_version);
  557. __ASM_OBSOLETE(wine_exec_wine_binary);
  558. #endif /* __ASM_OBSOLETE */