/* * Copyright (C) 2020-2021 Soleta Networks * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License as published by the * Free Software Foundation; either version 3 of the License, or * (at your option) any later version. */ #include #include #include #include #include #include #include "cfg.h" #include "list.h" #include "repo.h" #include "dbi.h" static struct og_repo *og_repo_alloc(uint32_t id, const char *name, struct in_addr *addr) { struct og_repo *repo; repo = calloc(1, sizeof(struct og_repo)); if (!repo) return NULL; repo->name = strdup(name); repo->id = id; repo->addr[0] = *addr; repo->num_ips++; return repo; } static int og_repo_add_ip(struct og_repo *repo, struct in_addr *addr) { if (repo->num_ips > OG_ADDR_REPO_MAX) return -1; repo->addr[repo->num_ips++] = *addr; return 0; } static struct og_repo *og_repo_find(uint32_t id, struct list_head *repo_list) { struct og_repo *repo; list_for_each_entry(repo, repo_list, list) { if (repo->id == id) return repo; } return NULL; } int og_repo_list(struct list_head *repo_list) { const char *name, *ip; struct og_repo *repo; struct in_addr addr; const char *msglog; struct og_dbi *dbi; uint32_t id, alias; dbi_result result; dbi = og_dbi_open(&ogconfig.db); if (!dbi) { syslog(LOG_ERR, "cannot open connection database (%s:%d)\n", __func__, __LINE__); return -1; } result = dbi_conn_queryf(dbi->conn, "SELECT idrepositorio, ip, nombrerepositorio, alias " "FROM repositorios"); if (!result) { dbi_conn_error(dbi->conn, &msglog); syslog(LOG_ERR, "failed to query database (%s:%d) %s\n", __func__, __LINE__, msglog); og_dbi_close(dbi); return -1; } while (dbi_result_next_row(result)) { id = dbi_result_get_ulonglong(result, "idrepositorio"); ip = dbi_result_get_string(result, "ip"); name = dbi_result_get_string(result, "nombrerepositorio"); alias = dbi_result_get_ulonglong(result, "alias"); if (!inet_aton(ip, &addr)) { syslog(LOG_ERR, "malformed IP in repo %s\n", name); goto err_repo_list; } if (alias) id = alias; repo = og_repo_find(id, repo_list); if (repo) { if (og_repo_add_ip(repo, &addr) < 0) { syslog(LOG_ERR, "too many IPs in repo %s\n", repo->name); goto err_repo_list; } continue; } repo = og_repo_alloc(id, name, &addr); if (!repo) goto err_repo_list; list_add_tail(&repo->list, repo_list); } dbi_result_free(result); og_dbi_close(dbi); return 0; err_repo_list: og_repo_free_list(repo_list); dbi_result_free(result); og_dbi_close(dbi); return -1; } void og_repo_free_list(struct list_head *repo_list) { struct og_repo *repo, *next; list_for_each_entry_safe(repo, next, repo_list, list) { list_del(&repo->list); free((void *)repo->name); free(repo); } }