src/libpakfire/key.c \
src/libpakfire/linter.c \
src/libpakfire/logging.c \
+ src/libpakfire/mirror.c \
+ src/libpakfire/mirrorlist.c \
src/libpakfire/mount.c \
src/libpakfire/package.c \
src/libpakfire/packager.c \
src/libpakfire/include/pakfire/key.h \
src/libpakfire/include/pakfire/linter.h \
src/libpakfire/include/pakfire/logging.h \
+ src/libpakfire/include/pakfire/mirror.h \
+ src/libpakfire/include/pakfire/mirrorlist.h \
src/libpakfire/include/pakfire/mount.h \
src/libpakfire/include/pakfire/package.h \
src/libpakfire/include/pakfire/packager.h \
#include <pakfire/i18n.h>
#include <pakfire/linter.h>
#include <pakfire/logging.h>
+#include <pakfire/mirror.h>
+#include <pakfire/mirrorlist.h>
#include <pakfire/package.h>
#include <pakfire/packager.h>
#include <pakfire/pakfire.h>
static int pakfire_dist_get_mirrorlist(struct pakfire* pakfire,
struct pakfire_parser* makefile, struct pakfire_mirrorlist** list) {
+ struct pakfire_ctx* ctx = pakfire_ctx(pakfire);
struct pakfire_mirrorlist* m = NULL;
+ struct pakfire_mirror* mirror = NULL;
char* p = NULL;
int r;
return 0;
// Create mirrorlist
- r = pakfire_mirrorlist_create(&m, pakfire);
+ r = pakfire_mirrorlist_create(&m, ctx);
if (r) {
ERROR(pakfire, "Could not create the mirrorlist\n");
goto ERROR;
}
// Add all mirrors
- const char* mirror = strtok_r(source_dl, " ", &p);
- while (mirror) {
+ const char* url = strtok_r(source_dl, " ", &p);
+ while (url) {
+ // Create a new mirror
+ r = pakfire_mirror_create(&mirror, ctx, url);
+ if (r)
+ goto ERROR;
+
+ // Add the mirror to the mirrorlist
r = pakfire_mirrorlist_add_mirror(m, mirror);
+ pakfire_mirror_unref(mirror);
if (r)
goto ERROR;
- mirror = strtok_r(NULL, " ", &p);
+ url = strtok_r(NULL, " ", &p);
}
// Success
ERROR:
if (m)
pakfire_mirrorlist_unref(m);
+ if (ctx)
+ pakfire_ctx_unref(ctx);
if (source_dl)
free(source_dl);
#include <pakfire/string.h>
#include <pakfire/util.h>
-// Retry a mirror up to N times before marking it as broken
-#define MIRROR_RETRIES 3
-
// The number of concurrent downloads
#define MAX_PARALLEL 4
-struct pakfire_mirror {
- STAILQ_ENTRY(pakfire_mirror) nodes;
-
- char url[PATH_MAX];
-
- unsigned int retries_left;
- int broken;
-};
-
struct pakfire_transfer {
struct pakfire* pakfire;
int nrefs;
struct pakfire* pakfire;
int nrefs;
-// struct pakfire_progress* progress;
unsigned int parallel;
// cURL multi handle
if (transfer->evp)
EVP_MD_CTX_free(transfer->evp);
+ if (transfer->mirror)
+ pakfire_mirror_unref(transfer->mirror);
if (transfer->mirrors)
pakfire_mirrorlist_unref(transfer->mirrors);
if (transfer->progress)
struct pakfire_transfer* transfer) {
// Choose the next mirror
if (transfer->mirror)
- transfer->mirror = STAILQ_NEXT(transfer->mirror, nodes);
+ transfer->mirror = pakfire_mirrorlist_get_next(transfer->mirrors, transfer->mirror);
// If no mirror has been selected yet, choose the first one
else
- transfer->mirror = pakfire_mirrorlist_first(transfer->mirrors);
+ transfer->mirror = pakfire_mirrorlist_get_first(transfer->mirrors);
// Skip this mirror if it is broken
- while (transfer->mirror && transfer->mirror->broken) {
+ while (transfer->mirror && pakfire_mirror_is_broken(transfer->mirror)) {
// Move on to the next mirror
- transfer->mirror = STAILQ_NEXT(transfer->mirror, nodes);
+ transfer->mirror = pakfire_mirrorlist_get_next(transfer->mirrors, transfer->mirror);
}
// No mirror found
return ENOENT;
}
- DEBUG(downloader->pakfire, "Selected mirror %s\n", transfer->mirror->url);
+ DEBUG(downloader->pakfire, "Selected mirror %s\n", pakfire_mirror_get_url(transfer->mirror));
return 0;
}
// Did we use a mirror?
if (transfer->mirror) {
- // Decrease retries and potentially mark mirror as broken
- if (!transfer->mirror->retries_left--) {
- DEBUG(downloader->pakfire, "Mark mirror %s as broken\n",
- transfer->mirror->url);
- transfer->mirror->broken = 1;
- }
+ pakfire_mirror_transfer_failed(transfer->mirror);
// Try again with another mirror
return EAGAIN;
if (r)
return r;
- r = pakfire_url_join(url, transfer->mirror->url, transfer->url);
+ r = pakfire_url_join(url, pakfire_mirror_get_url(transfer->mirror), transfer->url);
if (r)
return r;
return r;
}
-
-struct pakfire_mirrorlist {
- struct pakfire* pakfire;
- int nrefs;
-
- STAILQ_HEAD(mirrors, pakfire_mirror) mirrors;
-};
-
-static void pakfire_mirrorlist_clear(struct pakfire_mirrorlist* ml) {
- while (!STAILQ_EMPTY(&ml->mirrors)) {
- struct pakfire_mirror* mirror = STAILQ_FIRST(&ml->mirrors);
- STAILQ_REMOVE_HEAD(&ml->mirrors, nodes);
- free(mirror);
- }
-}
-
-static void pakfire_mirrorlist_free(struct pakfire_mirrorlist* ml) {
- pakfire_mirrorlist_clear(ml);
-
- pakfire_unref(ml->pakfire);
- free(ml);
-}
-
-int pakfire_mirrorlist_create(struct pakfire_mirrorlist** mirrorlist, struct pakfire* pakfire) {
- struct pakfire_mirrorlist* ml = calloc(1, sizeof(*ml));
- if (!ml)
- return ENOMEM;
-
- ml->pakfire = pakfire_ref(pakfire);
- ml->nrefs = 1;
-
- // Init mirrors
- STAILQ_INIT(&ml->mirrors);
-
- *mirrorlist = ml;
-
- return 0;
-}
-
-struct pakfire_mirrorlist* pakfire_mirrorlist_ref(struct pakfire_mirrorlist* ml) {
- ++ml->nrefs;
-
- return ml;
-}
-
-struct pakfire_mirrorlist* pakfire_mirrorlist_unref(struct pakfire_mirrorlist* ml) {
- if (--ml->nrefs > 0)
- return ml;
-
- pakfire_mirrorlist_free(ml);
-
- return NULL;
-}
-
-static int pakfire_mirrorlist_check_mirrorlist(struct pakfire_mirrorlist* ml,
- struct json_object* root) {
- struct json_object* typeobj = NULL;
- int r = 1;
-
- r = json_object_object_get_ex(root, "type", &typeobj);
- if (!r) {
- ERROR(ml->pakfire, "mirrorlist does not have a 'type' attribute\n");
- goto ERROR;
- }
-
- const char* type = json_object_get_string(typeobj);
- if (!type) {
- ERROR(ml->pakfire, "mirrorlist has an empty or unknown 'type' attribute\n");
- goto ERROR;
- }
-
- if (strcmp(type, "mirrorlist") != 0) {
- ERROR(ml->pakfire, "Unexpected type: %s\n", type);
- goto ERROR;
- }
-
- // Success
- r = 0;
-
-ERROR:
- if (typeobj)
- json_object_put(typeobj);
-
- return r;
-}
-
-int pakfire_mirrorlist_read(struct pakfire_mirrorlist* ml, const char* path) {
- if (!path || !*path) {
- errno = EINVAL;
- return 1;
- }
-
- DEBUG(ml->pakfire, "Reading mirrorlist from %s\n", path);
-
- struct json_object* json = pakfire_json_parse_from_file(ml->pakfire, path);
- if (!json) {
- // Ignore if path does not exist
- if (errno == ENOENT)
- return 0;
-
- ERROR(ml->pakfire, "Could not parse mirrorlist from %s: %m\n", path);
- return 1;
- }
-
- struct json_object* mirrors = NULL;
-
- // Check if we found a valid mirrorlist
- int r = pakfire_mirrorlist_check_mirrorlist(ml, json);
- if (r)
- goto ERROR;
-
- // Clear all existing mirrors
- pakfire_mirrorlist_clear(ml);
-
- // Add the new mirrors
- r = json_object_object_get_ex(json, "mirrors", &mirrors);
- if (!r) {
- DEBUG(ml->pakfire, "Mirrorlist has no mirrors\n");
- r = 0;
- goto ERROR;
- }
-
- size_t num_mirrors = json_object_array_length(mirrors);
-
- for (unsigned int i = 0; i < num_mirrors; i++) {
- struct json_object* mirror = json_object_array_get_idx(mirrors, i);
- if (!mirror)
- continue;
-
- // Find URL
- struct json_object* urlobj;
- r = json_object_object_get_ex(mirror, "url", &urlobj);
- if (!r)
- goto ERROR;
-
- const char* url = json_object_get_string(urlobj);
-
- // Add the mirror to the downloader
- r = pakfire_mirrorlist_add_mirror(ml, url);
- if (r) {
- ERROR(ml->pakfire, "Could not add mirror %s: %m\n", url);
- goto ERROR;
- }
- }
-
- // Success
- r = 0;
-
-ERROR:
- if (json)
- json_object_put(json);
-
- return r;
-}
-
-int pakfire_mirrorlist_add_mirror(struct pakfire_mirrorlist* ml, const char* url) {
- // Allocate a new mirror object
- struct pakfire_mirror* mirror = calloc(1, sizeof(*mirror));
- if (!mirror)
- return ENOMEM;
-
- // Copy URL
- pakfire_string_set(mirror->url, url);
-
- // Set retries
- mirror->retries_left = MIRROR_RETRIES;
-
- // Append it to the list
- STAILQ_INSERT_TAIL(&ml->mirrors, mirror, nodes);
-
- DEBUG(ml->pakfire, "Added mirror %s\n", mirror->url);
-
- return 0;
-}
-
-int pakfire_mirrorlist_empty(struct pakfire_mirrorlist* ml) {
- return STAILQ_EMPTY(&ml->mirrors);
-}
-
-struct pakfire_mirror* pakfire_mirrorlist_first(struct pakfire_mirrorlist* ml) {
- return STAILQ_FIRST(&ml->mirrors);
-}
#ifdef PAKFIRE_PRIVATE
struct pakfire_downloader;
-struct pakfire_mirrorlist;
#include <pakfire/digest.h>
+#include <pakfire/mirrorlist.h>
#include <pakfire/pakfire.h>
enum pakfire_transfer_flags {
int pakfire_downloader_transfer_run(struct pakfire_transfer* transfer, int flags);
int pakfire_downloader_run(struct pakfire_downloader* downloader, const char* title);
-// Mirror lists
-
-int pakfire_mirrorlist_create(struct pakfire_mirrorlist** ml, struct pakfire* pakfire);
-
-struct pakfire_mirrorlist* pakfire_mirrorlist_ref(struct pakfire_mirrorlist* ml);
-struct pakfire_mirrorlist* pakfire_mirrorlist_unref(struct pakfire_mirrorlist* ml);
-
-int pakfire_mirrorlist_read(struct pakfire_mirrorlist* ml, const char* path);
-int pakfire_mirrorlist_add_mirror(struct pakfire_mirrorlist* ml, const char* url);
-
-int pakfire_mirrorlist_empty(struct pakfire_mirrorlist* ml);
-struct pakfire_mirror* pakfire_mirrorlist_first(struct pakfire_mirrorlist* ml);
-
-#endif
+#endif /* PAKFIRE_PRIVATE */
#endif /* PAKFIRE_DOWNLOADER_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2023 Pakfire development team #
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_MIRROR_H
+#define PAKFIRE_MIRROR_H
+
+struct pakfire_mirror;
+
+#include <pakfire/ctx.h>
+
+int pakfire_mirror_create(struct pakfire_mirror** mirror,
+ struct pakfire_ctx* ctx, const char* url);
+
+struct pakfire_mirror* pakfire_mirror_ref(struct pakfire_mirror* mirror);
+struct pakfire_mirror* pakfire_mirror_unref(struct pakfire_mirror* mirror);
+
+const char* pakfire_mirror_get_url(struct pakfire_mirror* mirror);
+
+// Broken?
+
+int pakfire_mirror_is_broken(struct pakfire_mirror* mirror);
+void pakfire_mirror_mark_as_broken(struct pakfire_mirror* mirror);
+
+void pakfire_mirror_transfer_failed(struct pakfire_mirror* mirror);
+
+#endif /* PAKFIRE_MIRROR_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2023 Pakfire development team #
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_MIRRORLIST_H
+#define PAKFIRE_MIRRORLIST_H
+
+#ifdef PAKFIRE_PRIVATE
+
+struct pakfire_mirrorlist;
+
+#include <pakfire/ctx.h>
+#include <pakfire/mirror.h>
+
+int pakfire_mirrorlist_create(struct pakfire_mirrorlist** list, struct pakfire_ctx* ctx);
+
+struct pakfire_mirrorlist* pakfire_mirrorlist_ref(struct pakfire_mirrorlist* list);
+struct pakfire_mirrorlist* pakfire_mirrorlist_unref(struct pakfire_mirrorlist* list);
+
+int pakfire_mirrorlist_read(struct pakfire_mirrorlist* list, const char* path);
+
+int pakfire_mirrorlist_add_mirror(
+ struct pakfire_mirrorlist* list, struct pakfire_mirror* mirror);
+
+int pakfire_mirrorlist_empty(struct pakfire_mirrorlist* ml);
+
+struct pakfire_mirror* pakfire_mirrorlist_get_first(struct pakfire_mirrorlist* list);
+struct pakfire_mirror* pakfire_mirrorlist_get_next(
+ struct pakfire_mirrorlist* list, struct pakfire_mirror* mirror);
+
+#endif /* PAKFIRE_PRIVATE */
+
+#endif /* PAKFIRE_MIRRORLIST_H */
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
+#include <pakfire/ctx.h>
#include <pakfire/digest.h>
#include <pakfire/pakfire.h>
// JSON Stuff
-struct json_object* pakfire_json_parse_from_file(struct pakfire* pakfire, const char* path);
+struct json_object* pakfire_json_parse_from_file(struct pakfire_ctx* ctx, const char* path);
int pakfire_json_add_string(struct pakfire* pakfire,
struct json_object* json, const char* name, const char* value);
int pakfire_json_add_integer(struct pakfire* pakfire,
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2023 Pakfire development team #
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <pakfire/mirror.h>
+#include <pakfire/pakfire.h>
+#include <pakfire/string.h>
+
+// Retry a mirror up to N times before marking it as broken
+#define MIRROR_RETRIES 3
+
+struct pakfire_mirror {
+ struct pakfire_ctx* ctx;
+ int nrefs;
+
+ char url[PATH_MAX];
+
+ unsigned int retries_left;
+
+ // Set if the mirror is considered broken
+ int is_broken;
+};
+
+static void pakfire_mirror_free(struct pakfire_mirror* mirror) {
+ if (mirror->ctx)
+ pakfire_ctx_unref(mirror->ctx);
+
+ free(mirror);
+}
+
+int pakfire_mirror_create(struct pakfire_mirror** mirror,
+ struct pakfire_ctx* ctx, const char* url) {
+ struct pakfire_mirror* m = NULL;
+ int r;
+
+ // Allocate the mirror
+ m = calloc(1, sizeof(*m));
+ if (!m)
+ return -errno;
+
+ // Store a reference to the context
+ m->ctx = pakfire_ctx_ref(ctx);
+
+ // Initialize the reference counter
+ m->nrefs = 1;
+
+ // Store the URL
+ r = pakfire_string_set(m->url, url);
+ if (r)
+ goto ERROR;
+
+ // Set the default retries
+ m->retries_left = MIRROR_RETRIES;
+
+ // Return the pointer
+ *mirror = pakfire_mirror_ref(m);
+
+ERROR:
+ if (m)
+ pakfire_mirror_unref(m);
+
+ return r;
+}
+
+struct pakfire_mirror* pakfire_mirror_ref(struct pakfire_mirror* mirror) {
+ ++mirror->nrefs;
+
+ return mirror;
+}
+
+struct pakfire_mirror* pakfire_mirror_unref(struct pakfire_mirror* mirror) {
+ if (--mirror->nrefs > 0)
+ return mirror;
+
+ pakfire_mirror_free(mirror);
+ return NULL;
+}
+
+const char* pakfire_mirror_get_url(struct pakfire_mirror* mirror) {
+ return mirror->url;
+}
+
+// Broken
+
+int pakfire_mirror_is_broken(struct pakfire_mirror* mirror) {
+ return mirror->is_broken;
+}
+
+void pakfire_mirror_mark_as_broken(struct pakfire_mirror* mirror) {
+ CTX_DEBUG(mirror->ctx, "Mirror %s has been marked as broken\n", mirror->url);
+
+ mirror->is_broken = 1;
+}
+
+void pakfire_mirror_transfer_failed(struct pakfire_mirror* mirror) {
+ if (!mirror->retries_left--)
+ pakfire_mirror_mark_as_broken(mirror);
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2023 Pakfire development team #
+# #
+# 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <pakfire/ctx.h>
+#include <pakfire/logging.h>
+#include <pakfire/mirror.h>
+#include <pakfire/mirrorlist.h>
+#include <pakfire/util.h>
+
+struct pakfire_mirrorlist {
+ struct pakfire_ctx* ctx;
+ int nrefs;
+
+ // Mirrors
+ struct pakfire_mirror** mirrors;
+ unsigned int num_mirrors;
+};
+
+static void pakfire_mirrorlist_clear(struct pakfire_mirrorlist* list) {
+ if (list->mirrors) {
+ for (unsigned int i = 0; i < list->num_mirrors; i++)
+ pakfire_mirror_unref(list->mirrors[i]);
+
+ free(list->mirrors);
+
+ list->mirrors = NULL;
+ list->num_mirrors = 0;
+ }
+}
+
+static void pakfire_mirrorlist_free(struct pakfire_mirrorlist* list) {
+ pakfire_mirrorlist_clear(list);
+
+ if (list->ctx)
+ pakfire_ctx_unref(list->ctx);
+ free(list);
+}
+
+int pakfire_mirrorlist_create(struct pakfire_mirrorlist** list, struct pakfire_ctx* ctx) {
+ struct pakfire_mirrorlist* l = NULL;
+
+ // Allocate a new list
+ l = calloc(1, sizeof(*l));
+ if (!l)
+ return -errno;
+
+ // Store a reference to the context
+ l->ctx = pakfire_ctx_ref(ctx);
+
+ // Initialize the reference counter
+ l->nrefs = 1;
+
+ // Return the pointer
+ *list = l;
+
+ return 0;
+}
+
+struct pakfire_mirrorlist* pakfire_mirrorlist_ref(struct pakfire_mirrorlist* list) {
+ ++list->nrefs;
+
+ return list;
+}
+
+struct pakfire_mirrorlist* pakfire_mirrorlist_unref(struct pakfire_mirrorlist* list) {
+ if (--list->nrefs > 0)
+ return list;
+
+ pakfire_mirrorlist_free(list);
+ return NULL;
+}
+
+static int pakfire_mirrorlist_check_mirrorlist(struct pakfire_mirrorlist* list,
+ struct json_object* root) {
+ struct json_object* typeobj = NULL;
+ int r = 1;
+
+ r = json_object_object_get_ex(root, "type", &typeobj);
+ if (!r) {
+ CTX_ERROR(list->ctx, "mirrorlist does not have a 'type' attribute\n");
+ goto ERROR;
+ }
+
+ const char* type = json_object_get_string(typeobj);
+ if (!type) {
+ CTX_ERROR(list->ctx, "mirrorlist has an empty or unknown 'type' attribute\n");
+ goto ERROR;
+ }
+
+ if (strcmp(type, "mirrorlist") != 0) {
+ CTX_ERROR(list->ctx, "Unexpected type: %s\n", type);
+ goto ERROR;
+ }
+
+ // Success
+ r = 0;
+
+ERROR:
+ if (typeobj)
+ json_object_put(typeobj);
+
+ return r;
+}
+
+static int pakfire_mirrorlist_add_mirror_from_url(
+ struct pakfire_mirrorlist* list, const char* url) {
+ struct pakfire_mirror* mirror = NULL;
+ int r;
+
+ // Create a new mirror object
+ r = pakfire_mirror_create(&mirror, list->ctx, url);
+ if (r)
+ goto ERROR;
+
+ // Add the mirror to the list
+ r = pakfire_mirrorlist_add_mirror(list, mirror);
+ if (r)
+ goto ERROR;
+
+ERROR:
+ if (mirror)
+ pakfire_mirror_unref(mirror);
+
+ return r;
+}
+
+int pakfire_mirrorlist_read(struct pakfire_mirrorlist* list, const char* path) {
+ if (!path || !*path) {
+ errno = EINVAL;
+ return 1;
+ }
+
+ CTX_DEBUG(list->ctx, "Reading mirrorlist from %s\n", path);
+
+ struct json_object* json = pakfire_json_parse_from_file(list->ctx, path);
+ if (!json) {
+ // Ignore if path does not exist
+ if (errno == ENOENT)
+ return 0;
+
+ CTX_ERROR(list->ctx, "Could not parse mirrorlist from %s: %m\n", path);
+ return 1;
+ }
+
+ struct json_object* mirrors = NULL;
+
+ // Check if we found a valid mirrorlist
+ int r = pakfire_mirrorlist_check_mirrorlist(list, json);
+ if (r)
+ goto ERROR;
+
+ // Clear all existing mirrors
+ pakfire_mirrorlist_clear(list);
+
+ // Add the new mirrors
+ r = json_object_object_get_ex(json, "mirrors", &mirrors);
+ if (!r) {
+ CTX_DEBUG(list->ctx, "Mirrorlist has no mirrors\n");
+ r = 0;
+ goto ERROR;
+ }
+
+ size_t num_mirrors = json_object_array_length(mirrors);
+
+ for (unsigned int i = 0; i < num_mirrors; i++) {
+ struct json_object* mirror = json_object_array_get_idx(mirrors, i);
+ if (!mirror)
+ continue;
+
+ // Find URL
+ struct json_object* urlobj;
+ r = json_object_object_get_ex(mirror, "url", &urlobj);
+ if (!r)
+ goto ERROR;
+
+ const char* url = json_object_get_string(urlobj);
+
+ // Add the mirror to the downloader
+ r = pakfire_mirrorlist_add_mirror_from_url(list, url);
+ if (r) {
+ CTX_ERROR(list->ctx, "Could not add mirror %s: %m\n", url);
+ goto ERROR;
+ }
+ }
+
+ // Success
+ r = 0;
+
+ERROR:
+ if (json)
+ json_object_put(json);
+
+ return r;
+}
+
+int pakfire_mirrorlist_add_mirror(struct pakfire_mirrorlist* list, struct pakfire_mirror* mirror) {
+ // Check input
+ if (!mirror)
+ return -EINVAL;
+
+ // Grow the array
+ list->mirrors = reallocarray(list->mirrors, list->num_mirrors + 1, sizeof(*list->mirrors));
+ if (!list->mirrors)
+ return -errno;
+
+ // Store the mirror
+ list->mirrors[list->num_mirrors++] = pakfire_mirror_ref(mirror);
+
+ return 0;
+}
+
+int pakfire_mirrorlist_empty(struct pakfire_mirrorlist* list) {
+ return list->num_mirrors == 0;
+}
+
+struct pakfire_mirror* pakfire_mirrorlist_get_first(struct pakfire_mirrorlist* list) {
+ if (!list->num_mirrors)
+ return NULL;
+
+ return pakfire_mirror_ref(list->mirrors[0]);
+}
+
+struct pakfire_mirror* pakfire_mirrorlist_get_next(
+ struct pakfire_mirrorlist* list, struct pakfire_mirror* mirror) {
+ for (unsigned int i = 0; i < list->num_mirrors; i++) {
+ if (list->mirrors[i] == mirror) {
+ if (i < list->num_mirrors)
+ return list->mirrors[i+1];
+
+ break;
+ }
+ }
+
+ return NULL;
+}
if (!*repo->appdata->mirrorlist)
return NULL;
- int r = pakfire_mirrorlist_create(&repo->mirrorlist, repo->pakfire);
+ int r = pakfire_mirrorlist_create(&repo->mirrorlist, repo->ctx);
if (r) {
ERROR(repo->pakfire, "Could not create mirrorlist: %m\n");
return NULL;
DEBUG(repo->pakfire, "Reading repository metadata from %s...\n", path);
- struct json_object* json = pakfire_json_parse_from_file(repo->pakfire, path);
+ struct json_object* json = pakfire_json_parse_from_file(repo->ctx, path);
if (!json) {
switch (errno) {
case ENOENT:
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
+#include <pakfire/ctx.h>
#include <pakfire/constants.h>
#include <pakfire/logging.h>
#include <pakfire/package.h>
// JSON Stuff
-static struct json_object* pakfire_json_parse(struct pakfire* pakfire, FILE* f) {
+static struct json_object* pakfire_json_parse(struct pakfire_ctx* ctx, FILE* f) {
struct json_tokener* tokener = NULL;
struct json_object* json = NULL;
char* buffer = NULL;
// Create tokener
tokener = json_tokener_new();
if (!tokener) {
- ERROR(pakfire, "Could not allocate JSON tokener: %m\n");
+ CTX_ERROR(ctx, "Could not allocate JSON tokener: %m\n");
goto ERROR;
}
if (!json) {
enum json_tokener_error error = json_tokener_get_error(tokener);
- ERROR(pakfire, "JSON parsing error: %s\n", json_tokener_error_desc(error));
+ CTX_ERROR(ctx, "JSON parsing error: %s\n", json_tokener_error_desc(error));
goto ERROR;
}
// Log what we have parsed
- DEBUG(pakfire, "Parsed JSON:\n%s\n",
+ CTX_DEBUG(ctx, "Parsed JSON:\n%s\n",
json_object_to_json_string_ext(json,
JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY)
);
return json;
}
-struct json_object* pakfire_json_parse_from_file(struct pakfire* pakfire, const char* path) {
+struct json_object* pakfire_json_parse_from_file(struct pakfire_ctx* ctx, const char* path) {
FILE* f = fopen(path, "r");
if (!f)
return NULL;
- struct json_object* json = pakfire_json_parse(pakfire, f);
+ struct json_object* json = pakfire_json_parse(ctx, f);
fclose(f);
return json;