Advertisement
rockdrilla

wine-proxy.c: helper for Debian's wine-unstable

Aug 15th, 2014
574
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.05 KB | None | 0 0
  1. /*
  2. compile:
  3.   WINE_SUFFIX=-unstable
  4.   WINE_PROXY=wine${WINE_SUFFIX}
  5.   gcc -std=c11 -O3 -g0 wine-proxy.c -ldpkg -o ${WINE_PROXY} -DSUFFIX=${WINE_SUFFIX}
  6.   sudo install ${WINE_PROXY} /usr/bin
  7. */
  8.  
  9. #define _GNU_SOURCE
  10.  
  11. #include <fcntl.h>
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <unistd.h>
  16.  
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19.  
  20. #define LIBDPKG_VOLATILE_API
  21.  
  22. #include <dpkg/arch.h> // libdpkg-dev
  23.  
  24. // --------------------------
  25. // configuration
  26. // --------------------------
  27.  
  28. #ifndef SUFFIX
  29. // #define WINE_SUFFIX "-unstable"
  30. #define WINE_SUFFIX ""
  31. #else
  32. /*
  33.  two-pass stringification according to
  34.  http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
  35. */
  36. #define S0(a) #a
  37. #define S1(a) S0(a)
  38. #define WINE_SUFFIX S1(SUFFIX)
  39. #endif
  40.  
  41. #ifndef WINE_FULLNAME
  42. #define WINE_FULLNAME "wine"WINE_SUFFIX
  43. #endif
  44.  
  45. #ifndef WINE_BINDIR
  46. #define WINE_BINDIR "/usr/lib/"WINE_FULLNAME
  47. #endif
  48.  
  49. #ifndef WINE32
  50. #define WINE32 WINE_BINDIR"/wine"
  51. #endif
  52.  
  53. #ifndef WINE64
  54. #define WINE64 WINE_BINDIR"/wine64"
  55. #endif
  56.  
  57. // --------------------------
  58.  
  59. #define TRUE 1
  60. #define FALSE 0
  61. #define TEST(a,b) (((a)&(b))==(b))
  62.  
  63. void echo(const char * string) {
  64.     printf("%s\n", string);
  65. }
  66.  
  67. void env_default(const char * name, const char * value) {
  68.     char * curr = getenv(name);
  69.  
  70.     if ((curr != NULL) && (strlen(curr) > 0)) {
  71.         return;
  72.     }
  73.  
  74.     setenv(name, value, TRUE);
  75. }
  76.  
  77. int is_binary(char * path) {
  78.     int file;
  79.     struct stat file_stat;
  80.  
  81.     file = open(path, O_NOATIME | O_NOCTTY | O_PATH, O_ACCMODE);
  82.     if (file == -1) { return FALSE; }
  83.  
  84.     while (TRUE) {
  85.         if (0 != fstat(file, &file_stat)) { break; }
  86.         if (!S_ISREG(file_stat.st_mode)) { break; }
  87.         if (!TEST(file_stat.st_mode, S_IROTH | S_IXOTH)) { break; }
  88.  
  89.         close(file);
  90.  
  91.         return TRUE;
  92.     }
  93.  
  94.     return FALSE;
  95. }
  96.  
  97. // never returns if succeed
  98. int try_exec(char * binary_path, char ** argv, char ** env) {
  99.     int file = open(binary_path, O_NOATIME | O_NOCTTY | O_CLOEXEC, O_RDONLY);
  100.     if (file == -1) { return 1; }
  101.  
  102.     int result = fexecve(file, argv, env);
  103.  
  104.     close(file);
  105.  
  106.     return result;
  107. }
  108.  
  109. // --------------------------
  110.  
  111. char * wine32 = WINE32;
  112. char * wine64 = WINE64;
  113.  
  114. extern char ** environ;
  115.  
  116. // --------------------------
  117.  
  118. int main(int argc, char ** argv) {
  119.     char * wine = NULL;
  120.  
  121.     if (is_binary(wine32)) {
  122.         wine = wine32;
  123.     } else if (is_binary(wine64)) {
  124.         wine = wine64;
  125.  
  126.         struct dpkg_arch * a_amd64 = dpkg_arch_find("amd64");
  127.         struct dpkg_arch * a_i386 = dpkg_arch_find("i386");
  128.  
  129.         if (
  130.             (a_amd64->type == DPKG_ARCH_NATIVE)
  131.             &&
  132.             (a_i386->type != DPKG_ARCH_FOREIGN)
  133.         ) {
  134.             echo("It looks like multiarch needs to be enabled!");
  135.             echo("As root, please execute following:");
  136.             echo("    dpkg --add-architecture i386 && apt-get install wine32"WINE_SUFFIX);
  137.         }
  138.     } else {
  139.         echo("error: unable to find wine executable. this shouldn't happen.");
  140.         return 1;
  141.     }
  142.  
  143.     env_default("WINELOADER", wine);
  144.     env_default("WINEDEBUG", "-all");
  145.  
  146.     argv[0] = wine;
  147.  
  148.     // return try_exec(wine, argv, environ);
  149.     return execve(wine, argv, environ);
  150. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement