aboutsummaryrefslogtreecommitdiff
path: root/src/lutris.c
diff options
context:
space:
mode:
authorJan200101 <sentrycraft123@gmail.com>2020-08-18 23:58:16 +0200
committerJan200101 <sentrycraft123@gmail.com>2020-08-18 23:58:16 +0200
commitd53109eaa890ab807b66961a89291cea3cd3c003 (patch)
treea62382b32014266f5aecb6f639d0962bb1682bf0 /src/lutris.c
parent1753e2b151cbb4af75a4e9ea61720b3704b03805 (diff)
downloadpolecat-d53109eaa890ab807b66961a89291cea3cd3c003.tar.gz
polecat-d53109eaa890ab807b66961a89291cea3cd3c003.zip
first part of a proper lutris implementation and cleanup0.1.4
- remove all old build platform related variables - change behavior of clean - change tabs into spaces - make XDG fetching method static - replace strcpy and cat with strn alternative with proper bounds checking - add cache dir - reenable dxvk and download from ram - completely rework lutris fetching and convert it into an interal struct - only show http errors in debug - add sanity checks to methods with possible NULL return - change extracting methods to extract tar from ram
Diffstat (limited to 'src/lutris.c')
-rw-r--r--src/lutris.c490
1 files changed, 346 insertions, 144 deletions
diff --git a/src/lutris.c b/src/lutris.c
index 4adaa81..beb8384 100644
--- a/src/lutris.c
+++ b/src/lutris.c
@@ -28,191 +28,393 @@ int lutris(int argc, char** argv)
int lutris_install(int argc, char** argv)
{
-
+ return 0;
}
int lutris_info(int argc, char** argv)
{
if (argc == 2)
{
+ struct script installer = lutris_getInstaller(argv[1]);
+ if (installer.error != NO_SLUG)
+ {
+
+ printf("Name: %s\n"
+ "Version: %s\n"
+ "Runner: %i\n"
+ "Wine: %s\n"
+ "Error %i\n"
+ "Files: %zu\n"
+ "Directives: %zu\n",
+ installer.name,
+ installer.version,
+ installer.runner,
+ installer.wine,
+ installer.error,
+ installer.filecount,
+ installer.directivecount);
+
+ if (installer.filecount)
+ {
+ puts("\nFiles:");
+ for (int i = 0; i < installer.filecount; ++i)
+ {
+ printf("\t%s\t->\t%s\n", installer.files[i]->filename, installer.files[i]->url);
+ }
+ }
+
+ if (installer.directivecount)
+ {
+
+ puts("\nDirectives:");
+ for (int i = 0; i < installer.directivecount; ++i)
+ {
+ printf("\t%s", keywordstr[installer.directives[i]->command]);
+
+ if (installer.directives[i]->task != NO_TASK) printf(" %s", taskKeywordstr[installer.directives[i]->task]);
+
+ for (int j = 0; j < installer.directives[i]->size; ++j)
+ {
+ printf(" %s", installer.directives[i]->arguments[j]);
+ }
+
+ puts("");
+ }
+ }
+ }
+ else
+ {
+
+ }
+
+ lutris_freeInstaller(&installer);
+ }
+ return 0;
+}
+
+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;
+}
+
+void lutris_getInstallerURL(char* buffer, char* name, size_t size)
+{
+ strncpy(buffer, INSTALLER_API, size);
+ strncat(buffer, name, size - strlen(buffer));
+}
+
+struct script lutris_getInstaller(char* installername)
+{
+ struct script installer;
+ installer.name = NULL;
+ installer.version = NULL;
+ installer.runner = UNKNOWN_RUNNER;
+ installer.description = NULL;
+ installer.notes = NULL;
+ installer.wine = NULL;
+ installer.directives = NULL;
+ installer.directivecount = 0;
+ installer.files = NULL;
+ installer.filecount = 0;
+ installer.error = NONE;
+
+ if (installername)
+ {
char installerurl[PATH_MAX];
- lutris_getInstallerURL(installerurl, argv[1]);
+ lutris_getInstallerURL(installerurl, installername, sizeof(installerurl));
- struct json_object* installer = fetchJSON(installerurl);
+ struct json_object* installerjson = fetchJSON(installerurl);
- if (installer)
+ if (installerjson)
{
struct json_object* count, *results, *slug;
- json_object_object_get_ex(installer, "count", &count);
- json_object_object_get_ex(installer, "results", &results);
+ json_object_object_get_ex(installerjson, "count", &count);
+ json_object_object_get_ex(installerjson, "results", &results);
slug = json_object_array_get_idx(results, 0);
- if (json_object_get_int(count) != 0)
+ if (json_object_get_int(count) == 1)
{
- 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);
+ struct json_object* script, *scriptinstall, *files;
+
+ if(json_object_object_get_ex(slug, "script", &script))
+ {
+ {
+ struct json_object* name, *version, *runner, *description, *notes, *wine, *winever;
+ const char* namestr, *versionstr, *runnerstr, *descriptionstr, *notesstr, *winestr;
+
+ json_object_object_get_ex(slug, "name", &name);
+ namestr = json_object_get_string(name);
+ installer.name = malloc( strlen(namestr) * sizeof(char) +1 );
+ strcpy(installer.name, namestr);
+
+ json_object_object_get_ex(slug, "version", &version);
+ versionstr = json_object_get_string(version);
+ installer.version = malloc( strlen(versionstr) * sizeof(char) +1 );
+ strcpy(installer.version, versionstr);
+
+ json_object_object_get_ex(slug, "runner", &runner);
+ runnerstr = json_object_get_string(runner);
+ for (int i = 0; i < RUNNERMAX; ++i)
+ {
+ if(!strcmp(runnerstr, runnerStr[i]))
+ {
+ installer.runner = i;
+ break;
+ }
+ }
- json_object_object_get_ex(script, "wine", &wine);
- json_object_object_get_ex(wine, "version", &winever);
+ json_object_object_get_ex(slug, "description", &description);
+ if (description)
+ {
+ descriptionstr = json_object_get_string(description);
+ installer.description = malloc( strlen(descriptionstr) * sizeof(char) +1 );
+ strcpy(installer.description, descriptionstr);
+ }
- printf("[%s]", json_object_get_string(runner));
- if (winever) printf("[%s]", json_object_get_string(winever));
+ json_object_object_get_ex(slug, "notes", &notes);
+ if (notes)
+ {
+ notesstr = json_object_get_string(notes);
+ installer.notes = malloc( strlen(notesstr) * sizeof(char) +1 );
+ strcpy(installer.notes, notesstr);
+ }
- printf(" %s - %s\n", json_object_get_string(name), json_object_get_string(version));
+ json_object_object_get_ex(script, "wine", &wine);
+ json_object_object_get_ex(wine, "version", &winever);
+ if (winever)
+ {
+ winestr = json_object_get_string(winever);
+ installer.wine = malloc( strlen(winestr) * sizeof(char) +1 );
+ strcpy(installer.name, winestr);
+ }
- 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)
+ if (json_object_object_get_ex(script, "files", &files))
+ {
+ installer.filecount = json_object_array_length(files);
+
+ installer.files = malloc(installer.filecount * sizeof(void*));
+ for (int i = 0; i < installer.filecount; ++i)
+ {
+ struct json_object* file = json_object_array_get_idx(files, i);
+ struct lh_entry* entry = json_object_get_object(file)->head;
+
+ installer.files[i] = malloc(sizeof(struct file_t));
+
+ {
+ size_t namelen = strlen((char*)entry->k);
+ installer.files[i]->filename = malloc(namelen * sizeof(char) +1);
+ strcpy(installer.files[i]->filename, (char*)entry->k);
+ }
+
+ const char* urlstr;
+
+ if(json_object_get_type((struct json_object*)entry->v) == json_type_object)
+
+ {
+ struct json_object* url;
+ json_object_object_get_ex((struct json_object*)entry->v, "url", &url);
+ urlstr = json_object_get_string(url);
+ }
+ else
+ {
+ urlstr = json_object_get_string((struct json_object*)entry->v);
+ }
+
+ {
+ size_t urllen = strlen(urlstr);
+ installer.files[i]->url = malloc(urllen * sizeof(char) +1);
+ strcpy(installer.files[i]->url, urlstr);
+ }
+ }
+ }
+
+ if (json_object_object_get_ex(script, "installer", &scriptinstall))
{
- struct json_object* step = json_object_array_get_idx(scriptinstall, i);
- struct json_object* directive;
+ installer.directivecount = json_object_array_length(scriptinstall);
- for (int l = 0; l < KEYWORDMAX; ++l)
+ installer.directives = malloc(installer.directivecount * sizeof(void*));
+ for (int i = 0; i < installer.directivecount; ++i)
{
- json_object_object_get_ex(step, keywordstr[l], &directive);
- if (directive)
+ struct json_object* step = json_object_array_get_idx(scriptinstall, i);
+ struct json_object* directive;
+
+ installer.directives[i] = malloc(sizeof(struct directive_t));
+ installer.directives[i]->size = 0;
+ installer.directives[i]->command = UNKNOWN_DIRECTIVE;
+ installer.directives[i]->task = NO_TASK;
+
+ for (int l = 0; l < KEYWORDMAX; ++l)
{
- struct json_object* options[5];
- printf(" - ");
- switch (l)
+ if (json_object_object_get_ex(step, keywordstr[l], &directive))
{
- 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]))
+ struct json_object* options[5];
+ 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]);
+ installer.directives[i]->size = 2;
+ break;
+
+ case EXTRACT:
+ json_object_object_get_ex(directive, "file", &options[0]);
+ installer.directives[i]->size = 1;
+ break;
+
+ case CHMODX:
+ installer.directives[i]->size = 1;
+ break;
+
+ case EXECUTE:
+ if(!json_object_object_get_ex(directive, "command", &options[0])) json_object_object_get_ex(directive, "file", &options[0]);
+ installer.directives[i]->size = 1;
+ break;
+
+ case WRITE_FILE:
+ json_object_object_get_ex(directive, "file", &options[0]);
+ json_object_object_get_ex(directive, "content", &options[1]);
+ installer.directives[i]->size = 2;
+ 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]);
+ installer.directives[i]->size = 4;
+ break;
+
+ case WRITE_JSON:
+ break;
+
+ case INPUT_MENU:
+ json_object_object_get_ex(directive, "description", &options[0]);
+ installer.directives[i]->size = 1;
+ break;
+
+ case INSERT_DISC:
+ json_object_object_get_ex(directive, "requires", &options[0]);
+ installer.directives[i]->size = 1;
+ 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)
{
- switch(k)
+ if (!strcmp(name, taskKeywordstr[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;
+ switch(k)
+ {
+ case WINEEXEC:
+ json_object_object_get_ex(directive, "executable", &options[1]);
+ installer.directives[i]->size = 1;
+ break;
+
+ case WINETRICKS:
+ json_object_object_get_ex(directive, "app", &options[1]);
+ json_object_object_get_ex(directive, "prefix", &options[2]);
+ installer.directives[i]->size = 2;
+ break;
+
+ case CREATE_PREFIX:
+ case WINEKILL:
+ json_object_object_get_ex(directive, "prefix", &options[1]);
+ installer.directives[i]->size = 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]);
+ installer.directives[i]->size = 3;
+ break;
+ }
+ installer.directives[i]->task = k;
+ break;
}
- break;
}
- if (k == TASKKEYWORDMAX) printf("FIXME: unknown task %s\n", name);
- }
- break;
-
- default:
- printf("FIXME: unknown %s\n", keywordstr[l]);
+ break;
+ }
+ installer.directives[i]->command = l;
+
+ const char* str;
+ uint8_t offset = 0;
+ if (installer.directives[i]->task != NO_TASK)
+ {
+ offset = 1;
+ }
+
+
+ installer.directives[i]->arguments = malloc(installer.directives[i]->size * sizeof(char*));
+ for (int j = 0; j < installer.directives[i]->size; ++j)
+ {
+ str = json_object_get_string(options[j+offset]);
+ installer.directives[i]->arguments[j] = malloc(strlen(str) * sizeof(char) +1);
+ strcpy(installer.directives[i]->arguments[j], str);
+ }
+ break;
}
- break;
}
}
}
- }
- else puts("no install script found");
- }
- else
- {
- printf("`%s' does not exist on lutris\n", argv[1]);
+ else installer.error = NO_INSTALLER;
+ }
+ else installer.error = NO_SCRIPT;
}
+ else installer.error = NO_SLUG;
- json_object_put(installer);
+ json_object_put(installerjson);
}
+ else installer.error = NO_JSON;
}
- else puts(USAGE_STR " lutris info <installer-id>\nInstaller IDs are obtained from the lutris website");
- return 0;
+ return installer;
}
-void lutris_getInstallerURL(char* buffer, char* name)
+void lutris_freeInstaller(struct script* installer)
{
- strcpy(buffer, INSTALLER_API);
- strcat(buffer, name);
-}
-int lutris_help(int argc, char** argv)
-{
- puts(USAGE_STR " lutris <command>\n\nList of commands:");
+ if (installer)
+ {
+ free(installer->name);
+ free(installer->version);
+ free(installer->description);
+ free(installer->notes);
+ free(installer->wine);
- print_help(lutris_commands, ARRAY_LEN(lutris_commands));
+ if (installer->directives)
+ {
+ for (int i = 0; i < installer->directivecount; ++i)
+ {
+ for (int j = 0; j < installer->directives[i]->size; ++j)
+ {
+ free(installer->directives[i]->arguments[j]);
+ }
- return 0;
+ free(installer->directives[i]->arguments);
+ free(installer->directives[i]);
+ }
+ free(installer->directives);
+ }
+
+ if (installer->files)
+ {
+ for (int i = 0; i < installer->filecount; ++i)
+ {
+ free(installer->files[i]->filename);
+ free(installer->files[i]->url);
+ free(installer->files[i]);
+ }
+ free(installer->files);
+ }
+ }
} \ No newline at end of file