diff options
Diffstat (limited to 'dungeon.c')
-rw-r--r-- | dungeon.c | 59 |
1 files changed, 50 insertions, 9 deletions
@@ -5,20 +5,63 @@ #include <dirent.h> #include <string.h> +struct plugin_list +{ + char *name; + void *handle; + struct plugin_list *next; +}; + +struct plugin_list *plugins = NULL; +struct plugin_list **next = &plugins; + static void *load_plugin(const char *name) { + for (struct plugin_list *ptr = plugins; ptr != NULL; ptr = ptr->next) { + if (strcmp(ptr->name, name) == 0) + return ptr->handle; + } + size_t len = strlen(name); - char filename[1 + 1 + 7 + 1 + len + 1 + len + 1 + 2 + 1]; - sprintf(filename, "./plugins/%s/%s.so", name, name); - void *plugin_handle = dlmopen(LM_ID_BASE, filename, RTLD_NOW | RTLD_GLOBAL); + char dependency_file_name[1 + 1 + 7 + 1 + len + 1 + 12 + 1 + 3 + 1]; + sprintf(dependency_file_name, "./plugins/%s/dependencies.txt", name); + + FILE *dependency_file = fopen(dependency_file_name, "r"); + + if (dependency_file) { + char dependency[BUFSIZ]; + + while (fscanf(dependency_file, "%s", dependency) != EOF) + load_plugin(dependency); - if (! plugin_handle) { + fclose(dependency_file); + } + + char library_name[1 + 1 + 7 + 1 + len + 1 + len + 1 + 2 + 1]; + sprintf(library_name, "./plugins/%s/%s.so", name, name); + + void *handle = dlmopen(LM_ID_BASE, library_name, RTLD_NOW | RTLD_GLOBAL); + + if (! handle) { printf("%s\n", dlerror()); exit(EXIT_FAILURE); } - return plugin_handle; + char *namebuf = malloc(len + 1); + strcpy(namebuf, name); + + *next = malloc(sizeof(struct plugin_list)); + **next = (struct plugin_list) { + .name = namebuf, + .handle = handle, + .next = NULL, + }; + next = &(*next)->next; + + printf("Loaded %s\n", name); + + return handle; } int main() @@ -30,11 +73,9 @@ int main() struct dirent *dp; - while (dp = readdir(dir)) { - if (dp->d_name[0] != '.' && strcmp(dp->d_name, "game") != 0) { + while (dp = readdir(dir)) + if (dp->d_name[0] != '.') load_plugin(dp->d_name); - } - } closedir(dir); |