config.c 18 KB

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