untested bug fix

This commit is contained in:
Marc
2022-10-03 21:23:10 +02:00
parent e2429fee05
commit aaf3b9527e
6 changed files with 142 additions and 107 deletions
+73 -99
View File
@@ -1,4 +1,3 @@
#include "fomod.h"
#include <libxml/tree.h> #include <libxml/tree.h>
#include <libxml/parser.h> #include <libxml/parser.h>
#include <libxml/xmlstring.h> #include <libxml/xmlstring.h>
@@ -8,11 +7,12 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <dirent.h> #include <dirent.h>
#include <glib.h>
#include <stdarg.h> #include <stdarg.h>
#include <unistd.h>
#include "fomod.h"
#include "file.h" #include "file.h"
#include "libxml/globals.h" #include "libxml/globals.h"
#include "fomod/parser.h"
int getInputCount(const char * input) { int getInputCount(const char * input) {
char buff[2]; char buff[2];
@@ -47,39 +47,6 @@ gint priorityCmp(gconstpointer a, gconstpointer b) {
return fileA->priority - fileB->priority; return fileA->priority - fileB->priority;
} }
char * findFOModFolder(const char * modFolder) {
struct dirent * dir;
DIR *d = opendir(modFolder);
if (d) {
while ((dir = readdir(d)) != NULL) {
if(g_ascii_strcasecmp(dir->d_name, "fomod") == 0) {
char * fomodDir = g_build_path("/", modFolder, dir->d_name, NULL);
closedir(d);
return fomodDir;
}
}
closedir(d);
}
return NULL;
}
char * findFOModFile(const char * fomodFolder) {
struct dirent * dir;
DIR *d = opendir(fomodFolder);
if (d) {
while ((dir = readdir(d)) != NULL) {
if(g_ascii_strcasecmp(dir->d_name, "moduleconfig.xml") == 0) {
char * fomodFile = g_build_filename(fomodFolder, dir->d_name, NULL);
closedir(d);
return fomodFile;
}
}
closedir(d);
}
return NULL;
}
void printfOptionsInOrder(FOModGroup_t group) { void printfOptionsInOrder(FOModGroup_t group) {
for(int i = 0; i < group.pluginCount; i++) { for(int i = 0; i < group.pluginCount; i++) {
printf("%d, %s\n", i, group.plugins[i].name); printf("%d, %s\n", i, group.plugins[i].name);
@@ -152,18 +119,75 @@ void sortGroup(FOModGroup_t * group) {
} }
} }
//TODO: support priority //TODO: handle error
int installFOMod(const char * modFolder, const char * destination) { int processFileOperations(GList * pendingFileOperations, const char * modFolder, const char * destination) {
char * fomodFolder = findFOModFolder(modFolder); pendingFileOperations = g_list_sort(pendingFileOperations, priorityCmp);
if(fomodFolder == NULL) { GList * currentFileOperation = pendingFileOperations;
fprintf(stderr, "Fomod folder not found, are you sure this is a fomod mod ?\n");
return EXIT_FAILURE; while(currentFileOperation != NULL) {
//TODO: support destination
//no using link since priority is made to override files and link is annoying to deal with when overriding files.
const FOModFile_t * file = (const FOModFile_t *)currentFileOperation->data;
char * source = g_build_path("/", modFolder, file->source, NULL);
//fix the / and \ windows - unix paths
fixPath(source);
int copyResult;
if(file->isFolder) {
copyResult = copy(source, destination, CP_NO_TARGET_DIR | CP_RECURSIVE);
} else {
copyResult = copy(source, destination, 0);
}
if(copyResult != EXIT_SUCCESS) {
fprintf(stderr, "Copy failed, some file might be corrupted\n");
}
printf("source: %s, destination: %s\n", source, destination);
g_free(source);
currentFileOperation = g_list_next(currentFileOperation);
}
return EXIT_SUCCESS;
} }
char * fomodFile = findFOModFile(fomodFolder); GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendingFileOperations) {
if(fomodFile == NULL) { for(int condId = 0; condId < fomod->condFilesCount; condId++) {
const FOModCondFile_t *condFile = &fomod->condFiles[condId];
bool areAllFlagsValid = true;
//checking if all flags are valid
for(int flagId = 0; flagId < condFile->flagCount; flagId++) {
const GList * link = g_list_find_custom(flagList, &(condFile->requiredFlags[flagId]), (GCompareFunc)flagEqual);
if(link == NULL) {
areAllFlagsValid = false;
break;
}
}
if(areAllFlagsValid) {
for(int fileId = 0; fileId < condFile->flagCount; fileId++) {
const FOModFile_t * file = &(condFile->files[fileId]);
FOModFile_t * fileCopy = malloc(sizeof(*file));
*fileCopy = *file;
pendingFileOperations = g_list_append(pendingFileOperations, fileCopy);
}
}
}
return pendingFileOperations;
}
int installFOMod(const char * modFolder, const char * destination) {
//everything should be lowercase since we use casefold() before calling any install function
char * fomodFolder = g_build_path("/", modFolder, "fomod", NULL);
char * fomodFile = g_build_filename(fomodFolder, "moduleconfig.xml", NULL);
if(access(fomodFile, F_OK) != 0) {
fprintf(stderr, "FOMod file not found, are you sure this is a fomod mod ?\n"); fprintf(stderr, "FOMod file not found, are you sure this is a fomod mod ?\n");
g_free(fomodFolder); g_free(fomodFolder);
g_free(fomodFile);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -172,6 +196,7 @@ int installFOMod(const char * modFolder, const char * destination) {
if(returnValue != EXIT_SUCCESS) { if(returnValue != EXIT_SUCCESS) {
return returnValue; return returnValue;
} }
g_free(fomodFile);
GList * flagList = NULL; GList * flagList = NULL;
GList * pendingFileOperations = NULL; GList * pendingFileOperations = NULL;
@@ -179,7 +204,7 @@ int installFOMod(const char * modFolder, const char * destination) {
sortSteps(&fomod); sortSteps(&fomod);
for(int i = 0; i < fomod.stepCount; i++) { for(int i = 0; i < fomod.stepCount; i++) {
FOModStep_t * step = &fomod.steps[i]; const FOModStep_t * step = &fomod.steps[i];
bool validFlags = true; bool validFlags = true;
for(int flagId = 0; flagId < step->flagCount; flagId++) { for(int flagId = 0; flagId < step->flagCount; flagId++) {
@@ -280,66 +305,15 @@ int installFOMod(const char * modFolder, const char * destination) {
} }
} }
for(int condId = 0; condId < fomod.condFilesCount; condId++) {
const FOModCondFile_t *condFile = &fomod.condFiles[condId];
bool areAllFlagsValid = true;
//checking if all flags are valid
for(int flagId = 0; flagId < condFile->flagCount; flagId++) {
const GList * link = g_list_find_custom(flagList, &(condFile->requiredFlags[flagId]), (GCompareFunc)flagEqual);
if(link == NULL) {
areAllFlagsValid = false;
break;
}
}
if(areAllFlagsValid) {
for(int fileId = 0; fileId < condFile->flagCount; fileId++) {
const FOModFile_t * file = &(condFile->files[fileId]);
FOModFile_t * fileCopy = malloc(sizeof(*file));
*fileCopy = *file;
pendingFileOperations = g_list_append(pendingFileOperations, fileCopy);
}
}
}
pendingFileOperations = g_list_sort(pendingFileOperations, priorityCmp);
GList * currentFileOperation = pendingFileOperations;
while(currentFileOperation != NULL) {
//TODO: support destination
//TODO: handle error
//no using link since priority is made to override files and link is annoying to deal with when overriding files.
const FOModFile_t * file = (const FOModFile_t *)currentFileOperation->data;
char * source = g_build_path("/", modFolder, file->source, NULL);
//fix the / and \ windows - unix paths
fixPath(source);
int copyResult;
if(file->isFolder) {
copyResult = copy(source, destination, CP_NO_TARGET_DIR | CP_RECURSIVE);
} else {
copyResult = copy(source, destination, 0);
}
if(copyResult != EXIT_SUCCESS) {
fprintf(stderr, "Copy failed, some file might be corrupted\n");
}
printf("source: %s, destination: %s\n", source, destination);
g_free(source);
currentFileOperation = g_list_next(currentFileOperation);
}
pendingFileOperations = processCondFiles(&fomod, flagList, pendingFileOperations);
processFileOperations(pendingFileOperations, modFolder, destination);
printf("FOMod successfully installed!\n"); printf("FOMod successfully installed!\n");
g_list_free(flagList); g_list_free(flagList);
g_list_free_full(pendingFileOperations, free); g_list_free_full(pendingFileOperations, free);
freeFOMod(&fomod); freeFOMod(&fomod);
g_free(fomodFolder);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
+32 -1
View File
@@ -2,10 +2,41 @@
#define __FOMOD_H__ #define __FOMOD_H__
#include <stdbool.h> #include <stdbool.h>
#include <glib.h>
#include "fomod/parser.h"
#include "fomod/group.h" #include "fomod/group.h"
#include "fomod/xmlUtil.h" #include "fomod/xmlUtil.h"
/**
* @brief Start a terminal based install process for fomod.
*
* @param modFolder folder of the fomod file.
* @param destination folder of the new mod that contains the result of the fomod process.
* @return int
*/
int installFOMod(const char * modFolder, const char * destination); int installFOMod(const char * modFolder, const char * destination);
/**
* @brief In fomod there is file operations which depends on multiple flags this function find the ones that mach our current flags and append them to a list.
*
* @param fomod a pointer to a fomod obtained by the parser
* @param flagList a FOModFlag_t list which contains all of the flag found.
* @param pendingFileOperations a list of pending FOModFile_t operation to which add the new ones. (can be null)
* @return a list of pendingFileOperations(FOModFile_t)
*/
GList * processCondFiles(const FOMod_t * fomod, GList * flagList, GList * pendingFileOperations) __attribute__((warn_unused_result));
/**
* @brief FOModFile_t have a priority option and this function execute the file operation while taking this into account.
*
* @param pendingFileOperations list of FOModFile_t to process
* @param modFolder folder of the fomod file.
* @param destination folder of the new mod that contains the result of the process.
* @return error code
*/
int processFileOperations(GList * pendingFileOperations, const char * modFolder, const char * destination);
#endif #endif
+6 -3
View File
@@ -2,6 +2,7 @@
#include "libxml/tree.h" #include "libxml/tree.h"
#include "xmlUtil.h" #include "xmlUtil.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
//Maybe integrate this into the rest of the code instead of freeing after the fact //Maybe integrate this into the rest of the code instead of freeing after the fact
void freeFOMod(FOMod_t * fomod) { void freeFOMod(FOMod_t * fomod) {
@@ -21,11 +22,10 @@ void freeFOMod(FOMod_t * fomod) {
free(condFile->requiredFlags); free(condFile->requiredFlags);
} }
free(fomod->condFiles); free(fomod->condFiles);
free(fomod->moduleImage); free(fomod->moduleImage);
free(fomod->moduleName); free(fomod->moduleName);
int size = countUntilNull(fomod->requiredInstallFiles); int size = countUntilNull(fomod->requiredInstallFiles, sizeof(char **));
for(int i = 0; i < size; i++) { for(int i = 0; i < size; i++) {
free(fomod->requiredInstallFiles[i]); free(fomod->requiredInstallFiles[i]);
} }
@@ -46,6 +46,9 @@ void freeFOMod(FOMod_t * fomod) {
free(step->requiredFlags); free(step->requiredFlags);
free(step->name); free(step->name);
} }
//set every counter to zero and every pointer to null
memset(fomod, 0, sizeof(FOMod_t));
} }
int parseVisibleNode(xmlNodePtr node, FOModStep_t * step) { int parseVisibleNode(xmlNodePtr node, FOModStep_t * step) {
@@ -285,7 +288,7 @@ int parseFOMod(const char * fomodFile, FOMod_t* fomod) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int size = countUntilNull(fomod->requiredInstallFiles) + 2; int size = countUntilNull(fomod->requiredInstallFiles, sizeof(char **)) + 2;
fomod->requiredInstallFiles = realloc(fomod->requiredInstallFiles, sizeof(char *) * size); fomod->requiredInstallFiles = realloc(fomod->requiredInstallFiles, sizeof(char *) * size);
//ensure it is null terminated //ensure it is null terminated
fomod->requiredInstallFiles[size - 1] = NULL; fomod->requiredInstallFiles[size - 1] = NULL;
+12
View File
@@ -25,7 +25,19 @@ typedef struct FOMod {
int condFilesCount; int condFilesCount;
} FOMod_t; } FOMod_t;
/**
* @brief parse a fomod xml file (found inside the mod folder /fomod/moduleconfig.xml (everything should be lowercase))
*
* @param fomodFile path to the moduleconfig.xml
* @param fomod pointer to a new FOMod_t
* @return error code.
*/
int parseFOMod(const char * fomodFile, FOMod_t* fomod); int parseFOMod(const char * fomodFile, FOMod_t* fomod);
/**
* @brief Free content of a fomod file.
* @param fomod
*/
void freeFOMod(FOMod_t * fomod); void freeFOMod(FOMod_t * fomod);
#endif #endif
+2 -2
View File
@@ -27,10 +27,10 @@ void fixPath(char * path) {
} }
} }
int countUntilNull(void * pointers) { int countUntilNull(void * pointers, size_t typeSize) {
int i = 0; int i = 0;
while(pointers != NULL) { while(pointers != NULL) {
pointers++; pointers += typeSize;
i++; i++;
} }
return i; return i;
+16 -1
View File
@@ -8,9 +8,24 @@
typedef enum FOModOrder { ASC, DESC, ORD } FOModOrder_t; typedef enum FOModOrder { ASC, DESC, ORD } FOModOrder_t;
bool validateNode(xmlNodePtr * node, bool skipText, const char * names, ...); bool validateNode(xmlNodePtr * node, bool skipText, const char * names, ...);
/**
* @brief Free memory of and xmlChar and return a strdup version. just to make sure there is nothing remaining in libxml
*/
char * freeAndDup(xmlChar * line); char * freeAndDup(xmlChar * line);
FOModOrder_t getFOModOrder(const char * order); FOModOrder_t getFOModOrder(const char * order);
/**
* @brief replace / by \
* @param path
*/
void fixPath(char * path); void fixPath(char * path);
int countUntilNull(void * pointers);
/**
* @brief Count the number of step before null
*
* @param pointers pointer to the list
* @param typeSize size of each element of the list
* @return size
*/
int countUntilNull(void * pointers, size_t typeSize);
#endif #endif