diff options
-rw-r--r-- | src/common.c | 56 | ||||
-rw-r--r-- | src/common.h | 3 | ||||
-rw-r--r-- | src/dxvk.c | 32 | ||||
-rw-r--r-- | src/dxvk.h | 1 | ||||
-rw-r--r-- | src/wine.c | 46 | ||||
-rw-r--r-- | src/wine.h | 1 |
6 files changed, 136 insertions, 3 deletions
diff --git a/src/common.c b/src/common.c index c5d9435..9b0ab51 100644 --- a/src/common.c +++ b/src/common.c @@ -3,6 +3,9 @@ #include <string.h> #include <stdbool.h> #include <sys/stat.h> +#include <unistd.h> +#include <sys/types.h> +#include <dirent.h> #include "common.h" @@ -49,14 +52,63 @@ bool isDir(const char* path) return S_ISDIR(sb.st_mode) || S_ISLNK(sb.st_mode); } -void makeDir(const char* path) +int makeDir(const char* path) { // we do not care about the contents but what stat returns struct stat sb; if (stat(path, &sb) < 0) { - mkdir(path, 0755); + return mkdir(path, 0755); } + + return 0; // directory exists, pretend we made it } +int removeDir(const char *path) { + DIR *d = opendir(path); + size_t path_len = strlen(path); + int r = -1; + + if (d) { + struct dirent *p; + + r = 0; + while (!r && (p=readdir(d))) { + char *buf; + size_t len; + + // Skip the names "." and ".." as we don't want to recurse on them. + if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) + continue; + + len = path_len + strlen(p->d_name) + 2; + buf = malloc(len); + + if (buf) { + struct stat statbuf = {0}; + + snprintf(buf, len, "%s/%s", path, p->d_name); + if (!stat(buf, &statbuf)) { + if (S_ISDIR(statbuf.st_mode)) + r = removeDir(buf); + else if (S_ISLNK(statbuf.st_mode)) + r = unlink(buf); + else + r = remove(buf); + } + else // it is very likely that we found a dangling symlink which is not detected by stat + { + r = unlink(buf); + } + free(buf); + } + } + closedir(d); + } + + if (!r) + r = rmdir(path); + + return r; +}
\ No newline at end of file diff --git a/src/common.h b/src/common.h index fdd5ac2..f376195 100644 --- a/src/common.h +++ b/src/common.h @@ -50,6 +50,7 @@ struct stat getStat(const char* path); bool isFile(const char*); bool isDir(const char*); -void makeDir(const char* path); +int makeDir(const char* path); +int removeDir(const char *path); #endif @@ -84,6 +84,38 @@ COMMAND(dxvk, download) COMMAND(dxvk, remove) { + if (argc == 2) + { + char* dxvkver = argv[1]; + + char dxvkpath[PATH_MAX]; + getDXVKDir(dxvkpath, sizeof(dxvkpath)); + + strncat(dxvkpath, "/", sizeof(dxvkpath) - strlen(dxvkpath) - 1); + strncat(dxvkpath, dxvkver, sizeof(dxvkpath) - strlen(dxvkpath) - 1); + + + if (!isDir(dxvkpath)) + { + fprintf(stderr, "`%s' is not an downloaded DXVK version\n", dxvkver); + return 0; + } + + int retval = removeDir(dxvkpath); + if (!retval) + { + fprintf(stderr, "Done\n"); + } + else + { + fprintf(stderr, "Something might have gone wrong. Manual cleanup might be required\n"); + } + + return retval; + } + + fprintf(stderr, USAGE_STR " dxvk remove <version>\n\nInstalled dxvk versions can be obtained by using `" NAME " dxvk list-installed\n"); + return 0; } @@ -7,6 +7,7 @@ COMMAND_GROUP(dxvk); COMMAND(dxvk, download); +COMMAND(dxvk, remove); COMMAND(dxvk, list); COMMAND(dxvk, install); COMMAND(dxvk, installed); @@ -87,8 +87,54 @@ COMMAND(wine, download) return 0; } + COMMAND(wine, remove) { + if (argc == 2) + { + char* winever = argv[1]; + + char winepath[PATH_MAX]; + getWineDir(winepath, sizeof(winepath)); + + strncat(winepath, "/", sizeof(winepath) - strlen(winepath) - 1); + strncat(winepath, winever, sizeof(winepath) - strlen(winepath) - 1); + + if (!isDir(winepath)) + { + + // if the wine version does not exist try appending the system arch e.g. x86_64 + struct utsname buffer; + + if (!uname(&buffer)) + { + strncat(winepath, "-", sizeof(winepath) - strlen(winepath) - 1); + strncat(winepath, buffer.machine, sizeof(winepath) - strlen(winepath) - 1); + } + + // if it still doesn't exist tell this wine version is not installed + if (!isDir(winepath)) + { + fprintf(stderr, "`%s' is not an installed wine version\n", winever); + return 0; + } + } + + int retval = removeDir(winepath); + if (!retval) + { + fprintf(stderr, "Done\n"); + } + else + { + fprintf(stderr, "Something might have gone wrong. Manual cleanup might be required\n"); + } + + return retval; + } + + fprintf(stderr, USAGE_STR " wine remove <version>\n\nInstalled wine versions can be obtained by using `" NAME " wine list-installed\n"); + return 0; } @@ -16,6 +16,7 @@ enum wine_type_t { COMMAND_GROUP(wine); COMMAND(wine, download); +COMMAND(wine, remove); COMMAND(wine, list); COMMAND(wine, run); COMMAND(wine, installed); |