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:
+78
-66
@@ -9,97 +9,109 @@
|
||||
|
||||
//TODO: replace ALL system call by execv / execl since it make my code into swiss cheese
|
||||
|
||||
void unzip(const char * path, const char * outdir) {
|
||||
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);
|
||||
}
|
||||
free(unzipCommand);
|
||||
|
||||
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");
|
||||
returnValue = EXIT_FAILURE;
|
||||
}
|
||||
free(unzipCommand);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void unrar(const char * path, const char * outdir) {
|
||||
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);
|
||||
}
|
||||
free(unrarCommand);
|
||||
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");
|
||||
returnValue = EXIT_FAILURE;
|
||||
}
|
||||
free(unrarCommand);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void un7z(const char * path, const char * outdir) {
|
||||
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);
|
||||
}
|
||||
free(un7zCommand);
|
||||
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");
|
||||
returnValue = EXIT_FAILURE;
|
||||
}
|
||||
free(un7zCommand);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
char * extractLastPart(const char * filePath, const char delimeter) {
|
||||
int length = strlen(filePath);
|
||||
int index = -1;
|
||||
for(int i= length -1; i >= 0; i--) {
|
||||
if(filePath[i] == delimeter) {
|
||||
index = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int length = strlen(filePath);
|
||||
int index = -1;
|
||||
for(int i= length -1; i >= 0; i--) {
|
||||
if(filePath[i] == delimeter) {
|
||||
index = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(index <= 0) return NULL;
|
||||
char * extension = malloc((length - index) * sizeof(char));
|
||||
memcpy(extension, &filePath[index], (length - index));
|
||||
return extension;
|
||||
if(index <= 0 || index == length) return NULL;
|
||||
char * extension = malloc((length - index) * sizeof(char));
|
||||
memcpy(extension, &filePath[index], (length - index));
|
||||
return extension;
|
||||
}
|
||||
|
||||
char * extractExtension(const char * filePath) {
|
||||
return extractLastPart(filePath, '.');
|
||||
return extractLastPart(filePath, '.');
|
||||
}
|
||||
|
||||
char * extractFileName(const char * filePath) {
|
||||
return extractLastPart(filePath, '/');
|
||||
return extractLastPart(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);
|
||||
printf("File not found\n");
|
||||
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) {
|
||||
printf("Could not create mod folder");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("Could not create mod folder");
|
||||
returnValue = EXIT_FAILURE;
|
||||
goto exit2;
|
||||
}
|
||||
|
||||
char * filename = extractFileName(filePath);
|
||||
char * extension = extractExtension(filename);
|
||||
char * lowercaseExtension = g_ascii_strdown(extension, -1);
|
||||
free(extension);
|
||||
char * filename = extractFileName(filePath);
|
||||
char * extension = extractExtension(filename);
|
||||
char * lowercaseExtension = g_ascii_strdown(extension, -1);
|
||||
free(extension);
|
||||
|
||||
char appIdStr[20];
|
||||
sprintf(appIdStr, "%d", appId);
|
||||
char appIdStr[20];
|
||||
|
||||
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);
|
||||
printf("Adding mod, this process can be slow depending on your hardware\n");
|
||||
if(strcmp(lowercaseExtension, "rar") == 0) {
|
||||
unrar(filePath, outdir);
|
||||
} else if (strcmp(lowercaseExtension, "zip") == 0) {
|
||||
unzip(filePath, outdir);
|
||||
} else if (strcmp(lowercaseExtension, "7z") == 0) {
|
||||
un7z(filePath, outdir);
|
||||
} else {
|
||||
printf("Unsupported format only zip/7z/rar are supported\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
g_mkdir_with_parents(outdir, 0755);
|
||||
printf("Adding mod, this process can be slow depending on your hardware\n");
|
||||
if(strcmp(lowercaseExtension, "rar") == 0) {
|
||||
returnValue = unrar(filePath, outdir);
|
||||
} else if (strcmp(lowercaseExtension, "zip") == 0) {
|
||||
returnValue = unzip(filePath, outdir);
|
||||
} else if (strcmp(lowercaseExtension, "7z") == 0) {
|
||||
returnValue = un7z(filePath, outdir);
|
||||
} else {
|
||||
printf("Unsupported format only zip/7z/rar are supported\n");
|
||||
returnValue = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Done\n");
|
||||
printf("Done\n");
|
||||
|
||||
free(lowercaseExtension);
|
||||
free(filename);
|
||||
free(outdir);
|
||||
free(lowercaseExtension);
|
||||
free(filename);
|
||||
free(outdir);
|
||||
exit2:
|
||||
free(configFolder);
|
||||
exit:
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
+40
-20
@@ -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);
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user