Removed small memory leaks and improved error code path

at first when i create the proof of concept i didn't care at all about memory leak sine the kernel
was cleaning that for me.
This commit is contained in:
Marc
2022-09-11 14:14:42 +02:00
parent ef8776b6b1
commit 2d63fd8d92
4 changed files with 169 additions and 111 deletions
+28 -16
View File
@@ -9,32 +9,37 @@
//TODO: replace ALL system call by execv / execl since it make my code into swiss cheese //TODO: replace ALL system call by execv / execl since it make my code into swiss cheese
void unzip(const char * path, const char * outdir) { int unzip(const char * path, const char * outdir) {
int returnValue = EXIT_SUCCESS;
char * unzipCommand = g_strconcat("/bin/sh -c 'yes | unzip \"", path, "\" -d \"" , outdir, "\" > /dev/null'", NULL); char * unzipCommand = g_strconcat("/bin/sh -c 'yes | unzip \"", path, "\" -d \"" , outdir, "\" > /dev/null'", NULL);
if(system(unzipCommand) != 0) { if(system(unzipCommand) != 0) {
printf("\nFailed to unzip archive\n"); printf("\nFailed to unzip archive\n");
exit(EXIT_FAILURE); returnValue = EXIT_FAILURE;
} }
free(unzipCommand); free(unzipCommand);
return returnValue;
} }
void unrar(const char * path, const char * outdir) { int unrar(const char * path, const char * outdir) {
int returnValue = EXIT_SUCCESS;
char * unrarCommand = g_strconcat("/bin/sh -c 'unrar -y x \"", path, "\" \"", outdir, "\" > /dev/null'", NULL); char * unrarCommand = g_strconcat("/bin/sh -c 'unrar -y x \"", path, "\" \"", outdir, "\" > /dev/null'", NULL);
if(system(unrarCommand) != 0) { if(system(unrarCommand) != 0) {
printf("Failed to unzip archive\n"); printf("Failed to unzip archive\n");
exit(EXIT_FAILURE); returnValue = EXIT_FAILURE;
} }
free(unrarCommand); free(unrarCommand);
return returnValue;
} }
void un7z(const char * path, const char * outdir) { int un7z(const char * path, const char * outdir) {
int returnValue = EXIT_SUCCESS;
char * un7zCommand = g_strconcat("/bin/sh -c 'yes | 7z x \"", path, "\" \"-o", outdir, "\" > /dev/null'", NULL); char * un7zCommand = g_strconcat("/bin/sh -c 'yes | 7z x \"", path, "\" \"-o", outdir, "\" > /dev/null'", NULL);
if(system(un7zCommand) != 0) { if(system(un7zCommand) != 0) {
printf("Failed to unzip archive\n"); printf("Failed to unzip archive\n");
exit(EXIT_FAILURE); returnValue = EXIT_FAILURE;
} }
free(un7zCommand); free(un7zCommand);
return returnValue;
} }
char * extractLastPart(const char * filePath, const char delimeter) { char * extractLastPart(const char * filePath, const char delimeter) {
@@ -47,7 +52,7 @@ int length = strlen(filePath);
} }
} }
if(index <= 0) return NULL; if(index <= 0 || index == length) return NULL;
char * extension = malloc((length - index) * sizeof(char)); char * extension = malloc((length - index) * sizeof(char));
memcpy(extension, &filePath[index], (length - index)); memcpy(extension, &filePath[index], (length - index));
return extension; return extension;
@@ -62,16 +67,20 @@ char * extractFileName(const char * filePath) {
} }
void addMod(const char * filePath, int appId) { int addMod(const char * filePath, int appId) {
int returnValue = EXIT_SUCCESS;
if (access(filePath, F_OK) != 0) { if (access(filePath, F_OK) != 0) {
printf("File not found\n"); printf("File not found\n");
exit(EXIT_FAILURE); returnValue = EXIT_FAILURE;
goto exit;
} }
char * configFolder = g_build_filename(getenv("HOME"), MANAGER_FILES, NULL); char * configFolder = g_build_filename(getenv("HOME"), MANAGER_FILES, NULL);
if(g_mkdir_with_parents(configFolder, 0755) < 0) { if(g_mkdir_with_parents(configFolder, 0755) < 0) {
printf("Could not create mod folder"); printf("Could not create mod folder");
exit(EXIT_FAILURE); returnValue = EXIT_FAILURE;
goto exit2;
} }
char * filename = extractFileName(filePath); char * filename = extractFileName(filePath);
@@ -80,21 +89,20 @@ void addMod(const char * filePath, int appId) {
free(extension); free(extension);
char appIdStr[20]; char appIdStr[20];
sprintf(appIdStr, "%d", appId);
char * outdir = g_build_filename(configFolder, MOD_FOLDER_NAME, appIdStr, filename, NULL); char * outdir = g_build_filename(configFolder, MOD_FOLDER_NAME, appIdStr, filename, NULL);
g_mkdir_with_parents(outdir, 0755); g_mkdir_with_parents(outdir, 0755);
printf("Adding mod, this process can be slow depending on your hardware\n"); printf("Adding mod, this process can be slow depending on your hardware\n");
if(strcmp(lowercaseExtension, "rar") == 0) { if(strcmp(lowercaseExtension, "rar") == 0) {
unrar(filePath, outdir); returnValue = unrar(filePath, outdir);
} else if (strcmp(lowercaseExtension, "zip") == 0) { } else if (strcmp(lowercaseExtension, "zip") == 0) {
unzip(filePath, outdir); returnValue = unzip(filePath, outdir);
} else if (strcmp(lowercaseExtension, "7z") == 0) { } else if (strcmp(lowercaseExtension, "7z") == 0) {
un7z(filePath, outdir); returnValue = un7z(filePath, outdir);
} else { } else {
printf("Unsupported format only zip/7z/rar are supported\n"); printf("Unsupported format only zip/7z/rar are supported\n");
exit(EXIT_FAILURE); returnValue = EXIT_FAILURE;
} }
printf("Done\n"); printf("Done\n");
@@ -102,4 +110,8 @@ void addMod(const char * filePath, int appId) {
free(lowercaseExtension); free(lowercaseExtension);
free(filename); free(filename);
free(outdir); free(outdir);
exit2:
free(configFolder);
exit:
return returnValue;
} }
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef __INSTALL_H__ #ifndef __INSTALL_H__
#define __INSTALL_H__ #define __INSTALL_H__
#define INSTALLED_FLAG_FILE "__DO_NOT_REMOVE__" #define INSTALLED_FLAG_FILE "__DO_NOT_REMOVE__"
void addMod(const char * filePath, int appId); int addMod(const char * filePath, int appId);
#endif #endif
+50 -24
View File
@@ -365,17 +365,19 @@ int main(int argc, char ** argv) {
} }
gamePaths = search_games(); gamePaths = search_games();
int returnValue = EXIT_SUCCESS;
char * configFolder = g_build_filename(getHome(), MANAGER_FILES, NULL); char * configFolder = g_build_filename(getHome(), MANAGER_FILES, NULL);
if(access(configFolder, F_OK) != 0) { if(access(configFolder, F_OK) != 0) {
//check to NOT run this as root //check to NOT run this as root
//creating folder as root will causes lots of headache //creating folder as root will causes lots of headache
//such as problem with access rights and taking the risk of
//running system as root (wich is a big security issue)
if(getuid() == 0) { if(getuid() == 0) {
printf("For the first please run without sudo\n"); printf("For the first please run without sudo\n");
return EXIT_FAILURE; returnValue = EXIT_FAILURE;
goto exit;
} else { } else {
//leading 0 == octal //leading 0 == octal
int i = g_mkdir_with_parents(configFolder, 0755); int i = g_mkdir_with_parents(configFolder, 0755);
@@ -389,37 +391,61 @@ int main(int argc, char ** argv) {
free(chattrcommand); free(chattrcommand);
} }
} }
free(configFolder);
if(strcmp(argv[1], "--list-games") == 0 || strcmp(argv[1], "-l") == 0) { if(strcmp(argv[1], "--list-games") == 0 || strcmp(argv[1], "-l") == 0) {
if(isRoot()) return noRoot(); if(isRoot())
return listGames(argc, argv); returnValue = noRoot();
else
returnValue = listGames(argc, argv);
} else if(strcmp(argv[1], "--add") == 0 || strcmp(argv[1], "-a") == 0) { } else if(strcmp(argv[1], "--add") == 0 || strcmp(argv[1], "-a") == 0) {
if(isRoot()) return noRoot(); if(isRoot())
return add(argc, argv); returnValue = noRoot();
else
returnValue = add(argc, argv);
} else if(strcmp(argv[1], "--list-mods") == 0 || strcmp(argv[1], "-m") == 0) { } else if(strcmp(argv[1], "--list-mods") == 0 || strcmp(argv[1], "-m") == 0) {
if(isRoot()) return noRoot(); if(isRoot())
return listMods(argc, argv); returnValue = noRoot();
else
returnValue = listMods(argc, argv);
} else if(strcmp(argv[1], "--install") == 0 || strcmp(argv[1], "-i") == 0) { } else if(strcmp(argv[1], "--install") == 0 || strcmp(argv[1], "-i") == 0) {
if(isRoot()) return noRoot(); if(isRoot())
return installAndRemoveMod(argc, argv, true); returnValue = noRoot();
else
returnValue = installAndRemoveMod(argc, argv, true);
} else if(strcmp(argv[1], "--remove") == 0 || strcmp(argv[1], "-r") == 0) { } else if(strcmp(argv[1], "--remove") == 0 || strcmp(argv[1], "-r") == 0) {
if(isRoot()) return noRoot(); if(isRoot())
return installAndRemoveMod(argc, argv, false); returnValue = noRoot();
else
returnValue = installAndRemoveMod(argc, argv, false);
} else if(strcmp(argv[1], "--deploy") == 0 || strcmp(argv[1], "-d") == 0) { } else if(strcmp(argv[1], "--deploy") == 0 || strcmp(argv[1], "-d") == 0) {
if(!isRoot()) return needRoot(); if(!isRoot())
return deploy(argc, argv); returnValue = needRoot();
else
returnValue = deploy(argc, argv);
} else if(strcmp(argv[1], "--unbind") == 0 || strcmp(argv[1], "-u") == 0){ } else if(strcmp(argv[1], "--unbind") == 0 || strcmp(argv[1], "-u") == 0){
if(!isRoot()) return needRoot(); if(!isRoot())
return unbind(argc, argv); returnValue = needRoot();
else
returnValue = unbind(argc, argv);
} else if(strcmp(argv[1], "--setup") == 0) { } else if(strcmp(argv[1], "--setup") == 0) {
if(isRoot()) return noRoot(); if(isRoot())
return setup(argc, argv); returnValue = noRoot();
else
returnValue = setup(argc, argv);
} else { } else {
return usage(); usage();
returnValue = EXIT_FAILURE;
} }
exit:
return 0; free(configFolder);
return returnValue;
} }
+39 -19
View File
@@ -32,17 +32,17 @@ int getFiledId(const char * field) {
return FIELD_APPS; return FIELD_APPS;
} else { } else {
printf("unknown field"); printf("unknown field");
exit(EXIT_FAILURE); return -1;
} }
} }
ValveLibraries_t * parseVDF(const char * path, size_t * size) { ValveLibraries_t * parseVDF(const char * path, size_t * size, int * status) {
FILE * fd = fopen(path, "r"); FILE * fd = fopen(path, "r");
char * line = NULL; char * line = NULL;
size_t len = 0; size_t len = 0;
ssize_t read; ssize_t read;
*status = EXIT_SUCCESS;
bool inQuotes = false; bool inQuotes = false;
@@ -75,6 +75,11 @@ ValveLibraries_t * parseVDF(const char * path, size_t * size) {
buffer[bufferIndex] = '\0'; buffer[bufferIndex] = '\0';
if(nextFieldToFill == -1) { if(nextFieldToFill == -1) {
nextFieldToFill = getFiledId(buffer); nextFieldToFill = getFiledId(buffer);
if(nextFieldToFill == -1) {
if(libraries != NULL) free(libraries);
libraries = NULL;
goto exit;
}
} else { } else {
char * value = strndup(buffer, bufferIndex); char * value = strndup(buffer, bufferIndex);
@@ -137,7 +142,10 @@ ValveLibraries_t * parseVDF(const char * path, size_t * size) {
case '}': case '}':
if(inQuotes) { if(inQuotes) {
printf("Syntax error in VDF\n"); printf("Syntax error in VDF\n");
exit(EXIT_FAILURE); free(libraries);
libraries = NULL;
*status = EXIT_FAILURE;
goto exit;
} }
if(nextFieldToFill == FIELD_APPS) { if(nextFieldToFill == FIELD_APPS) {
nextFieldToFill = -1; nextFieldToFill = -1;
@@ -153,25 +161,47 @@ ValveLibraries_t * parseVDF(const char * path, size_t * size) {
} }
} }
exit:
fclose(fd); fclose(fd);
return libraries; return libraries;
} }
GHashTable* search_games() { void freeLibraries(ValveLibraries_t * libraries, int size) {
for(int i = 0; i < size; i++) {
free(libraries[i].path);
free(libraries[i].label);
free(libraries[i].contentId);
free(libraries[i].update_clean_bytes_tally);
free(libraries[i].time_last_update_corruption);
free(libraries[i].apps);
}
free(libraries);
}
GHashTable* search_games(int * status) {
ValveLibraries_t * libraries = NULL; ValveLibraries_t * libraries = NULL;
size_t size = 0; size_t size = 0;
const char * HOME = getHome(); char * home = getHome();
*status = EXIT_SUCCESS;
for(int i = 0; i < LEN(steamLibraries); i++) { for(int i = 0; i < LEN(steamLibraries); i++) {
char * path = g_build_filename(HOME, steamLibraries[i], "steamapps/libraryfolders.vdf", NULL); char * path = g_build_filename(home, steamLibraries[i], "steamapps/libraryfolders.vdf", NULL);
if (access(path, F_OK) == 0) { if (access(path, F_OK) == 0) {
libraries = parseVDF(path, &size); int parserStatus;
libraries = parseVDF(path, &size, &parserStatus);
if(parserStatus == EXIT_SUCCESS)
break; break;
} }
g_free(path); g_free(path);
} }
free(home);
if(libraries == NULL) {
*status = EXIT_FAILURE;
return NULL;
}
GHashTable* table = g_hash_table_new(g_int_hash, g_int_equal); GHashTable* table = g_hash_table_new(g_int_hash, g_int_equal);
//fill the table //fill the table
@@ -186,17 +216,7 @@ GHashTable* search_games() {
} }
} }
//free used up memory freeLibraries(libraries, size);
for(int i = 0; i < size; i++) {
free(libraries[i].path);
free(libraries[i].label);
free(libraries[i].contentId);
free(libraries[i].update_clean_bytes_tally);
free(libraries[i].time_last_update_corruption);
free(libraries[i].apps);
}
if(libraries != NULL) free(libraries);
return table; return table;
} }