#include "config.h" #include "mod.h" #include "semver.h" #include "util.h" #include #include #include #include #include #include #include #include #include #include static const char *PNAME = "modfetch"; static const semver VERSION = { .major = 0, .minor = 1, .patch = 0, }; int main(int argc, char *argv[]) { char *config_path; char *config_dir = getenv("XDG_CONFIG_HOME"); if (config_dir == NULL) { char *home = getenv("$HOME"); if (asprintf(&config_dir, "%s/.config", home) < 0) { fprintf(stderr, "error: failed formatting config dir (this shouldn't happen)"); exit(EXIT_FAILURE); } } if (asprintf(&config_path, "%s/modfetch.conf", config_dir) < 0) { fprintf(stderr, "error: failed formatting config path (this shouldn't happen)"); exit(EXIT_FAILURE); } for (size_t i = 1; i < (size_t)argc; ++i) { if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--config") == 0) { if (i == (size_t)argc - 1) { fprintf(stderr, "error: no config path passed\n"); exit(EXIT_FAILURE); } i += 1; config_path = argv[i]; continue; } if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { fprintf(stderr, "%s: modular fetch [%s]\n", PNAME, svtoa(VERSION)); fprintf(stderr, "\n"); fprintf(stderr, "OPTIONS\n"); fprintf(stderr, "\t-h, --help\t\t\tdisplays this help text\n"); fprintf(stderr, "\t-c, --config /path/to/config\tchanges config path from the default ($XDG_CONFIG_HOME/%s.conf)\n", PNAME); exit(EXIT_SUCCESS); } } FILE *config_file = fopen(config_path, "r"); if (config_file == NULL) { fprintf(stderr, "error: failed to open config at: %s\n", config_path); exit(EXIT_FAILURE); } Config config = parse_config(config_file); fclose(config_file); free(config_path); for (size_t i = 0; i < config.module_count; ++i) { Module current_module = config.modules[i]; void *handle = dlopen(current_module.path, RTLD_NOW); if (handle == NULL) { fprintf(stderr, "error: failed opening module %s\n", current_module.path); fprintf(stderr, "%s\n", dlerror()); exit(EXIT_FAILURE); } dlerror(); // stupid fucking c standard issue // I'm not fixing this // https://stackoverflow.com/questions/14134245/iso-c-void-and-function-pointers #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpedantic" semver (*mod_version)(void) = dlsym(handle, "version"); const char *(*mod_name)(void) = dlsym(handle, "name"); const char *(*mod_get)(void) = dlsym(handle, "get"); void (*mod_init)(semver, char**) = dlsym(handle, "init"); #pragma GCC diagnostic pop mod_init(API_VERSION, current_module.config); (void)mod_name; (void)mod_version; // printf("%s: %s\n", mod_name(), svtoa(mod_version())); printf("%s\n", mod_get()); } return 0; }