diff options
author | Jan200101 <sentrycraft123@gmail.com> | 2020-08-18 23:58:16 +0200 |
---|---|---|
committer | Jan200101 <sentrycraft123@gmail.com> | 2020-08-18 23:58:16 +0200 |
commit | d53109eaa890ab807b66961a89291cea3cd3c003 (patch) | |
tree | a62382b32014266f5aecb6f639d0962bb1682bf0 /src/lutris.c | |
parent | 1753e2b151cbb4af75a4e9ea61720b3704b03805 (diff) | |
download | polecat-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.c | 490 |
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", ¬es); - 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", ¬es); + 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 |