aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan200101 <sentrycraft123@gmail.com>2020-08-10 12:43:26 +0200
committerJan200101 <sentrycraft123@gmail.com>2020-08-10 12:43:26 +0200
commit1753e2b151cbb4af75a4e9ea61720b3704b03805 (patch)
tree6265e9829a6d6b76ddae13de2138ef8f1c657ccd
parentc11dd0eae09df4982459a34d764910d0501f2ae2 (diff)
downloadpolecat-1753e2b151cbb4af75a4e9ea61720b3704b03805.tar.gz
polecat-1753e2b151cbb4af75a4e9ea61720b3704b03805.zip
a lot of changes […]0.1.3
- go to next entry of argv and decrement argc the deeper it goes - add basic lutris functionality - remove "help" from help message and as a command - replace all stderr prints with stdout prints (usually stderr is better for directly informing the user but in this case I don't think it will help much) - add libarchive dependency to the README - bump version number
-rw-r--r--Makefile2
-rw-r--r--README.md1
-rw-r--r--src/common.c2
-rw-r--r--src/common.h1
-rw-r--r--src/dxvk.c9
-rw-r--r--src/lutris.c218
-rw-r--r--src/lutris.h61
-rw-r--r--src/main.c11
-rw-r--r--src/main.h4
-rw-r--r--src/net.c5
-rw-r--r--src/tar.c12
-rw-r--r--src/wine.c38
12 files changed, 322 insertions, 42 deletions
diff --git a/Makefile b/Makefile
index 5aedaf9..7bef6be 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
# GENERAL VARIABLES
NAME := polecat
-VERSION := 0.1.2
+VERSION := 0.1.3
TARGET ?= debug
DEBUG := 0
ifeq ($(TARGET),debug)
diff --git a/README.md b/README.md
index 09ba819..83f470a 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,7 @@ polecat depends on:
- libcurl
- json-c
+- libarchive
### License
MIT \ No newline at end of file
diff --git a/src/common.c b/src/common.c
index f3131e0..ca08f07 100644
--- a/src/common.c
+++ b/src/common.c
@@ -16,6 +16,6 @@ void print_help(const struct Command* commands, const size_t size)
for (size_t i = 0; i < size; ++i)
{
- printf("\t%-*s\t%s\n", longestCommand, commands[i].name, commands[i].description);
+ printf("\t%-*s\t %s\n", longestCommand, commands[i].name, commands[i].description);
}
}
diff --git a/src/common.h b/src/common.h
index 54882df..3b071cc 100644
--- a/src/common.h
+++ b/src/common.h
@@ -8,6 +8,7 @@
#define WINE_API "https://lutris.net/api/runners/wine"
#define DXVK_API "https://api.github.com/repos/lutris/dxvk/releases"
+#define INSTALLER_API "https://lutris.net/api/installers/"
#define USER_AGENT NAME "/" VERSION
diff --git a/src/dxvk.c b/src/dxvk.c
index f0ebc86..c5ac1d0 100644
--- a/src/dxvk.c
+++ b/src/dxvk.c
@@ -10,16 +10,15 @@
const static struct Command dxvk_commands[] = {
{ .name = "install", .func = dxvk_install, .description = "download and install a dxvk version" },
{ .name = "list", .func = dxvk_list, .description = "list available dxvk versions" },
- { .name = "help", .func = dxvk_help, .description = "shows this message" },
};
int dxvk(int argc, char** argv)
{
- if (argc > 2)
+ if (argc > 1)
{
for (int i = 0; i < ARRAY_LEN(dxvk_commands); ++i)
{
- if (!strcmp(dxvk_commands[i].name, argv[2])) return dxvk_commands[i].func(argc, argv);
+ if (!strcmp(dxvk_commands[i].name, argv[1])) return dxvk_commands[i].func(argc-1, argv+1);
}
}
@@ -29,14 +28,14 @@ int dxvk(int argc, char** argv)
int dxvk_install(int argc, char** argv)
{
- if (argc == 4)
+ if (argc == 2)
{
struct json_object* runner = fetchJSON(DXVK_API);
if (runner)
{
- int choice = atoi(argv[3]);
+ int choice = atoi(argv[1]);
if (choice > json_object_array_length(runner) - 1 || choice < 0)
{
diff --git a/src/lutris.c b/src/lutris.c
new file mode 100644
index 0000000..4adaa81
--- /dev/null
+++ b/src/lutris.c
@@ -0,0 +1,218 @@
+#include <stdio.h>
+#include <string.h>
+#include <linux/limits.h>
+
+#include "lutris.h"
+#include "net.h"
+#include "common.h"
+
+const static struct Command lutris_commands[] = {
+ { .name = "install", .func = lutris_install, .description = "install a lutris script" },
+ { .name = "info", .func = lutris_info, .description = "show information about a lutris script" },
+};
+
+int lutris(int argc, char** argv)
+{
+ if (argc > 1)
+ {
+ for (int i = 0; i < ARRAY_LEN(lutris_commands); ++i)
+ {
+ if (!strcmp(lutris_commands[i].name, argv[1])) return lutris_commands[i].func(argc-1, argv+1);
+ }
+ }
+
+
+ return lutris_help(argc, argv);
+}
+
+
+int lutris_install(int argc, char** argv)
+{
+
+}
+
+int lutris_info(int argc, char** argv)
+{
+ if (argc == 2)
+ {
+ char installerurl[PATH_MAX];
+ lutris_getInstallerURL(installerurl, argv[1]);
+
+ struct json_object* installer = fetchJSON(installerurl);
+
+ if (installer)
+ {
+ struct json_object* count, *results, *slug;
+
+ json_object_object_get_ex(installer, "count", &count);
+ json_object_object_get_ex(installer, "results", &results);
+ slug = json_object_array_get_idx(results, 0);
+
+ if (json_object_get_int(count) != 0)
+ {
+ struct json_object* name, *version, *runner, *description, *notes, *script, *scriptinstall, *wine, *winever;
+ json_object_object_get_ex(slug, "name", &name);
+ json_object_object_get_ex(slug, "version", &version);
+ json_object_object_get_ex(slug, "runner", &runner);
+ json_object_object_get_ex(slug, "description", &description);
+ json_object_object_get_ex(slug, "notes", &notes);
+ json_object_object_get_ex(slug, "script", &script);
+ json_object_object_get_ex(script, "installer", &scriptinstall);
+
+ json_object_object_get_ex(script, "wine", &wine);
+ json_object_object_get_ex(wine, "version", &winever);
+
+ printf("[%s]", json_object_get_string(runner));
+ if (winever) printf("[%s]", json_object_get_string(winever));
+
+ printf(" %s - %s\n", json_object_get_string(name), json_object_get_string(version));
+
+ if (description) printf("\n%s\n", json_object_get_string(description));
+ if (notes) printf("\n%s\n", json_object_get_string(notes));
+
+ if (scriptinstall)
+ {
+ puts("\ninstall script:");
+ for (int i = 0; i < json_object_array_length(scriptinstall); ++i)
+ {
+ struct json_object* step = json_object_array_get_idx(scriptinstall, i);
+ struct json_object* directive;
+
+ for (int l = 0; l < KEYWORDMAX; ++l)
+ {
+ json_object_object_get_ex(step, keywordstr[l], &directive);
+ if (directive)
+ {
+ struct json_object* options[5];
+ printf(" - ");
+ switch (l)
+ {
+ case MOVE:
+ case COPY:
+ case MERGE:
+ json_object_object_get_ex(directive, "src", &options[0]);
+ json_object_object_get_ex(directive, "dst", &options[1]);
+ printf("%s %s %s\n", keywordstr[l], json_object_get_string(options[0]), json_object_get_string(options[1]));
+ break;
+
+ case EXTRACT:
+ json_object_object_get_ex(directive, "file", &options[0]);
+ printf("%s %s\n", keywordstr[l], json_object_get_string(options[0]));
+ break;
+
+ case CHMODX:
+ printf("%s %s\n", keywordstr[l], json_object_get_string(directive));
+ break;
+
+ case EXECUTE:
+ json_object_object_get_ex(directive, "file", &options[0]);
+ printf("%s %s\n", keywordstr[l], json_object_get_string(options[0]));
+ break;
+
+ case WRITE_FILE:
+ json_object_object_get_ex(directive, "file", &options[0]);
+ printf("%s %s\n", keywordstr[l], json_object_get_string(options[0]));
+ break;
+
+ case WRITE_CONFIG:
+ json_object_object_get_ex(directive, "file", &options[0]);
+ json_object_object_get_ex(directive, "section", &options[1]);
+ json_object_object_get_ex(directive, "key", &options[2]);
+ json_object_object_get_ex(directive, "value", &options[3]);
+
+ printf("%s %s [%s] %s = %s\n", keywordstr[l], json_object_get_string(options[0]), json_object_get_string(options[1]), json_object_get_string(options[2]), json_object_get_string(options[3]));
+ break;
+
+ case WRITE_JSON:
+ printf("%s\n", keywordstr[l]);
+ break;
+
+ case INPUT_MENU:
+ json_object_object_get_ex(directive, "description", &options[0]);
+ printf("%s `%s'\n", keywordstr[l], json_object_get_string(options[0]));
+ break;
+
+ case INSERT_DISC:
+ json_object_object_get_ex(directive, "requires", &options[0]);
+ printf("%s %s\n", keywordstr[l], json_object_get_string(options[0]));
+ break;
+
+ case TASK:
+ json_object_object_get_ex(directive, "name", &options[0]);
+ const char* name = json_object_get_string(options[0]);
+ for (int k = 0; k <= TASKKEYWORDMAX; ++k)
+ {
+ if (!strcmp(name, taskKeywordstr[k]))
+ {
+ switch(k)
+ {
+ case WINEEXEC:
+ json_object_object_get_ex(directive, "executable", &options[1]);
+ printf("%s %s\n", name, json_object_get_string(options[1]));
+ break;
+
+ case WINETRICKS:
+ json_object_object_get_ex(directive, "app", &options[1]);
+ printf("%s %s\n", name, json_object_get_string(options[1]));
+ break;
+
+ case CREATE_PREFIX:
+ case WINEKILL:
+ json_object_object_get_ex(directive, "prefix", &options[1]);
+ printf("%s %s\n", name, json_object_get_string(options[1]));
+ break;
+
+ case SET_REGEDIT:
+ json_object_object_get_ex(directive, "path", &options[1]);
+ json_object_object_get_ex(directive, "key", &options[2]);
+ json_object_object_get_ex(directive, "value", &options[3]);
+
+ printf("%s %s\\%s = %s\n", name, json_object_get_string(options[1]), json_object_get_string(options[2]), json_object_get_string(options[3]));
+ break;
+
+ default:
+ puts(name);
+ break;
+ }
+ break;
+ }
+ if (k == TASKKEYWORDMAX) printf("FIXME: unknown task %s\n", name);
+ }
+ break;
+
+ default:
+ printf("FIXME: unknown %s\n", keywordstr[l]);
+ }
+ break;
+ }
+ }
+ }
+ }
+ else puts("no install script found");
+ }
+ else
+ {
+ printf("`%s' does not exist on lutris\n", argv[1]);
+ }
+
+ json_object_put(installer);
+ }
+ }
+ else puts(USAGE_STR " lutris info <installer-id>\nInstaller IDs are obtained from the lutris website");
+
+ return 0;
+}
+
+void lutris_getInstallerURL(char* buffer, char* name)
+{
+ strcpy(buffer, INSTALLER_API);
+ strcat(buffer, name);
+}
+int lutris_help(int argc, char** argv)
+{
+ puts(USAGE_STR " lutris <command>\n\nList of commands:");
+
+ print_help(lutris_commands, ARRAY_LEN(lutris_commands));
+
+ return 0;
+} \ No newline at end of file
diff --git a/src/lutris.h b/src/lutris.h
new file mode 100644
index 0000000..6f5fa40
--- /dev/null
+++ b/src/lutris.h
@@ -0,0 +1,61 @@
+#ifndef LUTRIS_H
+#define LUTRIS_H
+
+enum keywords {
+ MOVE = 0,
+ MERGE,
+ EXTRACT,
+ COPY,
+ CHMODX,
+ EXECUTE,
+ WRITE_FILE,
+ WRITE_CONFIG,
+ WRITE_JSON,
+ INPUT_MENU,
+ INSERT_DISC,
+ TASK,
+
+ KEYWORDMAX
+};
+
+static const char keywordstr[KEYWORDMAX][0xF] = {
+ "move",
+ "merge",
+ "extract",
+ "copy",
+ "chmodx",
+ "execute",
+ "write_file",
+ "write_config",
+ "write_json",
+ "input_menu",
+ "insert-disc",
+ "task",
+};
+
+enum taskKeywords {
+ WINEEXEC = 0,
+ WINETRICKS,
+ CREATE_PREFIX,
+ SET_REGEDIT,
+ WINEKILL,
+
+ TASKKEYWORDMAX
+};
+
+static const char taskKeywordstr[TASKKEYWORDMAX][0xF] =
+{
+ "wineexec",
+ "winetricks",
+ "create_prefix",
+ "set_regedit",
+ "winekill"
+};
+
+int lutris(int, char**);
+int lutris_install(int, char**);
+int lutris_info(int, char**);
+int lutris_help(int, char**);
+void lutris_getInstallerURL(char*, char*);
+
+#endif \ No newline at end of file
diff --git a/src/main.c b/src/main.c
index d56ac28..aa4f356 100644
--- a/src/main.c
+++ b/src/main.c
@@ -5,14 +5,15 @@
#include "main.h"
#include "wine.h"
#include "dxvk.h"
+#include "lutris.h"
#include "common.h"
#include "config.h"
const static struct Command main_commands[] = {
- { .name = "wine", .func = wine, .description = "manage wine versions" },
- //{ .name = "dxvk", .func = dxvk, .description = "manage dxvk versions (TODO)" },
- { .name = "info", .func = main_info, .description = "show some information about polecat" },
- { .name = "help", .func = main_help, .description = "displays this message" },
+ { .name = "wine", .func = wine, .description = "manage wine versions" },
+ //{ .name = "dxvk", .func = dxvk, .description = "manage dxvk versions (TODO)" },
+ { .name = "lutris", .func = lutris, .description = "run lutris instraller"},
+ { .name = "info", .func = main_info, .description = "show some information about polecat" },
};
@@ -22,7 +23,7 @@ int main(int argc, char** argv)
{
for (int i = 0; i < ARRAY_LEN(main_commands); ++i)
{
- if (!strcmp(main_commands[i].name, argv[1])) return main_commands[i].func(argc, argv);
+ if (!strcmp(main_commands[i].name, argv[1])) return main_commands[i].func(argc-1, argv+1);
}
}
diff --git a/src/main.h b/src/main.h
index 594b29e..e64eb9a 100644
--- a/src/main.h
+++ b/src/main.h
@@ -1,7 +1,7 @@
#ifndef MAIN_H
#define MAIN_H
-extern int main_help(int, char**);
-extern int main_info(int, char**);
+int main_help(int, char**);
+int main_info(int, char**);
#endif \ No newline at end of file
diff --git a/src/net.c b/src/net.c
index a1c574a..a23f772 100644
--- a/src/net.c
+++ b/src/net.c
@@ -56,13 +56,12 @@ struct MemoryStruct* downloadToRam(const char* URL)
curl_easy_getinfo (curl_handle, CURLINFO_RESPONSE_CODE, &http_code);
if(res != CURLE_OK) {
- fprintf(stderr, "curl_easy_perform() failed: %s\n",
- curl_easy_strerror(res));
+ printf("libcurl error: %s\n", curl_easy_strerror(res));
return NULL;
}
else if (http_code != 200)
{
- fprintf(stderr, "Server didn't respond as expected [HTTP Error %li]\n", http_code);
+ printf("HTTP Error %li\n", http_code);
return NULL;
}
diff --git a/src/tar.c b/src/tar.c
index 8894676..0fd4fc3 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -19,7 +19,7 @@ static int copy_data(struct archive* ar, struct archive* aw)
return (r);
r = archive_write_data_block(aw, buff, size, offset);
if (r < ARCHIVE_OK) {
- fprintf(stderr, "%s\n", archive_error_string(aw));
+ printf("%s\n", archive_error_string(aw));
return (r);
}
}
@@ -32,7 +32,7 @@ void extract(const char* filename, const char* outputdir)
if (chdir(outputdir) < 0)
{
- fprintf(stderr, "Cannot change to %s\n", outputdir);
+ printf("Cannot change to %s\n", outputdir);
return;
}
@@ -67,7 +67,7 @@ void extract(const char* filename, const char* outputdir)
if (r < ARCHIVE_OK)
{
- fprintf(stderr, "%s\n", archive_error_string(a));
+ printf("%s\n", archive_error_string(a));
}
if (r < ARCHIVE_WARN)
@@ -78,20 +78,20 @@ void extract(const char* filename, const char* outputdir)
r = archive_write_header(ext, entry);
if (r < ARCHIVE_OK)
{
- fprintf(stderr, "%s\n", archive_error_string(ext));
+ printf("%s\n", archive_error_string(ext));
}
else if (archive_entry_size(entry) > 0)
{
r = copy_data(a, ext);
if (r < ARCHIVE_OK)
- fprintf(stderr, "%s\n", archive_error_string(ext));
+ printf("%s\n", archive_error_string(ext));
if (r < ARCHIVE_WARN)
return;
}
r = archive_write_finish_entry(ext);
if (r < ARCHIVE_OK)
- fprintf(stderr, "%s\n", archive_error_string(ext));
+ printf("%s\n", archive_error_string(ext));
if (r < ARCHIVE_WARN)
return;
}
diff --git a/src/wine.c b/src/wine.c
index 3f50eee..c6f445e 100644
--- a/src/wine.c
+++ b/src/wine.c
@@ -17,29 +17,29 @@
const static struct Command wine_commands[] = {
- { .name = "download", .func = wine_download, .description = "download and extract a wine version from lutris" },
- { .name = "list", .func = wine_list, .description = "list installable wine versions" },
- { .name = "run", .func = wine_run, .description = "run a installed wine version" },
- { .name = "list-installed", .func = wine_installed, .description = "list installed wine versions" },
- { .name = "help", .func = wine_help, .description = "shows this message" },
+ { .name = "download", .func = wine_download, .description = "download and extract a wine version from lutris" },
+ { .name = "list", .func = wine_list, .description = "list installable wine versions" },
+ { .name = "run", .func = wine_run, .description = "run a installed wine version" },
+ { .name = "installed", .func = wine_installed, .description = "list installed wine versions" },
};
int wine(int argc, char** argv)
{
- if (argc > 2)
+ if (argc > 1)
{
for (int i = 0; i < ARRAY_LEN(wine_commands); ++i)
{
- if (!strcmp(wine_commands[i].name, argv[2])) return wine_commands[i].func(argc, argv);
+ if (!strcmp(wine_commands[i].name, argv[1])) return wine_commands[i].func(argc-1, argv+1);
}
}
+
return wine_help(argc, argv);
}
int wine_download(int argc, char** argv)
{
- if (argc == 4)
+ if (argc == 2)
{
struct json_object* runner = fetchJSON(WINE_API);
@@ -48,11 +48,11 @@ int wine_download(int argc, char** argv)
struct json_object* versions;
json_object_object_get_ex(runner, "versions", &versions);
- int choice = atoi(argv[3]);
+ int choice = atoi(argv[1]);
if (choice > json_object_array_length(versions) - 1 || choice < 0)
{
- fprintf(stderr, "`%i' is not a valid ID\n\nrun `polecat wine list' to get a valid ID\n", choice);
+ printf("`%i' is not a valid ID\n\nrun `polecat wine list' to get a valid ID\n", choice);
}
else
{
@@ -72,11 +72,11 @@ int wine_download(int argc, char** argv)
strcat(downloadpath, "/");
strcat(downloadpath, name);
- fprintf(stderr, "Downloading %s\n", name);
+ printf("Downloading %s\n", name);
downloadFile(json_object_get_string(url), downloadpath);
- fprintf(stderr, "Extracting %s\n", name);
+ printf("Extracting %s\n", name);
extract(downloadpath, datadir);
- fprintf(stderr, "Done\n");
+ printf("Done\n");
}
json_object_put(runner);
@@ -115,17 +115,17 @@ int wine_list(int argc, char** argv)
int wine_run(int argc, char** argv)
{
- if (argc > 3)
+ if (argc > 1)
{
char winepath[PATH_MAX];
getDataDir(winepath);
- char* winever = argv[3];
+ char* winever = argv[1];
strcat(winepath, "/");
strcat(winepath, winever);
strcat(winepath, "/bin/wine");
- for (int i = 4; i < argc; ++i)
+ for (int i = 2; i < argc; ++i)
{
strcat(winepath, " ");
strcat(winepath, argv[i]);
@@ -134,7 +134,7 @@ int wine_run(int argc, char** argv)
return system(winepath);
}
- fprintf(stderr, "Specify a what wine version to run.\nUse `" NAME " wine list-installed' to list available versions\n");
+ printf("Specify a what wine version to run.\nUse `" NAME " wine list-installed' to list available versions\n");
return 0;
}
@@ -147,7 +147,7 @@ int wine_installed(int argc, char** argv)
DIR *dir;
struct dirent *ent;
- fprintf(stderr, "Installed wine versions:\n");
+ printf("Installed wine versions:\n");
if ((dir = opendir(datadir)) != NULL)
{
while ((ent = readdir (dir)) != NULL)
@@ -158,7 +158,7 @@ int wine_installed(int argc, char** argv)
*/
if (ent->d_name[0] != '.' && ent->d_type == DT_DIR)
{
- fprintf(stderr, " - %s\n", ent->d_name);
+ printf(" - %s\n", ent->d_name);
}
}
closedir (dir);