// clang-format off /* * pooler | MatterLinux pool server * MatterLinux 2023-2024 (https://matterlinux.xyz) * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // clang-format on #include #include #include #include #include #include #include #include #include "config.h" #include "intl.h" #include "log.h" bool sync_callback( lm_ctx_t *ctx, lm_pool_t *pool, lm_ctx_sync_state_t state, size_t current, size_t total, void *data) { switch (state) { case SYNC_INFO_SUCCESS: log_info(_("%s: successfuly loaded the pool info"), pool->name); break; case SYNC_INFO_FAIL: log_info(_("%s: failed to load the pool info (%s)"), pool->name, lm_strerror()); return false; case SYNC_LIST_SUCCESS: log_info(_("%s: successfuly loaded the package list"), pool->name); break; case SYNC_LIST_FAIL: log_info(_("%s: failed to load the package list (%s)"), pool->name, lm_strerror()); return false; default: // ignore other callbacks break; } return true; } int main(int argc, char *argv[]) { if (argc != 2) { log_error(_("Configuration file not specified")); return EXIT_FAILURE; } char *poolsdir = NULL, *addr = NULL, *logfile = NULL; int ret = EXIT_FAILURE; pool_config_t *pool = NULL; size_t pool_count = 0; lm_ctx_t ctx; lm_ctx_init(&ctx); if (!config_load(argv[1])) goto end; if ((logfile = config_get_string("log")) != NULL) { FILE *log = fopen(logfile, "r"); if (NULL == log) log_error(_("Failed to open the log file: %s"), strerror(errno)); else { dup2(fileno(log), STDERR_FILENO); dup2(fileno(log), STDOUT_FILENO); fclose(log); } } addr = config_get_string("addr"); if (config_get_integer("threads") <= 0 || config_get_integer("threads") > 1000) { log_error(_("Please specify a valid thread count (1-1000)")); goto end; } if ((poolsdir = config_get_string("dir")) == NULL) { log_error(_("Pool directory not specified")); goto end; } if (!exists(poolsdir) && !can_read(poolsdir)) { log_error(_("Cannot access to the pool directory: %s"), poolsdir); goto end; } if ((pool = config.pools) == NULL) { log_error(_("Please specify at least one pool in the configuration")); goto end; } if (!lm_ctx_set_data(&ctx, poolsdir)) { log_error(_("Failed to use pool directory: %s"), lm_strerror()); goto end; } while (NULL != pool) { if (NULL == pool->host) { log_error(_("Hostname not specified for pool, skipping: %s")); goto end; } char url[strlen(pool->host) + 20]; sprintf(url, "mptp://%s", pool->host); if (NULL == lm_ctx_pool_add(&ctx, pool->name, url)) { log_error(_("Failed to add pool to the list: %s"), lm_strerror()); goto end; } pool = pool->next; } if ((pool_count = lm_ctx_sync(&ctx, false, sync_callback, NULL)) < 0) { log_error(_("Failed to sync the pools: %s"), lm_strerror()); goto end; } if (pool_count == 0) { log_error(_("None of the pools is available for serving")); goto end; } log_info(pool_count == 1 ? _("Serving %lu pool on %s") : _("Serving %lu pools on %s"), pool_count, addr); if (!lm_ctx_serve(&ctx, addr, config_get_integer("threads"))) { log_error(_("Failed to start the server: %s"), lm_strerror()); goto end; } ret = EXIT_SUCCESS; end: lm_ctx_free(&ctx); config_free(); return ret; }