From a50db8c694ba76609fef8a9693887639cf81fd45 Mon Sep 17 00:00:00 2001 From: Jan200101 Date: Sat, 23 Jul 2022 17:04:07 +0200 Subject: add shim functionality --- src/config.c | 9 ++++++- src/config.h | 1 + src/wine.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/wine.h | 1 + 4 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/config.c b/src/config.c index f05f5c1..ef4fd82 100644 --- a/src/config.c +++ b/src/config.c @@ -9,7 +9,9 @@ static void getXDGDir(const char* envvar, const char* homeext, char* config, const size_t size) { - char* xdg_var = getenv(envvar); + char* xdg_var = NULL; + if (envvar) + xdg_var = getenv(envvar); if (xdg_var) { @@ -46,6 +48,11 @@ void getCacheDir(char* config, const size_t size) getXDGDir("XDG_CACHE_HOME", "/.cache/" NAME, config, size); } +void getUserBinDir(char* config, const size_t size) +{ + getXDGDir(NULL, "/.local/bin", config, size); +} + void getWineDir(char* config, const size_t size) { getDataDir(config, size); diff --git a/src/config.h b/src/config.h index 39fb4d8..3c55d77 100644 --- a/src/config.h +++ b/src/config.h @@ -6,6 +6,7 @@ void getConfigDir(char*, const size_t); void getDataDir(char*, const size_t); void getCacheDir(char*, const size_t); +void getUserBinDir(char*, const size_t); void getWineDir(char*, const size_t); void getDXVKDir(char*, const size_t); diff --git a/src/wine.c b/src/wine.c index 9a249b1..fa65ebc 100644 --- a/src/wine.c +++ b/src/wine.c @@ -19,10 +19,11 @@ static const struct Command winecmd_commands[] = { { .name = "download", .func = winecmd_download, .description = "download and extract a wine version" }, { .name = "env", .func = winecmd_env, .description = "add wine to your PATH in a POSIX shell"}, { .name = "env-fish", .func = winecmd_env, .description = "add wine to your PATH in the fish shell"}, - { .name = "list", .func = winecmd_list, .description = "list available wine versions" }, { .name = "installed", .func = winecmd_installed, .description = "list installed wine versions" }, + { .name = "list", .func = winecmd_list, .description = "list available wine versions" }, { .name = "remove", .func = winecmd_remove, .description = "remove a wine version" }, { .name = "run", .func = winecmd_run, .description = "run an installed wine version" }, + { .name = "shim", .func = winecmd_shim, .description = "add a wine shim to your users bin folder" }, }; static const struct Flag winecmd_flags[] = { @@ -248,8 +249,11 @@ COMMAND(winecmd, run) } } + else + { + fprintf(stderr, USAGE_STR " wine run [version] \nUse '" NAME " wine list-installed' to list available versions\n"); + } - fprintf(stderr, "Specify a what wine version to run.\nUse '" NAME " wine list-installed' to list available versions\n"); return EXIT_SUCCESS; } @@ -376,7 +380,80 @@ COMMAND(winecmd, env) } else { - fprintf(stderr, "Specify a what wine version to run.\nUse '" NAME " wine list-installed' to list available versions\n"); + fprintf(stderr, USAGE_STR " wine env [version] \nUse '" NAME " wine list-installed' to list available versions\n"); + } + + return EXIT_SUCCESS; +} + +COMMAND(winecmd, shim) +{ + if (argc > 1) + { + char winepath[PATH_MAX]; + char* winebinloc = NULL; // to be set by the wine type check + getWineDir(winepath, sizeof(winepath)); + char* winever = argv[1]; + + strncat(winepath, "/", sizeof(winepath) - strlen(winepath) - 1); + strncat(winepath, winever, sizeof(winepath) - strlen(winepath) - 1); + + if (!isDir(winepath)) + { + + // try appending the system arch to find the wine version + struct utsname buffer; + + if (!uname(&buffer)) + { + strncat(winepath, "-", sizeof(winepath) - strlen(winepath) - 1); + strncat(winepath, buffer.machine, sizeof(winepath) - strlen(winepath) - 1); + } + + // if we still cannot find anything tell the user and exit + if (!isDir(winepath)) + { + fprintf(stderr, "'%s' is not an installed wine version\n", winever); + return 1; + } + } + + switch(check_wine_ver(winepath, sizeof(winepath)+1)) + { + default: + case WINE_NORMAL: + winebinloc = WINEBIN; + break; + + case WINE_PROTON: + winebinloc = PROTONBIN; + break; + } + + strncat(winepath, winebinloc, sizeof(winepath) - strlen(winepath) - 1); + + if (isFile(winepath)) + { + char buffer[BUFSIZ]; + char binpath[PATH_MAX]; + + readlink("/proc/self/exe", buffer, BUFSIZ); + getUserBinDir(binpath, sizeof(binpath)); + strcat(binpath, "/wine-"); + strcat(binpath, winever); + + symlink(buffer, binpath); + printf("Installed '%s' as '%s'ยด\n", winever, binpath); + } + else + { + fprintf(stderr, "cannot find wine for '%s'\n", winever); + } + + } + else + { + fprintf(stderr, USAGE_STR " wine shim [version]\n"); } return EXIT_SUCCESS; diff --git a/src/wine.h b/src/wine.h index 9b382df..24b8748 100644 --- a/src/wine.h +++ b/src/wine.h @@ -21,6 +21,7 @@ COMMAND(winecmd, list); COMMAND(winecmd, run); COMMAND(winecmd, installed); COMMAND(winecmd, env); +COMMAND(winecmd, shim); COMMAND(winecmd, help); enum wine_type_t check_wine_ver(char*, size_t); -- cgit v1.2.3