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
+29 -17
View File
@@ -9,36 +9,41 @@
//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);
if(system(unzipCommand) != 0) {
printf("\nFailed to unzip archive\n");
exit(EXIT_FAILURE);
returnValue = EXIT_FAILURE;
}
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);
if(system(unrarCommand) != 0) {
printf("Failed to unzip archive\n");
exit(EXIT_FAILURE);
returnValue = EXIT_FAILURE;
}
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);
if(system(un7zCommand) != 0) {
printf("Failed to unzip archive\n");
exit(EXIT_FAILURE);
returnValue = EXIT_FAILURE;
}
free(un7zCommand);
return returnValue;
}
char * extractLastPart(const char * filePath, const char delimeter) {
int length = strlen(filePath);
int length = strlen(filePath);
int index = -1;
for(int i= length -1; i >= 0; i--) {
if(filePath[i] == 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));
memcpy(extension, &filePath[index], (length - index));
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) {
printf("File not found\n");
exit(EXIT_FAILURE);
returnValue = EXIT_FAILURE;
goto exit;
}
char * configFolder = g_build_filename(getenv("HOME"), MANAGER_FILES, NULL);
if(g_mkdir_with_parents(configFolder, 0755) < 0) {
printf("Could not create mod folder");
exit(EXIT_FAILURE);
returnValue = EXIT_FAILURE;
goto exit2;
}
char * filename = extractFileName(filePath);
@@ -80,21 +89,20 @@ void addMod(const char * filePath, int appId) {
free(extension);
char appIdStr[20];
sprintf(appIdStr, "%d", appId);
char * outdir = g_build_filename(configFolder, MOD_FOLDER_NAME, appIdStr, filename, NULL);
g_mkdir_with_parents(outdir, 0755);
printf("Adding mod, this process can be slow depending on your hardware\n");
if(strcmp(lowercaseExtension, "rar") == 0) {
unrar(filePath, outdir);
returnValue = unrar(filePath, outdir);
} else if (strcmp(lowercaseExtension, "zip") == 0) {
unzip(filePath, outdir);
returnValue = unzip(filePath, outdir);
} else if (strcmp(lowercaseExtension, "7z") == 0) {
un7z(filePath, outdir);
returnValue = un7z(filePath, outdir);
} else {
printf("Unsupported format only zip/7z/rar are supported\n");
exit(EXIT_FAILURE);
returnValue = EXIT_FAILURE;
}
printf("Done\n");
@@ -102,4 +110,8 @@ void addMod(const char * filePath, int appId) {
free(lowercaseExtension);
free(filename);
free(outdir);
exit2:
free(configFolder);
exit:
return returnValue;
}
+1 -1
View File
@@ -1,6 +1,6 @@
#ifndef __INSTALL_H__
#define __INSTALL_H__
#define INSTALLED_FLAG_FILE "__DO_NOT_REMOVE__"
void addMod(const char * filePath, int appId);
int addMod(const char * filePath, int appId);
#endif
+50 -24
View File
@@ -365,17 +365,19 @@ int main(int argc, char ** argv) {
}
gamePaths = search_games();
int returnValue = EXIT_SUCCESS;
char * configFolder = g_build_filename(getHome(), MANAGER_FILES, NULL);
if(access(configFolder, F_OK) != 0) {
//check to NOT run this as root
//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) {
printf("For the first please run without sudo\n");
return EXIT_FAILURE;
returnValue = EXIT_FAILURE;
goto exit;
} else {
//leading 0 == octal
int i = g_mkdir_with_parents(configFolder, 0755);
@@ -389,37 +391,61 @@ int main(int argc, char ** argv) {
free(chattrcommand);
}
}
free(configFolder);
if(strcmp(argv[1], "--list-games") == 0 || strcmp(argv[1], "-l") == 0) {
if(isRoot()) return noRoot();
return listGames(argc, argv);
if(isRoot())
returnValue = noRoot();
else
returnValue = listGames(argc, argv);
} else if(strcmp(argv[1], "--add") == 0 || strcmp(argv[1], "-a") == 0) {
if(isRoot()) return noRoot();
return add(argc, argv);
if(isRoot())
returnValue = noRoot();
else
returnValue = add(argc, argv);
} else if(strcmp(argv[1], "--list-mods") == 0 || strcmp(argv[1], "-m") == 0) {
if(isRoot()) return noRoot();
return listMods(argc, argv);
if(isRoot())
returnValue = noRoot();
else
returnValue = listMods(argc, argv);
} else if(strcmp(argv[1], "--install") == 0 || strcmp(argv[1], "-i") == 0) {
if(isRoot()) return noRoot();
return installAndRemoveMod(argc, argv, true);
if(isRoot())
returnValue = noRoot();
else
returnValue = installAndRemoveMod(argc, argv, true);
} else if(strcmp(argv[1], "--remove") == 0 || strcmp(argv[1], "-r") == 0) {
if(isRoot()) return noRoot();
return installAndRemoveMod(argc, argv, false);
if(isRoot())
returnValue = noRoot();
else
returnValue = installAndRemoveMod(argc, argv, false);
} else if(strcmp(argv[1], "--deploy") == 0 || strcmp(argv[1], "-d") == 0) {
if(!isRoot()) return needRoot();
return deploy(argc, argv);
if(!isRoot())
returnValue = needRoot();
else
returnValue = deploy(argc, argv);
} else if(strcmp(argv[1], "--unbind") == 0 || strcmp(argv[1], "-u") == 0){
if(!isRoot()) return needRoot();
return unbind(argc, argv);
if(!isRoot())
returnValue = needRoot();
else
returnValue = unbind(argc, argv);
} else if(strcmp(argv[1], "--setup") == 0) {
if(isRoot()) return noRoot();
return setup(argc, argv);
if(isRoot())
returnValue = noRoot();
else
returnValue = setup(argc, argv);
} else {
return usage();
usage();
returnValue = EXIT_FAILURE;
}
return 0;
exit:
free(configFolder);
return returnValue;
}
+39 -19
View File
@@ -32,17 +32,17 @@ int getFiledId(const char * field) {
return FIELD_APPS;
} else {
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");
char * line = NULL;
size_t len = 0;
ssize_t read;
*status = EXIT_SUCCESS;
bool inQuotes = false;
@@ -75,6 +75,11 @@ ValveLibraries_t * parseVDF(const char * path, size_t * size) {
buffer[bufferIndex] = '\0';
if(nextFieldToFill == -1) {
nextFieldToFill = getFiledId(buffer);
if(nextFieldToFill == -1) {
if(libraries != NULL) free(libraries);
libraries = NULL;
goto exit;
}
} else {
char * value = strndup(buffer, bufferIndex);
@@ -137,7 +142,10 @@ ValveLibraries_t * parseVDF(const char * path, size_t * size) {
case '}':
if(inQuotes) {
printf("Syntax error in VDF\n");
exit(EXIT_FAILURE);
free(libraries);
libraries = NULL;
*status = EXIT_FAILURE;
goto exit;
}
if(nextFieldToFill == FIELD_APPS) {
nextFieldToFill = -1;
@@ -153,25 +161,47 @@ ValveLibraries_t * parseVDF(const char * path, size_t * size) {
}
}
exit:
fclose(fd);
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;
size_t size = 0;
const char * HOME = getHome();
char * home = getHome();
*status = EXIT_SUCCESS;
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) {
libraries = parseVDF(path, &size);
int parserStatus;
libraries = parseVDF(path, &size, &parserStatus);
if(parserStatus == EXIT_SUCCESS)
break;
}
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);
//fill the table
@@ -186,17 +216,7 @@ GHashTable* search_games() {
}
}
//free used up memory
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);
freeLibraries(libraries, size);
return table;
}