Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- compile:
- WINE_SUFFIX=-development
- WINE_PROXY=wine
- gcc -std=c99 wine-proxy.c -ldpkg -o ${WINE_PROXY} -s -DSUFFIX=${WINE_SUFFIX}
- sudo install ${WINE_PROXY} /usr/bin
- */
- #define _GNU_SOURCE
- #include <errno.h>
- #include <fcntl.h>
- #include <stdarg.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- // libdpkg-dev
- #define LIBDPKG_VOLATILE_API
- #include <dpkg/arch.h>
- // --------------------------
- // configuration
- // --------------------------
- #ifdef SUFFIX
- /*
- two-pass stringification according to
- http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
- */
- #define S0(a) #a
- #define S1(a) S0(a)
- #define WINE_SUFFIX S1(SUFFIX)
- #else
- #define WINE_SUFFIX ""
- #endif
- #define WINE_BINDIR "/usr/lib/wine"WINE_SUFFIX
- #define WINE32 WINE_BINDIR"/wine"
- #define WINE64 WINE_BINDIR"/wine64"
- // --------------------------
- #define TRUE 1
- #define FALSE 0
- #define TEST(what, with) (((what)&(with))==(with))
- #define _err(format, args...) fprintf(stderr, format, ##args);
- #define _log(facility, format, args...) _err("wine-proxy: %s: " format "\n", facility, ##args);
- #define _log_D(format, args...) _log("debug", format, ##args);
- #define _log_I(format, args...) _log("info", format, ##args);
- #define _log_W(format, args...) _log("warn", format, ##args);
- #define _log_E(format, args...) _log("error", format, ##args);
- void env_default(char * name, char * value) {
- char * curr = getenv(name);
- while (TRUE) {
- if (curr != NULL) {
- if (strlen(curr) > 0) { break; }
- _log_D("env['%s'] is set but empty, overwriting", name, curr);
- }
- curr = value;
- setenv(name, value, TRUE);
- break;
- }
- _log_D("env['%s'] = '%s'", name, curr);
- }
- int is_binary(char * path, int * out_handle) {
- int file, err;
- struct stat file_stat;
- file = open(path, O_NOATIME | O_NOCTTY | O_PATH | O_CLOEXEC, O_ACCMODE);
- err = errno;
- if (file == -1) {
- _log_W("is_binary# open() = %d: %s", err, strerror(err));
- return FALSE;
- }
- while (TRUE) {
- if (0 != fstat(file, &file_stat)) {
- err = errno;
- _log_W("is_binary# fstat() = %d: %s", err, strerror(err));
- break;
- }
- if (!S_ISREG(file_stat.st_mode)) { break; }
- if (!TEST(file_stat.st_mode, S_IROTH | S_IXOTH)) { break; }
- *out_handle = file;
- return TRUE;
- }
- close(file);
- return FALSE;
- }
- // never returns if succeed
- int try_exec(int binary_handle, char ** argv, char ** env) {
- int result, err;
- result = fexecve(binary_handle, argv, env);
- err = errno;
- close(binary_handle);
- _log_E("try_exec# fexecve() = %d: %s", result, strerror(err));
- return result;
- }
- char * dpkg_arch_to_string(enum dpkg_arch_type type) {
- switch(type) {
- case DPKG_ARCH_NONE: return "none";
- case DPKG_ARCH_EMPTY: return "empty";
- case DPKG_ARCH_ILLEGAL: return "illegal";
- case DPKG_ARCH_WILDCARD: return "wildcard";
- case DPKG_ARCH_ALL: return "all";
- case DPKG_ARCH_NATIVE: return "native";
- case DPKG_ARCH_FOREIGN: return "foreign";
- case DPKG_ARCH_UNKNOWN: return "unknown";
- default: return "BAD VALUE";
- }
- }
- void dpkg_list_archs(void) {
- for (struct dpkg_arch * i = dpkg_arch_get_list(); i != NULL; i = i->next) {
- _log_D("dpkg_arch['%s'] = %s", i->name, dpkg_arch_to_string(i->type));
- }
- }
- // --------------------------
- char * wine32 = WINE32;
- char * wine64 = WINE64;
- extern char ** environ;
- // --------------------------
- int main(int argc, char ** argv) {
- char * wine_path = NULL;
- int wine_handle = NULL;
- _log_I("written by rockdrilla, 2014.");
- dpkg_list_archs();
- if (is_binary(wine32, &wine_handle)) {
- _log_D("found 32-bit wine binary");
- wine_path = wine32;
- } else if (is_binary(wine64, &wine_handle)) {
- _log_D("found 64-bit wine binary");
- wine_path = wine64;
- struct dpkg_arch * a_amd64 = dpkg_arch_find("amd64");
- struct dpkg_arch * a_i386 = dpkg_arch_find("i386");
- if (
- (a_amd64->type == DPKG_ARCH_NATIVE)
- &&
- (a_i386->type != DPKG_ARCH_FOREIGN)
- ) {
- _log_W("it looks like multiarch needs to be enabled!");
- _log_W("as root, please execute following:");
- _log_W(" dpkg --add-architecture i386 && apt-get install wine32"WINE_SUFFIX);
- }
- } else {
- _log_E("unable to find wine executable. this shouldn't happen.");
- return 1;
- }
- env_default("WINELOADER", wine_path);
- env_default("WINEDEBUG", "-all");
- argv[0] = wine_path;
- return try_exec(wine_handle, argv, environ);
- }
- /*
- sample output:
- krd@office:~$ ./wine --version
- wine-proxy: info: written by rockdrilla, 2014.
- wine-proxy: debug: dpkg_arch['i386'] = native
- wine-proxy: debug: dpkg_arch['all'] = all
- wine-proxy: debug: dpkg_arch['any'] = wildcard
- wine-proxy: debug: found 32-bit wine binary
- wine-proxy: debug: env['WINELOADER'] = '/usr/lib/wine-development/wine'
- wine-proxy: debug: env['WINEDEBUG'] = '-all'
- wine-1.7.24
- krd@office:~$ WINEDEBUG=+all ./wine --version
- wine-proxy: info: written by rockdrilla, 2014.
- wine-proxy: debug: dpkg_arch['i386'] = native
- wine-proxy: debug: dpkg_arch['all'] = all
- wine-proxy: debug: dpkg_arch['any'] = wildcard
- wine-proxy: debug: found 32-bit wine binary
- wine-proxy: debug: env['WINELOADER'] = '/usr/lib/wine-development/wine'
- wine-proxy: debug: env['WINEDEBUG'] = '+all'
- wine-1.7.24
- krd@office:~$ WINEDEBUG= ./wine --version
- wine-proxy: info: written by rockdrilla, 2014.
- wine-proxy: debug: dpkg_arch['i386'] = native
- wine-proxy: debug: dpkg_arch['all'] = all
- wine-proxy: debug: dpkg_arch['any'] = wildcard
- wine-proxy: debug: found 32-bit wine binary
- wine-proxy: debug: env['WINELOADER'] = '/usr/lib/wine-development/wine'
- wine-proxy: debug: env['WINEDEBUG'] is set but empty, overwriting
- wine-proxy: debug: env['WINEDEBUG'] = '-all'
- wine-1.7.24
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement